Update to gcc-3.4.6
[dragonfly.git] / contrib / gcc-3.4 / gcc / config / i386 / i386.md
CommitLineData
003757ed
MD
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
4;; Free Software Foundation, Inc.
5;; Mostly by William Schelter.
6;; x86_64 support added by Jan Hubicka
7;;
8;; This file is part of GCC.
9;;
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)
13;; any later version.
14;;
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.
19;;
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, 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA. */
24;;
25;; The original PO technology requires these to be ordered by speed,
26;; so that assigner will pick the fastest.
27;;
28;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29;;
30;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31;; constraint letters.
32;;
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
35;; operands[1].
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.
43;;
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.
50
51;; UNSPEC usage:
52
53(define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
003757ed
MD
66 (UNSPEC_STACK_ALLOC 11)
67 (UNSPEC_SET_GOT 12)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69
70 ; TLS support
71 (UNSPEC_TP 15)
72 (UNSPEC_TLS_GD 16)
73 (UNSPEC_TLS_LD_BASE 17)
74
75 ; Other random patterns
76 (UNSPEC_SCAS 20)
77 (UNSPEC_SIN 21)
78 (UNSPEC_COS 22)
79 (UNSPEC_FNSTSW 24)
80 (UNSPEC_SAHF 25)
81 (UNSPEC_FSTCW 26)
82 (UNSPEC_ADD_CARRY 27)
83 (UNSPEC_FLDCW 28)
84
85 ; For SSE/MMX support:
86 (UNSPEC_FIX 30)
87 (UNSPEC_MASKMOV 32)
88 (UNSPEC_MOVMSK 33)
89 (UNSPEC_MOVNT 34)
90 (UNSPEC_MOVA 38)
91 (UNSPEC_MOVU 39)
92 (UNSPEC_SHUFFLE 41)
93 (UNSPEC_RCP 42)
94 (UNSPEC_RSQRT 43)
95 (UNSPEC_SFENCE 44)
96 (UNSPEC_NOP 45) ; prevents combiner cleverness
97 (UNSPEC_PAVGUSB 49)
98 (UNSPEC_PFRCP 50)
99 (UNSPEC_PFRCPIT1 51)
100 (UNSPEC_PFRCPIT2 52)
101 (UNSPEC_PFRSQRT 53)
102 (UNSPEC_PFRSQIT1 54)
103 (UNSPEC_PSHUFLW 55)
104 (UNSPEC_PSHUFHW 56)
105 (UNSPEC_MFENCE 59)
106 (UNSPEC_LFENCE 60)
107 (UNSPEC_PSADBW 61)
108 (UNSPEC_ADDSUB 71)
109 (UNSPEC_HADD 72)
110 (UNSPEC_HSUB 73)
111 (UNSPEC_MOVSHDUP 74)
112 (UNSPEC_MOVSLDUP 75)
113 (UNSPEC_LDQQU 76)
114 (UNSPEC_MOVDDUP 77)
115
116 ; x87 Floating point
117 (UNSPEC_FPATAN 65)
118 (UNSPEC_FYL2X 66)
119 (UNSPEC_FSCALE 67)
120 (UNSPEC_FRNDINT 68)
121 (UNSPEC_F2XM1 69)
122
123 ; REP instruction
124 (UNSPEC_REP 75)
125 ])
126
127(define_constants
128 [(UNSPECV_BLOCKAGE 0)
3a327f56 129 (UNSPECV_STACK_PROBE 10)
003757ed
MD
130 (UNSPECV_EH_RETURN 13)
131 (UNSPECV_EMMS 31)
132 (UNSPECV_LDMXCSR 37)
133 (UNSPECV_STMXCSR 40)
134 (UNSPECV_FEMMS 46)
135 (UNSPECV_CLFLUSH 57)
136 (UNSPECV_ALIGN 68)
137 (UNSPECV_MONITOR 69)
138 (UNSPECV_MWAIT 70)
139 ])
140
141;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
142;; from i386.c.
143
144;; In C guard expressions, put expressions which may be compile-time
145;; constants first. This allows for better optimization. For
146;; example, write "TARGET_64BIT && reload_completed", not
147;; "reload_completed && TARGET_64BIT".
148
149\f
150;; Processor type. This attribute must exactly match the processor_type
151;; enumeration in i386.h.
152(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153 (const (symbol_ref "ix86_tune")))
154
155;; A basic instruction type. Refinements due to arguments to be
156;; provided in other attributes.
157(define_attr "type"
158 "other,multi,
159 alu,alu1,negnot,imov,imovx,lea,
160 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161 icmp,test,ibr,setcc,icmov,
162 push,pop,call,callv,leave,
163 str,cld,
164 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165 sselog,sseiadd,sseishft,sseimul,
166 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
168 (const_string "other"))
169
170;; Main data type used by the insn
171(define_attr "mode"
172 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
173 (const_string "unknown"))
174
175;; The CPU unit operations uses.
176(define_attr "unit" "integer,i387,sse,mmx,unknown"
177 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178 (const_string "i387")
179 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181 (const_string "sse")
182 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183 (const_string "mmx")
184 (eq_attr "type" "other")
185 (const_string "unknown")]
186 (const_string "integer")))
187
188;; The (bounding maximum) length of an instruction immediate.
189(define_attr "length_immediate" ""
190 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
191 (const_int 0)
192 (eq_attr "unit" "i387,sse,mmx")
193 (const_int 0)
194 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195 imul,icmp,push,pop")
196 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
197 (eq_attr "type" "imov,test")
198 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
199 (eq_attr "type" "call")
200 (if_then_else (match_operand 0 "constant_call_address_operand" "")
201 (const_int 4)
202 (const_int 0))
203 (eq_attr "type" "callv")
204 (if_then_else (match_operand 1 "constant_call_address_operand" "")
205 (const_int 4)
206 (const_int 0))
207 ;; We don't know the size before shorten_branches. Expect
208 ;; the instruction to fit for better scheduling.
209 (eq_attr "type" "ibr")
210 (const_int 1)
211 ]
212 (symbol_ref "/* Update immediate_length and other attributes! */
213 abort(),1")))
214
215;; The (bounding maximum) length of an instruction address.
216(define_attr "length_address" ""
217 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
218 (const_int 0)
219 (and (eq_attr "type" "call")
220 (match_operand 0 "constant_call_address_operand" ""))
221 (const_int 0)
222 (and (eq_attr "type" "callv")
223 (match_operand 1 "constant_call_address_operand" ""))
224 (const_int 0)
225 ]
226 (symbol_ref "ix86_attr_length_address_default (insn)")))
227
228;; Set when length prefix is used.
229(define_attr "prefix_data16" ""
230 (if_then_else (ior (eq_attr "mode" "HI")
231 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
232 (const_int 1)
233 (const_int 0)))
234
235;; Set when string REP prefix is used.
236(define_attr "prefix_rep" ""
237 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238 (const_int 1)
239 (const_int 0)))
240
241;; Set when 0f opcode prefix is used.
242(define_attr "prefix_0f" ""
243 (if_then_else
244 (ior (eq_attr "type" "imovx,setcc,icmov")
245 (eq_attr "unit" "sse,mmx"))
246 (const_int 1)
247 (const_int 0)))
248
249;; Set when 0f opcode prefix is used.
250(define_attr "prefix_rex" ""
251 (cond [(and (eq_attr "mode" "DI")
252 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253 (const_int 1)
254 (and (eq_attr "mode" "QI")
255 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256 (const_int 0)))
257 (const_int 1)
258 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259 (const_int 0))
260 (const_int 1)
261 ]
262 (const_int 0)))
263
264;; Set when modrm byte is used.
265(define_attr "modrm" ""
266 (cond [(eq_attr "type" "str,cld,leave")
267 (const_int 0)
268 (eq_attr "unit" "i387")
269 (const_int 0)
270 (and (eq_attr "type" "incdec")
271 (ior (match_operand:SI 1 "register_operand" "")
272 (match_operand:HI 1 "register_operand" "")))
273 (const_int 0)
274 (and (eq_attr "type" "push")
275 (not (match_operand 1 "memory_operand" "")))
276 (const_int 0)
277 (and (eq_attr "type" "pop")
278 (not (match_operand 0 "memory_operand" "")))
279 (const_int 0)
280 (and (eq_attr "type" "imov")
281 (and (match_operand 0 "register_operand" "")
282 (match_operand 1 "immediate_operand" "")))
283 (const_int 0)
284 (and (eq_attr "type" "call")
285 (match_operand 0 "constant_call_address_operand" ""))
286 (const_int 0)
287 (and (eq_attr "type" "callv")
288 (match_operand 1 "constant_call_address_operand" ""))
289 (const_int 0)
290 ]
291 (const_int 1)))
292
293;; The (bounding maximum) length of an instruction in bytes.
294;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
295;; to split it and compute proper length as for other insns.
296(define_attr "length" ""
297 (cond [(eq_attr "type" "other,multi,fistp")
298 (const_int 16)
299 (eq_attr "type" "fcmp")
300 (const_int 4)
301 (eq_attr "unit" "i387")
302 (plus (const_int 2)
303 (plus (attr "prefix_data16")
304 (attr "length_address")))]
305 (plus (plus (attr "modrm")
306 (plus (attr "prefix_0f")
307 (plus (attr "prefix_rex")
308 (const_int 1))))
309 (plus (attr "prefix_rep")
310 (plus (attr "prefix_data16")
311 (plus (attr "length_immediate")
312 (attr "length_address")))))))
313
314;; The `memory' attribute is `none' if no memory is referenced, `load' or
315;; `store' if there is a simple memory reference therein, or `unknown'
316;; if the instruction is complex.
317
318(define_attr "memory" "none,load,store,both,unknown"
319 (cond [(eq_attr "type" "other,multi,str")
320 (const_string "unknown")
321 (eq_attr "type" "lea,fcmov,fpspc,cld")
322 (const_string "none")
323 (eq_attr "type" "fistp,leave")
324 (const_string "both")
325 (eq_attr "type" "push")
326 (if_then_else (match_operand 1 "memory_operand" "")
327 (const_string "both")
328 (const_string "store"))
329 (eq_attr "type" "pop")
330 (if_then_else (match_operand 0 "memory_operand" "")
331 (const_string "both")
332 (const_string "load"))
333 (eq_attr "type" "setcc")
334 (if_then_else (match_operand 0 "memory_operand" "")
335 (const_string "store")
336 (const_string "none"))
337 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
338 (if_then_else (ior (match_operand 0 "memory_operand" "")
339 (match_operand 1 "memory_operand" ""))
340 (const_string "load")
341 (const_string "none"))
342 (eq_attr "type" "ibr")
343 (if_then_else (match_operand 0 "memory_operand" "")
344 (const_string "load")
345 (const_string "none"))
346 (eq_attr "type" "call")
347 (if_then_else (match_operand 0 "constant_call_address_operand" "")
348 (const_string "none")
349 (const_string "load"))
350 (eq_attr "type" "callv")
351 (if_then_else (match_operand 1 "constant_call_address_operand" "")
352 (const_string "none")
353 (const_string "load"))
354 (and (eq_attr "type" "alu1,negnot,ishift1")
355 (match_operand 1 "memory_operand" ""))
356 (const_string "both")
357 (and (match_operand 0 "memory_operand" "")
358 (match_operand 1 "memory_operand" ""))
359 (const_string "both")
360 (match_operand 0 "memory_operand" "")
361 (const_string "store")
362 (match_operand 1 "memory_operand" "")
363 (const_string "load")
364 (and (eq_attr "type"
365 "!alu1,negnot,ishift1,
366 imov,imovx,icmp,test,
367 fmov,fcmp,fsgn,
368 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369 mmx,mmxmov,mmxcmp,mmxcvt")
370 (match_operand 2 "memory_operand" ""))
371 (const_string "load")
372 (and (eq_attr "type" "icmov")
373 (match_operand 3 "memory_operand" ""))
374 (const_string "load")
375 ]
376 (const_string "none")))
377
378;; Indicates if an instruction has both an immediate and a displacement.
379
380(define_attr "imm_disp" "false,true,unknown"
381 (cond [(eq_attr "type" "other,multi")
382 (const_string "unknown")
383 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
384 (and (match_operand 0 "memory_displacement_operand" "")
385 (match_operand 1 "immediate_operand" "")))
386 (const_string "true")
387 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
388 (and (match_operand 0 "memory_displacement_operand" "")
389 (match_operand 2 "immediate_operand" "")))
390 (const_string "true")
391 ]
392 (const_string "false")))
393
394;; Indicates if an FP operation has an integer source.
395
396(define_attr "fp_int_src" "false,true"
397 (const_string "false"))
398
399;; Describe a user's asm statement.
400(define_asm_attributes
401 [(set_attr "length" "128")
402 (set_attr "type" "multi")])
403\f
404(include "pentium.md")
405(include "ppro.md")
406(include "k6.md")
407(include "athlon.md")
408\f
409;; Compare instructions.
410
411;; All compare insns have expanders that save the operands away without
412;; actually generating RTL. The bCOND or sCOND (emitted immediately
413;; after the cmp) will actually emit the cmpM.
414
415(define_expand "cmpdi"
416 [(set (reg:CC 17)
417 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
418 (match_operand:DI 1 "x86_64_general_operand" "")))]
419 ""
420{
421 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
422 operands[0] = force_reg (DImode, operands[0]);
423 ix86_compare_op0 = operands[0];
424 ix86_compare_op1 = operands[1];
425 DONE;
426})
427
428(define_expand "cmpsi"
429 [(set (reg:CC 17)
430 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
431 (match_operand:SI 1 "general_operand" "")))]
432 ""
433{
434 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
435 operands[0] = force_reg (SImode, operands[0]);
436 ix86_compare_op0 = operands[0];
437 ix86_compare_op1 = operands[1];
438 DONE;
439})
440
441(define_expand "cmphi"
442 [(set (reg:CC 17)
443 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
444 (match_operand:HI 1 "general_operand" "")))]
445 ""
446{
447 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
448 operands[0] = force_reg (HImode, operands[0]);
449 ix86_compare_op0 = operands[0];
450 ix86_compare_op1 = operands[1];
451 DONE;
452})
453
454(define_expand "cmpqi"
455 [(set (reg:CC 17)
456 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
457 (match_operand:QI 1 "general_operand" "")))]
458 "TARGET_QIMODE_MATH"
459{
460 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
461 operands[0] = force_reg (QImode, operands[0]);
462 ix86_compare_op0 = operands[0];
463 ix86_compare_op1 = operands[1];
464 DONE;
465})
466
467(define_insn "cmpdi_ccno_1_rex64"
468 [(set (reg 17)
469 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
470 (match_operand:DI 1 "const0_operand" "n,n")))]
471 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
472 "@
473 test{q}\t{%0, %0|%0, %0}
474 cmp{q}\t{%1, %0|%0, %1}"
475 [(set_attr "type" "test,icmp")
476 (set_attr "length_immediate" "0,1")
477 (set_attr "mode" "DI")])
478
479(define_insn "*cmpdi_minus_1_rex64"
480 [(set (reg 17)
481 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
482 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
483 (const_int 0)))]
484 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
485 "cmp{q}\t{%1, %0|%0, %1}"
486 [(set_attr "type" "icmp")
487 (set_attr "mode" "DI")])
488
489(define_expand "cmpdi_1_rex64"
490 [(set (reg:CC 17)
491 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
492 (match_operand:DI 1 "general_operand" "")))]
493 "TARGET_64BIT"
494 "")
495
496(define_insn "cmpdi_1_insn_rex64"
497 [(set (reg 17)
498 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
499 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
500 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
501 "cmp{q}\t{%1, %0|%0, %1}"
502 [(set_attr "type" "icmp")
503 (set_attr "mode" "DI")])
504
505
506(define_insn "*cmpsi_ccno_1"
507 [(set (reg 17)
508 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
509 (match_operand:SI 1 "const0_operand" "n,n")))]
510 "ix86_match_ccmode (insn, CCNOmode)"
511 "@
512 test{l}\t{%0, %0|%0, %0}
513 cmp{l}\t{%1, %0|%0, %1}"
514 [(set_attr "type" "test,icmp")
515 (set_attr "length_immediate" "0,1")
516 (set_attr "mode" "SI")])
517
518(define_insn "*cmpsi_minus_1"
519 [(set (reg 17)
520 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
521 (match_operand:SI 1 "general_operand" "ri,mr"))
522 (const_int 0)))]
523 "ix86_match_ccmode (insn, CCGOCmode)"
524 "cmp{l}\t{%1, %0|%0, %1}"
525 [(set_attr "type" "icmp")
526 (set_attr "mode" "SI")])
527
528(define_expand "cmpsi_1"
529 [(set (reg:CC 17)
530 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
531 (match_operand:SI 1 "general_operand" "ri,mr")))]
532 ""
533 "")
534
535(define_insn "*cmpsi_1_insn"
536 [(set (reg 17)
537 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
538 (match_operand:SI 1 "general_operand" "ri,mr")))]
539 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
540 && ix86_match_ccmode (insn, CCmode)"
541 "cmp{l}\t{%1, %0|%0, %1}"
542 [(set_attr "type" "icmp")
543 (set_attr "mode" "SI")])
544
545(define_insn "*cmphi_ccno_1"
546 [(set (reg 17)
547 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
548 (match_operand:HI 1 "const0_operand" "n,n")))]
549 "ix86_match_ccmode (insn, CCNOmode)"
550 "@
551 test{w}\t{%0, %0|%0, %0}
552 cmp{w}\t{%1, %0|%0, %1}"
553 [(set_attr "type" "test,icmp")
554 (set_attr "length_immediate" "0,1")
555 (set_attr "mode" "HI")])
556
557(define_insn "*cmphi_minus_1"
558 [(set (reg 17)
559 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
560 (match_operand:HI 1 "general_operand" "ri,mr"))
561 (const_int 0)))]
562 "ix86_match_ccmode (insn, CCGOCmode)"
563 "cmp{w}\t{%1, %0|%0, %1}"
564 [(set_attr "type" "icmp")
565 (set_attr "mode" "HI")])
566
567(define_insn "*cmphi_1"
568 [(set (reg 17)
569 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:HI 1 "general_operand" "ri,mr")))]
571 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572 && ix86_match_ccmode (insn, CCmode)"
573 "cmp{w}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "HI")])
576
577(define_insn "*cmpqi_ccno_1"
578 [(set (reg 17)
579 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
580 (match_operand:QI 1 "const0_operand" "n,n")))]
581 "ix86_match_ccmode (insn, CCNOmode)"
582 "@
583 test{b}\t{%0, %0|%0, %0}
584 cmp{b}\t{$0, %0|%0, 0}"
585 [(set_attr "type" "test,icmp")
586 (set_attr "length_immediate" "0,1")
587 (set_attr "mode" "QI")])
588
589(define_insn "*cmpqi_1"
590 [(set (reg 17)
591 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
592 (match_operand:QI 1 "general_operand" "qi,mq")))]
593 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
594 && ix86_match_ccmode (insn, CCmode)"
595 "cmp{b}\t{%1, %0|%0, %1}"
596 [(set_attr "type" "icmp")
597 (set_attr "mode" "QI")])
598
599(define_insn "*cmpqi_minus_1"
600 [(set (reg 17)
601 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
602 (match_operand:QI 1 "general_operand" "qi,mq"))
603 (const_int 0)))]
604 "ix86_match_ccmode (insn, CCGOCmode)"
605 "cmp{b}\t{%1, %0|%0, %1}"
606 [(set_attr "type" "icmp")
607 (set_attr "mode" "QI")])
608
609(define_insn "*cmpqi_ext_1"
610 [(set (reg 17)
611 (compare
612 (match_operand:QI 0 "general_operand" "Qm")
613 (subreg:QI
614 (zero_extract:SI
615 (match_operand 1 "ext_register_operand" "Q")
616 (const_int 8)
617 (const_int 8)) 0)))]
618 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
619 "cmp{b}\t{%h1, %0|%0, %h1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "QI")])
622
623(define_insn "*cmpqi_ext_1_rex64"
624 [(set (reg 17)
625 (compare
626 (match_operand:QI 0 "register_operand" "Q")
627 (subreg:QI
628 (zero_extract:SI
629 (match_operand 1 "ext_register_operand" "Q")
630 (const_int 8)
631 (const_int 8)) 0)))]
632 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633 "cmp{b}\t{%h1, %0|%0, %h1}"
634 [(set_attr "type" "icmp")
635 (set_attr "mode" "QI")])
636
637(define_insn "*cmpqi_ext_2"
638 [(set (reg 17)
639 (compare
640 (subreg:QI
641 (zero_extract:SI
642 (match_operand 0 "ext_register_operand" "Q")
643 (const_int 8)
644 (const_int 8)) 0)
645 (match_operand:QI 1 "const0_operand" "n")))]
646 "ix86_match_ccmode (insn, CCNOmode)"
647 "test{b}\t%h0, %h0"
648 [(set_attr "type" "test")
649 (set_attr "length_immediate" "0")
650 (set_attr "mode" "QI")])
651
652(define_expand "cmpqi_ext_3"
653 [(set (reg:CC 17)
654 (compare:CC
655 (subreg:QI
656 (zero_extract:SI
657 (match_operand 0 "ext_register_operand" "")
658 (const_int 8)
659 (const_int 8)) 0)
660 (match_operand:QI 1 "general_operand" "")))]
661 ""
662 "")
663
664(define_insn "cmpqi_ext_3_insn"
665 [(set (reg 17)
666 (compare
667 (subreg:QI
668 (zero_extract:SI
669 (match_operand 0 "ext_register_operand" "Q")
670 (const_int 8)
671 (const_int 8)) 0)
672 (match_operand:QI 1 "general_operand" "Qmn")))]
673 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
674 "cmp{b}\t{%1, %h0|%h0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "QI")])
677
678(define_insn "cmpqi_ext_3_insn_rex64"
679 [(set (reg 17)
680 (compare
681 (subreg:QI
682 (zero_extract:SI
683 (match_operand 0 "ext_register_operand" "Q")
684 (const_int 8)
685 (const_int 8)) 0)
686 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{b}\t{%1, %h0|%h0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "QI")])
691
692(define_insn "*cmpqi_ext_4"
693 [(set (reg 17)
694 (compare
695 (subreg:QI
696 (zero_extract:SI
697 (match_operand 0 "ext_register_operand" "Q")
698 (const_int 8)
699 (const_int 8)) 0)
700 (subreg:QI
701 (zero_extract:SI
702 (match_operand 1 "ext_register_operand" "Q")
703 (const_int 8)
704 (const_int 8)) 0)))]
705 "ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%h1, %h0|%h0, %h1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
709
710;; These implement float point compares.
711;; %%% See if we can get away with VOIDmode operands on the actual insns,
712;; which would allow mix and match FP modes on the compares. Which is what
713;; the old patterns did, but with many more of them.
714
715(define_expand "cmpxf"
716 [(set (reg:CC 17)
717 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
718 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
719 "TARGET_80387"
720{
721 ix86_compare_op0 = operands[0];
722 ix86_compare_op1 = operands[1];
723 DONE;
724})
725
726(define_expand "cmpdf"
727 [(set (reg:CC 17)
728 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
729 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
730 "TARGET_80387 || TARGET_SSE2"
731{
732 ix86_compare_op0 = operands[0];
733 ix86_compare_op1 = operands[1];
734 DONE;
735})
736
737(define_expand "cmpsf"
738 [(set (reg:CC 17)
739 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
740 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
741 "TARGET_80387 || TARGET_SSE"
742{
743 ix86_compare_op0 = operands[0];
744 ix86_compare_op1 = operands[1];
745 DONE;
746})
747
748;; FP compares, step 1:
749;; Set the FP condition codes.
750;;
751;; CCFPmode compare with exceptions
752;; CCFPUmode compare with no exceptions
753
754;; %%% It is an unfortunate fact that ftst has no non-popping variant,
755;; and that fp moves clobber the condition codes, and that there is
756;; currently no way to describe this fact to reg-stack. So there are
757;; no splitters yet for this.
758
759;; %%% YIKES! This scheme does not retain a strong connection between
760;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
761;; work! Only allow tos/mem with tos in op 0.
762;;
763;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
764;; things aren't as bad as they sound...
765
766(define_insn "*cmpfp_0"
767 [(set (match_operand:HI 0 "register_operand" "=a")
768 (unspec:HI
769 [(compare:CCFP (match_operand 1 "register_operand" "f")
770 (match_operand 2 "const0_operand" "X"))]
771 UNSPEC_FNSTSW))]
772 "TARGET_80387
773 && FLOAT_MODE_P (GET_MODE (operands[1]))
774 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
775{
776 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
777 return "ftst\;fnstsw\t%0\;fstp\t%y0";
778 else
779 return "ftst\;fnstsw\t%0";
780}
781 [(set_attr "type" "multi")
782 (set (attr "mode")
783 (cond [(match_operand:SF 1 "" "")
784 (const_string "SF")
785 (match_operand:DF 1 "" "")
786 (const_string "DF")
787 ]
788 (const_string "XF")))])
789
790;; We may not use "#" to split and emit these, since the REG_DEAD notes
791;; used to manage the reg stack popping would not be preserved.
792
793(define_insn "*cmpfp_2_sf"
794 [(set (reg:CCFP 18)
795 (compare:CCFP
796 (match_operand:SF 0 "register_operand" "f")
797 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
798 "TARGET_80387"
799 "* return output_fp_compare (insn, operands, 0, 0);"
800 [(set_attr "type" "fcmp")
801 (set_attr "mode" "SF")])
802
803(define_insn "*cmpfp_2_sf_1"
804 [(set (match_operand:HI 0 "register_operand" "=a")
805 (unspec:HI
806 [(compare:CCFP
807 (match_operand:SF 1 "register_operand" "f")
808 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
809 UNSPEC_FNSTSW))]
810 "TARGET_80387"
811 "* return output_fp_compare (insn, operands, 2, 0);"
812 [(set_attr "type" "fcmp")
813 (set_attr "mode" "SF")])
814
815(define_insn "*cmpfp_2_df"
816 [(set (reg:CCFP 18)
817 (compare:CCFP
818 (match_operand:DF 0 "register_operand" "f")
819 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
820 "TARGET_80387"
821 "* return output_fp_compare (insn, operands, 0, 0);"
822 [(set_attr "type" "fcmp")
823 (set_attr "mode" "DF")])
824
825(define_insn "*cmpfp_2_df_1"
826 [(set (match_operand:HI 0 "register_operand" "=a")
827 (unspec:HI
828 [(compare:CCFP
829 (match_operand:DF 1 "register_operand" "f")
830 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
831 UNSPEC_FNSTSW))]
832 "TARGET_80387"
833 "* return output_fp_compare (insn, operands, 2, 0);"
834 [(set_attr "type" "multi")
835 (set_attr "mode" "DF")])
836
837(define_insn "*cmpfp_2_xf"
838 [(set (reg:CCFP 18)
839 (compare:CCFP
840 (match_operand:XF 0 "register_operand" "f")
841 (match_operand:XF 1 "register_operand" "f")))]
842 "TARGET_80387"
843 "* return output_fp_compare (insn, operands, 0, 0);"
844 [(set_attr "type" "fcmp")
845 (set_attr "mode" "XF")])
846
847(define_insn "*cmpfp_2_xf_1"
848 [(set (match_operand:HI 0 "register_operand" "=a")
849 (unspec:HI
850 [(compare:CCFP
851 (match_operand:XF 1 "register_operand" "f")
852 (match_operand:XF 2 "register_operand" "f"))]
853 UNSPEC_FNSTSW))]
854 "TARGET_80387"
855 "* return output_fp_compare (insn, operands, 2, 0);"
856 [(set_attr "type" "multi")
857 (set_attr "mode" "XF")])
858
859(define_insn "*cmpfp_2u"
860 [(set (reg:CCFPU 18)
861 (compare:CCFPU
862 (match_operand 0 "register_operand" "f")
863 (match_operand 1 "register_operand" "f")))]
864 "TARGET_80387
865 && FLOAT_MODE_P (GET_MODE (operands[0]))
866 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
867 "* return output_fp_compare (insn, operands, 0, 1);"
868 [(set_attr "type" "fcmp")
869 (set (attr "mode")
870 (cond [(match_operand:SF 1 "" "")
871 (const_string "SF")
872 (match_operand:DF 1 "" "")
873 (const_string "DF")
874 ]
875 (const_string "XF")))])
876
877(define_insn "*cmpfp_2u_1"
878 [(set (match_operand:HI 0 "register_operand" "=a")
879 (unspec:HI
880 [(compare:CCFPU
881 (match_operand 1 "register_operand" "f")
882 (match_operand 2 "register_operand" "f"))]
883 UNSPEC_FNSTSW))]
884 "TARGET_80387
885 && FLOAT_MODE_P (GET_MODE (operands[1]))
886 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887 "* return output_fp_compare (insn, operands, 2, 1);"
888 [(set_attr "type" "multi")
889 (set (attr "mode")
890 (cond [(match_operand:SF 1 "" "")
891 (const_string "SF")
892 (match_operand:DF 1 "" "")
893 (const_string "DF")
894 ]
895 (const_string "XF")))])
896
897;; Patterns to match the SImode-in-memory ficom instructions.
898;;
899;; %%% Play games with accepting gp registers, as otherwise we have to
900;; force them to memory during rtl generation, which is no good. We
901;; can get rid of this once we teach reload to do memory input reloads
902;; via pushes.
903
904(define_insn "*ficom_1"
905 [(set (reg:CCFP 18)
906 (compare:CCFP
907 (match_operand 0 "register_operand" "f,f")
908 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
909 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
910 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
911 "#")
912
913;; Split the not-really-implemented gp register case into a
914;; push-op-pop sequence.
915;;
916;; %%% This is most efficient, but am I gonna get in trouble
917;; for separating cc0_setter and cc0_user?
918
919(define_split
920 [(set (reg:CCFP 18)
921 (compare:CCFP
922 (match_operand:SF 0 "register_operand" "")
923 (float (match_operand:SI 1 "register_operand" ""))))]
924 "0 && TARGET_80387 && reload_completed"
925 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
926 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
927 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
928 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
929 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
930 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
931
932;; FP compares, step 2
933;; Move the fpsw to ax.
934
935(define_insn "*x86_fnstsw_1"
936 [(set (match_operand:HI 0 "register_operand" "=a")
937 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
938 "TARGET_80387"
939 "fnstsw\t%0"
940 [(set_attr "length" "2")
941 (set_attr "mode" "SI")
942 (set_attr "unit" "i387")
943 (set_attr "ppro_uops" "few")])
944
945;; FP compares, step 3
946;; Get ax into flags, general case.
947
948(define_insn "x86_sahf_1"
949 [(set (reg:CC 17)
950 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
951 "!TARGET_64BIT"
952 "sahf"
953 [(set_attr "length" "1")
954 (set_attr "athlon_decode" "vector")
955 (set_attr "mode" "SI")
956 (set_attr "ppro_uops" "one")])
957
958;; Pentium Pro can do steps 1 through 3 in one go.
959
960(define_insn "*cmpfp_i"
961 [(set (reg:CCFP 17)
962 (compare:CCFP (match_operand 0 "register_operand" "f")
963 (match_operand 1 "register_operand" "f")))]
964 "TARGET_80387 && TARGET_CMOVE
965 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966 && FLOAT_MODE_P (GET_MODE (operands[0]))
967 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
968 "* return output_fp_compare (insn, operands, 1, 0);"
969 [(set_attr "type" "fcmp")
970 (set (attr "mode")
971 (cond [(match_operand:SF 1 "" "")
972 (const_string "SF")
973 (match_operand:DF 1 "" "")
974 (const_string "DF")
975 ]
976 (const_string "XF")))
977 (set_attr "athlon_decode" "vector")])
978
979(define_insn "*cmpfp_i_sse"
980 [(set (reg:CCFP 17)
981 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
982 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
983 "TARGET_80387
984 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
985 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
986 "* return output_fp_compare (insn, operands, 1, 0);"
987 [(set_attr "type" "fcmp,ssecomi")
988 (set (attr "mode")
989 (if_then_else (match_operand:SF 1 "" "")
990 (const_string "SF")
991 (const_string "DF")))
992 (set_attr "athlon_decode" "vector")])
993
994(define_insn "*cmpfp_i_sse_only"
995 [(set (reg:CCFP 17)
996 (compare:CCFP (match_operand 0 "register_operand" "x")
997 (match_operand 1 "nonimmediate_operand" "xm")))]
998 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1000 "* return output_fp_compare (insn, operands, 1, 0);"
1001 [(set_attr "type" "ssecomi")
1002 (set (attr "mode")
1003 (if_then_else (match_operand:SF 1 "" "")
1004 (const_string "SF")
1005 (const_string "DF")))
1006 (set_attr "athlon_decode" "vector")])
1007
1008(define_insn "*cmpfp_iu"
1009 [(set (reg:CCFPU 17)
1010 (compare:CCFPU (match_operand 0 "register_operand" "f")
1011 (match_operand 1 "register_operand" "f")))]
1012 "TARGET_80387 && TARGET_CMOVE
1013 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1014 && FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 1);"
1017 [(set_attr "type" "fcmp")
1018 (set (attr "mode")
1019 (cond [(match_operand:SF 1 "" "")
1020 (const_string "SF")
1021 (match_operand:DF 1 "" "")
1022 (const_string "DF")
1023 ]
1024 (const_string "XF")))
1025 (set_attr "athlon_decode" "vector")])
1026
1027(define_insn "*cmpfp_iu_sse"
1028 [(set (reg:CCFPU 17)
1029 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1030 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1031 "TARGET_80387
1032 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1033 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034 "* return output_fp_compare (insn, operands, 1, 1);"
1035 [(set_attr "type" "fcmp,ssecomi")
1036 (set (attr "mode")
1037 (if_then_else (match_operand:SF 1 "" "")
1038 (const_string "SF")
1039 (const_string "DF")))
1040 (set_attr "athlon_decode" "vector")])
1041
1042(define_insn "*cmpfp_iu_sse_only"
1043 [(set (reg:CCFPU 17)
1044 (compare:CCFPU (match_operand 0 "register_operand" "x")
1045 (match_operand 1 "nonimmediate_operand" "xm")))]
1046 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048 "* return output_fp_compare (insn, operands, 1, 1);"
1049 [(set_attr "type" "ssecomi")
1050 (set (attr "mode")
1051 (if_then_else (match_operand:SF 1 "" "")
1052 (const_string "SF")
1053 (const_string "DF")))
1054 (set_attr "athlon_decode" "vector")])
1055\f
1056;; Move instructions.
1057
1058;; General case of fullword move.
1059
1060(define_expand "movsi"
1061 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1062 (match_operand:SI 1 "general_operand" ""))]
1063 ""
1064 "ix86_expand_move (SImode, operands); DONE;")
1065
1066;; Push/pop instructions. They are separate since autoinc/dec is not a
1067;; general_operand.
1068;;
1069;; %%% We don't use a post-inc memory reference because x86 is not a
1070;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1071;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1072;; targets without our curiosities, and it is just as easy to represent
1073;; this differently.
1074
1075(define_insn "*pushsi2"
1076 [(set (match_operand:SI 0 "push_operand" "=<")
1077 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1078 "!TARGET_64BIT"
1079 "push{l}\t%1"
1080 [(set_attr "type" "push")
1081 (set_attr "mode" "SI")])
1082
1083;; For 64BIT abi we always round up to 8 bytes.
1084(define_insn "*pushsi2_rex64"
1085 [(set (match_operand:SI 0 "push_operand" "=X")
1086 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1087 "TARGET_64BIT"
1088 "push{q}\t%q1"
1089 [(set_attr "type" "push")
1090 (set_attr "mode" "SI")])
1091
1092(define_insn "*pushsi2_prologue"
1093 [(set (match_operand:SI 0 "push_operand" "=<")
1094 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1095 (clobber (mem:BLK (scratch)))]
1096 "!TARGET_64BIT"
1097 "push{l}\t%1"
1098 [(set_attr "type" "push")
1099 (set_attr "mode" "SI")])
1100
1101(define_insn "*popsi1_epilogue"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103 (mem:SI (reg:SI 7)))
1104 (set (reg:SI 7)
1105 (plus:SI (reg:SI 7) (const_int 4)))
1106 (clobber (mem:BLK (scratch)))]
1107 "!TARGET_64BIT"
1108 "pop{l}\t%0"
1109 [(set_attr "type" "pop")
1110 (set_attr "mode" "SI")])
1111
1112(define_insn "popsi1"
1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114 (mem:SI (reg:SI 7)))
1115 (set (reg:SI 7)
1116 (plus:SI (reg:SI 7) (const_int 4)))]
1117 "!TARGET_64BIT"
1118 "pop{l}\t%0"
1119 [(set_attr "type" "pop")
1120 (set_attr "mode" "SI")])
1121
1122(define_insn "*movsi_xor"
1123 [(set (match_operand:SI 0 "register_operand" "=r")
1124 (match_operand:SI 1 "const0_operand" "i"))
1125 (clobber (reg:CC 17))]
1126 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1127 "xor{l}\t{%0, %0|%0, %0}"
1128 [(set_attr "type" "alu1")
1129 (set_attr "mode" "SI")
1130 (set_attr "length_immediate" "0")])
1131
1132(define_insn "*movsi_or"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (match_operand:SI 1 "immediate_operand" "i"))
1135 (clobber (reg:CC 17))]
1136 "reload_completed
1137 && operands[1] == constm1_rtx
1138 && (TARGET_PENTIUM || optimize_size)"
1139{
1140 operands[1] = constm1_rtx;
1141 return "or{l}\t{%1, %0|%0, %1}";
1142}
1143 [(set_attr "type" "alu1")
1144 (set_attr "mode" "SI")
1145 (set_attr "length_immediate" "1")])
1146
1147(define_insn "*movsi_1"
1148 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1149 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1150 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1151 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1152{
1153 switch (get_attr_type (insn))
1154 {
1155 case TYPE_SSEMOV:
1156 if (get_attr_mode (insn) == MODE_TI)
1157 return "movdqa\t{%1, %0|%0, %1}";
1158 return "movd\t{%1, %0|%0, %1}";
1159
1160 case TYPE_MMXMOV:
1161 if (get_attr_mode (insn) == MODE_DI)
1162 return "movq\t{%1, %0|%0, %1}";
1163 return "movd\t{%1, %0|%0, %1}";
1164
1165 case TYPE_LEA:
1166 return "lea{l}\t{%1, %0|%0, %1}";
1167
1168 default:
1169 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1170 abort();
1171 return "mov{l}\t{%1, %0|%0, %1}";
1172 }
1173}
1174 [(set (attr "type")
1175 (cond [(eq_attr "alternative" "2,3,4")
1176 (const_string "mmxmov")
1177 (eq_attr "alternative" "5,6,7")
1178 (const_string "ssemov")
1179 (and (ne (symbol_ref "flag_pic") (const_int 0))
1180 (match_operand:SI 1 "symbolic_operand" ""))
1181 (const_string "lea")
1182 ]
1183 (const_string "imov")))
1184 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1185
1186(define_insn "*movsi_1_nointernunit"
1187 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1188 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1189 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1190 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1191{
1192 switch (get_attr_type (insn))
1193 {
1194 case TYPE_SSEMOV:
1195 if (get_attr_mode (insn) == MODE_TI)
1196 return "movdqa\t{%1, %0|%0, %1}";
1197 return "movd\t{%1, %0|%0, %1}";
1198
1199 case TYPE_MMXMOV:
1200 if (get_attr_mode (insn) == MODE_DI)
1201 return "movq\t{%1, %0|%0, %1}";
1202 return "movd\t{%1, %0|%0, %1}";
1203
1204 case TYPE_LEA:
1205 return "lea{l}\t{%1, %0|%0, %1}";
1206
1207 default:
1208 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1209 abort();
1210 return "mov{l}\t{%1, %0|%0, %1}";
1211 }
1212}
1213 [(set (attr "type")
1214 (cond [(eq_attr "alternative" "2,3,4")
1215 (const_string "mmxmov")
1216 (eq_attr "alternative" "5,6,7")
1217 (const_string "ssemov")
1218 (and (ne (symbol_ref "flag_pic") (const_int 0))
1219 (match_operand:SI 1 "symbolic_operand" ""))
1220 (const_string "lea")
1221 ]
1222 (const_string "imov")))
1223 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1224
1225;; Stores and loads of ax to arbitrary constant address.
1226;; We fake an second form of instruction to force reload to load address
1227;; into register when rax is not available
1228(define_insn "*movabssi_1_rex64"
1229 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1230 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1231 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1232 "@
1233 movabs{l}\t{%1, %P0|%P0, %1}
1234 mov{l}\t{%1, %a0|%a0, %1}"
1235 [(set_attr "type" "imov")
1236 (set_attr "modrm" "0,*")
1237 (set_attr "length_address" "8,0")
1238 (set_attr "length_immediate" "0,*")
1239 (set_attr "memory" "store")
1240 (set_attr "mode" "SI")])
1241
1242(define_insn "*movabssi_2_rex64"
1243 [(set (match_operand:SI 0 "register_operand" "=a,r")
1244 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1245 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1246 "@
1247 movabs{l}\t{%P1, %0|%0, %P1}
1248 mov{l}\t{%a1, %0|%0, %a1}"
1249 [(set_attr "type" "imov")
1250 (set_attr "modrm" "0,*")
1251 (set_attr "length_address" "8,0")
1252 (set_attr "length_immediate" "0")
1253 (set_attr "memory" "load")
1254 (set_attr "mode" "SI")])
1255
1256(define_insn "*swapsi"
1257 [(set (match_operand:SI 0 "register_operand" "+r")
1258 (match_operand:SI 1 "register_operand" "+r"))
1259 (set (match_dup 1)
1260 (match_dup 0))]
1261 ""
1262 "xchg{l}\t%1, %0"
1263 [(set_attr "type" "imov")
1c1138ce 1264 (set_attr "mode" "SI")
003757ed
MD
1265 (set_attr "pent_pair" "np")
1266 (set_attr "athlon_decode" "vector")
003757ed
MD
1267 (set_attr "ppro_uops" "few")])
1268
1269(define_expand "movhi"
1270 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1271 (match_operand:HI 1 "general_operand" ""))]
1272 ""
1273 "ix86_expand_move (HImode, operands); DONE;")
1274
1275(define_insn "*pushhi2"
1276 [(set (match_operand:HI 0 "push_operand" "=<,<")
1277 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1278 "!TARGET_64BIT"
1279 "@
1280 push{w}\t{|WORD PTR }%1
1281 push{w}\t%1"
1282 [(set_attr "type" "push")
1283 (set_attr "mode" "HI")])
1284
1285;; For 64BIT abi we always round up to 8 bytes.
1286(define_insn "*pushhi2_rex64"
1287 [(set (match_operand:HI 0 "push_operand" "=X")
1288 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1289 "TARGET_64BIT"
1290 "push{q}\t%q1"
1291 [(set_attr "type" "push")
1292 (set_attr "mode" "QI")])
1293
1294(define_insn "*movhi_1"
1295 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1296 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1297 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1298{
1299 switch (get_attr_type (insn))
1300 {
1301 case TYPE_IMOVX:
1302 /* movzwl is faster than movw on p2 due to partial word stalls,
1303 though not as fast as an aligned movl. */
1304 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1305 default:
1306 if (get_attr_mode (insn) == MODE_SI)
1307 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1308 else
1309 return "mov{w}\t{%1, %0|%0, %1}";
1310 }
1311}
1312 [(set (attr "type")
1313 (cond [(and (eq_attr "alternative" "0")
1314 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315 (const_int 0))
1316 (eq (symbol_ref "TARGET_HIMODE_MATH")
1317 (const_int 0))))
1318 (const_string "imov")
1319 (and (eq_attr "alternative" "1,2")
1320 (match_operand:HI 1 "aligned_operand" ""))
1321 (const_string "imov")
1322 (and (ne (symbol_ref "TARGET_MOVX")
1323 (const_int 0))
1324 (eq_attr "alternative" "0,2"))
1325 (const_string "imovx")
1326 ]
1327 (const_string "imov")))
1328 (set (attr "mode")
1329 (cond [(eq_attr "type" "imovx")
1330 (const_string "SI")
1331 (and (eq_attr "alternative" "1,2")
1332 (match_operand:HI 1 "aligned_operand" ""))
1333 (const_string "SI")
1334 (and (eq_attr "alternative" "0")
1335 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1336 (const_int 0))
1337 (eq (symbol_ref "TARGET_HIMODE_MATH")
1338 (const_int 0))))
1339 (const_string "SI")
1340 ]
1341 (const_string "HI")))])
1342
1343;; Stores and loads of ax to arbitrary constant address.
1344;; We fake an second form of instruction to force reload to load address
1345;; into register when rax is not available
1346(define_insn "*movabshi_1_rex64"
1347 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1348 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1349 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1350 "@
1351 movabs{w}\t{%1, %P0|%P0, %1}
1352 mov{w}\t{%1, %a0|%a0, %1}"
1353 [(set_attr "type" "imov")
1354 (set_attr "modrm" "0,*")
1355 (set_attr "length_address" "8,0")
1356 (set_attr "length_immediate" "0,*")
1357 (set_attr "memory" "store")
1358 (set_attr "mode" "HI")])
1359
1360(define_insn "*movabshi_2_rex64"
1361 [(set (match_operand:HI 0 "register_operand" "=a,r")
1362 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1363 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1364 "@
1365 movabs{w}\t{%P1, %0|%0, %P1}
1366 mov{w}\t{%a1, %0|%0, %a1}"
1367 [(set_attr "type" "imov")
1368 (set_attr "modrm" "0,*")
1369 (set_attr "length_address" "8,0")
1370 (set_attr "length_immediate" "0")
1371 (set_attr "memory" "load")
1372 (set_attr "mode" "HI")])
1373
1374(define_insn "*swaphi_1"
1375 [(set (match_operand:HI 0 "register_operand" "+r")
1376 (match_operand:HI 1 "register_operand" "+r"))
1377 (set (match_dup 1)
1378 (match_dup 0))]
1c1138ce
JS
1379 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1380 "xchg{l}\t%k1, %k0"
003757ed 1381 [(set_attr "type" "imov")
1c1138ce 1382 (set_attr "mode" "SI")
003757ed 1383 (set_attr "pent_pair" "np")
1c1138ce 1384 (set_attr "athlon_decode" "vector")
003757ed
MD
1385 (set_attr "ppro_uops" "few")])
1386
1387(define_insn "*swaphi_2"
1388 [(set (match_operand:HI 0 "register_operand" "+r")
1389 (match_operand:HI 1 "register_operand" "+r"))
1390 (set (match_dup 1)
1391 (match_dup 0))]
1c1138ce
JS
1392 "TARGET_PARTIAL_REG_STALL"
1393 "xchg{w}\t%1, %0"
003757ed 1394 [(set_attr "type" "imov")
1c1138ce 1395 (set_attr "mode" "HI")
003757ed 1396 (set_attr "pent_pair" "np")
1c1138ce 1397 (set_attr "athlon_decode" "vector")
003757ed
MD
1398 (set_attr "ppro_uops" "few")])
1399
1400(define_expand "movstricthi"
1401 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1402 (match_operand:HI 1 "general_operand" ""))]
1403 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1404{
1405 /* Don't generate memory->memory moves, go through a register */
1406 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1407 operands[1] = force_reg (HImode, operands[1]);
1408})
1409
1410(define_insn "*movstricthi_1"
1411 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1412 (match_operand:HI 1 "general_operand" "rn,m"))]
1413 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1414 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1415 "mov{w}\t{%1, %0|%0, %1}"
1416 [(set_attr "type" "imov")
1417 (set_attr "mode" "HI")])
1418
1419(define_insn "*movstricthi_xor"
1420 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1421 (match_operand:HI 1 "const0_operand" "i"))
1422 (clobber (reg:CC 17))]
1423 "reload_completed
1424 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1425 "xor{w}\t{%0, %0|%0, %0}"
1426 [(set_attr "type" "alu1")
1427 (set_attr "mode" "HI")
1428 (set_attr "length_immediate" "0")])
1429
1430(define_expand "movqi"
1431 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1432 (match_operand:QI 1 "general_operand" ""))]
1433 ""
1434 "ix86_expand_move (QImode, operands); DONE;")
1435
1436;; emit_push_insn when it calls move_by_pieces requires an insn to
1437;; "push a byte". But actually we use pushw, which has the effect
1438;; of rounding the amount pushed up to a halfword.
1439
1440(define_insn "*pushqi2"
1441 [(set (match_operand:QI 0 "push_operand" "=X,X")
1442 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1443 "!TARGET_64BIT"
1444 "@
1445 push{w}\t{|word ptr }%1
1446 push{w}\t%w1"
1447 [(set_attr "type" "push")
1448 (set_attr "mode" "HI")])
1449
1450;; For 64BIT abi we always round up to 8 bytes.
1451(define_insn "*pushqi2_rex64"
1452 [(set (match_operand:QI 0 "push_operand" "=X")
1453 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1454 "TARGET_64BIT"
1455 "push{q}\t%q1"
1456 [(set_attr "type" "push")
1457 (set_attr "mode" "QI")])
1458
1459;; Situation is quite tricky about when to choose full sized (SImode) move
1460;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1461;; partial register dependency machines (such as AMD Athlon), where QImode
1462;; moves issue extra dependency and for partial register stalls machines
1463;; that don't use QImode patterns (and QImode move cause stall on the next
1464;; instruction).
1465;;
1466;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467;; register stall machines with, where we use QImode instructions, since
1468;; partial register stall can be caused there. Then we use movzx.
1469(define_insn "*movqi_1"
1470 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1472 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473{
1474 switch (get_attr_type (insn))
1475 {
1476 case TYPE_IMOVX:
1477 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1478 abort ();
1479 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480 default:
1481 if (get_attr_mode (insn) == MODE_SI)
1482 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483 else
1484 return "mov{b}\t{%1, %0|%0, %1}";
1485 }
1486}
1487 [(set (attr "type")
1488 (cond [(and (eq_attr "alternative" "3")
1489 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1490 (const_int 0))
1491 (eq (symbol_ref "TARGET_QIMODE_MATH")
1492 (const_int 0))))
1493 (const_string "imov")
1494 (eq_attr "alternative" "3,5")
1495 (const_string "imovx")
1496 (and (ne (symbol_ref "TARGET_MOVX")
1497 (const_int 0))
1498 (eq_attr "alternative" "2"))
1499 (const_string "imovx")
1500 ]
1501 (const_string "imov")))
1502 (set (attr "mode")
1503 (cond [(eq_attr "alternative" "3,4,5")
1504 (const_string "SI")
1505 (eq_attr "alternative" "6")
1506 (const_string "QI")
1507 (eq_attr "type" "imovx")
1508 (const_string "SI")
1509 (and (eq_attr "type" "imov")
1510 (and (eq_attr "alternative" "0,1,2")
1511 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1512 (const_int 0))))
1513 (const_string "SI")
1514 ;; Avoid partial register stalls when not using QImode arithmetic
1515 (and (eq_attr "type" "imov")
1516 (and (eq_attr "alternative" "0,1,2")
1517 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518 (const_int 0))
1519 (eq (symbol_ref "TARGET_QIMODE_MATH")
1520 (const_int 0)))))
1521 (const_string "SI")
1522 ]
1523 (const_string "QI")))])
1524
1525(define_expand "reload_outqi"
1526 [(parallel [(match_operand:QI 0 "" "=m")
1527 (match_operand:QI 1 "register_operand" "r")
1528 (match_operand:QI 2 "register_operand" "=&q")])]
1529 ""
1530{
1531 rtx op0, op1, op2;
1532 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1533
1534 if (reg_overlap_mentioned_p (op2, op0))
1535 abort ();
1536 if (! q_regs_operand (op1, QImode))
1537 {
1538 emit_insn (gen_movqi (op2, op1));
1539 op1 = op2;
1540 }
1541 emit_insn (gen_movqi (op0, op1));
1542 DONE;
1543})
1544
1c1138ce 1545(define_insn "*swapqi_1"
003757ed
MD
1546 [(set (match_operand:QI 0 "register_operand" "+r")
1547 (match_operand:QI 1 "register_operand" "+r"))
1548 (set (match_dup 1)
1549 (match_dup 0))]
1c1138ce
JS
1550 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1551 "xchg{l}\t%k1, %k0"
003757ed 1552 [(set_attr "type" "imov")
1c1138ce 1553 (set_attr "mode" "SI")
003757ed 1554 (set_attr "pent_pair" "np")
1c1138ce
JS
1555 (set_attr "athlon_decode" "vector")
1556 (set_attr "ppro_uops" "few")])
1557
1558(define_insn "*swapqi_2"
1559 [(set (match_operand:QI 0 "register_operand" "+q")
1560 (match_operand:QI 1 "register_operand" "+q"))
1561 (set (match_dup 1)
1562 (match_dup 0))]
1563 "TARGET_PARTIAL_REG_STALL"
1564 "xchg{b}\t%1, %0"
1565 [(set_attr "type" "imov")
003757ed 1566 (set_attr "mode" "QI")
1c1138ce
JS
1567 (set_attr "pent_pair" "np")
1568 (set_attr "athlon_decode" "vector")
003757ed
MD
1569 (set_attr "ppro_uops" "few")])
1570
1571(define_expand "movstrictqi"
1572 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1573 (match_operand:QI 1 "general_operand" ""))]
1574 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1575{
1576 /* Don't generate memory->memory moves, go through a register. */
1577 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1578 operands[1] = force_reg (QImode, operands[1]);
1579})
1580
1581(define_insn "*movstrictqi_1"
1582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1583 (match_operand:QI 1 "general_operand" "*qn,m"))]
1584 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1585 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1586 "mov{b}\t{%1, %0|%0, %1}"
1587 [(set_attr "type" "imov")
1588 (set_attr "mode" "QI")])
1589
1590(define_insn "*movstrictqi_xor"
1591 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1592 (match_operand:QI 1 "const0_operand" "i"))
1593 (clobber (reg:CC 17))]
1594 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1595 "xor{b}\t{%0, %0|%0, %0}"
1596 [(set_attr "type" "alu1")
1597 (set_attr "mode" "QI")
1598 (set_attr "length_immediate" "0")])
1599
1600(define_insn "*movsi_extv_1"
1601 [(set (match_operand:SI 0 "register_operand" "=R")
1602 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1603 (const_int 8)
1604 (const_int 8)))]
1605 ""
1606 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1607 [(set_attr "type" "imovx")
1608 (set_attr "mode" "SI")])
1609
1610(define_insn "*movhi_extv_1"
1611 [(set (match_operand:HI 0 "register_operand" "=R")
1612 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1613 (const_int 8)
1614 (const_int 8)))]
1615 ""
1616 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1617 [(set_attr "type" "imovx")
1618 (set_attr "mode" "SI")])
1619
1620(define_insn "*movqi_extv_1"
1621 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1622 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1623 (const_int 8)
1624 (const_int 8)))]
1625 "!TARGET_64BIT"
1626{
1627 switch (get_attr_type (insn))
1628 {
1629 case TYPE_IMOVX:
1630 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1631 default:
1632 return "mov{b}\t{%h1, %0|%0, %h1}";
1633 }
1634}
1635 [(set (attr "type")
1636 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1637 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1638 (ne (symbol_ref "TARGET_MOVX")
1639 (const_int 0))))
1640 (const_string "imovx")
1641 (const_string "imov")))
1642 (set (attr "mode")
1643 (if_then_else (eq_attr "type" "imovx")
1644 (const_string "SI")
1645 (const_string "QI")))])
1646
1647(define_insn "*movqi_extv_1_rex64"
1648 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1649 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1650 (const_int 8)
1651 (const_int 8)))]
1652 "TARGET_64BIT"
1653{
1654 switch (get_attr_type (insn))
1655 {
1656 case TYPE_IMOVX:
1657 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1658 default:
1659 return "mov{b}\t{%h1, %0|%0, %h1}";
1660 }
1661}
1662 [(set (attr "type")
1663 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1664 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1665 (ne (symbol_ref "TARGET_MOVX")
1666 (const_int 0))))
1667 (const_string "imovx")
1668 (const_string "imov")))
1669 (set (attr "mode")
1670 (if_then_else (eq_attr "type" "imovx")
1671 (const_string "SI")
1672 (const_string "QI")))])
1673
1674;; Stores and loads of ax to arbitrary constant address.
1675;; We fake an second form of instruction to force reload to load address
1676;; into register when rax is not available
1677(define_insn "*movabsqi_1_rex64"
1678 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1679 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1680 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1681 "@
1682 movabs{b}\t{%1, %P0|%P0, %1}
1683 mov{b}\t{%1, %a0|%a0, %1}"
1684 [(set_attr "type" "imov")
1685 (set_attr "modrm" "0,*")
1686 (set_attr "length_address" "8,0")
1687 (set_attr "length_immediate" "0,*")
1688 (set_attr "memory" "store")
1689 (set_attr "mode" "QI")])
1690
1691(define_insn "*movabsqi_2_rex64"
1692 [(set (match_operand:QI 0 "register_operand" "=a,r")
1693 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1694 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1695 "@
1696 movabs{b}\t{%P1, %0|%0, %P1}
1697 mov{b}\t{%a1, %0|%0, %a1}"
1698 [(set_attr "type" "imov")
1699 (set_attr "modrm" "0,*")
1700 (set_attr "length_address" "8,0")
1701 (set_attr "length_immediate" "0")
1702 (set_attr "memory" "load")
1703 (set_attr "mode" "QI")])
1704
1705(define_insn "*movsi_extzv_1"
1706 [(set (match_operand:SI 0 "register_operand" "=R")
1707 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1708 (const_int 8)
1709 (const_int 8)))]
1710 ""
1711 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1712 [(set_attr "type" "imovx")
1713 (set_attr "mode" "SI")])
1714
1715(define_insn "*movqi_extzv_2"
1716 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1717 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1718 (const_int 8)
1719 (const_int 8)) 0))]
1720 "!TARGET_64BIT"
1721{
1722 switch (get_attr_type (insn))
1723 {
1724 case TYPE_IMOVX:
1725 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1726 default:
1727 return "mov{b}\t{%h1, %0|%0, %h1}";
1728 }
1729}
1730 [(set (attr "type")
1731 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1732 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1733 (ne (symbol_ref "TARGET_MOVX")
1734 (const_int 0))))
1735 (const_string "imovx")
1736 (const_string "imov")))
1737 (set (attr "mode")
1738 (if_then_else (eq_attr "type" "imovx")
1739 (const_string "SI")
1740 (const_string "QI")))])
1741
1742(define_insn "*movqi_extzv_2_rex64"
1743 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1744 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1745 (const_int 8)
1746 (const_int 8)) 0))]
1747 "TARGET_64BIT"
1748{
1749 switch (get_attr_type (insn))
1750 {
1751 case TYPE_IMOVX:
1752 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1753 default:
1754 return "mov{b}\t{%h1, %0|%0, %h1}";
1755 }
1756}
1757 [(set (attr "type")
1758 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1759 (ne (symbol_ref "TARGET_MOVX")
1760 (const_int 0)))
1761 (const_string "imovx")
1762 (const_string "imov")))
1763 (set (attr "mode")
1764 (if_then_else (eq_attr "type" "imovx")
1765 (const_string "SI")
1766 (const_string "QI")))])
1767
1768(define_insn "movsi_insv_1"
1769 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1770 (const_int 8)
1771 (const_int 8))
1772 (match_operand:SI 1 "general_operand" "Qmn"))]
1773 "!TARGET_64BIT"
1774 "mov{b}\t{%b1, %h0|%h0, %b1}"
1775 [(set_attr "type" "imov")
1776 (set_attr "mode" "QI")])
1777
1778(define_insn "movdi_insv_1_rex64"
1779 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1780 (const_int 8)
1781 (const_int 8))
1782 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1783 "TARGET_64BIT"
1784 "mov{b}\t{%b1, %h0|%h0, %b1}"
1785 [(set_attr "type" "imov")
1786 (set_attr "mode" "QI")])
1787
1788(define_insn "*movqi_insv_2"
1789 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1790 (const_int 8)
1791 (const_int 8))
1792 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1793 (const_int 8)))]
1794 ""
1795 "mov{b}\t{%h1, %h0|%h0, %h1}"
1796 [(set_attr "type" "imov")
1797 (set_attr "mode" "QI")])
1798
1799(define_expand "movdi"
1800 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1801 (match_operand:DI 1 "general_operand" ""))]
1802 ""
1803 "ix86_expand_move (DImode, operands); DONE;")
1804
1805(define_insn "*pushdi"
1806 [(set (match_operand:DI 0 "push_operand" "=<")
1807 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1808 "!TARGET_64BIT"
1809 "#")
1810
1811(define_insn "pushdi2_rex64"
1812 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1813 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1814 "TARGET_64BIT"
1815 "@
1816 push{q}\t%1
1817 #"
1818 [(set_attr "type" "push,multi")
1819 (set_attr "mode" "DI")])
1820
1821;; Convert impossible pushes of immediate to existing instructions.
1822;; First try to get scratch register and go through it. In case this
1823;; fails, push sign extended lower part first and then overwrite
1824;; upper part by 32bit move.
1825(define_peephole2
1826 [(match_scratch:DI 2 "r")
1827 (set (match_operand:DI 0 "push_operand" "")
1828 (match_operand:DI 1 "immediate_operand" ""))]
1829 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1830 && !x86_64_immediate_operand (operands[1], DImode)"
1831 [(set (match_dup 2) (match_dup 1))
1832 (set (match_dup 0) (match_dup 2))]
1833 "")
1834
1835;; We need to define this as both peepholer and splitter for case
1836;; peephole2 pass is not run.
1837(define_peephole2
1838 [(set (match_operand:DI 0 "push_operand" "")
1839 (match_operand:DI 1 "immediate_operand" ""))]
1840 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1842 [(set (match_dup 0) (match_dup 1))
1843 (set (match_dup 2) (match_dup 3))]
1844 "split_di (operands + 1, 1, operands + 2, operands + 3);
1845 operands[1] = gen_lowpart (DImode, operands[2]);
1846 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1847 GEN_INT (4)));
1848 ")
1849
1850(define_split
1851 [(set (match_operand:DI 0 "push_operand" "")
1852 (match_operand:DI 1 "immediate_operand" ""))]
1378ea41
SS
1853 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1854 ? flow2_completed : reload_completed)
003757ed
MD
1855 && !symbolic_operand (operands[1], DImode)
1856 && !x86_64_immediate_operand (operands[1], DImode)"
1857 [(set (match_dup 0) (match_dup 1))
1858 (set (match_dup 2) (match_dup 3))]
1859 "split_di (operands + 1, 1, operands + 2, operands + 3);
1860 operands[1] = gen_lowpart (DImode, operands[2]);
1861 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1862 GEN_INT (4)));
1863 ")
1864
1865(define_insn "*pushdi2_prologue_rex64"
1866 [(set (match_operand:DI 0 "push_operand" "=<")
1867 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1868 (clobber (mem:BLK (scratch)))]
1869 "TARGET_64BIT"
1870 "push{q}\t%1"
1871 [(set_attr "type" "push")
1872 (set_attr "mode" "DI")])
1873
1874(define_insn "*popdi1_epilogue_rex64"
1875 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1876 (mem:DI (reg:DI 7)))
1877 (set (reg:DI 7)
1878 (plus:DI (reg:DI 7) (const_int 8)))
1879 (clobber (mem:BLK (scratch)))]
1880 "TARGET_64BIT"
1881 "pop{q}\t%0"
1882 [(set_attr "type" "pop")
1883 (set_attr "mode" "DI")])
1884
1885(define_insn "popdi1"
1886 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1887 (mem:DI (reg:DI 7)))
1888 (set (reg:DI 7)
1889 (plus:DI (reg:DI 7) (const_int 8)))]
1890 "TARGET_64BIT"
1891 "pop{q}\t%0"
1892 [(set_attr "type" "pop")
1893 (set_attr "mode" "DI")])
1894
1895(define_insn "*movdi_xor_rex64"
1896 [(set (match_operand:DI 0 "register_operand" "=r")
1897 (match_operand:DI 1 "const0_operand" "i"))
1898 (clobber (reg:CC 17))]
1899 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1900 && reload_completed"
1901 "xor{l}\t{%k0, %k0|%k0, %k0}"
1902 [(set_attr "type" "alu1")
1903 (set_attr "mode" "SI")
1904 (set_attr "length_immediate" "0")])
1905
1906(define_insn "*movdi_or_rex64"
1907 [(set (match_operand:DI 0 "register_operand" "=r")
1908 (match_operand:DI 1 "const_int_operand" "i"))
1909 (clobber (reg:CC 17))]
1910 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1911 && reload_completed
1912 && operands[1] == constm1_rtx"
1913{
1914 operands[1] = constm1_rtx;
1915 return "or{q}\t{%1, %0|%0, %1}";
1916}
1917 [(set_attr "type" "alu1")
1918 (set_attr "mode" "DI")
1919 (set_attr "length_immediate" "1")])
1920
1921(define_insn "*movdi_2"
1922 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1923 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1924 "!TARGET_64BIT
1925 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1926 "@
1927 #
1928 #
1929 movq\t{%1, %0|%0, %1}
1930 movq\t{%1, %0|%0, %1}
1931 movq\t{%1, %0|%0, %1}
1932 movdqa\t{%1, %0|%0, %1}
1933 movq\t{%1, %0|%0, %1}"
1934 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1935 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1936
1937(define_split
1938 [(set (match_operand:DI 0 "push_operand" "")
1939 (match_operand:DI 1 "general_operand" ""))]
1940 "!TARGET_64BIT && reload_completed
1941 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1942 [(const_int 0)]
1943 "ix86_split_long_move (operands); DONE;")
1944
1945;; %%% This multiword shite has got to go.
1946(define_split
1947 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1948 (match_operand:DI 1 "general_operand" ""))]
1949 "!TARGET_64BIT && reload_completed
1950 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1951 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1952 [(const_int 0)]
1953 "ix86_split_long_move (operands); DONE;")
1954
1955(define_insn "*movdi_1_rex64"
1956 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1957 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1958 "TARGET_64BIT
1959 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1960 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1961{
1962 switch (get_attr_type (insn))
1963 {
1964 case TYPE_SSEMOV:
1965 if (get_attr_mode (insn) == MODE_TI)
1966 return "movdqa\t{%1, %0|%0, %1}";
1967 /* FALLTHRU */
1968 case TYPE_MMXMOV:
1969 /* Moves from and into integer register is done using movd opcode with
1970 REX prefix. */
1971 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1972 return "movd\t{%1, %0|%0, %1}";
1973 return "movq\t{%1, %0|%0, %1}";
1974 case TYPE_MULTI:
1975 return "#";
1976 case TYPE_LEA:
1977 return "lea{q}\t{%a1, %0|%0, %a1}";
1978 default:
1979 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1980 abort ();
1981 if (get_attr_mode (insn) == MODE_SI)
1982 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1983 else if (which_alternative == 2)
1984 return "movabs{q}\t{%1, %0|%0, %1}";
1985 else
1986 return "mov{q}\t{%1, %0|%0, %1}";
1987 }
1988}
1989 [(set (attr "type")
1990 (cond [(eq_attr "alternative" "5,6,7")
1991 (const_string "mmxmov")
1992 (eq_attr "alternative" "8,9,10")
1993 (const_string "ssemov")
1994 (eq_attr "alternative" "4")
1995 (const_string "multi")
1996 (and (ne (symbol_ref "flag_pic") (const_int 0))
1997 (match_operand:DI 1 "symbolic_operand" ""))
1998 (const_string "lea")
1999 ]
2000 (const_string "imov")))
2001 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2002 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2003 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2004
2005(define_insn "*movdi_1_rex64_nointerunit"
2006 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2007 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2008 "TARGET_64BIT
2009 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2010 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2011{
2012 switch (get_attr_type (insn))
2013 {
2014 case TYPE_SSEMOV:
2015 if (get_attr_mode (insn) == MODE_TI)
2016 return "movdqa\t{%1, %0|%0, %1}";
2017 /* FALLTHRU */
2018 case TYPE_MMXMOV:
2019 return "movq\t{%1, %0|%0, %1}";
2020 case TYPE_MULTI:
2021 return "#";
2022 case TYPE_LEA:
2023 return "lea{q}\t{%a1, %0|%0, %a1}";
2024 default:
2025 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2026 abort ();
2027 if (get_attr_mode (insn) == MODE_SI)
2028 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2029 else if (which_alternative == 2)
2030 return "movabs{q}\t{%1, %0|%0, %1}";
2031 else
2032 return "mov{q}\t{%1, %0|%0, %1}";
2033 }
2034}
2035 [(set (attr "type")
2036 (cond [(eq_attr "alternative" "5,6,7")
2037 (const_string "mmxmov")
2038 (eq_attr "alternative" "8,9,10")
2039 (const_string "ssemov")
2040 (eq_attr "alternative" "4")
2041 (const_string "multi")
2042 (and (ne (symbol_ref "flag_pic") (const_int 0))
2043 (match_operand:DI 1 "symbolic_operand" ""))
2044 (const_string "lea")
2045 ]
2046 (const_string "imov")))
2047 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2048 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2049 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2050
2051;; Stores and loads of ax to arbitrary constant address.
2052;; We fake an second form of instruction to force reload to load address
2053;; into register when rax is not available
2054(define_insn "*movabsdi_1_rex64"
2055 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2056 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2057 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2058 "@
2059 movabs{q}\t{%1, %P0|%P0, %1}
2060 mov{q}\t{%1, %a0|%a0, %1}"
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" "store")
2066 (set_attr "mode" "DI")])
2067
2068(define_insn "*movabsdi_2_rex64"
2069 [(set (match_operand:DI 0 "register_operand" "=a,r")
2070 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2071 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2072 "@
2073 movabs{q}\t{%P1, %0|%0, %P1}
2074 mov{q}\t{%a1, %0|%0, %a1}"
2075 [(set_attr "type" "imov")
2076 (set_attr "modrm" "0,*")
2077 (set_attr "length_address" "8,0")
2078 (set_attr "length_immediate" "0")
2079 (set_attr "memory" "load")
2080 (set_attr "mode" "DI")])
2081
2082;; Convert impossible stores of immediate to existing instructions.
2083;; First try to get scratch register and go through it. In case this
2084;; fails, move by 32bit parts.
2085(define_peephole2
2086 [(match_scratch:DI 2 "r")
2087 (set (match_operand:DI 0 "memory_operand" "")
2088 (match_operand:DI 1 "immediate_operand" ""))]
2089 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090 && !x86_64_immediate_operand (operands[1], DImode)"
2091 [(set (match_dup 2) (match_dup 1))
2092 (set (match_dup 0) (match_dup 2))]
2093 "")
2094
2095;; We need to define this as both peepholer and splitter for case
2096;; peephole2 pass is not run.
2097(define_peephole2
2098 [(set (match_operand:DI 0 "memory_operand" "")
2099 (match_operand:DI 1 "immediate_operand" ""))]
2100 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2101 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2102 [(set (match_dup 2) (match_dup 3))
2103 (set (match_dup 4) (match_dup 5))]
2104 "split_di (operands, 2, operands + 2, operands + 4);")
2105
2106(define_split
2107 [(set (match_operand:DI 0 "memory_operand" "")
2108 (match_operand:DI 1 "immediate_operand" ""))]
1378ea41
SS
2109 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2110 ? flow2_completed : reload_completed)
003757ed
MD
2111 && !symbolic_operand (operands[1], DImode)
2112 && !x86_64_immediate_operand (operands[1], DImode)"
2113 [(set (match_dup 2) (match_dup 3))
2114 (set (match_dup 4) (match_dup 5))]
2115 "split_di (operands, 2, operands + 2, operands + 4);")
2116
2117(define_insn "*swapdi_rex64"
2118 [(set (match_operand:DI 0 "register_operand" "+r")
2119 (match_operand:DI 1 "register_operand" "+r"))
2120 (set (match_dup 1)
2121 (match_dup 0))]
2122 "TARGET_64BIT"
2123 "xchg{q}\t%1, %0"
2124 [(set_attr "type" "imov")
1c1138ce 2125 (set_attr "mode" "DI")
003757ed
MD
2126 (set_attr "pent_pair" "np")
2127 (set_attr "athlon_decode" "vector")
003757ed
MD
2128 (set_attr "ppro_uops" "few")])
2129
003757ed
MD
2130(define_expand "movsf"
2131 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2132 (match_operand:SF 1 "general_operand" ""))]
2133 ""
2134 "ix86_expand_move (SFmode, operands); DONE;")
2135
2136(define_insn "*pushsf"
2137 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2138 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2139 "!TARGET_64BIT"
2140{
2141 switch (which_alternative)
2142 {
2143 case 1:
2144 return "push{l}\t%1";
2145
2146 default:
2147 /* This insn should be already split before reg-stack. */
2148 abort ();
2149 }
2150}
2151 [(set_attr "type" "multi,push,multi")
2152 (set_attr "mode" "SF,SI,SF")])
2153
2154(define_insn "*pushsf_rex64"
2155 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2156 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2157 "TARGET_64BIT"
2158{
2159 switch (which_alternative)
2160 {
2161 case 1:
2162 return "push{q}\t%q1";
2163
2164 default:
2165 /* This insn should be already split before reg-stack. */
2166 abort ();
2167 }
2168}
2169 [(set_attr "type" "multi,push,multi")
2170 (set_attr "mode" "SF,DI,SF")])
2171
2172(define_split
2173 [(set (match_operand:SF 0 "push_operand" "")
2174 (match_operand:SF 1 "memory_operand" ""))]
2175 "reload_completed
2176 && GET_CODE (operands[1]) == MEM
1378ea41 2177 && constant_pool_reference_p (operands[1])"
003757ed
MD
2178 [(set (match_dup 0)
2179 (match_dup 1))]
1378ea41 2180 "operands[1] = avoid_constant_pool_reference (operands[1]);")
003757ed
MD
2181
2182
2183;; %%% Kill this when call knows how to work this out.
2184(define_split
2185 [(set (match_operand:SF 0 "push_operand" "")
2186 (match_operand:SF 1 "any_fp_register_operand" ""))]
2187 "!TARGET_64BIT"
2188 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2189 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2190
2191(define_split
2192 [(set (match_operand:SF 0 "push_operand" "")
2193 (match_operand:SF 1 "any_fp_register_operand" ""))]
2194 "TARGET_64BIT"
2195 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2196 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2197
2198(define_insn "*movsf_1"
2199 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2200 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2201 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2202 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2203 && (reload_in_progress || reload_completed
2204 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2205 || GET_CODE (operands[1]) != CONST_DOUBLE
2206 || memory_operand (operands[0], SFmode))"
2207{
2208 switch (which_alternative)
2209 {
2210 case 0:
2211 if (REG_P (operands[1])
2212 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2213 return "fstp\t%y0";
2214 else if (STACK_TOP_P (operands[0]))
2215 return "fld%z1\t%y1";
2216 else
2217 return "fst\t%y0";
2218
2219 case 1:
2220 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2221 return "fstp%z0\t%y0";
2222 else
2223 return "fst%z0\t%y0";
2224
2225 case 2:
2226 return standard_80387_constant_opcode (operands[1]);
2227
2228 case 3:
2229 case 4:
2230 return "mov{l}\t{%1, %0|%0, %1}";
2231 case 5:
2232 if (get_attr_mode (insn) == MODE_TI)
2233 return "pxor\t%0, %0";
2234 else
2235 return "xorps\t%0, %0";
2236 case 6:
2237 if (get_attr_mode (insn) == MODE_V4SF)
2238 return "movaps\t{%1, %0|%0, %1}";
2239 else
2240 return "movss\t{%1, %0|%0, %1}";
2241 case 7:
2242 case 8:
2243 return "movss\t{%1, %0|%0, %1}";
2244
2245 case 9:
2246 case 10:
2247 return "movd\t{%1, %0|%0, %1}";
2248
2249 case 11:
2250 return "movq\t{%1, %0|%0, %1}";
2251
2252 default:
2253 abort();
2254 }
2255}
2256 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2257 (set (attr "mode")
2258 (cond [(eq_attr "alternative" "3,4,9,10")
2259 (const_string "SI")
2260 (eq_attr "alternative" "5")
2261 (if_then_else
2262 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2263 (const_int 0))
2264 (ne (symbol_ref "TARGET_SSE2")
2265 (const_int 0)))
2266 (eq (symbol_ref "optimize_size")
2267 (const_int 0)))
2268 (const_string "TI")
2269 (const_string "V4SF"))
2270 /* For architectures resolving dependencies on
2271 whole SSE registers use APS move to break dependency
2272 chains, otherwise use short move to avoid extra work.
2273
2274 Do the same for architectures resolving dependencies on
2275 the parts. While in DF mode it is better to always handle
2276 just register parts, the SF mode is different due to lack
2277 of instructions to load just part of the register. It is
2278 better to maintain the whole registers in single format
2279 to avoid problems on using packed logical operations. */
2280 (eq_attr "alternative" "6")
2281 (if_then_else
2282 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2283 (const_int 0))
2284 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2285 (const_int 0)))
2286 (const_string "V4SF")
2287 (const_string "SF"))
2288 (eq_attr "alternative" "11")
2289 (const_string "DI")]
2290 (const_string "SF")))])
2291
2292(define_insn "*movsf_1_nointerunit"
2293 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2294 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2295 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2296 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2297 && (reload_in_progress || reload_completed
2298 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2299 || GET_CODE (operands[1]) != CONST_DOUBLE
2300 || memory_operand (operands[0], SFmode))"
2301{
2302 switch (which_alternative)
2303 {
2304 case 0:
2305 if (REG_P (operands[1])
2306 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2307 {
2308 if (REGNO (operands[0]) == FIRST_STACK_REG
2309 && TARGET_USE_FFREEP)
2310 return "ffreep\t%y0";
2311 return "fstp\t%y0";
2312 }
2313 else if (STACK_TOP_P (operands[0]))
2314 return "fld%z1\t%y1";
2315 else
2316 return "fst\t%y0";
2317
2318 case 1:
2319 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320 return "fstp%z0\t%y0";
2321 else
2322 return "fst%z0\t%y0";
2323
2324 case 2:
2325 return standard_80387_constant_opcode (operands[1]);
2326
2327 case 3:
2328 case 4:
2329 return "mov{l}\t{%1, %0|%0, %1}";
2330 case 5:
2331 if (get_attr_mode (insn) == MODE_TI)
2332 return "pxor\t%0, %0";
2333 else
2334 return "xorps\t%0, %0";
2335 case 6:
2336 if (get_attr_mode (insn) == MODE_V4SF)
2337 return "movaps\t{%1, %0|%0, %1}";
2338 else
2339 return "movss\t{%1, %0|%0, %1}";
2340 case 7:
2341 case 8:
2342 return "movss\t{%1, %0|%0, %1}";
2343
2344 case 9:
2345 case 10:
2346 return "movd\t{%1, %0|%0, %1}";
2347
2348 case 11:
2349 return "movq\t{%1, %0|%0, %1}";
2350
2351 default:
2352 abort();
2353 }
2354}
2355 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356 (set (attr "mode")
2357 (cond [(eq_attr "alternative" "3,4,9,10")
2358 (const_string "SI")
2359 (eq_attr "alternative" "5")
2360 (if_then_else
2361 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362 (const_int 0))
2363 (ne (symbol_ref "TARGET_SSE2")
2364 (const_int 0)))
2365 (eq (symbol_ref "optimize_size")
2366 (const_int 0)))
2367 (const_string "TI")
2368 (const_string "V4SF"))
2369 /* For architectures resolving dependencies on
2370 whole SSE registers use APS move to break dependency
2371 chains, otherwise use short move to avoid extra work.
2372
2373 Do the same for architectures resolving dependencies on
2374 the parts. While in DF mode it is better to always handle
2375 just register parts, the SF mode is different due to lack
2376 of instructions to load just part of the register. It is
2377 better to maintain the whole registers in single format
2378 to avoid problems on using packed logical operations. */
2379 (eq_attr "alternative" "6")
2380 (if_then_else
2381 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382 (const_int 0))
2383 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2384 (const_int 0)))
2385 (const_string "V4SF")
2386 (const_string "SF"))
2387 (eq_attr "alternative" "11")
2388 (const_string "DI")]
2389 (const_string "SF")))])
2390
2391(define_insn "*swapsf"
2392 [(set (match_operand:SF 0 "register_operand" "+f")
2393 (match_operand:SF 1 "register_operand" "+f"))
2394 (set (match_dup 1)
2395 (match_dup 0))]
2396 "reload_completed || !TARGET_SSE"
2397{
2398 if (STACK_TOP_P (operands[0]))
2399 return "fxch\t%1";
2400 else
2401 return "fxch\t%0";
2402}
2403 [(set_attr "type" "fxch")
2404 (set_attr "mode" "SF")])
2405
2406(define_expand "movdf"
2407 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408 (match_operand:DF 1 "general_operand" ""))]
2409 ""
2410 "ix86_expand_move (DFmode, operands); DONE;")
2411
2412;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413;; Size of pushdf using integer instructions is 2+2*memory operand size
2414;; On the average, pushdf using integers can be still shorter. Allow this
2415;; pattern for optimize_size too.
2416
2417(define_insn "*pushdf_nointeger"
2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2420 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421{
2422 /* This insn should be already split before reg-stack. */
2423 abort ();
2424}
2425 [(set_attr "type" "multi")
2426 (set_attr "mode" "DF,SI,SI,DF")])
2427
2428(define_insn "*pushdf_integer"
2429 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2430 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2431 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2432{
2433 /* This insn should be already split before reg-stack. */
2434 abort ();
2435}
2436 [(set_attr "type" "multi")
2437 (set_attr "mode" "DF,SI,DF")])
2438
2439;; %%% Kill this when call knows how to work this out.
2440(define_split
2441 [(set (match_operand:DF 0 "push_operand" "")
2442 (match_operand:DF 1 "any_fp_register_operand" ""))]
2443 "!TARGET_64BIT && reload_completed"
2444 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2445 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2446 "")
2447
2448(define_split
2449 [(set (match_operand:DF 0 "push_operand" "")
2450 (match_operand:DF 1 "any_fp_register_operand" ""))]
2451 "TARGET_64BIT && reload_completed"
2452 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2453 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2454 "")
2455
2456(define_split
2457 [(set (match_operand:DF 0 "push_operand" "")
2458 (match_operand:DF 1 "general_operand" ""))]
2459 "reload_completed"
2460 [(const_int 0)]
2461 "ix86_split_long_move (operands); DONE;")
2462
2463;; Moving is usually shorter when only FP registers are used. This separate
2464;; movdf pattern avoids the use of integer registers for FP operations
2465;; when optimizing for size.
2466
2467(define_insn "*movdf_nointeger"
2468 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2469 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2470 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2471 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2472 && (reload_in_progress || reload_completed
2473 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2474 || GET_CODE (operands[1]) != CONST_DOUBLE
2475 || memory_operand (operands[0], DFmode))"
2476{
2477 switch (which_alternative)
2478 {
2479 case 0:
2480 if (REG_P (operands[1])
2481 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2482 {
2483 if (REGNO (operands[0]) == FIRST_STACK_REG
2484 && TARGET_USE_FFREEP)
2485 return "ffreep\t%y0";
2486 return "fstp\t%y0";
2487 }
2488 else if (STACK_TOP_P (operands[0]))
2489 return "fld%z1\t%y1";
2490 else
2491 return "fst\t%y0";
2492
2493 case 1:
2494 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2495 return "fstp%z0\t%y0";
2496 else
2497 return "fst%z0\t%y0";
2498
2499 case 2:
2500 return standard_80387_constant_opcode (operands[1]);
2501
2502 case 3:
2503 case 4:
2504 return "#";
2505 case 5:
2506 switch (get_attr_mode (insn))
2507 {
2508 case MODE_V4SF:
2509 return "xorps\t%0, %0";
2510 case MODE_V2DF:
2511 return "xorpd\t%0, %0";
2512 case MODE_TI:
2513 return "pxor\t%0, %0";
2514 default:
2515 abort ();
2516 }
2517 case 6:
2518 switch (get_attr_mode (insn))
2519 {
2520 case MODE_V4SF:
2521 return "movaps\t{%1, %0|%0, %1}";
2522 case MODE_V2DF:
2523 return "movapd\t{%1, %0|%0, %1}";
2524 case MODE_DF:
2525 return "movsd\t{%1, %0|%0, %1}";
2526 default:
2527 abort ();
2528 }
2529 case 7:
2530 if (get_attr_mode (insn) == MODE_V2DF)
2531 return "movlpd\t{%1, %0|%0, %1}";
2532 else
2533 return "movsd\t{%1, %0|%0, %1}";
2534 case 8:
2535 return "movsd\t{%1, %0|%0, %1}";
2536
2537 default:
2538 abort();
2539 }
2540}
2541 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2542 (set (attr "mode")
2543 (cond [(eq_attr "alternative" "3,4")
2544 (const_string "SI")
2545 /* xorps is one byte shorter. */
2546 (eq_attr "alternative" "5")
2547 (cond [(ne (symbol_ref "optimize_size")
2548 (const_int 0))
2549 (const_string "V4SF")
2550 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2551 (const_int 0))
2552 (const_string "TI")]
2553 (const_string "V2DF"))
2554 /* For architectures resolving dependencies on
2555 whole SSE registers use APD move to break dependency
2556 chains, otherwise use short move to avoid extra work.
2557
2558 movaps encodes one byte shorter. */
2559 (eq_attr "alternative" "6")
2560 (cond
2561 [(ne (symbol_ref "optimize_size")
2562 (const_int 0))
2563 (const_string "V4SF")
2564 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2565 (const_int 0))
2566 (const_string "V2DF")]
2567 (const_string "DF"))
2568 /* For architectures resolving dependencies on register
2569 parts we may avoid extra work to zero out upper part
2570 of register. */
2571 (eq_attr "alternative" "7")
2572 (if_then_else
2573 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2574 (const_int 0))
2575 (const_string "V2DF")
2576 (const_string "DF"))]
2577 (const_string "DF")))])
2578
2579(define_insn "*movdf_integer"
2580 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2581 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2582 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2583 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2584 && (reload_in_progress || reload_completed
2585 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2586 || GET_CODE (operands[1]) != CONST_DOUBLE
2587 || memory_operand (operands[0], DFmode))"
2588{
2589 switch (which_alternative)
2590 {
2591 case 0:
2592 if (REG_P (operands[1])
2593 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2594 {
2595 if (REGNO (operands[0]) == FIRST_STACK_REG
2596 && TARGET_USE_FFREEP)
2597 return "ffreep\t%y0";
2598 return "fstp\t%y0";
2599 }
2600 else if (STACK_TOP_P (operands[0]))
2601 return "fld%z1\t%y1";
2602 else
2603 return "fst\t%y0";
2604
2605 case 1:
2606 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2607 return "fstp%z0\t%y0";
2608 else
2609 return "fst%z0\t%y0";
2610
2611 case 2:
2612 return standard_80387_constant_opcode (operands[1]);
2613
2614 case 3:
2615 case 4:
2616 return "#";
2617
2618 case 5:
2619 switch (get_attr_mode (insn))
2620 {
2621 case MODE_V4SF:
2622 return "xorps\t%0, %0";
2623 case MODE_V2DF:
2624 return "xorpd\t%0, %0";
2625 case MODE_TI:
2626 return "pxor\t%0, %0";
2627 default:
2628 abort ();
2629 }
2630 case 6:
2631 switch (get_attr_mode (insn))
2632 {
2633 case MODE_V4SF:
2634 return "movaps\t{%1, %0|%0, %1}";
2635 case MODE_V2DF:
2636 return "movapd\t{%1, %0|%0, %1}";
2637 case MODE_DF:
2638 return "movsd\t{%1, %0|%0, %1}";
2639 default:
2640 abort ();
2641 }
2642 case 7:
2643 if (get_attr_mode (insn) == MODE_V2DF)
2644 return "movlpd\t{%1, %0|%0, %1}";
2645 else
2646 return "movsd\t{%1, %0|%0, %1}";
2647 case 8:
2648 return "movsd\t{%1, %0|%0, %1}";
2649
2650 default:
2651 abort();
2652 }
2653}
2654 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2655 (set (attr "mode")
2656 (cond [(eq_attr "alternative" "3,4")
2657 (const_string "SI")
2658 /* xorps is one byte shorter. */
2659 (eq_attr "alternative" "5")
2660 (cond [(ne (symbol_ref "optimize_size")
2661 (const_int 0))
2662 (const_string "V4SF")
2663 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2664 (const_int 0))
2665 (const_string "TI")]
2666 (const_string "V2DF"))
2667 /* For architectures resolving dependencies on
2668 whole SSE registers use APD move to break dependency
2669 chains, otherwise use short move to avoid extra work.
2670
2671 movaps encodes one byte shorter. */
2672 (eq_attr "alternative" "6")
2673 (cond
2674 [(ne (symbol_ref "optimize_size")
2675 (const_int 0))
2676 (const_string "V4SF")
2677 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2678 (const_int 0))
2679 (const_string "V2DF")]
2680 (const_string "DF"))
2681 /* For architectures resolving dependencies on register
2682 parts we may avoid extra work to zero out upper part
2683 of register. */
2684 (eq_attr "alternative" "7")
2685 (if_then_else
2686 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2687 (const_int 0))
2688 (const_string "V2DF")
2689 (const_string "DF"))]
2690 (const_string "DF")))])
2691
2692(define_split
2693 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2694 (match_operand:DF 1 "general_operand" ""))]
2695 "reload_completed
2696 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2697 && ! (ANY_FP_REG_P (operands[0]) ||
2698 (GET_CODE (operands[0]) == SUBREG
2699 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2700 && ! (ANY_FP_REG_P (operands[1]) ||
2701 (GET_CODE (operands[1]) == SUBREG
2702 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2703 [(const_int 0)]
2704 "ix86_split_long_move (operands); DONE;")
2705
2706(define_insn "*swapdf"
2707 [(set (match_operand:DF 0 "register_operand" "+f")
2708 (match_operand:DF 1 "register_operand" "+f"))
2709 (set (match_dup 1)
2710 (match_dup 0))]
2711 "reload_completed || !TARGET_SSE2"
2712{
2713 if (STACK_TOP_P (operands[0]))
2714 return "fxch\t%1";
2715 else
2716 return "fxch\t%0";
2717}
2718 [(set_attr "type" "fxch")
2719 (set_attr "mode" "DF")])
2720
2721(define_expand "movxf"
2722 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2723 (match_operand:XF 1 "general_operand" ""))]
2724 ""
2725 "ix86_expand_move (XFmode, operands); DONE;")
2726
2727;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2728;; Size of pushdf using integer instructions is 3+3*memory operand size
2729;; Pushing using integer instructions is longer except for constants
2730;; and direct memory references.
2731;; (assuming that any given constant is pushed only once, but this ought to be
2732;; handled elsewhere).
2733
2734(define_insn "*pushxf_nointeger"
2735 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2736 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2737 "optimize_size"
2738{
2739 /* This insn should be already split before reg-stack. */
2740 abort ();
2741}
2742 [(set_attr "type" "multi")
2743 (set_attr "mode" "XF,SI,SI")])
2744
2745(define_insn "*pushxf_integer"
2746 [(set (match_operand:XF 0 "push_operand" "=<,<")
2747 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2748 "!optimize_size"
2749{
2750 /* This insn should be already split before reg-stack. */
2751 abort ();
2752}
2753 [(set_attr "type" "multi")
2754 (set_attr "mode" "XF,SI")])
2755
2756(define_split
2757 [(set (match_operand 0 "push_operand" "")
2758 (match_operand 1 "general_operand" ""))]
2759 "reload_completed
2760 && (GET_MODE (operands[0]) == XFmode
2761 || GET_MODE (operands[0]) == DFmode)
2762 && !ANY_FP_REG_P (operands[1])"
2763 [(const_int 0)]
2764 "ix86_split_long_move (operands); DONE;")
2765
2766(define_split
2767 [(set (match_operand:XF 0 "push_operand" "")
2768 (match_operand:XF 1 "any_fp_register_operand" ""))]
2769 "!TARGET_64BIT"
2770 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2771 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2772 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2773
2774(define_split
2775 [(set (match_operand:XF 0 "push_operand" "")
2776 (match_operand:XF 1 "any_fp_register_operand" ""))]
2777 "TARGET_64BIT"
2778 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2779 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2780 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2781
2782;; Do not use integer registers when optimizing for size
2783(define_insn "*movxf_nointeger"
2784 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2785 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2786 "optimize_size
2787 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2788 && (reload_in_progress || reload_completed
2789 || GET_CODE (operands[1]) != CONST_DOUBLE
2790 || memory_operand (operands[0], XFmode))"
2791{
2792 switch (which_alternative)
2793 {
2794 case 0:
2795 if (REG_P (operands[1])
2796 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2797 {
2798 if (REGNO (operands[0]) == FIRST_STACK_REG
2799 && TARGET_USE_FFREEP)
2800 return "ffreep\t%y0";
2801 return "fstp\t%y0";
2802 }
2803 else if (STACK_TOP_P (operands[0]))
2804 return "fld%z1\t%y1";
2805 else
2806 return "fst\t%y0";
2807
2808 case 1:
2809 /* There is no non-popping store to memory for XFmode. So if
2810 we need one, follow the store with a load. */
2811 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2812 return "fstp%z0\t%y0\;fld%z0\t%y0";
2813 else
2814 return "fstp%z0\t%y0";
2815
2816 case 2:
2817 return standard_80387_constant_opcode (operands[1]);
2818
2819 case 3: case 4:
2820 return "#";
2821 }
2822 abort();
2823}
2824 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2825 (set_attr "mode" "XF,XF,XF,SI,SI")])
2826
2827(define_insn "*movxf_integer"
2828 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2829 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2830 "!optimize_size
2831 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2832 && (reload_in_progress || reload_completed
2833 || GET_CODE (operands[1]) != CONST_DOUBLE
2834 || memory_operand (operands[0], XFmode))"
2835{
2836 switch (which_alternative)
2837 {
2838 case 0:
2839 if (REG_P (operands[1])
2840 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2841 {
2842 if (REGNO (operands[0]) == FIRST_STACK_REG
2843 && TARGET_USE_FFREEP)
2844 return "ffreep\t%y0";
2845 return "fstp\t%y0";
2846 }
2847 else if (STACK_TOP_P (operands[0]))
2848 return "fld%z1\t%y1";
2849 else
2850 return "fst\t%y0";
2851
2852 case 1:
2853 /* There is no non-popping store to memory for XFmode. So if
2854 we need one, follow the store with a load. */
2855 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2856 return "fstp%z0\t%y0\;fld%z0\t%y0";
2857 else
2858 return "fstp%z0\t%y0";
2859
2860 case 2:
2861 return standard_80387_constant_opcode (operands[1]);
2862
2863 case 3: case 4:
2864 return "#";
2865 }
2866 abort();
2867}
2868 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2869 (set_attr "mode" "XF,XF,XF,SI,SI")])
2870
2871(define_split
2872 [(set (match_operand 0 "nonimmediate_operand" "")
2873 (match_operand 1 "general_operand" ""))]
2874 "reload_completed
2875 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2876 && GET_MODE (operands[0]) == XFmode
2877 && ! (ANY_FP_REG_P (operands[0]) ||
2878 (GET_CODE (operands[0]) == SUBREG
2879 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2880 && ! (ANY_FP_REG_P (operands[1]) ||
2881 (GET_CODE (operands[1]) == SUBREG
2882 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2883 [(const_int 0)]
2884 "ix86_split_long_move (operands); DONE;")
2885
2886(define_split
2887 [(set (match_operand 0 "register_operand" "")
2888 (match_operand 1 "memory_operand" ""))]
2889 "reload_completed
2890 && GET_CODE (operands[1]) == MEM
2891 && (GET_MODE (operands[0]) == XFmode
2892 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
1378ea41 2893 && constant_pool_reference_p (operands[1])"
003757ed
MD
2894 [(set (match_dup 0) (match_dup 1))]
2895{
1378ea41 2896 rtx c = avoid_constant_pool_reference (operands[1]);
003757ed
MD
2897 rtx r = operands[0];
2898
2899 if (GET_CODE (r) == SUBREG)
2900 r = SUBREG_REG (r);
2901
2902 if (SSE_REG_P (r))
2903 {
2904 if (!standard_sse_constant_p (c))
2905 FAIL;
2906 }
2907 else if (FP_REG_P (r))
2908 {
2909 if (!standard_80387_constant_p (c))
2910 FAIL;
2911 }
2912 else if (MMX_REG_P (r))
2913 FAIL;
2914
2915 operands[1] = c;
2916})
2917
2918(define_insn "swapxf"
2919 [(set (match_operand:XF 0 "register_operand" "+f")
2920 (match_operand:XF 1 "register_operand" "+f"))
2921 (set (match_dup 1)
2922 (match_dup 0))]
2923 ""
2924{
2925 if (STACK_TOP_P (operands[0]))
2926 return "fxch\t%1";
2927 else
2928 return "fxch\t%0";
2929}
2930 [(set_attr "type" "fxch")
2931 (set_attr "mode" "XF")])
2932\f
2933;; Zero extension instructions
2934
2935(define_expand "zero_extendhisi2"
2936 [(set (match_operand:SI 0 "register_operand" "")
2937 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2938 ""
2939{
2940 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2941 {
2942 operands[1] = force_reg (HImode, operands[1]);
2943 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2944 DONE;
2945 }
2946})
2947
2948(define_insn "zero_extendhisi2_and"
2949 [(set (match_operand:SI 0 "register_operand" "=r")
2950 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2951 (clobber (reg:CC 17))]
2952 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2953 "#"
2954 [(set_attr "type" "alu1")
2955 (set_attr "mode" "SI")])
2956
2957(define_split
2958 [(set (match_operand:SI 0 "register_operand" "")
2959 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2960 (clobber (reg:CC 17))]
2961 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2962 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2963 (clobber (reg:CC 17))])]
2964 "")
2965
2966(define_insn "*zero_extendhisi2_movzwl"
2967 [(set (match_operand:SI 0 "register_operand" "=r")
2968 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2969 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2970 "movz{wl|x}\t{%1, %0|%0, %1}"
2971 [(set_attr "type" "imovx")
2972 (set_attr "mode" "SI")])
2973
2974(define_expand "zero_extendqihi2"
2975 [(parallel
2976 [(set (match_operand:HI 0 "register_operand" "")
2977 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2978 (clobber (reg:CC 17))])]
2979 ""
2980 "")
2981
2982(define_insn "*zero_extendqihi2_and"
2983 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2984 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2985 (clobber (reg:CC 17))]
2986 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2987 "#"
2988 [(set_attr "type" "alu1")
2989 (set_attr "mode" "HI")])
2990
2991(define_insn "*zero_extendqihi2_movzbw_and"
2992 [(set (match_operand:HI 0 "register_operand" "=r,r")
2993 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2994 (clobber (reg:CC 17))]
2995 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2996 "#"
2997 [(set_attr "type" "imovx,alu1")
2998 (set_attr "mode" "HI")])
2999
3000(define_insn "*zero_extendqihi2_movzbw"
3001 [(set (match_operand:HI 0 "register_operand" "=r")
3002 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3003 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3004 "movz{bw|x}\t{%1, %0|%0, %1}"
3005 [(set_attr "type" "imovx")
3006 (set_attr "mode" "HI")])
3007
3008;; For the movzbw case strip only the clobber
3009(define_split
3010 [(set (match_operand:HI 0 "register_operand" "")
3011 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012 (clobber (reg:CC 17))]
3013 "reload_completed
3014 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3015 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3016 [(set (match_operand:HI 0 "register_operand" "")
3017 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3018
3019;; When source and destination does not overlap, clear destination
3020;; first and then do the movb
3021(define_split
3022 [(set (match_operand:HI 0 "register_operand" "")
3023 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3024 (clobber (reg:CC 17))]
3025 "reload_completed
3026 && ANY_QI_REG_P (operands[0])
3027 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3028 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3029 [(set (match_dup 0) (const_int 0))
3030 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3031 "operands[2] = gen_lowpart (QImode, operands[0]);")
3032
3033;; Rest is handled by single and.
3034(define_split
3035 [(set (match_operand:HI 0 "register_operand" "")
3036 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3037 (clobber (reg:CC 17))]
3038 "reload_completed
3039 && true_regnum (operands[0]) == true_regnum (operands[1])"
3040 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3041 (clobber (reg:CC 17))])]
3042 "")
3043
3044(define_expand "zero_extendqisi2"
3045 [(parallel
3046 [(set (match_operand:SI 0 "register_operand" "")
3047 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3048 (clobber (reg:CC 17))])]
3049 ""
3050 "")
3051
3052(define_insn "*zero_extendqisi2_and"
3053 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3054 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3055 (clobber (reg:CC 17))]
3056 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3057 "#"
3058 [(set_attr "type" "alu1")
3059 (set_attr "mode" "SI")])
3060
3061(define_insn "*zero_extendqisi2_movzbw_and"
3062 [(set (match_operand:SI 0 "register_operand" "=r,r")
3063 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3064 (clobber (reg:CC 17))]
3065 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3066 "#"
3067 [(set_attr "type" "imovx,alu1")
3068 (set_attr "mode" "SI")])
3069
3070(define_insn "*zero_extendqisi2_movzbw"
3071 [(set (match_operand:SI 0 "register_operand" "=r")
3072 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3073 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3074 "movz{bl|x}\t{%1, %0|%0, %1}"
3075 [(set_attr "type" "imovx")
3076 (set_attr "mode" "SI")])
3077
3078;; For the movzbl case strip only the clobber
3079(define_split
3080 [(set (match_operand:SI 0 "register_operand" "")
3081 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3082 (clobber (reg:CC 17))]
3083 "reload_completed
3084 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3085 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3086 [(set (match_dup 0)
3087 (zero_extend:SI (match_dup 1)))])
3088
3089;; When source and destination does not overlap, clear destination
3090;; first and then do the movb
3091(define_split
3092 [(set (match_operand:SI 0 "register_operand" "")
3093 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3094 (clobber (reg:CC 17))]
3095 "reload_completed
3096 && ANY_QI_REG_P (operands[0])
3097 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3098 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3099 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3100 [(set (match_dup 0) (const_int 0))
3101 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3102 "operands[2] = gen_lowpart (QImode, operands[0]);")
3103
3104;; Rest is handled by single and.
3105(define_split
3106 [(set (match_operand:SI 0 "register_operand" "")
3107 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3108 (clobber (reg:CC 17))]
3109 "reload_completed
3110 && true_regnum (operands[0]) == true_regnum (operands[1])"
3111 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3112 (clobber (reg:CC 17))])]
3113 "")
3114
3115;; %%% Kill me once multi-word ops are sane.
3116(define_expand "zero_extendsidi2"
3117 [(set (match_operand:DI 0 "register_operand" "=r")
3118 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3119 ""
3120 "if (!TARGET_64BIT)
3121 {
3122 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3123 DONE;
3124 }
3125 ")
3126
3127(define_insn "zero_extendsidi2_32"
3128 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3129 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3130 (clobber (reg:CC 17))]
3131 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3132 "@
3133 #
3134 #
3135 #
3136 movd\t{%1, %0|%0, %1}
3137 movd\t{%1, %0|%0, %1}"
3138 [(set_attr "mode" "SI,SI,SI,DI,TI")
3139 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3140
3141(define_insn "*zero_extendsidi2_32_1"
3142 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3143 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3144 (clobber (reg:CC 17))]
3145 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3146 "@
3147 #
3148 #
3149 #
3150 movd\t{%1, %0|%0, %1}
3151 movd\t{%1, %0|%0, %1}"
3152 [(set_attr "mode" "SI,SI,SI,DI,TI")
3153 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3154
3155(define_insn "zero_extendsidi2_rex64"
3156 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3157 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3158 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3159 "@
3160 mov\t{%k1, %k0|%k0, %k1}
3161 #
3162 movd\t{%1, %0|%0, %1}
3163 movd\t{%1, %0|%0, %1}"
3164 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3165 (set_attr "mode" "SI,DI,DI,TI")])
3166
3167(define_insn "*zero_extendsidi2_rex64_1"
3168 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3169 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3170 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3171 "@
3172 mov\t{%k1, %k0|%k0, %k1}
3173 #
3174 movd\t{%1, %0|%0, %1}
3175 movd\t{%1, %0|%0, %1}"
3176 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3177 (set_attr "mode" "SI,DI,SI,SI")])
3178
3179(define_split
3180 [(set (match_operand:DI 0 "memory_operand" "")
3181 (zero_extend:DI (match_dup 0)))]
3182 "TARGET_64BIT"
3183 [(set (match_dup 4) (const_int 0))]
3184 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3185
3186(define_split
3187 [(set (match_operand:DI 0 "register_operand" "")
3188 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3189 (clobber (reg:CC 17))]
3190 "!TARGET_64BIT && reload_completed
3191 && true_regnum (operands[0]) == true_regnum (operands[1])"
3192 [(set (match_dup 4) (const_int 0))]
3193 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194
3195(define_split
3196 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3197 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3198 (clobber (reg:CC 17))]
3199 "!TARGET_64BIT && reload_completed
3200 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3201 [(set (match_dup 3) (match_dup 1))
3202 (set (match_dup 4) (const_int 0))]
3203 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3204
3205(define_insn "zero_extendhidi2"
3206 [(set (match_operand:DI 0 "register_operand" "=r,r")
3207 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3208 "TARGET_64BIT"
3209 "@
3210 movz{wl|x}\t{%1, %k0|%k0, %1}
3211 movz{wq|x}\t{%1, %0|%0, %1}"
3212 [(set_attr "type" "imovx")
3213 (set_attr "mode" "SI,DI")])
3214
3215(define_insn "zero_extendqidi2"
3216 [(set (match_operand:DI 0 "register_operand" "=r,r")
3217 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3218 "TARGET_64BIT"
3219 "@
3220 movz{bl|x}\t{%1, %k0|%k0, %1}
3221 movz{bq|x}\t{%1, %0|%0, %1}"
3222 [(set_attr "type" "imovx")
3223 (set_attr "mode" "SI,DI")])
3224\f
3225;; Sign extension instructions
3226
3227(define_expand "extendsidi2"
3228 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3229 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3230 (clobber (reg:CC 17))
3231 (clobber (match_scratch:SI 2 ""))])]
3232 ""
3233{
3234 if (TARGET_64BIT)
3235 {
3236 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3237 DONE;
3238 }
3239})
3240
3241(define_insn "*extendsidi2_1"
3242 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3243 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3244 (clobber (reg:CC 17))
3245 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3246 "!TARGET_64BIT"
3247 "#")
3248
3249(define_insn "extendsidi2_rex64"
3250 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3251 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3252 "TARGET_64BIT"
3253 "@
3254 {cltq|cdqe}
3255 movs{lq|x}\t{%1,%0|%0, %1}"
3256 [(set_attr "type" "imovx")
3257 (set_attr "mode" "DI")
3258 (set_attr "prefix_0f" "0")
3259 (set_attr "modrm" "0,1")])
3260
3261(define_insn "extendhidi2"
3262 [(set (match_operand:DI 0 "register_operand" "=r")
3263 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3264 "TARGET_64BIT"
3265 "movs{wq|x}\t{%1,%0|%0, %1}"
3266 [(set_attr "type" "imovx")
3267 (set_attr "mode" "DI")])
3268
3269(define_insn "extendqidi2"
3270 [(set (match_operand:DI 0 "register_operand" "=r")
3271 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3272 "TARGET_64BIT"
3273 "movs{bq|x}\t{%1,%0|%0, %1}"
3274 [(set_attr "type" "imovx")
3275 (set_attr "mode" "DI")])
3276
3277;; Extend to memory case when source register does die.
3278(define_split
3279 [(set (match_operand:DI 0 "memory_operand" "")
3280 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3281 (clobber (reg:CC 17))
3282 (clobber (match_operand:SI 2 "register_operand" ""))]
3283 "(reload_completed
3284 && dead_or_set_p (insn, operands[1])
3285 && !reg_mentioned_p (operands[1], operands[0]))"
3286 [(set (match_dup 3) (match_dup 1))
3287 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3288 (clobber (reg:CC 17))])
3289 (set (match_dup 4) (match_dup 1))]
3290 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3291
3292;; Extend to memory case when source register does not die.
3293(define_split
3294 [(set (match_operand:DI 0 "memory_operand" "")
3295 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3296 (clobber (reg:CC 17))
3297 (clobber (match_operand:SI 2 "register_operand" ""))]
3298 "reload_completed"
3299 [(const_int 0)]
3300{
3301 split_di (&operands[0], 1, &operands[3], &operands[4]);
3302
3303 emit_move_insn (operands[3], operands[1]);
3304
3305 /* Generate a cltd if possible and doing so it profitable. */
3306 if (true_regnum (operands[1]) == 0
3307 && true_regnum (operands[2]) == 1
3308 && (optimize_size || TARGET_USE_CLTD))
3309 {
3310 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3311 }
3312 else
3313 {
3314 emit_move_insn (operands[2], operands[1]);
3315 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3316 }
3317 emit_move_insn (operands[4], operands[2]);
3318 DONE;
3319})
3320
3321;; Extend to register case. Optimize case where source and destination
3322;; registers match and cases where we can use cltd.
3323(define_split
3324 [(set (match_operand:DI 0 "register_operand" "")
3325 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3326 (clobber (reg:CC 17))
3327 (clobber (match_scratch:SI 2 ""))]
3328 "reload_completed"
3329 [(const_int 0)]
3330{
3331 split_di (&operands[0], 1, &operands[3], &operands[4]);
3332
3333 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3334 emit_move_insn (operands[3], operands[1]);
3335
3336 /* Generate a cltd if possible and doing so it profitable. */
3337 if (true_regnum (operands[3]) == 0
3338 && (optimize_size || TARGET_USE_CLTD))
3339 {
3340 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3341 DONE;
3342 }
3343
3344 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3345 emit_move_insn (operands[4], operands[1]);
3346
3347 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3348 DONE;
3349})
3350
3351(define_insn "extendhisi2"
3352 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3353 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3354 ""
3355{
3356 switch (get_attr_prefix_0f (insn))
3357 {
3358 case 0:
3359 return "{cwtl|cwde}";
3360 default:
3361 return "movs{wl|x}\t{%1,%0|%0, %1}";
3362 }
3363}
3364 [(set_attr "type" "imovx")
3365 (set_attr "mode" "SI")
3366 (set (attr "prefix_0f")
3367 ;; movsx is short decodable while cwtl is vector decoded.
3368 (if_then_else (and (eq_attr "cpu" "!k6")
3369 (eq_attr "alternative" "0"))
3370 (const_string "0")
3371 (const_string "1")))
3372 (set (attr "modrm")
3373 (if_then_else (eq_attr "prefix_0f" "0")
3374 (const_string "0")
3375 (const_string "1")))])
3376
3377(define_insn "*extendhisi2_zext"
3378 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3379 (zero_extend:DI
3380 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3381 "TARGET_64BIT"
3382{
3383 switch (get_attr_prefix_0f (insn))
3384 {
3385 case 0:
3386 return "{cwtl|cwde}";
3387 default:
3388 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3389 }
3390}
3391 [(set_attr "type" "imovx")
3392 (set_attr "mode" "SI")
3393 (set (attr "prefix_0f")
3394 ;; movsx is short decodable while cwtl is vector decoded.
3395 (if_then_else (and (eq_attr "cpu" "!k6")
3396 (eq_attr "alternative" "0"))
3397 (const_string "0")
3398 (const_string "1")))
3399 (set (attr "modrm")
3400 (if_then_else (eq_attr "prefix_0f" "0")
3401 (const_string "0")
3402 (const_string "1")))])
3403
3404(define_insn "extendqihi2"
3405 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3406 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3407 ""
3408{
3409 switch (get_attr_prefix_0f (insn))
3410 {
3411 case 0:
3412 return "{cbtw|cbw}";
3413 default:
3414 return "movs{bw|x}\t{%1,%0|%0, %1}";
3415 }
3416}
3417 [(set_attr "type" "imovx")
3418 (set_attr "mode" "HI")
3419 (set (attr "prefix_0f")
3420 ;; movsx is short decodable while cwtl is vector decoded.
3421 (if_then_else (and (eq_attr "cpu" "!k6")
3422 (eq_attr "alternative" "0"))
3423 (const_string "0")
3424 (const_string "1")))
3425 (set (attr "modrm")
3426 (if_then_else (eq_attr "prefix_0f" "0")
3427 (const_string "0")
3428 (const_string "1")))])
3429
3430(define_insn "extendqisi2"
3431 [(set (match_operand:SI 0 "register_operand" "=r")
3432 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3433 ""
3434 "movs{bl|x}\t{%1,%0|%0, %1}"
3435 [(set_attr "type" "imovx")
3436 (set_attr "mode" "SI")])
3437
3438(define_insn "*extendqisi2_zext"
3439 [(set (match_operand:DI 0 "register_operand" "=r")
3440 (zero_extend:DI
3441 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3442 "TARGET_64BIT"
3443 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3444 [(set_attr "type" "imovx")
3445 (set_attr "mode" "SI")])
3446\f
3447;; Conversions between float and double.
3448
3449;; These are all no-ops in the model used for the 80387. So just
3450;; emit moves.
3451
3452;; %%% Kill these when call knows how to work out a DFmode push earlier.
3453(define_insn "*dummy_extendsfdf2"
3454 [(set (match_operand:DF 0 "push_operand" "=<")
3455 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3456 "0"
3457 "#")
3458
3459(define_split
3460 [(set (match_operand:DF 0 "push_operand" "")
3461 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3462 "!TARGET_64BIT"
3463 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3464 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3465
3466(define_split
3467 [(set (match_operand:DF 0 "push_operand" "")
3468 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469 "TARGET_64BIT"
3470 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3471 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3472
3473(define_insn "*dummy_extendsfxf2"
3474 [(set (match_operand:XF 0 "push_operand" "=<")
3475 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3476 "0"
3477 "#")
3478
3479(define_split
3480 [(set (match_operand:XF 0 "push_operand" "")
3481 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482 ""
3483 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3484 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3485 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3486
3487(define_split
3488 [(set (match_operand:XF 0 "push_operand" "")
3489 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3490 "TARGET_64BIT"
3491 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3492 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3493 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494
3495(define_split
3496 [(set (match_operand:XF 0 "push_operand" "")
3497 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498 ""
3499 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3500 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3501 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502
3503(define_split
3504 [(set (match_operand:XF 0 "push_operand" "")
3505 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3506 "TARGET_64BIT"
3507 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3508 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3509 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510
3511(define_expand "extendsfdf2"
3512 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3513 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3514 "TARGET_80387 || TARGET_SSE2"
3515{
3516 /* ??? Needed for compress_float_constant since all fp constants
3517 are LEGITIMATE_CONSTANT_P. */
3518 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3519 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3520 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3521 operands[1] = force_reg (SFmode, operands[1]);
3522})
3523
3524(define_insn "*extendsfdf2_1"
3525 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3526 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3527 "(TARGET_80387 || TARGET_SSE2)
3528 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3529{
3530 switch (which_alternative)
3531 {
3532 case 0:
3533 if (REG_P (operands[1])
3534 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3535 return "fstp\t%y0";
3536 else if (STACK_TOP_P (operands[0]))
3537 return "fld%z1\t%y1";
3538 else
3539 return "fst\t%y0";
3540
3541 case 1: