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
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)
129 (UNSPECV_STACK_PROBE 10)
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
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
404(include "pentium.md")
405(include "ppro.md")
406(include "k6.md")
407(include "athlon.md")
408
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
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")
1264 (set_attr "mode" "SI")
1265 (set_attr "pent_pair" "np")
1266 (set_attr "athlon_decode" "vector")
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))]
1379 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1380 "xchg{l}\t%k1, %k0"
1381 [(set_attr "type" "imov")
1382 (set_attr "mode" "SI")
1383 (set_attr "pent_pair" "np")
1384 (set_attr "athlon_decode" "vector")
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))]
1392 "TARGET_PARTIAL_REG_STALL"
1393 "xchg{w}\t%1, %0"
1394 [(set_attr "type" "imov")
1395 (set_attr "mode" "HI")
1396 (set_attr "pent_pair" "np")
1397 (set_attr "athlon_decode" "vector")
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
1545(define_insn "*swapqi_1"
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))]
1550 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1551 "xchg{l}\t%k1, %k0"
1552 [(set_attr "type" "imov")
1553 (set_attr "mode" "SI")
1554 (set_attr "pent_pair" "np")
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")
1566 (set_attr "mode" "QI")
1567 (set_attr "pent_pair" "np")
1568 (set_attr "athlon_decode" "vector")
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" ""))]
1853 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1854 && !symbolic_operand (operands[1], DImode)
1855 && !x86_64_immediate_operand (operands[1], DImode)"
1856 [(set (match_dup 0) (match_dup 1))
1857 (set (match_dup 2) (match_dup 3))]
1858 "split_di (operands + 1, 1, operands + 2, operands + 3);
1859 operands[1] = gen_lowpart (DImode, operands[2]);
1860 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1861 GEN_INT (4)));
1862 ")
1863
1864(define_insn "*pushdi2_prologue_rex64"
1865 [(set (match_operand:DI 0 "push_operand" "=<")
1866 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1867 (clobber (mem:BLK (scratch)))]
1868 "TARGET_64BIT"
1869 "push{q}\t%1"
1870 [(set_attr "type" "push")
1871 (set_attr "mode" "DI")])
1872
1873(define_insn "*popdi1_epilogue_rex64"
1874 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1875 (mem:DI (reg:DI 7)))
1876 (set (reg:DI 7)
1877 (plus:DI (reg:DI 7) (const_int 8)))
1878 (clobber (mem:BLK (scratch)))]
1879 "TARGET_64BIT"
1880 "pop{q}\t%0"
1881 [(set_attr "type" "pop")
1882 (set_attr "mode" "DI")])
1883
1884(define_insn "popdi1"
1885 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1886 (mem:DI (reg:DI 7)))
1887 (set (reg:DI 7)
1888 (plus:DI (reg:DI 7) (const_int 8)))]
1889 "TARGET_64BIT"
1890 "pop{q}\t%0"
1891 [(set_attr "type" "pop")
1892 (set_attr "mode" "DI")])
1893
1894(define_insn "*movdi_xor_rex64"
1895 [(set (match_operand:DI 0 "register_operand" "=r")
1896 (match_operand:DI 1 "const0_operand" "i"))
1897 (clobber (reg:CC 17))]
1898 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1899 && reload_completed"
1900 "xor{l}\t{%k0, %k0|%k0, %k0}"
1901 [(set_attr "type" "alu1")
1902 (set_attr "mode" "SI")
1903 (set_attr "length_immediate" "0")])
1904
1905(define_insn "*movdi_or_rex64"
1906 [(set (match_operand:DI 0 "register_operand" "=r")
1907 (match_operand:DI 1 "const_int_operand" "i"))
1908 (clobber (reg:CC 17))]
1909 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1910 && reload_completed
1911 && operands[1] == constm1_rtx"
1912{
1913 operands[1] = constm1_rtx;
1914 return "or{q}\t{%1, %0|%0, %1}";
1915}
1916 [(set_attr "type" "alu1")
1917 (set_attr "mode" "DI")
1918 (set_attr "length_immediate" "1")])
1919
1920(define_insn "*movdi_2"
1921 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1922 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1923 "!TARGET_64BIT
1924 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1925 "@
1926 #
1927 #
1928 movq\t{%1, %0|%0, %1}
1929 movq\t{%1, %0|%0, %1}
1930 movq\t{%1, %0|%0, %1}
1931 movdqa\t{%1, %0|%0, %1}
1932 movq\t{%1, %0|%0, %1}"
1933 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1934 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1935
1936(define_split
1937 [(set (match_operand:DI 0 "push_operand" "")
1938 (match_operand:DI 1 "general_operand" ""))]
1939 "!TARGET_64BIT && reload_completed
1940 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1941 [(const_int 0)]
1942 "ix86_split_long_move (operands); DONE;")
1943
1944;; %%% This multiword shite has got to go.
1945(define_split
1946 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1947 (match_operand:DI 1 "general_operand" ""))]
1948 "!TARGET_64BIT && reload_completed
1949 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1950 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1951 [(const_int 0)]
1952 "ix86_split_long_move (operands); DONE;")
1953
1954(define_insn "*movdi_1_rex64"
1955 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1956 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1957 "TARGET_64BIT
1958 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1959 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1960{
1961 switch (get_attr_type (insn))
1962 {
1963 case TYPE_SSEMOV:
1964 if (get_attr_mode (insn) == MODE_TI)
1965 return "movdqa\t{%1, %0|%0, %1}";
1966 /* FALLTHRU */
1967 case TYPE_MMXMOV:
1968 /* Moves from and into integer register is done using movd opcode with
1969 REX prefix. */
1970 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1971 return "movd\t{%1, %0|%0, %1}";
1972 return "movq\t{%1, %0|%0, %1}";
1973 case TYPE_MULTI:
1974 return "#";
1975 case TYPE_LEA:
1976 return "lea{q}\t{%a1, %0|%0, %a1}";
1977 default:
1978 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1979 abort ();
1980 if (get_attr_mode (insn) == MODE_SI)
1981 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1982 else if (which_alternative == 2)
1983 return "movabs{q}\t{%1, %0|%0, %1}";
1984 else
1985 return "mov{q}\t{%1, %0|%0, %1}";
1986 }
1987}
1988 [(set (attr "type")
1989 (cond [(eq_attr "alternative" "5,6,7")
1990 (const_string "mmxmov")
1991 (eq_attr "alternative" "8,9,10")
1992 (const_string "ssemov")
1993 (eq_attr "alternative" "4")
1994 (const_string "multi")
1995 (and (ne (symbol_ref "flag_pic") (const_int 0))
1996 (match_operand:DI 1 "symbolic_operand" ""))
1997 (const_string "lea")
1998 ]
1999 (const_string "imov")))
2000 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2001 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2002 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2003
2004(define_insn "*movdi_1_rex64_nointerunit"
2005 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2006 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2007 "TARGET_64BIT
2008 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2009 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2010{
2011 switch (get_attr_type (insn))
2012 {
2013 case TYPE_SSEMOV:
2014 if (get_attr_mode (insn) == MODE_TI)
2015 return "movdqa\t{%1, %0|%0, %1}";
2016 /* FALLTHRU */
2017 case TYPE_MMXMOV:
2018 return "movq\t{%1, %0|%0, %1}";
2019 case TYPE_MULTI:
2020 return "#";
2021 case TYPE_LEA:
2022 return "lea{q}\t{%a1, %0|%0, %a1}";
2023 default:
2024 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2025 abort ();
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 2)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2030 else
2031 return "mov{q}\t{%1, %0|%0, %1}";
2032 }
2033}
2034 [(set (attr "type")
2035 (cond [(eq_attr "alternative" "5,6,7")
2036 (const_string "mmxmov")
2037 (eq_attr "alternative" "8,9,10")
2038 (const_string "ssemov")
2039 (eq_attr "alternative" "4")
2040 (const_string "multi")
2041 (and (ne (symbol_ref "flag_pic") (const_int 0))
2042 (match_operand:DI 1 "symbolic_operand" ""))
2043 (const_string "lea")
2044 ]
2045 (const_string "imov")))
2046 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2047 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2048 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2049
2050;; Stores and loads of ax to arbitrary constant address.
2051;; We fake an second form of instruction to force reload to load address
2052;; into register when rax is not available
2053(define_insn "*movabsdi_1_rex64"
2054 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2055 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2056 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2057 "@
2058 movabs{q}\t{%1, %P0|%P0, %1}
2059 mov{q}\t{%1, %a0|%a0, %1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "modrm" "0,*")
2062 (set_attr "length_address" "8,0")
2063 (set_attr "length_immediate" "0,*")
2064 (set_attr "memory" "store")
2065 (set_attr "mode" "DI")])
2066
2067(define_insn "*movabsdi_2_rex64"
2068 [(set (match_operand:DI 0 "register_operand" "=a,r")
2069 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2070 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2071 "@
2072 movabs{q}\t{%P1, %0|%0, %P1}
2073 mov{q}\t{%a1, %0|%0, %a1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "modrm" "0,*")
2076 (set_attr "length_address" "8,0")
2077 (set_attr "length_immediate" "0")
2078 (set_attr "memory" "load")
2079 (set_attr "mode" "DI")])
2080
2081;; Convert impossible stores of immediate to existing instructions.
2082;; First try to get scratch register and go through it. In case this
2083;; fails, move by 32bit parts.
2084(define_peephole2
2085 [(match_scratch:DI 2 "r")
2086 (set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode)"
2090 [(set (match_dup 2) (match_dup 1))
2091 (set (match_dup 0) (match_dup 2))]
2092 "")
2093
2094;; We need to define this as both peepholer and splitter for case
2095;; peephole2 pass is not run.
2096(define_peephole2
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_di (operands, 2, operands + 2, operands + 4);")
2104
2105(define_split
2106 [(set (match_operand:DI 0 "memory_operand" "")
2107 (match_operand:DI 1 "immediate_operand" ""))]
2108 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2109 && !symbolic_operand (operands[1], DImode)
2110 && !x86_64_immediate_operand (operands[1], DImode)"
2111 [(set (match_dup 2) (match_dup 3))
2112 (set (match_dup 4) (match_dup 5))]
2113 "split_di (operands, 2, operands + 2, operands + 4);")
2114
2115(define_insn "*swapdi_rex64"
2116 [(set (match_operand:DI 0 "register_operand" "+r")
2117 (match_operand:DI 1 "register_operand" "+r"))
2118 (set (match_dup 1)
2119 (match_dup 0))]
2120 "TARGET_64BIT"
2121 "xchg{q}\t%1, %0"
2122 [(set_attr "type" "imov")
2123 (set_attr "mode" "DI")
2124 (set_attr "pent_pair" "np")
2125 (set_attr "athlon_decode" "vector")
2126 (set_attr "ppro_uops" "few")])
2127
2128(define_expand "movsf"
2129 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2130 (match_operand:SF 1 "general_operand" ""))]
2131 ""
2132 "ix86_expand_move (SFmode, operands); DONE;")
2133
2134(define_insn "*pushsf"
2135 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2136 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2137 "!TARGET_64BIT"
2138{
2139 switch (which_alternative)
2140 {
2141 case 1:
2142 return "push{l}\t%1";
2143
2144 default:
2145 /* This insn should be already split before reg-stack. */
2146 abort ();
2147 }
2148}
2149 [(set_attr "type" "multi,push,multi")
2150 (set_attr "mode" "SF,SI,SF")])
2151
2152(define_insn "*pushsf_rex64"
2153 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2154 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2155 "TARGET_64BIT"
2156{
2157 switch (which_alternative)
2158 {
2159 case 1:
2160 return "push{q}\t%q1";
2161
2162 default:
2163 /* This insn should be already split before reg-stack. */
2164 abort ();
2165 }
2166}
2167 [(set_attr "type" "multi,push,multi")
2168 (set_attr "mode" "SF,DI,SF")])
2169
2170(define_split
2171 [(set (match_operand:SF 0 "push_operand" "")
2172 (match_operand:SF 1 "memory_operand" ""))]
2173 "reload_completed
2174 && GET_CODE (operands[1]) == MEM
2175 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2176 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2177 [(set (match_dup 0)
2178 (match_dup 1))]
2179 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2180
2181
2182;; %%% Kill this when call knows how to work this out.
2183(define_split
2184 [(set (match_operand:SF 0 "push_operand" "")
2185 (match_operand:SF 1 "any_fp_register_operand" ""))]
2186 "!TARGET_64BIT"
2187 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2188 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2189
2190(define_split
2191 [(set (match_operand:SF 0 "push_operand" "")
2192 (match_operand:SF 1 "any_fp_register_operand" ""))]
2193 "TARGET_64BIT"
2194 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2195 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2196
2197(define_insn "*movsf_1"
2198 [(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")
2199 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2200 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2201 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2202 && (reload_in_progress || reload_completed
2203 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2204 || GET_CODE (operands[1]) != CONST_DOUBLE
2205 || memory_operand (operands[0], SFmode))"
2206{
2207 switch (which_alternative)
2208 {
2209 case 0:
2210 if (REG_P (operands[1])
2211 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2212 return "fstp\t%y0";
2213 else if (STACK_TOP_P (operands[0]))
2214 return "fld%z1\t%y1";
2215 else
2216 return "fst\t%y0";
2217
2218 case 1:
2219 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2220 return "fstp%z0\t%y0";
2221 else
2222 return "fst%z0\t%y0";
2223
2224 case 2:
2225 return standard_80387_constant_opcode (operands[1]);
2226
2227 case 3:
2228 case 4:
2229 return "mov{l}\t{%1, %0|%0, %1}";
2230 case 5:
2231 if (get_attr_mode (insn) == MODE_TI)
2232 return "pxor\t%0, %0";
2233 else
2234 return "xorps\t%0, %0";
2235 case 6:
2236 if (get_attr_mode (insn) == MODE_V4SF)
2237 return "movaps\t{%1, %0|%0, %1}";
2238 else
2239 return "movss\t{%1, %0|%0, %1}";
2240 case 7:
2241 case 8:
2242 return "movss\t{%1, %0|%0, %1}";
2243
2244 case 9:
2245 case 10:
2246 return "movd\t{%1, %0|%0, %1}";
2247
2248 case 11:
2249 return "movq\t{%1, %0|%0, %1}";
2250
2251 default:
2252 abort();
2253 }
2254}
2255 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2256 (set (attr "mode")
2257 (cond [(eq_attr "alternative" "3,4,9,10")
2258 (const_string "SI")
2259 (eq_attr "alternative" "5")
2260 (if_then_else
2261 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2262 (const_int 0))
2263 (ne (symbol_ref "TARGET_SSE2")
2264 (const_int 0)))
2265 (eq (symbol_ref "optimize_size")
2266 (const_int 0)))
2267 (const_string "TI")
2268 (const_string "V4SF"))
2269 /* For architectures resolving dependencies on
2270 whole SSE registers use APS move to break dependency
2271 chains, otherwise use short move to avoid extra work.
2272
2273 Do the same for architectures resolving dependencies on
2274 the parts. While in DF mode it is better to always handle
2275 just register parts, the SF mode is different due to lack
2276 of instructions to load just part of the register. It is
2277 better to maintain the whole registers in single format
2278 to avoid problems on using packed logical operations. */
2279 (eq_attr "alternative" "6")
2280 (if_then_else
2281 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2282 (const_int 0))
2283 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2284 (const_int 0)))
2285 (const_string "V4SF")
2286 (const_string "SF"))
2287 (eq_attr "alternative" "11")
2288 (const_string "DI")]
2289 (const_string "SF")))])
2290
2291(define_insn "*movsf_1_nointerunit"
2292 [(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")
2293 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2294 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2295 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2296 && (reload_in_progress || reload_completed
2297 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2298 || GET_CODE (operands[1]) != CONST_DOUBLE
2299 || memory_operand (operands[0], SFmode))"
2300{
2301 switch (which_alternative)
2302 {
2303 case 0:
2304 if (REG_P (operands[1])
2305 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2306 {
2307 if (REGNO (operands[0]) == FIRST_STACK_REG
2308 && TARGET_USE_FFREEP)
2309 return "ffreep\t%y0";
2310 return "fstp\t%y0";
2311 }
2312 else if (STACK_TOP_P (operands[0]))
2313 return "fld%z1\t%y1";
2314 else
2315 return "fst\t%y0";
2316
2317 case 1:
2318 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319 return "fstp%z0\t%y0";
2320 else
2321 return "fst%z0\t%y0";
2322
2323 case 2:
2324 return standard_80387_constant_opcode (operands[1]);
2325
2326 case 3:
2327 case 4:
2328 return "mov{l}\t{%1, %0|%0, %1}";
2329 case 5:
2330 if (get_attr_mode (insn) == MODE_TI)
2331 return "pxor\t%0, %0";
2332 else
2333 return "xorps\t%0, %0";
2334 case 6:
2335 if (get_attr_mode (insn) == MODE_V4SF)
2336 return "movaps\t{%1, %0|%0, %1}";
2337 else
2338 return "movss\t{%1, %0|%0, %1}";
2339 case 7:
2340 case 8:
2341 return "movss\t{%1, %0|%0, %1}";
2342
2343 case 9:
2344 case 10:
2345 return "movd\t{%1, %0|%0, %1}";
2346
2347 case 11:
2348 return "movq\t{%1, %0|%0, %1}";
2349
2350 default:
2351 abort();
2352 }
2353}
2354 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2355 (set (attr "mode")
2356 (cond [(eq_attr "alternative" "3,4,9,10")
2357 (const_string "SI")
2358 (eq_attr "alternative" "5")
2359 (if_then_else
2360 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2361 (const_int 0))
2362 (ne (symbol_ref "TARGET_SSE2")
2363 (const_int 0)))
2364 (eq (symbol_ref "optimize_size")
2365 (const_int 0)))
2366 (const_string "TI")
2367 (const_string "V4SF"))
2368 /* For architectures resolving dependencies on
2369 whole SSE registers use APS move to break dependency
2370 chains, otherwise use short move to avoid extra work.
2371
2372 Do the same for architectures resolving dependencies on
2373 the parts. While in DF mode it is better to always handle
2374 just register parts, the SF mode is different due to lack
2375 of instructions to load just part of the register. It is
2376 better to maintain the whole registers in single format
2377 to avoid problems on using packed logical operations. */
2378 (eq_attr "alternative" "6")
2379 (if_then_else
2380 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2381 (const_int 0))
2382 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2383 (const_int 0)))
2384 (const_string "V4SF")
2385 (const_string "SF"))
2386 (eq_attr "alternative" "11")
2387 (const_string "DI")]
2388 (const_string "SF")))])
2389
2390(define_insn "*swapsf"
2391 [(set (match_operand:SF 0 "register_operand" "+f")
2392 (match_operand:SF 1 "register_operand" "+f"))
2393 (set (match_dup 1)
2394 (match_dup 0))]
2395 "reload_completed || !TARGET_SSE"
2396{
2397 if (STACK_TOP_P (operands[0]))
2398 return "fxch\t%1";
2399 else
2400 return "fxch\t%0";
2401}
2402 [(set_attr "type" "fxch")
2403 (set_attr "mode" "SF")])
2404
2405(define_expand "movdf"
2406 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2407 (match_operand:DF 1 "general_operand" ""))]
2408 ""
2409 "ix86_expand_move (DFmode, operands); DONE;")
2410
2411;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2412;; Size of pushdf using integer instructions is 2+2*memory operand size
2413;; On the average, pushdf using integers can be still shorter. Allow this
2414;; pattern for optimize_size too.
2415
2416(define_insn "*pushdf_nointeger"
2417 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2418 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2419 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2420{
2421 /* This insn should be already split before reg-stack. */
2422 abort ();
2423}
2424 [(set_attr "type" "multi")
2425 (set_attr "mode" "DF,SI,SI,DF")])
2426
2427(define_insn "*pushdf_integer"
2428 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2429 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2430 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2431{
2432 /* This insn should be already split before reg-stack. */
2433 abort ();
2434}
2435 [(set_attr "type" "multi")
2436 (set_attr "mode" "DF,SI,DF")])
2437
2438;; %%% Kill this when call knows how to work this out.
2439(define_split
2440 [(set (match_operand:DF 0 "push_operand" "")
2441 (match_operand:DF 1 "any_fp_register_operand" ""))]
2442 "!TARGET_64BIT && reload_completed"
2443 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2444 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2445 "")
2446
2447(define_split
2448 [(set (match_operand:DF 0 "push_operand" "")
2449 (match_operand:DF 1 "any_fp_register_operand" ""))]
2450 "TARGET_64BIT && reload_completed"
2451 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2452 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2453 "")
2454
2455(define_split
2456 [(set (match_operand:DF 0 "push_operand" "")
2457 (match_operand:DF 1 "general_operand" ""))]
2458 "reload_completed"
2459 [(const_int 0)]
2460 "ix86_split_long_move (operands); DONE;")
2461
2462;; Moving is usually shorter when only FP registers are used. This separate
2463;; movdf pattern avoids the use of integer registers for FP operations
2464;; when optimizing for size.
2465
2466(define_insn "*movdf_nointeger"
2467 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2468 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2469 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2470 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2471 && (reload_in_progress || reload_completed
2472 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2473 || GET_CODE (operands[1]) != CONST_DOUBLE
2474 || memory_operand (operands[0], DFmode))"
2475{
2476 switch (which_alternative)
2477 {
2478 case 0:
2479 if (REG_P (operands[1])
2480 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2481 {
2482 if (REGNO (operands[0]) == FIRST_STACK_REG
2483 && TARGET_USE_FFREEP)
2484 return "ffreep\t%y0";
2485 return "fstp\t%y0";
2486 }
2487 else if (STACK_TOP_P (operands[0]))
2488 return "fld%z1\t%y1";
2489 else
2490 return "fst\t%y0";
2491
2492 case 1:
2493 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2494 return "fstp%z0\t%y0";
2495 else
2496 return "fst%z0\t%y0";
2497
2498 case 2:
2499 return standard_80387_constant_opcode (operands[1]);
2500
2501 case 3:
2502 case 4:
2503 return "#";
2504 case 5:
2505 switch (get_attr_mode (insn))
2506 {
2507 case MODE_V4SF:
2508 return "xorps\t%0, %0";
2509 case MODE_V2DF:
2510 return "xorpd\t%0, %0";
2511 case MODE_TI:
2512 return "pxor\t%0, %0";
2513 default:
2514 abort ();
2515 }
2516 case 6:
2517 switch (get_attr_mode (insn))
2518 {
2519 case MODE_V4SF:
2520 return "movaps\t{%1, %0|%0, %1}";
2521 case MODE_V2DF:
2522 return "movapd\t{%1, %0|%0, %1}";
2523 case MODE_DF:
2524 return "movsd\t{%1, %0|%0, %1}";
2525 default:
2526 abort ();
2527 }
2528 case 7:
2529 if (get_attr_mode (insn) == MODE_V2DF)
2530 return "movlpd\t{%1, %0|%0, %1}";
2531 else
2532 return "movsd\t{%1, %0|%0, %1}";
2533 case 8:
2534 return "movsd\t{%1, %0|%0, %1}";
2535
2536 default:
2537 abort();
2538 }
2539}
2540 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2541 (set (attr "mode")
2542 (cond [(eq_attr "alternative" "3,4")
2543 (const_string "SI")
2544 /* xorps is one byte shorter. */
2545 (eq_attr "alternative" "5")
2546 (cond [(ne (symbol_ref "optimize_size")
2547 (const_int 0))
2548 (const_string "V4SF")
2549 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2550 (const_int 0))
2551 (const_string "TI")]
2552 (const_string "V2DF"))
2553 /* For architectures resolving dependencies on
2554 whole SSE registers use APD move to break dependency
2555 chains, otherwise use short move to avoid extra work.
2556
2557 movaps encodes one byte shorter. */
2558 (eq_attr "alternative" "6")
2559 (cond
2560 [(ne (symbol_ref "optimize_size")
2561 (const_int 0))
2562 (const_string "V4SF")
2563 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2564 (const_int 0))
2565 (const_string "V2DF")]
2566 (const_string "DF"))
2567 /* For architectures resolving dependencies on register
2568 parts we may avoid extra work to zero out upper part
2569 of register. */
2570 (eq_attr "alternative" "7")
2571 (if_then_else
2572 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2573 (const_int 0))
2574 (const_string "V2DF")
2575 (const_string "DF"))]
2576 (const_string "DF")))])
2577
2578(define_insn "*movdf_integer"
2579 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2580 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2581 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2582 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2583 && (reload_in_progress || reload_completed
2584 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2585 || GET_CODE (operands[1]) != CONST_DOUBLE
2586 || memory_operand (operands[0], DFmode))"
2587{
2588 switch (which_alternative)
2589 {
2590 case 0:
2591 if (REG_P (operands[1])
2592 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2593 {
2594 if (REGNO (operands[0]) == FIRST_STACK_REG
2595 && TARGET_USE_FFREEP)
2596 return "ffreep\t%y0";
2597 return "fstp\t%y0";
2598 }
2599 else if (STACK_TOP_P (operands[0]))
2600 return "fld%z1\t%y1";
2601 else
2602 return "fst\t%y0";
2603
2604 case 1:
2605 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2606 return "fstp%z0\t%y0";
2607 else
2608 return "fst%z0\t%y0";
2609
2610 case 2:
2611 return standard_80387_constant_opcode (operands[1]);
2612
2613 case 3:
2614 case 4:
2615 return "#";
2616
2617 case 5:
2618 switch (get_attr_mode (insn))
2619 {
2620 case MODE_V4SF:
2621 return "xorps\t%0, %0";
2622 case MODE_V2DF:
2623 return "xorpd\t%0, %0";
2624 case MODE_TI:
2625 return "pxor\t%0, %0";
2626 default:
2627 abort ();
2628 }
2629 case 6:
2630 switch (get_attr_mode (insn))
2631 {
2632 case MODE_V4SF:
2633 return "movaps\t{%1, %0|%0, %1}";
2634 case MODE_V2DF:
2635 return "movapd\t{%1, %0|%0, %1}";
2636 case MODE_DF:
2637 return "movsd\t{%1, %0|%0, %1}";
2638 default:
2639 abort ();
2640 }
2641 case 7:
2642 if (get_attr_mode (insn) == MODE_V2DF)
2643 return "movlpd\t{%1, %0|%0, %1}";
2644 else
2645 return "movsd\t{%1, %0|%0, %1}";
2646 case 8:
2647 return "movsd\t{%1, %0|%0, %1}";
2648
2649 default:
2650 abort();
2651 }
2652}
2653 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2654 (set (attr "mode")
2655 (cond [(eq_attr "alternative" "3,4")
2656 (const_string "SI")
2657 /* xorps is one byte shorter. */
2658 (eq_attr "alternative" "5")
2659 (cond [(ne (symbol_ref "optimize_size")
2660 (const_int 0))
2661 (const_string "V4SF")
2662 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2663 (const_int 0))
2664 (const_string "TI")]
2665 (const_string "V2DF"))
2666 /* For architectures resolving dependencies on
2667 whole SSE registers use APD move to break dependency
2668 chains, otherwise use short move to avoid extra work.
2669
2670 movaps encodes one byte shorter. */
2671 (eq_attr "alternative" "6")
2672 (cond
2673 [(ne (symbol_ref "optimize_size")
2674 (const_int 0))
2675 (const_string "V4SF")
2676 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2677 (const_int 0))
2678 (const_string "V2DF")]
2679 (const_string "DF"))
2680 /* For architectures resolving dependencies on register
2681 parts we may avoid extra work to zero out upper part
2682 of register. */
2683 (eq_attr "alternative" "7")
2684 (if_then_else
2685 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2686 (const_int 0))
2687 (const_string "V2DF")
2688 (const_string "DF"))]
2689 (const_string "DF")))])
2690
2691(define_split
2692 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2693 (match_operand:DF 1 "general_operand" ""))]
2694 "reload_completed
2695 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2696 && ! (ANY_FP_REG_P (operands[0]) ||
2697 (GET_CODE (operands[0]) == SUBREG
2698 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2699 && ! (ANY_FP_REG_P (operands[1]) ||
2700 (GET_CODE (operands[1]) == SUBREG
2701 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2702 [(const_int 0)]
2703 "ix86_split_long_move (operands); DONE;")
2704
2705(define_insn "*swapdf"
2706 [(set (match_operand:DF 0 "register_operand" "+f")
2707 (match_operand:DF 1 "register_operand" "+f"))
2708 (set (match_dup 1)
2709 (match_dup 0))]
2710 "reload_completed || !TARGET_SSE2"
2711{
2712 if (STACK_TOP_P (operands[0]))
2713 return "fxch\t%1";
2714 else
2715 return "fxch\t%0";
2716}
2717 [(set_attr "type" "fxch")
2718 (set_attr "mode" "DF")])
2719
2720(define_expand "movxf"
2721 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2722 (match_operand:XF 1 "general_operand" ""))]
2723 ""
2724 "ix86_expand_move (XFmode, operands); DONE;")
2725
2726;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727;; Size of pushdf using integer instructions is 3+3*memory operand size
2728;; Pushing using integer instructions is longer except for constants
2729;; and direct memory references.
2730;; (assuming that any given constant is pushed only once, but this ought to be
2731;; handled elsewhere).
2732
2733(define_insn "*pushxf_nointeger"
2734 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2735 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2736 "optimize_size"
2737{
2738 /* This insn should be already split before reg-stack. */
2739 abort ();
2740}
2741 [(set_attr "type" "multi")
2742 (set_attr "mode" "XF,SI,SI")])
2743
2744(define_insn "*pushxf_integer"
2745 [(set (match_operand:XF 0 "push_operand" "=<,<")
2746 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2747 "!optimize_size"
2748{
2749 /* This insn should be already split before reg-stack. */
2750 abort ();
2751}
2752 [(set_attr "type" "multi")
2753 (set_attr "mode" "XF,SI")])
2754
2755(define_split
2756 [(set (match_operand 0 "push_operand" "")
2757 (match_operand 1 "general_operand" ""))]
2758 "reload_completed
2759 && (GET_MODE (operands[0]) == XFmode
2760 || GET_MODE (operands[0]) == DFmode)
2761 && !ANY_FP_REG_P (operands[1])"
2762 [(const_int 0)]
2763 "ix86_split_long_move (operands); DONE;")
2764
2765(define_split
2766 [(set (match_operand:XF 0 "push_operand" "")
2767 (match_operand:XF 1 "any_fp_register_operand" ""))]
2768 "!TARGET_64BIT"
2769 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2770 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2771 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772
2773(define_split
2774 [(set (match_operand:XF 0 "push_operand" "")
2775 (match_operand:XF 1 "any_fp_register_operand" ""))]
2776 "TARGET_64BIT"
2777 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2778 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2779 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2780
2781;; Do not use integer registers when optimizing for size
2782(define_insn "*movxf_nointeger"
2783 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2784 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785 "optimize_size
2786 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2787 && (reload_in_progress || reload_completed
2788 || GET_CODE (operands[1]) != CONST_DOUBLE
2789 || memory_operand (operands[0], XFmode))"
2790{
2791 switch (which_alternative)
2792 {
2793 case 0:
2794 if (REG_P (operands[1])
2795 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2796 {
2797 if (REGNO (operands[0]) == FIRST_STACK_REG
2798 && TARGET_USE_FFREEP)
2799 return "ffreep\t%y0";
2800 return "fstp\t%y0";
2801 }
2802 else if (STACK_TOP_P (operands[0]))
2803 return "fld%z1\t%y1";
2804 else
2805 return "fst\t%y0";
2806
2807 case 1:
2808 /* There is no non-popping store to memory for XFmode. So if
2809 we need one, follow the store with a load. */
2810 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2811 return "fstp%z0\t%y0\;fld%z0\t%y0";
2812 else
2813 return "fstp%z0\t%y0";
2814
2815 case 2:
2816 return standard_80387_constant_opcode (operands[1]);
2817
2818 case 3: case 4:
2819 return "#";
2820 }
2821 abort();
2822}
2823 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824 (set_attr "mode" "XF,XF,XF,SI,SI")])
2825
2826(define_insn "*movxf_integer"
2827 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2828 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2829 "!optimize_size
2830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831 && (reload_in_progress || reload_completed
2832 || GET_CODE (operands[1]) != CONST_DOUBLE
2833 || memory_operand (operands[0], XFmode))"
2834{
2835 switch (which_alternative)
2836 {
2837 case 0:
2838 if (REG_P (operands[1])
2839 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2840 {
2841 if (REGNO (operands[0]) == FIRST_STACK_REG
2842 && TARGET_USE_FFREEP)
2843 return "ffreep\t%y0";
2844 return "fstp\t%y0";
2845 }
2846 else if (STACK_TOP_P (operands[0]))
2847 return "fld%z1\t%y1";
2848 else
2849 return "fst\t%y0";
2850
2851 case 1:
2852 /* There is no non-popping store to memory for XFmode. So if
2853 we need one, follow the store with a load. */
2854 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2855 return "fstp%z0\t%y0\;fld%z0\t%y0";
2856 else
2857 return "fstp%z0\t%y0";
2858
2859 case 2:
2860 return standard_80387_constant_opcode (operands[1]);
2861
2862 case 3: case 4:
2863 return "#";
2864 }
2865 abort();
2866}
2867 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2868 (set_attr "mode" "XF,XF,XF,SI,SI")])
2869
2870(define_split
2871 [(set (match_operand 0 "nonimmediate_operand" "")
2872 (match_operand 1 "general_operand" ""))]
2873 "reload_completed
2874 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2875 && GET_MODE (operands[0]) == XFmode
2876 && ! (ANY_FP_REG_P (operands[0]) ||
2877 (GET_CODE (operands[0]) == SUBREG
2878 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2879 && ! (ANY_FP_REG_P (operands[1]) ||
2880 (GET_CODE (operands[1]) == SUBREG
2881 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2882 [(const_int 0)]
2883 "ix86_split_long_move (operands); DONE;")
2884
2885(define_split
2886 [(set (match_operand 0 "register_operand" "")
2887 (match_operand 1 "memory_operand" ""))]
2888 "reload_completed
2889 && GET_CODE (operands[1]) == MEM
2890 && (GET_MODE (operands[0]) == XFmode
2891 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2892 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2893 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2894 [(set (match_dup 0) (match_dup 1))]
2895{
2896 rtx c = get_pool_constant (XEXP (operands[1], 0));
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
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
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
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:
3542 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3543 return "fstp%z0\t%y0";
3544
3545 else
3546 return "fst%z0\t%y0";
3547 case 2:
3548 return "cvtss2sd\t{%1, %0|%0, %1}";
3549
3550 default:
3551 abort ();
3552 }
3553}
3554 [(set_attr "type" "fmov,fmov,ssecvt")
3555 (set_attr "mode" "SF,XF,DF")])
3556
3557(define_insn "*extendsfdf2_1_sse_only"
3558 [(set (match_operand:DF 0 "register_operand" "=Y")
3559 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3560 "!TARGET_80387 && TARGET_SSE2
3561 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3562 "cvtss2sd\t{%1, %0|%0, %1}"
3563 [(set_attr "type" "ssecvt")
3564 (set_attr "mode" "DF")])
3565
3566(define_expand "extendsfxf2"
3567 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3568 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3569 "TARGET_80387"
3570{
3571 /* ??? Needed for compress_float_constant since all fp constants
3572 are LEGITIMATE_CONSTANT_P. */
3573 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3574 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3575 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3576 operands[1] = force_reg (SFmode, operands[1]);
3577})
3578
3579(define_insn "*extendsfxf2_1"
3580 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3581 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3582 "TARGET_80387
3583 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3584{
3585 switch (which_alternative)
3586 {
3587 case 0:
3588 if (REG_P (operands[1])
3589 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3590 return "fstp\t%y0";
3591 else if (STACK_TOP_P (operands[0]))
3592 return "fld%z1\t%y1";
3593 else
3594 return "fst\t%y0";
3595
3596 case 1:
3597 /* There is no non-popping store to memory for XFmode. So if
3598 we need one, follow the store with a load. */
3599 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3600 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3601 else
3602 return "fstp%z0\t%y0";
3603
3604 default:
3605 abort ();
3606 }
3607}
3608 [(set_attr "type" "fmov")
3609 (set_attr "mode" "SF,XF")])
3610
3611(define_expand "extenddfxf2"
3612 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3613 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3614 "TARGET_80387"
3615{
3616 /* ??? Needed for compress_float_constant since all fp constants
3617 are LEGITIMATE_CONSTANT_P. */
3618 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3619 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3620 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3621 operands[1] = force_reg (DFmode, operands[1]);
3622})
3623
3624(define_insn "*extenddfxf2_1"
3625 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3626 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3627 "TARGET_80387
3628 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3629{
3630 switch (which_alternative)
3631 {
3632 case 0:
3633 if (REG_P (operands[1])
3634 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635 return "fstp\t%y0";
3636 else if (STACK_TOP_P (operands[0]))
3637 return "fld%z1\t%y1";
3638 else
3639 return "fst\t%y0";
3640
3641 case 1:
3642 /* There is no non-popping store to memory for XFmode. So if
3643 we need one, follow the store with a load. */
3644 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3645 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3646 else
3647 return "fstp%z0\t%y0";
3648
3649 default:
3650 abort ();
3651 }
3652}
3653 [(set_attr "type" "fmov")
3654 (set_attr "mode" "DF,XF")])
3655
3656;; %%% This seems bad bad news.
3657;; This cannot output into an f-reg because there is no way to be sure
3658;; of truncating in that case. Otherwise this is just like a simple move
3659;; insn. So we pretend we can output to a reg in order to get better
3660;; register preferencing, but we really use a stack slot.
3661
3662(define_expand "truncdfsf2"
3663 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3664 (float_truncate:SF
3665 (match_operand:DF 1 "register_operand" "")))
3666 (clobber (match_dup 2))])]
3667 "TARGET_80387 || TARGET_SSE2"
3668 "
3669 if (TARGET_80387)
3670 operands[2] = assign_386_stack_local (SFmode, 0);
3671 else
3672 {
3673 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3674 DONE;
3675 }
3676")
3677
3678(define_insn "*truncdfsf2_1"
3679 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3680 (float_truncate:SF
3681 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3682 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3683 "TARGET_80387 && !TARGET_SSE2"
3684{
3685 switch (which_alternative)
3686 {
3687 case 0:
3688 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689 return "fstp%z0\t%y0";
3690 else
3691 return "fst%z0\t%y0";
3692 default:
3693 abort ();
3694 }
3695}
3696 [(set_attr "type" "fmov,multi,multi,multi")
3697 (set_attr "mode" "SF,SF,SF,SF")])
3698
3699(define_insn "*truncdfsf2_1_sse"
3700 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3701 (float_truncate:SF
3702 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3703 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3704 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3705{
3706 switch (which_alternative)
3707 {
3708 case 0:
3709 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3710 return "fstp%z0\t%y0";
3711 else
3712 return "fst%z0\t%y0";
3713 case 4:
3714 return "#";
3715 default:
3716 abort ();
3717 }
3718}
3719 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3720 (set_attr "mode" "SF,SF,SF,SF,DF")])
3721
3722(define_insn "*truncdfsf2_1_sse_nooverlap"
3723 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3724 (float_truncate:SF
3725 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3726 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3727 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3728{
3729 switch (which_alternative)
3730 {
3731 case 0:
3732 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3733 return "fstp%z0\t%y0";
3734 else
3735 return "fst%z0\t%y0";
3736 case 4:
3737 return "#";
3738 default:
3739 abort ();
3740 }
3741}
3742 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3743 (set_attr "mode" "SF,SF,SF,SF,DF")])
3744
3745(define_insn "*truncdfsf2_2"
3746 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3747 (float_truncate:SF
3748 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3749 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3750 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3751{
3752 switch (which_alternative)
3753 {
3754 case 0:
3755 case 1:
3756 return "cvtsd2ss\t{%1, %0|%0, %1}";
3757 case 2:
3758 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3759 return "fstp%z0\t%y0";
3760 else
3761 return "fst%z0\t%y0";
3762 default:
3763 abort ();
3764 }
3765}
3766 [(set_attr "type" "ssecvt,ssecvt,fmov")
3767 (set_attr "athlon_decode" "vector,double,*")
3768 (set_attr "mode" "SF,SF,SF")])
3769
3770(define_insn "*truncdfsf2_2_nooverlap"
3771 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3772 (float_truncate:SF
3773 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3774 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3775 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3776{
3777 switch (which_alternative)
3778 {
3779 case 0:
3780 return "#";
3781 case 1:
3782 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783 return "fstp%z0\t%y0";
3784 else
3785 return "fst%z0\t%y0";
3786 default:
3787 abort ();
3788 }
3789}
3790 [(set_attr "type" "ssecvt,fmov")
3791 (set_attr "mode" "DF,SF")])
3792
3793(define_insn "*truncdfsf2_3"
3794 [(set (match_operand:SF 0 "memory_operand" "=m")
3795 (float_truncate:SF
3796 (match_operand:DF 1 "register_operand" "f")))]
3797 "TARGET_80387"
3798{
3799 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3800 return "fstp%z0\t%y0";
3801 else
3802 return "fst%z0\t%y0";
3803}
3804 [(set_attr "type" "fmov")
3805 (set_attr "mode" "SF")])
3806
3807(define_insn "truncdfsf2_sse_only"
3808 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3809 (float_truncate:SF
3810 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3811 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3812 "cvtsd2ss\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "ssecvt")
3814 (set_attr "athlon_decode" "vector,double")
3815 (set_attr "mode" "SF")])
3816
3817(define_insn "*truncdfsf2_sse_only_nooverlap"
3818 [(set (match_operand:SF 0 "register_operand" "=&Y")
3819 (float_truncate:SF
3820 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3821 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3822 "#"
3823 [(set_attr "type" "ssecvt")
3824 (set_attr "mode" "DF")])
3825
3826(define_split
3827 [(set (match_operand:SF 0 "memory_operand" "")
3828 (float_truncate:SF
3829 (match_operand:DF 1 "register_operand" "")))
3830 (clobber (match_operand:SF 2 "memory_operand" ""))]
3831 "TARGET_80387"
3832 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3833 "")
3834
3835; Avoid possible reformatting penalty on the destination by first
3836; zeroing it out
3837(define_split
3838 [(set (match_operand:SF 0 "register_operand" "")
3839 (float_truncate:SF
3840 (match_operand:DF 1 "nonimmediate_operand" "")))
3841 (clobber (match_operand 2 "" ""))]
3842 "TARGET_80387 && reload_completed
3843 && SSE_REG_P (operands[0])
3844 && !STACK_REG_P (operands[1])"
3845 [(const_int 0)]
3846{
3847 rtx src, dest;
3848 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3849 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3850 else
3851 {
3852 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3853 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3854 /* simplify_gen_subreg refuses to widen memory references. */
3855 if (GET_CODE (src) == SUBREG)
3856 alter_subreg (&src);
3857 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3858 abort ();
3859 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3860 emit_insn (gen_cvtsd2ss (dest, dest, src));
3861 }
3862 DONE;
3863})
3864
3865(define_split
3866 [(set (match_operand:SF 0 "register_operand" "")
3867 (float_truncate:SF
3868 (match_operand:DF 1 "nonimmediate_operand" "")))]
3869 "TARGET_80387 && reload_completed
3870 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3871 [(const_int 0)]
3872{
3873 rtx src, dest;
3874 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3875 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3876 /* simplify_gen_subreg refuses to widen memory references. */
3877 if (GET_CODE (src) == SUBREG)
3878 alter_subreg (&src);
3879 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3880 abort ();
3881 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3882 emit_insn (gen_cvtsd2ss (dest, dest, src));
3883 DONE;
3884})
3885
3886(define_split
3887 [(set (match_operand:SF 0 "register_operand" "")
3888 (float_truncate:SF
3889 (match_operand:DF 1 "fp_register_operand" "")))
3890 (clobber (match_operand:SF 2 "memory_operand" ""))]
3891 "TARGET_80387 && reload_completed"
3892 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3893 (set (match_dup 0) (match_dup 2))]
3894 "")
3895
3896(define_expand "truncxfsf2"
3897 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3898 (float_truncate:SF
3899 (match_operand:XF 1 "register_operand" "")))
3900 (clobber (match_dup 2))])]
3901 "TARGET_80387"
3902 "operands[2] = assign_386_stack_local (SFmode, 0);")
3903
3904(define_insn "*truncxfsf2_1"
3905 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3906 (float_truncate:SF
3907 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3908 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3909 "TARGET_80387"
3910{
3911 switch (which_alternative)
3912 {
3913 case 0:
3914 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3915 return "fstp%z0\t%y0";
3916 else
3917 return "fst%z0\t%y0";
3918 default:
3919 abort();
3920 }
3921}
3922 [(set_attr "type" "fmov,multi,multi,multi")
3923 (set_attr "mode" "SF")])
3924
3925(define_insn "*truncxfsf2_2"
3926 [(set (match_operand:SF 0 "memory_operand" "=m")
3927 (float_truncate:SF
3928 (match_operand:XF 1 "register_operand" "f")))]
3929 "TARGET_80387"
3930{
3931 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3932 return "fstp%z0\t%y0";
3933 else
3934 return "fst%z0\t%y0";
3935}
3936 [(set_attr "type" "fmov")
3937 (set_attr "mode" "SF")])
3938
3939(define_split
3940 [(set (match_operand:SF 0 "memory_operand" "")
3941 (float_truncate:SF
3942 (match_operand:XF 1 "register_operand" "")))
3943 (clobber (match_operand:SF 2 "memory_operand" ""))]
3944 "TARGET_80387"
3945 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3946 "")
3947
3948(define_split
3949 [(set (match_operand:SF 0 "register_operand" "")
3950 (float_truncate:SF
3951 (match_operand:XF 1 "register_operand" "")))
3952 (clobber (match_operand:SF 2 "memory_operand" ""))]
3953 "TARGET_80387 && reload_completed"
3954 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3955 (set (match_dup 0) (match_dup 2))]
3956 "")
3957
3958(define_expand "truncxfdf2"
3959 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3960 (float_truncate:DF
3961 (match_operand:XF 1 "register_operand" "")))
3962 (clobber (match_dup 2))])]
3963 "TARGET_80387"
3964 "operands[2] = assign_386_stack_local (DFmode, 0);")
3965
3966(define_insn "*truncxfdf2_1"
3967 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3968 (float_truncate:DF
3969 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971 "TARGET_80387"
3972{
3973 switch (which_alternative)
3974 {
3975 case 0:
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3978 else
3979 return "fst%z0\t%y0";
3980 default:
3981 abort();
3982 }
3983 abort ();
3984}
3985 [(set_attr "type" "fmov,multi,multi,multi")
3986 (set_attr "mode" "DF")])
3987
3988(define_insn "*truncxfdf2_2"
3989 [(set (match_operand:DF 0 "memory_operand" "=m")
3990 (float_truncate:DF
3991 (match_operand:XF 1 "register_operand" "f")))]
3992 "TARGET_80387"
3993{
3994 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3995 return "fstp%z0\t%y0";
3996 else
3997 return "fst%z0\t%y0";
3998}
3999 [(set_attr "type" "fmov")
4000 (set_attr "mode" "DF")])
4001
4002(define_split
4003 [(set (match_operand:DF 0 "memory_operand" "")
4004 (float_truncate:DF
4005 (match_operand:XF 1 "register_operand" "")))
4006 (clobber (match_operand:DF 2 "memory_operand" ""))]
4007 "TARGET_80387"
4008 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4009 "")
4010
4011(define_split
4012 [(set (match_operand:DF 0 "register_operand" "")
4013 (float_truncate:DF
4014 (match_operand:XF 1 "register_operand" "")))
4015 (clobber (match_operand:DF 2 "memory_operand" ""))]
4016 "TARGET_80387 && reload_completed"
4017 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4018 (set (match_dup 0) (match_dup 2))]
4019 "")
4020
4021
4022;; %%% Break up all these bad boys.
4023
4024;; Signed conversion to DImode.
4025
4026(define_expand "fix_truncxfdi2"
4027 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4029 "TARGET_80387"
4030 "")
4031
4032(define_expand "fix_truncdfdi2"
4033 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4034 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4035 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4036{
4037 if (TARGET_64BIT && TARGET_SSE2)
4038 {
4039 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4040 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4041 if (out != operands[0])
4042 emit_move_insn (operands[0], out);
4043 DONE;
4044 }
4045})
4046
4047(define_expand "fix_truncsfdi2"
4048 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4049 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4050 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4051{
4052 if (TARGET_SSE && TARGET_64BIT)
4053 {
4054 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4055 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4056 if (out != operands[0])
4057 emit_move_insn (operands[0], out);
4058 DONE;
4059 }
4060})
4061
4062;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4063;; of the machinery.
4064(define_insn_and_split "*fix_truncdi_1"
4065 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4066 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4067 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4068 && !reload_completed && !reload_in_progress
4069 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4070 "#"
4071 "&& 1"
4072 [(const_int 0)]
4073{
4074 ix86_optimize_mode_switching = 1;
4075 operands[2] = assign_386_stack_local (HImode, 1);
4076 operands[3] = assign_386_stack_local (HImode, 2);
4077 if (memory_operand (operands[0], VOIDmode))
4078 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4079 operands[2], operands[3]));
4080 else
4081 {
4082 operands[4] = assign_386_stack_local (DImode, 0);
4083 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4084 operands[2], operands[3],
4085 operands[4]));
4086 }
4087 DONE;
4088}
4089 [(set_attr "type" "fistp")
4090 (set_attr "mode" "DI")])
4091
4092(define_insn "fix_truncdi_nomemory"
4093 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4094 (fix:DI (match_operand 1 "register_operand" "f,f")))
4095 (use (match_operand:HI 2 "memory_operand" "m,m"))
4096 (use (match_operand:HI 3 "memory_operand" "m,m"))
4097 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4098 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4099 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4100 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4101 "#"
4102 [(set_attr "type" "fistp")
4103 (set_attr "mode" "DI")])
4104
4105(define_insn "fix_truncdi_memory"
4106 [(set (match_operand:DI 0 "memory_operand" "=m")
4107 (fix:DI (match_operand 1 "register_operand" "f")))
4108 (use (match_operand:HI 2 "memory_operand" "m"))
4109 (use (match_operand:HI 3 "memory_operand" "m"))
4110 (clobber (match_scratch:DF 4 "=&1f"))]
4111 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4112 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4113 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4114 [(set_attr "type" "fistp")
4115 (set_attr "mode" "DI")])
4116
4117(define_split
4118 [(set (match_operand:DI 0 "register_operand" "")
4119 (fix:DI (match_operand 1 "register_operand" "")))
4120 (use (match_operand:HI 2 "memory_operand" ""))
4121 (use (match_operand:HI 3 "memory_operand" ""))
4122 (clobber (match_operand:DI 4 "memory_operand" ""))
4123 (clobber (match_scratch 5 ""))]
4124 "reload_completed"
4125 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4126 (use (match_dup 2))
4127 (use (match_dup 3))
4128 (clobber (match_dup 5))])
4129 (set (match_dup 0) (match_dup 4))]
4130 "")
4131
4132(define_split
4133 [(set (match_operand:DI 0 "memory_operand" "")
4134 (fix:DI (match_operand 1 "register_operand" "")))
4135 (use (match_operand:HI 2 "memory_operand" ""))
4136 (use (match_operand:HI 3 "memory_operand" ""))
4137 (clobber (match_operand:DI 4 "memory_operand" ""))
4138 (clobber (match_scratch 5 ""))]
4139 "reload_completed"
4140 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4141 (use (match_dup 2))
4142 (use (match_dup 3))
4143 (clobber (match_dup 5))])]
4144 "")
4145
4146;; When SSE available, it is always faster to use it!
4147(define_insn "fix_truncsfdi_sse"
4148 [(set (match_operand:DI 0 "register_operand" "=r,r")
4149 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4150 "TARGET_64BIT && TARGET_SSE"
4151 "cvttss2si{q}\t{%1, %0|%0, %1}"
4152 [(set_attr "type" "sseicvt")
4153 (set_attr "mode" "SF")
4154 (set_attr "athlon_decode" "double,vector")])
4155
4156;; Avoid vector decoded form of the instruction.
4157(define_peephole2
4158 [(match_scratch:SF 2 "x")
4159 (set (match_operand:DI 0 "register_operand" "")
4160 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4161 "TARGET_K8 && !optimize_size"
4162 [(set (match_dup 2) (match_dup 1))
4163 (set (match_dup 0) (fix:DI (match_dup 2)))]
4164 "")
4165
4166(define_insn "fix_truncdfdi_sse"
4167 [(set (match_operand:DI 0 "register_operand" "=r,r")
4168 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4169 "TARGET_64BIT && TARGET_SSE2"
4170 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4171 [(set_attr "type" "sseicvt,sseicvt")
4172 (set_attr "mode" "DF")
4173 (set_attr "athlon_decode" "double,vector")])
4174
4175;; Avoid vector decoded form of the instruction.
4176(define_peephole2
4177 [(match_scratch:DF 2 "Y")
4178 (set (match_operand:DI 0 "register_operand" "")
4179 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4180 "TARGET_K8 && !optimize_size"
4181 [(set (match_dup 2) (match_dup 1))
4182 (set (match_dup 0) (fix:DI (match_dup 2)))]
4183 "")
4184
4185;; Signed conversion to SImode.
4186
4187(define_expand "fix_truncxfsi2"
4188 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4189 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4190 "TARGET_80387"
4191 "")
4192
4193(define_expand "fix_truncdfsi2"
4194 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4195 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4196 "TARGET_80387 || TARGET_SSE2"
4197{
4198 if (TARGET_SSE2)
4199 {
4200 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4201 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4202 if (out != operands[0])
4203 emit_move_insn (operands[0], out);
4204 DONE;
4205 }
4206})
4207
4208(define_expand "fix_truncsfsi2"
4209 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4210 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4211 "TARGET_80387 || TARGET_SSE"
4212{
4213 if (TARGET_SSE)
4214 {
4215 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4216 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4217 if (out != operands[0])
4218 emit_move_insn (operands[0], out);
4219 DONE;
4220 }
4221})
4222
4223;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4224;; of the machinery.
4225(define_insn_and_split "*fix_truncsi_1"
4226 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4227 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4228 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4229 && !reload_completed && !reload_in_progress
4230 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4231 "#"
4232 "&& 1"
4233 [(const_int 0)]
4234{
4235 ix86_optimize_mode_switching = 1;
4236 operands[2] = assign_386_stack_local (HImode, 1);
4237 operands[3] = assign_386_stack_local (HImode, 2);
4238 if (memory_operand (operands[0], VOIDmode))
4239 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4240 operands[2], operands[3]));
4241 else
4242 {
4243 operands[4] = assign_386_stack_local (SImode, 0);
4244 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4245 operands[2], operands[3],
4246 operands[4]));
4247 }
4248 DONE;
4249}
4250 [(set_attr "type" "fistp")
4251 (set_attr "mode" "SI")])
4252
4253(define_insn "fix_truncsi_nomemory"
4254 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4255 (fix:SI (match_operand 1 "register_operand" "f,f")))
4256 (use (match_operand:HI 2 "memory_operand" "m,m"))
4257 (use (match_operand:HI 3 "memory_operand" "m,m"))
4258 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4259 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4260 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4261 "#"
4262 [(set_attr "type" "fistp")
4263 (set_attr "mode" "SI")])
4264
4265(define_insn "fix_truncsi_memory"
4266 [(set (match_operand:SI 0 "memory_operand" "=m")
4267 (fix:SI (match_operand 1 "register_operand" "f")))
4268 (use (match_operand:HI 2 "memory_operand" "m"))
4269 (use (match_operand:HI 3 "memory_operand" "m"))]
4270 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4271 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4272 "* return output_fix_trunc (insn, operands);"
4273 [(set_attr "type" "fistp")
4274 (set_attr "mode" "SI")])
4275
4276;; When SSE available, it is always faster to use it!
4277(define_insn "fix_truncsfsi_sse"
4278 [(set (match_operand:SI 0 "register_operand" "=r,r")
4279 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4280 "TARGET_SSE"
4281 "cvttss2si\t{%1, %0|%0, %1}"
4282 [(set_attr "type" "sseicvt")
4283 (set_attr "mode" "DF")
4284 (set_attr "athlon_decode" "double,vector")])
4285
4286;; Avoid vector decoded form of the instruction.
4287(define_peephole2
4288 [(match_scratch:SF 2 "x")
4289 (set (match_operand:SI 0 "register_operand" "")
4290 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4291 "TARGET_K8 && !optimize_size"
4292 [(set (match_dup 2) (match_dup 1))
4293 (set (match_dup 0) (fix:SI (match_dup 2)))]
4294 "")
4295
4296(define_insn "fix_truncdfsi_sse"
4297 [(set (match_operand:SI 0 "register_operand" "=r,r")
4298 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4299 "TARGET_SSE2"
4300 "cvttsd2si\t{%1, %0|%0, %1}"
4301 [(set_attr "type" "sseicvt")
4302 (set_attr "mode" "DF")
4303 (set_attr "athlon_decode" "double,vector")])
4304
4305;; Avoid vector decoded form of the instruction.
4306(define_peephole2
4307 [(match_scratch:DF 2 "Y")
4308 (set (match_operand:SI 0 "register_operand" "")
4309 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4310 "TARGET_K8 && !optimize_size"
4311 [(set (match_dup 2) (match_dup 1))
4312 (set (match_dup 0) (fix:SI (match_dup 2)))]
4313 "")
4314
4315(define_split
4316 [(set (match_operand:SI 0 "register_operand" "")
4317 (fix:SI (match_operand 1 "register_operand" "")))
4318 (use (match_operand:HI 2 "memory_operand" ""))
4319 (use (match_operand:HI 3 "memory_operand" ""))
4320 (clobber (match_operand:SI 4 "memory_operand" ""))]
4321 "reload_completed"
4322 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4323 (use (match_dup 2))
4324 (use (match_dup 3))])
4325 (set (match_dup 0) (match_dup 4))]
4326 "")
4327
4328(define_split
4329 [(set (match_operand:SI 0 "memory_operand" "")
4330 (fix:SI (match_operand 1 "register_operand" "")))
4331 (use (match_operand:HI 2 "memory_operand" ""))
4332 (use (match_operand:HI 3 "memory_operand" ""))
4333 (clobber (match_operand:SI 4 "memory_operand" ""))]
4334 "reload_completed"
4335 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4336 (use (match_dup 2))
4337 (use (match_dup 3))])]
4338 "")
4339
4340;; Signed conversion to HImode.
4341
4342(define_expand "fix_truncxfhi2"
4343 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4344 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4345 "TARGET_80387"
4346 "")
4347
4348(define_expand "fix_truncdfhi2"
4349 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4350 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4351 "TARGET_80387 && !TARGET_SSE2"
4352 "")
4353
4354(define_expand "fix_truncsfhi2"
4355 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4356 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4357 "TARGET_80387 && !TARGET_SSE"
4358 "")
4359
4360;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4361;; of the machinery.
4362(define_insn_and_split "*fix_trunchi_1"
4363 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4364 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4365 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4366 && !reload_completed && !reload_in_progress
4367 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4368 "#"
4369 ""
4370 [(const_int 0)]
4371{
4372 ix86_optimize_mode_switching = 1;
4373 operands[2] = assign_386_stack_local (HImode, 1);
4374 operands[3] = assign_386_stack_local (HImode, 2);
4375 if (memory_operand (operands[0], VOIDmode))
4376 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4377 operands[2], operands[3]));
4378 else
4379 {
4380 operands[4] = assign_386_stack_local (HImode, 0);
4381 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4382 operands[2], operands[3],
4383 operands[4]));
4384 }
4385 DONE;
4386}
4387 [(set_attr "type" "fistp")
4388 (set_attr "mode" "HI")])
4389
4390(define_insn "fix_trunchi_nomemory"
4391 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4392 (fix:HI (match_operand 1 "register_operand" "f,f")))
4393 (use (match_operand:HI 2 "memory_operand" "m,m"))
4394 (use (match_operand:HI 3 "memory_operand" "m,m"))
4395 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4396 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4397 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4398 "#"
4399 [(set_attr "type" "fistp")
4400 (set_attr "mode" "HI")])
4401
4402(define_insn "fix_trunchi_memory"
4403 [(set (match_operand:HI 0 "memory_operand" "=m")
4404 (fix:HI (match_operand 1 "register_operand" "f")))
4405 (use (match_operand:HI 2 "memory_operand" "m"))
4406 (use (match_operand:HI 3 "memory_operand" "m"))]
4407 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4408 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4409 "* return output_fix_trunc (insn, operands);"
4410 [(set_attr "type" "fistp")
4411 (set_attr "mode" "HI")])
4412
4413(define_split
4414 [(set (match_operand:HI 0 "memory_operand" "")
4415 (fix:HI (match_operand 1 "register_operand" "")))
4416 (use (match_operand:HI 2 "memory_operand" ""))
4417 (use (match_operand:HI 3 "memory_operand" ""))
4418 (clobber (match_operand:HI 4 "memory_operand" ""))]
4419 "reload_completed"
4420 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4421 (use (match_dup 2))
4422 (use (match_dup 3))])]
4423 "")
4424
4425(define_split
4426 [(set (match_operand:HI 0 "register_operand" "")
4427 (fix:HI (match_operand 1 "register_operand" "")))
4428 (use (match_operand:HI 2 "memory_operand" ""))
4429 (use (match_operand:HI 3 "memory_operand" ""))
4430 (clobber (match_operand:HI 4 "memory_operand" ""))]
4431 "reload_completed"
4432 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4433 (use (match_dup 2))
4434 (use (match_dup 3))
4435 (clobber (match_dup 4))])
4436 (set (match_dup 0) (match_dup 4))]
4437 "")
4438
4439;; %% Not used yet.
4440(define_insn "x86_fnstcw_1"
4441 [(set (match_operand:HI 0 "memory_operand" "=m")
4442 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4443 "TARGET_80387"
4444 "fnstcw\t%0"
4445 [(set_attr "length" "2")
4446 (set_attr "mode" "HI")
4447 (set_attr "unit" "i387")
4448 (set_attr "ppro_uops" "few")])
4449
4450(define_insn "x86_fldcw_1"
4451 [(set (reg:HI 18)
4452 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4453 "TARGET_80387"
4454 "fldcw\t%0"
4455 [(set_attr "length" "2")
4456 (set_attr "mode" "HI")
4457 (set_attr "unit" "i387")
4458 (set_attr "athlon_decode" "vector")
4459 (set_attr "ppro_uops" "few")])
4460
4461;; Conversion between fixed point and floating point.
4462
4463;; Even though we only accept memory inputs, the backend _really_
4464;; wants to be able to do this between registers.
4465
4466(define_expand "floathisf2"
4467 [(set (match_operand:SF 0 "register_operand" "")
4468 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4469 "TARGET_SSE || TARGET_80387"
4470{
4471 if (TARGET_SSE && TARGET_SSE_MATH)
4472 {
4473 emit_insn (gen_floatsisf2 (operands[0],
4474 convert_to_mode (SImode, operands[1], 0)));
4475 DONE;
4476 }
4477})
4478
4479(define_insn "*floathisf2_1"
4480 [(set (match_operand:SF 0 "register_operand" "=f,f")
4481 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4482 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4483 "@
4484 fild%z1\t%1
4485 #"
4486 [(set_attr "type" "fmov,multi")
4487 (set_attr "mode" "SF")
4488 (set_attr "fp_int_src" "true")])
4489
4490(define_expand "floatsisf2"
4491 [(set (match_operand:SF 0 "register_operand" "")
4492 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4493 "TARGET_SSE || TARGET_80387"
4494 "")
4495
4496(define_insn "*floatsisf2_i387"
4497 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4498 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4499 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4500 "@
4501 fild%z1\t%1
4502 #
4503 cvtsi2ss\t{%1, %0|%0, %1}
4504 cvtsi2ss\t{%1, %0|%0, %1}"
4505 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4506 (set_attr "mode" "SF")
4507 (set_attr "athlon_decode" "*,*,vector,double")
4508 (set_attr "fp_int_src" "true")])
4509
4510(define_insn "*floatsisf2_sse"
4511 [(set (match_operand:SF 0 "register_operand" "=x,x")
4512 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4513 "TARGET_SSE"
4514 "cvtsi2ss\t{%1, %0|%0, %1}"
4515 [(set_attr "type" "sseicvt")
4516 (set_attr "mode" "SF")
4517 (set_attr "athlon_decode" "vector,double")
4518 (set_attr "fp_int_src" "true")])
4519
4520; Avoid possible reformatting penalty on the destination by first
4521; zeroing it out
4522(define_split
4523 [(set (match_operand:SF 0 "register_operand" "")
4524 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4526 && SSE_REG_P (operands[0])"
4527 [(const_int 0)]
4528{
4529 rtx dest;
4530 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4531 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4532 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4533 DONE;
4534})
4535
4536(define_expand "floatdisf2"
4537 [(set (match_operand:SF 0 "register_operand" "")
4538 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4539 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4540 "")
4541
4542(define_insn "*floatdisf2_i387_only"
4543 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4544 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4545 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4546 "@
4547 fild%z1\t%1
4548 #"
4549 [(set_attr "type" "fmov,multi")
4550 (set_attr "mode" "SF")
4551 (set_attr "fp_int_src" "true")])
4552
4553(define_insn "*floatdisf2_i387"
4554 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4555 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4556 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4557 "@
4558 fild%z1\t%1
4559 #
4560 cvtsi2ss{q}\t{%1, %0|%0, %1}
4561 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4563 (set_attr "mode" "SF")
4564 (set_attr "athlon_decode" "*,*,vector,double")
4565 (set_attr "fp_int_src" "true")])
4566
4567(define_insn "*floatdisf2_sse"
4568 [(set (match_operand:SF 0 "register_operand" "=x,x")
4569 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4570 "TARGET_64BIT && TARGET_SSE"
4571 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4572 [(set_attr "type" "sseicvt")
4573 (set_attr "mode" "SF")
4574 (set_attr "athlon_decode" "vector,double")
4575 (set_attr "fp_int_src" "true")])
4576
4577; Avoid possible reformatting penalty on the destination by first
4578; zeroing it out
4579(define_split
4580 [(set (match_operand:SF 0 "register_operand" "")
4581 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4582 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4583 && SSE_REG_P (operands[0])"
4584 [(const_int 0)]
4585{
4586 rtx dest;
4587 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4588 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4589 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4590 DONE;
4591})
4592
4593(define_expand "floathidf2"
4594 [(set (match_operand:DF 0 "register_operand" "")
4595 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4596 "TARGET_SSE2 || TARGET_80387"
4597{
4598 if (TARGET_SSE && TARGET_SSE_MATH)
4599 {
4600 emit_insn (gen_floatsidf2 (operands[0],
4601 convert_to_mode (SImode, operands[1], 0)));
4602 DONE;
4603 }
4604})
4605
4606(define_insn "*floathidf2_1"
4607 [(set (match_operand:DF 0 "register_operand" "=f,f")
4608 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4609 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4610 "@
4611 fild%z1\t%1
4612 #"
4613 [(set_attr "type" "fmov,multi")
4614 (set_attr "mode" "DF")
4615 (set_attr "fp_int_src" "true")])
4616
4617(define_expand "floatsidf2"
4618 [(set (match_operand:DF 0 "register_operand" "")
4619 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4620 "TARGET_80387 || TARGET_SSE2"
4621 "")
4622
4623(define_insn "*floatsidf2_i387"
4624 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4625 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4626 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4627 "@
4628 fild%z1\t%1
4629 #
4630 cvtsi2sd\t{%1, %0|%0, %1}
4631 cvtsi2sd\t{%1, %0|%0, %1}"
4632 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4633 (set_attr "mode" "DF")
4634 (set_attr "athlon_decode" "*,*,double,direct")
4635 (set_attr "fp_int_src" "true")])
4636
4637(define_insn "*floatsidf2_sse"
4638 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4639 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4640 "TARGET_SSE2"
4641 "cvtsi2sd\t{%1, %0|%0, %1}"
4642 [(set_attr "type" "sseicvt")
4643 (set_attr "mode" "DF")
4644 (set_attr "athlon_decode" "double,direct")
4645 (set_attr "fp_int_src" "true")])
4646
4647(define_expand "floatdidf2"
4648 [(set (match_operand:DF 0 "register_operand" "")
4649 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4650 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4651 "")
4652
4653(define_insn "*floatdidf2_i387_only"
4654 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4655 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4656 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4657 "@
4658 fild%z1\t%1
4659 #"
4660 [(set_attr "type" "fmov,multi")
4661 (set_attr "mode" "DF")
4662 (set_attr "fp_int_src" "true")])
4663
4664(define_insn "*floatdidf2_i387"
4665 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4666 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4667 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4668 "@
4669 fild%z1\t%1
4670 #
4671 cvtsi2sd{q}\t{%1, %0|%0, %1}
4672 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4674 (set_attr "mode" "DF")
4675 (set_attr "athlon_decode" "*,*,double,direct")
4676 (set_attr "fp_int_src" "true")])
4677
4678(define_insn "*floatdidf2_sse"
4679 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4680 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4681 "TARGET_SSE2"
4682 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4683 [(set_attr "type" "sseicvt")
4684 (set_attr "mode" "DF")
4685 (set_attr "athlon_decode" "double,direct")
4686 (set_attr "fp_int_src" "true")])
4687
4688(define_insn "floathixf2"
4689 [(set (match_operand:XF 0 "register_operand" "=f,f")
4690 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4691 "TARGET_80387"
4692 "@
4693 fild%z1\t%1
4694 #"
4695 [(set_attr "type" "fmov,multi")
4696 (set_attr "mode" "XF")
4697 (set_attr "fp_int_src" "true")])
4698
4699(define_insn "floatsixf2"
4700 [(set (match_operand:XF 0 "register_operand" "=f,f")
4701 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4702 "TARGET_80387"
4703 "@
4704 fild%z1\t%1
4705 #"
4706 [(set_attr "type" "fmov,multi")
4707 (set_attr "mode" "XF")
4708 (set_attr "fp_int_src" "true")])
4709
4710(define_insn "floatdixf2"
4711 [(set (match_operand:XF 0 "register_operand" "=f,f")
4712 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4713 "TARGET_80387"
4714 "@
4715 fild%z1\t%1
4716 #"
4717 [(set_attr "type" "fmov,multi")
4718 (set_attr "mode" "XF")
4719 (set_attr "fp_int_src" "true")])
4720
4721;; %%% Kill these when reload knows how to do it.
4722(define_split
4723 [(set (match_operand 0 "fp_register_operand" "")
4724 (float (match_operand 1 "register_operand" "")))]
4725 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4726 [(const_int 0)]
4727{
4728 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4729 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4730 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4731 ix86_free_from_memory (GET_MODE (operands[1]));
4732 DONE;
4733})
4734
4735(define_expand "floatunssisf2"
4736 [(use (match_operand:SF 0 "register_operand" ""))
4737 (use (match_operand:SI 1 "register_operand" ""))]
4738 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4739 "x86_emit_floatuns (operands); DONE;")
4740
4741(define_expand "floatunsdisf2"
4742 [(use (match_operand:SF 0 "register_operand" ""))
4743 (use (match_operand:DI 1 "register_operand" ""))]
4744 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4745 "x86_emit_floatuns (operands); DONE;")
4746
4747(define_expand "floatunsdidf2"
4748 [(use (match_operand:DF 0 "register_operand" ""))
4749 (use (match_operand:DI 1 "register_operand" ""))]
4750 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4751 "x86_emit_floatuns (operands); DONE;")
4752
4753;; SSE extract/set expanders
4754
4755(define_expand "vec_setv2df"
4756 [(match_operand:V2DF 0 "register_operand" "")
4757 (match_operand:DF 1 "register_operand" "")
4758 (match_operand 2 "const_int_operand" "")]
4759 "TARGET_SSE2"
4760{
4761 switch (INTVAL (operands[2]))
4762 {
4763 case 0:
4764 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4765 simplify_gen_subreg (V2DFmode, operands[1],
4766 DFmode, 0)));
4767 break;
4768 case 1:
4769 {
4770 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4771
4772 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4773 }
4774 break;
4775 default:
4776 abort ();
4777 }
4778 DONE;
4779})
4780
4781(define_expand "vec_extractv2df"
4782 [(match_operand:DF 0 "register_operand" "")
4783 (match_operand:V2DF 1 "register_operand" "")
4784 (match_operand 2 "const_int_operand" "")]
4785 "TARGET_SSE2"
4786{
4787 switch (INTVAL (operands[2]))
4788 {
4789 case 0:
4790 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4791 break;
4792 case 1:
4793 {
4794 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4795
4796 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4797 }
4798 break;
4799 default:
4800 abort ();
4801 }
4802 DONE;
4803})
4804
4805(define_expand "vec_initv2df"
4806 [(match_operand:V2DF 0 "register_operand" "")
4807 (match_operand 1 "" "")]
4808 "TARGET_SSE2"
4809{
4810 ix86_expand_vector_init (operands[0], operands[1]);
4811 DONE;
4812})
4813
4814(define_expand "vec_setv4sf"
4815 [(match_operand:V4SF 0 "register_operand" "")
4816 (match_operand:SF 1 "register_operand" "")
4817 (match_operand 2 "const_int_operand" "")]
4818 "TARGET_SSE"
4819{
4820 switch (INTVAL (operands[2]))
4821 {
4822 case 0:
4823 emit_insn (gen_sse_movss (operands[0], operands[0],
4824 simplify_gen_subreg (V4SFmode, operands[1],
4825 SFmode, 0)));
4826 break;
4827 case 1:
4828 {
4829 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4830 rtx tmp = gen_reg_rtx (V4SFmode);
4831
4832 emit_move_insn (tmp, operands[0]);
4833 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4834 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4835 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4837 }
4838 case 2:
4839 {
4840 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4841 rtx tmp = gen_reg_rtx (V4SFmode);
4842
4843 emit_move_insn (tmp, operands[0]);
4844 emit_insn (gen_sse_movss (tmp, tmp, op1));
4845 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4846 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4847 }
4848 break;
4849 case 3:
4850 {
4851 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4852 rtx tmp = gen_reg_rtx (V4SFmode);
4853
4854 emit_move_insn (tmp, operands[0]);
4855 emit_insn (gen_sse_movss (tmp, tmp, op1));
4856 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4857 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4858 }
4859 break;
4860 default:
4861 abort ();
4862 }
4863 DONE;
4864})
4865
4866(define_expand "vec_extractv4sf"
4867 [(match_operand:SF 0 "register_operand" "")
4868 (match_operand:V4SF 1 "register_operand" "")
4869 (match_operand 2 "const_int_operand" "")]
4870 "TARGET_SSE"
4871{
4872 switch (INTVAL (operands[2]))
4873 {
4874 case 0:
4875 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4876 break;
4877 case 1:
4878 {
4879 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4880 rtx tmp = gen_reg_rtx (V4SFmode);
4881
4882 emit_move_insn (tmp, operands[1]);
4883 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4884 GEN_INT (1)));
4885 }
4886 case 2:
4887 {
4888 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4889 rtx tmp = gen_reg_rtx (V4SFmode);
4890
4891 emit_move_insn (tmp, operands[1]);
4892 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4893 }
4894 case 3:
4895 {
4896 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4897 rtx tmp = gen_reg_rtx (V4SFmode);
4898
4899 emit_move_insn (tmp, operands[1]);
4900 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4901 GEN_INT (3)));
4902 }
4903 default:
4904 abort ();
4905 }
4906 DONE;
4907})
4908
4909(define_expand "vec_initv4sf"
4910 [(match_operand:V4SF 0 "register_operand" "")
4911 (match_operand 1 "" "")]
4912 "TARGET_SSE"
4913{
4914 ix86_expand_vector_init (operands[0], operands[1]);
4915 DONE;
4916})
4917
4918;; Add instructions
4919
4920;; %%% splits for addsidi3
4921; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4922; (plus:DI (match_operand:DI 1 "general_operand" "")
4923; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4924
4925(define_expand "adddi3"
4926 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4927 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4928 (match_operand:DI 2 "x86_64_general_operand" "")))
4929 (clobber (reg:CC 17))]
4930 ""
4931 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4932
4933(define_insn "*adddi3_1"
4934 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4935 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4936 (match_operand:DI 2 "general_operand" "roiF,riF")))
4937 (clobber (reg:CC 17))]
4938 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4939 "#")
4940
4941(define_split
4942 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4943 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4944 (match_operand:DI 2 "general_operand" "")))
4945 (clobber (reg:CC 17))]
4946 "!TARGET_64BIT && reload_completed"
4947 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4948 UNSPEC_ADD_CARRY))
4949 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4950 (parallel [(set (match_dup 3)
4951 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4952 (match_dup 4))
4953 (match_dup 5)))
4954 (clobber (reg:CC 17))])]
4955 "split_di (operands+0, 1, operands+0, operands+3);
4956 split_di (operands+1, 1, operands+1, operands+4);
4957 split_di (operands+2, 1, operands+2, operands+5);")
4958
4959(define_insn "adddi3_carry_rex64"
4960 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4961 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4962 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4963 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4964 (clobber (reg:CC 17))]
4965 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4966 "adc{q}\t{%2, %0|%0, %2}"
4967 [(set_attr "type" "alu")
4968 (set_attr "pent_pair" "pu")
4969 (set_attr "mode" "DI")
4970 (set_attr "ppro_uops" "few")])
4971
4972(define_insn "*adddi3_cc_rex64"
4973 [(set (reg:CC 17)
4974 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4975 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4976 UNSPEC_ADD_CARRY))
4977 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4978 (plus:DI (match_dup 1) (match_dup 2)))]
4979 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4980 "add{q}\t{%2, %0|%0, %2}"
4981 [(set_attr "type" "alu")
4982 (set_attr "mode" "DI")])
4983
4984(define_insn "addqi3_carry"
4985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4986 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4987 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4988 (match_operand:QI 2 "general_operand" "qi,qm")))
4989 (clobber (reg:CC 17))]
4990 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4991 "adc{b}\t{%2, %0|%0, %2}"
4992 [(set_attr "type" "alu")
4993 (set_attr "pent_pair" "pu")
4994 (set_attr "mode" "QI")
4995 (set_attr "ppro_uops" "few")])
4996
4997(define_insn "addhi3_carry"
4998 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4999 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5000 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5001 (match_operand:HI 2 "general_operand" "ri,rm")))
5002 (clobber (reg:CC 17))]
5003 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5004 "adc{w}\t{%2, %0|%0, %2}"
5005 [(set_attr "type" "alu")
5006 (set_attr "pent_pair" "pu")
5007 (set_attr "mode" "HI")
5008 (set_attr "ppro_uops" "few")])
5009
5010(define_insn "addsi3_carry"
5011 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5012 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5013 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5014 (match_operand:SI 2 "general_operand" "ri,rm")))
5015 (clobber (reg:CC 17))]
5016 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5017 "adc{l}\t{%2, %0|%0, %2}"
5018 [(set_attr "type" "alu")
5019 (set_attr "pent_pair" "pu")
5020 (set_attr "mode" "SI")
5021 (set_attr "ppro_uops" "few")])
5022
5023(define_insn "*addsi3_carry_zext"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (zero_extend:DI
5026 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5027 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5028 (match_operand:SI 2 "general_operand" "rim"))))
5029 (clobber (reg:CC 17))]
5030 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5031 "adc{l}\t{%2, %k0|%k0, %2}"
5032 [(set_attr "type" "alu")
5033 (set_attr "pent_pair" "pu")
5034 (set_attr "mode" "SI")
5035 (set_attr "ppro_uops" "few")])
5036
5037(define_insn "*addsi3_cc"
5038 [(set (reg:CC 17)
5039 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5040 (match_operand:SI 2 "general_operand" "ri,rm")]
5041 UNSPEC_ADD_CARRY))
5042 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5043 (plus:SI (match_dup 1) (match_dup 2)))]
5044 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5045 "add{l}\t{%2, %0|%0, %2}"
5046 [(set_attr "type" "alu")
5047 (set_attr "mode" "SI")])
5048
5049(define_insn "addqi3_cc"
5050 [(set (reg:CC 17)
5051 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5052 (match_operand:QI 2 "general_operand" "qi,qm")]
5053 UNSPEC_ADD_CARRY))
5054 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5055 (plus:QI (match_dup 1) (match_dup 2)))]
5056 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5057 "add{b}\t{%2, %0|%0, %2}"
5058 [(set_attr "type" "alu")
5059 (set_attr "mode" "QI")])
5060
5061(define_expand "addsi3"
5062 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5063 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5064 (match_operand:SI 2 "general_operand" "")))
5065 (clobber (reg:CC 17))])]
5066 ""
5067 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5068
5069(define_insn "*lea_1"
5070 [(set (match_operand:SI 0 "register_operand" "=r")
5071 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5072 "!TARGET_64BIT"
5073 "lea{l}\t{%a1, %0|%0, %a1}"
5074 [(set_attr "type" "lea")
5075 (set_attr "mode" "SI")])
5076
5077(define_insn "*lea_1_rex64"
5078 [(set (match_operand:SI 0 "register_operand" "=r")
5079 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5080 "TARGET_64BIT"
5081 "lea{l}\t{%a1, %0|%0, %a1}"
5082 [(set_attr "type" "lea")
5083 (set_attr "mode" "SI")])
5084
5085(define_insn "*lea_1_zext"
5086 [(set (match_operand:DI 0 "register_operand" "=r")
5087 (zero_extend:DI
5088 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5089 "TARGET_64BIT"
5090 "lea{l}\t{%a1, %k0|%k0, %a1}"
5091 [(set_attr "type" "lea")
5092 (set_attr "mode" "SI")])
5093
5094(define_insn "*lea_2_rex64"
5095 [(set (match_operand:DI 0 "register_operand" "=r")
5096 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5097 "TARGET_64BIT"
5098 "lea{q}\t{%a1, %0|%0, %a1}"
5099 [(set_attr "type" "lea")
5100 (set_attr "mode" "DI")])
5101
5102;; The lea patterns for non-Pmodes needs to be matched by several
5103;; insns converted to real lea by splitters.
5104
5105(define_insn_and_split "*lea_general_1"
5106 [(set (match_operand 0 "register_operand" "=r")
5107 (plus (plus (match_operand 1 "index_register_operand" "r")
5108 (match_operand 2 "register_operand" "r"))
5109 (match_operand 3 "immediate_operand" "i")))]
5110 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5111 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5112 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5113 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5114 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5115 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5116 || GET_MODE (operands[3]) == VOIDmode)"
5117 "#"
5118 "&& reload_completed"
5119 [(const_int 0)]
5120{
5121 rtx pat;
5122 operands[0] = gen_lowpart (SImode, operands[0]);
5123 operands[1] = gen_lowpart (Pmode, operands[1]);
5124 operands[2] = gen_lowpart (Pmode, operands[2]);
5125 operands[3] = gen_lowpart (Pmode, operands[3]);
5126 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5127 operands[3]);
5128 if (Pmode != SImode)
5129 pat = gen_rtx_SUBREG (SImode, pat, 0);
5130 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5131 DONE;
5132}
5133 [(set_attr "type" "lea")
5134 (set_attr "mode" "SI")])
5135
5136(define_insn_and_split "*lea_general_1_zext"
5137 [(set (match_operand:DI 0 "register_operand" "=r")
5138 (zero_extend:DI
5139 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5140 (match_operand:SI 2 "register_operand" "r"))
5141 (match_operand:SI 3 "immediate_operand" "i"))))]
5142 "TARGET_64BIT"
5143 "#"
5144 "&& reload_completed"
5145 [(set (match_dup 0)
5146 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5147 (match_dup 2))
5148 (match_dup 3)) 0)))]
5149{
5150 operands[1] = gen_lowpart (Pmode, operands[1]);
5151 operands[2] = gen_lowpart (Pmode, operands[2]);
5152 operands[3] = gen_lowpart (Pmode, operands[3]);
5153}
5154 [(set_attr "type" "lea")
5155 (set_attr "mode" "SI")])
5156
5157(define_insn_and_split "*lea_general_2"
5158 [(set (match_operand 0 "register_operand" "=r")
5159 (plus (mult (match_operand 1 "index_register_operand" "r")
5160 (match_operand 2 "const248_operand" "i"))
5161 (match_operand 3 "nonmemory_operand" "ri")))]
5162 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5163 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5164 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5165 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5166 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5167 || GET_MODE (operands[3]) == VOIDmode)"
5168 "#"
5169 "&& reload_completed"
5170 [(const_int 0)]
5171{
5172 rtx pat;
5173 operands[0] = gen_lowpart (SImode, operands[0]);
5174 operands[1] = gen_lowpart (Pmode, operands[1]);
5175 operands[3] = gen_lowpart (Pmode, operands[3]);
5176 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5177 operands[3]);
5178 if (Pmode != SImode)
5179 pat = gen_rtx_SUBREG (SImode, pat, 0);
5180 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5181 DONE;
5182}
5183 [(set_attr "type" "lea")
5184 (set_attr "mode" "SI")])
5185
5186(define_insn_and_split "*lea_general_2_zext"
5187 [(set (match_operand:DI 0 "register_operand" "=r")
5188 (zero_extend:DI
5189 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5190 (match_operand:SI 2 "const248_operand" "n"))
5191 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5192 "TARGET_64BIT"
5193 "#"
5194 "&& reload_completed"
5195 [(set (match_dup 0)
5196 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5197 (match_dup 2))
5198 (match_dup 3)) 0)))]
5199{
5200 operands[1] = gen_lowpart (Pmode, operands[1]);
5201 operands[3] = gen_lowpart (Pmode, operands[3]);
5202}
5203 [(set_attr "type" "lea")
5204 (set_attr "mode" "SI")])
5205
5206(define_insn_and_split "*lea_general_3"
5207 [(set (match_operand 0 "register_operand" "=r")
5208 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5209 (match_operand 2 "const248_operand" "i"))
5210 (match_operand 3 "register_operand" "r"))
5211 (match_operand 4 "immediate_operand" "i")))]
5212 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5213 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5214 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5215 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5216 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5217 "#"
5218 "&& reload_completed"
5219 [(const_int 0)]
5220{
5221 rtx pat;
5222 operands[0] = gen_lowpart (SImode, operands[0]);
5223 operands[1] = gen_lowpart (Pmode, operands[1]);
5224 operands[3] = gen_lowpart (Pmode, operands[3]);
5225 operands[4] = gen_lowpart (Pmode, operands[4]);
5226 pat = gen_rtx_PLUS (Pmode,
5227 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5228 operands[2]),
5229 operands[3]),
5230 operands[4]);
5231 if (Pmode != SImode)
5232 pat = gen_rtx_SUBREG (SImode, pat, 0);
5233 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5234 DONE;
5235}
5236 [(set_attr "type" "lea")
5237 (set_attr "mode" "SI")])
5238
5239(define_insn_and_split "*lea_general_3_zext"
5240 [(set (match_operand:DI 0 "register_operand" "=r")
5241 (zero_extend:DI
5242 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5243 (match_operand:SI 2 "const248_operand" "n"))
5244 (match_operand:SI 3 "register_operand" "r"))
5245 (match_operand:SI 4 "immediate_operand" "i"))))]
5246 "TARGET_64BIT"
5247 "#"
5248 "&& reload_completed"
5249 [(set (match_dup 0)
5250 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5251 (match_dup 2))
5252 (match_dup 3))
5253 (match_dup 4)) 0)))]
5254{
5255 operands[1] = gen_lowpart (Pmode, operands[1]);
5256 operands[3] = gen_lowpart (Pmode, operands[3]);
5257 operands[4] = gen_lowpart (Pmode, operands[4]);
5258}
5259 [(set_attr "type" "lea")
5260 (set_attr "mode" "SI")])
5261
5262(define_insn "*adddi_1_rex64"
5263 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5264 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5265 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5266 (clobber (reg:CC 17))]
5267 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5268{
5269 switch (get_attr_type (insn))
5270 {
5271 case TYPE_LEA:
5272 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5273 return "lea{q}\t{%a2, %0|%0, %a2}";
5274
5275 case TYPE_INCDEC:
5276 if (! rtx_equal_p (operands[0], operands[1]))
5277 abort ();
5278 if (operands[2] == const1_rtx)
5279 return "inc{q}\t%0";
5280 else if (operands[2] == constm1_rtx)
5281 return "dec{q}\t%0";
5282 else
5283 abort ();
5284
5285 default:
5286 if (! rtx_equal_p (operands[0], operands[1]))
5287 abort ();
5288
5289 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5290 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5291 if (GET_CODE (operands[2]) == CONST_INT
5292 /* Avoid overflows. */
5293 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5294 && (INTVAL (operands[2]) == 128
5295 || (INTVAL (operands[2]) < 0
5296 && INTVAL (operands[2]) != -128)))
5297 {
5298 operands[2] = GEN_INT (-INTVAL (operands[2]));
5299 return "sub{q}\t{%2, %0|%0, %2}";
5300 }
5301 return "add{q}\t{%2, %0|%0, %2}";
5302 }
5303}
5304 [(set (attr "type")
5305 (cond [(eq_attr "alternative" "2")
5306 (const_string "lea")
5307 ; Current assemblers are broken and do not allow @GOTOFF in
5308 ; ought but a memory context.
5309 (match_operand:DI 2 "pic_symbolic_operand" "")
5310 (const_string "lea")
5311 (match_operand:DI 2 "incdec_operand" "")
5312 (const_string "incdec")
5313 ]
5314 (const_string "alu")))
5315 (set_attr "mode" "DI")])
5316
5317;; Convert lea to the lea pattern to avoid flags dependency.
5318(define_split
5319 [(set (match_operand:DI 0 "register_operand" "")
5320 (plus:DI (match_operand:DI 1 "register_operand" "")
5321 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5322 (clobber (reg:CC 17))]
5323 "TARGET_64BIT && reload_completed
5324 && true_regnum (operands[0]) != true_regnum (operands[1])"
5325 [(set (match_dup 0)
5326 (plus:DI (match_dup 1)
5327 (match_dup 2)))]
5328 "")
5329
5330(define_insn "*adddi_2_rex64"
5331 [(set (reg 17)
5332 (compare
5333 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5334 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5335 (const_int 0)))
5336 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5337 (plus:DI (match_dup 1) (match_dup 2)))]
5338 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5339 && ix86_binary_operator_ok (PLUS, DImode, operands)
5340 /* Current assemblers are broken and do not allow @GOTOFF in
5341 ought but a memory context. */
5342 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5343{
5344 switch (get_attr_type (insn))
5345 {
5346 case TYPE_INCDEC:
5347 if (! rtx_equal_p (operands[0], operands[1]))
5348 abort ();
5349 if (operands[2] == const1_rtx)
5350 return "inc{q}\t%0";
5351 else if (operands[2] == constm1_rtx)
5352 return "dec{q}\t%0";
5353 else
5354 abort ();
5355
5356 default:
5357 if (! rtx_equal_p (operands[0], operands[1]))
5358 abort ();
5359 /* ???? We ought to handle there the 32bit case too
5360 - do we need new constraint? */
5361 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5363 if (GET_CODE (operands[2]) == CONST_INT
5364 /* Avoid overflows. */
5365 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366 && (INTVAL (operands[2]) == 128
5367 || (INTVAL (operands[2]) < 0
5368 && INTVAL (operands[2]) != -128)))
5369 {
5370 operands[2] = GEN_INT (-INTVAL (operands[2]));
5371 return "sub{q}\t{%2, %0|%0, %2}";
5372 }
5373 return "add{q}\t{%2, %0|%0, %2}";
5374 }
5375}
5376 [(set (attr "type")
5377 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378 (const_string "incdec")
5379 (const_string "alu")))
5380 (set_attr "mode" "DI")])
5381
5382(define_insn "*adddi_3_rex64"
5383 [(set (reg 17)
5384 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5385 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5386 (clobber (match_scratch:DI 0 "=r"))]
5387 "TARGET_64BIT
5388 && ix86_match_ccmode (insn, CCZmode)
5389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390 /* Current assemblers are broken and do not allow @GOTOFF in
5391 ought but a memory context. */
5392 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5393{
5394 switch (get_attr_type (insn))
5395 {
5396 case TYPE_INCDEC:
5397 if (! rtx_equal_p (operands[0], operands[1]))
5398 abort ();
5399 if (operands[2] == const1_rtx)
5400 return "inc{q}\t%0";
5401 else if (operands[2] == constm1_rtx)
5402 return "dec{q}\t%0";
5403 else
5404 abort ();
5405
5406 default:
5407 if (! rtx_equal_p (operands[0], operands[1]))
5408 abort ();
5409 /* ???? We ought to handle there the 32bit case too
5410 - do we need new constraint? */
5411 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5413 if (GET_CODE (operands[2]) == CONST_INT
5414 /* Avoid overflows. */
5415 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5416 && (INTVAL (operands[2]) == 128
5417 || (INTVAL (operands[2]) < 0
5418 && INTVAL (operands[2]) != -128)))
5419 {
5420 operands[2] = GEN_INT (-INTVAL (operands[2]));
5421 return "sub{q}\t{%2, %0|%0, %2}";
5422 }
5423 return "add{q}\t{%2, %0|%0, %2}";
5424 }
5425}
5426 [(set (attr "type")
5427 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5428 (const_string "incdec")
5429 (const_string "alu")))
5430 (set_attr "mode" "DI")])
5431
5432; For comparisons against 1, -1 and 128, we may generate better code
5433; by converting cmp to add, inc or dec as done by peephole2. This pattern
5434; is matched then. We can't accept general immediate, because for
5435; case of overflows, the result is messed up.
5436; This pattern also don't hold of 0x8000000000000000, since the value overflows
5437; when negated.
5438; Also carry flag is reversed compared to cmp, so this conversion is valid
5439; only for comparisons not depending on it.
5440(define_insn "*adddi_4_rex64"
5441 [(set (reg 17)
5442 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5443 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5444 (clobber (match_scratch:DI 0 "=rm"))]
5445 "TARGET_64BIT
5446 && ix86_match_ccmode (insn, CCGCmode)"
5447{
5448 switch (get_attr_type (insn))
5449 {
5450 case TYPE_INCDEC:
5451 if (operands[2] == constm1_rtx)
5452 return "inc{q}\t%0";
5453 else if (operands[2] == const1_rtx)
5454 return "dec{q}\t%0";
5455 else
5456 abort();
5457
5458 default:
5459 if (! rtx_equal_p (operands[0], operands[1]))
5460 abort ();
5461 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5462 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5463 if ((INTVAL (operands[2]) == -128
5464 || (INTVAL (operands[2]) > 0
5465 && INTVAL (operands[2]) != 128))
5466 /* Avoid overflows. */
5467 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5468 return "sub{q}\t{%2, %0|%0, %2}";
5469 operands[2] = GEN_INT (-INTVAL (operands[2]));
5470 return "add{q}\t{%2, %0|%0, %2}";
5471 }
5472}
5473 [(set (attr "type")
5474 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5475 (const_string "incdec")
5476 (const_string "alu")))
5477 (set_attr "mode" "DI")])
5478
5479(define_insn "*adddi_5_rex64"
5480 [(set (reg 17)
5481 (compare
5482 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5483 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5484 (const_int 0)))
5485 (clobber (match_scratch:DI 0 "=r"))]
5486 "TARGET_64BIT
5487 && ix86_match_ccmode (insn, CCGOCmode)
5488 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5489 /* Current assemblers are broken and do not allow @GOTOFF in
5490 ought but a memory context. */
5491 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5492{
5493 switch (get_attr_type (insn))
5494 {
5495 case TYPE_INCDEC:
5496 if (! rtx_equal_p (operands[0], operands[1]))
5497 abort ();
5498 if (operands[2] == const1_rtx)
5499 return "inc{q}\t%0";
5500 else if (operands[2] == constm1_rtx)
5501 return "dec{q}\t%0";
5502 else
5503 abort();
5504
5505 default:
5506 if (! rtx_equal_p (operands[0], operands[1]))
5507 abort ();
5508 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5509 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5510 if (GET_CODE (operands[2]) == CONST_INT
5511 /* Avoid overflows. */
5512 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5513 && (INTVAL (operands[2]) == 128
5514 || (INTVAL (operands[2]) < 0
5515 && INTVAL (operands[2]) != -128)))
5516 {
5517 operands[2] = GEN_INT (-INTVAL (operands[2]));
5518 return "sub{q}\t{%2, %0|%0, %2}";
5519 }
5520 return "add{q}\t{%2, %0|%0, %2}";
5521 }
5522}
5523 [(set (attr "type")
5524 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5525 (const_string "incdec")
5526 (const_string "alu")))
5527 (set_attr "mode" "DI")])
5528
5529
5530(define_insn "*addsi_1"
5531 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5533 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5534 (clobber (reg:CC 17))]
5535 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5536{
5537 switch (get_attr_type (insn))
5538 {
5539 case TYPE_LEA:
5540 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5541 return "lea{l}\t{%a2, %0|%0, %a2}";
5542
5543 case TYPE_INCDEC:
5544 if (! rtx_equal_p (operands[0], operands[1]))
5545 abort ();
5546 if (operands[2] == const1_rtx)
5547 return "inc{l}\t%0";
5548 else if (operands[2] == constm1_rtx)
5549 return "dec{l}\t%0";
5550 else
5551 abort();
5552
5553 default:
5554 if (! rtx_equal_p (operands[0], operands[1]))
5555 abort ();
5556
5557 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5558 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5559 if (GET_CODE (operands[2]) == CONST_INT
5560 && (INTVAL (operands[2]) == 128
5561 || (INTVAL (operands[2]) < 0
5562 && INTVAL (operands[2]) != -128)))
5563 {
5564 operands[2] = GEN_INT (-INTVAL (operands[2]));
5565 return "sub{l}\t{%2, %0|%0, %2}";
5566 }
5567 return "add{l}\t{%2, %0|%0, %2}";
5568 }
5569}
5570 [(set (attr "type")
5571 (cond [(eq_attr "alternative" "2")
5572 (const_string "lea")
5573 ; Current assemblers are broken and do not allow @GOTOFF in
5574 ; ought but a memory context.
5575 (match_operand:SI 2 "pic_symbolic_operand" "")
5576 (const_string "lea")
5577 (match_operand:SI 2 "incdec_operand" "")
5578 (const_string "incdec")
5579 ]
5580 (const_string "alu")))
5581 (set_attr "mode" "SI")])
5582
5583;; Convert lea to the lea pattern to avoid flags dependency.
5584(define_split
5585 [(set (match_operand 0 "register_operand" "")
5586 (plus (match_operand 1 "register_operand" "")
5587 (match_operand 2 "nonmemory_operand" "")))
5588 (clobber (reg:CC 17))]
5589 "reload_completed
5590 && true_regnum (operands[0]) != true_regnum (operands[1])"
5591 [(const_int 0)]
5592{
5593 rtx pat;
5594 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5595 may confuse gen_lowpart. */
5596 if (GET_MODE (operands[0]) != Pmode)
5597 {
5598 operands[1] = gen_lowpart (Pmode, operands[1]);
5599 operands[2] = gen_lowpart (Pmode, operands[2]);
5600 }
5601 operands[0] = gen_lowpart (SImode, operands[0]);
5602 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5603 if (Pmode != SImode)
5604 pat = gen_rtx_SUBREG (SImode, pat, 0);
5605 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5606 DONE;
5607})
5608
5609;; It may seem that nonimmediate operand is proper one for operand 1.
5610;; The addsi_1 pattern allows nonimmediate operand at that place and
5611;; we take care in ix86_binary_operator_ok to not allow two memory
5612;; operands so proper swapping will be done in reload. This allow
5613;; patterns constructed from addsi_1 to match.
5614(define_insn "addsi_1_zext"
5615 [(set (match_operand:DI 0 "register_operand" "=r,r")
5616 (zero_extend:DI
5617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5618 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5619 (clobber (reg:CC 17))]
5620 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5621{
5622 switch (get_attr_type (insn))
5623 {
5624 case TYPE_LEA:
5625 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5626 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5627
5628 case TYPE_INCDEC:
5629 if (operands[2] == const1_rtx)
5630 return "inc{l}\t%k0";
5631 else if (operands[2] == constm1_rtx)
5632 return "dec{l}\t%k0";
5633 else
5634 abort();
5635
5636 default:
5637 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5639 if (GET_CODE (operands[2]) == CONST_INT
5640 && (INTVAL (operands[2]) == 128
5641 || (INTVAL (operands[2]) < 0
5642 && INTVAL (operands[2]) != -128)))
5643 {
5644 operands[2] = GEN_INT (-INTVAL (operands[2]));
5645 return "sub{l}\t{%2, %k0|%k0, %2}";
5646 }
5647 return "add{l}\t{%2, %k0|%k0, %2}";
5648 }
5649}
5650 [(set (attr "type")
5651 (cond [(eq_attr "alternative" "1")
5652 (const_string "lea")
5653 ; Current assemblers are broken and do not allow @GOTOFF in
5654 ; ought but a memory context.
5655 (match_operand:SI 2 "pic_symbolic_operand" "")
5656 (const_string "lea")
5657 (match_operand:SI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 ]
5660 (const_string "alu")))
5661 (set_attr "mode" "SI")])
5662
5663;; Convert lea to the lea pattern to avoid flags dependency.
5664(define_split
5665 [(set (match_operand:DI 0 "register_operand" "")
5666 (zero_extend:DI
5667 (plus:SI (match_operand:SI 1 "register_operand" "")
5668 (match_operand:SI 2 "nonmemory_operand" ""))))
5669 (clobber (reg:CC 17))]
5670 "TARGET_64BIT && reload_completed
5671 && true_regnum (operands[0]) != true_regnum (operands[1])"
5672 [(set (match_dup 0)
5673 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5674{
5675 operands[1] = gen_lowpart (Pmode, operands[1]);
5676 operands[2] = gen_lowpart (Pmode, operands[2]);
5677})
5678
5679(define_insn "*addsi_2"
5680 [(set (reg 17)
5681 (compare
5682 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5683 (match_operand:SI 2 "general_operand" "rmni,rni"))
5684 (const_int 0)))
5685 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5686 (plus:SI (match_dup 1) (match_dup 2)))]
5687 "ix86_match_ccmode (insn, CCGOCmode)
5688 && ix86_binary_operator_ok (PLUS, SImode, operands)
5689 /* Current assemblers are broken and do not allow @GOTOFF in
5690 ought but a memory context. */
5691 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5692{
5693 switch (get_attr_type (insn))
5694 {
5695 case TYPE_INCDEC:
5696 if (! rtx_equal_p (operands[0], operands[1]))
5697 abort ();
5698 if (operands[2] == const1_rtx)
5699 return "inc{l}\t%0";
5700 else if (operands[2] == constm1_rtx)
5701 return "dec{l}\t%0";
5702 else
5703 abort();
5704
5705 default:
5706 if (! rtx_equal_p (operands[0], operands[1]))
5707 abort ();
5708 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5709 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5710 if (GET_CODE (operands[2]) == CONST_INT
5711 && (INTVAL (operands[2]) == 128
5712 || (INTVAL (operands[2]) < 0
5713 && INTVAL (operands[2]) != -128)))
5714 {
5715 operands[2] = GEN_INT (-INTVAL (operands[2]));
5716 return "sub{l}\t{%2, %0|%0, %2}";
5717 }
5718 return "add{l}\t{%2, %0|%0, %2}";
5719 }
5720}
5721 [(set (attr "type")
5722 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723 (const_string "incdec")
5724 (const_string "alu")))
5725 (set_attr "mode" "SI")])
5726
5727;; See comment for addsi_1_zext why we do use nonimmediate_operand
5728(define_insn "*addsi_2_zext"
5729 [(set (reg 17)
5730 (compare
5731 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5732 (match_operand:SI 2 "general_operand" "rmni"))
5733 (const_int 0)))
5734 (set (match_operand:DI 0 "register_operand" "=r")
5735 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5736 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5737 && ix86_binary_operator_ok (PLUS, SImode, operands)
5738 /* Current assemblers are broken and do not allow @GOTOFF in
5739 ought but a memory context. */
5740 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5741{
5742 switch (get_attr_type (insn))
5743 {
5744 case TYPE_INCDEC:
5745 if (operands[2] == const1_rtx)
5746 return "inc{l}\t%k0";
5747 else if (operands[2] == constm1_rtx)
5748 return "dec{l}\t%k0";
5749 else
5750 abort();
5751
5752 default:
5753 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5755 if (GET_CODE (operands[2]) == CONST_INT
5756 && (INTVAL (operands[2]) == 128
5757 || (INTVAL (operands[2]) < 0
5758 && INTVAL (operands[2]) != -128)))
5759 {
5760 operands[2] = GEN_INT (-INTVAL (operands[2]));
5761 return "sub{l}\t{%2, %k0|%k0, %2}";
5762 }
5763 return "add{l}\t{%2, %k0|%k0, %2}";
5764 }
5765}
5766 [(set (attr "type")
5767 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5768 (const_string "incdec")
5769 (const_string "alu")))
5770 (set_attr "mode" "SI")])
5771
5772(define_insn "*addsi_3"
5773 [(set (reg 17)
5774 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5775 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5776 (clobber (match_scratch:SI 0 "=r"))]
5777 "ix86_match_ccmode (insn, CCZmode)
5778 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5779 /* Current assemblers are broken and do not allow @GOTOFF in
5780 ought but a memory context. */
5781 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5782{
5783 switch (get_attr_type (insn))
5784 {
5785 case TYPE_INCDEC:
5786 if (! rtx_equal_p (operands[0], operands[1]))
5787 abort ();
5788 if (operands[2] == const1_rtx)
5789 return "inc{l}\t%0";
5790 else if (operands[2] == constm1_rtx)
5791 return "dec{l}\t%0";
5792 else
5793 abort();
5794
5795 default:
5796 if (! rtx_equal_p (operands[0], operands[1]))
5797 abort ();
5798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5800 if (GET_CODE (operands[2]) == CONST_INT
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5804 {
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
5806 return "sub{l}\t{%2, %0|%0, %2}";
5807 }
5808 return "add{l}\t{%2, %0|%0, %2}";
5809 }
5810}
5811 [(set (attr "type")
5812 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "SI")])
5816
5817;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818(define_insn "*addsi_3_zext"
5819 [(set (reg 17)
5820 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5821 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5822 (set (match_operand:DI 0 "register_operand" "=r")
5823 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5824 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5825 && ix86_binary_operator_ok (PLUS, SImode, operands)
5826 /* Current assemblers are broken and do not allow @GOTOFF in
5827 ought but a memory context. */
5828 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5829{
5830 switch (get_attr_type (insn))
5831 {
5832 case TYPE_INCDEC:
5833 if (operands[2] == const1_rtx)
5834 return "inc{l}\t%k0";
5835 else if (operands[2] == constm1_rtx)
5836 return "dec{l}\t%k0";
5837 else
5838 abort();
5839
5840 default:
5841 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5843 if (GET_CODE (operands[2]) == CONST_INT
5844 && (INTVAL (operands[2]) == 128
5845 || (INTVAL (operands[2]) < 0
5846 && INTVAL (operands[2]) != -128)))
5847 {
5848 operands[2] = GEN_INT (-INTVAL (operands[2]));
5849 return "sub{l}\t{%2, %k0|%k0, %2}";
5850 }
5851 return "add{l}\t{%2, %k0|%k0, %2}";
5852 }
5853}
5854 [(set (attr "type")
5855 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5856 (const_string "incdec")
5857 (const_string "alu")))
5858 (set_attr "mode" "SI")])
5859
5860; For comparisons against 1, -1 and 128, we may generate better code
5861; by converting cmp to add, inc or dec as done by peephole2. This pattern
5862; is matched then. We can't accept general immediate, because for
5863; case of overflows, the result is messed up.
5864; This pattern also don't hold of 0x80000000, since the value overflows
5865; when negated.
5866; Also carry flag is reversed compared to cmp, so this conversion is valid
5867; only for comparisons not depending on it.
5868(define_insn "*addsi_4"
5869 [(set (reg 17)
5870 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5871 (match_operand:SI 2 "const_int_operand" "n")))
5872 (clobber (match_scratch:SI 0 "=rm"))]
5873 "ix86_match_ccmode (insn, CCGCmode)
5874 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5875{
5876 switch (get_attr_type (insn))
5877 {
5878 case TYPE_INCDEC:
5879 if (operands[2] == constm1_rtx)
5880 return "inc{l}\t%0";
5881 else if (operands[2] == const1_rtx)
5882 return "dec{l}\t%0";
5883 else
5884 abort();
5885
5886 default:
5887 if (! rtx_equal_p (operands[0], operands[1]))
5888 abort ();
5889 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5890 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5891 if ((INTVAL (operands[2]) == -128
5892 || (INTVAL (operands[2]) > 0
5893 && INTVAL (operands[2]) != 128)))
5894 return "sub{l}\t{%2, %0|%0, %2}";
5895 operands[2] = GEN_INT (-INTVAL (operands[2]));
5896 return "add{l}\t{%2, %0|%0, %2}";
5897 }
5898}
5899 [(set (attr "type")
5900 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "SI")])
5904
5905(define_insn "*addsi_5"
5906 [(set (reg 17)
5907 (compare
5908 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5909 (match_operand:SI 2 "general_operand" "rmni"))
5910 (const_int 0)))
5911 (clobber (match_scratch:SI 0 "=r"))]
5912 "ix86_match_ccmode (insn, CCGOCmode)
5913 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5914 /* Current assemblers are broken and do not allow @GOTOFF in
5915 ought but a memory context. */
5916 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5917{
5918 switch (get_attr_type (insn))
5919 {
5920 case TYPE_INCDEC:
5921 if (! rtx_equal_p (operands[0], operands[1]))
5922 abort ();
5923 if (operands[2] == const1_rtx)
5924 return "inc{l}\t%0";
5925 else if (operands[2] == constm1_rtx)
5926 return "dec{l}\t%0";
5927 else
5928 abort();
5929
5930 default:
5931 if (! rtx_equal_p (operands[0], operands[1]))
5932 abort ();
5933 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5935 if (GET_CODE (operands[2]) == CONST_INT
5936 && (INTVAL (operands[2]) == 128
5937 || (INTVAL (operands[2]) < 0
5938 && INTVAL (operands[2]) != -128)))
5939 {
5940 operands[2] = GEN_INT (-INTVAL (operands[2]));
5941 return "sub{l}\t{%2, %0|%0, %2}";
5942 }
5943 return "add{l}\t{%2, %0|%0, %2}";
5944 }
5945}
5946 [(set (attr "type")
5947 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948 (const_string "incdec")
5949 (const_string "alu")))
5950 (set_attr "mode" "SI")])
5951
5952(define_expand "addhi3"
5953 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5954 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5955 (match_operand:HI 2 "general_operand" "")))
5956 (clobber (reg:CC 17))])]
5957 "TARGET_HIMODE_MATH"
5958 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5959
5960;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5961;; type optimizations enabled by define-splits. This is not important
5962;; for PII, and in fact harmful because of partial register stalls.
5963
5964(define_insn "*addhi_1_lea"
5965 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5966 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5967 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5968 (clobber (reg:CC 17))]
5969 "!TARGET_PARTIAL_REG_STALL
5970 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5971{
5972 switch (get_attr_type (insn))
5973 {
5974 case TYPE_LEA:
5975 return "#";
5976 case TYPE_INCDEC:
5977 if (operands[2] == const1_rtx)
5978 return "inc{w}\t%0";
5979 else if (operands[2] == constm1_rtx)
5980 return "dec{w}\t%0";
5981 abort();
5982
5983 default:
5984 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5985 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5986 if (GET_CODE (operands[2]) == CONST_INT
5987 && (INTVAL (operands[2]) == 128
5988 || (INTVAL (operands[2]) < 0
5989 && INTVAL (operands[2]) != -128)))
5990 {
5991 operands[2] = GEN_INT (-INTVAL (operands[2]));
5992 return "sub{w}\t{%2, %0|%0, %2}";
5993 }
5994 return "add{w}\t{%2, %0|%0, %2}";
5995 }
5996}
5997 [(set (attr "type")
5998 (if_then_else (eq_attr "alternative" "2")
5999 (const_string "lea")
6000 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001 (const_string "incdec")
6002 (const_string "alu"))))
6003 (set_attr "mode" "HI,HI,SI")])
6004
6005(define_insn "*addhi_1"
6006 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6007 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6008 (match_operand:HI 2 "general_operand" "ri,rm")))
6009 (clobber (reg:CC 17))]
6010 "TARGET_PARTIAL_REG_STALL
6011 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6012{
6013 switch (get_attr_type (insn))
6014 {
6015 case TYPE_INCDEC:
6016 if (operands[2] == const1_rtx)
6017 return "inc{w}\t%0";
6018 else if (operands[2] == constm1_rtx)
6019 return "dec{w}\t%0";
6020 abort();
6021
6022 default:
6023 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6025 if (GET_CODE (operands[2]) == CONST_INT
6026 && (INTVAL (operands[2]) == 128
6027 || (INTVAL (operands[2]) < 0
6028 && INTVAL (operands[2]) != -128)))
6029 {
6030 operands[2] = GEN_INT (-INTVAL (operands[2]));
6031 return "sub{w}\t{%2, %0|%0, %2}";
6032 }
6033 return "add{w}\t{%2, %0|%0, %2}";
6034 }
6035}
6036 [(set (attr "type")
6037 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6038 (const_string "incdec")
6039 (const_string "alu")))
6040 (set_attr "mode" "HI")])
6041
6042(define_insn "*addhi_2"
6043 [(set (reg 17)
6044 (compare
6045 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046 (match_operand:HI 2 "general_operand" "rmni,rni"))
6047 (const_int 0)))
6048 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6049 (plus:HI (match_dup 1) (match_dup 2)))]
6050 "ix86_match_ccmode (insn, CCGOCmode)
6051 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6052{
6053 switch (get_attr_type (insn))
6054 {
6055 case TYPE_INCDEC:
6056 if (operands[2] == const1_rtx)
6057 return "inc{w}\t%0";
6058 else if (operands[2] == constm1_rtx)
6059 return "dec{w}\t%0";
6060 abort();
6061
6062 default:
6063 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6065 if (GET_CODE (operands[2]) == CONST_INT
6066 && (INTVAL (operands[2]) == 128
6067 || (INTVAL (operands[2]) < 0
6068 && INTVAL (operands[2]) != -128)))
6069 {
6070 operands[2] = GEN_INT (-INTVAL (operands[2]));
6071 return "sub{w}\t{%2, %0|%0, %2}";
6072 }
6073 return "add{w}\t{%2, %0|%0, %2}";
6074 }
6075}
6076 [(set (attr "type")
6077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078 (const_string "incdec")
6079 (const_string "alu")))
6080 (set_attr "mode" "HI")])
6081
6082(define_insn "*addhi_3"
6083 [(set (reg 17)
6084 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6085 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6086 (clobber (match_scratch:HI 0 "=r"))]
6087 "ix86_match_ccmode (insn, CCZmode)
6088 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6089{
6090 switch (get_attr_type (insn))
6091 {
6092 case TYPE_INCDEC:
6093 if (operands[2] == const1_rtx)
6094 return "inc{w}\t%0";
6095 else if (operands[2] == constm1_rtx)
6096 return "dec{w}\t%0";
6097 abort();
6098
6099 default:
6100 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6102 if (GET_CODE (operands[2]) == CONST_INT
6103 && (INTVAL (operands[2]) == 128
6104 || (INTVAL (operands[2]) < 0
6105 && INTVAL (operands[2]) != -128)))
6106 {
6107 operands[2] = GEN_INT (-INTVAL (operands[2]));
6108 return "sub{w}\t{%2, %0|%0, %2}";
6109 }
6110 return "add{w}\t{%2, %0|%0, %2}";
6111 }
6112}
6113 [(set (attr "type")
6114 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6115 (const_string "incdec")
6116 (const_string "alu")))
6117 (set_attr "mode" "HI")])
6118
6119; See comments above addsi_3_imm for details.
6120(define_insn "*addhi_4"
6121 [(set (reg 17)
6122 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6123 (match_operand:HI 2 "const_int_operand" "n")))
6124 (clobber (match_scratch:HI 0 "=rm"))]
6125 "ix86_match_ccmode (insn, CCGCmode)
6126 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6127{
6128 switch (get_attr_type (insn))
6129 {
6130 case TYPE_INCDEC:
6131 if (operands[2] == constm1_rtx)
6132 return "inc{w}\t%0";
6133 else if (operands[2] == const1_rtx)
6134 return "dec{w}\t%0";
6135 else
6136 abort();
6137
6138 default:
6139 if (! rtx_equal_p (operands[0], operands[1]))
6140 abort ();
6141 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6143 if ((INTVAL (operands[2]) == -128
6144 || (INTVAL (operands[2]) > 0
6145 && INTVAL (operands[2]) != 128)))
6146 return "sub{w}\t{%2, %0|%0, %2}";
6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 return "add{w}\t{%2, %0|%0, %2}";
6149 }
6150}
6151 [(set (attr "type")
6152 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153 (const_string "incdec")
6154 (const_string "alu")))
6155 (set_attr "mode" "SI")])
6156
6157
6158(define_insn "*addhi_5"
6159 [(set (reg 17)
6160 (compare
6161 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6162 (match_operand:HI 2 "general_operand" "rmni"))
6163 (const_int 0)))
6164 (clobber (match_scratch:HI 0 "=r"))]
6165 "ix86_match_ccmode (insn, CCGOCmode)
6166 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6167{
6168 switch (get_attr_type (insn))
6169 {
6170 case TYPE_INCDEC:
6171 if (operands[2] == const1_rtx)
6172 return "inc{w}\t%0";
6173 else if (operands[2] == constm1_rtx)
6174 return "dec{w}\t%0";
6175 abort();
6176
6177 default:
6178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6179 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6180 if (GET_CODE (operands[2]) == CONST_INT
6181 && (INTVAL (operands[2]) == 128
6182 || (INTVAL (operands[2]) < 0
6183 && INTVAL (operands[2]) != -128)))
6184 {
6185 operands[2] = GEN_INT (-INTVAL (operands[2]));
6186 return "sub{w}\t{%2, %0|%0, %2}";
6187 }
6188 return "add{w}\t{%2, %0|%0, %2}";
6189 }
6190}
6191 [(set (attr "type")
6192 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6193 (const_string "incdec")
6194 (const_string "alu")))
6195 (set_attr "mode" "HI")])
6196
6197(define_expand "addqi3"
6198 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6199 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6200 (match_operand:QI 2 "general_operand" "")))
6201 (clobber (reg:CC 17))])]
6202 "TARGET_QIMODE_MATH"
6203 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6204
6205;; %%% Potential partial reg stall on alternative 2. What to do?
6206(define_insn "*addqi_1_lea"
6207 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6208 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6209 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6210 (clobber (reg:CC 17))]
6211 "!TARGET_PARTIAL_REG_STALL
6212 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6213{
6214 int widen = (which_alternative == 2);
6215 switch (get_attr_type (insn))
6216 {
6217 case TYPE_LEA:
6218 return "#";
6219 case TYPE_INCDEC:
6220 if (operands[2] == const1_rtx)
6221 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222 else if (operands[2] == constm1_rtx)
6223 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6224 abort();
6225
6226 default:
6227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6229 if (GET_CODE (operands[2]) == CONST_INT
6230 && (INTVAL (operands[2]) == 128
6231 || (INTVAL (operands[2]) < 0
6232 && INTVAL (operands[2]) != -128)))
6233 {
6234 operands[2] = GEN_INT (-INTVAL (operands[2]));
6235 if (widen)
6236 return "sub{l}\t{%2, %k0|%k0, %2}";
6237 else
6238 return "sub{b}\t{%2, %0|%0, %2}";
6239 }
6240 if (widen)
6241 return "add{l}\t{%k2, %k0|%k0, %k2}";
6242 else
6243 return "add{b}\t{%2, %0|%0, %2}";
6244 }
6245}
6246 [(set (attr "type")
6247 (if_then_else (eq_attr "alternative" "3")
6248 (const_string "lea")
6249 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250 (const_string "incdec")
6251 (const_string "alu"))))
6252 (set_attr "mode" "QI,QI,SI,SI")])
6253
6254(define_insn "*addqi_1"
6255 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6256 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6257 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6258 (clobber (reg:CC 17))]
6259 "TARGET_PARTIAL_REG_STALL
6260 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6261{
6262 int widen = (which_alternative == 2);
6263 switch (get_attr_type (insn))
6264 {
6265 case TYPE_INCDEC:
6266 if (operands[2] == const1_rtx)
6267 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6268 else if (operands[2] == constm1_rtx)
6269 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6270 abort();
6271
6272 default:
6273 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6274 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6275 if (GET_CODE (operands[2]) == CONST_INT
6276 && (INTVAL (operands[2]) == 128
6277 || (INTVAL (operands[2]) < 0
6278 && INTVAL (operands[2]) != -128)))
6279 {
6280 operands[2] = GEN_INT (-INTVAL (operands[2]));
6281 if (widen)
6282 return "sub{l}\t{%2, %k0|%k0, %2}";
6283 else
6284 return "sub{b}\t{%2, %0|%0, %2}";
6285 }
6286 if (widen)
6287 return "add{l}\t{%k2, %k0|%k0, %k2}";
6288 else
6289 return "add{b}\t{%2, %0|%0, %2}";
6290 }
6291}
6292 [(set (attr "type")
6293 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set_attr "mode" "QI,QI,SI")])
6297
6298(define_insn "*addqi_1_slp"
6299 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6300 (plus:QI (match_dup 0)
6301 (match_operand:QI 1 "general_operand" "qn,qnm")))
6302 (clobber (reg:CC 17))]
6303 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6304 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6305{
6306 switch (get_attr_type (insn))
6307 {
6308 case TYPE_INCDEC:
6309 if (operands[1] == const1_rtx)
6310 return "inc{b}\t%0";
6311 else if (operands[1] == constm1_rtx)
6312 return "dec{b}\t%0";
6313 abort();
6314
6315 default:
6316 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6317 if (GET_CODE (operands[1]) == CONST_INT
6318 && INTVAL (operands[1]) < 0)
6319 {
6320 operands[1] = GEN_INT (-INTVAL (operands[1]));
6321 return "sub{b}\t{%1, %0|%0, %1}";
6322 }
6323 return "add{b}\t{%1, %0|%0, %1}";
6324 }
6325}
6326 [(set (attr "type")
6327 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6328 (const_string "incdec")
6329 (const_string "alu1")))
6330 (set (attr "memory")
6331 (if_then_else (match_operand 1 "memory_operand" "")
6332 (const_string "load")
6333 (const_string "none")))
6334 (set_attr "mode" "QI")])
6335
6336(define_insn "*addqi_2"
6337 [(set (reg 17)
6338 (compare
6339 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6340 (match_operand:QI 2 "general_operand" "qmni,qni"))
6341 (const_int 0)))
6342 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6343 (plus:QI (match_dup 1) (match_dup 2)))]
6344 "ix86_match_ccmode (insn, CCGOCmode)
6345 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6346{
6347 switch (get_attr_type (insn))
6348 {
6349 case TYPE_INCDEC:
6350 if (operands[2] == const1_rtx)
6351 return "inc{b}\t%0";
6352 else if (operands[2] == constm1_rtx
6353 || (GET_CODE (operands[2]) == CONST_INT
6354 && INTVAL (operands[2]) == 255))
6355 return "dec{b}\t%0";
6356 abort();
6357
6358 default:
6359 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6360 if (GET_CODE (operands[2]) == CONST_INT
6361 && INTVAL (operands[2]) < 0)
6362 {
6363 operands[2] = GEN_INT (-INTVAL (operands[2]));
6364 return "sub{b}\t{%2, %0|%0, %2}";
6365 }
6366 return "add{b}\t{%2, %0|%0, %2}";
6367 }
6368}
6369 [(set (attr "type")
6370 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6371 (const_string "incdec")
6372 (const_string "alu")))
6373 (set_attr "mode" "QI")])
6374
6375(define_insn "*addqi_3"
6376 [(set (reg 17)
6377 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6378 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6379 (clobber (match_scratch:QI 0 "=q"))]
6380 "ix86_match_ccmode (insn, CCZmode)
6381 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6382{
6383 switch (get_attr_type (insn))
6384 {
6385 case TYPE_INCDEC:
6386 if (operands[2] == const1_rtx)
6387 return "inc{b}\t%0";
6388 else if (operands[2] == constm1_rtx
6389 || (GET_CODE (operands[2]) == CONST_INT
6390 && INTVAL (operands[2]) == 255))
6391 return "dec{b}\t%0";
6392 abort();
6393
6394 default:
6395 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6396 if (GET_CODE (operands[2]) == CONST_INT
6397 && INTVAL (operands[2]) < 0)
6398 {
6399 operands[2] = GEN_INT (-INTVAL (operands[2]));
6400 return "sub{b}\t{%2, %0|%0, %2}";
6401 }
6402 return "add{b}\t{%2, %0|%0, %2}";
6403 }
6404}
6405 [(set (attr "type")
6406 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407 (const_string "incdec")
6408 (const_string "alu")))
6409 (set_attr "mode" "QI")])
6410
6411; See comments above addsi_3_imm for details.
6412(define_insn "*addqi_4"
6413 [(set (reg 17)
6414 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6415 (match_operand:QI 2 "const_int_operand" "n")))
6416 (clobber (match_scratch:QI 0 "=qm"))]
6417 "ix86_match_ccmode (insn, CCGCmode)
6418 && (INTVAL (operands[2]) & 0xff) != 0x80"
6419{
6420 switch (get_attr_type (insn))
6421 {
6422 case TYPE_INCDEC:
6423 if (operands[2] == constm1_rtx
6424 || (GET_CODE (operands[2]) == CONST_INT
6425 && INTVAL (operands[2]) == 255))
6426 return "inc{b}\t%0";
6427 else if (operands[2] == const1_rtx)
6428 return "dec{b}\t%0";
6429 else
6430 abort();
6431
6432 default:
6433 if (! rtx_equal_p (operands[0], operands[1]))
6434 abort ();
6435 if (INTVAL (operands[2]) < 0)
6436 {
6437 operands[2] = GEN_INT (-INTVAL (operands[2]));
6438 return "add{b}\t{%2, %0|%0, %2}";
6439 }
6440 return "sub{b}\t{%2, %0|%0, %2}";
6441 }
6442}
6443 [(set (attr "type")
6444 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6445 (const_string "incdec")
6446 (const_string "alu")))
6447 (set_attr "mode" "QI")])
6448
6449
6450(define_insn "*addqi_5"
6451 [(set (reg 17)
6452 (compare
6453 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6454 (match_operand:QI 2 "general_operand" "qmni"))
6455 (const_int 0)))
6456 (clobber (match_scratch:QI 0 "=q"))]
6457 "ix86_match_ccmode (insn, CCGOCmode)
6458 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6459{
6460 switch (get_attr_type (insn))
6461 {
6462 case TYPE_INCDEC:
6463 if (operands[2] == const1_rtx)
6464 return "inc{b}\t%0";
6465 else if (operands[2] == constm1_rtx
6466 || (GET_CODE (operands[2]) == CONST_INT
6467 && INTVAL (operands[2]) == 255))
6468 return "dec{b}\t%0";
6469 abort();
6470
6471 default:
6472 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6473 if (GET_CODE (operands[2]) == CONST_INT
6474 && INTVAL (operands[2]) < 0)
6475 {
6476 operands[2] = GEN_INT (-INTVAL (operands[2]));
6477 return "sub{b}\t{%2, %0|%0, %2}";
6478 }
6479 return "add{b}\t{%2, %0|%0, %2}";
6480 }
6481}
6482 [(set (attr "type")
6483 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6484 (const_string "incdec")
6485 (const_string "alu")))
6486 (set_attr "mode" "QI")])
6487
6488
6489(define_insn "addqi_ext_1"
6490 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6491 (const_int 8)
6492 (const_int 8))
6493 (plus:SI
6494 (zero_extract:SI
6495 (match_operand 1 "ext_register_operand" "0")
6496 (const_int 8)
6497 (const_int 8))
6498 (match_operand:QI 2 "general_operand" "Qmn")))
6499 (clobber (reg:CC 17))]
6500 "!TARGET_64BIT"
6501{
6502 switch (get_attr_type (insn))
6503 {
6504 case TYPE_INCDEC:
6505 if (operands[2] == const1_rtx)
6506 return "inc{b}\t%h0";
6507 else if (operands[2] == constm1_rtx
6508 || (GET_CODE (operands[2]) == CONST_INT
6509 && INTVAL (operands[2]) == 255))
6510 return "dec{b}\t%h0";
6511 abort();
6512
6513 default:
6514 return "add{b}\t{%2, %h0|%h0, %2}";
6515 }
6516}
6517 [(set (attr "type")
6518 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6519 (const_string "incdec")
6520 (const_string "alu")))
6521 (set_attr "mode" "QI")])
6522
6523(define_insn "*addqi_ext_1_rex64"
6524 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6525 (const_int 8)
6526 (const_int 8))
6527 (plus:SI
6528 (zero_extract:SI
6529 (match_operand 1 "ext_register_operand" "0")
6530 (const_int 8)
6531 (const_int 8))
6532 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6533 (clobber (reg:CC 17))]
6534 "TARGET_64BIT"
6535{
6536 switch (get_attr_type (insn))
6537 {
6538 case TYPE_INCDEC:
6539 if (operands[2] == const1_rtx)
6540 return "inc{b}\t%h0";
6541 else if (operands[2] == constm1_rtx
6542 || (GET_CODE (operands[2]) == CONST_INT
6543 && INTVAL (operands[2]) == 255))
6544 return "dec{b}\t%h0";
6545 abort();
6546
6547 default:
6548 return "add{b}\t{%2, %h0|%h0, %2}";
6549 }
6550}
6551 [(set (attr "type")
6552 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6553 (const_string "incdec")
6554 (const_string "alu")))
6555 (set_attr "mode" "QI")])
6556
6557(define_insn "*addqi_ext_2"
6558 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6559 (const_int 8)
6560 (const_int 8))
6561 (plus:SI
6562 (zero_extract:SI
6563 (match_operand 1 "ext_register_operand" "%0")
6564 (const_int 8)
6565 (const_int 8))
6566 (zero_extract:SI
6567 (match_operand 2 "ext_register_operand" "Q")
6568 (const_int 8)
6569 (const_int 8))))
6570 (clobber (reg:CC 17))]
6571 ""
6572 "add{b}\t{%h2, %h0|%h0, %h2}"
6573 [(set_attr "type" "alu")
6574 (set_attr "mode" "QI")])
6575
6576;; The patterns that match these are at the end of this file.
6577
6578(define_expand "addxf3"
6579 [(set (match_operand:XF 0 "register_operand" "")
6580 (plus:XF (match_operand:XF 1 "register_operand" "")
6581 (match_operand:XF 2 "register_operand" "")))]
6582 "TARGET_80387"
6583 "")
6584
6585(define_expand "adddf3"
6586 [(set (match_operand:DF 0 "register_operand" "")
6587 (plus:DF (match_operand:DF 1 "register_operand" "")
6588 (match_operand:DF 2 "nonimmediate_operand" "")))]
6589 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6590 "")
6591
6592(define_expand "addsf3"
6593 [(set (match_operand:SF 0 "register_operand" "")
6594 (plus:SF (match_operand:SF 1 "register_operand" "")
6595 (match_operand:SF 2 "nonimmediate_operand" "")))]
6596 "TARGET_80387 || TARGET_SSE_MATH"
6597 "")
6598
6599;; Subtract instructions
6600
6601;; %%% splits for subsidi3
6602
6603(define_expand "subdi3"
6604 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6605 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6606 (match_operand:DI 2 "x86_64_general_operand" "")))
6607 (clobber (reg:CC 17))])]
6608 ""
6609 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6610
6611(define_insn "*subdi3_1"
6612 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6613 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6614 (match_operand:DI 2 "general_operand" "roiF,riF")))
6615 (clobber (reg:CC 17))]
6616 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6617 "#")
6618
6619(define_split
6620 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6621 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6622 (match_operand:DI 2 "general_operand" "")))
6623 (clobber (reg:CC 17))]
6624 "!TARGET_64BIT && reload_completed"
6625 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6626 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6627 (parallel [(set (match_dup 3)
6628 (minus:SI (match_dup 4)
6629 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6630 (match_dup 5))))
6631 (clobber (reg:CC 17))])]
6632 "split_di (operands+0, 1, operands+0, operands+3);
6633 split_di (operands+1, 1, operands+1, operands+4);
6634 split_di (operands+2, 1, operands+2, operands+5);")
6635
6636(define_insn "subdi3_carry_rex64"
6637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6638 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6639 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6640 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6641 (clobber (reg:CC 17))]
6642 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6643 "sbb{q}\t{%2, %0|%0, %2}"
6644 [(set_attr "type" "alu")
6645 (set_attr "pent_pair" "pu")
6646 (set_attr "ppro_uops" "few")
6647 (set_attr "mode" "DI")])
6648
6649(define_insn "*subdi_1_rex64"
6650 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6651 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6652 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6653 (clobber (reg:CC 17))]
6654 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6655 "sub{q}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "mode" "DI")])
6658
6659(define_insn "*subdi_2_rex64"
6660 [(set (reg 17)
6661 (compare
6662 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6663 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6664 (const_int 0)))
6665 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6666 (minus:DI (match_dup 1) (match_dup 2)))]
6667 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6668 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6669 "sub{q}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "DI")])
6672
6673(define_insn "*subdi_3_rex63"
6674 [(set (reg 17)
6675 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6676 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6677 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6678 (minus:DI (match_dup 1) (match_dup 2)))]
6679 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6680 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6681 "sub{q}\t{%2, %0|%0, %2}"
6682 [(set_attr "type" "alu")
6683 (set_attr "mode" "DI")])
6684
6685(define_insn "subqi3_carry"
6686 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6687 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6688 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6689 (match_operand:QI 2 "general_operand" "qi,qm"))))
6690 (clobber (reg:CC 17))]
6691 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6692 "sbb{b}\t{%2, %0|%0, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "pent_pair" "pu")
6695 (set_attr "ppro_uops" "few")
6696 (set_attr "mode" "QI")])
6697
6698(define_insn "subhi3_carry"
6699 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6700 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6701 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6702 (match_operand:HI 2 "general_operand" "ri,rm"))))
6703 (clobber (reg:CC 17))]
6704 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6705 "sbb{w}\t{%2, %0|%0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "pent_pair" "pu")
6708 (set_attr "ppro_uops" "few")
6709 (set_attr "mode" "HI")])
6710
6711(define_insn "subsi3_carry"
6712 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6715 (match_operand:SI 2 "general_operand" "ri,rm"))))
6716 (clobber (reg:CC 17))]
6717 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6718 "sbb{l}\t{%2, %0|%0, %2}"
6719 [(set_attr "type" "alu")
6720 (set_attr "pent_pair" "pu")
6721 (set_attr "ppro_uops" "few")
6722 (set_attr "mode" "SI")])
6723
6724(define_insn "subsi3_carry_zext"
6725 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6726 (zero_extend:DI
6727 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6728 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6729 (match_operand:SI 2 "general_operand" "ri,rm")))))
6730 (clobber (reg:CC 17))]
6731 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6732 "sbb{l}\t{%2, %k0|%k0, %2}"
6733 [(set_attr "type" "alu")
6734 (set_attr "pent_pair" "pu")
6735 (set_attr "ppro_uops" "few")
6736 (set_attr "mode" "SI")])
6737
6738(define_expand "subsi3"
6739 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6740 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6741 (match_operand:SI 2 "general_operand" "")))
6742 (clobber (reg:CC 17))])]
6743 ""
6744 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6745
6746(define_insn "*subsi_1"
6747 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6748 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6749 (match_operand:SI 2 "general_operand" "ri,rm")))
6750 (clobber (reg:CC 17))]
6751 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6752 "sub{l}\t{%2, %0|%0, %2}"
6753 [(set_attr "type" "alu")
6754 (set_attr "mode" "SI")])
6755
6756(define_insn "*subsi_1_zext"
6757 [(set (match_operand:DI 0 "register_operand" "=r")
6758 (zero_extend:DI
6759 (minus:SI (match_operand:SI 1 "register_operand" "0")
6760 (match_operand:SI 2 "general_operand" "rim"))))
6761 (clobber (reg:CC 17))]
6762 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763 "sub{l}\t{%2, %k0|%k0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "SI")])
6766
6767(define_insn "*subsi_2"
6768 [(set (reg 17)
6769 (compare
6770 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6771 (match_operand:SI 2 "general_operand" "ri,rm"))
6772 (const_int 0)))
6773 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6774 (minus:SI (match_dup 1) (match_dup 2)))]
6775 "ix86_match_ccmode (insn, CCGOCmode)
6776 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777 "sub{l}\t{%2, %0|%0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "mode" "SI")])
6780
6781(define_insn "*subsi_2_zext"
6782 [(set (reg 17)
6783 (compare
6784 (minus:SI (match_operand:SI 1 "register_operand" "0")
6785 (match_operand:SI 2 "general_operand" "rim"))
6786 (const_int 0)))
6787 (set (match_operand:DI 0 "register_operand" "=r")
6788 (zero_extend:DI
6789 (minus:SI (match_dup 1)
6790 (match_dup 2))))]
6791 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6792 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6793 "sub{l}\t{%2, %k0|%k0, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "mode" "SI")])
6796
6797(define_insn "*subsi_3"
6798 [(set (reg 17)
6799 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6800 (match_operand:SI 2 "general_operand" "ri,rm")))
6801 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6802 (minus:SI (match_dup 1) (match_dup 2)))]
6803 "ix86_match_ccmode (insn, CCmode)
6804 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805 "sub{l}\t{%2, %0|%0, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "SI")])
6808
6809(define_insn "*subsi_3_zext"
6810 [(set (reg 17)
6811 (compare (match_operand:SI 1 "register_operand" "0")
6812 (match_operand:SI 2 "general_operand" "rim")))
6813 (set (match_operand:DI 0 "register_operand" "=r")
6814 (zero_extend:DI
6815 (minus:SI (match_dup 1)
6816 (match_dup 2))))]
6817 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6818 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6819 "sub{q}\t{%2, %0|%0, %2}"
6820 [(set_attr "type" "alu")
6821 (set_attr "mode" "DI")])
6822
6823(define_expand "subhi3"
6824 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6825 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6826 (match_operand:HI 2 "general_operand" "")))
6827 (clobber (reg:CC 17))])]
6828 "TARGET_HIMODE_MATH"
6829 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6830
6831(define_insn "*subhi_1"
6832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6833 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6834 (match_operand:HI 2 "general_operand" "ri,rm")))
6835 (clobber (reg:CC 17))]
6836 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6837 "sub{w}\t{%2, %0|%0, %2}"
6838 [(set_attr "type" "alu")
6839 (set_attr "mode" "HI")])
6840
6841(define_insn "*subhi_2"
6842 [(set (reg 17)
6843 (compare
6844 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6845 (match_operand:HI 2 "general_operand" "ri,rm"))
6846 (const_int 0)))
6847 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6848 (minus:HI (match_dup 1) (match_dup 2)))]
6849 "ix86_match_ccmode (insn, CCGOCmode)
6850 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6851 "sub{w}\t{%2, %0|%0, %2}"
6852 [(set_attr "type" "alu")
6853 (set_attr "mode" "HI")])
6854
6855(define_insn "*subhi_3"
6856 [(set (reg 17)
6857 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6858 (match_operand:HI 2 "general_operand" "ri,rm")))
6859 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6860 (minus:HI (match_dup 1) (match_dup 2)))]
6861 "ix86_match_ccmode (insn, CCmode)
6862 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6863 "sub{w}\t{%2, %0|%0, %2}"
6864 [(set_attr "type" "alu")
6865 (set_attr "mode" "HI")])
6866
6867(define_expand "subqi3"
6868 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6869 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6870 (match_operand:QI 2 "general_operand" "")))
6871 (clobber (reg:CC 17))])]
6872 "TARGET_QIMODE_MATH"
6873 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6874
6875(define_insn "*subqi_1"
6876 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6877 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878 (match_operand:QI 2 "general_operand" "qn,qmn")))
6879 (clobber (reg:CC 17))]
6880 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6881 "sub{b}\t{%2, %0|%0, %2}"
6882 [(set_attr "type" "alu")
6883 (set_attr "mode" "QI")])
6884
6885(define_insn "*subqi_1_slp"
6886 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6887 (minus:QI (match_dup 0)
6888 (match_operand:QI 1 "general_operand" "qn,qmn")))
6889 (clobber (reg:CC 17))]
6890 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6891 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6892 "sub{b}\t{%1, %0|%0, %1}"
6893 [(set_attr "type" "alu1")
6894 (set_attr "mode" "QI")])
6895
6896(define_insn "*subqi_2"
6897 [(set (reg 17)
6898 (compare
6899 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6900 (match_operand:QI 2 "general_operand" "qi,qm"))
6901 (const_int 0)))
6902 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6903 (minus:HI (match_dup 1) (match_dup 2)))]
6904 "ix86_match_ccmode (insn, CCGOCmode)
6905 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6906 "sub{b}\t{%2, %0|%0, %2}"
6907 [(set_attr "type" "alu")
6908 (set_attr "mode" "QI")])
6909
6910(define_insn "*subqi_3"
6911 [(set (reg 17)
6912 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6913 (match_operand:QI 2 "general_operand" "qi,qm")))
6914 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6915 (minus:HI (match_dup 1) (match_dup 2)))]
6916 "ix86_match_ccmode (insn, CCmode)
6917 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6918 "sub{b}\t{%2, %0|%0, %2}"
6919 [(set_attr "type" "alu")
6920 (set_attr "mode" "QI")])
6921
6922;; The patterns that match these are at the end of this file.
6923
6924(define_expand "subxf3"
6925 [(set (match_operand:XF 0 "register_operand" "")
6926 (minus:XF (match_operand:XF 1 "register_operand" "")
6927 (match_operand:XF 2 "register_operand" "")))]
6928 "TARGET_80387"
6929 "")
6930
6931(define_expand "subdf3"
6932 [(set (match_operand:DF 0 "register_operand" "")
6933 (minus:DF (match_operand:DF 1 "register_operand" "")
6934 (match_operand:DF 2 "nonimmediate_operand" "")))]
6935 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6936 "")
6937
6938(define_expand "subsf3"
6939 [(set (match_operand:SF 0 "register_operand" "")
6940 (minus:SF (match_operand:SF 1 "register_operand" "")
6941 (match_operand:SF 2 "nonimmediate_operand" "")))]
6942 "TARGET_80387 || TARGET_SSE_MATH"
6943 "")
6944
6945;; Multiply instructions
6946
6947(define_expand "muldi3"
6948 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6949 (mult:DI (match_operand:DI 1 "register_operand" "")
6950 (match_operand:DI 2 "x86_64_general_operand" "")))
6951 (clobber (reg:CC 17))])]
6952 "TARGET_64BIT"
6953 "")
6954
6955(define_insn "*muldi3_1_rex64"
6956 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6958 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6959 (clobber (reg:CC 17))]
6960 "TARGET_64BIT
6961 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6962 "@
6963 imul{q}\t{%2, %1, %0|%0, %1, %2}
6964 imul{q}\t{%2, %1, %0|%0, %1, %2}
6965 imul{q}\t{%2, %0|%0, %2}"
6966 [(set_attr "type" "imul")
6967 (set_attr "prefix_0f" "0,0,1")
6968 (set (attr "athlon_decode")
6969 (cond [(eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (eq_attr "alternative" "1")
6972 (const_string "vector")
6973 (and (eq_attr "alternative" "2")
6974 (match_operand 1 "memory_operand" ""))
6975 (const_string "vector")]
6976 (const_string "direct")))
6977 (set_attr "mode" "DI")])
6978
6979(define_expand "mulsi3"
6980 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6981 (mult:SI (match_operand:SI 1 "register_operand" "")
6982 (match_operand:SI 2 "general_operand" "")))
6983 (clobber (reg:CC 17))])]
6984 ""
6985 "")
6986
6987(define_insn "*mulsi3_1"
6988 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6989 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6990 (match_operand:SI 2 "general_operand" "K,i,mr")))
6991 (clobber (reg:CC 17))]
6992 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6993 "@
6994 imul{l}\t{%2, %1, %0|%0, %1, %2}
6995 imul{l}\t{%2, %1, %0|%0, %1, %2}
6996 imul{l}\t{%2, %0|%0, %2}"
6997 [(set_attr "type" "imul")
6998 (set_attr "prefix_0f" "0,0,1")
6999 (set (attr "athlon_decode")
7000 (cond [(eq_attr "cpu" "athlon")
7001 (const_string "vector")
7002 (eq_attr "alternative" "1")
7003 (const_string "vector")
7004 (and (eq_attr "alternative" "2")
7005 (match_operand 1 "memory_operand" ""))
7006 (const_string "vector")]
7007 (const_string "direct")))
7008 (set_attr "mode" "SI")])
7009
7010(define_insn "*mulsi3_1_zext"
7011 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7012 (zero_extend:DI
7013 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7014 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7015 (clobber (reg:CC 17))]
7016 "TARGET_64BIT
7017 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7018 "@
7019 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7020 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7021 imul{l}\t{%2, %k0|%k0, %2}"
7022 [(set_attr "type" "imul")
7023 (set_attr "prefix_0f" "0,0,1")
7024 (set (attr "athlon_decode")
7025 (cond [(eq_attr "cpu" "athlon")
7026 (const_string "vector")
7027 (eq_attr "alternative" "1")
7028 (const_string "vector")
7029 (and (eq_attr "alternative" "2")
7030 (match_operand 1 "memory_operand" ""))
7031 (const_string "vector")]
7032 (const_string "direct")))
7033 (set_attr "mode" "SI")])
7034
7035(define_expand "mulhi3"
7036 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7037 (mult:HI (match_operand:HI 1 "register_operand" "")
7038 (match_operand:HI 2 "general_operand" "")))
7039 (clobber (reg:CC 17))])]
7040 "TARGET_HIMODE_MATH"
7041 "")
7042
7043(define_insn "*mulhi3_1"
7044 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7045 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7046 (match_operand:HI 2 "general_operand" "K,i,mr")))
7047 (clobber (reg:CC 17))]
7048 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7049 "@
7050 imul{w}\t{%2, %1, %0|%0, %1, %2}
7051 imul{w}\t{%2, %1, %0|%0, %1, %2}
7052 imul{w}\t{%2, %0|%0, %2}"
7053 [(set_attr "type" "imul")
7054 (set_attr "prefix_0f" "0,0,1")
7055 (set (attr "athlon_decode")
7056 (cond [(eq_attr "cpu" "athlon")
7057 (const_string "vector")
7058 (eq_attr "alternative" "1,2")
7059 (const_string "vector")]
7060 (const_string "direct")))
7061 (set_attr "mode" "HI")])
7062
7063(define_expand "mulqi3"
7064 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7065 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7066 (match_operand:QI 2 "register_operand" "")))
7067 (clobber (reg:CC 17))])]
7068 "TARGET_QIMODE_MATH"
7069 "")
7070
7071(define_insn "*mulqi3_1"
7072 [(set (match_operand:QI 0 "register_operand" "=a")
7073 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7074 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7075 (clobber (reg:CC 17))]
7076 "TARGET_QIMODE_MATH
7077 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7078 "mul{b}\t%2"
7079 [(set_attr "type" "imul")
7080 (set_attr "length_immediate" "0")
7081 (set (attr "athlon_decode")
7082 (if_then_else (eq_attr "cpu" "athlon")
7083 (const_string "vector")
7084 (const_string "direct")))
7085 (set_attr "mode" "QI")])
7086
7087(define_expand "umulqihi3"
7088 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7089 (mult:HI (zero_extend:HI
7090 (match_operand:QI 1 "nonimmediate_operand" ""))
7091 (zero_extend:HI
7092 (match_operand:QI 2 "register_operand" ""))))
7093 (clobber (reg:CC 17))])]
7094 "TARGET_QIMODE_MATH"
7095 "")
7096
7097(define_insn "*umulqihi3_1"
7098 [(set (match_operand:HI 0 "register_operand" "=a")
7099 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7100 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7101 (clobber (reg:CC 17))]
7102 "TARGET_QIMODE_MATH
7103 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7104 "mul{b}\t%2"
7105 [(set_attr "type" "imul")
7106 (set_attr "length_immediate" "0")
7107 (set (attr "athlon_decode")
7108 (if_then_else (eq_attr "cpu" "athlon")
7109 (const_string "vector")
7110 (const_string "direct")))
7111 (set_attr "mode" "QI")])
7112
7113(define_expand "mulqihi3"
7114 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7115 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7116 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7117 (clobber (reg:CC 17))])]
7118 "TARGET_QIMODE_MATH"
7119 "")
7120
7121(define_insn "*mulqihi3_insn"
7122 [(set (match_operand:HI 0 "register_operand" "=a")
7123 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7124 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7125 (clobber (reg:CC 17))]
7126 "TARGET_QIMODE_MATH
7127 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7128 "imul{b}\t%2"
7129 [(set_attr "type" "imul")
7130 (set_attr "length_immediate" "0")
7131 (set (attr "athlon_decode")
7132 (if_then_else (eq_attr "cpu" "athlon")
7133 (const_string "vector")
7134 (const_string "direct")))
7135 (set_attr "mode" "QI")])
7136
7137(define_expand "umulditi3"
7138 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7139 (mult:TI (zero_extend:TI
7140 (match_operand:DI 1 "nonimmediate_operand" ""))
7141 (zero_extend:TI
7142 (match_operand:DI 2 "register_operand" ""))))
7143 (clobber (reg:CC 17))])]
7144 "TARGET_64BIT"
7145 "")
7146
7147(define_insn "*umulditi3_insn"
7148 [(set (match_operand:TI 0 "register_operand" "=A")
7149 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7150 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7151 (clobber (reg:CC 17))]
7152 "TARGET_64BIT
7153 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7154 "mul{q}\t%2"
7155 [(set_attr "type" "imul")
7156 (set_attr "ppro_uops" "few")
7157 (set_attr "length_immediate" "0")
7158 (set (attr "athlon_decode")
7159 (if_then_else (eq_attr "cpu" "athlon")
7160 (const_string "vector")
7161 (const_string "double")))
7162 (set_attr "mode" "DI")])
7163
7164;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7165(define_expand "umulsidi3"
7166 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7167 (mult:DI (zero_extend:DI
7168 (match_operand:SI 1 "nonimmediate_operand" ""))
7169 (zero_extend:DI
7170 (match_operand:SI 2 "register_operand" ""))))
7171 (clobber (reg:CC 17))])]
7172 "!TARGET_64BIT"
7173 "")
7174
7175(define_insn "*umulsidi3_insn"
7176 [(set (match_operand:DI 0 "register_operand" "=A")
7177 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7178 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7179 (clobber (reg:CC 17))]
7180 "!TARGET_64BIT
7181 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7182 "mul{l}\t%2"
7183 [(set_attr "type" "imul")
7184 (set_attr "ppro_uops" "few")
7185 (set_attr "length_immediate" "0")
7186 (set (attr "athlon_decode")
7187 (if_then_else (eq_attr "cpu" "athlon")
7188 (const_string "vector")
7189 (const_string "double")))
7190 (set_attr "mode" "SI")])
7191
7192(define_expand "mulditi3"
7193 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7194 (mult:TI (sign_extend:TI
7195 (match_operand:DI 1 "nonimmediate_operand" ""))
7196 (sign_extend:TI
7197 (match_operand:DI 2 "register_operand" ""))))
7198 (clobber (reg:CC 17))])]
7199 "TARGET_64BIT"
7200 "")
7201
7202(define_insn "*mulditi3_insn"
7203 [(set (match_operand:TI 0 "register_operand" "=A")
7204 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7205 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7206 (clobber (reg:CC 17))]
7207 "TARGET_64BIT
7208 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7209 "imul{q}\t%2"
7210 [(set_attr "type" "imul")
7211 (set_attr "length_immediate" "0")
7212 (set (attr "athlon_decode")
7213 (if_then_else (eq_attr "cpu" "athlon")
7214 (const_string "vector")
7215 (const_string "double")))
7216 (set_attr "mode" "DI")])
7217
7218(define_expand "mulsidi3"
7219 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7220 (mult:DI (sign_extend:DI
7221 (match_operand:SI 1 "nonimmediate_operand" ""))
7222 (sign_extend:DI
7223 (match_operand:SI 2 "register_operand" ""))))
7224 (clobber (reg:CC 17))])]
7225 "!TARGET_64BIT"
7226 "")
7227
7228(define_insn "*mulsidi3_insn"
7229 [(set (match_operand:DI 0 "register_operand" "=A")
7230 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7231 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7232 (clobber (reg:CC 17))]
7233 "!TARGET_64BIT
7234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235 "imul{l}\t%2"
7236 [(set_attr "type" "imul")
7237 (set_attr "length_immediate" "0")
7238 (set (attr "athlon_decode")
7239 (if_then_else (eq_attr "cpu" "athlon")
7240 (const_string "vector")
7241 (const_string "double")))
7242 (set_attr "mode" "SI")])
7243
7244(define_expand "umuldi3_highpart"
7245 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7246 (truncate:DI
7247 (lshiftrt:TI
7248 (mult:TI (zero_extend:TI
7249 (match_operand:DI 1 "nonimmediate_operand" ""))
7250 (zero_extend:TI
7251 (match_operand:DI 2 "register_operand" "")))
7252 (const_int 64))))
7253 (clobber (match_scratch:DI 3 ""))
7254 (clobber (reg:CC 17))])]
7255 "TARGET_64BIT"
7256 "")
7257
7258(define_insn "*umuldi3_highpart_rex64"
7259 [(set (match_operand:DI 0 "register_operand" "=d")
7260 (truncate:DI
7261 (lshiftrt:TI
7262 (mult:TI (zero_extend:TI
7263 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7264 (zero_extend:TI
7265 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7266 (const_int 64))))
7267 (clobber (match_scratch:DI 3 "=1"))
7268 (clobber (reg:CC 17))]
7269 "TARGET_64BIT
7270 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7271 "mul{q}\t%2"
7272 [(set_attr "type" "imul")
7273 (set_attr "ppro_uops" "few")
7274 (set_attr "length_immediate" "0")
7275 (set (attr "athlon_decode")
7276 (if_then_else (eq_attr "cpu" "athlon")
7277 (const_string "vector")
7278 (const_string "double")))
7279 (set_attr "mode" "DI")])
7280
7281(define_expand "umulsi3_highpart"
7282 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7283 (truncate:SI
7284 (lshiftrt:DI
7285 (mult:DI (zero_extend:DI
7286 (match_operand:SI 1 "nonimmediate_operand" ""))
7287 (zero_extend:DI
7288 (match_operand:SI 2 "register_operand" "")))
7289 (const_int 32))))
7290 (clobber (match_scratch:SI 3 ""))
7291 (clobber (reg:CC 17))])]
7292 ""
7293 "")
7294
7295(define_insn "*umulsi3_highpart_insn"
7296 [(set (match_operand:SI 0 "register_operand" "=d")
7297 (truncate:SI
7298 (lshiftrt:DI
7299 (mult:DI (zero_extend:DI
7300 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7301 (zero_extend:DI
7302 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7303 (const_int 32))))
7304 (clobber (match_scratch:SI 3 "=1"))
7305 (clobber (reg:CC 17))]
7306 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7307 "mul{l}\t%2"
7308 [(set_attr "type" "imul")
7309 (set_attr "ppro_uops" "few")
7310 (set_attr "length_immediate" "0")
7311 (set (attr "athlon_decode")
7312 (if_then_else (eq_attr "cpu" "athlon")
7313 (const_string "vector")
7314 (const_string "double")))
7315 (set_attr "mode" "SI")])
7316
7317(define_insn "*umulsi3_highpart_zext"
7318 [(set (match_operand:DI 0 "register_operand" "=d")
7319 (zero_extend:DI (truncate:SI
7320 (lshiftrt:DI
7321 (mult:DI (zero_extend:DI
7322 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7323 (zero_extend:DI
7324 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7325 (const_int 32)))))
7326 (clobber (match_scratch:SI 3 "=1"))
7327 (clobber (reg:CC 17))]
7328 "TARGET_64BIT
7329 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7330 "mul{l}\t%2"
7331 [(set_attr "type" "imul")
7332 (set_attr "ppro_uops" "few")
7333 (set_attr "length_immediate" "0")
7334 (set (attr "athlon_decode")
7335 (if_then_else (eq_attr "cpu" "athlon")
7336 (const_string "vector")
7337 (const_string "double")))
7338 (set_attr "mode" "SI")])
7339
7340(define_expand "smuldi3_highpart"
7341 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7342 (truncate:DI
7343 (lshiftrt:TI
7344 (mult:TI (sign_extend:TI
7345 (match_operand:DI 1 "nonimmediate_operand" ""))
7346 (sign_extend:TI
7347 (match_operand:DI 2 "register_operand" "")))
7348 (const_int 64))))
7349 (clobber (match_scratch:DI 3 ""))
7350 (clobber (reg:CC 17))])]
7351 "TARGET_64BIT"
7352 "")
7353
7354(define_insn "*smuldi3_highpart_rex64"
7355 [(set (match_operand:DI 0 "register_operand" "=d")
7356 (truncate:DI
7357 (lshiftrt:TI
7358 (mult:TI (sign_extend:TI
7359 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7360 (sign_extend:TI
7361 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7362 (const_int 64))))
7363 (clobber (match_scratch:DI 3 "=1"))
7364 (clobber (reg:CC 17))]
7365 "TARGET_64BIT
7366 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7367 "imul{q}\t%2"
7368 [(set_attr "type" "imul")
7369 (set_attr "ppro_uops" "few")
7370 (set (attr "athlon_decode")
7371 (if_then_else (eq_attr "cpu" "athlon")
7372 (const_string "vector")
7373 (const_string "double")))
7374 (set_attr "mode" "DI")])
7375
7376(define_expand "smulsi3_highpart"
7377 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7378 (truncate:SI
7379 (lshiftrt:DI
7380 (mult:DI (sign_extend:DI
7381 (match_operand:SI 1 "nonimmediate_operand" ""))
7382 (sign_extend:DI
7383 (match_operand:SI 2 "register_operand" "")))
7384 (const_int 32))))
7385 (clobber (match_scratch:SI 3 ""))
7386 (clobber (reg:CC 17))])]
7387 ""
7388 "")
7389
7390(define_insn "*smulsi3_highpart_insn"
7391 [(set (match_operand:SI 0 "register_operand" "=d")
7392 (truncate:SI
7393 (lshiftrt:DI
7394 (mult:DI (sign_extend:DI
7395 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7396 (sign_extend:DI
7397 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7398 (const_int 32))))
7399 (clobber (match_scratch:SI 3 "=1"))
7400 (clobber (reg:CC 17))]
7401 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7402 "imul{l}\t%2"
7403 [(set_attr "type" "imul")
7404 (set_attr "ppro_uops" "few")
7405 (set (attr "athlon_decode")
7406 (if_then_else (eq_attr "cpu" "athlon")
7407 (const_string "vector")
7408 (const_string "double")))
7409 (set_attr "mode" "SI")])
7410
7411(define_insn "*smulsi3_highpart_zext"
7412 [(set (match_operand:DI 0 "register_operand" "=d")
7413 (zero_extend:DI (truncate:SI
7414 (lshiftrt:DI
7415 (mult:DI (sign_extend:DI
7416 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7417 (sign_extend:DI
7418 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7419 (const_int 32)))))
7420 (clobber (match_scratch:SI 3 "=1"))
7421 (clobber (reg:CC 17))]
7422 "TARGET_64BIT
7423 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7424 "imul{l}\t%2"
7425 [(set_attr "type" "imul")
7426 (set_attr "ppro_uops" "few")
7427 (set (attr "athlon_decode")
7428 (if_then_else (eq_attr "cpu" "athlon")
7429 (const_string "vector")
7430 (const_string "double")))
7431 (set_attr "mode" "SI")])
7432
7433;; The patterns that match these are at the end of this file.
7434
7435(define_expand "mulxf3"
7436 [(set (match_operand:XF 0 "register_operand" "")
7437 (mult:XF (match_operand:XF 1 "register_operand" "")
7438 (match_operand:XF 2 "register_operand" "")))]
7439 "TARGET_80387"
7440 "")
7441
7442(define_expand "muldf3"
7443 [(set (match_operand:DF 0 "register_operand" "")
7444 (mult:DF (match_operand:DF 1 "register_operand" "")
7445 (match_operand:DF 2 "nonimmediate_operand" "")))]
7446 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7447 "")
7448
7449(define_expand "mulsf3"
7450 [(set (match_operand:SF 0 "register_operand" "")
7451 (mult:SF (match_operand:SF 1 "register_operand" "")
7452 (match_operand:SF 2 "nonimmediate_operand" "")))]
7453 "TARGET_80387 || TARGET_SSE_MATH"
7454 "")
7455
7456;; Divide instructions
7457
7458(define_insn "divqi3"
7459 [(set (match_operand:QI 0 "register_operand" "=a")
7460 (div:QI (match_operand:HI 1 "register_operand" "0")
7461 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7462 (clobber (reg:CC 17))]
7463 "TARGET_QIMODE_MATH"
7464 "idiv{b}\t%2"
7465 [(set_attr "type" "idiv")
7466 (set_attr "mode" "QI")
7467 (set_attr "ppro_uops" "few")])
7468
7469(define_insn "udivqi3"
7470 [(set (match_operand:QI 0 "register_operand" "=a")
7471 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7472 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7473 (clobber (reg:CC 17))]
7474 "TARGET_QIMODE_MATH"
7475 "div{b}\t%2"
7476 [(set_attr "type" "idiv")
7477 (set_attr "mode" "QI")
7478 (set_attr "ppro_uops" "few")])
7479
7480;; The patterns that match these are at the end of this file.
7481
7482(define_expand "divxf3"
7483 [(set (match_operand:XF 0 "register_operand" "")
7484 (div:XF (match_operand:XF 1 "register_operand" "")
7485 (match_operand:XF 2 "register_operand" "")))]
7486 "TARGET_80387"
7487 "")
7488
7489(define_expand "divdf3"
7490 [(set (match_operand:DF 0 "register_operand" "")
7491 (div:DF (match_operand:DF 1 "register_operand" "")
7492 (match_operand:DF 2 "nonimmediate_operand" "")))]
7493 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7494 "")
7495
7496(define_expand "divsf3"
7497 [(set (match_operand:SF 0 "register_operand" "")
7498 (div:SF (match_operand:SF 1 "register_operand" "")
7499 (match_operand:SF 2 "nonimmediate_operand" "")))]
7500 "TARGET_80387 || TARGET_SSE_MATH"
7501 "")
7502
7503;; Remainder instructions.
7504
7505(define_expand "divmoddi4"
7506 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7507 (div:DI (match_operand:DI 1 "register_operand" "")
7508 (match_operand:DI 2 "nonimmediate_operand" "")))
7509 (set (match_operand:DI 3 "register_operand" "")
7510 (mod:DI (match_dup 1) (match_dup 2)))
7511 (clobber (reg:CC 17))])]
7512 "TARGET_64BIT"
7513 "")
7514
7515;; Allow to come the parameter in eax or edx to avoid extra moves.
7516;; Penalize eax case slightly because it results in worse scheduling
7517;; of code.
7518(define_insn "*divmoddi4_nocltd_rex64"
7519 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7520 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7521 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7522 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7523 (mod:DI (match_dup 2) (match_dup 3)))
7524 (clobber (reg:CC 17))]
7525 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7526 "#"
7527 [(set_attr "type" "multi")])
7528
7529(define_insn "*divmoddi4_cltd_rex64"
7530 [(set (match_operand:DI 0 "register_operand" "=a")
7531 (div:DI (match_operand:DI 2 "register_operand" "a")
7532 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7533 (set (match_operand:DI 1 "register_operand" "=&d")
7534 (mod:DI (match_dup 2) (match_dup 3)))
7535 (clobber (reg:CC 17))]
7536 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7537 "#"
7538 [(set_attr "type" "multi")])
7539
7540(define_insn "*divmoddi_noext_rex64"
7541 [(set (match_operand:DI 0 "register_operand" "=a")
7542 (div:DI (match_operand:DI 1 "register_operand" "0")
7543 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7544 (set (match_operand:DI 3 "register_operand" "=d")
7545 (mod:DI (match_dup 1) (match_dup 2)))
7546 (use (match_operand:DI 4 "register_operand" "3"))
7547 (clobber (reg:CC 17))]
7548 "TARGET_64BIT"
7549 "idiv{q}\t%2"
7550 [(set_attr "type" "idiv")
7551 (set_attr "mode" "DI")
7552 (set_attr "ppro_uops" "few")])
7553
7554(define_split
7555 [(set (match_operand:DI 0 "register_operand" "")
7556 (div:DI (match_operand:DI 1 "register_operand" "")
7557 (match_operand:DI 2 "nonimmediate_operand" "")))
7558 (set (match_operand:DI 3 "register_operand" "")
7559 (mod:DI (match_dup 1) (match_dup 2)))
7560 (clobber (reg:CC 17))]
7561 "TARGET_64BIT && reload_completed"
7562 [(parallel [(set (match_dup 3)
7563 (ashiftrt:DI (match_dup 4) (const_int 63)))
7564 (clobber (reg:CC 17))])
7565 (parallel [(set (match_dup 0)
7566 (div:DI (reg:DI 0) (match_dup 2)))
7567 (set (match_dup 3)
7568 (mod:DI (reg:DI 0) (match_dup 2)))
7569 (use (match_dup 3))
7570 (clobber (reg:CC 17))])]
7571{
7572 /* Avoid use of cltd in favor of a mov+shift. */
7573 if (!TARGET_USE_CLTD && !optimize_size)
7574 {
7575 if (true_regnum (operands[1]))
7576 emit_move_insn (operands[0], operands[1]);
7577 else
7578 emit_move_insn (operands[3], operands[1]);
7579 operands[4] = operands[3];
7580 }
7581 else
7582 {
7583 if (true_regnum (operands[1]))
7584 abort();
7585 operands[4] = operands[1];
7586 }
7587})
7588
7589
7590(define_expand "divmodsi4"
7591 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7592 (div:SI (match_operand:SI 1 "register_operand" "")
7593 (match_operand:SI 2 "nonimmediate_operand" "")))
7594 (set (match_operand:SI 3 "register_operand" "")
7595 (mod:SI (match_dup 1) (match_dup 2)))
7596 (clobber (reg:CC 17))])]
7597 ""
7598 "")
7599
7600;; Allow to come the parameter in eax or edx to avoid extra moves.
7601;; Penalize eax case slightly because it results in worse scheduling
7602;; of code.
7603(define_insn "*divmodsi4_nocltd"
7604 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7605 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7606 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7607 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7608 (mod:SI (match_dup 2) (match_dup 3)))
7609 (clobber (reg:CC 17))]
7610 "!optimize_size && !TARGET_USE_CLTD"
7611 "#"
7612 [(set_attr "type" "multi")])
7613
7614(define_insn "*divmodsi4_cltd"
7615 [(set (match_operand:SI 0 "register_operand" "=a")
7616 (div:SI (match_operand:SI 2 "register_operand" "a")
7617 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7618 (set (match_operand:SI 1 "register_operand" "=&d")
7619 (mod:SI (match_dup 2) (match_dup 3)))
7620 (clobber (reg:CC 17))]
7621 "optimize_size || TARGET_USE_CLTD"
7622 "#"
7623 [(set_attr "type" "multi")])
7624
7625(define_insn "*divmodsi_noext"
7626 [(set (match_operand:SI 0 "register_operand" "=a")
7627 (div:SI (match_operand:SI 1 "register_operand" "0")
7628 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7629 (set (match_operand:SI 3 "register_operand" "=d")
7630 (mod:SI (match_dup 1) (match_dup 2)))
7631 (use (match_operand:SI 4 "register_operand" "3"))
7632 (clobber (reg:CC 17))]
7633 ""
7634 "idiv{l}\t%2"
7635 [(set_attr "type" "idiv")
7636 (set_attr "mode" "SI")
7637 (set_attr "ppro_uops" "few")])
7638
7639(define_split
7640 [(set (match_operand:SI 0 "register_operand" "")
7641 (div:SI (match_operand:SI 1 "register_operand" "")
7642 (match_operand:SI 2 "nonimmediate_operand" "")))
7643 (set (match_operand:SI 3 "register_operand" "")
7644 (mod:SI (match_dup 1) (match_dup 2)))
7645 (clobber (reg:CC 17))]
7646 "reload_completed"
7647 [(parallel [(set (match_dup 3)
7648 (ashiftrt:SI (match_dup 4) (const_int 31)))
7649 (clobber (reg:CC 17))])
7650 (parallel [(set (match_dup 0)
7651 (div:SI (reg:SI 0) (match_dup 2)))
7652 (set (match_dup 3)
7653 (mod:SI (reg:SI 0) (match_dup 2)))
7654 (use (match_dup 3))
7655 (clobber (reg:CC 17))])]
7656{
7657 /* Avoid use of cltd in favor of a mov+shift. */
7658 if (!TARGET_USE_CLTD && !optimize_size)
7659 {
7660 if (true_regnum (operands[1]))
7661 emit_move_insn (operands[0], operands[1]);
7662 else
7663 emit_move_insn (operands[3], operands[1]);
7664 operands[4] = operands[3];
7665 }
7666 else
7667 {
7668 if (true_regnum (operands[1]))
7669 abort();
7670 operands[4] = operands[1];
7671 }
7672})
7673;; %%% Split me.
7674(define_insn "divmodhi4"
7675 [(set (match_operand:HI 0 "register_operand" "=a")
7676 (div:HI (match_operand:HI 1 "register_operand" "0")
7677 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7678 (set (match_operand:HI 3 "register_operand" "=&d")
7679 (mod:HI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC 17))]
7681 "TARGET_HIMODE_MATH"
7682 "cwtd\;idiv{w}\t%2"
7683 [(set_attr "type" "multi")
7684 (set_attr "length_immediate" "0")
7685 (set_attr "mode" "SI")])
7686
7687(define_insn "udivmoddi4"
7688 [(set (match_operand:DI 0 "register_operand" "=a")
7689 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7690 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7691 (set (match_operand:DI 3 "register_operand" "=&d")
7692 (umod:DI (match_dup 1) (match_dup 2)))
7693 (clobber (reg:CC 17))]
7694 "TARGET_64BIT"
7695 "xor{q}\t%3, %3\;div{q}\t%2"
7696 [(set_attr "type" "multi")
7697 (set_attr "length_immediate" "0")
7698 (set_attr "mode" "DI")])
7699
7700(define_insn "*udivmoddi4_noext"
7701 [(set (match_operand:DI 0 "register_operand" "=a")
7702 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7703 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7704 (set (match_operand:DI 3 "register_operand" "=d")
7705 (umod:DI (match_dup 1) (match_dup 2)))
7706 (use (match_dup 3))
7707 (clobber (reg:CC 17))]
7708 "TARGET_64BIT"
7709 "div{q}\t%2"
7710 [(set_attr "type" "idiv")
7711 (set_attr "ppro_uops" "few")
7712 (set_attr "mode" "DI")])
7713
7714(define_split
7715 [(set (match_operand:DI 0 "register_operand" "")
7716 (udiv:DI (match_operand:DI 1 "register_operand" "")
7717 (match_operand:DI 2 "nonimmediate_operand" "")))
7718 (set (match_operand:DI 3 "register_operand" "")
7719 (umod:DI (match_dup 1) (match_dup 2)))
7720 (clobber (reg:CC 17))]
7721 "TARGET_64BIT && reload_completed"
7722 [(set (match_dup 3) (const_int 0))
7723 (parallel [(set (match_dup 0)
7724 (udiv:DI (match_dup 1) (match_dup 2)))
7725 (set (match_dup 3)
7726 (umod:DI (match_dup 1) (match_dup 2)))
7727 (use (match_dup 3))
7728 (clobber (reg:CC 17))])]
7729 "")
7730
7731(define_insn "udivmodsi4"
7732 [(set (match_operand:SI 0 "register_operand" "=a")
7733 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7734 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7735 (set (match_operand:SI 3 "register_operand" "=&d")
7736 (umod:SI (match_dup 1) (match_dup 2)))
7737 (clobber (reg:CC 17))]
7738 ""
7739 "xor{l}\t%3, %3\;div{l}\t%2"
7740 [(set_attr "type" "multi")
7741 (set_attr "length_immediate" "0")
7742 (set_attr "mode" "SI")])
7743
7744(define_insn "*udivmodsi4_noext"
7745 [(set (match_operand:SI 0 "register_operand" "=a")
7746 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7747 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7748 (set (match_operand:SI 3 "register_operand" "=d")
7749 (umod:SI (match_dup 1) (match_dup 2)))
7750 (use (match_dup 3))
7751 (clobber (reg:CC 17))]
7752 ""
7753 "div{l}\t%2"
7754 [(set_attr "type" "idiv")
7755 (set_attr "ppro_uops" "few")
7756 (set_attr "mode" "SI")])
7757
7758(define_split
7759 [(set (match_operand:SI 0 "register_operand" "")
7760 (udiv:SI (match_operand:SI 1 "register_operand" "")
7761 (match_operand:SI 2 "nonimmediate_operand" "")))
7762 (set (match_operand:SI 3 "register_operand" "")
7763 (umod:SI (match_dup 1) (match_dup 2)))
7764 (clobber (reg:CC 17))]
7765 "reload_completed"
7766 [(set (match_dup 3) (const_int 0))
7767 (parallel [(set (match_dup 0)
7768 (udiv:SI (match_dup 1) (match_dup 2)))
7769 (set (match_dup 3)
7770 (umod:SI (match_dup 1) (match_dup 2)))
7771 (use (match_dup 3))
7772 (clobber (reg:CC 17))])]
7773 "")
7774
7775(define_expand "udivmodhi4"
7776 [(set (match_dup 4) (const_int 0))
7777 (parallel [(set (match_operand:HI 0 "register_operand" "")
7778 (udiv:HI (match_operand:HI 1 "register_operand" "")
7779 (match_operand:HI 2 "nonimmediate_operand" "")))
7780 (set (match_operand:HI 3 "register_operand" "")
7781 (umod:HI (match_dup 1) (match_dup 2)))
7782 (use (match_dup 4))
7783 (clobber (reg:CC 17))])]
7784 "TARGET_HIMODE_MATH"
7785 "operands[4] = gen_reg_rtx (HImode);")
7786
7787(define_insn "*udivmodhi_noext"
7788 [(set (match_operand:HI 0 "register_operand" "=a")
7789 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7790 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7791 (set (match_operand:HI 3 "register_operand" "=d")
7792 (umod:HI (match_dup 1) (match_dup 2)))
7793 (use (match_operand:HI 4 "register_operand" "3"))
7794 (clobber (reg:CC 17))]
7795 ""
7796 "div{w}\t%2"
7797 [(set_attr "type" "idiv")
7798 (set_attr "mode" "HI")
7799 (set_attr "ppro_uops" "few")])
7800
7801;; We can not use div/idiv for double division, because it causes
7802;; "division by zero" on the overflow and that's not what we expect
7803;; from truncate. Because true (non truncating) double division is
7804;; never generated, we can't create this insn anyway.
7805;
7806;(define_insn ""
7807; [(set (match_operand:SI 0 "register_operand" "=a")
7808; (truncate:SI
7809; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7810; (zero_extend:DI
7811; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7812; (set (match_operand:SI 3 "register_operand" "=d")
7813; (truncate:SI
7814; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7815; (clobber (reg:CC 17))]
7816; ""
7817; "div{l}\t{%2, %0|%0, %2}"
7818; [(set_attr "type" "idiv")
7819; (set_attr "ppro_uops" "few")])
7820
7821;;- Logical AND instructions
7822
7823;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7824;; Note that this excludes ah.
7825
7826(define_insn "*testdi_1_rex64"
7827 [(set (reg 17)
7828 (compare
7829 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7830 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7831 (const_int 0)))]
7832 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7834 "@
7835 test{l}\t{%k1, %k0|%k0, %k1}
7836 test{l}\t{%k1, %k0|%k0, %k1}
7837 test{q}\t{%1, %0|%0, %1}
7838 test{q}\t{%1, %0|%0, %1}
7839 test{q}\t{%1, %0|%0, %1}"
7840 [(set_attr "type" "test")
7841 (set_attr "modrm" "0,1,0,1,1")
7842 (set_attr "mode" "SI,SI,DI,DI,DI")
7843 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7844
7845(define_insn "testsi_1"
7846 [(set (reg 17)
7847 (compare
7848 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7849 (match_operand:SI 1 "general_operand" "in,in,rin"))
7850 (const_int 0)))]
7851 "ix86_match_ccmode (insn, CCNOmode)
7852 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7853 "test{l}\t{%1, %0|%0, %1}"
7854 [(set_attr "type" "test")
7855 (set_attr "modrm" "0,1,1")
7856 (set_attr "mode" "SI")
7857 (set_attr "pent_pair" "uv,np,uv")])
7858
7859(define_expand "testsi_ccno_1"
7860 [(set (reg:CCNO 17)
7861 (compare:CCNO
7862 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7863 (match_operand:SI 1 "nonmemory_operand" ""))
7864 (const_int 0)))]
7865 ""
7866 "")
7867
7868(define_insn "*testhi_1"
7869 [(set (reg 17)
7870 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7871 (match_operand:HI 1 "general_operand" "n,n,rn"))
7872 (const_int 0)))]
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7875 "test{w}\t{%1, %0|%0, %1}"
7876 [(set_attr "type" "test")
7877 (set_attr "modrm" "0,1,1")
7878 (set_attr "mode" "HI")
7879 (set_attr "pent_pair" "uv,np,uv")])
7880
7881(define_expand "testqi_ccz_1"
7882 [(set (reg:CCZ 17)
7883 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7884 (match_operand:QI 1 "nonmemory_operand" ""))
7885 (const_int 0)))]
7886 ""
7887 "")
7888
7889(define_insn "*testqi_1_maybe_si"
7890 [(set (reg 17)
7891 (compare
7892 (and:QI
7893 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7894 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7895 (const_int 0)))]
7896 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7897 && ix86_match_ccmode (insn,
7898 GET_CODE (operands[1]) == CONST_INT
7899 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7900{
7901 if (which_alternative == 3)
7902 {
7903 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7904 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7905 return "test{l}\t{%1, %k0|%k0, %1}";
7906 }
7907 return "test{b}\t{%1, %0|%0, %1}";
7908}
7909 [(set_attr "type" "test")
7910 (set_attr "modrm" "0,1,1,1")
7911 (set_attr "mode" "QI,QI,QI,SI")
7912 (set_attr "pent_pair" "uv,np,uv,np")])
7913
7914(define_insn "*testqi_1"
7915 [(set (reg 17)
7916 (compare
7917 (and:QI
7918 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7919 (match_operand:QI 1 "general_operand" "n,n,qn"))
7920 (const_int 0)))]
7921 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7922 && ix86_match_ccmode (insn, CCNOmode)"
7923 "test{b}\t{%1, %0|%0, %1}"
7924 [(set_attr "type" "test")
7925 (set_attr "modrm" "0,1,1")
7926 (set_attr "mode" "QI")
7927 (set_attr "pent_pair" "uv,np,uv")])
7928
7929(define_expand "testqi_ext_ccno_0"
7930 [(set (reg:CCNO 17)
7931 (compare:CCNO
7932 (and:SI
7933 (zero_extract:SI
7934 (match_operand 0 "ext_register_operand" "")
7935 (const_int 8)
7936 (const_int 8))
7937 (match_operand 1 "const_int_operand" ""))
7938 (const_int 0)))]
7939 ""
7940 "")
7941
7942(define_insn "*testqi_ext_0"
7943 [(set (reg 17)
7944 (compare
7945 (and:SI
7946 (zero_extract:SI
7947 (match_operand 0 "ext_register_operand" "Q")
7948 (const_int 8)
7949 (const_int 8))
7950 (match_operand 1 "const_int_operand" "n"))
7951 (const_int 0)))]
7952 "ix86_match_ccmode (insn, CCNOmode)"
7953 "test{b}\t{%1, %h0|%h0, %1}"
7954 [(set_attr "type" "test")
7955 (set_attr "mode" "QI")
7956 (set_attr "length_immediate" "1")
7957 (set_attr "pent_pair" "np")])
7958
7959(define_insn "*testqi_ext_1"
7960 [(set (reg 17)
7961 (compare
7962 (and:SI
7963 (zero_extract:SI
7964 (match_operand 0 "ext_register_operand" "Q")
7965 (const_int 8)
7966 (const_int 8))
7967 (zero_extend:SI
7968 (match_operand:QI 1 "general_operand" "Qm")))
7969 (const_int 0)))]
7970 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7971 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7972 "test{b}\t{%1, %h0|%h0, %1}"
7973 [(set_attr "type" "test")
7974 (set_attr "mode" "QI")])
7975
7976(define_insn "*testqi_ext_1_rex64"
7977 [(set (reg 17)
7978 (compare
7979 (and:SI
7980 (zero_extract:SI
7981 (match_operand 0 "ext_register_operand" "Q")
7982 (const_int 8)
7983 (const_int 8))
7984 (zero_extend:SI
7985 (match_operand:QI 1 "register_operand" "Q")))
7986 (const_int 0)))]
7987 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7988 "test{b}\t{%1, %h0|%h0, %1}"
7989 [(set_attr "type" "test")
7990 (set_attr "mode" "QI")])
7991
7992(define_insn "*testqi_ext_2"
7993 [(set (reg 17)
7994 (compare
7995 (and:SI
7996 (zero_extract:SI
7997 (match_operand 0 "ext_register_operand" "Q")
7998 (const_int 8)
7999 (const_int 8))
8000 (zero_extract:SI
8001 (match_operand 1 "ext_register_operand" "Q")
8002 (const_int 8)
8003 (const_int 8)))
8004 (const_int 0)))]
8005 "ix86_match_ccmode (insn, CCNOmode)"
8006 "test{b}\t{%h1, %h0|%h0, %h1}"
8007 [(set_attr "type" "test")
8008 (set_attr "mode" "QI")])
8009
8010;; Combine likes to form bit extractions for some tests. Humor it.
8011(define_insn "*testqi_ext_3"
8012 [(set (reg 17)
8013 (compare (zero_extract:SI
8014 (match_operand 0 "nonimmediate_operand" "rm")
8015 (match_operand:SI 1 "const_int_operand" "")
8016 (match_operand:SI 2 "const_int_operand" ""))
8017 (const_int 0)))]
8018 "ix86_match_ccmode (insn, CCNOmode)
8019 && (GET_MODE (operands[0]) == SImode
8020 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8021 || GET_MODE (operands[0]) == HImode
8022 || GET_MODE (operands[0]) == QImode)"
8023 "#")
8024
8025(define_insn "*testqi_ext_3_rex64"
8026 [(set (reg 17)
8027 (compare (zero_extract:DI
8028 (match_operand 0 "nonimmediate_operand" "rm")
8029 (match_operand:DI 1 "const_int_operand" "")
8030 (match_operand:DI 2 "const_int_operand" ""))
8031 (const_int 0)))]
8032 "TARGET_64BIT
8033 && ix86_match_ccmode (insn, CCNOmode)
8034 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8035 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8036 /* Ensure that resulting mask is zero or sign extended operand. */
8037 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8038 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8039 && INTVAL (operands[1]) > 32))
8040 && (GET_MODE (operands[0]) == SImode
8041 || GET_MODE (operands[0]) == DImode
8042 || GET_MODE (operands[0]) == HImode
8043 || GET_MODE (operands[0]) == QImode)"
8044 "#")
8045
8046(define_split
8047 [(set (match_operand 0 "flags_reg_operand" "")
8048 (match_operator 1 "compare_operator"
8049 [(zero_extract
8050 (match_operand 2 "nonimmediate_operand" "")
8051 (match_operand 3 "const_int_operand" "")
8052 (match_operand 4 "const_int_operand" ""))
8053 (const_int 0)]))]
8054 "ix86_match_ccmode (insn, CCNOmode)"
8055 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8056{
8057 rtx val = operands[2];
8058 HOST_WIDE_INT len = INTVAL (operands[3]);
8059 HOST_WIDE_INT pos = INTVAL (operands[4]);
8060 HOST_WIDE_INT mask;
8061 enum machine_mode mode, submode;
8062
8063 mode = GET_MODE (val);
8064 if (GET_CODE (val) == MEM)
8065 {
8066 /* ??? Combine likes to put non-volatile mem extractions in QImode
8067 no matter the size of the test. So find a mode that works. */
8068 if (! MEM_VOLATILE_P (val))
8069 {
8070 mode = smallest_mode_for_size (pos + len, MODE_INT);
8071 val = adjust_address (val, mode, 0);
8072 }
8073 }
8074 else if (GET_CODE (val) == SUBREG
8075 && (submode = GET_MODE (SUBREG_REG (val)),
8076 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8077 && pos + len <= GET_MODE_BITSIZE (submode))
8078 {
8079 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8080 mode = submode;
8081 val = SUBREG_REG (val);
8082 }
8083 else if (mode == HImode && pos + len <= 8)
8084 {
8085 /* Small HImode tests can be converted to QImode. */
8086 mode = QImode;
8087 val = gen_lowpart (QImode, val);
8088 }
8089
8090 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8091 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8092
8093 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8094})
8095
8096;; Convert HImode/SImode test instructions with immediate to QImode ones.
8097;; i386 does not allow to encode test with 8bit sign extended immediate, so
8098;; this is relatively important trick.
8099;; Do the conversion only post-reload to avoid limiting of the register class
8100;; to QI regs.
8101(define_split
8102 [(set (match_operand 0 "flags_reg_operand" "")
8103 (match_operator 1 "compare_operator"
8104 [(and (match_operand 2 "register_operand" "")
8105 (match_operand 3 "const_int_operand" ""))
8106 (const_int 0)]))]
8107 "reload_completed
8108 && QI_REG_P (operands[2])
8109 && GET_MODE (operands[2]) != QImode
8110 && ((ix86_match_ccmode (insn, CCZmode)
8111 && !(INTVAL (operands[3]) & ~(255 << 8)))
8112 || (ix86_match_ccmode (insn, CCNOmode)
8113 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8114 [(set (match_dup 0)
8115 (match_op_dup 1
8116 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8117 (match_dup 3))
8118 (const_int 0)]))]
8119 "operands[2] = gen_lowpart (SImode, operands[2]);
8120 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8121
8122(define_split
8123 [(set (match_operand 0 "flags_reg_operand" "")
8124 (match_operator 1 "compare_operator"
8125 [(and (match_operand 2 "nonimmediate_operand" "")
8126 (match_operand 3 "const_int_operand" ""))
8127 (const_int 0)]))]
8128 "reload_completed
8129 && GET_MODE (operands[2]) != QImode
8130 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8131 && ((ix86_match_ccmode (insn, CCZmode)
8132 && !(INTVAL (operands[3]) & ~255))
8133 || (ix86_match_ccmode (insn, CCNOmode)
8134 && !(INTVAL (operands[3]) & ~127)))"
8135 [(set (match_dup 0)
8136 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8137 (const_int 0)]))]
8138 "operands[2] = gen_lowpart (QImode, operands[2]);
8139 operands[3] = gen_lowpart (QImode, operands[3]);")
8140
8141
8142;; %%% This used to optimize known byte-wide and operations to memory,
8143;; and sometimes to QImode registers. If this is considered useful,
8144;; it should be done with splitters.
8145
8146(define_expand "anddi3"
8147 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8148 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8149 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8150 (clobber (reg:CC 17))]
8151 "TARGET_64BIT"
8152 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8153
8154(define_insn "*anddi_1_rex64"
8155 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8156 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8157 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8158 (clobber (reg:CC 17))]
8159 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8160{
8161 switch (get_attr_type (insn))
8162 {
8163 case TYPE_IMOVX:
8164 {
8165 enum machine_mode mode;
8166
8167 if (GET_CODE (operands[2]) != CONST_INT)
8168 abort ();
8169 if (INTVAL (operands[2]) == 0xff)
8170 mode = QImode;
8171 else if (INTVAL (operands[2]) == 0xffff)
8172 mode = HImode;
8173 else
8174 abort ();
8175
8176 operands[1] = gen_lowpart (mode, operands[1]);
8177 if (mode == QImode)
8178 return "movz{bq|x}\t{%1,%0|%0, %1}";
8179 else
8180 return "movz{wq|x}\t{%1,%0|%0, %1}";
8181 }
8182
8183 default:
8184 if (! rtx_equal_p (operands[0], operands[1]))
8185 abort ();
8186 if (get_attr_mode (insn) == MODE_SI)
8187 return "and{l}\t{%k2, %k0|%k0, %k2}";
8188 else
8189 return "and{q}\t{%2, %0|%0, %2}";
8190 }
8191}
8192 [(set_attr "type" "alu,alu,alu,imovx")
8193 (set_attr "length_immediate" "*,*,*,0")
8194 (set_attr "mode" "SI,DI,DI,DI")])
8195
8196(define_insn "*anddi_2"
8197 [(set (reg 17)
8198 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8199 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8200 (const_int 0)))
8201 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8202 (and:DI (match_dup 1) (match_dup 2)))]
8203 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8204 && ix86_binary_operator_ok (AND, DImode, operands)"
8205 "@
8206 and{l}\t{%k2, %k0|%k0, %k2}
8207 and{q}\t{%2, %0|%0, %2}
8208 and{q}\t{%2, %0|%0, %2}"
8209 [(set_attr "type" "alu")
8210 (set_attr "mode" "SI,DI,DI")])
8211
8212(define_expand "andsi3"
8213 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8214 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8215 (match_operand:SI 2 "general_operand" "")))
8216 (clobber (reg:CC 17))]
8217 ""
8218 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8219
8220(define_insn "*andsi_1"
8221 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8222 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8223 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8224 (clobber (reg:CC 17))]
8225 "ix86_binary_operator_ok (AND, SImode, operands)"
8226{
8227 switch (get_attr_type (insn))
8228 {
8229 case TYPE_IMOVX:
8230 {
8231 enum machine_mode mode;
8232
8233 if (GET_CODE (operands[2]) != CONST_INT)
8234 abort ();
8235 if (INTVAL (operands[2]) == 0xff)
8236 mode = QImode;
8237 else if (INTVAL (operands[2]) == 0xffff)
8238 mode = HImode;
8239 else
8240 abort ();
8241
8242 operands[1] = gen_lowpart (mode, operands[1]);
8243 if (mode == QImode)
8244 return "movz{bl|x}\t{%1,%0|%0, %1}";
8245 else
8246 return "movz{wl|x}\t{%1,%0|%0, %1}";
8247 }
8248
8249 default:
8250 if (! rtx_equal_p (operands[0], operands[1]))
8251 abort ();
8252 return "and{l}\t{%2, %0|%0, %2}";
8253 }
8254}
8255 [(set_attr "type" "alu,alu,imovx")
8256 (set_attr "length_immediate" "*,*,0")
8257 (set_attr "mode" "SI")])
8258
8259(define_split
8260 [(set (match_operand 0 "register_operand" "")
8261 (and (match_dup 0)
8262 (const_int -65536)))
8263 (clobber (reg:CC 17))]
8264 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8265 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8266 "operands[1] = gen_lowpart (HImode, operands[0]);")
8267
8268(define_split
8269 [(set (match_operand 0 "ext_register_operand" "")
8270 (and (match_dup 0)
8271 (const_int -256)))
8272 (clobber (reg:CC 17))]
8273 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8274 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8275 "operands[1] = gen_lowpart (QImode, operands[0]);")
8276
8277(define_split
8278 [(set (match_operand 0 "ext_register_operand" "")
8279 (and (match_dup 0)
8280 (const_int -65281)))
8281 (clobber (reg:CC 17))]
8282 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8283 [(parallel [(set (zero_extract:SI (match_dup 0)
8284 (const_int 8)
8285 (const_int 8))
8286 (xor:SI
8287 (zero_extract:SI (match_dup 0)
8288 (const_int 8)
8289 (const_int 8))
8290 (zero_extract:SI (match_dup 0)
8291 (const_int 8)
8292 (const_int 8))))
8293 (clobber (reg:CC 17))])]
8294 "operands[0] = gen_lowpart (SImode, operands[0]);")
8295
8296;; See comment for addsi_1_zext why we do use nonimmediate_operand
8297(define_insn "*andsi_1_zext"
8298 [(set (match_operand:DI 0 "register_operand" "=r")
8299 (zero_extend:DI
8300 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8301 (match_operand:SI 2 "general_operand" "rim"))))
8302 (clobber (reg:CC 17))]
8303 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8304 "and{l}\t{%2, %k0|%k0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "SI")])
8307
8308(define_insn "*andsi_2"
8309 [(set (reg 17)
8310 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8311 (match_operand:SI 2 "general_operand" "rim,ri"))
8312 (const_int 0)))
8313 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8314 (and:SI (match_dup 1) (match_dup 2)))]
8315 "ix86_match_ccmode (insn, CCNOmode)
8316 && ix86_binary_operator_ok (AND, SImode, operands)"
8317 "and{l}\t{%2, %0|%0, %2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "SI")])
8320
8321;; See comment for addsi_1_zext why we do use nonimmediate_operand
8322(define_insn "*andsi_2_zext"
8323 [(set (reg 17)
8324 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8325 (match_operand:SI 2 "general_operand" "rim"))
8326 (const_int 0)))
8327 (set (match_operand:DI 0 "register_operand" "=r")
8328 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8329 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8330 && ix86_binary_operator_ok (AND, SImode, operands)"
8331 "and{l}\t{%2, %k0|%k0, %2}"
8332 [(set_attr "type" "alu")
8333 (set_attr "mode" "SI")])
8334
8335(define_expand "andhi3"
8336 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8337 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8338 (match_operand:HI 2 "general_operand" "")))
8339 (clobber (reg:CC 17))]
8340 "TARGET_HIMODE_MATH"
8341 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8342
8343(define_insn "*andhi_1"
8344 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8345 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8346 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8347 (clobber (reg:CC 17))]
8348 "ix86_binary_operator_ok (AND, HImode, operands)"
8349{
8350 switch (get_attr_type (insn))
8351 {
8352 case TYPE_IMOVX:
8353 if (GET_CODE (operands[2]) != CONST_INT)
8354 abort ();
8355 if (INTVAL (operands[2]) == 0xff)
8356 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8357 abort ();
8358
8359 default:
8360 if (! rtx_equal_p (operands[0], operands[1]))
8361 abort ();
8362
8363 return "and{w}\t{%2, %0|%0, %2}";
8364 }
8365}
8366 [(set_attr "type" "alu,alu,imovx")
8367 (set_attr "length_immediate" "*,*,0")
8368 (set_attr "mode" "HI,HI,SI")])
8369
8370(define_insn "*andhi_2"
8371 [(set (reg 17)
8372 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8373 (match_operand:HI 2 "general_operand" "rim,ri"))
8374 (const_int 0)))
8375 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8376 (and:HI (match_dup 1) (match_dup 2)))]
8377 "ix86_match_ccmode (insn, CCNOmode)
8378 && ix86_binary_operator_ok (AND, HImode, operands)"
8379 "and{w}\t{%2, %0|%0, %2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "HI")])
8382
8383(define_expand "andqi3"
8384 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8385 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8386 (match_operand:QI 2 "general_operand" "")))
8387 (clobber (reg:CC 17))]
8388 "TARGET_QIMODE_MATH"
8389 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8390
8391;; %%% Potential partial reg stall on alternative 2. What to do?
8392(define_insn "*andqi_1"
8393 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8394 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8396 (clobber (reg:CC 17))]
8397 "ix86_binary_operator_ok (AND, QImode, operands)"
8398 "@
8399 and{b}\t{%2, %0|%0, %2}
8400 and{b}\t{%2, %0|%0, %2}
8401 and{l}\t{%k2, %k0|%k0, %k2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "mode" "QI,QI,SI")])
8404
8405(define_insn "*andqi_1_slp"
8406 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8407 (and:QI (match_dup 0)
8408 (match_operand:QI 1 "general_operand" "qi,qmi")))
8409 (clobber (reg:CC 17))]
8410 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8411 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8412 "and{b}\t{%1, %0|%0, %1}"
8413 [(set_attr "type" "alu1")
8414 (set_attr "mode" "QI")])
8415
8416(define_insn "*andqi_2_maybe_si"
8417 [(set (reg 17)
8418 (compare (and:QI
8419 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8420 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8421 (const_int 0)))
8422 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8423 (and:QI (match_dup 1) (match_dup 2)))]
8424 "ix86_binary_operator_ok (AND, QImode, operands)
8425 && ix86_match_ccmode (insn,
8426 GET_CODE (operands[2]) == CONST_INT
8427 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8428{
8429 if (which_alternative == 2)
8430 {
8431 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8432 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8433 return "and{l}\t{%2, %k0|%k0, %2}";
8434 }
8435 return "and{b}\t{%2, %0|%0, %2}";
8436}
8437 [(set_attr "type" "alu")
8438 (set_attr "mode" "QI,QI,SI")])
8439
8440(define_insn "*andqi_2"
8441 [(set (reg 17)
8442 (compare (and:QI
8443 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8444 (match_operand:QI 2 "general_operand" "qim,qi"))
8445 (const_int 0)))
8446 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8447 (and:QI (match_dup 1) (match_dup 2)))]
8448 "ix86_match_ccmode (insn, CCNOmode)
8449 && ix86_binary_operator_ok (AND, QImode, operands)"
8450 "and{b}\t{%2, %0|%0, %2}"
8451 [(set_attr "type" "alu")
8452 (set_attr "mode" "QI")])
8453
8454(define_insn "*andqi_2_slp"
8455 [(set (reg 17)
8456 (compare (and:QI
8457 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8458 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8459 (const_int 0)))
8460 (set (strict_low_part (match_dup 0))
8461 (and:QI (match_dup 0) (match_dup 1)))]
8462 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8463 && ix86_match_ccmode (insn, CCNOmode)
8464 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8465 "and{b}\t{%1, %0|%0, %1}"
8466 [(set_attr "type" "alu1")
8467 (set_attr "mode" "QI")])
8468
8469;; ??? A bug in recog prevents it from recognizing a const_int as an
8470;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8471;; for a QImode operand, which of course failed.
8472
8473(define_insn "andqi_ext_0"
8474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 (const_int 8)
8476 (const_int 8))
8477 (and:SI
8478 (zero_extract:SI
8479 (match_operand 1 "ext_register_operand" "0")
8480 (const_int 8)
8481 (const_int 8))
8482 (match_operand 2 "const_int_operand" "n")))
8483 (clobber (reg:CC 17))]
8484 ""
8485 "and{b}\t{%2, %h0|%h0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "length_immediate" "1")
8488 (set_attr "mode" "QI")])
8489
8490;; Generated by peephole translating test to and. This shows up
8491;; often in fp comparisons.
8492
8493(define_insn "*andqi_ext_0_cc"
8494 [(set (reg 17)
8495 (compare
8496 (and:SI
8497 (zero_extract:SI
8498 (match_operand 1 "ext_register_operand" "0")
8499 (const_int 8)
8500 (const_int 8))
8501 (match_operand 2 "const_int_operand" "n"))
8502 (const_int 0)))
8503 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504 (const_int 8)
8505 (const_int 8))
8506 (and:SI
8507 (zero_extract:SI
8508 (match_dup 1)
8509 (const_int 8)
8510 (const_int 8))
8511 (match_dup 2)))]
8512 "ix86_match_ccmode (insn, CCNOmode)"
8513 "and{b}\t{%2, %h0|%h0, %2}"
8514 [(set_attr "type" "alu")
8515 (set_attr "length_immediate" "1")
8516 (set_attr "mode" "QI")])
8517
8518(define_insn "*andqi_ext_1"
8519 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8520 (const_int 8)
8521 (const_int 8))
8522 (and:SI
8523 (zero_extract:SI
8524 (match_operand 1 "ext_register_operand" "0")
8525 (const_int 8)
8526 (const_int 8))
8527 (zero_extend:SI
8528 (match_operand:QI 2 "general_operand" "Qm"))))
8529 (clobber (reg:CC 17))]
8530 "!TARGET_64BIT"
8531 "and{b}\t{%2, %h0|%h0, %2}"
8532 [(set_attr "type" "alu")
8533 (set_attr "length_immediate" "0")
8534 (set_attr "mode" "QI")])
8535
8536(define_insn "*andqi_ext_1_rex64"
8537 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8538 (const_int 8)
8539 (const_int 8))
8540 (and:SI
8541 (zero_extract:SI
8542 (match_operand 1 "ext_register_operand" "0")
8543 (const_int 8)
8544 (const_int 8))
8545 (zero_extend:SI
8546 (match_operand 2 "ext_register_operand" "Q"))))
8547 (clobber (reg:CC 17))]
8548 "TARGET_64BIT"
8549 "and{b}\t{%2, %h0|%h0, %2}"
8550 [(set_attr "type" "alu")
8551 (set_attr "length_immediate" "0")
8552 (set_attr "mode" "QI")])
8553
8554(define_insn "*andqi_ext_2"
8555 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8556 (const_int 8)
8557 (const_int 8))
8558 (and:SI
8559 (zero_extract:SI
8560 (match_operand 1 "ext_register_operand" "%0")
8561 (const_int 8)
8562 (const_int 8))
8563 (zero_extract:SI
8564 (match_operand 2 "ext_register_operand" "Q")
8565 (const_int 8)
8566 (const_int 8))))
8567 (clobber (reg:CC 17))]
8568 ""
8569 "and{b}\t{%h2, %h0|%h0, %h2}"
8570 [(set_attr "type" "alu")
8571 (set_attr "length_immediate" "0")
8572 (set_attr "mode" "QI")])
8573
8574;; Convert wide AND instructions with immediate operand to shorter QImode
8575;; equivalents when possible.
8576;; Don't do the splitting with memory operands, since it introduces risk
8577;; of memory mismatch stalls. We may want to do the splitting for optimizing
8578;; for size, but that can (should?) be handled by generic code instead.
8579(define_split
8580 [(set (match_operand 0 "register_operand" "")
8581 (and (match_operand 1 "register_operand" "")
8582 (match_operand 2 "const_int_operand" "")))
8583 (clobber (reg:CC 17))]
8584 "reload_completed
8585 && QI_REG_P (operands[0])
8586 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8587 && !(~INTVAL (operands[2]) & ~(255 << 8))
8588 && GET_MODE (operands[0]) != QImode"
8589 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8590 (and:SI (zero_extract:SI (match_dup 1)
8591 (const_int 8) (const_int 8))
8592 (match_dup 2)))
8593 (clobber (reg:CC 17))])]
8594 "operands[0] = gen_lowpart (SImode, operands[0]);
8595 operands[1] = gen_lowpart (SImode, operands[1]);
8596 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8597
8598;; Since AND can be encoded with sign extended immediate, this is only
8599;; profitable when 7th bit is not set.
8600(define_split
8601 [(set (match_operand 0 "register_operand" "")
8602 (and (match_operand 1 "general_operand" "")
8603 (match_operand 2 "const_int_operand" "")))
8604 (clobber (reg:CC 17))]
8605 "reload_completed
8606 && ANY_QI_REG_P (operands[0])
8607 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8608 && !(~INTVAL (operands[2]) & ~255)
8609 && !(INTVAL (operands[2]) & 128)
8610 && GET_MODE (operands[0]) != QImode"
8611 [(parallel [(set (strict_low_part (match_dup 0))
8612 (and:QI (match_dup 1)
8613 (match_dup 2)))
8614 (clobber (reg:CC 17))])]
8615 "operands[0] = gen_lowpart (QImode, operands[0]);
8616 operands[1] = gen_lowpart (QImode, operands[1]);
8617 operands[2] = gen_lowpart (QImode, operands[2]);")
8618
8619;; Logical inclusive OR instructions
8620
8621;; %%% This used to optimize known byte-wide and operations to memory.
8622;; If this is considered useful, it should be done with splitters.
8623
8624(define_expand "iordi3"
8625 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8626 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8627 (match_operand:DI 2 "x86_64_general_operand" "")))
8628 (clobber (reg:CC 17))]
8629 "TARGET_64BIT"
8630 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8631
8632(define_insn "*iordi_1_rex64"
8633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8634 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8636 (clobber (reg:CC 17))]
8637 "TARGET_64BIT
8638 && ix86_binary_operator_ok (IOR, DImode, operands)"
8639 "or{q}\t{%2, %0|%0, %2}"
8640 [(set_attr "type" "alu")
8641 (set_attr "mode" "DI")])
8642
8643(define_insn "*iordi_2_rex64"
8644 [(set (reg 17)
8645 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8646 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8647 (const_int 0)))
8648 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8649 (ior:DI (match_dup 1) (match_dup 2)))]
8650 "TARGET_64BIT
8651 && ix86_match_ccmode (insn, CCNOmode)
8652 && ix86_binary_operator_ok (IOR, DImode, operands)"
8653 "or{q}\t{%2, %0|%0, %2}"
8654 [(set_attr "type" "alu")
8655 (set_attr "mode" "DI")])
8656
8657(define_insn "*iordi_3_rex64"
8658 [(set (reg 17)
8659 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8660 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8661 (const_int 0)))
8662 (clobber (match_scratch:DI 0 "=r"))]
8663 "TARGET_64BIT
8664 && ix86_match_ccmode (insn, CCNOmode)
8665 && ix86_binary_operator_ok (IOR, DImode, operands)"
8666 "or{q}\t{%2, %0|%0, %2}"
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "DI")])
8669
8670
8671(define_expand "iorsi3"
8672 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8673 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8674 (match_operand:SI 2 "general_operand" "")))
8675 (clobber (reg:CC 17))]
8676 ""
8677 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8678
8679(define_insn "*iorsi_1"
8680 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8681 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8682 (match_operand:SI 2 "general_operand" "ri,rmi")))
8683 (clobber (reg:CC 17))]
8684 "ix86_binary_operator_ok (IOR, SImode, operands)"
8685 "or{l}\t{%2, %0|%0, %2}"
8686 [(set_attr "type" "alu")
8687 (set_attr "mode" "SI")])
8688
8689;; See comment for addsi_1_zext why we do use nonimmediate_operand
8690(define_insn "*iorsi_1_zext"
8691 [(set (match_operand:DI 0 "register_operand" "=rm")
8692 (zero_extend:DI
8693 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8694 (match_operand:SI 2 "general_operand" "rim"))))
8695 (clobber (reg:CC 17))]
8696 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8697 "or{l}\t{%2, %k0|%k0, %2}"
8698 [(set_attr "type" "alu")
8699 (set_attr "mode" "SI")])
8700
8701(define_insn "*iorsi_1_zext_imm"
8702 [(set (match_operand:DI 0 "register_operand" "=rm")
8703 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8704 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8705 (clobber (reg:CC 17))]
8706 "TARGET_64BIT"
8707 "or{l}\t{%2, %k0|%k0, %2}"
8708 [(set_attr "type" "alu")
8709 (set_attr "mode" "SI")])
8710
8711(define_insn "*iorsi_2"
8712 [(set (reg 17)
8713 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8714 (match_operand:SI 2 "general_operand" "rim,ri"))
8715 (const_int 0)))
8716 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8717 (ior:SI (match_dup 1) (match_dup 2)))]
8718 "ix86_match_ccmode (insn, CCNOmode)
8719 && ix86_binary_operator_ok (IOR, SImode, operands)"
8720 "or{l}\t{%2, %0|%0, %2}"
8721 [(set_attr "type" "alu")
8722 (set_attr "mode" "SI")])
8723
8724;; See comment for addsi_1_zext why we do use nonimmediate_operand
8725;; ??? Special case for immediate operand is missing - it is tricky.
8726(define_insn "*iorsi_2_zext"
8727 [(set (reg 17)
8728 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8729 (match_operand:SI 2 "general_operand" "rim"))
8730 (const_int 0)))
8731 (set (match_operand:DI 0 "register_operand" "=r")
8732 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8733 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8734 && ix86_binary_operator_ok (IOR, SImode, operands)"
8735 "or{l}\t{%2, %k0|%k0, %2}"
8736 [(set_attr "type" "alu")
8737 (set_attr "mode" "SI")])
8738
8739(define_insn "*iorsi_2_zext_imm"
8740 [(set (reg 17)
8741 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8742 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8743 (const_int 0)))
8744 (set (match_operand:DI 0 "register_operand" "=r")
8745 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8746 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8747 && ix86_binary_operator_ok (IOR, SImode, operands)"
8748 "or{l}\t{%2, %k0|%k0, %2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "mode" "SI")])
8751
8752(define_insn "*iorsi_3"
8753 [(set (reg 17)
8754 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8755 (match_operand:SI 2 "general_operand" "rim"))
8756 (const_int 0)))
8757 (clobber (match_scratch:SI 0 "=r"))]
8758 "ix86_match_ccmode (insn, CCNOmode)
8759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760 "or{l}\t{%2, %0|%0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "SI")])
8763
8764(define_expand "iorhi3"
8765 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8766 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8767 (match_operand:HI 2 "general_operand" "")))
8768 (clobber (reg:CC 17))]
8769 "TARGET_HIMODE_MATH"
8770 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8771
8772(define_insn "*iorhi_1"
8773 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8774 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8775 (match_operand:HI 2 "general_operand" "rmi,ri")))
8776 (clobber (reg:CC 17))]
8777 "ix86_binary_operator_ok (IOR, HImode, operands)"
8778 "or{w}\t{%2, %0|%0, %2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "mode" "HI")])
8781
8782(define_insn "*iorhi_2"
8783 [(set (reg 17)
8784 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8785 (match_operand:HI 2 "general_operand" "rim,ri"))
8786 (const_int 0)))
8787 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8788 (ior:HI (match_dup 1) (match_dup 2)))]
8789 "ix86_match_ccmode (insn, CCNOmode)
8790 && ix86_binary_operator_ok (IOR, HImode, operands)"
8791 "or{w}\t{%2, %0|%0, %2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "mode" "HI")])
8794
8795(define_insn "*iorhi_3"
8796 [(set (reg 17)
8797 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8798 (match_operand:HI 2 "general_operand" "rim"))
8799 (const_int 0)))
8800 (clobber (match_scratch:HI 0 "=r"))]
8801 "ix86_match_ccmode (insn, CCNOmode)
8802 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8803 "or{w}\t{%2, %0|%0, %2}"
8804 [(set_attr "type" "alu")
8805 (set_attr "mode" "HI")])
8806
8807(define_expand "iorqi3"
8808 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8809 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8810 (match_operand:QI 2 "general_operand" "")))
8811 (clobber (reg:CC 17))]
8812 "TARGET_QIMODE_MATH"
8813 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8814
8815;; %%% Potential partial reg stall on alternative 2. What to do?
8816(define_insn "*iorqi_1"
8817 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8818 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8819 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8820 (clobber (reg:CC 17))]
8821 "ix86_binary_operator_ok (IOR, QImode, operands)"
8822 "@
8823 or{b}\t{%2, %0|%0, %2}
8824 or{b}\t{%2, %0|%0, %2}
8825 or{l}\t{%k2, %k0|%k0, %k2}"
8826 [(set_attr "type" "alu")
8827 (set_attr "mode" "QI,QI,SI")])
8828
8829(define_insn "*iorqi_1_slp"
8830 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8831 (ior:QI (match_dup 0)
8832 (match_operand:QI 1 "general_operand" "qmi,qi")))
8833 (clobber (reg:CC 17))]
8834 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8835 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8836 "or{b}\t{%1, %0|%0, %1}"
8837 [(set_attr "type" "alu1")
8838 (set_attr "mode" "QI")])
8839
8840(define_insn "*iorqi_2"
8841 [(set (reg 17)
8842 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8843 (match_operand:QI 2 "general_operand" "qim,qi"))
8844 (const_int 0)))
8845 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8846 (ior:QI (match_dup 1) (match_dup 2)))]
8847 "ix86_match_ccmode (insn, CCNOmode)
8848 && ix86_binary_operator_ok (IOR, QImode, operands)"
8849 "or{b}\t{%2, %0|%0, %2}"
8850 [(set_attr "type" "alu")
8851 (set_attr "mode" "QI")])
8852
8853(define_insn "*iorqi_2_slp"
8854 [(set (reg 17)
8855 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8856 (match_operand:QI 1 "general_operand" "qim,qi"))
8857 (const_int 0)))
8858 (set (strict_low_part (match_dup 0))
8859 (ior:QI (match_dup 0) (match_dup 1)))]
8860 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8861 && ix86_match_ccmode (insn, CCNOmode)
8862 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8863 "or{b}\t{%1, %0|%0, %1}"
8864 [(set_attr "type" "alu1")
8865 (set_attr "mode" "QI")])
8866
8867(define_insn "*iorqi_3"
8868 [(set (reg 17)
8869 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8870 (match_operand:QI 2 "general_operand" "qim"))
8871 (const_int 0)))
8872 (clobber (match_scratch:QI 0 "=q"))]
8873 "ix86_match_ccmode (insn, CCNOmode)
8874 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8875 "or{b}\t{%2, %0|%0, %2}"
8876 [(set_attr "type" "alu")
8877 (set_attr "mode" "QI")])
8878
8879(define_insn "iorqi_ext_0"
8880 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8881 (const_int 8)
8882 (const_int 8))
8883 (ior:SI
8884 (zero_extract:SI
8885 (match_operand 1 "ext_register_operand" "0")
8886 (const_int 8)
8887 (const_int 8))
8888 (match_operand 2 "const_int_operand" "n")))
8889 (clobber (reg:CC 17))]
8890 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8891 "or{b}\t{%2, %h0|%h0, %2}"
8892 [(set_attr "type" "alu")
8893 (set_attr "length_immediate" "1")
8894 (set_attr "mode" "QI")])
8895
8896(define_insn "*iorqi_ext_1"
8897 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8898 (const_int 8)
8899 (const_int 8))
8900 (ior:SI
8901 (zero_extract:SI
8902 (match_operand 1 "ext_register_operand" "0")
8903 (const_int 8)
8904 (const_int 8))
8905 (zero_extend:SI
8906 (match_operand:QI 2 "general_operand" "Qm"))))
8907 (clobber (reg:CC 17))]
8908 "!TARGET_64BIT
8909 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910 "or{b}\t{%2, %h0|%h0, %2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "length_immediate" "0")
8913 (set_attr "mode" "QI")])
8914
8915(define_insn "*iorqi_ext_1_rex64"
8916 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8917 (const_int 8)
8918 (const_int 8))
8919 (ior:SI
8920 (zero_extract:SI
8921 (match_operand 1 "ext_register_operand" "0")
8922 (const_int 8)
8923 (const_int 8))
8924 (zero_extend:SI
8925 (match_operand 2 "ext_register_operand" "Q"))))
8926 (clobber (reg:CC 17))]
8927 "TARGET_64BIT
8928 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8929 "or{b}\t{%2, %h0|%h0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "length_immediate" "0")
8932 (set_attr "mode" "QI")])
8933
8934(define_insn "*iorqi_ext_2"
8935 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8936 (const_int 8)
8937 (const_int 8))
8938 (ior:SI
8939 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8940 (const_int 8)
8941 (const_int 8))
8942 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8943 (const_int 8)
8944 (const_int 8))))
8945 (clobber (reg:CC 17))]
8946 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8947 "ior{b}\t{%h2, %h0|%h0, %h2}"
8948 [(set_attr "type" "alu")
8949 (set_attr "length_immediate" "0")
8950 (set_attr "mode" "QI")])
8951
8952(define_split
8953 [(set (match_operand 0 "register_operand" "")
8954 (ior (match_operand 1 "register_operand" "")
8955 (match_operand 2 "const_int_operand" "")))
8956 (clobber (reg:CC 17))]
8957 "reload_completed
8958 && QI_REG_P (operands[0])
8959 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8960 && !(INTVAL (operands[2]) & ~(255 << 8))
8961 && GET_MODE (operands[0]) != QImode"
8962 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8963 (ior:SI (zero_extract:SI (match_dup 1)
8964 (const_int 8) (const_int 8))
8965 (match_dup 2)))
8966 (clobber (reg:CC 17))])]
8967 "operands[0] = gen_lowpart (SImode, operands[0]);
8968 operands[1] = gen_lowpart (SImode, operands[1]);
8969 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8970
8971;; Since OR can be encoded with sign extended immediate, this is only
8972;; profitable when 7th bit is set.
8973(define_split
8974 [(set (match_operand 0 "register_operand" "")
8975 (ior (match_operand 1 "general_operand" "")
8976 (match_operand 2 "const_int_operand" "")))
8977 (clobber (reg:CC 17))]
8978 "reload_completed
8979 && ANY_QI_REG_P (operands[0])
8980 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8981 && !(INTVAL (operands[2]) & ~255)
8982 && (INTVAL (operands[2]) & 128)
8983 && GET_MODE (operands[0]) != QImode"
8984 [(parallel [(set (strict_low_part (match_dup 0))
8985 (ior:QI (match_dup 1)
8986 (match_dup 2)))
8987 (clobber (reg:CC 17))])]
8988 "operands[0] = gen_lowpart (QImode, operands[0]);
8989 operands[1] = gen_lowpart (QImode, operands[1]);
8990 operands[2] = gen_lowpart (QImode, operands[2]);")
8991
8992;; Logical XOR instructions
8993
8994;; %%% This used to optimize known byte-wide and operations to memory.
8995;; If this is considered useful, it should be done with splitters.
8996
8997(define_expand "xordi3"
8998 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8999 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9000 (match_operand:DI 2 "x86_64_general_operand" "")))
9001 (clobber (reg:CC 17))]
9002 "TARGET_64BIT"
9003 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9004
9005(define_insn "*xordi_1_rex64"
9006 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9007 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9008 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9009 (clobber (reg:CC 17))]
9010 "TARGET_64BIT
9011 && ix86_binary_operator_ok (XOR, DImode, operands)"
9012 "@
9013 xor{q}\t{%2, %0|%0, %2}
9014 xor{q}\t{%2, %0|%0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "DI,DI")])
9017
9018(define_insn "*xordi_2_rex64"
9019 [(set (reg 17)
9020 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9021 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9022 (const_int 0)))
9023 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9024 (xor:DI (match_dup 1) (match_dup 2)))]
9025 "TARGET_64BIT
9026 && ix86_match_ccmode (insn, CCNOmode)
9027 && ix86_binary_operator_ok (XOR, DImode, operands)"
9028 "@
9029 xor{q}\t{%2, %0|%0, %2}
9030 xor{q}\t{%2, %0|%0, %2}"
9031 [(set_attr "type" "alu")
9032 (set_attr "mode" "DI,DI")])
9033
9034(define_insn "*xordi_3_rex64"
9035 [(set (reg 17)
9036 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9037 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9038 (const_int 0)))
9039 (clobber (match_scratch:DI 0 "=r"))]
9040 "TARGET_64BIT
9041 && ix86_match_ccmode (insn, CCNOmode)
9042 && ix86_binary_operator_ok (XOR, DImode, operands)"
9043 "xor{q}\t{%2, %0|%0, %2}"
9044 [(set_attr "type" "alu")
9045 (set_attr "mode" "DI")])
9046
9047(define_expand "xorsi3"
9048 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9049 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9050 (match_operand:SI 2 "general_operand" "")))
9051 (clobber (reg:CC 17))]
9052 ""
9053 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9054
9055(define_insn "*xorsi_1"
9056 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9057 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9058 (match_operand:SI 2 "general_operand" "ri,rm")))
9059 (clobber (reg:CC 17))]
9060 "ix86_binary_operator_ok (XOR, SImode, operands)"
9061 "xor{l}\t{%2, %0|%0, %2}"
9062 [(set_attr "type" "alu")
9063 (set_attr "mode" "SI")])
9064
9065;; See comment for addsi_1_zext why we do use nonimmediate_operand
9066;; Add speccase for immediates
9067(define_insn "*xorsi_1_zext"
9068 [(set (match_operand:DI 0 "register_operand" "=r")
9069 (zero_extend:DI
9070 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9071 (match_operand:SI 2 "general_operand" "rim"))))
9072 (clobber (reg:CC 17))]
9073 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9074 "xor{l}\t{%2, %k0|%k0, %2}"
9075 [(set_attr "type" "alu")
9076 (set_attr "mode" "SI")])
9077
9078(define_insn "*xorsi_1_zext_imm"
9079 [(set (match_operand:DI 0 "register_operand" "=r")
9080 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9081 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9082 (clobber (reg:CC 17))]
9083 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9084 "xor{l}\t{%2, %k0|%k0, %2}"
9085 [(set_attr "type" "alu")
9086 (set_attr "mode" "SI")])
9087
9088(define_insn "*xorsi_2"
9089 [(set (reg 17)
9090 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9091 (match_operand:SI 2 "general_operand" "rim,ri"))
9092 (const_int 0)))
9093 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9094 (xor:SI (match_dup 1) (match_dup 2)))]
9095 "ix86_match_ccmode (insn, CCNOmode)
9096 && ix86_binary_operator_ok (XOR, SImode, operands)"
9097 "xor{l}\t{%2, %0|%0, %2}"
9098 [(set_attr "type" "alu")
9099 (set_attr "mode" "SI")])
9100
9101;; See comment for addsi_1_zext why we do use nonimmediate_operand
9102;; ??? Special case for immediate operand is missing - it is tricky.
9103(define_insn "*xorsi_2_zext"
9104 [(set (reg 17)
9105 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9106 (match_operand:SI 2 "general_operand" "rim"))
9107 (const_int 0)))
9108 (set (match_operand:DI 0 "register_operand" "=r")
9109 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9110 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9111 && ix86_binary_operator_ok (XOR, SImode, operands)"
9112 "xor{l}\t{%2, %k0|%k0, %2}"
9113 [(set_attr "type" "alu")
9114 (set_attr "mode" "SI")])
9115
9116(define_insn "*xorsi_2_zext_imm"
9117 [(set (reg 17)
9118 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9119 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9120 (const_int 0)))
9121 (set (match_operand:DI 0 "register_operand" "=r")
9122 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9123 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9124 && ix86_binary_operator_ok (XOR, SImode, operands)"
9125 "xor{l}\t{%2, %k0|%k0, %2}"
9126 [(set_attr "type" "alu")
9127 (set_attr "mode" "SI")])
9128
9129(define_insn "*xorsi_3"
9130 [(set (reg 17)
9131 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9132 (match_operand:SI 2 "general_operand" "rim"))
9133 (const_int 0)))
9134 (clobber (match_scratch:SI 0 "=r"))]
9135 "ix86_match_ccmode (insn, CCNOmode)
9136 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9137 "xor{l}\t{%2, %0|%0, %2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "mode" "SI")])
9140
9141(define_expand "xorhi3"
9142 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9143 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9144 (match_operand:HI 2 "general_operand" "")))
9145 (clobber (reg:CC 17))]
9146 "TARGET_HIMODE_MATH"
9147 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9148
9149(define_insn "*xorhi_1"
9150 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9151 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9152 (match_operand:HI 2 "general_operand" "rmi,ri")))
9153 (clobber (reg:CC 17))]
9154 "ix86_binary_operator_ok (XOR, HImode, operands)"
9155 "xor{w}\t{%2, %0|%0, %2}"
9156 [(set_attr "type" "alu")
9157 (set_attr "mode" "HI")])
9158
9159(define_insn "*xorhi_2"
9160 [(set (reg 17)
9161 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9162 (match_operand:HI 2 "general_operand" "rim,ri"))
9163 (const_int 0)))
9164 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9165 (xor:HI (match_dup 1) (match_dup 2)))]
9166 "ix86_match_ccmode (insn, CCNOmode)
9167 && ix86_binary_operator_ok (XOR, HImode, operands)"
9168 "xor{w}\t{%2, %0|%0, %2}"
9169 [(set_attr "type" "alu")
9170 (set_attr "mode" "HI")])
9171
9172(define_insn "*xorhi_3"
9173 [(set (reg 17)
9174 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9175 (match_operand:HI 2 "general_operand" "rim"))
9176 (const_int 0)))
9177 (clobber (match_scratch:HI 0 "=r"))]
9178 "ix86_match_ccmode (insn, CCNOmode)
9179 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9180 "xor{w}\t{%2, %0|%0, %2}"
9181 [(set_attr "type" "alu")
9182 (set_attr "mode" "HI")])
9183
9184(define_expand "xorqi3"
9185 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9186 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9187 (match_operand:QI 2 "general_operand" "")))
9188 (clobber (reg:CC 17))]
9189 "TARGET_QIMODE_MATH"
9190 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9191
9192;; %%% Potential partial reg stall on alternative 2. What to do?
9193(define_insn "*xorqi_1"
9194 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9195 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9196 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9197 (clobber (reg:CC 17))]
9198 "ix86_binary_operator_ok (XOR, QImode, operands)"
9199 "@
9200 xor{b}\t{%2, %0|%0, %2}
9201 xor{b}\t{%2, %0|%0, %2}
9202 xor{l}\t{%k2, %k0|%k0, %k2}"
9203 [(set_attr "type" "alu")
9204 (set_attr "mode" "QI,QI,SI")])
9205
9206(define_insn "*xorqi_1_slp"
9207 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9208 (xor:QI (match_dup 0)
9209 (match_operand:QI 1 "general_operand" "qi,qmi")))
9210 (clobber (reg:CC 17))]
9211 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9212 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9213 "xor{b}\t{%1, %0|%0, %1}"
9214 [(set_attr "type" "alu1")
9215 (set_attr "mode" "QI")])
9216
9217(define_insn "xorqi_ext_0"
9218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9219 (const_int 8)
9220 (const_int 8))
9221 (xor:SI
9222 (zero_extract:SI
9223 (match_operand 1 "ext_register_operand" "0")
9224 (const_int 8)
9225 (const_int 8))
9226 (match_operand 2 "const_int_operand" "n")))
9227 (clobber (reg:CC 17))]
9228 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9229 "xor{b}\t{%2, %h0|%h0, %2}"
9230 [(set_attr "type" "alu")
9231 (set_attr "length_immediate" "1")
9232 (set_attr "mode" "QI")])
9233
9234(define_insn "*xorqi_ext_1"
9235 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9236 (const_int 8)
9237 (const_int 8))
9238 (xor:SI
9239 (zero_extract:SI
9240 (match_operand 1 "ext_register_operand" "0")
9241 (const_int 8)
9242 (const_int 8))
9243 (zero_extend:SI
9244 (match_operand:QI 2 "general_operand" "Qm"))))
9245 (clobber (reg:CC 17))]
9246 "!TARGET_64BIT
9247 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248 "xor{b}\t{%2, %h0|%h0, %2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "length_immediate" "0")
9251 (set_attr "mode" "QI")])
9252
9253(define_insn "*xorqi_ext_1_rex64"
9254 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9255 (const_int 8)
9256 (const_int 8))
9257 (xor:SI
9258 (zero_extract:SI
9259 (match_operand 1 "ext_register_operand" "0")
9260 (const_int 8)
9261 (const_int 8))
9262 (zero_extend:SI
9263 (match_operand 2 "ext_register_operand" "Q"))))
9264 (clobber (reg:CC 17))]
9265 "TARGET_64BIT
9266 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9267 "xor{b}\t{%2, %h0|%h0, %2}"
9268 [(set_attr "type" "alu")
9269 (set_attr "length_immediate" "0")
9270 (set_attr "mode" "QI")])
9271
9272(define_insn "*xorqi_ext_2"
9273 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274 (const_int 8)
9275 (const_int 8))
9276 (xor:SI
9277 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9278 (const_int 8)
9279 (const_int 8))
9280 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9281 (const_int 8)
9282 (const_int 8))))
9283 (clobber (reg:CC 17))]
9284 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9285 "xor{b}\t{%h2, %h0|%h0, %h2}"
9286 [(set_attr "type" "alu")
9287 (set_attr "length_immediate" "0")
9288 (set_attr "mode" "QI")])
9289
9290(define_insn "*xorqi_cc_1"
9291 [(set (reg 17)
9292 (compare
9293 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9294 (match_operand:QI 2 "general_operand" "qim,qi"))
9295 (const_int 0)))
9296 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9297 (xor:QI (match_dup 1) (match_dup 2)))]
9298 "ix86_match_ccmode (insn, CCNOmode)
9299 && ix86_binary_operator_ok (XOR, QImode, operands)"
9300 "xor{b}\t{%2, %0|%0, %2}"
9301 [(set_attr "type" "alu")
9302 (set_attr "mode" "QI")])
9303
9304(define_insn "*xorqi_2_slp"
9305 [(set (reg 17)
9306 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9307 (match_operand:QI 1 "general_operand" "qim,qi"))
9308 (const_int 0)))
9309 (set (strict_low_part (match_dup 0))
9310 (xor:QI (match_dup 0) (match_dup 1)))]
9311 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9312 && ix86_match_ccmode (insn, CCNOmode)
9313 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9314 "xor{b}\t{%1, %0|%0, %1}"
9315 [(set_attr "type" "alu1")
9316 (set_attr "mode" "QI")])
9317
9318(define_insn "*xorqi_cc_2"
9319 [(set (reg 17)
9320 (compare
9321 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9322 (match_operand:QI 2 "general_operand" "qim"))
9323 (const_int 0)))
9324 (clobber (match_scratch:QI 0 "=q"))]
9325 "ix86_match_ccmode (insn, CCNOmode)
9326 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9327 "xor{b}\t{%2, %0|%0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "QI")])
9330
9331(define_insn "*xorqi_cc_ext_1"
9332 [(set (reg 17)
9333 (compare
9334 (xor:SI
9335 (zero_extract:SI
9336 (match_operand 1 "ext_register_operand" "0")
9337 (const_int 8)
9338 (const_int 8))
9339 (match_operand:QI 2 "general_operand" "qmn"))
9340 (const_int 0)))
9341 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9342 (const_int 8)
9343 (const_int 8))
9344 (xor:SI
9345 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9346 (match_dup 2)))]
9347 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9348 "xor{b}\t{%2, %h0|%h0, %2}"
9349 [(set_attr "type" "alu")
9350 (set_attr "mode" "QI")])
9351
9352(define_insn "*xorqi_cc_ext_1_rex64"
9353 [(set (reg 17)
9354 (compare
9355 (xor:SI
9356 (zero_extract:SI
9357 (match_operand 1 "ext_register_operand" "0")
9358 (const_int 8)
9359 (const_int 8))
9360 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9361 (const_int 0)))
9362 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9363 (const_int 8)
9364 (const_int 8))
9365 (xor:SI
9366 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9367 (match_dup 2)))]
9368 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9369 "xor{b}\t{%2, %h0|%h0, %2}"
9370 [(set_attr "type" "alu")
9371 (set_attr "mode" "QI")])
9372
9373(define_expand "xorqi_cc_ext_1"
9374 [(parallel [
9375 (set (reg:CCNO 17)
9376 (compare:CCNO
9377 (xor:SI
9378 (zero_extract:SI
9379 (match_operand 1 "ext_register_operand" "")
9380 (const_int 8)
9381 (const_int 8))
9382 (match_operand:QI 2 "general_operand" ""))
9383 (const_int 0)))
9384 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9385 (const_int 8)
9386 (const_int 8))
9387 (xor:SI
9388 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9389 (match_dup 2)))])]
9390 ""
9391 "")
9392
9393(define_split
9394 [(set (match_operand 0 "register_operand" "")
9395 (xor (match_operand 1 "register_operand" "")
9396 (match_operand 2 "const_int_operand" "")))
9397 (clobber (reg:CC 17))]
9398 "reload_completed
9399 && QI_REG_P (operands[0])
9400 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9401 && !(INTVAL (operands[2]) & ~(255 << 8))
9402 && GET_MODE (operands[0]) != QImode"
9403 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9404 (xor:SI (zero_extract:SI (match_dup 1)
9405 (const_int 8) (const_int 8))
9406 (match_dup 2)))
9407 (clobber (reg:CC 17))])]
9408 "operands[0] = gen_lowpart (SImode, operands[0]);
9409 operands[1] = gen_lowpart (SImode, operands[1]);
9410 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9411
9412;; Since XOR can be encoded with sign extended immediate, this is only
9413;; profitable when 7th bit is set.
9414(define_split
9415 [(set (match_operand 0 "register_operand" "")
9416 (xor (match_operand 1 "general_operand" "")
9417 (match_operand 2 "const_int_operand" "")))
9418 (clobber (reg:CC 17))]
9419 "reload_completed
9420 && ANY_QI_REG_P (operands[0])
9421 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9422 && !(INTVAL (operands[2]) & ~255)
9423 && (INTVAL (operands[2]) & 128)
9424 && GET_MODE (operands[0]) != QImode"
9425 [(parallel [(set (strict_low_part (match_dup 0))
9426 (xor:QI (match_dup 1)
9427 (match_dup 2)))
9428 (clobber (reg:CC 17))])]
9429 "operands[0] = gen_lowpart (QImode, operands[0]);
9430 operands[1] = gen_lowpart (QImode, operands[1]);
9431 operands[2] = gen_lowpart (QImode, operands[2]);")
9432
9433;; Negation instructions
9434
9435(define_expand "negdi2"
9436 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9437 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9438 (clobber (reg:CC 17))])]
9439 ""
9440 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9441
9442(define_insn "*negdi2_1"
9443 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9444 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9445 (clobber (reg:CC 17))]
9446 "!TARGET_64BIT
9447 && ix86_unary_operator_ok (NEG, DImode, operands)"
9448 "#")
9449
9450(define_split
9451 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9452 (neg:DI (match_operand:DI 1 "general_operand" "")))
9453 (clobber (reg:CC 17))]
9454 "!TARGET_64BIT && reload_completed"
9455 [(parallel
9456 [(set (reg:CCZ 17)
9457 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9458 (set (match_dup 0) (neg:SI (match_dup 2)))])
9459 (parallel
9460 [(set (match_dup 1)
9461 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9462 (match_dup 3))
9463 (const_int 0)))
9464 (clobber (reg:CC 17))])
9465 (parallel
9466 [(set (match_dup 1)
9467 (neg:SI (match_dup 1)))
9468 (clobber (reg:CC 17))])]
9469 "split_di (operands+1, 1, operands+2, operands+3);
9470 split_di (operands+0, 1, operands+0, operands+1);")
9471
9472(define_insn "*negdi2_1_rex64"
9473 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9474 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9475 (clobber (reg:CC 17))]
9476 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9477 "neg{q}\t%0"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "DI")])
9480
9481;; The problem with neg is that it does not perform (compare x 0),
9482;; it really performs (compare 0 x), which leaves us with the zero
9483;; flag being the only useful item.
9484
9485(define_insn "*negdi2_cmpz_rex64"
9486 [(set (reg:CCZ 17)
9487 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9488 (const_int 0)))
9489 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9490 (neg:DI (match_dup 1)))]
9491 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9492 "neg{q}\t%0"
9493 [(set_attr "type" "negnot")
9494 (set_attr "mode" "DI")])
9495
9496
9497(define_expand "negsi2"
9498 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9499 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9500 (clobber (reg:CC 17))])]
9501 ""
9502 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9503
9504(define_insn "*negsi2_1"
9505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9506 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9507 (clobber (reg:CC 17))]
9508 "ix86_unary_operator_ok (NEG, SImode, operands)"
9509 "neg{l}\t%0"
9510 [(set_attr "type" "negnot")
9511 (set_attr "mode" "SI")])
9512
9513;; Combine is quite creative about this pattern.
9514(define_insn "*negsi2_1_zext"
9515 [(set (match_operand:DI 0 "register_operand" "=r")
9516 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9517 (const_int 32)))
9518 (const_int 32)))
9519 (clobber (reg:CC 17))]
9520 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9521 "neg{l}\t%k0"
9522 [(set_attr "type" "negnot")
9523 (set_attr "mode" "SI")])
9524
9525;; The problem with neg is that it does not perform (compare x 0),
9526;; it really performs (compare 0 x), which leaves us with the zero
9527;; flag being the only useful item.
9528
9529(define_insn "*negsi2_cmpz"
9530 [(set (reg:CCZ 17)
9531 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9532 (const_int 0)))
9533 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9534 (neg:SI (match_dup 1)))]
9535 "ix86_unary_operator_ok (NEG, SImode, operands)"
9536 "neg{l}\t%0"
9537 [(set_attr "type" "negnot")
9538 (set_attr "mode" "SI")])
9539
9540(define_insn "*negsi2_cmpz_zext"
9541 [(set (reg:CCZ 17)
9542 (compare:CCZ (lshiftrt:DI
9543 (neg:DI (ashift:DI
9544 (match_operand:DI 1 "register_operand" "0")
9545 (const_int 32)))
9546 (const_int 32))
9547 (const_int 0)))
9548 (set (match_operand:DI 0 "register_operand" "=r")
9549 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9550 (const_int 32)))
9551 (const_int 32)))]
9552 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9553 "neg{l}\t%k0"
9554 [(set_attr "type" "negnot")
9555 (set_attr "mode" "SI")])
9556
9557(define_expand "neghi2"
9558 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9559 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9560 (clobber (reg:CC 17))])]
9561 "TARGET_HIMODE_MATH"
9562 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9563
9564(define_insn "*neghi2_1"
9565 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9566 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9567 (clobber (reg:CC 17))]
9568 "ix86_unary_operator_ok (NEG, HImode, operands)"
9569 "neg{w}\t%0"
9570 [(set_attr "type" "negnot")
9571 (set_attr "mode" "HI")])
9572
9573(define_insn "*neghi2_cmpz"
9574 [(set (reg:CCZ 17)
9575 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9576 (const_int 0)))
9577 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9578 (neg:HI (match_dup 1)))]
9579 "ix86_unary_operator_ok (NEG, HImode, operands)"
9580 "neg{w}\t%0"
9581 [(set_attr "type" "negnot")
9582 (set_attr "mode" "HI")])
9583
9584(define_expand "negqi2"
9585 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9586 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9587 (clobber (reg:CC 17))])]
9588 "TARGET_QIMODE_MATH"
9589 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9590
9591(define_insn "*negqi2_1"
9592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9593 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9594 (clobber (reg:CC 17))]
9595 "ix86_unary_operator_ok (NEG, QImode, operands)"
9596 "neg{b}\t%0"
9597 [(set_attr "type" "negnot")
9598 (set_attr "mode" "QI")])
9599
9600(define_insn "*negqi2_cmpz"
9601 [(set (reg:CCZ 17)
9602 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9603 (const_int 0)))
9604 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9605 (neg:QI (match_dup 1)))]
9606 "ix86_unary_operator_ok (NEG, QImode, operands)"
9607 "neg{b}\t%0"
9608 [(set_attr "type" "negnot")
9609 (set_attr "mode" "QI")])
9610
9611;; Changing of sign for FP values is doable using integer unit too.
9612
9613(define_expand "negsf2"
9614 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9615 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9616 (clobber (reg:CC 17))])]
9617 "TARGET_80387 || TARGET_SSE_MATH"
9618 "if (TARGET_SSE_MATH)
9619 {
9620 /* In case operand is in memory, we will not use SSE. */
9621 if (memory_operand (operands[0], VOIDmode)
9622 && rtx_equal_p (operands[0], operands[1]))
9623 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9624 else
9625 {
9626 /* Using SSE is tricky, since we need bitwise negation of -0
9627 in register. */
9628 rtx reg = gen_reg_rtx (SFmode);
9629 rtx dest = operands[0];
9630 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9631
9632 operands[1] = force_reg (SFmode, operands[1]);
9633 operands[0] = force_reg (SFmode, operands[0]);
9634 reg = force_reg (V4SFmode,
9635 gen_rtx_CONST_VECTOR (V4SFmode,
9636 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9637 CONST0_RTX (SFmode),
9638 CONST0_RTX (SFmode))));
9639 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9640 if (dest != operands[0])
9641 emit_move_insn (dest, operands[0]);
9642 }
9643 DONE;
9644 }
9645 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9646
9647(define_insn "negsf2_memory"
9648 [(set (match_operand:SF 0 "memory_operand" "=m")
9649 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9650 (clobber (reg:CC 17))]
9651 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9652 "#")
9653
9654(define_insn "negsf2_ifs"
9655 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9656 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9657 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9658 (clobber (reg:CC 17))]
9659 "TARGET_SSE
9660 && (reload_in_progress || reload_completed
9661 || (register_operand (operands[0], VOIDmode)
9662 && register_operand (operands[1], VOIDmode)))"
9663 "#")
9664
9665(define_split
9666 [(set (match_operand:SF 0 "memory_operand" "")
9667 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9668 (use (match_operand:SF 2 "" ""))
9669 (clobber (reg:CC 17))]
9670 ""
9671 [(parallel [(set (match_dup 0)
9672 (neg:SF (match_dup 1)))
9673 (clobber (reg:CC 17))])])
9674
9675(define_split
9676 [(set (match_operand:SF 0 "register_operand" "")
9677 (neg:SF (match_operand:SF 1 "register_operand" "")))
9678 (use (match_operand:V4SF 2 "" ""))
9679 (clobber (reg:CC 17))]
9680 "reload_completed && !SSE_REG_P (operands[0])"
9681 [(parallel [(set (match_dup 0)
9682 (neg:SF (match_dup 1)))
9683 (clobber (reg:CC 17))])])
9684
9685(define_split
9686 [(set (match_operand:SF 0 "register_operand" "")
9687 (neg:SF (match_operand:SF 1 "register_operand" "")))
9688 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9689 (clobber (reg:CC 17))]
9690 "reload_completed && SSE_REG_P (operands[0])"
9691 [(set (match_dup 0)
9692 (xor:V4SF (match_dup 1)
9693 (match_dup 2)))]
9694{
9695 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9696 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9697 if (operands_match_p (operands[0], operands[2]))
9698 {
9699 rtx tmp;
9700 tmp = operands[1];
9701 operands[1] = operands[2];
9702 operands[2] = tmp;
9703 }
9704})
9705
9706
9707;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9708;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9709;; to itself.
9710(define_insn "*negsf2_if"
9711 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9712 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9713 (clobber (reg:CC 17))]
9714 "TARGET_80387
9715 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9716 "#")
9717
9718(define_split
9719 [(set (match_operand:SF 0 "fp_register_operand" "")
9720 (neg:SF (match_operand:SF 1 "register_operand" "")))
9721 (clobber (reg:CC 17))]
9722 "TARGET_80387 && reload_completed"
9723 [(set (match_dup 0)
9724 (neg:SF (match_dup 1)))]
9725 "")
9726
9727(define_split
9728 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9729 (neg:SF (match_operand:SF 1 "register_operand" "")))
9730 (clobber (reg:CC 17))]
9731 "TARGET_80387 && reload_completed"
9732 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9733 (clobber (reg:CC 17))])]
9734 "operands[1] = gen_int_mode (0x80000000, SImode);
9735 operands[0] = gen_lowpart (SImode, operands[0]);")
9736
9737(define_split
9738 [(set (match_operand 0 "memory_operand" "")
9739 (neg (match_operand 1 "memory_operand" "")))
9740 (clobber (reg:CC 17))]
9741 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9742 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9743 (clobber (reg:CC 17))])]
9744{
9745 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9746
9747 if (GET_MODE (operands[1]) == XFmode)
9748 size = 10;
9749 operands[0] = adjust_address (operands[0], QImode, size - 1);
9750 operands[1] = gen_int_mode (0x80, QImode);
9751})
9752
9753(define_expand "negdf2"
9754 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9755 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9756 (clobber (reg:CC 17))])]
9757 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9758 "if (TARGET_SSE2 && TARGET_SSE_MATH)
9759 {
9760 /* In case operand is in memory, we will not use SSE. */
9761 if (memory_operand (operands[0], VOIDmode)
9762 && rtx_equal_p (operands[0], operands[1]))
9763 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9764 else
9765 {
9766 /* Using SSE is tricky, since we need bitwise negation of -0
9767 in register. */
9768 rtx reg;
9769#if HOST_BITS_PER_WIDE_INT >= 64
9770 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9771#else
9772 rtx imm = immed_double_const (0, 0x80000000, DImode);
9773#endif
9774 rtx dest = operands[0];
9775
9776 operands[1] = force_reg (DFmode, operands[1]);
9777 operands[0] = force_reg (DFmode, operands[0]);
9778 imm = gen_lowpart (DFmode, imm);
9779 reg = force_reg (V2DFmode,
9780 gen_rtx_CONST_VECTOR (V2DFmode,
9781 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9782 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9783 if (dest != operands[0])
9784 emit_move_insn (dest, operands[0]);
9785 }
9786 DONE;
9787 }
9788 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9789
9790(define_insn "negdf2_memory"
9791 [(set (match_operand:DF 0 "memory_operand" "=m")
9792 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9793 (clobber (reg:CC 17))]
9794 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9795 "#")
9796
9797(define_insn "negdf2_ifs"
9798 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9799 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9800 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9801 (clobber (reg:CC 17))]
9802 "!TARGET_64BIT && TARGET_SSE2
9803 && (reload_in_progress || reload_completed
9804 || (register_operand (operands[0], VOIDmode)
9805 && register_operand (operands[1], VOIDmode)))"
9806 "#")
9807
9808(define_insn "*negdf2_ifs_rex64"
9809 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9810 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9811 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9812 (clobber (reg:CC 17))]
9813 "TARGET_64BIT && TARGET_SSE2
9814 && (reload_in_progress || reload_completed
9815 || (register_operand (operands[0], VOIDmode)
9816 && register_operand (operands[1], VOIDmode)))"
9817 "#")
9818
9819(define_split
9820 [(set (match_operand:DF 0 "memory_operand" "")
9821 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9822 (use (match_operand:V2DF 2 "" ""))
9823 (clobber (reg:CC 17))]
9824 ""
9825 [(parallel [(set (match_dup 0)
9826 (neg:DF (match_dup 1)))
9827 (clobber (reg:CC 17))])])
9828
9829(define_split
9830 [(set (match_operand:DF 0 "register_operand" "")
9831 (neg:DF (match_operand:DF 1 "register_operand" "")))
9832 (use (match_operand:V2DF 2 "" ""))
9833 (clobber (reg:CC 17))]
9834 "reload_completed && !SSE_REG_P (operands[0])
9835 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9836 [(parallel [(set (match_dup 0)
9837 (neg:DF (match_dup 1)))
9838 (clobber (reg:CC 17))])])
9839
9840(define_split
9841 [(set (match_operand:DF 0 "register_operand" "")
9842 (neg:DF (match_operand:DF 1 "register_operand" "")))
9843 (use (match_operand:V2DF 2 "" ""))
9844 (clobber (reg:CC 17))]
9845 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9846 [(parallel [(set (match_dup 0)
9847 (xor:DI (match_dup 1) (match_dup 2)))
9848 (clobber (reg:CC 17))])]
9849 "operands[0] = gen_lowpart (DImode, operands[0]);
9850 operands[1] = gen_lowpart (DImode, operands[1]);
9851 operands[2] = gen_lowpart (DImode, operands[2]);")
9852
9853(define_split
9854 [(set (match_operand:DF 0 "register_operand" "")
9855 (neg:DF (match_operand:DF 1 "register_operand" "")))
9856 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9857 (clobber (reg:CC 17))]
9858 "reload_completed && SSE_REG_P (operands[0])"
9859 [(set (match_dup 0)
9860 (xor:V2DF (match_dup 1)
9861 (match_dup 2)))]
9862{
9863 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9864 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9865 /* Avoid possible reformatting on the operands. */
9866 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9867 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9868 if (operands_match_p (operands[0], operands[2]))
9869 {
9870 rtx tmp;
9871 tmp = operands[1];
9872 operands[1] = operands[2];
9873 operands[2] = tmp;
9874 }
9875})
9876
9877;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9878;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9879;; to itself.
9880(define_insn "*negdf2_if"
9881 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9882 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9883 (clobber (reg:CC 17))]
9884 "!TARGET_64BIT && TARGET_80387
9885 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9886 "#")
9887
9888;; FIXME: We should to allow integer registers here. Problem is that
9889;; we need another scratch register to get constant from.
9890;; Forcing constant to mem if no register available in peep2 should be
9891;; safe even for PIC mode, because of RIP relative addressing.
9892(define_insn "*negdf2_if_rex64"
9893 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9894 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9895 (clobber (reg:CC 17))]
9896 "TARGET_64BIT && TARGET_80387
9897 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9898 "#")
9899
9900(define_split
9901 [(set (match_operand:DF 0 "fp_register_operand" "")
9902 (neg:DF (match_operand:DF 1 "register_operand" "")))
9903 (clobber (reg:CC 17))]
9904 "TARGET_80387 && reload_completed"
9905 [(set (match_dup 0)
9906 (neg:DF (match_dup 1)))]
9907 "")
9908
9909(define_split
9910 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9911 (neg:DF (match_operand:DF 1 "register_operand" "")))
9912 (clobber (reg:CC 17))]
9913 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9914 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9915 (clobber (reg:CC 17))])]
9916 "operands[4] = gen_int_mode (0x80000000, SImode);
9917 split_di (operands+0, 1, operands+2, operands+3);")
9918
9919(define_expand "negxf2"
9920 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9921 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9922 (clobber (reg:CC 17))])]
9923 "TARGET_80387"
9924 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9925
9926;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9927;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9928;; to itself.
9929(define_insn "*negxf2_if"
9930 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9931 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9932 (clobber (reg:CC 17))]
9933 "TARGET_80387
9934 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9935 "#")
9936
9937(define_split
9938 [(set (match_operand:XF 0 "fp_register_operand" "")
9939 (neg:XF (match_operand:XF 1 "register_operand" "")))
9940 (clobber (reg:CC 17))]
9941 "TARGET_80387 && reload_completed"
9942 [(set (match_dup 0)
9943 (neg:XF (match_dup 1)))]
9944 "")
9945
9946(define_split
9947 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9948 (neg:XF (match_operand:XF 1 "register_operand" "")))
9949 (clobber (reg:CC 17))]
9950 "TARGET_80387 && reload_completed"
9951 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9952 (clobber (reg:CC 17))])]
9953 "operands[1] = GEN_INT (0x8000);
9954 operands[0] = gen_rtx_REG (SImode,
9955 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9956
9957;; Conditionalize these after reload. If they matches before reload, we
9958;; lose the clobber and ability to use integer instructions.
9959
9960(define_insn "*negsf2_1"
9961 [(set (match_operand:SF 0 "register_operand" "=f")
9962 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9963 "TARGET_80387 && reload_completed"
9964 "fchs"
9965 [(set_attr "type" "fsgn")
9966 (set_attr "mode" "SF")
9967 (set_attr "ppro_uops" "few")])
9968
9969(define_insn "*negdf2_1"
9970 [(set (match_operand:DF 0 "register_operand" "=f")
9971 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9972 "TARGET_80387 && reload_completed"
9973 "fchs"
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "DF")
9976 (set_attr "ppro_uops" "few")])
9977
9978(define_insn "*negextendsfdf2"
9979 [(set (match_operand:DF 0 "register_operand" "=f")
9980 (neg:DF (float_extend:DF
9981 (match_operand:SF 1 "register_operand" "0"))))]
9982 "TARGET_80387"
9983 "fchs"
9984 [(set_attr "type" "fsgn")
9985 (set_attr "mode" "DF")
9986 (set_attr "ppro_uops" "few")])
9987
9988(define_insn "*negxf2_1"
9989 [(set (match_operand:XF 0 "register_operand" "=f")
9990 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9991 "TARGET_80387 && reload_completed"
9992 "fchs"
9993 [(set_attr "type" "fsgn")
9994 (set_attr "mode" "XF")
9995 (set_attr "ppro_uops" "few")])
9996
9997(define_insn "*negextenddfxf2"
9998 [(set (match_operand:XF 0 "register_operand" "=f")
9999 (neg:XF (float_extend:XF
10000 (match_operand:DF 1 "register_operand" "0"))))]
10001 "TARGET_80387"
10002 "fchs"
10003 [(set_attr "type" "fsgn")
10004 (set_attr "mode" "XF")
10005 (set_attr "ppro_uops" "few")])
10006
10007(define_insn "*negextendsfxf2"
10008 [(set (match_operand:XF 0 "register_operand" "=f")
10009 (neg:XF (float_extend:XF
10010 (match_operand:SF 1 "register_operand" "0"))))]
10011 "TARGET_80387"
10012 "fchs"
10013 [(set_attr "type" "fsgn")
10014 (set_attr "mode" "XF")
10015 (set_attr "ppro_uops" "few")])
10016
10017;; Absolute value instructions
10018
10019(define_expand "abssf2"
10020 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10021 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10022 (clobber (reg:CC 17))])]
10023 "TARGET_80387 || TARGET_SSE_MATH"
10024 "if (TARGET_SSE_MATH)
10025 {
10026 /* In case operand is in memory, we will not use SSE. */
10027 if (memory_operand (operands[0], VOIDmode)
10028 && rtx_equal_p (operands[0], operands[1]))
10029 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10030 else
10031 {
10032 /* Using SSE is tricky, since we need bitwise negation of -0
10033 in register. */
10034 rtx reg = gen_reg_rtx (V4SFmode);
10035 rtx dest = operands[0];
10036 rtx imm;
10037
10038 operands[1] = force_reg (SFmode, operands[1]);
10039 operands[0] = force_reg (SFmode, operands[0]);
10040 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10041 reg = force_reg (V4SFmode,
10042 gen_rtx_CONST_VECTOR (V4SFmode,
10043 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10044 CONST0_RTX (SFmode),
10045 CONST0_RTX (SFmode))));
10046 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10047 if (dest != operands[0])
10048 emit_move_insn (dest, operands[0]);
10049 }
10050 DONE;
10051 }
10052 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10053
10054(define_insn "abssf2_memory"
10055 [(set (match_operand:SF 0 "memory_operand" "=m")
10056 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10057 (clobber (reg:CC 17))]
10058 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10059 "#")
10060
10061(define_insn "abssf2_ifs"
10062 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10063 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10064 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10065 (clobber (reg:CC 17))]
10066 "TARGET_SSE
10067 && (reload_in_progress || reload_completed
10068 || (register_operand (operands[0], VOIDmode)
10069 && register_operand (operands[1], VOIDmode)))"
10070 "#")
10071
10072(define_split
10073 [(set (match_operand:SF 0 "memory_operand" "")
10074 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10075 (use (match_operand:V4SF 2 "" ""))
10076 (clobber (reg:CC 17))]
10077 ""
10078 [(parallel [(set (match_dup 0)
10079 (abs:SF (match_dup 1)))
10080 (clobber (reg:CC 17))])])
10081
10082(define_split
10083 [(set (match_operand:SF 0 "register_operand" "")
10084 (abs:SF (match_operand:SF 1 "register_operand" "")))
10085 (use (match_operand:V4SF 2 "" ""))
10086 (clobber (reg:CC 17))]
10087 "reload_completed && !SSE_REG_P (operands[0])"
10088 [(parallel [(set (match_dup 0)
10089 (abs:SF (match_dup 1)))
10090 (clobber (reg:CC 17))])])
10091
10092(define_split
10093 [(set (match_operand:SF 0 "register_operand" "")
10094 (abs:SF (match_operand:SF 1 "register_operand" "")))
10095 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10096 (clobber (reg:CC 17))]
10097 "reload_completed && SSE_REG_P (operands[0])"
10098 [(set (match_dup 0)
10099 (and:V4SF (match_dup 1)
10100 (match_dup 2)))]
10101{
10102 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10103 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10104 if (operands_match_p (operands[0], operands[2]))
10105 {
10106 rtx tmp;
10107 tmp = operands[1];
10108 operands[1] = operands[2];
10109 operands[2] = tmp;
10110 }
10111})
10112
10113;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10114;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10115;; to itself.
10116(define_insn "*abssf2_if"
10117 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10118 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10119 (clobber (reg:CC 17))]
10120 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
10121 "#")
10122
10123(define_split
10124 [(set (match_operand:SF 0 "fp_register_operand" "")
10125 (abs:SF (match_operand:SF 1 "register_operand" "")))
10126 (clobber (reg:CC 17))]
10127 "TARGET_80387 && reload_completed"
10128 [(set (match_dup 0)
10129 (abs:SF (match_dup 1)))]
10130 "")
10131
10132(define_split
10133 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10134 (abs:SF (match_operand:SF 1 "register_operand" "")))
10135 (clobber (reg:CC 17))]
10136 "TARGET_80387 && reload_completed"
10137 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10138 (clobber (reg:CC 17))])]
10139 "operands[1] = gen_int_mode (~0x80000000, SImode);
10140 operands[0] = gen_lowpart (SImode, operands[0]);")
10141
10142(define_split
10143 [(set (match_operand 0 "memory_operand" "")
10144 (abs (match_operand 1 "memory_operand" "")))
10145 (clobber (reg:CC 17))]
10146 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10147 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10148 (clobber (reg:CC 17))])]
10149{
10150 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10151
10152 if (GET_MODE (operands[1]) == XFmode)
10153 size = 10;
10154 operands[0] = adjust_address (operands[0], QImode, size - 1);
10155 operands[1] = gen_int_mode (~0x80, QImode);
10156})
10157
10158(define_expand "absdf2"
10159 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10160 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10161 (clobber (reg:CC 17))])]
10162 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10163 "if (TARGET_SSE2 && TARGET_SSE_MATH)
10164 {
10165 /* In case operand is in memory, we will not use SSE. */
10166 if (memory_operand (operands[0], VOIDmode)
10167 && rtx_equal_p (operands[0], operands[1]))
10168 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10169 else
10170 {
10171 /* Using SSE is tricky, since we need bitwise negation of -0
10172 in register. */
10173 rtx reg = gen_reg_rtx (V2DFmode);
10174#if HOST_BITS_PER_WIDE_INT >= 64
10175 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10176#else
10177 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10178#endif
10179 rtx dest = operands[0];
10180
10181 operands[1] = force_reg (DFmode, operands[1]);
10182 operands[0] = force_reg (DFmode, operands[0]);
10183
10184 /* Produce LONG_DOUBLE with the proper immediate argument. */
10185 imm = gen_lowpart (DFmode, imm);
10186 reg = force_reg (V2DFmode,
10187 gen_rtx_CONST_VECTOR (V2DFmode,
10188 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10189 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10190 if (dest != operands[0])
10191 emit_move_insn (dest, operands[0]);
10192 }
10193 DONE;
10194 }
10195 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10196
10197(define_insn "absdf2_memory"
10198 [(set (match_operand:DF 0 "memory_operand" "=m")
10199 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10200 (clobber (reg:CC 17))]
10201 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10202 "#")
10203
10204(define_insn "absdf2_ifs"
10205 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10206 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10207 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10208 (clobber (reg:CC 17))]
10209 "!TARGET_64BIT && TARGET_SSE2
10210 && (reload_in_progress || reload_completed
10211 || (register_operand (operands[0], VOIDmode)
10212 && register_operand (operands[1], VOIDmode)))"
10213 "#")
10214
10215(define_insn "*absdf2_ifs_rex64"
10216 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10217 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10218 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10219 (clobber (reg:CC 17))]
10220 "TARGET_64BIT && TARGET_SSE2
10221 && (reload_in_progress || reload_completed
10222 || (register_operand (operands[0], VOIDmode)
10223 && register_operand (operands[1], VOIDmode)))"
10224 "#")
10225
10226(define_split
10227 [(set (match_operand:DF 0 "memory_operand" "")
10228 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10229 (use (match_operand:V2DF 2 "" ""))
10230 (clobber (reg:CC 17))]
10231 ""
10232 [(parallel [(set (match_dup 0)
10233 (abs:DF (match_dup 1)))
10234 (clobber (reg:CC 17))])])
10235
10236(define_split
10237 [(set (match_operand:DF 0 "register_operand" "")
10238 (abs:DF (match_operand:DF 1 "register_operand" "")))
10239 (use (match_operand:V2DF 2 "" ""))
10240 (clobber (reg:CC 17))]
10241 "reload_completed && !SSE_REG_P (operands[0])"
10242 [(parallel [(set (match_dup 0)
10243 (abs:DF (match_dup 1)))
10244 (clobber (reg:CC 17))])])
10245
10246(define_split
10247 [(set (match_operand:DF 0 "register_operand" "")
10248 (abs:DF (match_operand:DF 1 "register_operand" "")))
10249 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10250 (clobber (reg:CC 17))]
10251 "reload_completed && SSE_REG_P (operands[0])"
10252 [(set (match_dup 0)
10253 (and:V2DF (match_dup 1)
10254 (match_dup 2)))]
10255{
10256 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10257 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10258 /* Avoid possible reformatting on the operands. */
10259 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10260 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10261 if (operands_match_p (operands[0], operands[2]))
10262 {
10263 rtx tmp;
10264 tmp = operands[1];
10265 operands[1] = operands[2];
10266 operands[2] = tmp;
10267 }
10268})
10269
10270
10271;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10272;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10273;; to itself.
10274(define_insn "*absdf2_if"
10275 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10276 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10277 (clobber (reg:CC 17))]
10278 "!TARGET_64BIT && TARGET_80387
10279 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10280 "#")
10281
10282;; FIXME: We should to allow integer registers here. Problem is that
10283;; we need another scratch register to get constant from.
10284;; Forcing constant to mem if no register available in peep2 should be
10285;; safe even for PIC mode, because of RIP relative addressing.
10286(define_insn "*absdf2_if_rex64"
10287 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10288 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10289 (clobber (reg:CC 17))]
10290 "TARGET_64BIT && TARGET_80387
10291 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10292 "#")
10293
10294(define_split
10295 [(set (match_operand:DF 0 "fp_register_operand" "")
10296 (abs:DF (match_operand:DF 1 "register_operand" "")))
10297 (clobber (reg:CC 17))]
10298 "TARGET_80387 && reload_completed"
10299 [(set (match_dup 0)
10300 (abs:DF (match_dup 1)))]
10301 "")
10302
10303(define_split
10304 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10305 (abs:DF (match_operand:DF 1 "register_operand" "")))
10306 (clobber (reg:CC 17))]
10307 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10308 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10309 (clobber (reg:CC 17))])]
10310 "operands[4] = gen_int_mode (~0x80000000, SImode);
10311 split_di (operands+0, 1, operands+2, operands+3);")
10312
10313(define_expand "absxf2"
10314 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10315 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10316 (clobber (reg:CC 17))])]
10317 "TARGET_80387"
10318 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10319
10320;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10321;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10322;; to itself.
10323(define_insn "*absxf2_if"
10324 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10325 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10326 (clobber (reg:CC 17))]
10327 "TARGET_80387
10328 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10329 "#")
10330
10331(define_split
10332 [(set (match_operand:XF 0 "fp_register_operand" "")
10333 (abs:XF (match_operand:XF 1 "register_operand" "")))
10334 (clobber (reg:CC 17))]
10335 "TARGET_80387 && reload_completed"
10336 [(set (match_dup 0)
10337 (abs:XF (match_dup 1)))]
10338 "")
10339
10340(define_split
10341 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10342 (abs:XF (match_operand:XF 1 "register_operand" "")))
10343 (clobber (reg:CC 17))]
10344 "TARGET_80387 && reload_completed"
10345 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10346 (clobber (reg:CC 17))])]
10347 "operands[1] = GEN_INT (~0x8000);
10348 operands[0] = gen_rtx_REG (SImode,
10349 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10350
10351(define_insn "*abssf2_1"
10352 [(set (match_operand:SF 0 "register_operand" "=f")
10353 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10354 "TARGET_80387 && reload_completed"
10355 "fabs"
10356 [(set_attr "type" "fsgn")
10357 (set_attr "mode" "SF")])
10358
10359(define_insn "*absdf2_1"
10360 [(set (match_operand:DF 0 "register_operand" "=f")
10361 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10362 "TARGET_80387 && reload_completed"
10363 "fabs"
10364 [(set_attr "type" "fsgn")
10365 (set_attr "mode" "DF")])
10366
10367(define_insn "*absextendsfdf2"
10368 [(set (match_operand:DF 0 "register_operand" "=f")
10369 (abs:DF (float_extend:DF
10370 (match_operand:SF 1 "register_operand" "0"))))]
10371 "TARGET_80387"
10372 "fabs"
10373 [(set_attr "type" "fsgn")
10374 (set_attr "mode" "DF")])
10375
10376(define_insn "*absxf2_1"
10377 [(set (match_operand:XF 0 "register_operand" "=f")
10378 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10379 "TARGET_80387 && reload_completed"
10380 "fabs"
10381 [(set_attr "type" "fsgn")
10382 (set_attr "mode" "DF")])
10383
10384(define_insn "*absextenddfxf2"
10385 [(set (match_operand:XF 0 "register_operand" "=f")
10386 (abs:XF (float_extend:XF
10387 (match_operand:DF 1 "register_operand" "0"))))]
10388 "TARGET_80387"
10389 "fabs"
10390 [(set_attr "type" "fsgn")
10391 (set_attr "mode" "XF")])
10392
10393(define_insn "*absextendsfxf2"
10394 [(set (match_operand:XF 0 "register_operand" "=f")
10395 (abs:XF (float_extend:XF
10396 (match_operand:SF 1 "register_operand" "0"))))]
10397 "TARGET_80387"
10398 "fabs"
10399 [(set_attr "type" "fsgn")
10400 (set_attr "mode" "XF")])
10401
10402;; One complement instructions
10403
10404(define_expand "one_cmpldi2"
10405 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10406 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10407 "TARGET_64BIT"
10408 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10409
10410(define_insn "*one_cmpldi2_1_rex64"
10411 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10412 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10413 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10414 "not{q}\t%0"
10415 [(set_attr "type" "negnot")
10416 (set_attr "mode" "DI")])
10417
10418(define_insn "*one_cmpldi2_2_rex64"
10419 [(set (reg 17)
10420 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10421 (const_int 0)))
10422 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10423 (not:DI (match_dup 1)))]
10424 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10425 && ix86_unary_operator_ok (NOT, DImode, operands)"
10426 "#"
10427 [(set_attr "type" "alu1")
10428 (set_attr "mode" "DI")])
10429
10430(define_split
10431 [(set (match_operand 0 "flags_reg_operand" "")
10432 (match_operator 2 "compare_operator"
10433 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10434 (const_int 0)]))
10435 (set (match_operand:DI 1 "nonimmediate_operand" "")
10436 (not:DI (match_dup 3)))]
10437 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10438 [(parallel [(set (match_dup 0)
10439 (match_op_dup 2
10440 [(xor:DI (match_dup 3) (const_int -1))
10441 (const_int 0)]))
10442 (set (match_dup 1)
10443 (xor:DI (match_dup 3) (const_int -1)))])]
10444 "")
10445
10446(define_expand "one_cmplsi2"
10447 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10448 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10449 ""
10450 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10451
10452(define_insn "*one_cmplsi2_1"
10453 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10454 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10455 "ix86_unary_operator_ok (NOT, SImode, operands)"
10456 "not{l}\t%0"
10457 [(set_attr "type" "negnot")
10458 (set_attr "mode" "SI")])
10459
10460;; ??? Currently never generated - xor is used instead.
10461(define_insn "*one_cmplsi2_1_zext"
10462 [(set (match_operand:DI 0 "register_operand" "=r")
10463 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10464 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10465 "not{l}\t%k0"
10466 [(set_attr "type" "negnot")
10467 (set_attr "mode" "SI")])
10468
10469(define_insn "*one_cmplsi2_2"
10470 [(set (reg 17)
10471 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10472 (const_int 0)))
10473 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10474 (not:SI (match_dup 1)))]
10475 "ix86_match_ccmode (insn, CCNOmode)
10476 && ix86_unary_operator_ok (NOT, SImode, operands)"
10477 "#"
10478 [(set_attr "type" "alu1")
10479 (set_attr "mode" "SI")])
10480
10481(define_split
10482 [(set (match_operand 0 "flags_reg_operand" "")
10483 (match_operator 2 "compare_operator"
10484 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10485 (const_int 0)]))
10486 (set (match_operand:SI 1 "nonimmediate_operand" "")
10487 (not:SI (match_dup 3)))]
10488 "ix86_match_ccmode (insn, CCNOmode)"
10489 [(parallel [(set (match_dup 0)
10490 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10491 (const_int 0)]))
10492 (set (match_dup 1)
10493 (xor:SI (match_dup 3) (const_int -1)))])]
10494 "")
10495
10496;; ??? Currently never generated - xor is used instead.
10497(define_insn "*one_cmplsi2_2_zext"
10498 [(set (reg 17)
10499 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10500 (const_int 0)))
10501 (set (match_operand:DI 0 "register_operand" "=r")
10502 (zero_extend:DI (not:SI (match_dup 1))))]
10503 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10504 && ix86_unary_operator_ok (NOT, SImode, operands)"
10505 "#"
10506 [(set_attr "type" "alu1")
10507 (set_attr "mode" "SI")])
10508
10509(define_split
10510 [(set (match_operand 0 "flags_reg_operand" "")
10511 (match_operator 2 "compare_operator"
10512 [(not:SI (match_operand:SI 3 "register_operand" ""))
10513 (const_int 0)]))
10514 (set (match_operand:DI 1 "register_operand" "")
10515 (zero_extend:DI (not:SI (match_dup 3))))]
10516 "ix86_match_ccmode (insn, CCNOmode)"
10517 [(parallel [(set (match_dup 0)
10518 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10519 (const_int 0)]))
10520 (set (match_dup 1)
10521 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10522 "")
10523
10524(define_expand "one_cmplhi2"
10525 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10526 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10527 "TARGET_HIMODE_MATH"
10528 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10529
10530(define_insn "*one_cmplhi2_1"
10531 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10532 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10533 "ix86_unary_operator_ok (NOT, HImode, operands)"
10534 "not{w}\t%0"
10535 [(set_attr "type" "negnot")
10536 (set_attr "mode" "HI")])
10537
10538(define_insn "*one_cmplhi2_2"
10539 [(set (reg 17)
10540 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10541 (const_int 0)))
10542 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10543 (not:HI (match_dup 1)))]
10544 "ix86_match_ccmode (insn, CCNOmode)
10545 && ix86_unary_operator_ok (NEG, HImode, operands)"
10546 "#"
10547 [(set_attr "type" "alu1")
10548 (set_attr "mode" "HI")])
10549
10550(define_split
10551 [(set (match_operand 0 "flags_reg_operand" "")
10552 (match_operator 2 "compare_operator"
10553 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10554 (const_int 0)]))
10555 (set (match_operand:HI 1 "nonimmediate_operand" "")
10556 (not:HI (match_dup 3)))]
10557 "ix86_match_ccmode (insn, CCNOmode)"
10558 [(parallel [(set (match_dup 0)
10559 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10560 (const_int 0)]))
10561 (set (match_dup 1)
10562 (xor:HI (match_dup 3) (const_int -1)))])]
10563 "")
10564
10565;; %%% Potential partial reg stall on alternative 1. What to do?
10566(define_expand "one_cmplqi2"
10567 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10568 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10569 "TARGET_QIMODE_MATH"
10570 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10571
10572(define_insn "*one_cmplqi2_1"
10573 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10574 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10575 "ix86_unary_operator_ok (NOT, QImode, operands)"
10576 "@
10577 not{b}\t%0
10578 not{l}\t%k0"
10579 [(set_attr "type" "negnot")
10580 (set_attr "mode" "QI,SI")])
10581
10582(define_insn "*one_cmplqi2_2"
10583 [(set (reg 17)
10584 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10585 (const_int 0)))
10586 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10587 (not:QI (match_dup 1)))]
10588 "ix86_match_ccmode (insn, CCNOmode)
10589 && ix86_unary_operator_ok (NOT, QImode, operands)"
10590 "#"
10591 [(set_attr "type" "alu1")
10592 (set_attr "mode" "QI")])
10593
10594(define_split
10595 [(set (match_operand 0 "flags_reg_operand" "")
10596 (match_operator 2 "compare_operator"
10597 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10598 (const_int 0)]))
10599 (set (match_operand:QI 1 "nonimmediate_operand" "")
10600 (not:QI (match_dup 3)))]
10601 "ix86_match_ccmode (insn, CCNOmode)"
10602 [(parallel [(set (match_dup 0)
10603 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10604 (const_int 0)]))
10605 (set (match_dup 1)
10606 (xor:QI (match_dup 3) (const_int -1)))])]
10607 "")
10608
10609;; Arithmetic shift instructions
10610
10611;; DImode shifts are implemented using the i386 "shift double" opcode,
10612;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10613;; is variable, then the count is in %cl and the "imm" operand is dropped
10614;; from the assembler input.
10615;;
10616;; This instruction shifts the target reg/mem as usual, but instead of
10617;; shifting in zeros, bits are shifted in from reg operand. If the insn
10618;; is a left shift double, bits are taken from the high order bits of
10619;; reg, else if the insn is a shift right double, bits are taken from the
10620;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10621;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10622;;
10623;; Since sh[lr]d does not change the `reg' operand, that is done
10624;; separately, making all shifts emit pairs of shift double and normal
10625;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10626;; support a 63 bit shift, each shift where the count is in a reg expands
10627;; to a pair of shifts, a branch, a shift by 32 and a label.
10628;;
10629;; If the shift count is a constant, we need never emit more than one
10630;; shift pair, instead using moves and sign extension for counts greater
10631;; than 31.
10632
10633(define_expand "ashldi3"
10634 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10635 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10636 (match_operand:QI 2 "nonmemory_operand" "")))
10637 (clobber (reg:CC 17))])]
10638 ""
10639{
10640 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10641 {
10642 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10643 DONE;
10644 }
10645 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10646 DONE;
10647})
10648
10649(define_insn "*ashldi3_1_rex64"
10650 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10651 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10652 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10653 (clobber (reg:CC 17))]
10654 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10655{
10656 switch (get_attr_type (insn))
10657 {
10658 case TYPE_ALU:
10659 if (operands[2] != const1_rtx)
10660 abort ();
10661 if (!rtx_equal_p (operands[0], operands[1]))
10662 abort ();
10663 return "add{q}\t{%0, %0|%0, %0}";
10664
10665 case TYPE_LEA:
10666 if (GET_CODE (operands[2]) != CONST_INT
10667 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10668 abort ();
10669 operands[1] = gen_rtx_MULT (DImode, operands[1],
10670 GEN_INT (1 << INTVAL (operands[2])));
10671 return "lea{q}\t{%a1, %0|%0, %a1}";
10672
10673 default:
10674 if (REG_P (operands[2]))
10675 return "sal{q}\t{%b2, %0|%0, %b2}";
10676 else if (GET_CODE (operands[2]) == CONST_INT
10677 && INTVAL (operands[2]) == 1
10678 && (TARGET_SHIFT1 || optimize_size))
10679 return "sal{q}\t%0";
10680 else
10681 return "sal{q}\t{%2, %0|%0, %2}";
10682 }
10683}
10684 [(set (attr "type")
10685 (cond [(eq_attr "alternative" "1")
10686 (const_string "lea")
10687 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10688 (const_int 0))
10689 (match_operand 0 "register_operand" ""))
10690 (match_operand 2 "const1_operand" ""))
10691 (const_string "alu")
10692 ]
10693 (const_string "ishift")))
10694 (set_attr "mode" "DI")])
10695
10696;; Convert lea to the lea pattern to avoid flags dependency.
10697(define_split
10698 [(set (match_operand:DI 0 "register_operand" "")
10699 (ashift:DI (match_operand:DI 1 "register_operand" "")
10700 (match_operand:QI 2 "immediate_operand" "")))
10701 (clobber (reg:CC 17))]
10702 "TARGET_64BIT && reload_completed
10703 && true_regnum (operands[0]) != true_regnum (operands[1])"
10704 [(set (match_dup 0)
10705 (mult:DI (match_dup 1)
10706 (match_dup 2)))]
10707 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10708
10709;; This pattern can't accept a variable shift count, since shifts by
10710;; zero don't affect the flags. We assume that shifts by constant
10711;; zero are optimized away.
10712(define_insn "*ashldi3_cmp_rex64"
10713 [(set (reg 17)
10714 (compare
10715 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10716 (match_operand:QI 2 "immediate_operand" "e"))
10717 (const_int 0)))
10718 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10719 (ashift:DI (match_dup 1) (match_dup 2)))]
10720 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10721 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10722{
10723 switch (get_attr_type (insn))
10724 {
10725 case TYPE_ALU:
10726 if (operands[2] != const1_rtx)
10727 abort ();
10728 return "add{q}\t{%0, %0|%0, %0}";
10729
10730 default:
10731 if (REG_P (operands[2]))
10732 return "sal{q}\t{%b2, %0|%0, %b2}";
10733 else if (GET_CODE (operands[2]) == CONST_INT
10734 && INTVAL (operands[2]) == 1
10735 && (TARGET_SHIFT1 || optimize_size))
10736 return "sal{q}\t%0";
10737 else
10738 return "sal{q}\t{%2, %0|%0, %2}";
10739 }
10740}
10741 [(set (attr "type")
10742 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10743 (const_int 0))
10744 (match_operand 0 "register_operand" ""))
10745 (match_operand 2 "const1_operand" ""))
10746 (const_string "alu")
10747 ]
10748 (const_string "ishift")))
10749 (set_attr "mode" "DI")])
10750
10751(define_insn "ashldi3_1"
10752 [(set (match_operand:DI 0 "register_operand" "=r")
10753 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10754 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10755 (clobber (match_scratch:SI 3 "=&r"))
10756 (clobber (reg:CC 17))]
10757 "!TARGET_64BIT && TARGET_CMOVE"
10758 "#"
10759 [(set_attr "type" "multi")])
10760
10761(define_insn "*ashldi3_2"
10762 [(set (match_operand:DI 0 "register_operand" "=r")
10763 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10764 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10765 (clobber (reg:CC 17))]
10766 "!TARGET_64BIT"
10767 "#"
10768 [(set_attr "type" "multi")])
10769
10770(define_split
10771 [(set (match_operand:DI 0 "register_operand" "")
10772 (ashift:DI (match_operand:DI 1 "register_operand" "")
10773 (match_operand:QI 2 "nonmemory_operand" "")))
10774 (clobber (match_scratch:SI 3 ""))
10775 (clobber (reg:CC 17))]
10776 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10777 [(const_int 0)]
10778 "ix86_split_ashldi (operands, operands[3]); DONE;")
10779
10780(define_split
10781 [(set (match_operand:DI 0 "register_operand" "")
10782 (ashift:DI (match_operand:DI 1 "register_operand" "")
10783 (match_operand:QI 2 "nonmemory_operand" "")))
10784 (clobber (reg:CC 17))]
10785 "!TARGET_64BIT && reload_completed"
10786 [(const_int 0)]
10787 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10788
10789(define_insn "x86_shld_1"
10790 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10791 (ior:SI (ashift:SI (match_dup 0)
10792 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10793 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10794 (minus:QI (const_int 32) (match_dup 2)))))
10795 (clobber (reg:CC 17))]
10796 ""
10797 "@
10798 shld{l}\t{%2, %1, %0|%0, %1, %2}
10799 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10800 [(set_attr "type" "ishift")
10801 (set_attr "prefix_0f" "1")
10802 (set_attr "mode" "SI")
10803 (set_attr "pent_pair" "np")
10804 (set_attr "athlon_decode" "vector")
10805 (set_attr "ppro_uops" "few")])
10806
10807(define_expand "x86_shift_adj_1"
10808 [(set (reg:CCZ 17)
10809 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10810 (const_int 32))
10811 (const_int 0)))
10812 (set (match_operand:SI 0 "register_operand" "")
10813 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10814 (match_operand:SI 1 "register_operand" "")
10815 (match_dup 0)))
10816 (set (match_dup 1)
10817 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10818 (match_operand:SI 3 "register_operand" "r")
10819 (match_dup 1)))]
10820 "TARGET_CMOVE"
10821 "")
10822
10823(define_expand "x86_shift_adj_2"
10824 [(use (match_operand:SI 0 "register_operand" ""))
10825 (use (match_operand:SI 1 "register_operand" ""))
10826 (use (match_operand:QI 2 "register_operand" ""))]
10827 ""
10828{
10829 rtx label = gen_label_rtx ();
10830 rtx tmp;
10831
10832 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10833
10834 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10835 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10836 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10837 gen_rtx_LABEL_REF (VOIDmode, label),
10838 pc_rtx);
10839 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10840 JUMP_LABEL (tmp) = label;
10841
10842 emit_move_insn (operands[0], operands[1]);
10843 emit_move_insn (operands[1], const0_rtx);
10844
10845 emit_label (label);
10846 LABEL_NUSES (label) = 1;
10847
10848 DONE;
10849})
10850
10851(define_expand "ashlsi3"
10852 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10853 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10854 (match_operand:QI 2 "nonmemory_operand" "")))
10855 (clobber (reg:CC 17))]
10856 ""
10857 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10858
10859(define_insn "*ashlsi3_1"
10860 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10861 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10862 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10863 (clobber (reg:CC 17))]
10864 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10865{
10866 switch (get_attr_type (insn))
10867 {
10868 case TYPE_ALU:
10869 if (operands[2] != const1_rtx)
10870 abort ();
10871 if (!rtx_equal_p (operands[0], operands[1]))
10872 abort ();
10873 return "add{l}\t{%0, %0|%0, %0}";
10874
10875 case TYPE_LEA:
10876 return "#";
10877
10878 default:
10879 if (REG_P (operands[2]))
10880 return "sal{l}\t{%b2, %0|%0, %b2}";
10881 else if (GET_CODE (operands[2]) == CONST_INT
10882 && INTVAL (operands[2]) == 1
10883 && (TARGET_SHIFT1 || optimize_size))
10884 return "sal{l}\t%0";
10885 else
10886 return "sal{l}\t{%2, %0|%0, %2}";
10887 }
10888}
10889 [(set (attr "type")
10890 (cond [(eq_attr "alternative" "1")
10891 (const_string "lea")
10892 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893 (const_int 0))
10894 (match_operand 0 "register_operand" ""))
10895 (match_operand 2 "const1_operand" ""))
10896 (const_string "alu")
10897 ]
10898 (const_string "ishift")))
10899 (set_attr "mode" "SI")])
10900
10901;; Convert lea to the lea pattern to avoid flags dependency.
10902(define_split
10903 [(set (match_operand 0 "register_operand" "")
10904 (ashift (match_operand 1 "index_register_operand" "")
10905 (match_operand:QI 2 "const_int_operand" "")))
10906 (clobber (reg:CC 17))]
10907 "reload_completed
10908 && true_regnum (operands[0]) != true_regnum (operands[1])"
10909 [(const_int 0)]
10910{
10911 rtx pat;
10912 operands[0] = gen_lowpart (SImode, operands[0]);
10913 operands[1] = gen_lowpart (Pmode, operands[1]);
10914 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10915 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10916 if (Pmode != SImode)
10917 pat = gen_rtx_SUBREG (SImode, pat, 0);
10918 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10919 DONE;
10920})
10921
10922;; Rare case of shifting RSP is handled by generating move and shift
10923(define_split
10924 [(set (match_operand 0 "register_operand" "")
10925 (ashift (match_operand 1 "register_operand" "")
10926 (match_operand:QI 2 "const_int_operand" "")))
10927 (clobber (reg:CC 17))]
10928 "reload_completed
10929 && true_regnum (operands[0]) != true_regnum (operands[1])"
10930 [(const_int 0)]
10931{
10932 rtx pat, clob;
10933 emit_move_insn (operands[1], operands[0]);
10934 pat = gen_rtx_SET (VOIDmode, operands[0],
10935 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10936 operands[0], operands[2]));
10937 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10938 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10939 DONE;
10940})
10941
10942(define_insn "*ashlsi3_1_zext"
10943 [(set (match_operand:DI 0 "register_operand" "=r,r")
10944 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10945 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10946 (clobber (reg:CC 17))]
10947 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10948{
10949 switch (get_attr_type (insn))
10950 {
10951 case TYPE_ALU:
10952 if (operands[2] != const1_rtx)
10953 abort ();
10954 return "add{l}\t{%k0, %k0|%k0, %k0}";
10955
10956 case TYPE_LEA:
10957 return "#";
10958
10959 default:
10960 if (REG_P (operands[2]))
10961 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10962 else if (GET_CODE (operands[2]) == CONST_INT
10963 && INTVAL (operands[2]) == 1
10964 && (TARGET_SHIFT1 || optimize_size))
10965 return "sal{l}\t%k0";
10966 else
10967 return "sal{l}\t{%2, %k0|%k0, %2}";
10968 }
10969}
10970 [(set (attr "type")
10971 (cond [(eq_attr "alternative" "1")
10972 (const_string "lea")
10973 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974 (const_int 0))
10975 (match_operand 2 "const1_operand" ""))
10976 (const_string "alu")
10977 ]
10978 (const_string "ishift")))
10979 (set_attr "mode" "SI")])
10980
10981;; Convert lea to the lea pattern to avoid flags dependency.
10982(define_split
10983 [(set (match_operand:DI 0 "register_operand" "")
10984 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10985 (match_operand:QI 2 "const_int_operand" ""))))
10986 (clobber (reg:CC 17))]
10987 "TARGET_64BIT && reload_completed
10988 && true_regnum (operands[0]) != true_regnum (operands[1])"
10989 [(set (match_dup 0) (zero_extend:DI
10990 (subreg:SI (mult:SI (match_dup 1)
10991 (match_dup 2)) 0)))]
10992{
10993 operands[1] = gen_lowpart (Pmode, operands[1]);
10994 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10995})
10996
10997;; This pattern can't accept a variable shift count, since shifts by
10998;; zero don't affect the flags. We assume that shifts by constant
10999;; zero are optimized away.
11000(define_insn "*ashlsi3_cmp"
11001 [(set (reg 17)
11002 (compare
11003 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11004 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11005 (const_int 0)))
11006 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11007 (ashift:SI (match_dup 1) (match_dup 2)))]
11008 "ix86_match_ccmode (insn, CCGOCmode)
11009 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11010{
11011 switch (get_attr_type (insn))
11012 {
11013 case TYPE_ALU:
11014 if (operands[2] != const1_rtx)
11015 abort ();
11016 return "add{l}\t{%0, %0|%0, %0}";
11017
11018 default:
11019 if (REG_P (operands[2]))
11020 return "sal{l}\t{%b2, %0|%0, %b2}";
11021 else if (GET_CODE (operands[2]) == CONST_INT
11022 && INTVAL (operands[2]) == 1
11023 && (TARGET_SHIFT1 || optimize_size))
11024 return "sal{l}\t%0";
11025 else
11026 return "sal{l}\t{%2, %0|%0, %2}";
11027 }
11028}
11029 [(set (attr "type")
11030 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11031 (const_int 0))
11032 (match_operand 0 "register_operand" ""))
11033 (match_operand 2 "const1_operand" ""))
11034 (const_string "alu")
11035 ]
11036 (const_string "ishift")))
11037 (set_attr "mode" "SI")])
11038
11039(define_insn "*ashlsi3_cmp_zext"
11040 [(set (reg 17)
11041 (compare
11042 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11043 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11044 (const_int 0)))
11045 (set (match_operand:DI 0 "register_operand" "=r")
11046 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11047 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11048 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11049{
11050 switch (get_attr_type (insn))
11051 {
11052 case TYPE_ALU:
11053 if (operands[2] != const1_rtx)
11054 abort ();
11055 return "add{l}\t{%k0, %k0|%k0, %k0}";
11056
11057 default:
11058 if (REG_P (operands[2]))
11059 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11060 else if (GET_CODE (operands[2]) == CONST_INT
11061 && INTVAL (operands[2]) == 1
11062 && (TARGET_SHIFT1 || optimize_size))
11063 return "sal{l}\t%k0";
11064 else
11065 return "sal{l}\t{%2, %k0|%k0, %2}";
11066 }
11067}
11068 [(set (attr "type")
11069 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11070 (const_int 0))
11071 (match_operand 2 "const1_operand" ""))
11072 (const_string "alu")
11073 ]
11074 (const_string "ishift")))
11075 (set_attr "mode" "SI")])
11076
11077(define_expand "ashlhi3"
11078 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11079 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11080 (match_operand:QI 2 "nonmemory_operand" "")))
11081 (clobber (reg:CC 17))]
11082 "TARGET_HIMODE_MATH"
11083 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11084
11085(define_insn "*ashlhi3_1_lea"
11086 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11087 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11088 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11089 (clobber (reg:CC 17))]
11090 "!TARGET_PARTIAL_REG_STALL
11091 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11092{
11093 switch (get_attr_type (insn))
11094 {
11095 case TYPE_LEA:
11096 return "#";
11097 case TYPE_ALU:
11098 if (operands[2] != const1_rtx)
11099 abort ();
11100 return "add{w}\t{%0, %0|%0, %0}";
11101
11102 default:
11103 if (REG_P (operands[2]))
11104 return "sal{w}\t{%b2, %0|%0, %b2}";
11105 else if (GET_CODE (operands[2]) == CONST_INT
11106 && INTVAL (operands[2]) == 1
11107 && (TARGET_SHIFT1 || optimize_size))
11108 return "sal{w}\t%0";
11109 else
11110 return "sal{w}\t{%2, %0|%0, %2}";
11111 }
11112}
11113 [(set (attr "type")
11114 (cond [(eq_attr "alternative" "1")
11115 (const_string "lea")
11116 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11117 (const_int 0))
11118 (match_operand 0 "register_operand" ""))
11119 (match_operand 2 "const1_operand" ""))
11120 (const_string "alu")
11121 ]
11122 (const_string "ishift")))
11123 (set_attr "mode" "HI,SI")])
11124
11125(define_insn "*ashlhi3_1"
11126 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11127 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11128 (match_operand:QI 2 "nonmemory_operand" "cI")))
11129 (clobber (reg:CC 17))]
11130 "TARGET_PARTIAL_REG_STALL
11131 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11132{
11133 switch (get_attr_type (insn))
11134 {
11135 case TYPE_ALU:
11136 if (operands[2] != const1_rtx)
11137 abort ();
11138 return "add{w}\t{%0, %0|%0, %0}";
11139
11140 default:
11141 if (REG_P (operands[2]))
11142 return "sal{w}\t{%b2, %0|%0, %b2}";
11143 else if (GET_CODE (operands[2]) == CONST_INT
11144 && INTVAL (operands[2]) == 1
11145 && (TARGET_SHIFT1 || optimize_size))
11146 return "sal{w}\t%0";
11147 else
11148 return "sal{w}\t{%2, %0|%0, %2}";
11149 }
11150}
11151 [(set (attr "type")
11152 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11153 (const_int 0))
11154 (match_operand 0 "register_operand" ""))
11155 (match_operand 2 "const1_operand" ""))
11156 (const_string "alu")
11157 ]
11158 (const_string "ishift")))
11159 (set_attr "mode" "HI")])
11160
11161;; This pattern can't accept a variable shift count, since shifts by
11162;; zero don't affect the flags. We assume that shifts by constant
11163;; zero are optimized away.
11164(define_insn "*ashlhi3_cmp"
11165 [(set (reg 17)
11166 (compare
11167 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11168 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11169 (const_int 0)))
11170 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11171 (ashift:HI (match_dup 1) (match_dup 2)))]
11172 "ix86_match_ccmode (insn, CCGOCmode)
11173 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11174{
11175 switch (get_attr_type (insn))
11176 {
11177 case TYPE_ALU:
11178 if (operands[2] != const1_rtx)
11179 abort ();
11180 return "add{w}\t{%0, %0|%0, %0}";
11181
11182 default:
11183 if (REG_P (operands[2]))
11184 return "sal{w}\t{%b2, %0|%0, %b2}";
11185 else if (GET_CODE (operands[2]) == CONST_INT
11186 && INTVAL (operands[2]) == 1
11187 && (TARGET_SHIFT1 || optimize_size))
11188 return "sal{w}\t%0";
11189 else
11190 return "sal{w}\t{%2, %0|%0, %2}";
11191 }
11192}
11193 [(set (attr "type")
11194 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11195 (const_int 0))
11196 (match_operand 0 "register_operand" ""))
11197 (match_operand 2 "const1_operand" ""))
11198 (const_string "alu")
11199 ]
11200 (const_string "ishift")))
11201 (set_attr "mode" "HI")])
11202
11203(define_expand "ashlqi3"
11204 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11205 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11206 (match_operand:QI 2 "nonmemory_operand" "")))
11207 (clobber (reg:CC 17))]
11208 "TARGET_QIMODE_MATH"
11209 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11210
11211;; %%% Potential partial reg stall on alternative 2. What to do?
11212
11213(define_insn "*ashlqi3_1_lea"
11214 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11215 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11216 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11217 (clobber (reg:CC 17))]
11218 "!TARGET_PARTIAL_REG_STALL
11219 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11220{
11221 switch (get_attr_type (insn))
11222 {
11223 case TYPE_LEA:
11224 return "#";
11225 case TYPE_ALU:
11226 if (operands[2] != const1_rtx)
11227 abort ();
11228 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11229 return "add{l}\t{%k0, %k0|%k0, %k0}";
11230 else
11231 return "add{b}\t{%0, %0|%0, %0}";
11232
11233 default:
11234 if (REG_P (operands[2]))
11235 {
11236 if (get_attr_mode (insn) == MODE_SI)
11237 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11238 else
11239 return "sal{b}\t{%b2, %0|%0, %b2}";
11240 }
11241 else if (GET_CODE (operands[2]) == CONST_INT
11242 && INTVAL (operands[2]) == 1
11243 && (TARGET_SHIFT1 || optimize_size))
11244 {
11245 if (get_attr_mode (insn) == MODE_SI)
11246 return "sal{l}\t%0";
11247 else
11248 return "sal{b}\t%0";
11249 }
11250 else
11251 {
11252 if (get_attr_mode (insn) == MODE_SI)
11253 return "sal{l}\t{%2, %k0|%k0, %2}";
11254 else
11255 return "sal{b}\t{%2, %0|%0, %2}";
11256 }
11257 }
11258}
11259 [(set (attr "type")
11260 (cond [(eq_attr "alternative" "2")
11261 (const_string "lea")
11262 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11263 (const_int 0))
11264 (match_operand 0 "register_operand" ""))
11265 (match_operand 2 "const1_operand" ""))
11266 (const_string "alu")
11267 ]
11268 (const_string "ishift")))
11269 (set_attr "mode" "QI,SI,SI")])
11270
11271(define_insn "*ashlqi3_1"
11272 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11273 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11274 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11275 (clobber (reg:CC 17))]
11276 "TARGET_PARTIAL_REG_STALL
11277 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11278{
11279 switch (get_attr_type (insn))
11280 {
11281 case TYPE_ALU:
11282 if (operands[2] != const1_rtx)
11283 abort ();
11284 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11285 return "add{l}\t{%k0, %k0|%k0, %k0}";
11286 else
11287 return "add{b}\t{%0, %0|%0, %0}";
11288
11289 default:
11290 if (REG_P (operands[2]))
11291 {
11292 if (get_attr_mode (insn) == MODE_SI)
11293 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11294 else
11295 return "sal{b}\t{%b2, %0|%0, %b2}";
11296 }
11297 else if (GET_CODE (operands[2]) == CONST_INT
11298 && INTVAL (operands[2]) == 1
11299 && (TARGET_SHIFT1 || optimize_size))
11300 {
11301 if (get_attr_mode (insn) == MODE_SI)
11302 return "sal{l}\t%0";
11303 else
11304 return "sal{b}\t%0";
11305 }
11306 else
11307 {
11308 if (get_attr_mode (insn) == MODE_SI)
11309 return "sal{l}\t{%2, %k0|%k0, %2}";
11310 else
11311 return "sal{b}\t{%2, %0|%0, %2}";
11312 }
11313 }
11314}
11315 [(set (attr "type")
11316 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11317 (const_int 0))
11318 (match_operand 0 "register_operand" ""))
11319 (match_operand 2 "const1_operand" ""))
11320 (const_string "alu")
11321 ]
11322 (const_string "ishift")))
11323 (set_attr "mode" "QI,SI")])
11324
11325;; This pattern can't accept a variable shift count, since shifts by
11326;; zero don't affect the flags. We assume that shifts by constant
11327;; zero are optimized away.
11328(define_insn "*ashlqi3_cmp"
11329 [(set (reg 17)
11330 (compare
11331 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11332 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11333 (const_int 0)))
11334 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11335 (ashift:QI (match_dup 1) (match_dup 2)))]
11336 "ix86_match_ccmode (insn, CCGOCmode)
11337 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11338{
11339 switch (get_attr_type (insn))
11340 {
11341 case TYPE_ALU:
11342 if (operands[2] != const1_rtx)
11343 abort ();
11344 return "add{b}\t{%0, %0|%0, %0}";
11345
11346 default:
11347 if (REG_P (operands[2]))
11348 return "sal{b}\t{%b2, %0|%0, %b2}";
11349 else if (GET_CODE (operands[2]) == CONST_INT
11350 && INTVAL (operands[2]) == 1
11351 && (TARGET_SHIFT1 || optimize_size))
11352 return "sal{b}\t%0";
11353 else
11354 return "sal{b}\t{%2, %0|%0, %2}";
11355 }
11356}
11357 [(set (attr "type")
11358 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11359 (const_int 0))
11360 (match_operand 0 "register_operand" ""))
11361 (match_operand 2 "const1_operand" ""))
11362 (const_string "alu")
11363 ]
11364 (const_string "ishift")))
11365 (set_attr "mode" "QI")])
11366
11367;; See comment above `ashldi3' about how this works.
11368
11369(define_expand "ashrdi3"
11370 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11371 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11372 (match_operand:QI 2 "nonmemory_operand" "")))
11373 (clobber (reg:CC 17))])]
11374 ""
11375{
11376 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11377 {
11378 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11379 DONE;
11380 }
11381 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11382 DONE;
11383})
11384
11385(define_insn "ashrdi3_63_rex64"
11386 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11387 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11388 (match_operand:DI 2 "const_int_operand" "i,i")))
11389 (clobber (reg:CC 17))]
11390 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11391 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11392 "@
11393 {cqto|cqo}
11394 sar{q}\t{%2, %0|%0, %2}"
11395 [(set_attr "type" "imovx,ishift")
11396 (set_attr "prefix_0f" "0,*")
11397 (set_attr "length_immediate" "0,*")
11398 (set_attr "modrm" "0,1")
11399 (set_attr "mode" "DI")])
11400
11401(define_insn "*ashrdi3_1_one_bit_rex64"
11402 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11403 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404 (match_operand:QI 2 "const1_operand" "")))
11405 (clobber (reg:CC 17))]
11406 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11407 && (TARGET_SHIFT1 || optimize_size)"
11408 "sar{q}\t%0"
11409 [(set_attr "type" "ishift")
11410 (set (attr "length")
11411 (if_then_else (match_operand:DI 0 "register_operand" "")
11412 (const_string "2")
11413 (const_string "*")))])
11414
11415(define_insn "*ashrdi3_1_rex64"
11416 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11417 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11418 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11419 (clobber (reg:CC 17))]
11420 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11421 "@
11422 sar{q}\t{%2, %0|%0, %2}
11423 sar{q}\t{%b2, %0|%0, %b2}"
11424 [(set_attr "type" "ishift")
11425 (set_attr "mode" "DI")])
11426
11427;; This pattern can't accept a variable shift count, since shifts by
11428;; zero don't affect the flags. We assume that shifts by constant
11429;; zero are optimized away.
11430(define_insn "*ashrdi3_one_bit_cmp_rex64"
11431 [(set (reg 17)
11432 (compare
11433 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434 (match_operand:QI 2 "const1_operand" ""))
11435 (const_int 0)))
11436 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439 && (TARGET_SHIFT1 || optimize_size)
11440 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11441 "sar{q}\t%0"
11442 [(set_attr "type" "ishift")
11443 (set (attr "length")
11444 (if_then_else (match_operand:DI 0 "register_operand" "")
11445 (const_string "2")
11446 (const_string "*")))])
11447
11448;; This pattern can't accept a variable shift count, since shifts by
11449;; zero don't affect the flags. We assume that shifts by constant
11450;; zero are optimized away.
11451(define_insn "*ashrdi3_cmp_rex64"
11452 [(set (reg 17)
11453 (compare
11454 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11455 (match_operand:QI 2 "const_int_operand" "n"))
11456 (const_int 0)))
11457 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11458 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11459 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11460 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11461 "sar{q}\t{%2, %0|%0, %2}"
11462 [(set_attr "type" "ishift")
11463 (set_attr "mode" "DI")])
11464
11465
11466(define_insn "ashrdi3_1"
11467 [(set (match_operand:DI 0 "register_operand" "=r")
11468 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11469 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11470 (clobber (match_scratch:SI 3 "=&r"))
11471 (clobber (reg:CC 17))]
11472 "!TARGET_64BIT && TARGET_CMOVE"
11473 "#"
11474 [(set_attr "type" "multi")])
11475
11476(define_insn "*ashrdi3_2"
11477 [(set (match_operand:DI 0 "register_operand" "=r")
11478 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11479 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11480 (clobber (reg:CC 17))]
11481 "!TARGET_64BIT"
11482 "#"
11483 [(set_attr "type" "multi")])
11484
11485(define_split
11486 [(set (match_operand:DI 0 "register_operand" "")
11487 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11488 (match_operand:QI 2 "nonmemory_operand" "")))
11489 (clobber (match_scratch:SI 3 ""))
11490 (clobber (reg:CC 17))]
11491 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11492 [(const_int 0)]
11493 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11494
11495(define_split
11496 [(set (match_operand:DI 0 "register_operand" "")
11497 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11498 (match_operand:QI 2 "nonmemory_operand" "")))
11499 (clobber (reg:CC 17))]
11500 "!TARGET_64BIT && reload_completed"
11501 [(const_int 0)]
11502 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11503
11504(define_insn "x86_shrd_1"
11505 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11506 (ior:SI (ashiftrt:SI (match_dup 0)
11507 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11508 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11509 (minus:QI (const_int 32) (match_dup 2)))))
11510 (clobber (reg:CC 17))]
11511 ""
11512 "@
11513 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11514 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11515 [(set_attr "type" "ishift")
11516 (set_attr "prefix_0f" "1")
11517 (set_attr "pent_pair" "np")
11518 (set_attr "ppro_uops" "few")
11519 (set_attr "mode" "SI")])
11520
11521(define_expand "x86_shift_adj_3"
11522 [(use (match_operand:SI 0 "register_operand" ""))
11523 (use (match_operand:SI 1 "register_operand" ""))
11524 (use (match_operand:QI 2 "register_operand" ""))]
11525 ""
11526{
11527 rtx label = gen_label_rtx ();
11528 rtx tmp;
11529
11530 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11531
11532 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11533 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11534 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11535 gen_rtx_LABEL_REF (VOIDmode, label),
11536 pc_rtx);
11537 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11538 JUMP_LABEL (tmp) = label;
11539
11540 emit_move_insn (operands[0], operands[1]);
11541 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11542
11543 emit_label (label);
11544 LABEL_NUSES (label) = 1;
11545
11546 DONE;
11547})
11548
11549(define_insn "ashrsi3_31"
11550 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11551 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11552 (match_operand:SI 2 "const_int_operand" "i,i")))
11553 (clobber (reg:CC 17))]
11554 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11555 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11556 "@
11557 {cltd|cdq}
11558 sar{l}\t{%2, %0|%0, %2}"
11559 [(set_attr "type" "imovx,ishift")
11560 (set_attr "prefix_0f" "0,*")
11561 (set_attr "length_immediate" "0,*")
11562 (set_attr "modrm" "0,1")
11563 (set_attr "mode" "SI")])
11564
11565(define_insn "*ashrsi3_31_zext"
11566 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11567 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11568 (match_operand:SI 2 "const_int_operand" "i,i"))))
11569 (clobber (reg:CC 17))]
11570 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11571 && INTVAL (operands[2]) == 31
11572 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11573 "@
11574 {cltd|cdq}
11575 sar{l}\t{%2, %k0|%k0, %2}"
11576 [(set_attr "type" "imovx,ishift")
11577 (set_attr "prefix_0f" "0,*")
11578 (set_attr "length_immediate" "0,*")
11579 (set_attr "modrm" "0,1")
11580 (set_attr "mode" "SI")])
11581
11582(define_expand "ashrsi3"
11583 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11584 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11585 (match_operand:QI 2 "nonmemory_operand" "")))
11586 (clobber (reg:CC 17))]
11587 ""
11588 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11589
11590(define_insn "*ashrsi3_1_one_bit"
11591 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11592 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11593 (match_operand:QI 2 "const1_operand" "")))
11594 (clobber (reg:CC 17))]
11595 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11596 && (TARGET_SHIFT1 || optimize_size)"
11597 "sar{l}\t%0"
11598 [(set_attr "type" "ishift")
11599 (set (attr "length")
11600 (if_then_else (match_operand:SI 0 "register_operand" "")
11601 (const_string "2")
11602 (const_string "*")))])
11603
11604(define_insn "*ashrsi3_1_one_bit_zext"
11605 [(set (match_operand:DI 0 "register_operand" "=r")
11606 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11607 (match_operand:QI 2 "const1_operand" ""))))
11608 (clobber (reg:CC 17))]
11609 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11610 && (TARGET_SHIFT1 || optimize_size)"
11611 "sar{l}\t%k0"
11612 [(set_attr "type" "ishift")
11613 (set_attr "length" "2")])
11614
11615(define_insn "*ashrsi3_1"
11616 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11617 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11618 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11619 (clobber (reg:CC 17))]
11620 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11621 "@
11622 sar{l}\t{%2, %0|%0, %2}
11623 sar{l}\t{%b2, %0|%0, %b2}"
11624 [(set_attr "type" "ishift")
11625 (set_attr "mode" "SI")])
11626
11627(define_insn "*ashrsi3_1_zext"
11628 [(set (match_operand:DI 0 "register_operand" "=r,r")
11629 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11630 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11631 (clobber (reg:CC 17))]
11632 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11633 "@
11634 sar{l}\t{%2, %k0|%k0, %2}
11635 sar{l}\t{%b2, %k0|%k0, %b2}"
11636 [(set_attr "type" "ishift")
11637 (set_attr "mode" "SI")])
11638
11639;; This pattern can't accept a variable shift count, since shifts by
11640;; zero don't affect the flags. We assume that shifts by constant
11641;; zero are optimized away.
11642(define_insn "*ashrsi3_one_bit_cmp"
11643 [(set (reg 17)
11644 (compare
11645 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11646 (match_operand:QI 2 "const1_operand" ""))
11647 (const_int 0)))
11648 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11649 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11650 "ix86_match_ccmode (insn, CCGOCmode)
11651 && (TARGET_SHIFT1 || optimize_size)
11652 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653 "sar{l}\t%0"
11654 [(set_attr "type" "ishift")
11655 (set (attr "length")
11656 (if_then_else (match_operand:SI 0 "register_operand" "")
11657 (const_string "2")
11658 (const_string "*")))])
11659
11660(define_insn "*ashrsi3_one_bit_cmp_zext"
11661 [(set (reg 17)
11662 (compare
11663 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11664 (match_operand:QI 2 "const1_operand" ""))
11665 (const_int 0)))
11666 (set (match_operand:DI 0 "register_operand" "=r")
11667 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11668 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11669 && (TARGET_SHIFT1 || optimize_size)
11670 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11671 "sar{l}\t%k0"
11672 [(set_attr "type" "ishift")
11673 (set_attr "length" "2")])
11674
11675;; This pattern can't accept a variable shift count, since shifts by
11676;; zero don't affect the flags. We assume that shifts by constant
11677;; zero are optimized away.
11678(define_insn "*ashrsi3_cmp"
11679 [(set (reg 17)
11680 (compare
11681 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11683 (const_int 0)))
11684 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11685 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11686 "ix86_match_ccmode (insn, CCGOCmode)
11687 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11688 "sar{l}\t{%2, %0|%0, %2}"
11689 [(set_attr "type" "ishift")
11690 (set_attr "mode" "SI")])
11691
11692(define_insn "*ashrsi3_cmp_zext"
11693 [(set (reg 17)
11694 (compare
11695 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11696 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11697 (const_int 0)))
11698 (set (match_operand:DI 0 "register_operand" "=r")
11699 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11700 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11702 "sar{l}\t{%2, %k0|%k0, %2}"
11703 [(set_attr "type" "ishift")
11704 (set_attr "mode" "SI")])
11705
11706(define_expand "ashrhi3"
11707 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709 (match_operand:QI 2 "nonmemory_operand" "")))
11710 (clobber (reg:CC 17))]
11711 "TARGET_HIMODE_MATH"
11712 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11713
11714(define_insn "*ashrhi3_1_one_bit"
11715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11716 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717 (match_operand:QI 2 "const1_operand" "")))
11718 (clobber (reg:CC 17))]
11719 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11720 && (TARGET_SHIFT1 || optimize_size)"
11721 "sar{w}\t%0"
11722 [(set_attr "type" "ishift")
11723 (set (attr "length")
11724 (if_then_else (match_operand 0 "register_operand" "")
11725 (const_string "2")
11726 (const_string "*")))])
11727
11728(define_insn "*ashrhi3_1"
11729 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11730 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11731 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11732 (clobber (reg:CC 17))]
11733 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11734 "@
11735 sar{w}\t{%2, %0|%0, %2}
11736 sar{w}\t{%b2, %0|%0, %b2}"
11737 [(set_attr "type" "ishift")
11738 (set_attr "mode" "HI")])
11739
11740;; This pattern can't accept a variable shift count, since shifts by
11741;; zero don't affect the flags. We assume that shifts by constant
11742;; zero are optimized away.
11743(define_insn "*ashrhi3_one_bit_cmp"
11744 [(set (reg 17)
11745 (compare
11746 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747 (match_operand:QI 2 "const1_operand" ""))
11748 (const_int 0)))
11749 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11750 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11751 "ix86_match_ccmode (insn, CCGOCmode)
11752 && (TARGET_SHIFT1 || optimize_size)
11753 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11754 "sar{w}\t%0"
11755 [(set_attr "type" "ishift")
11756 (set (attr "length")
11757 (if_then_else (match_operand 0 "register_operand" "")
11758 (const_string "2")
11759 (const_string "*")))])
11760
11761;; This pattern can't accept a variable shift count, since shifts by
11762;; zero don't affect the flags. We assume that shifts by constant
11763;; zero are optimized away.
11764(define_insn "*ashrhi3_cmp"
11765 [(set (reg 17)
11766 (compare
11767 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11768 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11769 (const_int 0)))
11770 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11771 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11772 "ix86_match_ccmode (insn, CCGOCmode)
11773 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11774 "sar{w}\t{%2, %0|%0, %2}"
11775 [(set_attr "type" "ishift")
11776 (set_attr "mode" "HI")])
11777
11778(define_expand "ashrqi3"
11779 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11780 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11781 (match_operand:QI 2 "nonmemory_operand" "")))
11782 (clobber (reg:CC 17))]
11783 "TARGET_QIMODE_MATH"
11784 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11785
11786(define_insn "*ashrqi3_1_one_bit"
11787 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789 (match_operand:QI 2 "const1_operand" "")))
11790 (clobber (reg:CC 17))]
11791 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11792 && (TARGET_SHIFT1 || optimize_size)"
11793 "sar{b}\t%0"
11794 [(set_attr "type" "ishift")
11795 (set (attr "length")
11796 (if_then_else (match_operand 0 "register_operand" "")
11797 (const_string "2")
11798 (const_string "*")))])
11799
11800(define_insn "*ashrqi3_1_one_bit_slp"
11801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11802 (ashiftrt:QI (match_dup 0)
11803 (match_operand:QI 1 "const1_operand" "")))
11804 (clobber (reg:CC 17))]
11805 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11806 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11807 && (TARGET_SHIFT1 || optimize_size)"
11808 "sar{b}\t%0"
11809 [(set_attr "type" "ishift1")
11810 (set (attr "length")
11811 (if_then_else (match_operand 0 "register_operand" "")
11812 (const_string "2")
11813 (const_string "*")))])
11814
11815(define_insn "*ashrqi3_1"
11816 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11817 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11818 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11819 (clobber (reg:CC 17))]
11820 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11821 "@
11822 sar{b}\t{%2, %0|%0, %2}
11823 sar{b}\t{%b2, %0|%0, %b2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "QI")])
11826
11827(define_insn "*ashrqi3_1_slp"
11828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11829 (ashiftrt:QI (match_dup 0)
11830 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11831 (clobber (reg:CC 17))]
11832 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11834 "@
11835 sar{b}\t{%1, %0|%0, %1}
11836 sar{b}\t{%b1, %0|%0, %b1}"
11837 [(set_attr "type" "ishift1")
11838 (set_attr "mode" "QI")])
11839
11840;; This pattern can't accept a variable shift count, since shifts by
11841;; zero don't affect the flags. We assume that shifts by constant
11842;; zero are optimized away.
11843(define_insn "*ashrqi3_one_bit_cmp"
11844 [(set (reg 17)
11845 (compare
11846 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11847 (match_operand:QI 2 "const1_operand" "I"))
11848 (const_int 0)))
11849 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11850 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11851 "ix86_match_ccmode (insn, CCGOCmode)
11852 && (TARGET_SHIFT1 || optimize_size)
11853 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11854 "sar{b}\t%0"
11855 [(set_attr "type" "ishift")
11856 (set (attr "length")
11857 (if_then_else (match_operand 0 "register_operand" "")
11858 (const_string "2")
11859 (const_string "*")))])
11860
11861;; This pattern can't accept a variable shift count, since shifts by
11862;; zero don't affect the flags. We assume that shifts by constant
11863;; zero are optimized away.
11864(define_insn "*ashrqi3_cmp"
11865 [(set (reg 17)
11866 (compare
11867 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11868 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11869 (const_int 0)))
11870 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11871 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11872 "ix86_match_ccmode (insn, CCGOCmode)
11873 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11874 "sar{b}\t{%2, %0|%0, %2}"
11875 [(set_attr "type" "ishift")
11876 (set_attr "mode" "QI")])
11877
11878;; Logical shift instructions
11879
11880;; See comment above `ashldi3' about how this works.
11881
11882(define_expand "lshrdi3"
11883 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11884 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11885 (match_operand:QI 2 "nonmemory_operand" "")))
11886 (clobber (reg:CC 17))])]
11887 ""
11888{
11889 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11890 {
11891 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11892 DONE;
11893 }
11894 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11895 DONE;
11896})
11897
11898(define_insn "*lshrdi3_1_one_bit_rex64"
11899 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11900 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11901 (match_operand:QI 2 "const1_operand" "")))
11902 (clobber (reg:CC 17))]
11903 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11904 && (TARGET_SHIFT1 || optimize_size)"
11905 "shr{q}\t%0"
11906 [(set_attr "type" "ishift")
11907 (set (attr "length")
11908 (if_then_else (match_operand:DI 0 "register_operand" "")
11909 (const_string "2")
11910 (const_string "*")))])
11911
11912(define_insn "*lshrdi3_1_rex64"
11913 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11914 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11915 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11916 (clobber (reg:CC 17))]
11917 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11918 "@
11919 shr{q}\t{%2, %0|%0, %2}
11920 shr{q}\t{%b2, %0|%0, %b2}"
11921 [(set_attr "type" "ishift")
11922 (set_attr "mode" "DI")])
11923
11924;; This pattern can't accept a variable shift count, since shifts by
11925;; zero don't affect the flags. We assume that shifts by constant
11926;; zero are optimized away.
11927(define_insn "*lshrdi3_cmp_one_bit_rex64"
11928 [(set (reg 17)
11929 (compare
11930 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11931 (match_operand:QI 2 "const1_operand" ""))
11932 (const_int 0)))
11933 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11934 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11935 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11936 && (TARGET_SHIFT1 || optimize_size)
11937 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11938 "shr{q}\t%0"
11939 [(set_attr "type" "ishift")
11940 (set (attr "length")
11941 (if_then_else (match_operand:DI 0 "register_operand" "")
11942 (const_string "2")
11943 (const_string "*")))])
11944
11945;; This pattern can't accept a variable shift count, since shifts by
11946;; zero don't affect the flags. We assume that shifts by constant
11947;; zero are optimized away.
11948(define_insn "*lshrdi3_cmp_rex64"
11949 [(set (reg 17)
11950 (compare
11951 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11952 (match_operand:QI 2 "const_int_operand" "e"))
11953 (const_int 0)))
11954 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11955 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11956 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11957 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11958 "shr{q}\t{%2, %0|%0, %2}"
11959 [(set_attr "type" "ishift")
11960 (set_attr "mode" "DI")])
11961
11962(define_insn "lshrdi3_1"
11963 [(set (match_operand:DI 0 "register_operand" "=r")
11964 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11965 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11966 (clobber (match_scratch:SI 3 "=&r"))
11967 (clobber (reg:CC 17))]
11968 "!TARGET_64BIT && TARGET_CMOVE"
11969 "#"
11970 [(set_attr "type" "multi")])
11971
11972(define_insn "*lshrdi3_2"
11973 [(set (match_operand:DI 0 "register_operand" "=r")
11974 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11975 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11976 (clobber (reg:CC 17))]
11977 "!TARGET_64BIT"
11978 "#"
11979 [(set_attr "type" "multi")])
11980
11981(define_split
11982 [(set (match_operand:DI 0 "register_operand" "")
11983 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11984 (match_operand:QI 2 "nonmemory_operand" "")))
11985 (clobber (match_scratch:SI 3 ""))
11986 (clobber (reg:CC 17))]
11987 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11988 [(const_int 0)]
11989 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11990
11991(define_split
11992 [(set (match_operand:DI 0 "register_operand" "")
11993 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11994 (match_operand:QI 2 "nonmemory_operand" "")))
11995 (clobber (reg:CC 17))]
11996 "!TARGET_64BIT && reload_completed"
11997 [(const_int 0)]
11998 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11999
12000(define_expand "lshrsi3"
12001 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12002 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12003 (match_operand:QI 2 "nonmemory_operand" "")))
12004 (clobber (reg:CC 17))]
12005 ""
12006 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12007
12008(define_insn "*lshrsi3_1_one_bit"
12009 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12010 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12011 (match_operand:QI 2 "const1_operand" "")))
12012 (clobber (reg:CC 17))]
12013 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12014 && (TARGET_SHIFT1 || optimize_size)"
12015 "shr{l}\t%0"
12016 [(set_attr "type" "ishift")
12017 (set (attr "length")
12018 (if_then_else (match_operand:SI 0 "register_operand" "")
12019 (const_string "2")
12020 (const_string "*")))])
12021
12022(define_insn "*lshrsi3_1_one_bit_zext"
12023 [(set (match_operand:DI 0 "register_operand" "=r")
12024 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12025 (match_operand:QI 2 "const1_operand" "")))
12026 (clobber (reg:CC 17))]
12027 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12028 && (TARGET_SHIFT1 || optimize_size)"
12029 "shr{l}\t%k0"
12030 [(set_attr "type" "ishift")
12031 (set_attr "length" "2")])
12032
12033(define_insn "*lshrsi3_1"
12034 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12035 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12036 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12037 (clobber (reg:CC 17))]
12038 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12039 "@
12040 shr{l}\t{%2, %0|%0, %2}
12041 shr{l}\t{%b2, %0|%0, %b2}"
12042 [(set_attr "type" "ishift")
12043 (set_attr "mode" "SI")])
12044
12045(define_insn "*lshrsi3_1_zext"
12046 [(set (match_operand:DI 0 "register_operand" "=r,r")
12047 (zero_extend:DI
12048 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12049 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12050 (clobber (reg:CC 17))]
12051 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12052 "@
12053 shr{l}\t{%2, %k0|%k0, %2}
12054 shr{l}\t{%b2, %k0|%k0, %b2}"
12055 [(set_attr "type" "ishift")
12056 (set_attr "mode" "SI")])
12057
12058;; This pattern can't accept a variable shift count, since shifts by
12059;; zero don't affect the flags. We assume that shifts by constant
12060;; zero are optimized away.
12061(define_insn "*lshrsi3_one_bit_cmp"
12062 [(set (reg 17)
12063 (compare
12064 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12065 (match_operand:QI 2 "const1_operand" ""))
12066 (const_int 0)))
12067 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12068 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12069 "ix86_match_ccmode (insn, CCGOCmode)
12070 && (TARGET_SHIFT1 || optimize_size)
12071 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12072 "shr{l}\t%0"
12073 [(set_attr "type" "ishift")
12074 (set (attr "length")
12075 (if_then_else (match_operand:SI 0 "register_operand" "")
12076 (const_string "2")
12077 (const_string "*")))])
12078
12079(define_insn "*lshrsi3_cmp_one_bit_zext"
12080 [(set (reg 17)
12081 (compare
12082 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12083 (match_operand:QI 2 "const1_operand" ""))
12084 (const_int 0)))
12085 (set (match_operand:DI 0 "register_operand" "=r")
12086 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12087 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12088 && (TARGET_SHIFT1 || optimize_size)
12089 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12090 "shr{l}\t%k0"
12091 [(set_attr "type" "ishift")
12092 (set_attr "length" "2")])
12093
12094;; This pattern can't accept a variable shift count, since shifts by
12095;; zero don't affect the flags. We assume that shifts by constant
12096;; zero are optimized away.
12097(define_insn "*lshrsi3_cmp"
12098 [(set (reg 17)
12099 (compare
12100 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12101 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12102 (const_int 0)))
12103 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12104 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12105 "ix86_match_ccmode (insn, CCGOCmode)
12106 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12107 "shr{l}\t{%2, %0|%0, %2}"
12108 [(set_attr "type" "ishift")
12109 (set_attr "mode" "SI")])
12110
12111(define_insn "*lshrsi3_cmp_zext"
12112 [(set (reg 17)
12113 (compare
12114 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12115 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12116 (const_int 0)))
12117 (set (match_operand:DI 0 "register_operand" "=r")
12118 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12119 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12120 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12121 "shr{l}\t{%2, %k0|%k0, %2}"
12122 [(set_attr "type" "ishift")
12123 (set_attr "mode" "SI")])
12124
12125(define_expand "lshrhi3"
12126 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12127 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12128 (match_operand:QI 2 "nonmemory_operand" "")))
12129 (clobber (reg:CC 17))]
12130 "TARGET_HIMODE_MATH"
12131 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12132
12133(define_insn "*lshrhi3_1_one_bit"
12134 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12135 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136 (match_operand:QI 2 "const1_operand" "")))
12137 (clobber (reg:CC 17))]
12138 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12139 && (TARGET_SHIFT1 || optimize_size)"
12140 "shr{w}\t%0"
12141 [(set_attr "type" "ishift")
12142 (set (attr "length")
12143 (if_then_else (match_operand 0 "register_operand" "")
12144 (const_string "2")
12145 (const_string "*")))])
12146
12147(define_insn "*lshrhi3_1"
12148 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12149 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12150 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12151 (clobber (reg:CC 17))]
12152 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12153 "@
12154 shr{w}\t{%2, %0|%0, %2}
12155 shr{w}\t{%b2, %0|%0, %b2}"
12156 [(set_attr "type" "ishift")
12157 (set_attr "mode" "HI")])
12158
12159;; This pattern can't accept a variable shift count, since shifts by
12160;; zero don't affect the flags. We assume that shifts by constant
12161;; zero are optimized away.
12162(define_insn "*lshrhi3_one_bit_cmp"
12163 [(set (reg 17)
12164 (compare
12165 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12166 (match_operand:QI 2 "const1_operand" ""))
12167 (const_int 0)))
12168 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12169 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12170 "ix86_match_ccmode (insn, CCGOCmode)
12171 && (TARGET_SHIFT1 || optimize_size)
12172 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12173 "shr{w}\t%0"
12174 [(set_attr "type" "ishift")
12175 (set (attr "length")
12176 (if_then_else (match_operand:SI 0 "register_operand" "")
12177 (const_string "2")
12178 (const_string "*")))])
12179
12180;; This pattern can't accept a variable shift count, since shifts by
12181;; zero don't affect the flags. We assume that shifts by constant
12182;; zero are optimized away.
12183(define_insn "*lshrhi3_cmp"
12184 [(set (reg 17)
12185 (compare
12186 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12187 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12188 (const_int 0)))
12189 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12190 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12191 "ix86_match_ccmode (insn, CCGOCmode)
12192 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12193 "shr{w}\t{%2, %0|%0, %2}"
12194 [(set_attr "type" "ishift")
12195 (set_attr "mode" "HI")])
12196
12197(define_expand "lshrqi3"
12198 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12199 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12200 (match_operand:QI 2 "nonmemory_operand" "")))
12201 (clobber (reg:CC 17))]
12202 "TARGET_QIMODE_MATH"
12203 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12204
12205(define_insn "*lshrqi3_1_one_bit"
12206 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12207 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12208 (match_operand:QI 2 "const1_operand" "")))
12209 (clobber (reg:CC 17))]
12210 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12211 && (TARGET_SHIFT1 || optimize_size)"
12212 "shr{b}\t%0"
12213 [(set_attr "type" "ishift")
12214 (set (attr "length")
12215 (if_then_else (match_operand 0 "register_operand" "")
12216 (const_string "2")
12217 (const_string "*")))])
12218
12219(define_insn "*lshrqi3_1_one_bit_slp"
12220 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221 (lshiftrt:QI (match_dup 0)
12222 (match_operand:QI 1 "const1_operand" "")))
12223 (clobber (reg:CC 17))]
12224 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225 && (TARGET_SHIFT1 || optimize_size)"
12226 "shr{b}\t%0"
12227 [(set_attr "type" "ishift1")
12228 (set (attr "length")
12229 (if_then_else (match_operand 0 "register_operand" "")
12230 (const_string "2")
12231 (const_string "*")))])
12232
12233(define_insn "*lshrqi3_1"
12234 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12235 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12236 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12237 (clobber (reg:CC 17))]
12238 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12239 "@
12240 shr{b}\t{%2, %0|%0, %2}
12241 shr{b}\t{%b2, %0|%0, %b2}"
12242 [(set_attr "type" "ishift")
12243 (set_attr "mode" "QI")])
12244
12245(define_insn "*lshrqi3_1_slp"
12246 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12247 (lshiftrt:QI (match_dup 0)
12248 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12249 (clobber (reg:CC 17))]
12250 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12251 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12252 "@
12253 shr{b}\t{%1, %0|%0, %1}
12254 shr{b}\t{%b1, %0|%0, %b1}"
12255 [(set_attr "type" "ishift1")
12256 (set_attr "mode" "QI")])
12257
12258;; This pattern can't accept a variable shift count, since shifts by
12259;; zero don't affect the flags. We assume that shifts by constant
12260;; zero are optimized away.
12261(define_insn "*lshrqi2_one_bit_cmp"
12262 [(set (reg 17)
12263 (compare
12264 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12265 (match_operand:QI 2 "const1_operand" ""))
12266 (const_int 0)))
12267 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12268 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12269 "ix86_match_ccmode (insn, CCGOCmode)
12270 && (TARGET_SHIFT1 || optimize_size)
12271 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12272 "shr{b}\t%0"
12273 [(set_attr "type" "ishift")
12274 (set (attr "length")
12275 (if_then_else (match_operand:SI 0 "register_operand" "")
12276 (const_string "2")
12277 (const_string "*")))])
12278
12279;; This pattern can't accept a variable shift count, since shifts by
12280;; zero don't affect the flags. We assume that shifts by constant
12281;; zero are optimized away.
12282(define_insn "*lshrqi2_cmp"
12283 [(set (reg 17)
12284 (compare
12285 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12286 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12287 (const_int 0)))
12288 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12289 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12290 "ix86_match_ccmode (insn, CCGOCmode)
12291 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12292 "shr{b}\t{%2, %0|%0, %2}"
12293 [(set_attr "type" "ishift")
12294 (set_attr "mode" "QI")])
12295
12296;; Rotate instructions
12297
12298(define_expand "rotldi3"
12299 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12300 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12301 (match_operand:QI 2 "nonmemory_operand" "")))
12302 (clobber (reg:CC 17))]
12303 "TARGET_64BIT"
12304 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12305
12306(define_insn "*rotlsi3_1_one_bit_rex64"
12307 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12308 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12309 (match_operand:QI 2 "const1_operand" "")))
12310 (clobber (reg:CC 17))]
12311 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12312 && (TARGET_SHIFT1 || optimize_size)"
12313 "rol{q}\t%0"
12314 [(set_attr "type" "rotate")
12315 (set (attr "length")
12316 (if_then_else (match_operand:DI 0 "register_operand" "")
12317 (const_string "2")
12318 (const_string "*")))])
12319
12320(define_insn "*rotldi3_1_rex64"
12321 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12322 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12323 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12324 (clobber (reg:CC 17))]
12325 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12326 "@
12327 rol{q}\t{%2, %0|%0, %2}
12328 rol{q}\t{%b2, %0|%0, %b2}"
12329 [(set_attr "type" "rotate")
12330 (set_attr "mode" "DI")])
12331
12332(define_expand "rotlsi3"
12333 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12334 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12335 (match_operand:QI 2 "nonmemory_operand" "")))
12336 (clobber (reg:CC 17))]
12337 ""
12338 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12339
12340(define_insn "*rotlsi3_1_one_bit"
12341 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12342 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12343 (match_operand:QI 2 "const1_operand" "")))
12344 (clobber (reg:CC 17))]
12345 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12346 && (TARGET_SHIFT1 || optimize_size)"
12347 "rol{l}\t%0"
12348 [(set_attr "type" "rotate")
12349 (set (attr "length")
12350 (if_then_else (match_operand:SI 0 "register_operand" "")
12351 (const_string "2")
12352 (const_string "*")))])
12353
12354(define_insn "*rotlsi3_1_one_bit_zext"
12355 [(set (match_operand:DI 0 "register_operand" "=r")
12356 (zero_extend:DI
12357 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12358 (match_operand:QI 2 "const1_operand" ""))))
12359 (clobber (reg:CC 17))]
12360 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12361 && (TARGET_SHIFT1 || optimize_size)"
12362 "rol{l}\t%k0"
12363 [(set_attr "type" "rotate")
12364 (set_attr "length" "2")])
12365
12366(define_insn "*rotlsi3_1"
12367 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12368 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12369 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12370 (clobber (reg:CC 17))]
12371 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12372 "@
12373 rol{l}\t{%2, %0|%0, %2}
12374 rol{l}\t{%b2, %0|%0, %b2}"
12375 [(set_attr "type" "rotate")
12376 (set_attr "mode" "SI")])
12377
12378(define_insn "*rotlsi3_1_zext"
12379 [(set (match_operand:DI 0 "register_operand" "=r,r")
12380 (zero_extend:DI
12381 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12382 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12383 (clobber (reg:CC 17))]
12384 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12385 "@
12386 rol{l}\t{%2, %k0|%k0, %2}
12387 rol{l}\t{%b2, %k0|%k0, %b2}"
12388 [(set_attr "type" "rotate")
12389 (set_attr "mode" "SI")])
12390
12391(define_expand "rotlhi3"
12392 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12393 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12394 (match_operand:QI 2 "nonmemory_operand" "")))
12395 (clobber (reg:CC 17))]
12396 "TARGET_HIMODE_MATH"
12397 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12398
12399(define_insn "*rotlhi3_1_one_bit"
12400 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402 (match_operand:QI 2 "const1_operand" "")))
12403 (clobber (reg:CC 17))]
12404 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12405 && (TARGET_SHIFT1 || optimize_size)"
12406 "rol{w}\t%0"
12407 [(set_attr "type" "rotate")
12408 (set (attr "length")
12409 (if_then_else (match_operand 0 "register_operand" "")
12410 (const_string "2")
12411 (const_string "*")))])
12412
12413(define_insn "*rotlhi3_1"
12414 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12415 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12416 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12417 (clobber (reg:CC 17))]
12418 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12419 "@
12420 rol{w}\t{%2, %0|%0, %2}
12421 rol{w}\t{%b2, %0|%0, %b2}"
12422 [(set_attr "type" "rotate")
12423 (set_attr "mode" "HI")])
12424
12425(define_expand "rotlqi3"
12426 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12427 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12428 (match_operand:QI 2 "nonmemory_operand" "")))
12429 (clobber (reg:CC 17))]
12430 "TARGET_QIMODE_MATH"
12431 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12432
12433(define_insn "*rotlqi3_1_one_bit_slp"
12434 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12435 (rotate:QI (match_dup 0)
12436 (match_operand:QI 1 "const1_operand" "")))
12437 (clobber (reg:CC 17))]
12438 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12439 && (TARGET_SHIFT1 || optimize_size)"
12440 "rol{b}\t%0"
12441 [(set_attr "type" "rotate1")
12442 (set (attr "length")
12443 (if_then_else (match_operand 0 "register_operand" "")
12444 (const_string "2")
12445 (const_string "*")))])
12446
12447(define_insn "*rotlqi3_1_one_bit"
12448 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12449 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450 (match_operand:QI 2 "const1_operand" "")))
12451 (clobber (reg:CC 17))]
12452 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12453 && (TARGET_SHIFT1 || optimize_size)"
12454 "rol{b}\t%0"
12455 [(set_attr "type" "rotate")
12456 (set (attr "length")
12457 (if_then_else (match_operand 0 "register_operand" "")
12458 (const_string "2")
12459 (const_string "*")))])
12460
12461(define_insn "*rotlqi3_1_slp"
12462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463 (rotate:QI (match_dup 0)
12464 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465 (clobber (reg:CC 17))]
12466 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12468 "@
12469 rol{b}\t{%1, %0|%0, %1}
12470 rol{b}\t{%b1, %0|%0, %b1}"
12471 [(set_attr "type" "rotate1")
12472 (set_attr "mode" "QI")])
12473
12474(define_insn "*rotlqi3_1"
12475 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12476 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12477 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478 (clobber (reg:CC 17))]
12479 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12480 "@
12481 rol{b}\t{%2, %0|%0, %2}
12482 rol{b}\t{%b2, %0|%0, %b2}"
12483 [(set_attr "type" "rotate")
12484 (set_attr "mode" "QI")])
12485
12486(define_expand "rotrdi3"
12487 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12488 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12489 (match_operand:QI 2 "nonmemory_operand" "")))
12490 (clobber (reg:CC 17))]
12491 "TARGET_64BIT"
12492 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12493
12494(define_insn "*rotrdi3_1_one_bit_rex64"
12495 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12496 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12497 (match_operand:QI 2 "const1_operand" "")))
12498 (clobber (reg:CC 17))]
12499 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12500 && (TARGET_SHIFT1 || optimize_size)"
12501 "ror{q}\t%0"
12502 [(set_attr "type" "rotate")
12503 (set (attr "length")
12504 (if_then_else (match_operand:DI 0 "register_operand" "")
12505 (const_string "2")
12506 (const_string "*")))])
12507
12508(define_insn "*rotrdi3_1_rex64"
12509 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12510 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12511 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12512 (clobber (reg:CC 17))]
12513 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12514 "@
12515 ror{q}\t{%2, %0|%0, %2}
12516 ror{q}\t{%b2, %0|%0, %b2}"
12517 [(set_attr "type" "rotate")
12518 (set_attr "mode" "DI")])
12519
12520(define_expand "rotrsi3"
12521 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12522 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12523 (match_operand:QI 2 "nonmemory_operand" "")))
12524 (clobber (reg:CC 17))]
12525 ""
12526 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12527
12528(define_insn "*rotrsi3_1_one_bit"
12529 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12530 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12531 (match_operand:QI 2 "const1_operand" "")))
12532 (clobber (reg:CC 17))]
12533 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12534 && (TARGET_SHIFT1 || optimize_size)"
12535 "ror{l}\t%0"
12536 [(set_attr "type" "rotate")
12537 (set (attr "length")
12538 (if_then_else (match_operand:SI 0 "register_operand" "")
12539 (const_string "2")
12540 (const_string "*")))])
12541
12542(define_insn "*rotrsi3_1_one_bit_zext"
12543 [(set (match_operand:DI 0 "register_operand" "=r")
12544 (zero_extend:DI
12545 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12546 (match_operand:QI 2 "const1_operand" ""))))
12547 (clobber (reg:CC 17))]
12548 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12549 && (TARGET_SHIFT1 || optimize_size)"
12550 "ror{l}\t%k0"
12551 [(set_attr "type" "rotate")
12552 (set (attr "length")
12553 (if_then_else (match_operand:SI 0 "register_operand" "")
12554 (const_string "2")
12555 (const_string "*")))])
12556
12557(define_insn "*rotrsi3_1"
12558 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12559 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12560 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12561 (clobber (reg:CC 17))]
12562 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12563 "@
12564 ror{l}\t{%2, %0|%0, %2}
12565 ror{l}\t{%b2, %0|%0, %b2}"
12566 [(set_attr "type" "rotate")
12567 (set_attr "mode" "SI")])
12568
12569(define_insn "*rotrsi3_1_zext"
12570 [(set (match_operand:DI 0 "register_operand" "=r,r")
12571 (zero_extend:DI
12572 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12573 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12574 (clobber (reg:CC 17))]
12575 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12576 "@
12577 ror{l}\t{%2, %k0|%k0, %2}
12578 ror{l}\t{%b2, %k0|%k0, %b2}"
12579 [(set_attr "type" "rotate")
12580 (set_attr "mode" "SI")])
12581
12582(define_expand "rotrhi3"
12583 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12584 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12585 (match_operand:QI 2 "nonmemory_operand" "")))
12586 (clobber (reg:CC 17))]
12587 "TARGET_HIMODE_MATH"
12588 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12589
12590(define_insn "*rotrhi3_one_bit"
12591 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12592 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12593 (match_operand:QI 2 "const1_operand" "")))
12594 (clobber (reg:CC 17))]
12595 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12596 && (TARGET_SHIFT1 || optimize_size)"
12597 "ror{w}\t%0"
12598 [(set_attr "type" "rotate")
12599 (set (attr "length")
12600 (if_then_else (match_operand 0 "register_operand" "")
12601 (const_string "2")
12602 (const_string "*")))])
12603
12604(define_insn "*rotrhi3"
12605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12606 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12607 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12608 (clobber (reg:CC 17))]
12609 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12610 "@
12611 ror{w}\t{%2, %0|%0, %2}
12612 ror{w}\t{%b2, %0|%0, %b2}"
12613 [(set_attr "type" "rotate")
12614 (set_attr "mode" "HI")])
12615
12616(define_expand "rotrqi3"
12617 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12618 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12619 (match_operand:QI 2 "nonmemory_operand" "")))
12620 (clobber (reg:CC 17))]
12621 "TARGET_QIMODE_MATH"
12622 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12623
12624(define_insn "*rotrqi3_1_one_bit"
12625 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12626 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12627 (match_operand:QI 2 "const1_operand" "")))
12628 (clobber (reg:CC 17))]
12629 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12630 && (TARGET_SHIFT1 || optimize_size)"
12631 "ror{b}\t%0"
12632 [(set_attr "type" "rotate")
12633 (set (attr "length")
12634 (if_then_else (match_operand 0 "register_operand" "")
12635 (const_string "2")
12636 (const_string "*")))])
12637
12638(define_insn "*rotrqi3_1_one_bit_slp"
12639 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12640 (rotatert:QI (match_dup 0)
12641 (match_operand:QI 1 "const1_operand" "")))
12642 (clobber (reg:CC 17))]
12643 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12644 && (TARGET_SHIFT1 || optimize_size)"
12645 "ror{b}\t%0"
12646 [(set_attr "type" "rotate1")
12647 (set (attr "length")
12648 (if_then_else (match_operand 0 "register_operand" "")
12649 (const_string "2")
12650 (const_string "*")))])
12651
12652(define_insn "*rotrqi3_1"
12653 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12654 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12655 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12656 (clobber (reg:CC 17))]
12657 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12658 "@
12659 ror{b}\t{%2, %0|%0, %2}
12660 ror{b}\t{%b2, %0|%0, %b2}"
12661 [(set_attr "type" "rotate")
12662 (set_attr "mode" "QI")])
12663
12664(define_insn "*rotrqi3_1_slp"
12665 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12666 (rotatert:QI (match_dup 0)
12667 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12668 (clobber (reg:CC 17))]
12669 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12670 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12671 "@
12672 ror{b}\t{%1, %0|%0, %1}
12673 ror{b}\t{%b1, %0|%0, %b1}"
12674 [(set_attr "type" "rotate1")
12675 (set_attr "mode" "QI")])
12676
12677;; Bit set / bit test instructions
12678
12679(define_expand "extv"
12680 [(set (match_operand:SI 0 "register_operand" "")
12681 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12682 (match_operand:SI 2 "immediate_operand" "")
12683 (match_operand:SI 3 "immediate_operand" "")))]
12684 ""
12685{
12686 /* Handle extractions from %ah et al. */
12687 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12688 FAIL;
12689
12690 /* From mips.md: extract_bit_field doesn't verify that our source
12691 matches the predicate, so check it again here. */
12692 if (! register_operand (operands[1], VOIDmode))
12693 FAIL;
12694})
12695
12696(define_expand "extzv"
12697 [(set (match_operand:SI 0 "register_operand" "")
12698 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12699 (match_operand:SI 2 "immediate_operand" "")
12700 (match_operand:SI 3 "immediate_operand" "")))]
12701 ""
12702{
12703 /* Handle extractions from %ah et al. */
12704 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12705 FAIL;
12706
12707 /* From mips.md: extract_bit_field doesn't verify that our source
12708 matches the predicate, so check it again here. */
12709 if (! register_operand (operands[1], VOIDmode))
12710 FAIL;
12711})
12712
12713(define_expand "insv"
12714 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12715 (match_operand 1 "immediate_operand" "")
12716 (match_operand 2 "immediate_operand" ""))
12717 (match_operand 3 "register_operand" ""))]
12718 ""
12719{
12720 /* Handle extractions from %ah et al. */
12721 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12722 FAIL;
12723
12724 /* From mips.md: insert_bit_field doesn't verify that our source
12725 matches the predicate, so check it again here. */
12726 if (! register_operand (operands[0], VOIDmode))
12727 FAIL;
12728
12729 if (TARGET_64BIT)
12730 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12731 else
12732 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12733
12734 DONE;
12735})
12736
12737;; %%% bts, btr, btc, bt.
12738
12739;; Store-flag instructions.
12740
12741;; For all sCOND expanders, also expand the compare or test insn that
12742;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12743
12744;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12745;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12746;; way, which can later delete the movzx if only QImode is needed.
12747
12748(define_expand "seq"
12749 [(set (match_operand:QI 0 "register_operand" "")
12750 (eq:QI (reg:CC 17) (const_int 0)))]
12751 ""
12752 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12753
12754(define_expand "sne"
12755 [(set (match_operand:QI 0 "register_operand" "")
12756 (ne:QI (reg:CC 17) (const_int 0)))]
12757 ""
12758 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12759
12760(define_expand "sgt"
12761 [(set (match_operand:QI 0 "register_operand" "")
12762 (gt:QI (reg:CC 17) (const_int 0)))]
12763 ""
12764 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12765
12766(define_expand "sgtu"
12767 [(set (match_operand:QI 0 "register_operand" "")
12768 (gtu:QI (reg:CC 17) (const_int 0)))]
12769 ""
12770 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12771
12772(define_expand "slt"
12773 [(set (match_operand:QI 0 "register_operand" "")
12774 (lt:QI (reg:CC 17) (const_int 0)))]
12775 ""
12776 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12777
12778(define_expand "sltu"
12779 [(set (match_operand:QI 0 "register_operand" "")
12780 (ltu:QI (reg:CC 17) (const_int 0)))]
12781 ""
12782 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12783
12784(define_expand "sge"
12785 [(set (match_operand:QI 0 "register_operand" "")
12786 (ge:QI (reg:CC 17) (const_int 0)))]
12787 ""
12788 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12789
12790(define_expand "sgeu"
12791 [(set (match_operand:QI 0 "register_operand" "")
12792 (geu:QI (reg:CC 17) (const_int 0)))]
12793 ""
12794 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12795
12796(define_expand "sle"
12797 [(set (match_operand:QI 0 "register_operand" "")
12798 (le:QI (reg:CC 17) (const_int 0)))]
12799 ""
12800 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12801
12802(define_expand "sleu"
12803 [(set (match_operand:QI 0 "register_operand" "")
12804 (leu:QI (reg:CC 17) (const_int 0)))]
12805 ""
12806 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12807
12808(define_expand "sunordered"
12809 [(set (match_operand:QI 0 "register_operand" "")
12810 (unordered:QI (reg:CC 17) (const_int 0)))]
12811 "TARGET_80387 || TARGET_SSE"
12812 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12813
12814(define_expand "sordered"
12815 [(set (match_operand:QI 0 "register_operand" "")
12816 (ordered:QI (reg:CC 17) (const_int 0)))]
12817 "TARGET_80387"
12818 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12819
12820(define_expand "suneq"
12821 [(set (match_operand:QI 0 "register_operand" "")
12822 (uneq:QI (reg:CC 17) (const_int 0)))]
12823 "TARGET_80387 || TARGET_SSE"
12824 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12825
12826(define_expand "sunge"
12827 [(set (match_operand:QI 0 "register_operand" "")
12828 (unge:QI (reg:CC 17) (const_int 0)))]
12829 "TARGET_80387 || TARGET_SSE"
12830 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12831
12832(define_expand "sungt"
12833 [(set (match_operand:QI 0 "register_operand" "")
12834 (ungt:QI (reg:CC 17) (const_int 0)))]
12835 "TARGET_80387 || TARGET_SSE"
12836 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12837
12838(define_expand "sunle"
12839 [(set (match_operand:QI 0 "register_operand" "")
12840 (unle:QI (reg:CC 17) (const_int 0)))]
12841 "TARGET_80387 || TARGET_SSE"
12842 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12843
12844(define_expand "sunlt"
12845 [(set (match_operand:QI 0 "register_operand" "")
12846 (unlt:QI (reg:CC 17) (const_int 0)))]
12847 "TARGET_80387 || TARGET_SSE"
12848 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12849
12850(define_expand "sltgt"
12851 [(set (match_operand:QI 0 "register_operand" "")
12852 (ltgt:QI (reg:CC 17) (const_int 0)))]
12853 "TARGET_80387 || TARGET_SSE"
12854 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12855
12856(define_insn "*setcc_1"
12857 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12858 (match_operator:QI 1 "ix86_comparison_operator"
12859 [(reg 17) (const_int 0)]))]
12860 ""
12861 "set%C1\t%0"
12862 [(set_attr "type" "setcc")
12863 (set_attr "mode" "QI")])
12864
12865(define_insn "setcc_2"
12866 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12867 (match_operator:QI 1 "ix86_comparison_operator"
12868 [(reg 17) (const_int 0)]))]
12869 ""
12870 "set%C1\t%0"
12871 [(set_attr "type" "setcc")
12872 (set_attr "mode" "QI")])
12873
12874;; In general it is not safe to assume too much about CCmode registers,
12875;; so simplify-rtx stops when it sees a second one. Under certain
12876;; conditions this is safe on x86, so help combine not create
12877;;
12878;; seta %al
12879;; testb %al, %al
12880;; sete %al
12881
12882(define_split
12883 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12884 (ne:QI (match_operator 1 "ix86_comparison_operator"
12885 [(reg 17) (const_int 0)])
12886 (const_int 0)))]
12887 ""
12888 [(set (match_dup 0) (match_dup 1))]
12889{
12890 PUT_MODE (operands[1], QImode);
12891})
12892
12893(define_split
12894 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12895 (ne:QI (match_operator 1 "ix86_comparison_operator"
12896 [(reg 17) (const_int 0)])
12897 (const_int 0)))]
12898 ""
12899 [(set (match_dup 0) (match_dup 1))]
12900{
12901 PUT_MODE (operands[1], QImode);
12902})
12903
12904(define_split
12905 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12906 (eq:QI (match_operator 1 "ix86_comparison_operator"
12907 [(reg 17) (const_int 0)])
12908 (const_int 0)))]
12909 ""
12910 [(set (match_dup 0) (match_dup 1))]
12911{
12912 rtx new_op1 = copy_rtx (operands[1]);
12913 operands[1] = new_op1;
12914 PUT_MODE (new_op1, QImode);
12915 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12916 GET_MODE (XEXP (new_op1, 0))));
12917
12918 /* Make sure that (a) the CCmode we have for the flags is strong
12919 enough for the reversed compare or (b) we have a valid FP compare. */
12920 if (! ix86_comparison_operator (new_op1, VOIDmode))
12921 FAIL;
12922})
12923
12924(define_split
12925 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12926 (eq:QI (match_operator 1 "ix86_comparison_operator"
12927 [(reg 17) (const_int 0)])
12928 (const_int 0)))]
12929 ""
12930 [(set (match_dup 0) (match_dup 1))]
12931{
12932 rtx new_op1 = copy_rtx (operands[1]);
12933 operands[1] = new_op1;
12934 PUT_MODE (new_op1, QImode);
12935 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12936 GET_MODE (XEXP (new_op1, 0))));
12937
12938 /* Make sure that (a) the CCmode we have for the flags is strong
12939 enough for the reversed compare or (b) we have a valid FP compare. */
12940 if (! ix86_comparison_operator (new_op1, VOIDmode))
12941 FAIL;
12942})
12943
12944;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12945;; subsequent logical operations are used to imitate conditional moves.
12946;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12947;; it directly. Further holding this value in pseudo register might bring
12948;; problem in implicit normalization in spill code.
12949;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12950;; instructions after reload by splitting the conditional move patterns.
12951
12952(define_insn "*sse_setccsf"
12953 [(set (match_operand:SF 0 "register_operand" "=x")
12954 (match_operator:SF 1 "sse_comparison_operator"
12955 [(match_operand:SF 2 "register_operand" "0")
12956 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12957 "TARGET_SSE && reload_completed"
12958 "cmp%D1ss\t{%3, %0|%0, %3}"
12959 [(set_attr "type" "ssecmp")
12960 (set_attr "mode" "SF")])
12961
12962(define_insn "*sse_setccdf"
12963 [(set (match_operand:DF 0 "register_operand" "=Y")
12964 (match_operator:DF 1 "sse_comparison_operator"
12965 [(match_operand:DF 2 "register_operand" "0")
12966 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12967 "TARGET_SSE2 && reload_completed"
12968 "cmp%D1sd\t{%3, %0|%0, %3}"
12969 [(set_attr "type" "ssecmp")
12970 (set_attr "mode" "DF")])
12971
12972;; Basic conditional jump instructions.
12973;; We ignore the overflow flag for signed branch instructions.
12974
12975;; For all bCOND expanders, also expand the compare or test insn that
12976;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12977
12978(define_expand "beq"
12979 [(set (pc)
12980 (if_then_else (match_dup 1)
12981 (label_ref (match_operand 0 "" ""))
12982 (pc)))]
12983 ""
12984 "ix86_expand_branch (EQ, operands[0]); DONE;")
12985
12986(define_expand "bne"
12987 [(set (pc)
12988 (if_then_else (match_dup 1)
12989 (label_ref (match_operand 0 "" ""))
12990 (pc)))]
12991 ""
12992 "ix86_expand_branch (NE, operands[0]); DONE;")
12993
12994(define_expand "bgt"
12995 [(set (pc)
12996 (if_then_else (match_dup 1)
12997 (label_ref (match_operand 0 "" ""))
12998 (pc)))]
12999 ""
13000 "ix86_expand_branch (GT, operands[0]); DONE;")
13001
13002(define_expand "bgtu"
13003 [(set (pc)
13004 (if_then_else (match_dup 1)
13005 (label_ref (match_operand 0 "" ""))
13006 (pc)))]
13007 ""
13008 "ix86_expand_branch (GTU, operands[0]); DONE;")
13009
13010(define_expand "blt"
13011 [(set (pc)
13012 (if_then_else (match_dup 1)
13013 (label_ref (match_operand 0 "" ""))
13014 (pc)))]
13015 ""
13016 "ix86_expand_branch (LT, operands[0]); DONE;")
13017
13018(define_expand "bltu"
13019 [(set (pc)
13020 (if_then_else (match_dup 1)
13021 (label_ref (match_operand 0 "" ""))
13022 (pc)))]
13023 ""
13024 "ix86_expand_branch (LTU, operands[0]); DONE;")
13025
13026(define_expand "bge"
13027 [(set (pc)
13028 (if_then_else (match_dup 1)
13029 (label_ref (match_operand 0 "" ""))
13030 (pc)))]
13031 ""
13032 "ix86_expand_branch (GE, operands[0]); DONE;")
13033
13034(define_expand "bgeu"
13035 [(set (pc)
13036 (if_then_else (match_dup 1)
13037 (label_ref (match_operand 0 "" ""))
13038 (pc)))]
13039 ""
13040 "ix86_expand_branch (GEU, operands[0]); DONE;")
13041
13042(define_expand "ble"
13043 [(set (pc)
13044 (if_then_else (match_dup 1)
13045 (label_ref (match_operand 0 "" ""))
13046 (pc)))]
13047 ""
13048 "ix86_expand_branch (LE, operands[0]); DONE;")
13049
13050(define_expand "bleu"
13051 [(set (pc)
13052 (if_then_else (match_dup 1)
13053 (label_ref (match_operand 0 "" ""))
13054 (pc)))]
13055 ""
13056 "ix86_expand_branch (LEU, operands[0]); DONE;")
13057
13058(define_expand "bunordered"
13059 [(set (pc)
13060 (if_then_else (match_dup 1)
13061 (label_ref (match_operand 0 "" ""))
13062 (pc)))]
13063 "TARGET_80387 || TARGET_SSE"
13064 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13065
13066(define_expand "bordered"
13067 [(set (pc)
13068 (if_then_else (match_dup 1)
13069 (label_ref (match_operand 0 "" ""))
13070 (pc)))]
13071 "TARGET_80387 || TARGET_SSE"
13072 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13073
13074(define_expand "buneq"
13075 [(set (pc)
13076 (if_then_else (match_dup 1)
13077 (label_ref (match_operand 0 "" ""))
13078 (pc)))]
13079 "TARGET_80387 || TARGET_SSE"
13080 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13081
13082(define_expand "bunge"
13083 [(set (pc)
13084 (if_then_else (match_dup 1)
13085 (label_ref (match_operand 0 "" ""))
13086 (pc)))]
13087 "TARGET_80387 || TARGET_SSE"
13088 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13089
13090(define_expand "bungt"
13091 [(set (pc)
13092 (if_then_else (match_dup 1)
13093 (label_ref (match_operand 0 "" ""))
13094 (pc)))]
13095 "TARGET_80387 || TARGET_SSE"
13096 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13097
13098(define_expand "bunle"
13099 [(set (pc)
13100 (if_then_else (match_dup 1)
13101 (label_ref (match_operand 0 "" ""))
13102 (pc)))]
13103 "TARGET_80387 || TARGET_SSE"
13104 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13105
13106(define_expand "bunlt"
13107 [(set (pc)
13108 (if_then_else (match_dup 1)
13109 (label_ref (match_operand 0 "" ""))
13110 (pc)))]
13111 "TARGET_80387 || TARGET_SSE"
13112 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13113
13114(define_expand "bltgt"
13115 [(set (pc)
13116 (if_then_else (match_dup 1)
13117 (label_ref (match_operand 0 "" ""))
13118 (pc)))]
13119 "TARGET_80387 || TARGET_SSE"
13120 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13121
13122(define_insn "*jcc_1"
13123 [(set (pc)
13124 (if_then_else (match_operator 1 "ix86_comparison_operator"
13125 [(reg 17) (const_int 0)])
13126 (label_ref (match_operand 0 "" ""))
13127 (pc)))]
13128 ""
13129 "%+j%C1\t%l0"
13130 [(set_attr "type" "ibr")
13131 (set_attr "modrm" "0")
13132 (set (attr "length")
13133 (if_then_else (and (ge (minus (match_dup 0) (pc))
13134 (const_int -126))
13135 (lt (minus (match_dup 0) (pc))
13136 (const_int 128)))
13137 (const_int 2)
13138 (const_int 6)))])
13139
13140(define_insn "*jcc_2"
13141 [(set (pc)
13142 (if_then_else (match_operator 1 "ix86_comparison_operator"
13143 [(reg 17) (const_int 0)])
13144 (pc)
13145 (label_ref (match_operand 0 "" ""))))]
13146 ""
13147 "%+j%c1\t%l0"
13148 [(set_attr "type" "ibr")
13149 (set_attr "modrm" "0")
13150 (set (attr "length")
13151 (if_then_else (and (ge (minus (match_dup 0) (pc))
13152 (const_int -126))
13153 (lt (minus (match_dup 0) (pc))
13154 (const_int 128)))
13155 (const_int 2)
13156 (const_int 6)))])
13157
13158;; In general it is not safe to assume too much about CCmode registers,
13159;; so simplify-rtx stops when it sees a second one. Under certain
13160;; conditions this is safe on x86, so help combine not create
13161;;
13162;; seta %al
13163;; testb %al, %al
13164;; je Lfoo
13165
13166(define_split
13167 [(set (pc)
13168 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13169 [(reg 17) (const_int 0)])
13170 (const_int 0))
13171 (label_ref (match_operand 1 "" ""))
13172 (pc)))]
13173 ""
13174 [(set (pc)
13175 (if_then_else (match_dup 0)
13176 (label_ref (match_dup 1))
13177 (pc)))]
13178{
13179 PUT_MODE (operands[0], VOIDmode);
13180})
13181
13182(define_split
13183 [(set (pc)
13184 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13185 [(reg 17) (const_int 0)])
13186 (const_int 0))
13187 (label_ref (match_operand 1 "" ""))
13188 (pc)))]
13189 ""
13190 [(set (pc)
13191 (if_then_else (match_dup 0)
13192 (label_ref (match_dup 1))
13193 (pc)))]
13194{
13195 rtx new_op0 = copy_rtx (operands[0]);
13196 operands[0] = new_op0;
13197 PUT_MODE (new_op0, VOIDmode);
13198 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13199 GET_MODE (XEXP (new_op0, 0))));
13200
13201 /* Make sure that (a) the CCmode we have for the flags is strong
13202 enough for the reversed compare or (b) we have a valid FP compare. */
13203 if (! ix86_comparison_operator (new_op0, VOIDmode))
13204 FAIL;
13205})
13206
13207;; Define combination compare-and-branch fp compare instructions to use
13208;; during early optimization. Splitting the operation apart early makes
13209;; for bad code when we want to reverse the operation.
13210
13211(define_insn "*fp_jcc_1"
13212 [(set (pc)
13213 (if_then_else (match_operator 0 "comparison_operator"
13214 [(match_operand 1 "register_operand" "f")
13215 (match_operand 2 "register_operand" "f")])
13216 (label_ref (match_operand 3 "" ""))
13217 (pc)))
13218 (clobber (reg:CCFP 18))
13219 (clobber (reg:CCFP 17))]
13220 "TARGET_CMOVE && TARGET_80387
13221 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13222 && FLOAT_MODE_P (GET_MODE (operands[1]))
13223 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13224 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13225 "#")
13226
13227(define_insn "*fp_jcc_1_sse"
13228 [(set (pc)
13229 (if_then_else (match_operator 0 "comparison_operator"
13230 [(match_operand 1 "register_operand" "f#x,x#f")
13231 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13232 (label_ref (match_operand 3 "" ""))
13233 (pc)))
13234 (clobber (reg:CCFP 18))
13235 (clobber (reg:CCFP 17))]
13236 "TARGET_80387
13237 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13238 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13239 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13240 "#")
13241
13242(define_insn "*fp_jcc_1_sse_only"
13243 [(set (pc)
13244 (if_then_else (match_operator 0 "comparison_operator"
13245 [(match_operand 1 "register_operand" "x")
13246 (match_operand 2 "nonimmediate_operand" "xm")])
13247 (label_ref (match_operand 3 "" ""))
13248 (pc)))
13249 (clobber (reg:CCFP 18))
13250 (clobber (reg:CCFP 17))]
13251 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13252 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13253 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13254 "#")
13255
13256(define_insn "*fp_jcc_2"
13257 [(set (pc)
13258 (if_then_else (match_operator 0 "comparison_operator"
13259 [(match_operand 1 "register_operand" "f")
13260 (match_operand 2 "register_operand" "f")])
13261 (pc)
13262 (label_ref (match_operand 3 "" ""))))
13263 (clobber (reg:CCFP 18))
13264 (clobber (reg:CCFP 17))]
13265 "TARGET_CMOVE && TARGET_80387
13266 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13267 && FLOAT_MODE_P (GET_MODE (operands[1]))
13268 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13269 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13270 "#")
13271
13272(define_insn "*fp_jcc_2_sse"
13273 [(set (pc)
13274 (if_then_else (match_operator 0 "comparison_operator"
13275 [(match_operand 1 "register_operand" "f#x,x#f")
13276 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13277 (pc)
13278 (label_ref (match_operand 3 "" ""))))
13279 (clobber (reg:CCFP 18))
13280 (clobber (reg:CCFP 17))]
13281 "TARGET_80387
13282 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13283 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13284 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13285 "#")
13286
13287(define_insn "*fp_jcc_2_sse_only"
13288 [(set (pc)
13289 (if_then_else (match_operator 0 "comparison_operator"
13290 [(match_operand 1 "register_operand" "x")
13291 (match_operand 2 "nonimmediate_operand" "xm")])
13292 (pc)
13293 (label_ref (match_operand 3 "" ""))))
13294 (clobber (reg:CCFP 18))
13295 (clobber (reg:CCFP 17))]
13296 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13297 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13298 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13299 "#")
13300
13301(define_insn "*fp_jcc_3"
13302 [(set (pc)
13303 (if_then_else (match_operator 0 "comparison_operator"
13304 [(match_operand 1 "register_operand" "f")
13305 (match_operand 2 "nonimmediate_operand" "fm")])
13306 (label_ref (match_operand 3 "" ""))
13307 (pc)))
13308 (clobber (reg:CCFP 18))
13309 (clobber (reg:CCFP 17))
13310 (clobber (match_scratch:HI 4 "=a"))]
13311 "TARGET_80387
13312 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13313 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13314 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13315 && SELECT_CC_MODE (GET_CODE (operands[0]),
13316 operands[1], operands[2]) == CCFPmode
13317 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13318 "#")
13319
13320(define_insn "*fp_jcc_4"
13321 [(set (pc)
13322 (if_then_else (match_operator 0 "comparison_operator"
13323 [(match_operand 1 "register_operand" "f")
13324 (match_operand 2 "nonimmediate_operand" "fm")])
13325 (pc)
13326 (label_ref (match_operand 3 "" ""))))
13327 (clobber (reg:CCFP 18))
13328 (clobber (reg:CCFP 17))
13329 (clobber (match_scratch:HI 4 "=a"))]
13330 "TARGET_80387
13331 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13332 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13333 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13334 && SELECT_CC_MODE (GET_CODE (operands[0]),
13335 operands[1], operands[2]) == CCFPmode
13336 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13337 "#")
13338
13339(define_insn "*fp_jcc_5"
13340 [(set (pc)
13341 (if_then_else (match_operator 0 "comparison_operator"
13342 [(match_operand 1 "register_operand" "f")
13343 (match_operand 2 "register_operand" "f")])
13344 (label_ref (match_operand 3 "" ""))
13345 (pc)))
13346 (clobber (reg:CCFP 18))
13347 (clobber (reg:CCFP 17))
13348 (clobber (match_scratch:HI 4 "=a"))]
13349 "TARGET_80387
13350 && FLOAT_MODE_P (GET_MODE (operands[1]))
13351 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13352 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13353 "#")
13354
13355(define_insn "*fp_jcc_6"
13356 [(set (pc)
13357 (if_then_else (match_operator 0 "comparison_operator"
13358 [(match_operand 1 "register_operand" "f")
13359 (match_operand 2 "register_operand" "f")])
13360 (pc)
13361 (label_ref (match_operand 3 "" ""))))
13362 (clobber (reg:CCFP 18))
13363 (clobber (reg:CCFP 17))
13364 (clobber (match_scratch:HI 4 "=a"))]
13365 "TARGET_80387
13366 && FLOAT_MODE_P (GET_MODE (operands[1]))
13367 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13368 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13369 "#")
13370
13371(define_split
13372 [(set (pc)
13373 (if_then_else (match_operator 0 "comparison_operator"
13374 [(match_operand 1 "register_operand" "")
13375 (match_operand 2 "nonimmediate_operand" "")])
13376 (match_operand 3 "" "")
13377 (match_operand 4 "" "")))
13378 (clobber (reg:CCFP 18))
13379 (clobber (reg:CCFP 17))]
13380 "reload_completed"
13381 [(const_int 0)]
13382{
13383 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13384 operands[3], operands[4], NULL_RTX);
13385 DONE;
13386})
13387
13388(define_split
13389 [(set (pc)
13390 (if_then_else (match_operator 0 "comparison_operator"
13391 [(match_operand 1 "register_operand" "")
13392 (match_operand 2 "nonimmediate_operand" "")])
13393 (match_operand 3 "" "")
13394 (match_operand 4 "" "")))
13395 (clobber (reg:CCFP 18))
13396 (clobber (reg:CCFP 17))
13397 (clobber (match_scratch:HI 5 "=a"))]
13398 "reload_completed"
13399 [(set (pc)
13400 (if_then_else (match_dup 6)
13401 (match_dup 3)
13402 (match_dup 4)))]
13403{
13404 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13405 operands[3], operands[4], operands[5]);
13406 DONE;
13407})
13408
13409;; Unconditional and other jump instructions
13410
13411(define_insn "jump"
13412 [(set (pc)
13413 (label_ref (match_operand 0 "" "")))]
13414 ""
13415 "jmp\t%l0"
13416 [(set_attr "type" "ibr")
13417 (set (attr "length")
13418 (if_then_else (and (ge (minus (match_dup 0) (pc))
13419 (const_int -126))
13420 (lt (minus (match_dup 0) (pc))
13421 (const_int 128)))
13422 (const_int 2)
13423 (const_int 5)))
13424 (set_attr "modrm" "0")])
13425
13426(define_expand "indirect_jump"
13427 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13428 ""
13429 "")
13430
13431(define_insn "*indirect_jump"
13432 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13433 "!TARGET_64BIT"
13434 "jmp\t%A0"
13435 [(set_attr "type" "ibr")
13436 (set_attr "length_immediate" "0")])
13437
13438(define_insn "*indirect_jump_rtx64"
13439 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13440 "TARGET_64BIT"
13441 "jmp\t%A0"
13442 [(set_attr "type" "ibr")
13443 (set_attr "length_immediate" "0")])
13444
13445(define_expand "tablejump"
13446 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13447 (use (label_ref (match_operand 1 "" "")))])]
13448 ""
13449{
13450 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13451 relative. Convert the relative address to an absolute address. */
13452 if (flag_pic)
13453 {
13454 rtx op0, op1;
13455 enum rtx_code code;
13456
13457 if (TARGET_64BIT)
13458 {
13459 code = PLUS;
13460 op0 = operands[0];
13461 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13462 }
13463 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13464 {
13465 code = PLUS;
13466 op0 = operands[0];
13467 op1 = pic_offset_table_rtx;
13468 }
13469 else
13470 {
13471 code = MINUS;
13472 op0 = pic_offset_table_rtx;
13473 op1 = operands[0];
13474 }
13475
13476 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13477 OPTAB_DIRECT);
13478 }
13479})
13480
13481(define_insn "*tablejump_1"
13482 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13483 (use (label_ref (match_operand 1 "" "")))]
13484 "!TARGET_64BIT"
13485 "jmp\t%A0"
13486 [(set_attr "type" "ibr")
13487 (set_attr "length_immediate" "0")])
13488
13489(define_insn "*tablejump_1_rtx64"
13490 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13491 (use (label_ref (match_operand 1 "" "")))]
13492 "TARGET_64BIT"
13493 "jmp\t%A0"
13494 [(set_attr "type" "ibr")
13495 (set_attr "length_immediate" "0")])
13496
13497;; Loop instruction
13498;;
13499;; This is all complicated by the fact that since this is a jump insn
13500;; we must handle our own reloads.
13501
13502(define_expand "doloop_end"
13503 [(use (match_operand 0 "" "")) ; loop pseudo
13504 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13505 (use (match_operand 2 "" "")) ; max iterations
13506 (use (match_operand 3 "" "")) ; loop level
13507 (use (match_operand 4 "" ""))] ; label
13508 "!TARGET_64BIT && TARGET_USE_LOOP"
13509 "
13510{
13511 /* Only use cloop on innermost loops. */
13512 if (INTVAL (operands[3]) > 1)
13513 FAIL;
13514 if (GET_MODE (operands[0]) != SImode)
13515 FAIL;
13516 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13517 operands[0]));
13518 DONE;
13519}")
13520
13521(define_insn "doloop_end_internal"
13522 [(set (pc)
13523 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13524 (const_int 1))
13525 (label_ref (match_operand 0 "" ""))
13526 (pc)))
13527 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13528 (plus:SI (match_dup 1)
13529 (const_int -1)))
13530 (clobber (match_scratch:SI 3 "=X,X,r"))
13531 (clobber (reg:CC 17))]
13532 "!TARGET_64BIT && TARGET_USE_LOOP"
13533{
13534 if (which_alternative != 0)
13535 return "#";
13536 if (get_attr_length (insn) == 2)
13537 return "%+loop\t%l0";
13538 else
13539 return "dec{l}\t%1\;%+jne\t%l0";
13540}
13541 [(set_attr "ppro_uops" "many")
13542 (set (attr "length")
13543 (if_then_else (and (eq_attr "alternative" "0")
13544 (and (ge (minus (match_dup 0) (pc))
13545 (const_int -126))
13546 (lt (minus (match_dup 0) (pc))
13547 (const_int 128))))
13548 (const_int 2)
13549 (const_int 16)))
13550 ;; We don't know the type before shorten branches. Optimistically expect
13551 ;; the loop instruction to match.
13552 (set (attr "type") (const_string "ibr"))])
13553
13554(define_split
13555 [(set (pc)
13556 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13557 (const_int 1))
13558 (match_operand 0 "" "")
13559 (pc)))
13560 (set (match_dup 1)
13561 (plus:SI (match_dup 1)
13562 (const_int -1)))
13563 (clobber (match_scratch:SI 2 ""))
13564 (clobber (reg:CC 17))]
13565 "!TARGET_64BIT && TARGET_USE_LOOP
13566 && reload_completed
13567 && REGNO (operands[1]) != 2"
13568 [(parallel [(set (reg:CCZ 17)
13569 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13570 (const_int 0)))
13571 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13572 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13573 (match_dup 0)
13574 (pc)))]
13575 "")
13576
13577(define_split
13578 [(set (pc)
13579 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13580 (const_int 1))
13581 (match_operand 0 "" "")
13582 (pc)))
13583 (set (match_operand:SI 2 "nonimmediate_operand" "")
13584 (plus:SI (match_dup 1)
13585 (const_int -1)))
13586 (clobber (match_scratch:SI 3 ""))
13587 (clobber (reg:CC 17))]
13588 "!TARGET_64BIT && TARGET_USE_LOOP
13589 && reload_completed
13590 && (! REG_P (operands[2])
13591 || ! rtx_equal_p (operands[1], operands[2]))"
13592 [(set (match_dup 3) (match_dup 1))
13593 (parallel [(set (reg:CCZ 17)
13594 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13595 (const_int 0)))
13596 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13597 (set (match_dup 2) (match_dup 3))
13598 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13599 (match_dup 0)
13600 (pc)))]
13601 "")
13602
13603;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13604
13605(define_peephole2
13606 [(set (reg 17) (match_operand 0 "" ""))
13607 (set (match_operand:QI 1 "register_operand" "")
13608 (match_operator:QI 2 "ix86_comparison_operator"
13609 [(reg 17) (const_int 0)]))
13610 (set (match_operand 3 "q_regs_operand" "")
13611 (zero_extend (match_dup 1)))]
13612 "(peep2_reg_dead_p (3, operands[1])
13613 || operands_match_p (operands[1], operands[3]))
13614 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13615 [(set (match_dup 4) (match_dup 0))
13616 (set (strict_low_part (match_dup 5))
13617 (match_dup 2))]
13618{
13619 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13620 operands[5] = gen_lowpart (QImode, operands[3]);
13621 ix86_expand_clear (operands[3]);
13622})
13623
13624;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13625
13626(define_peephole2
13627 [(set (reg 17) (match_operand 0 "" ""))
13628 (set (match_operand:QI 1 "register_operand" "")
13629 (match_operator:QI 2 "ix86_comparison_operator"
13630 [(reg 17) (const_int 0)]))
13631 (parallel [(set (match_operand 3 "q_regs_operand" "")
13632 (zero_extend (match_dup 1)))
13633 (clobber (reg:CC 17))])]
13634 "(peep2_reg_dead_p (3, operands[1])
13635 || operands_match_p (operands[1], operands[3]))
13636 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13637 [(set (match_dup 4) (match_dup 0))
13638 (set (strict_low_part (match_dup 5))
13639 (match_dup 2))]
13640{
13641 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13642 operands[5] = gen_lowpart (QImode, operands[3]);
13643 ix86_expand_clear (operands[3]);
13644})
13645
13646;; Call instructions.
13647
13648;; The predicates normally associated with named expanders are not properly
13649;; checked for calls. This is a bug in the generic code, but it isn't that
13650;; easy to fix. Ignore it for now and be prepared to fix things up.
13651
13652;; Call subroutine returning no value.
13653
13654(define_expand "call_pop"
13655 [(parallel [(call (match_operand:QI 0 "" "")
13656 (match_operand:SI 1 "" ""))
13657 (set (reg:SI 7)
13658 (plus:SI (reg:SI 7)
13659 (match_operand:SI 3 "" "")))])]
13660 "!TARGET_64BIT"
13661{
13662 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13663 DONE;
13664})
13665
13666(define_insn "*call_pop_0"
13667 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13668 (match_operand:SI 1 "" ""))
13669 (set (reg:SI 7) (plus:SI (reg:SI 7)
13670 (match_operand:SI 2 "immediate_operand" "")))]
13671 "!TARGET_64BIT"
13672{
13673 if (SIBLING_CALL_P (insn))
13674 return "jmp\t%P0";
13675 else
13676 return "call\t%P0";
13677}
13678 [(set_attr "type" "call")])
13679
13680(define_insn "*call_pop_1"
13681 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13682 (match_operand:SI 1 "" ""))
13683 (set (reg:SI 7) (plus:SI (reg:SI 7)
13684 (match_operand:SI 2 "immediate_operand" "i")))]
13685 "!TARGET_64BIT"
13686{
13687 if (constant_call_address_operand (operands[0], Pmode))
13688 {
13689 if (SIBLING_CALL_P (insn))
13690 return "jmp\t%P0";
13691 else
13692 return "call\t%P0";
13693 }
13694 if (SIBLING_CALL_P (insn))
13695 return "jmp\t%A0";
13696 else
13697 return "call\t%A0";
13698}
13699 [(set_attr "type" "call")])
13700
13701(define_expand "call"
13702 [(call (match_operand:QI 0 "" "")
13703 (match_operand 1 "" ""))
13704 (use (match_operand 2 "" ""))]
13705 ""
13706{
13707 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13708 DONE;
13709})
13710
13711(define_expand "sibcall"
13712 [(call (match_operand:QI 0 "" "")
13713 (match_operand 1 "" ""))
13714 (use (match_operand 2 "" ""))]
13715 ""
13716{
13717 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13718 DONE;
13719})
13720
13721(define_insn "*call_0"
13722 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13723 (match_operand 1 "" ""))]
13724 ""
13725{
13726 if (SIBLING_CALL_P (insn))
13727 return "jmp\t%P0";
13728 else
13729 return "call\t%P0";
13730}
13731 [(set_attr "type" "call")])
13732
13733(define_insn "*call_1"
13734 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13735 (match_operand 1 "" ""))]
13736 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13737{
13738 if (constant_call_address_operand (operands[0], QImode))
13739 return "call\t%P0";
13740 return "call\t%A0";
13741}
13742 [(set_attr "type" "call")])
13743
13744(define_insn "*sibcall_1"
13745 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13746 (match_operand 1 "" ""))]
13747 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13748{
13749 if (constant_call_address_operand (operands[0], QImode))
13750 return "jmp\t%P0";
13751 return "jmp\t%A0";
13752}
13753 [(set_attr "type" "call")])
13754
13755(define_insn "*call_1_rex64"
13756 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13757 (match_operand 1 "" ""))]
13758 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13759{
13760 if (constant_call_address_operand (operands[0], QImode))
13761 return "call\t%P0";
13762 return "call\t%A0";
13763}
13764 [(set_attr "type" "call")])
13765
13766(define_insn "*sibcall_1_rex64"
13767 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13768 (match_operand 1 "" ""))]
13769 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13770 "jmp\t%P0"
13771 [(set_attr "type" "call")])
13772
13773(define_insn "*sibcall_1_rex64_v"
13774 [(call (mem:QI (reg:DI 40))
13775 (match_operand 0 "" ""))]
13776 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13777 "jmp\t*%%r11"
13778 [(set_attr "type" "call")])
13779
13780
13781;; Call subroutine, returning value in operand 0
13782
13783(define_expand "call_value_pop"
13784 [(parallel [(set (match_operand 0 "" "")
13785 (call (match_operand:QI 1 "" "")
13786 (match_operand:SI 2 "" "")))
13787 (set (reg:SI 7)
13788 (plus:SI (reg:SI 7)
13789 (match_operand:SI 4 "" "")))])]
13790 "!TARGET_64BIT"
13791{
13792 ix86_expand_call (operands[0], operands[1], operands[2],
13793 operands[3], operands[4], 0);
13794 DONE;
13795})
13796
13797(define_expand "call_value"
13798 [(set (match_operand 0 "" "")
13799 (call (match_operand:QI 1 "" "")
13800 (match_operand:SI 2 "" "")))
13801 (use (match_operand:SI 3 "" ""))]
13802 ;; Operand 2 not used on the i386.
13803 ""
13804{
13805 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13806 DONE;
13807})
13808
13809(define_expand "sibcall_value"
13810 [(set (match_operand 0 "" "")
13811 (call (match_operand:QI 1 "" "")
13812 (match_operand:SI 2 "" "")))
13813 (use (match_operand:SI 3 "" ""))]
13814 ;; Operand 2 not used on the i386.
13815 ""
13816{
13817 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13818 DONE;
13819})
13820
13821;; Call subroutine returning any type.
13822
13823(define_expand "untyped_call"
13824 [(parallel [(call (match_operand 0 "" "")
13825 (const_int 0))
13826 (match_operand 1 "" "")
13827 (match_operand 2 "" "")])]
13828 ""
13829{
13830 int i;
13831
13832 /* In order to give reg-stack an easier job in validating two
13833 coprocessor registers as containing a possible return value,
13834 simply pretend the untyped call returns a complex long double
13835 value. */
13836
13837 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13838 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13839 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13840 NULL, 0);
13841
13842 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13843 {
13844 rtx set = XVECEXP (operands[2], 0, i);
13845 emit_move_insn (SET_DEST (set), SET_SRC (set));
13846 }
13847
13848 /* The optimizer does not know that the call sets the function value
13849 registers we stored in the result block. We avoid problems by
13850 claiming that all hard registers are used and clobbered at this
13851 point. */
13852 emit_insn (gen_blockage (const0_rtx));
13853
13854 DONE;
13855})
13856
13857;; Prologue and epilogue instructions
13858
13859;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13860;; all of memory. This blocks insns from being moved across this point.
13861
13862(define_insn "blockage"
13863 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13864 ""
13865 ""
13866 [(set_attr "length" "0")])
13867
13868;; Insn emitted into the body of a function to return from a function.
13869;; This is only done if the function's epilogue is known to be simple.
13870;; See comments for ix86_can_use_return_insn_p in i386.c.
13871
13872(define_expand "return"
13873 [(return)]
13874 "ix86_can_use_return_insn_p ()"
13875{
13876 if (current_function_pops_args)
13877 {
13878 rtx popc = GEN_INT (current_function_pops_args);
13879 emit_jump_insn (gen_return_pop_internal (popc));
13880 DONE;
13881 }
13882})
13883
13884(define_insn "return_internal"
13885 [(return)]
13886 "reload_completed"
13887 "ret"
13888 [(set_attr "length" "1")
13889 (set_attr "length_immediate" "0")
13890 (set_attr "modrm" "0")])
13891
13892;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13893;; instruction Athlon and K8 have.
13894
13895(define_insn "return_internal_long"
13896 [(return)
13897 (unspec [(const_int 0)] UNSPEC_REP)]
13898 "reload_completed"
13899 "rep {;} ret"
13900 [(set_attr "length" "1")
13901 (set_attr "length_immediate" "0")
13902 (set_attr "prefix_rep" "1")
13903 (set_attr "modrm" "0")])
13904
13905(define_insn "return_pop_internal"
13906 [(return)
13907 (use (match_operand:SI 0 "const_int_operand" ""))]
13908 "reload_completed"
13909 "ret\t%0"
13910 [(set_attr "length" "3")
13911 (set_attr "length_immediate" "2")
13912 (set_attr "modrm" "0")])
13913
13914(define_insn "return_indirect_internal"
13915 [(return)
13916 (use (match_operand:SI 0 "register_operand" "r"))]
13917 "reload_completed"
13918 "jmp\t%A0"
13919 [(set_attr "type" "ibr")
13920 (set_attr "length_immediate" "0")])
13921
13922(define_insn "nop"
13923 [(const_int 0)]
13924 ""
13925 "nop"
13926 [(set_attr "length" "1")
13927 (set_attr "length_immediate" "0")
13928 (set_attr "modrm" "0")
13929 (set_attr "ppro_uops" "one")])
13930
13931;; Align to 16-byte boundary, max skip in op0. Used to avoid
13932;; branch prediction penalty for the third jump in a 16-byte
13933;; block on K8.
13934
13935(define_insn "align"
13936 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13937 ""
13938{
13939#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13940 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13941#else
13942 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13943 The align insn is used to avoid 3 jump instructions in the row to improve
13944 branch prediction and the benefits hardly outweight the cost of extra 8
13945 nops on the average inserted by full alignment pseudo operation. */
13946#endif
13947 return "";
13948}
13949 [(set_attr "length" "16")])
13950
13951(define_expand "prologue"
13952 [(const_int 1)]
13953 ""
13954 "ix86_expand_prologue (); DONE;")
13955
13956(define_insn "set_got"
13957 [(set (match_operand:SI 0 "register_operand" "=r")
13958 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13959 (clobber (reg:CC 17))]
13960 "!TARGET_64BIT"
13961 { return output_set_got (operands[0]); }
13962 [(set_attr "type" "multi")
13963 (set_attr "length" "12")])
13964
13965(define_expand "epilogue"
13966 [(const_int 1)]
13967 ""
13968 "ix86_expand_epilogue (1); DONE;")
13969
13970(define_expand "sibcall_epilogue"
13971 [(const_int 1)]
13972 ""
13973 "ix86_expand_epilogue (0); DONE;")
13974
13975(define_expand "eh_return"
13976 [(use (match_operand 0 "register_operand" ""))]
13977 ""
13978{
13979 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13980
13981 /* Tricky bit: we write the address of the handler to which we will
13982 be returning into someone else's stack frame, one word below the
13983 stack address we wish to restore. */
13984 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13985 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13986 tmp = gen_rtx_MEM (Pmode, tmp);
13987 emit_move_insn (tmp, ra);
13988
13989 if (Pmode == SImode)
13990 emit_insn (gen_eh_return_si (sa));
13991 else
13992 emit_insn (gen_eh_return_di (sa));
13993 emit_barrier ();
13994 DONE;
13995})
13996
13997(define_insn_and_split "eh_return_si"
13998 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13999 UNSPECV_EH_RETURN)]
14000 "!TARGET_64BIT"
14001 "#"
14002 "reload_completed"
14003 [(const_int 1)]
14004 "ix86_expand_epilogue (2); DONE;")
14005
14006(define_insn_and_split "eh_return_di"
14007 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14008 UNSPECV_EH_RETURN)]
14009 "TARGET_64BIT"
14010 "#"
14011 "reload_completed"
14012 [(const_int 1)]
14013 "ix86_expand_epilogue (2); DONE;")
14014
14015(define_insn "leave"
14016 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14017 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14018 (clobber (mem:BLK (scratch)))]
14019 "!TARGET_64BIT"
14020 "leave"
14021 [(set_attr "type" "leave")])
14022
14023(define_insn "leave_rex64"
14024 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14025 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14026 (clobber (mem:BLK (scratch)))]
14027 "TARGET_64BIT"
14028 "leave"
14029 [(set_attr "type" "leave")])
14030
14031(define_expand "ffssi2"
14032 [(parallel
14033 [(set (match_operand:SI 0 "register_operand" "")
14034 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14035 (clobber (match_scratch:SI 2 ""))
14036 (clobber (reg:CC 17))])]
14037 ""
14038 "")
14039
14040(define_insn_and_split "*ffs_cmove"
14041 [(set (match_operand:SI 0 "register_operand" "=r")
14042 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14043 (clobber (match_scratch:SI 2 "=&r"))
14044 (clobber (reg:CC 17))]
14045 "TARGET_CMOVE"
14046 "#"
14047 "&& reload_completed"
14048 [(set (match_dup 2) (const_int -1))
14049 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14050 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14051 (set (match_dup 0) (if_then_else:SI
14052 (eq (reg:CCZ 17) (const_int 0))
14053 (match_dup 2)
14054 (match_dup 0)))
14055 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14056 (clobber (reg:CC 17))])]
14057 "")
14058
14059(define_insn_and_split "*ffs_no_cmove"
14060 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14061 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14062 (clobber (match_scratch:SI 2 "=&q"))
14063 (clobber (reg:CC 17))]
14064 ""
14065 "#"
14066 "reload_completed"
14067 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14068 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14069 (set (strict_low_part (match_dup 3))
14070 (eq:QI (reg:CCZ 17) (const_int 0)))
14071 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14072 (clobber (reg:CC 17))])
14073 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14074 (clobber (reg:CC 17))])
14075 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14076 (clobber (reg:CC 17))])]
14077{
14078 operands[3] = gen_lowpart (QImode, operands[2]);
14079 ix86_expand_clear (operands[2]);
14080})
14081
14082(define_insn "*ffssi_1"
14083 [(set (reg:CCZ 17)
14084 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14085 (const_int 0)))
14086 (set (match_operand:SI 0 "register_operand" "=r")
14087 (ctz:SI (match_dup 1)))]
14088 ""
14089 "bsf{l}\t{%1, %0|%0, %1}"
14090 [(set_attr "prefix_0f" "1")
14091 (set_attr "ppro_uops" "few")])
14092
14093(define_insn "ctzsi2"
14094 [(set (match_operand:SI 0 "register_operand" "=r")
14095 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14096 (clobber (reg:CC 17))]
14097 ""
14098 "bsf{l}\t{%1, %0|%0, %1}"
14099 [(set_attr "prefix_0f" "1")
14100 (set_attr "ppro_uops" "few")])
14101
14102(define_expand "clzsi2"
14103 [(parallel
14104 [(set (match_operand:SI 0 "register_operand" "")
14105 (minus:SI (const_int 31)
14106 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14107 (clobber (reg:CC 17))])
14108 (parallel
14109 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14110 (clobber (reg:CC 17))])]
14111 ""
14112 "")
14113
14114(define_insn "*bsr"
14115 [(set (match_operand:SI 0 "register_operand" "=r")
14116 (minus:SI (const_int 31)
14117 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14118 (clobber (reg:CC 17))]
14119 ""
14120 "bsr{l}\t{%1, %0|%0, %1}"
14121 [(set_attr "prefix_0f" "1")
14122 (set_attr "ppro_uops" "few")])
14123
14124;; Thread-local storage patterns for ELF.
14125;;
14126;; Note that these code sequences must appear exactly as shown
14127;; in order to allow linker relaxation.
14128
14129(define_insn "*tls_global_dynamic_32_gnu"
14130 [(set (match_operand:SI 0 "register_operand" "=a")
14131 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14132 (match_operand:SI 2 "tls_symbolic_operand" "")
14133 (match_operand:SI 3 "call_insn_operand" "")]
14134 UNSPEC_TLS_GD))
14135 (clobber (match_scratch:SI 4 "=d"))
14136 (clobber (match_scratch:SI 5 "=c"))
14137 (clobber (reg:CC 17))]
14138 "!TARGET_64BIT && TARGET_GNU_TLS"
14139 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14140 [(set_attr "type" "multi")
14141 (set_attr "length" "12")])
14142
14143(define_insn "*tls_global_dynamic_32_sun"
14144 [(set (match_operand:SI 0 "register_operand" "=a")
14145 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14146 (match_operand:SI 2 "tls_symbolic_operand" "")
14147 (match_operand:SI 3 "call_insn_operand" "")]
14148 UNSPEC_TLS_GD))
14149 (clobber (match_scratch:SI 4 "=d"))
14150 (clobber (match_scratch:SI 5 "=c"))
14151 (clobber (reg:CC 17))]
14152 "!TARGET_64BIT && TARGET_SUN_TLS"
14153 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14154 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14155 [(set_attr "type" "multi")
14156 (set_attr "length" "14")])
14157
14158(define_expand "tls_global_dynamic_32"
14159 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14160 (unspec:SI
14161 [(match_dup 2)
14162 (match_operand:SI 1 "tls_symbolic_operand" "")
14163 (match_dup 3)]
14164 UNSPEC_TLS_GD))
14165 (clobber (match_scratch:SI 4 ""))
14166 (clobber (match_scratch:SI 5 ""))
14167 (clobber (reg:CC 17))])]
14168 ""
14169{
14170 if (flag_pic)
14171 operands[2] = pic_offset_table_rtx;
14172 else
14173 {
14174 operands[2] = gen_reg_rtx (Pmode);
14175 emit_insn (gen_set_got (operands[2]));
14176 }
14177 operands[3] = ix86_tls_get_addr ();
14178})
14179
14180(define_insn "*tls_global_dynamic_64"
14181 [(set (match_operand:DI 0 "register_operand" "=a")
14182 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14183 (match_operand:DI 3 "" "")))
14184 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14185 UNSPEC_TLS_GD)]
14186 "TARGET_64BIT"
14187 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14188 [(set_attr "type" "multi")
14189 (set_attr "length" "16")])
14190
14191(define_expand "tls_global_dynamic_64"
14192 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14193 (call (mem:QI (match_dup 2)) (const_int 0)))
14194 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14195 UNSPEC_TLS_GD)])]
14196 ""
14197{
14198 operands[2] = ix86_tls_get_addr ();
14199})
14200
14201(define_insn "*tls_local_dynamic_base_32_gnu"
14202 [(set (match_operand:SI 0 "register_operand" "=a")
14203 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14204 (match_operand:SI 2 "call_insn_operand" "")]
14205 UNSPEC_TLS_LD_BASE))
14206 (clobber (match_scratch:SI 3 "=d"))
14207 (clobber (match_scratch:SI 4 "=c"))
14208 (clobber (reg:CC 17))]
14209 "!TARGET_64BIT && TARGET_GNU_TLS"
14210 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14211 [(set_attr "type" "multi")
14212 (set_attr "length" "11")])
14213
14214(define_insn "*tls_local_dynamic_base_32_sun"
14215 [(set (match_operand:SI 0 "register_operand" "=a")
14216 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14217 (match_operand:SI 2 "call_insn_operand" "")]
14218 UNSPEC_TLS_LD_BASE))
14219 (clobber (match_scratch:SI 3 "=d"))
14220 (clobber (match_scratch:SI 4 "=c"))
14221 (clobber (reg:CC 17))]
14222 "!TARGET_64BIT && TARGET_SUN_TLS"
14223 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14224 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14225 [(set_attr "type" "multi")
14226 (set_attr "length" "13")])
14227
14228(define_expand "tls_local_dynamic_base_32"
14229 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14230 (unspec:SI [(match_dup 1) (match_dup 2)]
14231 UNSPEC_TLS_LD_BASE))
14232 (clobber (match_scratch:SI 3 ""))
14233 (clobber (match_scratch:SI 4 ""))
14234 (clobber (reg:CC 17))])]
14235 ""
14236{
14237 if (flag_pic)
14238 operands[1] = pic_offset_table_rtx;
14239 else
14240 {
14241 operands[1] = gen_reg_rtx (Pmode);
14242 emit_insn (gen_set_got (operands[1]));
14243 }
14244 operands[2] = ix86_tls_get_addr ();
14245})
14246
14247(define_insn "*tls_local_dynamic_base_64"
14248 [(set (match_operand:DI 0 "register_operand" "=a")
14249 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14250 (match_operand:DI 2 "" "")))
14251 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14252 "TARGET_64BIT"
14253 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14254 [(set_attr "type" "multi")
14255 (set_attr "length" "12")])
14256
14257(define_expand "tls_local_dynamic_base_64"
14258 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14259 (call (mem:QI (match_dup 1)) (const_int 0)))
14260 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14261 ""
14262{
14263 operands[1] = ix86_tls_get_addr ();
14264})
14265
14266;; Local dynamic of a single variable is a lose. Show combine how
14267;; to convert that back to global dynamic.
14268
14269(define_insn_and_split "*tls_local_dynamic_32_once"
14270 [(set (match_operand:SI 0 "register_operand" "=a")
14271 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14272 (match_operand:SI 2 "call_insn_operand" "")]
14273 UNSPEC_TLS_LD_BASE)
14274 (const:SI (unspec:SI
14275 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14276 UNSPEC_DTPOFF))))
14277 (clobber (match_scratch:SI 4 "=d"))
14278 (clobber (match_scratch:SI 5 "=c"))
14279 (clobber (reg:CC 17))]
14280 ""
14281 "#"
14282 ""
14283 [(parallel [(set (match_dup 0)
14284 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14285 UNSPEC_TLS_GD))
14286 (clobber (match_dup 4))
14287 (clobber (match_dup 5))
14288 (clobber (reg:CC 17))])]
14289 "")
14290
14291;; Load and add the thread base pointer from %gs:0.
14292
14293(define_insn "*load_tp_si"
14294 [(set (match_operand:SI 0 "register_operand" "=r")
14295 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14296 "!TARGET_64BIT"
14297 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14298 [(set_attr "type" "imov")
14299 (set_attr "modrm" "0")
14300 (set_attr "length" "7")
14301 (set_attr "memory" "load")
14302 (set_attr "imm_disp" "false")])
14303
14304(define_insn "*add_tp_si"
14305 [(set (match_operand:SI 0 "register_operand" "=r")
14306 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14307 (match_operand:SI 1 "register_operand" "0")))
14308 (clobber (reg:CC 17))]
14309 "!TARGET_64BIT"
14310 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14311 [(set_attr "type" "alu")
14312 (set_attr "modrm" "0")
14313 (set_attr "length" "7")
14314 (set_attr "memory" "load")
14315 (set_attr "imm_disp" "false")])
14316
14317(define_insn "*load_tp_di"
14318 [(set (match_operand:DI 0 "register_operand" "=r")
14319 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14320 "TARGET_64BIT"
14321 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14322 [(set_attr "type" "imov")
14323 (set_attr "modrm" "0")
14324 (set_attr "length" "7")
14325 (set_attr "memory" "load")
14326 (set_attr "imm_disp" "false")])
14327
14328(define_insn "*add_tp_di"
14329 [(set (match_operand:DI 0 "register_operand" "=r")
14330 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14331 (match_operand:DI 1 "register_operand" "0")))
14332 (clobber (reg:CC 17))]
14333 "TARGET_64BIT"
14334 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14335 [(set_attr "type" "alu")
14336 (set_attr "modrm" "0")
14337 (set_attr "length" "7")
14338 (set_attr "memory" "load")
14339 (set_attr "imm_disp" "false")])
14340
14341;; These patterns match the binary 387 instructions for addM3, subM3,
14342;; mulM3 and divM3. There are three patterns for each of DFmode and
14343;; SFmode. The first is the normal insn, the second the same insn but
14344;; with one operand a conversion, and the third the same insn but with
14345;; the other operand a conversion. The conversion may be SFmode or
14346;; SImode if the target mode DFmode, but only SImode if the target mode
14347;; is SFmode.
14348
14349;; Gcc is slightly more smart about handling normal two address instructions
14350;; so use special patterns for add and mull.
14351(define_insn "*fop_sf_comm_nosse"
14352 [(set (match_operand:SF 0 "register_operand" "=f")
14353 (match_operator:SF 3 "binary_fp_operator"
14354 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14355 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14356 "TARGET_80387 && !TARGET_SSE_MATH
14357 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14358 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14359 "* return output_387_binary_op (insn, operands);"
14360 [(set (attr "type")
14361 (if_then_else (match_operand:SF 3 "mult_operator" "")
14362 (const_string "fmul")
14363 (const_string "fop")))
14364 (set_attr "mode" "SF")])
14365
14366(define_insn "*fop_sf_comm"
14367 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14368 (match_operator:SF 3 "binary_fp_operator"
14369 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14370 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14371 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14372 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14374 "* return output_387_binary_op (insn, operands);"
14375 [(set (attr "type")
14376 (if_then_else (eq_attr "alternative" "1")
14377 (if_then_else (match_operand:SF 3 "mult_operator" "")
14378 (const_string "ssemul")
14379 (const_string "sseadd"))
14380 (if_then_else (match_operand:SF 3 "mult_operator" "")
14381 (const_string "fmul")
14382 (const_string "fop"))))
14383 (set_attr "mode" "SF")])
14384
14385(define_insn "*fop_sf_comm_sse"
14386 [(set (match_operand:SF 0 "register_operand" "=x")
14387 (match_operator:SF 3 "binary_fp_operator"
14388 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14389 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14390 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14391 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14392 "* return output_387_binary_op (insn, operands);"
14393 [(set (attr "type")
14394 (if_then_else (match_operand:SF 3 "mult_operator" "")
14395 (const_string "ssemul")
14396 (const_string "sseadd")))
14397 (set_attr "mode" "SF")])
14398
14399(define_insn "*fop_df_comm_nosse"
14400 [(set (match_operand:DF 0 "register_operand" "=f")
14401 (match_operator:DF 3 "binary_fp_operator"
14402 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14403 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14404 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14405 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14406 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14407 "* return output_387_binary_op (insn, operands);"
14408 [(set (attr "type")
14409 (if_then_else (match_operand:SF 3 "mult_operator" "")
14410 (const_string "fmul")
14411 (const_string "fop")))
14412 (set_attr "mode" "DF")])
14413
14414(define_insn "*fop_df_comm"
14415 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14416 (match_operator:DF 3 "binary_fp_operator"
14417 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14418 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14419 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14420 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14421 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14422 "* return output_387_binary_op (insn, operands);"
14423 [(set (attr "type")
14424 (if_then_else (eq_attr "alternative" "1")
14425 (if_then_else (match_operand:SF 3 "mult_operator" "")
14426 (const_string "ssemul")
14427 (const_string "sseadd"))
14428 (if_then_else (match_operand:SF 3 "mult_operator" "")
14429 (const_string "fmul")
14430 (const_string "fop"))))
14431 (set_attr "mode" "DF")])
14432
14433(define_insn "*fop_df_comm_sse"
14434 [(set (match_operand:DF 0 "register_operand" "=Y")
14435 (match_operator:DF 3 "binary_fp_operator"
14436 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14437 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14438 "TARGET_SSE2 && TARGET_SSE_MATH
14439 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14440 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14441 "* return output_387_binary_op (insn, operands);"
14442 [(set (attr "type")
14443 (if_then_else (match_operand:SF 3 "mult_operator" "")
14444 (const_string "ssemul")
14445 (const_string "sseadd")))
14446 (set_attr "mode" "DF")])
14447
14448(define_insn "*fop_xf_comm"
14449 [(set (match_operand:XF 0 "register_operand" "=f")
14450 (match_operator:XF 3 "binary_fp_operator"
14451 [(match_operand:XF 1 "register_operand" "%0")
14452 (match_operand:XF 2 "register_operand" "f")]))]
14453 "TARGET_80387
14454 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14455 "* return output_387_binary_op (insn, operands);"
14456 [(set (attr "type")
14457 (if_then_else (match_operand:XF 3 "mult_operator" "")
14458 (const_string "fmul")
14459 (const_string "fop")))
14460 (set_attr "mode" "XF")])
14461
14462(define_insn "*fop_sf_1_nosse"
14463 [(set (match_operand:SF 0 "register_operand" "=f,f")
14464 (match_operator:SF 3 "binary_fp_operator"
14465 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14466 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14467 "TARGET_80387 && !TARGET_SSE_MATH
14468 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14469 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14470 "* return output_387_binary_op (insn, operands);"
14471 [(set (attr "type")
14472 (cond [(match_operand:SF 3 "mult_operator" "")
14473 (const_string "fmul")
14474 (match_operand:SF 3 "div_operator" "")
14475 (const_string "fdiv")
14476 ]
14477 (const_string "fop")))
14478 (set_attr "mode" "SF")])
14479
14480(define_insn "*fop_sf_1"
14481 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14482 (match_operator:SF 3 "binary_fp_operator"
14483 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14484 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14485 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14486 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14487 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14488 "* return output_387_binary_op (insn, operands);"
14489 [(set (attr "type")
14490 (cond [(and (eq_attr "alternative" "2")
14491 (match_operand:SF 3 "mult_operator" ""))
14492 (const_string "ssemul")
14493 (and (eq_attr "alternative" "2")
14494 (match_operand:SF 3 "div_operator" ""))
14495 (const_string "ssediv")
14496 (eq_attr "alternative" "2")
14497 (const_string "sseadd")
14498 (match_operand:SF 3 "mult_operator" "")
14499 (const_string "fmul")
14500 (match_operand:SF 3 "div_operator" "")
14501 (const_string "fdiv")
14502 ]
14503 (const_string "fop")))
14504 (set_attr "mode" "SF")])
14505
14506(define_insn "*fop_sf_1_sse"
14507 [(set (match_operand:SF 0 "register_operand" "=x")
14508 (match_operator:SF 3 "binary_fp_operator"
14509 [(match_operand:SF 1 "register_operand" "0")
14510 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14511 "TARGET_SSE_MATH
14512 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14513 "* return output_387_binary_op (insn, operands);"
14514 [(set (attr "type")
14515 (cond [(match_operand:SF 3 "mult_operator" "")
14516 (const_string "ssemul")
14517 (match_operand:SF 3 "div_operator" "")
14518 (const_string "ssediv")
14519 ]
14520 (const_string "sseadd")))
14521 (set_attr "mode" "SF")])
14522
14523;; ??? Add SSE splitters for these!
14524(define_insn "*fop_sf_2"
14525 [(set (match_operand:SF 0 "register_operand" "=f,f")
14526 (match_operator:SF 3 "binary_fp_operator"
14527 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14528 (match_operand:SF 2 "register_operand" "0,0")]))]
14529 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14530 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14531 [(set (attr "type")
14532 (cond [(match_operand:SF 3 "mult_operator" "")
14533 (const_string "fmul")
14534 (match_operand:SF 3 "div_operator" "")
14535 (const_string "fdiv")
14536 ]
14537 (const_string "fop")))
14538 (set_attr "fp_int_src" "true")
14539 (set_attr "ppro_uops" "many")
14540 (set_attr "mode" "SI")])
14541
14542(define_insn "*fop_sf_3"
14543 [(set (match_operand:SF 0 "register_operand" "=f,f")
14544 (match_operator:SF 3 "binary_fp_operator"
14545 [(match_operand:SF 1 "register_operand" "0,0")
14546 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14547 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14548 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14549 [(set (attr "type")
14550 (cond [(match_operand:SF 3 "mult_operator" "")
14551 (const_string "fmul")
14552 (match_operand:SF 3 "div_operator" "")
14553 (const_string "fdiv")
14554 ]
14555 (const_string "fop")))
14556 (set_attr "fp_int_src" "true")
14557 (set_attr "ppro_uops" "many")
14558 (set_attr "mode" "SI")])
14559
14560(define_insn "*fop_df_1_nosse"
14561 [(set (match_operand:DF 0 "register_operand" "=f,f")
14562 (match_operator:DF 3 "binary_fp_operator"
14563 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14564 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14565 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14566 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14567 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14568 "* return output_387_binary_op (insn, operands);"
14569 [(set (attr "type")
14570 (cond [(match_operand:DF 3 "mult_operator" "")
14571 (const_string "fmul")
14572 (match_operand:DF 3 "div_operator" "")
14573 (const_string "fdiv")
14574 ]
14575 (const_string "fop")))
14576 (set_attr "mode" "DF")])
14577
14578
14579(define_insn "*fop_df_1"
14580 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14581 (match_operator:DF 3 "binary_fp_operator"
14582 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14583 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14584 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14585 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14586 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14587 "* return output_387_binary_op (insn, operands);"
14588 [(set (attr "type")
14589 (cond [(and (eq_attr "alternative" "2")
14590 (match_operand:SF 3 "mult_operator" ""))
14591 (const_string "ssemul")
14592 (and (eq_attr "alternative" "2")
14593 (match_operand:SF 3 "div_operator" ""))
14594 (const_string "ssediv")
14595 (eq_attr "alternative" "2")
14596 (const_string "sseadd")
14597 (match_operand:DF 3 "mult_operator" "")
14598 (const_string "fmul")
14599 (match_operand:DF 3 "div_operator" "")
14600 (const_string "fdiv")
14601 ]
14602 (const_string "fop")))
14603 (set_attr "mode" "DF")])
14604
14605(define_insn "*fop_df_1_sse"
14606 [(set (match_operand:DF 0 "register_operand" "=Y")
14607 (match_operator:DF 3 "binary_fp_operator"
14608 [(match_operand:DF 1 "register_operand" "0")
14609 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14610 "TARGET_SSE2 && TARGET_SSE_MATH
14611 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14612 "* return output_387_binary_op (insn, operands);"
14613 [(set_attr "mode" "DF")
14614 (set (attr "type")
14615 (cond [(match_operand:SF 3 "mult_operator" "")
14616 (const_string "ssemul")
14617 (match_operand:SF 3 "div_operator" "")
14618 (const_string "ssediv")
14619 ]
14620 (const_string "sseadd")))])
14621
14622;; ??? Add SSE splitters for these!
14623(define_insn "*fop_df_2"
14624 [(set (match_operand:DF 0 "register_operand" "=f,f")
14625 (match_operator:DF 3 "binary_fp_operator"
14626 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14627 (match_operand:DF 2 "register_operand" "0,0")]))]
14628 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14629 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14630 [(set (attr "type")
14631 (cond [(match_operand:DF 3 "mult_operator" "")
14632 (const_string "fmul")
14633 (match_operand:DF 3 "div_operator" "")
14634 (const_string "fdiv")
14635 ]
14636 (const_string "fop")))
14637 (set_attr "fp_int_src" "true")
14638 (set_attr "ppro_uops" "many")
14639 (set_attr "mode" "SI")])
14640
14641(define_insn "*fop_df_3"
14642 [(set (match_operand:DF 0 "register_operand" "=f,f")
14643 (match_operator:DF 3 "binary_fp_operator"
14644 [(match_operand:DF 1 "register_operand" "0,0")
14645 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14646 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14647 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14648 [(set (attr "type")
14649 (cond [(match_operand:DF 3 "mult_operator" "")
14650 (const_string "fmul")
14651 (match_operand:DF 3 "div_operator" "")
14652 (const_string "fdiv")
14653 ]
14654 (const_string "fop")))
14655 (set_attr "fp_int_src" "true")
14656 (set_attr "ppro_uops" "many")
14657 (set_attr "mode" "SI")])
14658
14659(define_insn "*fop_df_4"
14660 [(set (match_operand:DF 0 "register_operand" "=f,f")
14661 (match_operator:DF 3 "binary_fp_operator"
14662 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14663 (match_operand:DF 2 "register_operand" "0,f")]))]
14664 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14666 "* return output_387_binary_op (insn, operands);"
14667 [(set (attr "type")
14668 (cond [(match_operand:DF 3 "mult_operator" "")
14669 (const_string "fmul")
14670 (match_operand:DF 3 "div_operator" "")
14671 (const_string "fdiv")
14672 ]
14673 (const_string "fop")))
14674 (set_attr "mode" "SF")])
14675
14676(define_insn "*fop_df_5"
14677 [(set (match_operand:DF 0 "register_operand" "=f,f")
14678 (match_operator:DF 3 "binary_fp_operator"
14679 [(match_operand:DF 1 "register_operand" "0,f")
14680 (float_extend:DF
14681 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14682 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14683 "* return output_387_binary_op (insn, operands);"
14684 [(set (attr "type")
14685 (cond [(match_operand:DF 3 "mult_operator" "")
14686 (const_string "fmul")
14687 (match_operand:DF 3 "div_operator" "")
14688 (const_string "fdiv")
14689 ]
14690 (const_string "fop")))
14691 (set_attr "mode" "SF")])
14692
14693(define_insn "*fop_df_6"
14694 [(set (match_operand:DF 0 "register_operand" "=f,f")
14695 (match_operator:DF 3 "binary_fp_operator"
14696 [(float_extend:DF
14697 (match_operand:SF 1 "register_operand" "0,f"))
14698 (float_extend:DF
14699 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14700 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14701 "* return output_387_binary_op (insn, operands);"
14702 [(set (attr "type")
14703 (cond [(match_operand:DF 3 "mult_operator" "")
14704 (const_string "fmul")
14705 (match_operand:DF 3 "div_operator" "")
14706 (const_string "fdiv")
14707 ]
14708 (const_string "fop")))
14709 (set_attr "mode" "SF")])
14710
14711(define_insn "*fop_xf_1"
14712 [(set (match_operand:XF 0 "register_operand" "=f,f")
14713 (match_operator:XF 3 "binary_fp_operator"
14714 [(match_operand:XF 1 "register_operand" "0,f")
14715 (match_operand:XF 2 "register_operand" "f,0")]))]
14716 "TARGET_80387
14717 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14718 "* return output_387_binary_op (insn, operands);"
14719 [(set (attr "type")
14720 (cond [(match_operand:XF 3 "mult_operator" "")
14721 (const_string "fmul")
14722 (match_operand:XF 3 "div_operator" "")
14723 (const_string "fdiv")
14724 ]
14725 (const_string "fop")))
14726 (set_attr "mode" "XF")])
14727
14728(define_insn "*fop_xf_2"
14729 [(set (match_operand:XF 0 "register_operand" "=f,f")
14730 (match_operator:XF 3 "binary_fp_operator"
14731 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14732 (match_operand:XF 2 "register_operand" "0,0")]))]
14733 "TARGET_80387 && TARGET_USE_FIOP"
14734 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14735 [(set (attr "type")
14736 (cond [(match_operand:XF 3 "mult_operator" "")
14737 (const_string "fmul")
14738 (match_operand:XF 3 "div_operator" "")
14739 (const_string "fdiv")
14740 ]
14741 (const_string "fop")))
14742 (set_attr "fp_int_src" "true")
14743 (set_attr "mode" "SI")
14744 (set_attr "ppro_uops" "many")])
14745
14746(define_insn "*fop_xf_3"
14747 [(set (match_operand:XF 0 "register_operand" "=f,f")
14748 (match_operator:XF 3 "binary_fp_operator"
14749 [(match_operand:XF 1 "register_operand" "0,0")
14750 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14751 "TARGET_80387 && TARGET_USE_FIOP"
14752 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14753 [(set (attr "type")
14754 (cond [(match_operand:XF 3 "mult_operator" "")
14755 (const_string "fmul")
14756 (match_operand:XF 3 "div_operator" "")
14757 (const_string "fdiv")
14758 ]
14759 (const_string "fop")))
14760 (set_attr "fp_int_src" "true")
14761 (set_attr "mode" "SI")
14762 (set_attr "ppro_uops" "many")])
14763
14764(define_insn "*fop_xf_4"
14765 [(set (match_operand:XF 0 "register_operand" "=f,f")
14766 (match_operator:XF 3 "binary_fp_operator"
14767 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14768 (match_operand:XF 2 "register_operand" "0,f")]))]
14769 "TARGET_80387"
14770 "* return output_387_binary_op (insn, operands);"
14771 [(set (attr "type")
14772 (cond [(match_operand:XF 3 "mult_operator" "")
14773 (const_string "fmul")
14774 (match_operand:XF 3 "div_operator" "")
14775 (const_string "fdiv")
14776 ]
14777 (const_string "fop")))
14778 (set_attr "mode" "SF")])
14779
14780(define_insn "*fop_xf_5"
14781 [(set (match_operand:XF 0 "register_operand" "=f,f")
14782 (match_operator:XF 3 "binary_fp_operator"
14783 [(match_operand:XF 1 "register_operand" "0,f")
14784 (float_extend:XF
14785 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14786 "TARGET_80387"
14787 "* return output_387_binary_op (insn, operands);"
14788 [(set (attr "type")
14789 (cond [(match_operand:XF 3 "mult_operator" "")
14790 (const_string "fmul")
14791 (match_operand:XF 3 "div_operator" "")
14792 (const_string "fdiv")
14793 ]
14794 (const_string "fop")))
14795 (set_attr "mode" "SF")])
14796
14797(define_insn "*fop_xf_6"
14798 [(set (match_operand:XF 0 "register_operand" "=f,f")
14799 (match_operator:XF 3 "binary_fp_operator"
14800 [(float_extend:XF
14801 (match_operand 1 "register_operand" "0,f"))
14802 (float_extend:XF
14803 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14804 "TARGET_80387"
14805 "* return output_387_binary_op (insn, operands);"
14806 [(set (attr "type")
14807 (cond [(match_operand:XF 3 "mult_operator" "")
14808 (const_string "fmul")
14809 (match_operand:XF 3 "div_operator" "")
14810 (const_string "fdiv")
14811 ]
14812 (const_string "fop")))
14813 (set_attr "mode" "SF")])
14814
14815(define_split
14816 [(set (match_operand 0 "register_operand" "")
14817 (match_operator 3 "binary_fp_operator"
14818 [(float (match_operand:SI 1 "register_operand" ""))
14819 (match_operand 2 "register_operand" "")]))]
14820 "TARGET_80387 && reload_completed
14821 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14822 [(const_int 0)]
14823{
14824 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14825 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14826 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14827 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14828 GET_MODE (operands[3]),
14829 operands[4],
14830 operands[2])));
14831 ix86_free_from_memory (GET_MODE (operands[1]));
14832 DONE;
14833})
14834
14835(define_split
14836 [(set (match_operand 0 "register_operand" "")
14837 (match_operator 3 "binary_fp_operator"
14838 [(match_operand 1 "register_operand" "")
14839 (float (match_operand:SI 2 "register_operand" ""))]))]
14840 "TARGET_80387 && reload_completed
14841 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14842 [(const_int 0)]
14843{
14844 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14845 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14846 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14847 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14848 GET_MODE (operands[3]),
14849 operands[1],
14850 operands[4])));
14851 ix86_free_from_memory (GET_MODE (operands[2]));
14852 DONE;
14853})
14854
14855;; FPU special functions.
14856
14857(define_expand "sqrtsf2"
14858 [(set (match_operand:SF 0 "register_operand" "")
14859 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14860 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14861{
14862 if (!TARGET_SSE_MATH)
14863 operands[1] = force_reg (SFmode, operands[1]);
14864})
14865
14866(define_insn "sqrtsf2_1"
14867 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14868 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14869 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14870 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14871 "@
14872 fsqrt
14873 sqrtss\t{%1, %0|%0, %1}"
14874 [(set_attr "type" "fpspc,sse")
14875 (set_attr "mode" "SF,SF")
14876 (set_attr "athlon_decode" "direct,*")])
14877
14878(define_insn "sqrtsf2_1_sse_only"
14879 [(set (match_operand:SF 0 "register_operand" "=x")
14880 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14881 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14882 "sqrtss\t{%1, %0|%0, %1}"
14883 [(set_attr "type" "sse")
14884 (set_attr "mode" "SF")
14885 (set_attr "athlon_decode" "*")])
14886
14887(define_insn "sqrtsf2_i387"
14888 [(set (match_operand:SF 0 "register_operand" "=f")
14889 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14890 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14891 && !TARGET_SSE_MATH"
14892 "fsqrt"
14893 [(set_attr "type" "fpspc")
14894 (set_attr "mode" "SF")
14895 (set_attr "athlon_decode" "direct")])
14896
14897(define_expand "sqrtdf2"
14898 [(set (match_operand:DF 0 "register_operand" "")
14899 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14900 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14901 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14902{
14903 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14904 operands[1] = force_reg (DFmode, operands[1]);
14905})
14906
14907(define_insn "sqrtdf2_1"
14908 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14909 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14910 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14911 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14912 "@
14913 fsqrt
14914 sqrtsd\t{%1, %0|%0, %1}"
14915 [(set_attr "type" "fpspc,sse")
14916 (set_attr "mode" "DF,DF")
14917 (set_attr "athlon_decode" "direct,*")])
14918
14919(define_insn "sqrtdf2_1_sse_only"
14920 [(set (match_operand:DF 0 "register_operand" "=Y")
14921 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14922 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14923 "sqrtsd\t{%1, %0|%0, %1}"
14924 [(set_attr "type" "sse")
14925 (set_attr "mode" "DF")
14926 (set_attr "athlon_decode" "*")])
14927
14928(define_insn "sqrtdf2_i387"
14929 [(set (match_operand:DF 0 "register_operand" "=f")
14930 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14931 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14932 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14933 "fsqrt"
14934 [(set_attr "type" "fpspc")
14935 (set_attr "mode" "DF")
14936 (set_attr "athlon_decode" "direct")])
14937
14938(define_insn "*sqrtextendsfdf2"
14939 [(set (match_operand:DF 0 "register_operand" "=f")
14940 (sqrt:DF (float_extend:DF
14941 (match_operand:SF 1 "register_operand" "0"))))]
14942 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14943 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14944 "fsqrt"
14945 [(set_attr "type" "fpspc")
14946 (set_attr "mode" "DF")
14947 (set_attr "athlon_decode" "direct")])
14948
14949(define_insn "sqrtxf2"
14950 [(set (match_operand:XF 0 "register_operand" "=f")
14951 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14952 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14953 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14954 "fsqrt"
14955 [(set_attr "type" "fpspc")
14956 (set_attr "mode" "XF")
14957 (set_attr "athlon_decode" "direct")])
14958
14959(define_insn "*sqrtextenddfxf2"
14960 [(set (match_operand:XF 0 "register_operand" "=f")
14961 (sqrt:XF (float_extend:XF
14962 (match_operand:DF 1 "register_operand" "0"))))]
14963 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14964 "fsqrt"
14965 [(set_attr "type" "fpspc")
14966 (set_attr "mode" "XF")
14967 (set_attr "athlon_decode" "direct")])
14968
14969(define_insn "*sqrtextendsfxf2"
14970 [(set (match_operand:XF 0 "register_operand" "=f")
14971 (sqrt:XF (float_extend:XF
14972 (match_operand:SF 1 "register_operand" "0"))))]
14973 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14974 "fsqrt"
14975 [(set_attr "type" "fpspc")
14976 (set_attr "mode" "XF")
14977 (set_attr "athlon_decode" "direct")])
14978
14979(define_insn "sindf2"
14980 [(set (match_operand:DF 0 "register_operand" "=f")
14981 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14982 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14983 && flag_unsafe_math_optimizations"
14984 "fsin"
14985 [(set_attr "type" "fpspc")
14986 (set_attr "mode" "DF")])
14987
14988(define_insn "sinsf2"
14989 [(set (match_operand:SF 0 "register_operand" "=f")
14990 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14991 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14992 && flag_unsafe_math_optimizations"
14993 "fsin"
14994 [(set_attr "type" "fpspc")
14995 (set_attr "mode" "SF")])
14996
14997(define_insn "*sinextendsfdf2"
14998 [(set (match_operand:DF 0 "register_operand" "=f")
14999 (unspec:DF [(float_extend:DF
15000 (match_operand:SF 1 "register_operand" "0"))]
15001 UNSPEC_SIN))]
15002 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15003 && flag_unsafe_math_optimizations"
15004 "fsin"
15005 [(set_attr "type" "fpspc")
15006 (set_attr "mode" "DF")])
15007
15008(define_insn "sinxf2"
15009 [(set (match_operand:XF 0 "register_operand" "=f")
15010 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15011 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15012 && flag_unsafe_math_optimizations"
15013 "fsin"
15014 [(set_attr "type" "fpspc")
15015 (set_attr "mode" "XF")])
15016
15017(define_insn "cosdf2"
15018 [(set (match_operand:DF 0 "register_operand" "=f")
15019 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15020 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15021 && flag_unsafe_math_optimizations"
15022 "fcos"
15023 [(set_attr "type" "fpspc")
15024 (set_attr "mode" "DF")])
15025
15026(define_insn "cossf2"
15027 [(set (match_operand:SF 0 "register_operand" "=f")
15028 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15029 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15030 && flag_unsafe_math_optimizations"
15031 "fcos"
15032 [(set_attr "type" "fpspc")
15033 (set_attr "mode" "SF")])
15034
15035(define_insn "*cosextendsfdf2"
15036 [(set (match_operand:DF 0 "register_operand" "=f")
15037 (unspec:DF [(float_extend:DF
15038 (match_operand:SF 1 "register_operand" "0"))]
15039 UNSPEC_COS))]
15040 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15041 && flag_unsafe_math_optimizations"
15042 "fcos"
15043 [(set_attr "type" "fpspc")
15044 (set_attr "mode" "DF")])
15045
15046(define_insn "cosxf2"
15047 [(set (match_operand:XF 0 "register_operand" "=f")
15048 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15049 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15050 && flag_unsafe_math_optimizations"
15051 "fcos"
15052 [(set_attr "type" "fpspc")
15053 (set_attr "mode" "XF")])
15054
15055(define_insn "atan2df3_1"
15056 [(set (match_operand:DF 0 "register_operand" "=f")
15057 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15058 (match_operand:DF 1 "register_operand" "u")]
15059 UNSPEC_FPATAN))
15060 (clobber (match_scratch:DF 3 "=1"))]
15061 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15062 && flag_unsafe_math_optimizations"
15063 "fpatan"
15064 [(set_attr "type" "fpspc")
15065 (set_attr "mode" "DF")])
15066
15067(define_expand "atan2df3"
15068 [(use (match_operand:DF 0 "register_operand" "=f"))
15069 (use (match_operand:DF 2 "register_operand" "0"))
15070 (use (match_operand:DF 1 "register_operand" "u"))]
15071 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15072 && flag_unsafe_math_optimizations"
15073{
15074 rtx copy = gen_reg_rtx (DFmode);
15075 emit_move_insn (copy, operands[1]);
15076 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15077 DONE;
15078})
15079
15080(define_insn "atan2sf3_1"
15081 [(set (match_operand:SF 0 "register_operand" "=f")
15082 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15083 (match_operand:SF 1 "register_operand" "u")]
15084 UNSPEC_FPATAN))
15085 (clobber (match_scratch:SF 3 "=1"))]
15086 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15087 && flag_unsafe_math_optimizations"
15088 "fpatan"
15089 [(set_attr "type" "fpspc")
15090 (set_attr "mode" "SF")])
15091
15092(define_expand "atan2sf3"
15093 [(use (match_operand:SF 0 "register_operand" "=f"))
15094 (use (match_operand:SF 2 "register_operand" "0"))
15095 (use (match_operand:SF 1 "register_operand" "u"))]
15096 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15097 && flag_unsafe_math_optimizations"
15098{
15099 rtx copy = gen_reg_rtx (SFmode);
15100 emit_move_insn (copy, operands[1]);
15101 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15102 DONE;
15103})
15104
15105(define_insn "atan2xf3_1"
15106 [(set (match_operand:XF 0 "register_operand" "=f")
15107 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15108 (match_operand:XF 1 "register_operand" "u")]
15109 UNSPEC_FPATAN))
15110 (clobber (match_scratch:XF 3 "=1"))]
15111 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15112 && flag_unsafe_math_optimizations"
15113 "fpatan"
15114 [(set_attr "type" "fpspc")
15115 (set_attr "mode" "XF")])
15116
15117(define_expand "atan2xf3"
15118 [(use (match_operand:XF 0 "register_operand" "=f"))
15119 (use (match_operand:XF 2 "register_operand" "0"))
15120 (use (match_operand:XF 1 "register_operand" "u"))]
15121 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15122 && flag_unsafe_math_optimizations"
15123{
15124 rtx copy = gen_reg_rtx (XFmode);
15125 emit_move_insn (copy, operands[1]);
15126 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15127 DONE;
15128})
15129
15130(define_insn "*fyl2x_sfxf3"
15131 [(set (match_operand:SF 0 "register_operand" "=f")
15132 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15133 (match_operand:XF 1 "register_operand" "u")]
15134 UNSPEC_FYL2X))
15135 (clobber (match_scratch:SF 3 "=1"))]
15136 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15137 && flag_unsafe_math_optimizations"
15138 "fyl2x"
15139 [(set_attr "type" "fpspc")
15140 (set_attr "mode" "SF")])
15141
15142(define_insn "*fyl2x_dfxf3"
15143 [(set (match_operand:DF 0 "register_operand" "=f")
15144 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15145 (match_operand:XF 1 "register_operand" "u")]
15146 UNSPEC_FYL2X))
15147 (clobber (match_scratch:DF 3 "=1"))]
15148 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15149 && flag_unsafe_math_optimizations"
15150 "fyl2x"
15151 [(set_attr "type" "fpspc")
15152 (set_attr "mode" "DF")])
15153
15154(define_insn "*fyl2x_xf3"
15155 [(set (match_operand:XF 0 "register_operand" "=f")
15156 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15157 (match_operand:XF 1 "register_operand" "u")]
15158 UNSPEC_FYL2X))
15159 (clobber (match_scratch:XF 3 "=1"))]
15160 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15161 && flag_unsafe_math_optimizations"
15162 "fyl2x"
15163 [(set_attr "type" "fpspc")
15164 (set_attr "mode" "XF")])
15165
15166(define_expand "logsf2"
15167 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15168 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15169 (match_dup 2)] UNSPEC_FYL2X))
15170 (clobber (match_scratch:SF 3 ""))])]
15171 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15172 && flag_unsafe_math_optimizations"
15173{
15174 rtx temp;
15175
15176 operands[2] = gen_reg_rtx (XFmode);
15177 temp = standard_80387_constant_rtx (4); /* fldln2 */
15178 emit_move_insn (operands[2], temp);
15179})
15180
15181(define_expand "logdf2"
15182 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15183 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15184 (match_dup 2)] UNSPEC_FYL2X))
15185 (clobber (match_scratch:DF 3 ""))])]
15186 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15187 && flag_unsafe_math_optimizations"
15188{
15189 rtx temp;
15190
15191 operands[2] = gen_reg_rtx (XFmode);
15192 temp = standard_80387_constant_rtx (4); /* fldln2 */
15193 emit_move_insn (operands[2], temp);
15194})
15195
15196(define_expand "logxf2"
15197 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15198 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15199 (match_dup 2)] UNSPEC_FYL2X))
15200 (clobber (match_scratch:XF 3 ""))])]
15201 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15202 && flag_unsafe_math_optimizations"
15203{
15204 rtx temp;
15205
15206 operands[2] = gen_reg_rtx (XFmode);
15207 temp = standard_80387_constant_rtx (4); /* fldln2 */
15208 emit_move_insn (operands[2], temp);
15209})
15210
15211(define_insn "*fscale_sfxf3"
15212 [(set (match_operand:SF 0 "register_operand" "=f")
15213 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15214 (match_operand:XF 1 "register_operand" "u")]
15215 UNSPEC_FSCALE))
15216 (clobber (match_scratch:SF 3 "=1"))]
15217 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15218 && flag_unsafe_math_optimizations"
15219 "fscale\;fstp\t%y1"
15220 [(set_attr "type" "fpspc")
15221 (set_attr "mode" "SF")])
15222
15223(define_insn "*fscale_dfxf3"
15224 [(set (match_operand:DF 0 "register_operand" "=f")
15225 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15226 (match_operand:XF 1 "register_operand" "u")]
15227 UNSPEC_FSCALE))
15228 (clobber (match_scratch:DF 3 "=1"))]
15229 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15230 && flag_unsafe_math_optimizations"
15231 "fscale\;fstp\t%y1"
15232 [(set_attr "type" "fpspc")
15233 (set_attr "mode" "DF")])
15234
15235(define_insn "*fscale_xf3"
15236 [(set (match_operand:XF 0 "register_operand" "=f")
15237 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15238 (match_operand:XF 1 "register_operand" "u")]
15239 UNSPEC_FSCALE))
15240 (clobber (match_scratch:XF 3 "=1"))]
15241 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15242 && flag_unsafe_math_optimizations"
15243 "fscale\;fstp\t%y1"
15244 [(set_attr "type" "fpspc")
15245 (set_attr "mode" "XF")])
15246
15247(define_insn "*frndintxf2"
15248 [(set (match_operand:XF 0 "register_operand" "=f")
15249 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15250 UNSPEC_FRNDINT))]
15251 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15252 && flag_unsafe_math_optimizations"
15253 "frndint"
15254 [(set_attr "type" "fpspc")
15255 (set_attr "mode" "XF")])
15256
15257(define_insn "*f2xm1xf2"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260 UNSPEC_F2XM1))]
15261 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15262 && flag_unsafe_math_optimizations"
15263 "f2xm1"
15264 [(set_attr "type" "fpspc")
15265 (set_attr "mode" "XF")])
15266
15267(define_expand "expsf2"
15268 [(set (match_dup 2)
15269 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15270 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15271 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15272 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15273 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15274 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15275 (parallel [(set (match_operand:SF 0 "register_operand" "")
15276 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15277 (clobber (match_scratch:SF 5 ""))])]
15278 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15279 && flag_unsafe_math_optimizations"
15280{
15281 rtx temp;
15282 int i;
15283
15284 for (i=2; i<10; i++)
15285 operands[i] = gen_reg_rtx (XFmode);
15286 temp = standard_80387_constant_rtx (5); /* fldl2e */
15287 emit_move_insn (operands[3], temp);
15288 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15289})
15290
15291(define_expand "expdf2"
15292 [(set (match_dup 2)
15293 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15294 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15295 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15296 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15297 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15298 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15299 (parallel [(set (match_operand:DF 0 "register_operand" "")
15300 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15301 (clobber (match_scratch:DF 5 ""))])]
15302 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15303 && flag_unsafe_math_optimizations"
15304{
15305 rtx temp;
15306 int i;
15307
15308 for (i=2; i<10; i++)
15309 operands[i] = gen_reg_rtx (XFmode);
15310 temp = standard_80387_constant_rtx (5); /* fldl2e */
15311 emit_move_insn (operands[3], temp);
15312 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15313})
15314
15315(define_expand "expxf2"
15316 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15317 (match_dup 2)))
15318 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15319 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15320 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15321 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15322 (parallel [(set (match_operand:XF 0 "register_operand" "")
15323 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15324 (clobber (match_scratch:XF 5 ""))])]
15325 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15326 && flag_unsafe_math_optimizations"
15327{
15328 rtx temp;
15329 int i;
15330
15331 for (i=2; i<9; i++)
15332 operands[i] = gen_reg_rtx (XFmode);
15333 temp = standard_80387_constant_rtx (5); /* fldl2e */
15334 emit_move_insn (operands[2], temp);
15335 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15336})
15337
15338(define_expand "atansf2"
15339 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15340 (unspec:SF [(match_dup 2)
15341 (match_operand:SF 1 "register_operand" "")]
15342 UNSPEC_FPATAN))
15343 (clobber (match_scratch:SF 3 ""))])]
15344 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15345 && flag_unsafe_math_optimizations"
15346{
15347 operands[2] = gen_reg_rtx (SFmode);
15348 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15349})
15350
15351(define_expand "atandf2"
15352 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15353 (unspec:DF [(match_dup 2)
15354 (match_operand:DF 1 "register_operand" "")]
15355 UNSPEC_FPATAN))
15356 (clobber (match_scratch:DF 3 ""))])]
15357 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15358 && flag_unsafe_math_optimizations"
15359{
15360 operands[2] = gen_reg_rtx (DFmode);
15361 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15362})
15363
15364(define_expand "atanxf2"
15365 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15366 (unspec:XF [(match_dup 2)
15367 (match_operand:XF 1 "register_operand" "")]
15368 UNSPEC_FPATAN))
15369 (clobber (match_scratch:XF 3 ""))])]
15370 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15371 && flag_unsafe_math_optimizations"
15372{
15373 operands[2] = gen_reg_rtx (XFmode);
15374 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15375})
15376
15377;; Block operation instructions
15378
15379(define_insn "cld"
15380 [(set (reg:SI 19) (const_int 0))]
15381 ""
15382 "cld"
15383 [(set_attr "type" "cld")])
15384
15385(define_expand "movstrsi"
15386 [(use (match_operand:BLK 0 "memory_operand" ""))
15387 (use (match_operand:BLK 1 "memory_operand" ""))
15388 (use (match_operand:SI 2 "nonmemory_operand" ""))
15389 (use (match_operand:SI 3 "const_int_operand" ""))]
15390 "! optimize_size"
15391{
15392 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15393 DONE;
15394 else
15395 FAIL;
15396})
15397
15398(define_expand "movstrdi"
15399 [(use (match_operand:BLK 0 "memory_operand" ""))
15400 (use (match_operand:BLK 1 "memory_operand" ""))
15401 (use (match_operand:DI 2 "nonmemory_operand" ""))
15402 (use (match_operand:DI 3 "const_int_operand" ""))]
15403 "TARGET_64BIT"
15404{
15405 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15406 DONE;
15407 else
15408 FAIL;
15409})
15410
15411;; Most CPUs don't like single string operations
15412;; Handle this case here to simplify previous expander.
15413
15414(define_expand "strmov"
15415 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15416 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15417 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15418 (clobber (reg:CC 17))])
15419 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15420 (clobber (reg:CC 17))])]
15421 ""
15422{
15423 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15424
15425 /* If .md ever supports :P for Pmode, these can be directly
15426 in the pattern above. */
15427 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15428 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15429
15430 if (TARGET_SINGLE_STRINGOP || optimize_size)
15431 {
15432 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15433 operands[2], operands[3],
15434 operands[5], operands[6]));
15435 DONE;
15436 }
15437
15438 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15439})
15440
15441(define_expand "strmov_singleop"
15442 [(parallel [(set (match_operand 1 "memory_operand" "")
15443 (match_operand 3 "memory_operand" ""))
15444 (set (match_operand 0 "register_operand" "")
15445 (match_operand 4 "" ""))
15446 (set (match_operand 2 "register_operand" "")
15447 (match_operand 5 "" ""))
15448 (use (reg:SI 19))])]
15449 "TARGET_SINGLE_STRINGOP || optimize_size"
15450 "")
15451
15452(define_insn "*strmovdi_rex_1"
15453 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15454 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15455 (set (match_operand:DI 0 "register_operand" "=D")
15456 (plus:DI (match_dup 2)
15457 (const_int 8)))
15458 (set (match_operand:DI 1 "register_operand" "=S")
15459 (plus:DI (match_dup 3)
15460 (const_int 8)))
15461 (use (reg:SI 19))]
15462 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15463 "movsq"
15464 [(set_attr "type" "str")
15465 (set_attr "mode" "DI")
15466 (set_attr "memory" "both")])
15467
15468(define_insn "*strmovsi_1"
15469 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15470 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15471 (set (match_operand:SI 0 "register_operand" "=D")
15472 (plus:SI (match_dup 2)
15473 (const_int 4)))
15474 (set (match_operand:SI 1 "register_operand" "=S")
15475 (plus:SI (match_dup 3)
15476 (const_int 4)))
15477 (use (reg:SI 19))]
15478 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15479 "{movsl|movsd}"
15480 [(set_attr "type" "str")
15481 (set_attr "mode" "SI")
15482 (set_attr "memory" "both")])
15483
15484(define_insn "*strmovsi_rex_1"
15485 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15486 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15487 (set (match_operand:DI 0 "register_operand" "=D")
15488 (plus:DI (match_dup 2)
15489 (const_int 4)))
15490 (set (match_operand:DI 1 "register_operand" "=S")
15491 (plus:DI (match_dup 3)
15492 (const_int 4)))
15493 (use (reg:SI 19))]
15494 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15495 "{movsl|movsd}"
15496 [(set_attr "type" "str")
15497 (set_attr "mode" "SI")
15498 (set_attr "memory" "both")])
15499
15500(define_insn "*strmovhi_1"
15501 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15502 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15503 (set (match_operand:SI 0 "register_operand" "=D")
15504 (plus:SI (match_dup 2)
15505 (const_int 2)))
15506 (set (match_operand:SI 1 "register_operand" "=S")
15507 (plus:SI (match_dup 3)
15508 (const_int 2)))
15509 (use (reg:SI 19))]
15510 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15511 "movsw"
15512 [(set_attr "type" "str")
15513 (set_attr "memory" "both")
15514 (set_attr "mode" "HI")])
15515
15516(define_insn "*strmovhi_rex_1"
15517 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15518 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15519 (set (match_operand:DI 0 "register_operand" "=D")
15520 (plus:DI (match_dup 2)
15521 (const_int 2)))
15522 (set (match_operand:DI 1 "register_operand" "=S")
15523 (plus:DI (match_dup 3)
15524 (const_int 2)))
15525 (use (reg:SI 19))]
15526 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15527 "movsw"
15528 [(set_attr "type" "str")
15529 (set_attr "memory" "both")
15530 (set_attr "mode" "HI")])
15531
15532(define_insn "*strmovqi_1"
15533 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15534 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15535 (set (match_operand:SI 0 "register_operand" "=D")
15536 (plus:SI (match_dup 2)
15537 (const_int 1)))
15538 (set (match_operand:SI 1 "register_operand" "=S")
15539 (plus:SI (match_dup 3)
15540 (const_int 1)))
15541 (use (reg:SI 19))]
15542 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15543 "movsb"
15544 [(set_attr "type" "str")
15545 (set_attr "memory" "both")
15546 (set_attr "mode" "QI")])
15547
15548(define_insn "*strmovqi_rex_1"
15549 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15550 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15551 (set (match_operand:DI 0 "register_operand" "=D")
15552 (plus:DI (match_dup 2)
15553 (const_int 1)))
15554 (set (match_operand:DI 1 "register_operand" "=S")
15555 (plus:DI (match_dup 3)
15556 (const_int 1)))
15557 (use (reg:SI 19))]
15558 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15559 "movsb"
15560 [(set_attr "type" "str")
15561 (set_attr "memory" "both")
15562 (set_attr "mode" "QI")])
15563
15564(define_expand "rep_mov"
15565 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15566 (set (match_operand 0 "register_operand" "")
15567 (match_operand 5 "" ""))
15568 (set (match_operand 2 "register_operand" "")
15569 (match_operand 6 "" ""))
15570 (set (match_operand 1 "memory_operand" "")
15571 (match_operand 3 "memory_operand" ""))
15572 (use (match_dup 4))
15573 (use (reg:SI 19))])]
15574 ""
15575 "")
15576
15577(define_insn "*rep_movdi_rex64"
15578 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15579 (set (match_operand:DI 0 "register_operand" "=D")
15580 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15581 (const_int 3))
15582 (match_operand:DI 3 "register_operand" "0")))
15583 (set (match_operand:DI 1 "register_operand" "=S")
15584 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15585 (match_operand:DI 4 "register_operand" "1")))
15586 (set (mem:BLK (match_dup 3))
15587 (mem:BLK (match_dup 4)))
15588 (use (match_dup 5))
15589 (use (reg:SI 19))]
15590 "TARGET_64BIT"
15591 "{rep\;movsq|rep movsq}"
15592 [(set_attr "type" "str")
15593 (set_attr "prefix_rep" "1")
15594 (set_attr "memory" "both")
15595 (set_attr "mode" "DI")])
15596
15597(define_insn "*rep_movsi"
15598 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15599 (set (match_operand:SI 0 "register_operand" "=D")
15600 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15601 (const_int 2))
15602 (match_operand:SI 3 "register_operand" "0")))
15603 (set (match_operand:SI 1 "register_operand" "=S")
15604 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15605 (match_operand:SI 4 "register_operand" "1")))
15606 (set (mem:BLK (match_dup 3))
15607 (mem:BLK (match_dup 4)))
15608 (use (match_dup 5))
15609 (use (reg:SI 19))]
15610 "!TARGET_64BIT"
15611 "{rep\;movsl|rep movsd}"
15612 [(set_attr "type" "str")
15613 (set_attr "prefix_rep" "1")
15614 (set_attr "memory" "both")
15615 (set_attr "mode" "SI")])
15616
15617(define_insn "*rep_movsi_rex64"
15618 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15619 (set (match_operand:DI 0 "register_operand" "=D")
15620 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15621 (const_int 2))
15622 (match_operand:DI 3 "register_operand" "0")))
15623 (set (match_operand:DI 1 "register_operand" "=S")
15624 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15625 (match_operand:DI 4 "register_operand" "1")))
15626 (set (mem:BLK (match_dup 3))
15627 (mem:BLK (match_dup 4)))
15628 (use (match_dup 5))
15629 (use (reg:SI 19))]
15630 "TARGET_64BIT"
15631 "{rep\;movsl|rep movsd}"
15632 [(set_attr "type" "str")
15633 (set_attr "prefix_rep" "1")
15634 (set_attr "memory" "both")
15635 (set_attr "mode" "SI")])
15636
15637(define_insn "*rep_movqi"
15638 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15639 (set (match_operand:SI 0 "register_operand" "=D")
15640 (plus:SI (match_operand:SI 3 "register_operand" "0")
15641 (match_operand:SI 5 "register_operand" "2")))
15642 (set (match_operand:SI 1 "register_operand" "=S")
15643 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15644 (set (mem:BLK (match_dup 3))
15645 (mem:BLK (match_dup 4)))
15646 (use (match_dup 5))
15647 (use (reg:SI 19))]
15648 "!TARGET_64BIT"
15649 "{rep\;movsb|rep movsb}"
15650 [(set_attr "type" "str")
15651 (set_attr "prefix_rep" "1")
15652 (set_attr "memory" "both")
15653 (set_attr "mode" "SI")])
15654
15655(define_insn "*rep_movqi_rex64"
15656 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15657 (set (match_operand:DI 0 "register_operand" "=D")
15658 (plus:DI (match_operand:DI 3 "register_operand" "0")
15659 (match_operand:DI 5 "register_operand" "2")))
15660 (set (match_operand:DI 1 "register_operand" "=S")
15661 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15662 (set (mem:BLK (match_dup 3))
15663 (mem:BLK (match_dup 4)))
15664 (use (match_dup 5))
15665 (use (reg:SI 19))]
15666 "TARGET_64BIT"
15667 "{rep\;movsb|rep movsb}"
15668 [(set_attr "type" "str")
15669 (set_attr "prefix_rep" "1")
15670 (set_attr "memory" "both")
15671 (set_attr "mode" "SI")])
15672
15673(define_expand "clrstrsi"
15674 [(use (match_operand:BLK 0 "memory_operand" ""))
15675 (use (match_operand:SI 1 "nonmemory_operand" ""))
15676 (use (match_operand 2 "const_int_operand" ""))]
15677 ""
15678{
15679 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15680 DONE;
15681 else
15682 FAIL;
15683})
15684
15685(define_expand "clrstrdi"
15686 [(use (match_operand:BLK 0 "memory_operand" ""))
15687 (use (match_operand:DI 1 "nonmemory_operand" ""))
15688 (use (match_operand 2 "const_int_operand" ""))]
15689 "TARGET_64BIT"
15690{
15691 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15692 DONE;
15693 else
15694 FAIL;
15695})
15696
15697;; Most CPUs don't like single string operations
15698;; Handle this case here to simplify previous expander.
15699
15700(define_expand "strset"
15701 [(set (match_operand 1 "memory_operand" "")
15702 (match_operand 2 "register_operand" ""))
15703 (parallel [(set (match_operand 0 "register_operand" "")
15704 (match_dup 3))
15705 (clobber (reg:CC 17))])]
15706 ""
15707{
15708 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15709 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15710
15711 /* If .md ever supports :P for Pmode, this can be directly
15712 in the pattern above. */
15713 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15714 GEN_INT (GET_MODE_SIZE (GET_MODE
15715 (operands[2]))));
15716 if (TARGET_SINGLE_STRINGOP || optimize_size)
15717 {
15718 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15719 operands[3]));
15720 DONE;
15721 }
15722})
15723
15724(define_expand "strset_singleop"
15725 [(parallel [(set (match_operand 1 "memory_operand" "")
15726 (match_operand 2 "register_operand" ""))
15727 (set (match_operand 0 "register_operand" "")
15728 (match_operand 3 "" ""))
15729 (use (reg:SI 19))])]
15730 "TARGET_SINGLE_STRINGOP || optimize_size"
15731 "")
15732
15733(define_insn "*strsetdi_rex_1"
15734 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15735 (match_operand:SI 2 "register_operand" "a"))
15736 (set (match_operand:DI 0 "register_operand" "=D")
15737 (plus:DI (match_dup 1)
15738 (const_int 8)))
15739 (use (reg:SI 19))]
15740 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15741 "stosq"
15742 [(set_attr "type" "str")
15743 (set_attr "memory" "store")
15744 (set_attr "mode" "DI")])
15745
15746(define_insn "*strsetsi_1"
15747 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15748 (match_operand:SI 2 "register_operand" "a"))
15749 (set (match_operand:SI 0 "register_operand" "=D")
15750 (plus:SI (match_dup 1)
15751 (const_int 4)))
15752 (use (reg:SI 19))]
15753 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15754 "{stosl|stosd}"
15755 [(set_attr "type" "str")
15756 (set_attr "memory" "store")
15757 (set_attr "mode" "SI")])
15758
15759(define_insn "*strsetsi_rex_1"
15760 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15761 (match_operand:SI 2 "register_operand" "a"))
15762 (set (match_operand:DI 0 "register_operand" "=D")
15763 (plus:DI (match_dup 1)
15764 (const_int 4)))
15765 (use (reg:SI 19))]
15766 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15767 "{stosl|stosd}"
15768 [(set_attr "type" "str")
15769 (set_attr "memory" "store")
15770 (set_attr "mode" "SI")])
15771
15772(define_insn "*strsethi_1"
15773 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15774 (match_operand:HI 2 "register_operand" "a"))
15775 (set (match_operand:SI 0 "register_operand" "=D")
15776 (plus:SI (match_dup 1)
15777 (const_int 2)))
15778 (use (reg:SI 19))]
15779 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15780 "stosw"
15781 [(set_attr "type" "str")
15782 (set_attr "memory" "store")
15783 (set_attr "mode" "HI")])
15784
15785(define_insn "*strsethi_rex_1"
15786 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15787 (match_operand:HI 2 "register_operand" "a"))
15788 (set (match_operand:DI 0 "register_operand" "=D")
15789 (plus:DI (match_dup 1)
15790 (const_int 2)))
15791 (use (reg:SI 19))]
15792 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15793 "stosw"
15794 [(set_attr "type" "str")
15795 (set_attr "memory" "store")
15796 (set_attr "mode" "HI")])
15797
15798(define_insn "*strsetqi_1"
15799 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15800 (match_operand:QI 2 "register_operand" "a"))
15801 (set (match_operand:SI 0 "register_operand" "=D")
15802 (plus:SI (match_dup 1)
15803 (const_int 1)))
15804 (use (reg:SI 19))]
15805 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15806 "stosb"
15807 [(set_attr "type" "str")
15808 (set_attr "memory" "store")
15809 (set_attr "mode" "QI")])
15810
15811(define_insn "*strsetqi_rex_1"
15812 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15813 (match_operand:QI 2 "register_operand" "a"))
15814 (set (match_operand:DI 0 "register_operand" "=D")
15815 (plus:DI (match_dup 1)
15816 (const_int 1)))
15817 (use (reg:SI 19))]
15818 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15819 "stosb"
15820 [(set_attr "type" "str")
15821 (set_attr "memory" "store")
15822 (set_attr "mode" "QI")])
15823
15824(define_expand "rep_stos"
15825 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15826 (set (match_operand 0 "register_operand" "")
15827 (match_operand 4 "" ""))
15828 (set (match_operand 2 "memory_operand" "") (const_int 0))
15829 (use (match_operand 3 "register_operand" ""))
15830 (use (match_dup 1))
15831 (use (reg:SI 19))])]
15832 ""
15833 "")
15834
15835(define_insn "*rep_stosdi_rex64"
15836 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15837 (set (match_operand:DI 0 "register_operand" "=D")
15838 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15839 (const_int 3))
15840 (match_operand:DI 3 "register_operand" "0")))
15841 (set (mem:BLK (match_dup 3))
15842 (const_int 0))
15843 (use (match_operand:DI 2 "register_operand" "a"))
15844 (use (match_dup 4))
15845 (use (reg:SI 19))]
15846 "TARGET_64BIT"
15847 "{rep\;stosq|rep stosq}"
15848 [(set_attr "type" "str")
15849 (set_attr "prefix_rep" "1")
15850 (set_attr "memory" "store")
15851 (set_attr "mode" "DI")])
15852
15853(define_insn "*rep_stossi"
15854 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15855 (set (match_operand:SI 0 "register_operand" "=D")
15856 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15857 (const_int 2))
15858 (match_operand:SI 3 "register_operand" "0")))
15859 (set (mem:BLK (match_dup 3))
15860 (const_int 0))
15861 (use (match_operand:SI 2 "register_operand" "a"))
15862 (use (match_dup 4))
15863 (use (reg:SI 19))]
15864 "!TARGET_64BIT"
15865 "{rep\;stosl|rep stosd}"
15866 [(set_attr "type" "str")
15867 (set_attr "prefix_rep" "1")
15868 (set_attr "memory" "store")
15869 (set_attr "mode" "SI")])
15870
15871(define_insn "*rep_stossi_rex64"
15872 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15873 (set (match_operand:DI 0 "register_operand" "=D")
15874 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15875 (const_int 2))
15876 (match_operand:DI 3 "register_operand" "0")))
15877 (set (mem:BLK (match_dup 3))
15878 (const_int 0))
15879 (use (match_operand:SI 2 "register_operand" "a"))
15880 (use (match_dup 4))
15881 (use (reg:SI 19))]
15882 "TARGET_64BIT"
15883 "{rep\;stosl|rep stosd}"
15884 [(set_attr "type" "str")
15885 (set_attr "prefix_rep" "1")
15886 (set_attr "memory" "store")
15887 (set_attr "mode" "SI")])
15888
15889(define_insn "*rep_stosqi"
15890 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15891 (set (match_operand:SI 0 "register_operand" "=D")
15892 (plus:SI (match_operand:SI 3 "register_operand" "0")
15893 (match_operand:SI 4 "register_operand" "1")))
15894 (set (mem:BLK (match_dup 3))
15895 (const_int 0))
15896 (use (match_operand:QI 2 "register_operand" "a"))
15897 (use (match_dup 4))
15898 (use (reg:SI 19))]
15899 "!TARGET_64BIT"
15900 "{rep\;stosb|rep stosb}"
15901 [(set_attr "type" "str")
15902 (set_attr "prefix_rep" "1")
15903 (set_attr "memory" "store")
15904 (set_attr "mode" "QI")])
15905
15906(define_insn "*rep_stosqi_rex64"
15907 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15908 (set (match_operand:DI 0 "register_operand" "=D")
15909 (plus:DI (match_operand:DI 3 "register_operand" "0")
15910 (match_operand:DI 4 "register_operand" "1")))
15911 (set (mem:BLK (match_dup 3))
15912 (const_int 0))
15913 (use (match_operand:QI 2 "register_operand" "a"))
15914 (use (match_dup 4))
15915 (use (reg:SI 19))]
15916 "TARGET_64BIT"
15917 "{rep\;stosb|rep stosb}"
15918 [(set_attr "type" "str")
15919 (set_attr "prefix_rep" "1")
15920 (set_attr "memory" "store")
15921 (set_attr "mode" "QI")])
15922
15923(define_expand "cmpstrsi"
15924 [(set (match_operand:SI 0 "register_operand" "")
15925 (compare:SI (match_operand:BLK 1 "general_operand" "")
15926 (match_operand:BLK 2 "general_operand" "")))
15927 (use (match_operand 3 "general_operand" ""))
15928 (use (match_operand 4 "immediate_operand" ""))]
15929 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15930{
15931 rtx addr1, addr2, out, outlow, count, countreg, align;
15932
15933 /* Can't use this if the user has appropriated esi or edi. */
15934 if (global_regs[4] || global_regs[5])
15935 FAIL;
15936
15937 out = operands[0];
15938 if (GET_CODE (out) != REG)
15939 out = gen_reg_rtx (SImode);
15940
15941 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15942 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15943 if (addr1 != XEXP (operands[1], 0))
15944 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15945 if (addr2 != XEXP (operands[2], 0))
15946 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15947
15948 count = operands[3];
15949 countreg = ix86_zero_extend_to_Pmode (count);
15950
15951 /* %%% Iff we are testing strict equality, we can use known alignment
15952 to good advantage. This may be possible with combine, particularly
15953 once cc0 is dead. */
15954 align = operands[4];
15955
15956 emit_insn (gen_cld ());
15957 if (GET_CODE (count) == CONST_INT)
15958 {
15959 if (INTVAL (count) == 0)
15960 {
15961 emit_move_insn (operands[0], const0_rtx);
15962 DONE;
15963 }
15964 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15965 operands[1], operands[2]));
15966 }
15967 else
15968 {
15969 if (TARGET_64BIT)
15970 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15971 else
15972 emit_insn (gen_cmpsi_1 (countreg, countreg));
15973 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15974 operands[1], operands[2]));
15975 }
15976
15977 outlow = gen_lowpart (QImode, out);
15978 emit_insn (gen_cmpintqi (outlow));
15979 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15980
15981 if (operands[0] != out)
15982 emit_move_insn (operands[0], out);
15983
15984 DONE;
15985})
15986
15987;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15988
15989(define_expand "cmpintqi"
15990 [(set (match_dup 1)
15991 (gtu:QI (reg:CC 17) (const_int 0)))
15992 (set (match_dup 2)
15993 (ltu:QI (reg:CC 17) (const_int 0)))
15994 (parallel [(set (match_operand:QI 0 "register_operand" "")
15995 (minus:QI (match_dup 1)
15996 (match_dup 2)))
15997 (clobber (reg:CC 17))])]
15998 ""
15999 "operands[1] = gen_reg_rtx (QImode);
16000 operands[2] = gen_reg_rtx (QImode);")
16001
16002;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16003;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16004
16005(define_expand "cmpstrqi_nz_1"
16006 [(parallel [(set (reg:CC 17)
16007 (compare:CC (match_operand 4 "memory_operand" "")
16008 (match_operand 5 "memory_operand" "")))
16009 (use (match_operand 2 "register_operand" ""))
16010 (use (match_operand:SI 3 "immediate_operand" ""))
16011 (use (reg:SI 19))
16012 (clobber (match_operand 0 "register_operand" ""))
16013 (clobber (match_operand 1 "register_operand" ""))
16014 (clobber (match_dup 2))])]
16015 ""
16016 "")
16017
16018(define_insn "*cmpstrqi_nz_1"
16019 [(set (reg:CC 17)
16020 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16021 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16022 (use (match_operand:SI 6 "register_operand" "2"))
16023 (use (match_operand:SI 3 "immediate_operand" "i"))
16024 (use (reg:SI 19))
16025 (clobber (match_operand:SI 0 "register_operand" "=S"))
16026 (clobber (match_operand:SI 1 "register_operand" "=D"))
16027 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16028 "!TARGET_64BIT"
16029 "repz{\;| }cmpsb"
16030 [(set_attr "type" "str")
16031 (set_attr "mode" "QI")
16032 (set_attr "prefix_rep" "1")])
16033
16034(define_insn "*cmpstrqi_nz_rex_1"
16035 [(set (reg:CC 17)
16036 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16037 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16038 (use (match_operand:DI 6 "register_operand" "2"))
16039 (use (match_operand:SI 3 "immediate_operand" "i"))
16040 (use (reg:SI 19))
16041 (clobber (match_operand:DI 0 "register_operand" "=S"))
16042 (clobber (match_operand:DI 1 "register_operand" "=D"))
16043 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16044 "TARGET_64BIT"
16045 "repz{\;| }cmpsb"
16046 [(set_attr "type" "str")
16047 (set_attr "mode" "QI")
16048 (set_attr "prefix_rep" "1")])
16049
16050;; The same, but the count is not known to not be zero.
16051
16052(define_expand "cmpstrqi_1"
16053 [(parallel [(set (reg:CC 17)
16054 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16055 (const_int 0))
16056 (compare:CC (match_operand 4 "memory_operand" "")
16057 (match_operand 5 "memory_operand" ""))
16058 (const_int 0)))
16059 (use (match_operand:SI 3 "immediate_operand" ""))
16060 (use (reg:CC 17))
16061 (use (reg:SI 19))
16062 (clobber (match_operand 0 "register_operand" ""))
16063 (clobber (match_operand 1 "register_operand" ""))
16064 (clobber (match_dup 2))])]
16065 ""
16066 "")
16067
16068(define_insn "*cmpstrqi_1"
16069 [(set (reg:CC 17)
16070 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16071 (const_int 0))
16072 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16073 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16074 (const_int 0)))
16075 (use (match_operand:SI 3 "immediate_operand" "i"))
16076 (use (reg:CC 17))
16077 (use (reg:SI 19))
16078 (clobber (match_operand:SI 0 "register_operand" "=S"))
16079 (clobber (match_operand:SI 1 "register_operand" "=D"))
16080 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16081 "!TARGET_64BIT"
16082 "repz{\;| }cmpsb"
16083 [(set_attr "type" "str")
16084 (set_attr "mode" "QI")
16085 (set_attr "prefix_rep" "1")])
16086
16087(define_insn "*cmpstrqi_rex_1"
16088 [(set (reg:CC 17)
16089 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16090 (const_int 0))
16091 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16092 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16093 (const_int 0)))
16094 (use (match_operand:SI 3 "immediate_operand" "i"))
16095 (use (reg:CC 17))
16096 (use (reg:SI 19))
16097 (clobber (match_operand:DI 0 "register_operand" "=S"))
16098 (clobber (match_operand:DI 1 "register_operand" "=D"))
16099 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16100 "TARGET_64BIT"
16101 "repz{\;| }cmpsb"
16102 [(set_attr "type" "str")
16103 (set_attr "mode" "QI")
16104 (set_attr "prefix_rep" "1")])
16105
16106(define_expand "strlensi"
16107 [(set (match_operand:SI 0 "register_operand" "")
16108 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16109 (match_operand:QI 2 "immediate_operand" "")
16110 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16111 ""
16112{
16113 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16114 DONE;
16115 else
16116 FAIL;
16117})
16118
16119(define_expand "strlendi"
16120 [(set (match_operand:DI 0 "register_operand" "")
16121 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16122 (match_operand:QI 2 "immediate_operand" "")
16123 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16124 ""
16125{
16126 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16127 DONE;
16128 else
16129 FAIL;
16130})
16131
16132(define_expand "strlenqi_1"
16133 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16134 (use (reg:SI 19))
16135 (clobber (match_operand 1 "register_operand" ""))
16136 (clobber (reg:CC 17))])]
16137 ""
16138 "")
16139
16140(define_insn "*strlenqi_1"
16141 [(set (match_operand:SI 0 "register_operand" "=&c")
16142 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16143 (match_operand:QI 2 "register_operand" "a")
16144 (match_operand:SI 3 "immediate_operand" "i")
16145 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16146 (use (reg:SI 19))
16147 (clobber (match_operand:SI 1 "register_operand" "=D"))
16148 (clobber (reg:CC 17))]
16149 "!TARGET_64BIT"
16150 "repnz{\;| }scasb"
16151 [(set_attr "type" "str")
16152 (set_attr "mode" "QI")
16153 (set_attr "prefix_rep" "1")])
16154
16155(define_insn "*strlenqi_rex_1"
16156 [(set (match_operand:DI 0 "register_operand" "=&c")
16157 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16158 (match_operand:QI 2 "register_operand" "a")
16159 (match_operand:DI 3 "immediate_operand" "i")
16160 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16161 (use (reg:SI 19))
16162 (clobber (match_operand:DI 1 "register_operand" "=D"))
16163 (clobber (reg:CC 17))]
16164 "TARGET_64BIT"
16165 "repnz{\;| }scasb"
16166 [(set_attr "type" "str")
16167 (set_attr "mode" "QI")
16168 (set_attr "prefix_rep" "1")])
16169
16170;; Peephole optimizations to clean up after cmpstr*. This should be
16171;; handled in combine, but it is not currently up to the task.
16172;; When used for their truth value, the cmpstr* expanders generate
16173;; code like this:
16174;;
16175;; repz cmpsb
16176;; seta %al
16177;; setb %dl
16178;; cmpb %al, %dl
16179;; jcc label
16180;;
16181;; The intermediate three instructions are unnecessary.
16182
16183;; This one handles cmpstr*_nz_1...
16184(define_peephole2
16185 [(parallel[
16186 (set (reg:CC 17)
16187 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16188 (mem:BLK (match_operand 5 "register_operand" ""))))
16189 (use (match_operand 6 "register_operand" ""))
16190 (use (match_operand:SI 3 "immediate_operand" ""))
16191 (use (reg:SI 19))
16192 (clobber (match_operand 0 "register_operand" ""))
16193 (clobber (match_operand 1 "register_operand" ""))
16194 (clobber (match_operand 2 "register_operand" ""))])
16195 (set (match_operand:QI 7 "register_operand" "")
16196 (gtu:QI (reg:CC 17) (const_int 0)))
16197 (set (match_operand:QI 8 "register_operand" "")
16198 (ltu:QI (reg:CC 17) (const_int 0)))
16199 (set (reg 17)
16200 (compare (match_dup 7) (match_dup 8)))
16201 ]
16202 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16203 [(parallel[
16204 (set (reg:CC 17)
16205 (compare:CC (mem:BLK (match_dup 4))
16206 (mem:BLK (match_dup 5))))
16207 (use (match_dup 6))
16208 (use (match_dup 3))
16209 (use (reg:SI 19))
16210 (clobber (match_dup 0))
16211 (clobber (match_dup 1))
16212 (clobber (match_dup 2))])]
16213 "")
16214
16215;; ...and this one handles cmpstr*_1.
16216(define_peephole2
16217 [(parallel[
16218 (set (reg:CC 17)
16219 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16220 (const_int 0))
16221 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16222 (mem:BLK (match_operand 5 "register_operand" "")))
16223 (const_int 0)))
16224 (use (match_operand:SI 3 "immediate_operand" ""))
16225 (use (reg:CC 17))
16226 (use (reg:SI 19))
16227 (clobber (match_operand 0 "register_operand" ""))
16228 (clobber (match_operand 1 "register_operand" ""))
16229 (clobber (match_operand 2 "register_operand" ""))])
16230 (set (match_operand:QI 7 "register_operand" "")
16231 (gtu:QI (reg:CC 17) (const_int 0)))
16232 (set (match_operand:QI 8 "register_operand" "")
16233 (ltu:QI (reg:CC 17) (const_int 0)))
16234 (set (reg 17)
16235 (compare (match_dup 7) (match_dup 8)))
16236 ]
16237 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16238 [(parallel[
16239 (set (reg:CC 17)
16240 (if_then_else:CC (ne (match_dup 6)
16241 (const_int 0))
16242 (compare:CC (mem:BLK (match_dup 4))
16243 (mem:BLK (match_dup 5)))
16244 (const_int 0)))
16245 (use (match_dup 3))
16246 (use (reg:CC 17))
16247 (use (reg:SI 19))
16248 (clobber (match_dup 0))
16249 (clobber (match_dup 1))
16250 (clobber (match_dup 2))])]
16251 "")
16252
16253
16254
16255;; Conditional move instructions.
16256
16257(define_expand "movdicc"
16258 [(set (match_operand:DI 0 "register_operand" "")
16259 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16260 (match_operand:DI 2 "general_operand" "")
16261 (match_operand:DI 3 "general_operand" "")))]
16262 "TARGET_64BIT"
16263 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16264
16265(define_insn "x86_movdicc_0_m1_rex64"
16266 [(set (match_operand:DI 0 "register_operand" "=r")
16267 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16268 (const_int -1)
16269 (const_int 0)))
16270 (clobber (reg:CC 17))]
16271 "TARGET_64BIT"
16272 "sbb{q}\t%0, %0"
16273 ; Since we don't have the proper number of operands for an alu insn,
16274 ; fill in all the blanks.
16275 [(set_attr "type" "alu")
16276 (set_attr "pent_pair" "pu")
16277 (set_attr "memory" "none")
16278 (set_attr "imm_disp" "false")
16279 (set_attr "mode" "DI")
16280 (set_attr "length_immediate" "0")])
16281
16282(define_insn "movdicc_c_rex64"
16283 [(set (match_operand:DI 0 "register_operand" "=r,r")
16284 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16285 [(reg 17) (const_int 0)])
16286 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16287 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16288 "TARGET_64BIT && TARGET_CMOVE
16289 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16290 "@
16291 cmov%O2%C1\t{%2, %0|%0, %2}
16292 cmov%O2%c1\t{%3, %0|%0, %3}"
16293 [(set_attr "type" "icmov")
16294 (set_attr "mode" "DI")])
16295
16296(define_expand "movsicc"
16297 [(set (match_operand:SI 0 "register_operand" "")
16298 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16299 (match_operand:SI 2 "general_operand" "")
16300 (match_operand:SI 3 "general_operand" "")))]
16301 ""
16302 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16303
16304;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16305;; the register first winds up with `sbbl $0,reg', which is also weird.
16306;; So just document what we're doing explicitly.
16307
16308(define_insn "x86_movsicc_0_m1"
16309 [(set (match_operand:SI 0 "register_operand" "=r")
16310 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16311 (const_int -1)
16312 (const_int 0)))
16313 (clobber (reg:CC 17))]
16314 ""
16315 "sbb{l}\t%0, %0"
16316 ; Since we don't have the proper number of operands for an alu insn,
16317 ; fill in all the blanks.
16318 [(set_attr "type" "alu")
16319 (set_attr "pent_pair" "pu")
16320 (set_attr "memory" "none")
16321 (set_attr "imm_disp" "false")
16322 (set_attr "mode" "SI")
16323 (set_attr "length_immediate" "0")])
16324
16325(define_insn "*movsicc_noc"
16326 [(set (match_operand:SI 0 "register_operand" "=r,r")
16327 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16328 [(reg 17) (const_int 0)])
16329 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16330 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16331 "TARGET_CMOVE
16332 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16333 "@
16334 cmov%O2%C1\t{%2, %0|%0, %2}
16335 cmov%O2%c1\t{%3, %0|%0, %3}"
16336 [(set_attr "type" "icmov")
16337 (set_attr "mode" "SI")])
16338
16339(define_expand "movhicc"
16340 [(set (match_operand:HI 0 "register_operand" "")
16341 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16342 (match_operand:HI 2 "general_operand" "")
16343 (match_operand:HI 3 "general_operand" "")))]
16344 "TARGET_HIMODE_MATH"
16345 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16346
16347(define_insn "*movhicc_noc"
16348 [(set (match_operand:HI 0 "register_operand" "=r,r")
16349 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16350 [(reg 17) (const_int 0)])
16351 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16352 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16353 "TARGET_CMOVE
16354 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16355 "@
16356 cmov%O2%C1\t{%2, %0|%0, %2}
16357 cmov%O2%c1\t{%3, %0|%0, %3}"
16358 [(set_attr "type" "icmov")
16359 (set_attr "mode" "HI")])
16360
16361(define_expand "movqicc"
16362 [(set (match_operand:QI 0 "register_operand" "")
16363 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16364 (match_operand:QI 2 "general_operand" "")
16365 (match_operand:QI 3 "general_operand" "")))]
16366 "TARGET_QIMODE_MATH"
16367 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16368
16369(define_insn_and_split "*movqicc_noc"
16370 [(set (match_operand:QI 0 "register_operand" "=r,r")
16371 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16372 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16373 (match_operand:QI 2 "register_operand" "r,0")
16374 (match_operand:QI 3 "register_operand" "0,r")))]
16375 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16376 "#"
16377 "&& reload_completed"
16378 [(set (match_dup 0)
16379 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16380 (match_dup 2)
16381 (match_dup 3)))]
16382 "operands[0] = gen_lowpart (SImode, operands[0]);
16383 operands[2] = gen_lowpart (SImode, operands[2]);
16384 operands[3] = gen_lowpart (SImode, operands[3]);"
16385 [(set_attr "type" "icmov")
16386 (set_attr "mode" "SI")])
16387
16388(define_expand "movsfcc"
16389 [(set (match_operand:SF 0 "register_operand" "")
16390 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16391 (match_operand:SF 2 "register_operand" "")
16392 (match_operand:SF 3 "register_operand" "")))]
16393 "TARGET_CMOVE"
16394 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16395
16396(define_insn "*movsfcc_1"
16397 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16398 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16399 [(reg 17) (const_int 0)])
16400 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16401 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16402 "TARGET_CMOVE
16403 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16404 "@
16405 fcmov%F1\t{%2, %0|%0, %2}
16406 fcmov%f1\t{%3, %0|%0, %3}
16407 cmov%O2%C1\t{%2, %0|%0, %2}
16408 cmov%O2%c1\t{%3, %0|%0, %3}"
16409 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16410 (set_attr "mode" "SF,SF,SI,SI")])
16411
16412(define_expand "movdfcc"
16413 [(set (match_operand:DF 0 "register_operand" "")
16414 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16415 (match_operand:DF 2 "register_operand" "")
16416 (match_operand:DF 3 "register_operand" "")))]
16417 "TARGET_CMOVE"
16418 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16419
16420(define_insn "*movdfcc_1"
16421 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16422 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16423 [(reg 17) (const_int 0)])
16424 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16425 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16426 "!TARGET_64BIT && TARGET_CMOVE
16427 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16428 "@
16429 fcmov%F1\t{%2, %0|%0, %2}
16430 fcmov%f1\t{%3, %0|%0, %3}
16431 #
16432 #"
16433 [(set_attr "type" "fcmov,fcmov,multi,multi")
16434 (set_attr "mode" "DF")])
16435
16436(define_insn "*movdfcc_1_rex64"
16437 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16438 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16439 [(reg 17) (const_int 0)])
16440 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16441 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16442 "TARGET_64BIT && TARGET_CMOVE
16443 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16444 "@
16445 fcmov%F1\t{%2, %0|%0, %2}
16446 fcmov%f1\t{%3, %0|%0, %3}
16447 cmov%O2%C1\t{%2, %0|%0, %2}
16448 cmov%O2%c1\t{%3, %0|%0, %3}"
16449 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16450 (set_attr "mode" "DF")])
16451
16452(define_split
16453 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16454 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16455 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16456 (match_operand:DF 2 "nonimmediate_operand" "")
16457 (match_operand:DF 3 "nonimmediate_operand" "")))]
16458 "!TARGET_64BIT && reload_completed"
16459 [(set (match_dup 2)
16460 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16461 (match_dup 5)
16462 (match_dup 7)))
16463 (set (match_dup 3)
16464 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16465 (match_dup 6)
16466 (match_dup 8)))]
16467 "split_di (operands+2, 1, operands+5, operands+6);
16468 split_di (operands+3, 1, operands+7, operands+8);
16469 split_di (operands, 1, operands+2, operands+3);")
16470
16471(define_expand "movxfcc"
16472 [(set (match_operand:XF 0 "register_operand" "")
16473 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16474 (match_operand:XF 2 "register_operand" "")
16475 (match_operand:XF 3 "register_operand" "")))]
16476 "TARGET_CMOVE"
16477 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16478
16479(define_insn "*movxfcc_1"
16480 [(set (match_operand:XF 0 "register_operand" "=f,f")
16481 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16482 [(reg 17) (const_int 0)])
16483 (match_operand:XF 2 "register_operand" "f,0")
16484 (match_operand:XF 3 "register_operand" "0,f")))]
16485 "TARGET_CMOVE"
16486 "@
16487 fcmov%F1\t{%2, %0|%0, %2}
16488 fcmov%f1\t{%3, %0|%0, %3}"
16489 [(set_attr "type" "fcmov")
16490 (set_attr "mode" "XF")])
16491
16492(define_expand "minsf3"
16493 [(parallel [
16494 (set (match_operand:SF 0 "register_operand" "")
16495 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16496 (match_operand:SF 2 "nonimmediate_operand" ""))
16497 (match_dup 1)
16498 (match_dup 2)))
16499 (clobber (reg:CC 17))])]
16500 "TARGET_SSE"
16501 "")
16502
16503(define_insn "*minsf"
16504 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16505 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16506 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16507 (match_dup 1)
16508 (match_dup 2)))
16509 (clobber (reg:CC 17))]
16510 "TARGET_SSE && TARGET_IEEE_FP"
16511 "#")
16512
16513(define_insn "*minsf_nonieee"
16514 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16515 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16516 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16517 (match_dup 1)
16518 (match_dup 2)))
16519 (clobber (reg:CC 17))]
16520 "TARGET_SSE && !TARGET_IEEE_FP
16521 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16522 "#")
16523
16524(define_split
16525 [(set (match_operand:SF 0 "register_operand" "")
16526 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16527 (match_operand:SF 2 "nonimmediate_operand" ""))
16528 (match_operand:SF 3 "register_operand" "")
16529 (match_operand:SF 4 "nonimmediate_operand" "")))
16530 (clobber (reg:CC 17))]
16531 "SSE_REG_P (operands[0]) && reload_completed
16532 && ((operands_match_p (operands[1], operands[3])
16533 && operands_match_p (operands[2], operands[4]))
16534 || (operands_match_p (operands[1], operands[4])
16535 && operands_match_p (operands[2], operands[3])))"
16536 [(set (match_dup 0)
16537 (if_then_else:SF (lt (match_dup 1)
16538 (match_dup 2))
16539 (match_dup 1)
16540 (match_dup 2)))])
16541
16542;; Conditional addition patterns
16543(define_expand "addqicc"
16544 [(match_operand:QI 0 "register_operand" "")
16545 (match_operand 1 "comparison_operator" "")
16546 (match_operand:QI 2 "register_operand" "")
16547 (match_operand:QI 3 "const_int_operand" "")]
16548 ""
16549 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16550
16551(define_expand "addhicc"
16552 [(match_operand:HI 0 "register_operand" "")
16553 (match_operand 1 "comparison_operator" "")
16554 (match_operand:HI 2 "register_operand" "")
16555 (match_operand:HI 3 "const_int_operand" "")]
16556 ""
16557 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16558
16559(define_expand "addsicc"
16560 [(match_operand:SI 0 "register_operand" "")
16561 (match_operand 1 "comparison_operator" "")
16562 (match_operand:SI 2 "register_operand" "")
16563 (match_operand:SI 3 "const_int_operand" "")]
16564 ""
16565 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16566
16567(define_expand "adddicc"
16568 [(match_operand:DI 0 "register_operand" "")
16569 (match_operand 1 "comparison_operator" "")
16570 (match_operand:DI 2 "register_operand" "")
16571 (match_operand:DI 3 "const_int_operand" "")]
16572 "TARGET_64BIT"
16573 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16574
16575;; We can't represent the LT test directly. Do this by swapping the operands.
16576
16577(define_split
16578 [(set (match_operand:SF 0 "fp_register_operand" "")
16579 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16580 (match_operand:SF 2 "register_operand" ""))
16581 (match_operand:SF 3 "register_operand" "")
16582 (match_operand:SF 4 "register_operand" "")))
16583 (clobber (reg:CC 17))]
16584 "reload_completed
16585 && ((operands_match_p (operands[1], operands[3])
16586 && operands_match_p (operands[2], operands[4]))
16587 || (operands_match_p (operands[1], operands[4])
16588 && operands_match_p (operands[2], operands[3])))"
16589 [(set (reg:CCFP 17)
16590 (compare:CCFP (match_dup 2)
16591 (match_dup 1)))
16592 (set (match_dup 0)
16593 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16594 (match_dup 1)
16595 (match_dup 2)))])
16596
16597(define_insn "*minsf_sse"
16598 [(set (match_operand:SF 0 "register_operand" "=x")
16599 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16600 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16601 (match_dup 1)
16602 (match_dup 2)))]
16603 "TARGET_SSE && reload_completed"
16604 "minss\t{%2, %0|%0, %2}"
16605 [(set_attr "type" "sse")
16606 (set_attr "mode" "SF")])
16607
16608(define_expand "mindf3"
16609 [(parallel [
16610 (set (match_operand:DF 0 "register_operand" "")
16611 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16612 (match_operand:DF 2 "nonimmediate_operand" ""))
16613 (match_dup 1)
16614 (match_dup 2)))
16615 (clobber (reg:CC 17))])]
16616 "TARGET_SSE2 && TARGET_SSE_MATH"
16617 "#")
16618
16619(define_insn "*mindf"
16620 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16621 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16622 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16623 (match_dup 1)
16624 (match_dup 2)))
16625 (clobber (reg:CC 17))]
16626 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16627 "#")
16628
16629(define_insn "*mindf_nonieee"
16630 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16631 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16632 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16633 (match_dup 1)
16634 (match_dup 2)))
16635 (clobber (reg:CC 17))]
16636 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16637 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16638 "#")
16639
16640(define_split
16641 [(set (match_operand:DF 0 "register_operand" "")
16642 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16643 (match_operand:DF 2 "nonimmediate_operand" ""))
16644 (match_operand:DF 3 "register_operand" "")
16645 (match_operand:DF 4 "nonimmediate_operand" "")))
16646 (clobber (reg:CC 17))]
16647 "SSE_REG_P (operands[0]) && reload_completed
16648 && ((operands_match_p (operands[1], operands[3])
16649 && operands_match_p (operands[2], operands[4]))
16650 || (operands_match_p (operands[1], operands[4])
16651 && operands_match_p (operands[2], operands[3])))"
16652 [(set (match_dup 0)
16653 (if_then_else:DF (lt (match_dup 1)
16654 (match_dup 2))
16655 (match_dup 1)
16656 (match_dup 2)))])
16657
16658;; We can't represent the LT test directly. Do this by swapping the operands.
16659(define_split
16660 [(set (match_operand:DF 0 "fp_register_operand" "")
16661 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16662 (match_operand:DF 2 "register_operand" ""))
16663 (match_operand:DF 3 "register_operand" "")
16664 (match_operand:DF 4 "register_operand" "")))
16665 (clobber (reg:CC 17))]
16666 "reload_completed
16667 && ((operands_match_p (operands[1], operands[3])
16668 && operands_match_p (operands[2], operands[4]))
16669 || (operands_match_p (operands[1], operands[4])
16670 && operands_match_p (operands[2], operands[3])))"
16671 [(set (reg:CCFP 17)
16672 (compare:CCFP (match_dup 2)
16673 (match_dup 1)))
16674 (set (match_dup 0)
16675 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16676 (match_dup 1)
16677 (match_dup 2)))])
16678
16679(define_insn "*mindf_sse"
16680 [(set (match_operand:DF 0 "register_operand" "=Y")
16681 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16682 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16683 (match_dup 1)
16684 (match_dup 2)))]
16685 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16686 "minsd\t{%2, %0|%0, %2}"
16687 [(set_attr "type" "sse")
16688 (set_attr "mode" "DF")])
16689
16690(define_expand "maxsf3"
16691 [(parallel [
16692 (set (match_operand:SF 0 "register_operand" "")
16693 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16694 (match_operand:SF 2 "nonimmediate_operand" ""))
16695 (match_dup 1)
16696 (match_dup 2)))
16697 (clobber (reg:CC 17))])]
16698 "TARGET_SSE"
16699 "#")
16700
16701(define_insn "*maxsf"
16702 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16703 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16704 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16705 (match_dup 1)
16706 (match_dup 2)))
16707 (clobber (reg:CC 17))]
16708 "TARGET_SSE && TARGET_IEEE_FP"
16709 "#")
16710
16711(define_insn "*maxsf_nonieee"
16712 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16713 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16714 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16715 (match_dup 1)
16716 (match_dup 2)))
16717 (clobber (reg:CC 17))]
16718 "TARGET_SSE && !TARGET_IEEE_FP
16719 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16720 "#")
16721
16722(define_split
16723 [(set (match_operand:SF 0 "register_operand" "")
16724 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16725 (match_operand:SF 2 "nonimmediate_operand" ""))
16726 (match_operand:SF 3 "register_operand" "")
16727 (match_operand:SF 4 "nonimmediate_operand" "")))
16728 (clobber (reg:CC 17))]
16729 "SSE_REG_P (operands[0]) && reload_completed
16730 && ((operands_match_p (operands[1], operands[3])
16731 && operands_match_p (operands[2], operands[4]))
16732 || (operands_match_p (operands[1], operands[4])
16733 && operands_match_p (operands[2], operands[3])))"
16734 [(set (match_dup 0)
16735 (if_then_else:SF (gt (match_dup 1)
16736 (match_dup 2))
16737 (match_dup 1)
16738 (match_dup 2)))])
16739
16740(define_split
16741 [(set (match_operand:SF 0 "fp_register_operand" "")
16742 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16743 (match_operand:SF 2 "register_operand" ""))
16744 (match_operand:SF 3 "register_operand" "")
16745 (match_operand:SF 4 "register_operand" "")))
16746 (clobber (reg:CC 17))]
16747 "reload_completed
16748 && ((operands_match_p (operands[1], operands[3])
16749 && operands_match_p (operands[2], operands[4]))
16750 || (operands_match_p (operands[1], operands[4])
16751 && operands_match_p (operands[2], operands[3])))"
16752 [(set (reg:CCFP 17)
16753 (compare:CCFP (match_dup 1)
16754 (match_dup 2)))
16755 (set (match_dup 0)
16756 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16757 (match_dup 1)
16758 (match_dup 2)))])
16759
16760(define_insn "*maxsf_sse"
16761 [(set (match_operand:SF 0 "register_operand" "=x")
16762 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16763 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16764 (match_dup 1)
16765 (match_dup 2)))]
16766 "TARGET_SSE && reload_completed"
16767 "maxss\t{%2, %0|%0, %2}"
16768 [(set_attr "type" "sse")
16769 (set_attr "mode" "SF")])
16770
16771(define_expand "maxdf3"
16772 [(parallel [
16773 (set (match_operand:DF 0 "register_operand" "")
16774 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16775 (match_operand:DF 2 "nonimmediate_operand" ""))
16776 (match_dup 1)
16777 (match_dup 2)))
16778 (clobber (reg:CC 17))])]
16779 "TARGET_SSE2 && TARGET_SSE_MATH"
16780 "#")
16781
16782(define_insn "*maxdf"
16783 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16784 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16785 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16786 (match_dup 1)
16787 (match_dup 2)))
16788 (clobber (reg:CC 17))]
16789 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16790 "#")
16791
16792(define_insn "*maxdf_nonieee"
16793 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16794 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16795 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16796 (match_dup 1)
16797 (match_dup 2)))
16798 (clobber (reg:CC 17))]
16799 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16800 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16801 "#")
16802
16803(define_split
16804 [(set (match_operand:DF 0 "register_operand" "")
16805 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16806 (match_operand:DF 2 "nonimmediate_operand" ""))
16807 (match_operand:DF 3 "register_operand" "")
16808 (match_operand:DF 4 "nonimmediate_operand" "")))
16809 (clobber (reg:CC 17))]
16810 "SSE_REG_P (operands[0]) && reload_completed
16811 && ((operands_match_p (operands[1], operands[3])
16812 && operands_match_p (operands[2], operands[4]))
16813 || (operands_match_p (operands[1], operands[4])
16814 && operands_match_p (operands[2], operands[3])))"
16815 [(set (match_dup 0)
16816 (if_then_else:DF (gt (match_dup 1)
16817 (match_dup 2))
16818 (match_dup 1)
16819 (match_dup 2)))])
16820
16821(define_split
16822 [(set (match_operand:DF 0 "fp_register_operand" "")
16823 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16824 (match_operand:DF 2 "register_operand" ""))
16825 (match_operand:DF 3 "register_operand" "")
16826 (match_operand:DF 4 "register_operand" "")))
16827 (clobber (reg:CC 17))]
16828 "reload_completed
16829 && ((operands_match_p (operands[1], operands[3])
16830 && operands_match_p (operands[2], operands[4]))
16831 || (operands_match_p (operands[1], operands[4])
16832 && operands_match_p (operands[2], operands[3])))"
16833 [(set (reg:CCFP 17)
16834 (compare:CCFP (match_dup 1)
16835 (match_dup 2)))
16836 (set (match_dup 0)
16837 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16838 (match_dup 1)
16839 (match_dup 2)))])
16840
16841(define_insn "*maxdf_sse"
16842 [(set (match_operand:DF 0 "register_operand" "=Y")
16843 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16844 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16845 (match_dup 1)
16846 (match_dup 2)))]
16847 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16848 "maxsd\t{%2, %0|%0, %2}"
16849 [(set_attr "type" "sse")
16850 (set_attr "mode" "DF")])
16851
16852;; Misc patterns (?)
16853
16854;; This pattern exists to put a dependency on all ebp-based memory accesses.
16855;; Otherwise there will be nothing to keep
16856;;
16857;; [(set (reg ebp) (reg esp))]
16858;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16859;; (clobber (eflags)]
16860;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16861;;
16862;; in proper program order.
16863(define_insn "pro_epilogue_adjust_stack_1"
16864 [(set (match_operand:SI 0 "register_operand" "=r,r")
16865 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16866 (match_operand:SI 2 "immediate_operand" "i,i")))
16867 (clobber (reg:CC 17))
16868 (clobber (mem:BLK (scratch)))]
16869 "!TARGET_64BIT"
16870{
16871 switch (get_attr_type (insn))
16872 {
16873 case TYPE_IMOV:
16874 return "mov{l}\t{%1, %0|%0, %1}";
16875
16876 case TYPE_ALU:
16877 if (GET_CODE (operands[2]) == CONST_INT
16878 && (INTVAL (operands[2]) == 128
16879 || (INTVAL (operands[2]) < 0
16880 && INTVAL (operands[2]) != -128)))
16881 {
16882 operands[2] = GEN_INT (-INTVAL (operands[2]));
16883 return "sub{l}\t{%2, %0|%0, %2}";
16884 }
16885 return "add{l}\t{%2, %0|%0, %2}";
16886
16887 case TYPE_LEA:
16888 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16889 return "lea{l}\t{%a2, %0|%0, %a2}";
16890
16891 default:
16892 abort ();
16893 }
16894}
16895 [(set (attr "type")
16896 (cond [(eq_attr "alternative" "0")
16897 (const_string "alu")
16898 (match_operand:SI 2 "const0_operand" "")
16899 (const_string "imov")
16900 ]
16901 (const_string "lea")))
16902 (set_attr "mode" "SI")])
16903
16904(define_insn "pro_epilogue_adjust_stack_rex64"
16905 [(set (match_operand:DI 0 "register_operand" "=r,r")
16906 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16907 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16908 (clobber (reg:CC 17))
16909 (clobber (mem:BLK (scratch)))]
16910 "TARGET_64BIT"
16911{
16912 switch (get_attr_type (insn))
16913 {
16914 case TYPE_IMOV:
16915 return "mov{q}\t{%1, %0|%0, %1}";
16916
16917 case TYPE_ALU:
16918 if (GET_CODE (operands[2]) == CONST_INT
16919 /* Avoid overflows. */
16920 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16921 && (INTVAL (operands[2]) == 128
16922 || (INTVAL (operands[2]) < 0
16923 && INTVAL (operands[2]) != -128)))
16924 {
16925 operands[2] = GEN_INT (-INTVAL (operands[2]));
16926 return "sub{q}\t{%2, %0|%0, %2}";
16927 }
16928 return "add{q}\t{%2, %0|%0, %2}";
16929
16930 case TYPE_LEA:
16931 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16932 return "lea{q}\t{%a2, %0|%0, %a2}";
16933
16934 default:
16935 abort ();
16936 }
16937}
16938 [(set (attr "type")
16939 (cond [(eq_attr "alternative" "0")
16940 (const_string "alu")
16941 (match_operand:DI 2 "const0_operand" "")
16942 (const_string "imov")
16943 ]
16944 (const_string "lea")))
16945 (set_attr "mode" "DI")])
16946
16947(define_insn "pro_epilogue_adjust_stack_rex64_2"
16948 [(set (match_operand:DI 0 "register_operand" "=r,r")
16949 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16950 (match_operand:DI 3 "immediate_operand" "i,i")))
16951 (use (match_operand:DI 2 "register_operand" "r,r"))
16952 (clobber (reg:CC 17))
16953 (clobber (mem:BLK (scratch)))]
16954 "TARGET_64BIT"
16955{
16956 switch (get_attr_type (insn))
16957 {
16958 case TYPE_ALU:
16959 return "add{q}\t{%2, %0|%0, %2}";
16960
16961 case TYPE_LEA:
16962 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16963 return "lea{q}\t{%a2, %0|%0, %a2}";
16964
16965 default:
16966 abort ();
16967 }
16968}
16969 [(set_attr "type" "alu,lea")
16970 (set_attr "mode" "DI")])
16971
16972;; Placeholder for the conditional moves. This one is split either to SSE
16973;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16974;; fact is that compares supported by the cmp??ss instructions are exactly
16975;; swapped of those supported by cmove sequence.
16976;; The EQ/NE comparisons also needs bit care, since they are not directly
16977;; supported by i387 comparisons and we do need to emit two conditional moves
16978;; in tandem.
16979
16980(define_insn "sse_movsfcc"
16981 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16982 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16983 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16984 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16985 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16986 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16987 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16988 (clobber (reg:CC 17))]
16989 "TARGET_SSE
16990 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16991 /* Avoid combine from being smart and converting min/max
16992 instruction patterns into conditional moves. */
16993 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16994 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16995 || !rtx_equal_p (operands[4], operands[2])
16996 || !rtx_equal_p (operands[5], operands[3]))
16997 && (!TARGET_IEEE_FP
16998 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16999 "#")
17000
17001(define_insn "sse_movsfcc_eq"
17002 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17003 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17004 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17005 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17006 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17007 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17008 (clobber (reg:CC 17))]
17009 "TARGET_SSE
17010 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17011 "#")
17012
17013(define_insn "sse_movdfcc"
17014 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
17015 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17016 [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
17017 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
17018 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
17019 (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
17020 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17021 (clobber (reg:CC 17))]
17022 "TARGET_SSE2
17023 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17024 /* Avoid combine from being smart and converting min/max
17025 instruction patterns into conditional moves. */
17026 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17027 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17028 || !rtx_equal_p (operands[4], operands[2])
17029 || !rtx_equal_p (operands[5], operands[3]))
17030 && (!TARGET_IEEE_FP
17031 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17032 "#")
17033
17034(define_insn "sse_movdfcc_eq"
17035 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17036 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17037 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17038 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17039 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17040 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17041 (clobber (reg:CC 17))]
17042 "TARGET_SSE
17043 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17044 "#")
17045
17046;; For non-sse moves just expand the usual cmove sequence.
17047(define_split
17048 [(set (match_operand 0 "register_operand" "")
17049 (if_then_else (match_operator 1 "comparison_operator"
17050 [(match_operand 4 "nonimmediate_operand" "")
17051 (match_operand 5 "register_operand" "")])
17052 (match_operand 2 "nonimmediate_operand" "")
17053 (match_operand 3 "nonimmediate_operand" "")))
17054 (clobber (match_operand 6 "" ""))
17055 (clobber (reg:CC 17))]
17056 "!SSE_REG_P (operands[0]) && reload_completed
17057 && (GET_MODE (operands[0]) == SFmode
17058 || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
17059 [(const_int 0)]
17060{
17061 ix86_compare_op0 = operands[5];
17062 ix86_compare_op1 = operands[4];
17063 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17064 VOIDmode, operands[5], operands[4]);
17065 ix86_expand_fp_movcc (operands);
17066 DONE;
17067})
17068
17069;; Split SSE based conditional move into sequence:
17070;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17071;; and op2, op0 - zero op2 if comparison was false
17072;; nand op0, op3 - load op3 to op0 if comparison was false
17073;; or op2, op0 - get the nonzero one into the result.
17074(define_split
17075 [(set (match_operand:SF 0 "register_operand" "")
17076 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17077 [(match_operand:SF 4 "register_operand" "")
17078 (match_operand:SF 5 "nonimmediate_operand" "")])
17079 (match_operand:SF 2 "register_operand" "")
17080 (match_operand:SF 3 "register_operand" "")))
17081 (clobber (match_operand 6 "" ""))
17082 (clobber (reg:CC 17))]
17083 "SSE_REG_P (operands[0]) && reload_completed"
17084 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17085 (set (match_dup 2) (and:V4SF (match_dup 2)
17086 (match_dup 8)))
17087 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17088 (match_dup 3)))
17089 (set (match_dup 0) (ior:V4SF (match_dup 6)
17090 (match_dup 7)))]
17091{
17092 /* If op2 == op3, op3 would be clobbered before it is used. */
17093 if (operands_match_p (operands[2], operands[3]))
17094 {
17095 emit_move_insn (operands[0], operands[2]);
17096 DONE;
17097 }
17098
17099 PUT_MODE (operands[1], GET_MODE (operands[0]));
17100 if (operands_match_p (operands[0], operands[4]))
17101 operands[6] = operands[4], operands[7] = operands[2];
17102 else
17103 operands[6] = operands[2], operands[7] = operands[4];
17104 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17105 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17106 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17107 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17108 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17109 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17110})
17111
17112(define_split
17113 [(set (match_operand:DF 0 "register_operand" "")
17114 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17115 [(match_operand:DF 4 "register_operand" "")
17116 (match_operand:DF 5 "nonimmediate_operand" "")])
17117 (match_operand:DF 2 "register_operand" "")
17118 (match_operand:DF 3 "register_operand" "")))
17119 (clobber (match_operand 6 "" ""))
17120 (clobber (reg:CC 17))]
17121 "SSE_REG_P (operands[0]) && reload_completed"
17122 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17123 (set (match_dup 2) (and:V2DF (match_dup 2)
17124 (match_dup 8)))
17125 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17126 (match_dup 3)))
17127 (set (match_dup 0) (ior:V2DF (match_dup 6)
17128 (match_dup 7)))]
17129{
17130 if (GET_MODE (operands[2]) == DFmode
17131 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17132 {
17133 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17134 emit_insn (gen_sse2_unpcklpd (op, op, op));
17135 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17136 emit_insn (gen_sse2_unpcklpd (op, op, op));
17137 }
17138
17139 /* If op2 == op3, op3 would be clobbered before it is used. */
17140 if (operands_match_p (operands[2], operands[3]))
17141 {
17142 emit_move_insn (operands[0], operands[2]);
17143 DONE;
17144 }
17145
17146 PUT_MODE (operands[1], GET_MODE (operands[0]));
17147 if (operands_match_p (operands[0], operands[4]))
17148 operands[6] = operands[4], operands[7] = operands[2];
17149 else
17150 operands[6] = operands[2], operands[7] = operands[4];
17151 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17152 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17153 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17154 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17155 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17156 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17157})
17158
17159;; Special case of conditional move we can handle effectively.
17160;; Do not brother with the integer/floating point case, since these are
17161;; bot considerably slower, unlike in the generic case.
17162(define_insn "*sse_movsfcc_const0_1"
17163 [(set (match_operand:SF 0 "register_operand" "=&x")
17164 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17165 [(match_operand:SF 4 "register_operand" "0")
17166 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17167 (match_operand:SF 2 "register_operand" "x")
17168 (match_operand:SF 3 "const0_operand" "X")))]
17169 "TARGET_SSE"
17170 "#")
17171
17172(define_insn "*sse_movsfcc_const0_2"
17173 [(set (match_operand:SF 0 "register_operand" "=&x")
17174 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17175 [(match_operand:SF 4 "register_operand" "0")
17176 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17177 (match_operand:SF 2 "const0_operand" "X")
17178 (match_operand:SF 3 "register_operand" "x")))]
17179 "TARGET_SSE"
17180 "#")
17181
17182(define_insn "*sse_movsfcc_const0_3"
17183 [(set (match_operand:SF 0 "register_operand" "=&x")
17184 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17185 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17186 (match_operand:SF 5 "register_operand" "0")])
17187 (match_operand:SF 2 "register_operand" "x")
17188 (match_operand:SF 3 "const0_operand" "X")))]
17189 "TARGET_SSE"
17190 "#")
17191
17192(define_insn "*sse_movsfcc_const0_4"
17193 [(set (match_operand:SF 0 "register_operand" "=&x")
17194 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17195 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17196 (match_operand:SF 5 "register_operand" "0")])
17197 (match_operand:SF 2 "const0_operand" "X")
17198 (match_operand:SF 3 "register_operand" "x")))]
17199 "TARGET_SSE"
17200 "#")
17201
17202(define_insn "*sse_movdfcc_const0_1"
17203 [(set (match_operand:DF 0 "register_operand" "=&Y")
17204 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17205 [(match_operand:DF 4 "register_operand" "0")
17206 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17207 (match_operand:DF 2 "register_operand" "Y")
17208 (match_operand:DF 3 "const0_operand" "X")))]
17209 "TARGET_SSE2"
17210 "#")
17211
17212(define_insn "*sse_movdfcc_const0_2"
17213 [(set (match_operand:DF 0 "register_operand" "=&Y")
17214 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17215 [(match_operand:DF 4 "register_operand" "0")
17216 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17217 (match_operand:DF 2 "const0_operand" "X")
17218 (match_operand:DF 3 "register_operand" "Y")))]
17219 "TARGET_SSE2"
17220 "#")
17221
17222(define_insn "*sse_movdfcc_const0_3"
17223 [(set (match_operand:DF 0 "register_operand" "=&Y")
17224 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17225 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17226 (match_operand:DF 5 "register_operand" "0")])
17227 (match_operand:DF 2 "register_operand" "Y")
17228 (match_operand:DF 3 "const0_operand" "X")))]
17229 "TARGET_SSE2"
17230 "#")
17231
17232(define_insn "*sse_movdfcc_const0_4"
17233 [(set (match_operand:DF 0 "register_operand" "=&Y")
17234 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17235 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17236 (match_operand:DF 5 "register_operand" "0")])
17237 (match_operand:DF 2 "const0_operand" "X")
17238 (match_operand:DF 3 "register_operand" "Y")))]
17239 "TARGET_SSE2"
17240 "#")
17241
17242(define_split
17243 [(set (match_operand:SF 0 "register_operand" "")
17244 (if_then_else:SF (match_operator 1 "comparison_operator"
17245 [(match_operand:SF 4 "nonimmediate_operand" "")
17246 (match_operand:SF 5 "nonimmediate_operand" "")])
17247 (match_operand:SF 2 "nonmemory_operand" "")
17248 (match_operand:SF 3 "nonmemory_operand" "")))]
17249 "SSE_REG_P (operands[0]) && reload_completed
17250 && (const0_operand (operands[2], GET_MODE (operands[0]))
17251 || const0_operand (operands[3], GET_MODE (operands[0])))"
17252 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17253 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17254{
17255 PUT_MODE (operands[1], GET_MODE (operands[0]));
17256 if (!sse_comparison_operator (operands[1], VOIDmode)
17257 || !rtx_equal_p (operands[0], operands[4]))
17258 {
17259 rtx tmp = operands[5];
17260 operands[5] = operands[4];
17261 operands[4] = tmp;
17262 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17263 }
17264 if (!rtx_equal_p (operands[0], operands[4]))
17265 abort ();
17266 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17267 if (const0_operand (operands[2], GET_MODE (operands[2])))
17268 {
17269 operands[7] = operands[3];
17270 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17271 }
17272 else
17273 {
17274 operands[7] = operands[2];
17275 operands[6] = operands[8];
17276 }
17277 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17278})
17279
17280(define_split
17281 [(set (match_operand:DF 0 "register_operand" "")
17282 (if_then_else:DF (match_operator 1 "comparison_operator"
17283 [(match_operand:DF 4 "nonimmediate_operand" "")
17284 (match_operand:DF 5 "nonimmediate_operand" "")])
17285 (match_operand:DF 2 "nonmemory_operand" "")
17286 (match_operand:DF 3 "nonmemory_operand" "")))]
17287 "SSE_REG_P (operands[0]) && reload_completed
17288 && (const0_operand (operands[2], GET_MODE (operands[0]))
17289 || const0_operand (operands[3], GET_MODE (operands[0])))"
17290 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17291 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17292{
17293 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17294 && GET_MODE (operands[2]) == DFmode)
17295 {
17296 if (REG_P (operands[2]))
17297 {
17298 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17299 emit_insn (gen_sse2_unpcklpd (op, op, op));
17300 }
17301 if (REG_P (operands[3]))
17302 {
17303 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17304 emit_insn (gen_sse2_unpcklpd (op, op, op));
17305 }
17306 }
17307 PUT_MODE (operands[1], GET_MODE (operands[0]));
17308 if (!sse_comparison_operator (operands[1], VOIDmode)
17309 || !rtx_equal_p (operands[0], operands[4]))
17310 {
17311 rtx tmp = operands[5];
17312 operands[5] = operands[4];
17313 operands[4] = tmp;
17314 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17315 }
17316 if (!rtx_equal_p (operands[0], operands[4]))
17317 abort ();
17318 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17319 if (const0_operand (operands[2], GET_MODE (operands[2])))
17320 {
17321 operands[7] = operands[3];
17322 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
17323 }
17324 else
17325 {
17326 operands[7] = operands[2];
17327 operands[6] = operands[8];
17328 }
17329 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17330})
17331
17332(define_expand "allocate_stack_worker"
17333 [(match_operand:SI 0 "register_operand" "")]
17334 "TARGET_STACK_PROBE"
17335{
17336 if (reload_completed)
17337 {
17338 if (TARGET_64BIT)
17339 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17340 else
17341 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17342 }
17343 else
17344 {
17345 if (TARGET_64BIT)
17346 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17347 else
17348 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17349 }
17350 DONE;
17351})
17352
17353(define_insn "allocate_stack_worker_1"
17354 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17355 UNSPECV_STACK_PROBE)
17356 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17357 (clobber (match_scratch:SI 1 "=0"))
17358 (clobber (reg:CC 17))]
17359 "!TARGET_64BIT && TARGET_STACK_PROBE"
17360 "call\t__alloca"
17361 [(set_attr "type" "multi")
17362 (set_attr "length" "5")])
17363
17364(define_expand "allocate_stack_worker_postreload"
17365 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17366 UNSPECV_STACK_PROBE)
17367 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17368 (clobber (match_dup 0))
17369 (clobber (reg:CC 17))])]
17370 ""
17371 "")
17372
17373(define_insn "allocate_stack_worker_rex64"
17374 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17375 UNSPECV_STACK_PROBE)
17376 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17377 (clobber (match_scratch:DI 1 "=0"))
17378 (clobber (reg:CC 17))]
17379 "TARGET_64BIT && TARGET_STACK_PROBE"
17380 "call\t__alloca"
17381 [(set_attr "type" "multi")
17382 (set_attr "length" "5")])
17383
17384(define_expand "allocate_stack_worker_rex64_postreload"
17385 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17386 UNSPECV_STACK_PROBE)
17387 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17388 (clobber (match_dup 0))
17389 (clobber (reg:CC 17))])]
17390 ""
17391 "")
17392
17393(define_expand "allocate_stack"
17394 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17395 (minus:SI (reg:SI 7)
17396 (match_operand:SI 1 "general_operand" "")))
17397 (clobber (reg:CC 17))])
17398 (parallel [(set (reg:SI 7)
17399 (minus:SI (reg:SI 7) (match_dup 1)))
17400 (clobber (reg:CC 17))])]
17401 "TARGET_STACK_PROBE"
17402{
17403#ifdef CHECK_STACK_LIMIT
17404 if (GET_CODE (operands[1]) == CONST_INT
17405 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17406 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17407 operands[1]));
17408 else
17409#endif
17410 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17411 operands[1])));
17412
17413 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17414 DONE;
17415})
17416
17417(define_expand "builtin_setjmp_receiver"
17418 [(label_ref (match_operand 0 "" ""))]
17419 "!TARGET_64BIT && flag_pic"
17420{
17421 emit_insn (gen_set_got (pic_offset_table_rtx));
17422 DONE;
17423})
17424
17425;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17426
17427(define_split
17428 [(set (match_operand 0 "register_operand" "")
17429 (match_operator 3 "promotable_binary_operator"
17430 [(match_operand 1 "register_operand" "")
17431 (match_operand 2 "aligned_operand" "")]))
17432 (clobber (reg:CC 17))]
17433 "! TARGET_PARTIAL_REG_STALL && reload_completed
17434 && ((GET_MODE (operands[0]) == HImode
17435 && ((!optimize_size && !TARGET_FAST_PREFIX)
17436 || GET_CODE (operands[2]) != CONST_INT
17437 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17438 || (GET_MODE (operands[0]) == QImode
17439 && (TARGET_PROMOTE_QImode || optimize_size)))"
17440 [(parallel [(set (match_dup 0)
17441 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17442 (clobber (reg:CC 17))])]
17443 "operands[0] = gen_lowpart (SImode, operands[0]);
17444 operands[1] = gen_lowpart (SImode, operands[1]);
17445 if (GET_CODE (operands[3]) != ASHIFT)
17446 operands[2] = gen_lowpart (SImode, operands[2]);
17447 PUT_MODE (operands[3], SImode);")
17448
17449; Promote the QImode tests, as i386 has encoding of the AND
17450; instruction with 32-bit sign-extended immediate and thus the
17451; instruction size is unchanged, except in the %eax case for
17452; which it is increased by one byte, hence the ! optimize_size.
17453(define_split
17454 [(set (match_operand 0 "flags_reg_operand" "")
17455 (match_operator 2 "compare_operator"
17456 [(and (match_operand 3 "aligned_operand" "")
17457 (match_operand 4 "const_int_operand" ""))
17458 (const_int 0)]))
17459 (set (match_operand 1 "register_operand" "")
17460 (and (match_dup 3) (match_dup 4)))]
17461 "! TARGET_PARTIAL_REG_STALL && reload_completed
17462 /* Ensure that the operand will remain sign-extended immediate. */
17463 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
17464 && ! optimize_size
17465 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17466 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
17467 [(parallel [(set (match_dup 0)
17468 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17469 (const_int 0)]))
17470 (set (match_dup 1)
17471 (and:SI (match_dup 3) (match_dup 4)))])]
17472{
17473 operands[4]
17474 = gen_int_mode (INTVAL (operands[4])
17475 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17476 operands[1] = gen_lowpart (SImode, operands[1]);
17477 operands[3] = gen_lowpart (SImode, operands[3]);
17478})
17479
17480; Don't promote the QImode tests, as i386 doesn't have encoding of
17481; the TEST instruction with 32-bit sign-extended immediate and thus
17482; the instruction size would at least double, which is not what we
17483; want even with ! optimize_size.
17484(define_split
17485 [(set (match_operand 0 "flags_reg_operand" "")
17486 (match_operator 1 "compare_operator"
17487 [(and (match_operand:HI 2 "aligned_operand" "")
17488 (match_operand:HI 3 "const_int_operand" ""))
17489 (const_int 0)]))]
17490 "! TARGET_PARTIAL_REG_STALL && reload_completed
17491 /* Ensure that the operand will remain sign-extended immediate. */
17492 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
17493 && ! TARGET_FAST_PREFIX
17494 && ! optimize_size"
17495 [(set (match_dup 0)
17496 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17497 (const_int 0)]))]
17498{
17499 operands[3]
17500 = gen_int_mode (INTVAL (operands[3])
17501 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17502 operands[2] = gen_lowpart (SImode, operands[2]);
17503})
17504
17505(define_split
17506 [(set (match_operand 0 "register_operand" "")
17507 (neg (match_operand 1 "register_operand" "")))
17508 (clobber (reg:CC 17))]
17509 "! TARGET_PARTIAL_REG_STALL && reload_completed
17510 && (GET_MODE (operands[0]) == HImode
17511 || (GET_MODE (operands[0]) == QImode
17512 && (TARGET_PROMOTE_QImode || optimize_size)))"
17513 [(parallel [(set (match_dup 0)
17514 (neg:SI (match_dup 1)))
17515 (clobber (reg:CC 17))])]
17516 "operands[0] = gen_lowpart (SImode, operands[0]);
17517 operands[1] = gen_lowpart (SImode, operands[1]);")
17518
17519(define_split
17520 [(set (match_operand 0 "register_operand" "")
17521 (not (match_operand 1 "register_operand" "")))]
17522 "! TARGET_PARTIAL_REG_STALL && reload_completed
17523 && (GET_MODE (operands[0]) == HImode
17524 || (GET_MODE (operands[0]) == QImode
17525 && (TARGET_PROMOTE_QImode || optimize_size)))"
17526 [(set (match_dup 0)
17527 (not:SI (match_dup 1)))]
17528 "operands[0] = gen_lowpart (SImode, operands[0]);
17529 operands[1] = gen_lowpart (SImode, operands[1]);")
17530
17531(define_split
17532 [(set (match_operand 0 "register_operand" "")
17533 (if_then_else (match_operator 1 "comparison_operator"
17534 [(reg 17) (const_int 0)])
17535 (match_operand 2 "register_operand" "")
17536 (match_operand 3 "register_operand" "")))]
17537 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17538 && (GET_MODE (operands[0]) == HImode
17539 || (GET_MODE (operands[0]) == QImode
17540 && (TARGET_PROMOTE_QImode || optimize_size)))"
17541 [(set (match_dup 0)
17542 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17543 "operands[0] = gen_lowpart (SImode, operands[0]);
17544 operands[2] = gen_lowpart (SImode, operands[2]);
17545 operands[3] = gen_lowpart (SImode, operands[3]);")
17546
17547
17548;; RTL Peephole optimizations, run before sched2. These primarily look to
17549;; transform a complex memory operation into two memory to register operations.
17550
17551;; Don't push memory operands
17552(define_peephole2
17553 [(set (match_operand:SI 0 "push_operand" "")
17554 (match_operand:SI 1 "memory_operand" ""))
17555 (match_scratch:SI 2 "r")]
17556 "! optimize_size && ! TARGET_PUSH_MEMORY"
17557 [(set (match_dup 2) (match_dup 1))
17558 (set (match_dup 0) (match_dup 2))]
17559 "")
17560
17561(define_peephole2
17562 [(set (match_operand:DI 0 "push_operand" "")
17563 (match_operand:DI 1 "memory_operand" ""))
17564 (match_scratch:DI 2 "r")]
17565 "! optimize_size && ! TARGET_PUSH_MEMORY"
17566 [(set (match_dup 2) (match_dup 1))
17567 (set (match_dup 0) (match_dup 2))]
17568 "")
17569
17570;; We need to handle SFmode only, because DFmode and XFmode is split to
17571;; SImode pushes.
17572(define_peephole2
17573 [(set (match_operand:SF 0 "push_operand" "")
17574 (match_operand:SF 1 "memory_operand" ""))
17575 (match_scratch:SF 2 "r")]
17576 "! optimize_size && ! TARGET_PUSH_MEMORY"
17577 [(set (match_dup 2) (match_dup 1))
17578 (set (match_dup 0) (match_dup 2))]
17579 "")
17580
17581(define_peephole2
17582 [(set (match_operand:HI 0 "push_operand" "")
17583 (match_operand:HI 1 "memory_operand" ""))
17584 (match_scratch:HI 2 "r")]
17585 "! optimize_size && ! TARGET_PUSH_MEMORY"
17586 [(set (match_dup 2) (match_dup 1))
17587 (set (match_dup 0) (match_dup 2))]
17588 "")
17589
17590(define_peephole2
17591 [(set (match_operand:QI 0 "push_operand" "")
17592 (match_operand:QI 1 "memory_operand" ""))
17593 (match_scratch:QI 2 "q")]
17594 "! optimize_size && ! TARGET_PUSH_MEMORY"
17595 [(set (match_dup 2) (match_dup 1))
17596 (set (match_dup 0) (match_dup 2))]
17597 "")
17598
17599;; Don't move an immediate directly to memory when the instruction
17600;; gets too big.
17601(define_peephole2
17602 [(match_scratch:SI 1 "r")
17603 (set (match_operand:SI 0 "memory_operand" "")
17604 (const_int 0))]
17605 "! optimize_size
17606 && ! TARGET_USE_MOV0
17607 && TARGET_SPLIT_LONG_MOVES
17608 && get_attr_length (insn) >= ix86_cost->large_insn
17609 && peep2_regno_dead_p (0, FLAGS_REG)"
17610 [(parallel [(set (match_dup 1) (const_int 0))
17611 (clobber (reg:CC 17))])
17612 (set (match_dup 0) (match_dup 1))]
17613 "")
17614
17615(define_peephole2
17616 [(match_scratch:HI 1 "r")
17617 (set (match_operand:HI 0 "memory_operand" "")
17618 (const_int 0))]
17619 "! optimize_size
17620 && ! TARGET_USE_MOV0
17621 && TARGET_SPLIT_LONG_MOVES
17622 && get_attr_length (insn) >= ix86_cost->large_insn
17623 && peep2_regno_dead_p (0, FLAGS_REG)"
17624 [(parallel [(set (match_dup 2) (const_int 0))
17625 (clobber (reg:CC 17))])
17626 (set (match_dup 0) (match_dup 1))]
17627 "operands[2] = gen_lowpart (SImode, operands[1]);")
17628
17629(define_peephole2
17630 [(match_scratch:QI 1 "q")
17631 (set (match_operand:QI 0 "memory_operand" "")
17632 (const_int 0))]
17633 "! optimize_size
17634 && ! TARGET_USE_MOV0
17635 && TARGET_SPLIT_LONG_MOVES
17636 && get_attr_length (insn) >= ix86_cost->large_insn
17637 && peep2_regno_dead_p (0, FLAGS_REG)"
17638 [(parallel [(set (match_dup 2) (const_int 0))
17639 (clobber (reg:CC 17))])
17640 (set (match_dup 0) (match_dup 1))]
17641 "operands[2] = gen_lowpart (SImode, operands[1]);")
17642
17643(define_peephole2
17644 [(match_scratch:SI 2 "r")
17645 (set (match_operand:SI 0 "memory_operand" "")
17646 (match_operand:SI 1 "immediate_operand" ""))]
17647 "! optimize_size
17648 && get_attr_length (insn) >= ix86_cost->large_insn
17649 && TARGET_SPLIT_LONG_MOVES"
17650 [(set (match_dup 2) (match_dup 1))
17651 (set (match_dup 0) (match_dup 2))]
17652 "")
17653
17654(define_peephole2
17655 [(match_scratch:HI 2 "r")
17656 (set (match_operand:HI 0 "memory_operand" "")
17657 (match_operand:HI 1 "immediate_operand" ""))]
17658 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17659 && TARGET_SPLIT_LONG_MOVES"
17660 [(set (match_dup 2) (match_dup 1))
17661 (set (match_dup 0) (match_dup 2))]
17662 "")
17663
17664(define_peephole2
17665 [(match_scratch:QI 2 "q")
17666 (set (match_operand:QI 0 "memory_operand" "")
17667 (match_operand:QI 1 "immediate_operand" ""))]
17668 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17669 && TARGET_SPLIT_LONG_MOVES"
17670 [(set (match_dup 2) (match_dup 1))
17671 (set (match_dup 0) (match_dup 2))]
17672 "")
17673
17674;; Don't compare memory with zero, load and use a test instead.
17675(define_peephole2
17676 [(set (match_operand 0 "flags_reg_operand" "")
17677 (match_operator 1 "compare_operator"
17678 [(match_operand:SI 2 "memory_operand" "")
17679 (const_int 0)]))
17680 (match_scratch:SI 3 "r")]
17681 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17682 [(set (match_dup 3) (match_dup 2))
17683 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17684 "")
17685
17686;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17687;; Don't split NOTs with a displacement operand, because resulting XOR
17688;; will not be pairable anyway.
17689;;
17690;; On AMD K6, NOT is vector decoded with memory operand that can not be
17691;; represented using a modRM byte. The XOR replacement is long decoded,
17692;; so this split helps here as well.
17693;;
17694;; Note: Can't do this as a regular split because we can't get proper
17695;; lifetime information then.
17696
17697(define_peephole2
17698 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17699 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17700 "!optimize_size
17701 && peep2_regno_dead_p (0, FLAGS_REG)
17702 && ((TARGET_PENTIUM
17703 && (GET_CODE (operands[0]) != MEM
17704 || !memory_displacement_operand (operands[0], SImode)))
17705 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17706 [(parallel [(set (match_dup 0)
17707 (xor:SI (match_dup 1) (const_int -1)))
17708 (clobber (reg:CC 17))])]
17709 "")
17710
17711(define_peephole2
17712 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17713 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17714 "!optimize_size
17715 && peep2_regno_dead_p (0, FLAGS_REG)
17716 && ((TARGET_PENTIUM
17717 && (GET_CODE (operands[0]) != MEM
17718 || !memory_displacement_operand (operands[0], HImode)))
17719 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17720 [(parallel [(set (match_dup 0)
17721 (xor:HI (match_dup 1) (const_int -1)))
17722 (clobber (reg:CC 17))])]
17723 "")
17724
17725(define_peephole2
17726 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17727 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17728 "!optimize_size
17729 && peep2_regno_dead_p (0, FLAGS_REG)
17730 && ((TARGET_PENTIUM
17731 && (GET_CODE (operands[0]) != MEM
17732 || !memory_displacement_operand (operands[0], QImode)))
17733 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17734 [(parallel [(set (match_dup 0)
17735 (xor:QI (match_dup 1) (const_int -1)))
17736 (clobber (reg:CC 17))])]
17737 "")
17738
17739;; Non pairable "test imm, reg" instructions can be translated to
17740;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17741;; byte opcode instead of two, have a short form for byte operands),
17742;; so do it for other CPUs as well. Given that the value was dead,
17743;; this should not create any new dependencies. Pass on the sub-word
17744;; versions if we're concerned about partial register stalls.
17745
17746(define_peephole2
17747 [(set (match_operand 0 "flags_reg_operand" "")
17748 (match_operator 1 "compare_operator"
17749 [(and:SI (match_operand:SI 2 "register_operand" "")
17750 (match_operand:SI 3 "immediate_operand" ""))
17751 (const_int 0)]))]
17752 "ix86_match_ccmode (insn, CCNOmode)
17753 && (true_regnum (operands[2]) != 0
17754 || (GET_CODE (operands[3]) == CONST_INT
17755 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
17756 && peep2_reg_dead_p (1, operands[2])"
17757 [(parallel
17758 [(set (match_dup 0)
17759 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17760 (const_int 0)]))
17761 (set (match_dup 2)
17762 (and:SI (match_dup 2) (match_dup 3)))])]
17763 "")
17764
17765;; We don't need to handle HImode case, because it will be promoted to SImode
17766;; on ! TARGET_PARTIAL_REG_STALL
17767
17768(define_peephole2
17769 [(set (match_operand 0 "flags_reg_operand" "")
17770 (match_operator 1 "compare_operator"
17771 [(and:QI (match_operand:QI 2 "register_operand" "")
17772 (match_operand:QI 3 "immediate_operand" ""))
17773 (const_int 0)]))]
17774 "! TARGET_PARTIAL_REG_STALL
17775 && ix86_match_ccmode (insn, CCNOmode)
17776 && true_regnum (operands[2]) != 0
17777 && peep2_reg_dead_p (1, operands[2])"
17778 [(parallel
17779 [(set (match_dup 0)
17780 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17781 (const_int 0)]))
17782 (set (match_dup 2)
17783 (and:QI (match_dup 2) (match_dup 3)))])]
17784 "")
17785
17786(define_peephole2
17787 [(set (match_operand 0 "flags_reg_operand" "")
17788 (match_operator 1 "compare_operator"
17789 [(and:SI
17790 (zero_extract:SI
17791 (match_operand 2 "ext_register_operand" "")
17792 (const_int 8)
17793 (const_int 8))
17794 (match_operand 3 "const_int_operand" ""))
17795 (const_int 0)]))]
17796 "! TARGET_PARTIAL_REG_STALL
17797 && ix86_match_ccmode (insn, CCNOmode)
17798 && true_regnum (operands[2]) != 0
17799 && peep2_reg_dead_p (1, operands[2])"
17800 [(parallel [(set (match_dup 0)
17801 (match_op_dup 1
17802 [(and:SI
17803 (zero_extract:SI
17804 (match_dup 2)
17805 (const_int 8)
17806 (const_int 8))
17807 (match_dup 3))
17808 (const_int 0)]))
17809 (set (zero_extract:SI (match_dup 2)
17810 (const_int 8)
17811 (const_int 8))
17812 (and:SI
17813 (zero_extract:SI
17814 (match_dup 2)
17815 (const_int 8)
17816 (const_int 8))
17817 (match_dup 3)))])]
17818 "")
17819
17820;; Don't do logical operations with memory inputs.
17821(define_peephole2
17822 [(match_scratch:SI 2 "r")
17823 (parallel [(set (match_operand:SI 0 "register_operand" "")
17824 (match_operator:SI 3 "arith_or_logical_operator"
17825 [(match_dup 0)
17826 (match_operand:SI 1 "memory_operand" "")]))
17827 (clobber (reg:CC 17))])]
17828 "! optimize_size && ! TARGET_READ_MODIFY"
17829 [(set (match_dup 2) (match_dup 1))
17830 (parallel [(set (match_dup 0)
17831 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17832 (clobber (reg:CC 17))])]
17833 "")
17834
17835(define_peephole2
17836 [(match_scratch:SI 2 "r")
17837 (parallel [(set (match_operand:SI 0 "register_operand" "")
17838 (match_operator:SI 3 "arith_or_logical_operator"
17839 [(match_operand:SI 1 "memory_operand" "")
17840 (match_dup 0)]))
17841 (clobber (reg:CC 17))])]
17842 "! optimize_size && ! TARGET_READ_MODIFY"
17843 [(set (match_dup 2) (match_dup 1))
17844 (parallel [(set (match_dup 0)
17845 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17846 (clobber (reg:CC 17))])]
17847 "")
17848
17849; Don't do logical operations with memory outputs
17850;
17851; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17852; instruction into two 1-uop insns plus a 2-uop insn. That last has
17853; the same decoder scheduling characteristics as the original.
17854
17855(define_peephole2
17856 [(match_scratch:SI 2 "r")
17857 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17858 (match_operator:SI 3 "arith_or_logical_operator"
17859 [(match_dup 0)
17860 (match_operand:SI 1 "nonmemory_operand" "")]))
17861 (clobber (reg:CC 17))])]
17862 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17863 [(set (match_dup 2) (match_dup 0))
17864 (parallel [(set (match_dup 2)
17865 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17866 (clobber (reg:CC 17))])
17867 (set (match_dup 0) (match_dup 2))]
17868 "")
17869
17870(define_peephole2
17871 [(match_scratch:SI 2 "r")
17872 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17873 (match_operator:SI 3 "arith_or_logical_operator"
17874 [(match_operand:SI 1 "nonmemory_operand" "")
17875 (match_dup 0)]))
17876 (clobber (reg:CC 17))])]
17877 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17878 [(set (match_dup 2) (match_dup 0))
17879 (parallel [(set (match_dup 2)
17880 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17881 (clobber (reg:CC 17))])
17882 (set (match_dup 0) (match_dup 2))]
17883 "")
17884
17885;; Attempt to always use XOR for zeroing registers.
17886(define_peephole2
17887 [(set (match_operand 0 "register_operand" "")
17888 (const_int 0))]
17889 "(GET_MODE (operands[0]) == QImode
17890 || GET_MODE (operands[0]) == HImode
17891 || GET_MODE (operands[0]) == SImode
17892 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17893 && (! TARGET_USE_MOV0 || optimize_size)
17894 && peep2_regno_dead_p (0, FLAGS_REG)"
17895 [(parallel [(set (match_dup 0) (const_int 0))
17896 (clobber (reg:CC 17))])]
17897 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17898 operands[0]);")
17899
17900(define_peephole2
17901 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17902 (const_int 0))]
17903 "(GET_MODE (operands[0]) == QImode
17904 || GET_MODE (operands[0]) == HImode)
17905 && (! TARGET_USE_MOV0 || optimize_size)
17906 && peep2_regno_dead_p (0, FLAGS_REG)"
17907 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17908 (clobber (reg:CC 17))])])
17909
17910;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17911(define_peephole2
17912 [(set (match_operand 0 "register_operand" "")
17913 (const_int -1))]
17914 "(GET_MODE (operands[0]) == HImode
17915 || GET_MODE (operands[0]) == SImode
17916 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17917 && (optimize_size || TARGET_PENTIUM)
17918 && peep2_regno_dead_p (0, FLAGS_REG)"
17919 [(parallel [(set (match_dup 0) (const_int -1))
17920 (clobber (reg:CC 17))])]
17921 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17922 operands[0]);")
17923
17924;; Attempt to convert simple leas to adds. These can be created by
17925;; move expanders.
17926(define_peephole2
17927 [(set (match_operand:SI 0 "register_operand" "")
17928 (plus:SI (match_dup 0)
17929 (match_operand:SI 1 "nonmemory_operand" "")))]
17930 "peep2_regno_dead_p (0, FLAGS_REG)"
17931 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17932 (clobber (reg:CC 17))])]
17933 "")
17934
17935(define_peephole2
17936 [(set (match_operand:SI 0 "register_operand" "")
17937 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17938 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17939 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17940 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17941 (clobber (reg:CC 17))])]
17942 "operands[2] = gen_lowpart (SImode, operands[2]);")
17943
17944(define_peephole2
17945 [(set (match_operand:DI 0 "register_operand" "")
17946 (plus:DI (match_dup 0)
17947 (match_operand:DI 1 "x86_64_general_operand" "")))]
17948 "peep2_regno_dead_p (0, FLAGS_REG)"
17949 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17950 (clobber (reg:CC 17))])]
17951 "")
17952
17953(define_peephole2
17954 [(set (match_operand:SI 0 "register_operand" "")
17955 (mult:SI (match_dup 0)
17956 (match_operand:SI 1 "const_int_operand" "")))]
17957 "exact_log2 (INTVAL (operands[1])) >= 0
17958 && peep2_regno_dead_p (0, FLAGS_REG)"
17959 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17960 (clobber (reg:CC 17))])]
17961 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17962
17963(define_peephole2
17964 [(set (match_operand:DI 0 "register_operand" "")
17965 (mult:DI (match_dup 0)
17966 (match_operand:DI 1 "const_int_operand" "")))]
17967 "exact_log2 (INTVAL (operands[1])) >= 0
17968 && peep2_regno_dead_p (0, FLAGS_REG)"
17969 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17970 (clobber (reg:CC 17))])]
17971 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17972
17973(define_peephole2
17974 [(set (match_operand:SI 0 "register_operand" "")
17975 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17976 (match_operand:DI 2 "const_int_operand" "")) 0))]
17977 "exact_log2 (INTVAL (operands[2])) >= 0
17978 && REGNO (operands[0]) == REGNO (operands[1])
17979 && peep2_regno_dead_p (0, FLAGS_REG)"
17980 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17981 (clobber (reg:CC 17))])]
17982 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17983
17984;; The ESP adjustments can be done by the push and pop instructions. Resulting
17985;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17986;; many CPUs it is also faster, since special hardware to avoid esp
17987;; dependencies is present.
17988
17989;; While some of these conversions may be done using splitters, we use peepholes
17990;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17991
17992;; Convert prologue esp subtractions to push.
17993;; We need register to push. In order to keep verify_flow_info happy we have
17994;; two choices
17995;; - use scratch and clobber it in order to avoid dependencies
17996;; - use already live register
17997;; We can't use the second way right now, since there is no reliable way how to
17998;; verify that given register is live. First choice will also most likely in
17999;; fewer dependencies. On the place of esp adjustments it is very likely that
18000;; call clobbered registers are dead. We may want to use base pointer as an
18001;; alternative when no register is available later.
18002
18003(define_peephole2
18004 [(match_scratch:SI 0 "r")
18005 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18006 (clobber (reg:CC 17))
18007 (clobber (mem:BLK (scratch)))])]
18008 "optimize_size || !TARGET_SUB_ESP_4"
18009 [(clobber (match_dup 0))
18010 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18011 (clobber (mem:BLK (scratch)))])])
18012
18013(define_peephole2
18014 [(match_scratch:SI 0 "r")
18015 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18016 (clobber (reg:CC 17))
18017 (clobber (mem:BLK (scratch)))])]
18018 "optimize_size || !TARGET_SUB_ESP_8"
18019 [(clobber (match_dup 0))
18020 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18021 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18022 (clobber (mem:BLK (scratch)))])])
18023
18024;; Convert esp subtractions to push.
18025(define_peephole2
18026 [(match_scratch:SI 0 "r")
18027 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18028 (clobber (reg:CC 17))])]
18029 "optimize_size || !TARGET_SUB_ESP_4"
18030 [(clobber (match_dup 0))
18031 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18032
18033(define_peephole2
18034 [(match_scratch:SI 0 "r")
18035 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18036 (clobber (reg:CC 17))])]
18037 "optimize_size || !TARGET_SUB_ESP_8"
18038 [(clobber (match_dup 0))
18039 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18040 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18041
18042;; Convert epilogue deallocator to pop.
18043(define_peephole2
18044 [(match_scratch:SI 0 "r")
18045 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18046 (clobber (reg:CC 17))
18047 (clobber (mem:BLK (scratch)))])]
18048 "optimize_size || !TARGET_ADD_ESP_4"
18049 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18050 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18051 (clobber (mem:BLK (scratch)))])]
18052 "")
18053
18054;; Two pops case is tricky, since pop causes dependency on destination register.
18055;; We use two registers if available.
18056(define_peephole2
18057 [(match_scratch:SI 0 "r")
18058 (match_scratch:SI 1 "r")
18059 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18060 (clobber (reg:CC 17))
18061 (clobber (mem:BLK (scratch)))])]
18062 "optimize_size || !TARGET_ADD_ESP_8"
18063 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18064 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18065 (clobber (mem:BLK (scratch)))])
18066 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18067 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18068 "")
18069
18070(define_peephole2
18071 [(match_scratch:SI 0 "r")
18072 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18073 (clobber (reg:CC 17))
18074 (clobber (mem:BLK (scratch)))])]
18075 "optimize_size"
18076 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18077 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18078 (clobber (mem:BLK (scratch)))])
18079 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18080 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18081 "")
18082
18083;; Convert esp additions to pop.
18084(define_peephole2
18085 [(match_scratch:SI 0 "r")
18086 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18087 (clobber (reg:CC 17))])]
18088 ""
18089 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18090 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18091 "")
18092
18093;; Two pops case is tricky, since pop causes dependency on destination register.
18094;; We use two registers if available.
18095(define_peephole2
18096 [(match_scratch:SI 0 "r")
18097 (match_scratch:SI 1 "r")
18098 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18099 (clobber (reg:CC 17))])]
18100 ""
18101 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18102 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18103 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18104 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18105 "")
18106
18107(define_peephole2
18108 [(match_scratch:SI 0 "r")
18109 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18110 (clobber (reg:CC 17))])]
18111 "optimize_size"
18112 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18113 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18114 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18115 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18116 "")
18117
18118;; Convert compares with 1 to shorter inc/dec operations when CF is not
18119;; required and register dies. Similarly for 128 to plus -128.
18120(define_peephole2
18121 [(set (match_operand 0 "flags_reg_operand" "")
18122 (match_operator 1 "compare_operator"
18123 [(match_operand 2 "register_operand" "")
18124 (match_operand 3 "const_int_operand" "")]))]
18125 "(INTVAL (operands[3]) == -1
18126 || INTVAL (operands[3]) == 1
18127 || INTVAL (operands[3]) == 128)
18128 && ix86_match_ccmode (insn, CCGCmode)
18129 && peep2_reg_dead_p (1, operands[2])"
18130 [(parallel [(set (match_dup 0)
18131 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18132 (clobber (match_dup 2))])]
18133 "")
18134
18135(define_peephole2
18136 [(match_scratch:DI 0 "r")
18137 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18138 (clobber (reg:CC 17))
18139 (clobber (mem:BLK (scratch)))])]
18140 "optimize_size || !TARGET_SUB_ESP_4"
18141 [(clobber (match_dup 0))
18142 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18143 (clobber (mem:BLK (scratch)))])])
18144
18145(define_peephole2
18146 [(match_scratch:DI 0 "r")
18147 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18148 (clobber (reg:CC 17))
18149 (clobber (mem:BLK (scratch)))])]
18150 "optimize_size || !TARGET_SUB_ESP_8"
18151 [(clobber (match_dup 0))
18152 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18153 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18154 (clobber (mem:BLK (scratch)))])])
18155
18156;; Convert esp subtractions to push.
18157(define_peephole2
18158 [(match_scratch:DI 0 "r")
18159 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18160 (clobber (reg:CC 17))])]
18161 "optimize_size || !TARGET_SUB_ESP_4"
18162 [(clobber (match_dup 0))
18163 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18164
18165(define_peephole2
18166 [(match_scratch:DI 0 "r")
18167 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18168 (clobber (reg:CC 17))])]
18169 "optimize_size || !TARGET_SUB_ESP_8"
18170 [(clobber (match_dup 0))
18171 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18172 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18173
18174;; Convert epilogue deallocator to pop.
18175(define_peephole2
18176 [(match_scratch:DI 0 "r")
18177 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18178 (clobber (reg:CC 17))
18179 (clobber (mem:BLK (scratch)))])]
18180 "optimize_size || !TARGET_ADD_ESP_4"
18181 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18182 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18183 (clobber (mem:BLK (scratch)))])]
18184 "")
18185
18186;; Two pops case is tricky, since pop causes dependency on destination register.
18187;; We use two registers if available.
18188(define_peephole2
18189 [(match_scratch:DI 0 "r")
18190 (match_scratch:DI 1 "r")
18191 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18192 (clobber (reg:CC 17))
18193 (clobber (mem:BLK (scratch)))])]
18194 "optimize_size || !TARGET_ADD_ESP_8"
18195 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18196 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18197 (clobber (mem:BLK (scratch)))])
18198 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18199 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18200 "")
18201
18202(define_peephole2
18203 [(match_scratch:DI 0 "r")
18204 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18205 (clobber (reg:CC 17))
18206 (clobber (mem:BLK (scratch)))])]
18207 "optimize_size"
18208 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18209 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18210 (clobber (mem:BLK (scratch)))])
18211 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18212 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18213 "")
18214
18215;; Convert esp additions to pop.
18216(define_peephole2
18217 [(match_scratch:DI 0 "r")
18218 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18219 (clobber (reg:CC 17))])]
18220 ""
18221 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18222 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18223 "")
18224
18225;; Two pops case is tricky, since pop causes dependency on destination register.
18226;; We use two registers if available.
18227(define_peephole2
18228 [(match_scratch:DI 0 "r")
18229 (match_scratch:DI 1 "r")
18230 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18231 (clobber (reg:CC 17))])]
18232 ""
18233 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18234 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18235 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18236 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18237 "")
18238
18239(define_peephole2
18240 [(match_scratch:DI 0 "r")
18241 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18242 (clobber (reg:CC 17))])]
18243 "optimize_size"
18244 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18245 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18246 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18247 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18248 "")
18249
18250;; Imul $32bit_imm, mem, reg is vector decoded, while
18251;; imul $32bit_imm, reg, reg is direct decoded.
18252(define_peephole2
18253 [(match_scratch:DI 3 "r")
18254 (parallel [(set (match_operand:DI 0 "register_operand" "")
18255 (mult:DI (match_operand:DI 1 "memory_operand" "")
18256 (match_operand:DI 2 "immediate_operand" "")))
18257 (clobber (reg:CC 17))])]
18258 "TARGET_K8 && !optimize_size
18259 && (GET_CODE (operands[2]) != CONST_INT
18260 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18261 [(set (match_dup 3) (match_dup 1))
18262 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18263 (clobber (reg:CC 17))])]
18264"")
18265
18266(define_peephole2
18267 [(match_scratch:SI 3 "r")
18268 (parallel [(set (match_operand:SI 0 "register_operand" "")
18269 (mult:SI (match_operand:SI 1 "memory_operand" "")
18270 (match_operand:SI 2 "immediate_operand" "")))
18271 (clobber (reg:CC 17))])]
18272 "TARGET_K8 && !optimize_size
18273 && (GET_CODE (operands[2]) != CONST_INT
18274 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18275 [(set (match_dup 3) (match_dup 1))
18276 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18277 (clobber (reg:CC 17))])]
18278"")
18279
18280(define_peephole2
18281 [(match_scratch:SI 3 "r")
18282 (parallel [(set (match_operand:DI 0 "register_operand" "")
18283 (zero_extend:DI
18284 (mult:SI (match_operand:SI 1 "memory_operand" "")
18285 (match_operand:SI 2 "immediate_operand" ""))))
18286 (clobber (reg:CC 17))])]
18287 "TARGET_K8 && !optimize_size
18288 && (GET_CODE (operands[2]) != CONST_INT
18289 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18290 [(set (match_dup 3) (match_dup 1))
18291 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18292 (clobber (reg:CC 17))])]
18293"")
18294
18295;; imul $8/16bit_imm, regmem, reg is vector decoded.
18296;; Convert it into imul reg, reg
18297;; It would be better to force assembler to encode instruction using long
18298;; immediate, but there is apparently no way to do so.
18299(define_peephole2
18300 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18301 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18302 (match_operand:DI 2 "const_int_operand" "")))
18303 (clobber (reg:CC 17))])
18304 (match_scratch:DI 3 "r")]
18305 "TARGET_K8 && !optimize_size
18306 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18307 [(set (match_dup 3) (match_dup 2))
18308 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18309 (clobber (reg:CC 17))])]
18310{
18311 if (!rtx_equal_p (operands[0], operands[1]))
18312 emit_move_insn (operands[0], operands[1]);
18313})
18314
18315(define_peephole2
18316 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18317 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18318 (match_operand:SI 2 "const_int_operand" "")))
18319 (clobber (reg:CC 17))])
18320 (match_scratch:SI 3 "r")]
18321 "TARGET_K8 && !optimize_size
18322 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18323 [(set (match_dup 3) (match_dup 2))
18324 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18325 (clobber (reg:CC 17))])]
18326{
18327 if (!rtx_equal_p (operands[0], operands[1]))
18328 emit_move_insn (operands[0], operands[1]);
18329})
18330
18331(define_peephole2
18332 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18333 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18334 (match_operand:HI 2 "immediate_operand" "")))
18335 (clobber (reg:CC 17))])
18336 (match_scratch:HI 3 "r")]
18337 "TARGET_K8 && !optimize_size"
18338 [(set (match_dup 3) (match_dup 2))
18339 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18340 (clobber (reg:CC 17))])]
18341{
18342 if (!rtx_equal_p (operands[0], operands[1]))
18343 emit_move_insn (operands[0], operands[1]);
18344})
18345
18346;; Call-value patterns last so that the wildcard operand does not
18347;; disrupt insn-recog's switch tables.
18348
18349(define_insn "*call_value_pop_0"
18350 [(set (match_operand 0 "" "")
18351 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18352 (match_operand:SI 2 "" "")))
18353 (set (reg:SI 7) (plus:SI (reg:SI 7)
18354 (match_operand:SI 3 "immediate_operand" "")))]
18355 "!TARGET_64BIT"
18356{
18357 if (SIBLING_CALL_P (insn))
18358 return "jmp\t%P1";
18359 else
18360 return "call\t%P1";
18361}
18362 [(set_attr "type" "callv")])
18363
18364(define_insn "*call_value_pop_1"
18365 [(set (match_operand 0 "" "")
18366 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18367 (match_operand:SI 2 "" "")))
18368 (set (reg:SI 7) (plus:SI (reg:SI 7)
18369 (match_operand:SI 3 "immediate_operand" "i")))]
18370 "!TARGET_64BIT"
18371{
18372 if (constant_call_address_operand (operands[1], QImode))
18373 {
18374 if (SIBLING_CALL_P (insn))
18375 return "jmp\t%P1";
18376 else
18377 return "call\t%P1";
18378 }
18379 if (SIBLING_CALL_P (insn))
18380 return "jmp\t%A1";
18381 else
18382 return "call\t%A1";
18383}
18384 [(set_attr "type" "callv")])
18385
18386(define_insn "*call_value_0"
18387 [(set (match_operand 0 "" "")
18388 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18389 (match_operand:SI 2 "" "")))]
18390 "!TARGET_64BIT"
18391{
18392 if (SIBLING_CALL_P (insn))
18393 return "jmp\t%P1";
18394 else
18395 return "call\t%P1";
18396}
18397 [(set_attr "type" "callv")])
18398
18399(define_insn "*call_value_0_rex64"
18400 [(set (match_operand 0 "" "")
18401 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18402 (match_operand:DI 2 "const_int_operand" "")))]
18403 "TARGET_64BIT"
18404{
18405 if (SIBLING_CALL_P (insn))
18406 return "jmp\t%P1";
18407 else
18408 return "call\t%P1";
18409}
18410 [(set_attr "type" "callv")])
18411
18412(define_insn "*call_value_1"
18413 [(set (match_operand 0 "" "")
18414 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18415 (match_operand:SI 2 "" "")))]
18416 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18417{
18418 if (constant_call_address_operand (operands[1], QImode))
18419 return "call\t%P1";
18420 return "call\t%A1";
18421}
18422 [(set_attr "type" "callv")])
18423
18424(define_insn "*sibcall_value_1"
18425 [(set (match_operand 0 "" "")
18426 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18427 (match_operand:SI 2 "" "")))]
18428 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18429{
18430 if (constant_call_address_operand (operands[1], QImode))
18431 return "jmp\t%P1";
18432 return "jmp\t%A1";
18433}
18434 [(set_attr "type" "callv")])
18435
18436(define_insn "*call_value_1_rex64"
18437 [(set (match_operand 0 "" "")
18438 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18439 (match_operand:DI 2 "" "")))]
18440 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18441{
18442 if (constant_call_address_operand (operands[1], QImode))
18443 return "call\t%P1";
18444 return "call\t%A1";
18445}
18446 [(set_attr "type" "callv")])
18447
18448(define_insn "*sibcall_value_1_rex64"
18449 [(set (match_operand 0 "" "")
18450 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18451 (match_operand:DI 2 "" "")))]
18452 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18453 "jmp\t%P1"
18454 [(set_attr "type" "callv")])
18455
18456(define_insn "*sibcall_value_1_rex64_v"
18457 [(set (match_operand 0 "" "")
18458 (call (mem:QI (reg:DI 40))
18459 (match_operand:DI 1 "" "")))]
18460 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18461 "jmp\t*%%r11"
18462 [(set_attr "type" "callv")])
18463
18464(define_insn "trap"
18465 [(trap_if (const_int 1) (const_int 5))]
18466 ""
18467 "int\t$5")
18468
18469;;; ix86 doesn't have conditional trap instructions, but we fake them
18470;;; for the sake of bounds checking. By emitting bounds checks as
18471;;; conditional traps rather than as conditional jumps around
18472;;; unconditional traps we avoid introducing spurious basic-block
18473;;; boundaries and facilitate elimination of redundant checks. In
18474;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18475;;; interrupt 5.
18476;;;
18477;;; FIXME: Static branch prediction rules for ix86 are such that
18478;;; forward conditional branches predict as untaken. As implemented
18479;;; below, pseudo conditional traps violate that rule. We should use
18480;;; .pushsection/.popsection to place all of the `int 5's in a special
18481;;; section loaded at the end of the text segment and branch forward
18482;;; there on bounds-failure, and then jump back immediately (in case
18483;;; the system chooses to ignore bounds violations, or to report
18484;;; violations and continue execution).
18485
18486(define_expand "conditional_trap"
18487 [(trap_if (match_operator 0 "comparison_operator"
18488 [(match_dup 2) (const_int 0)])
18489 (match_operand 1 "const_int_operand" ""))]
18490 ""
18491{
18492 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18493 ix86_expand_compare (GET_CODE (operands[0]),
18494 NULL, NULL),
18495 operands[1]));
18496 DONE;
18497})
18498
18499(define_insn "*conditional_trap_1"
18500 [(trap_if (match_operator 0 "comparison_operator"
18501 [(reg 17) (const_int 0)])
18502 (match_operand 1 "const_int_operand" ""))]
18503 ""
18504{
18505 operands[2] = gen_label_rtx ();
18506 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18507 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18508 CODE_LABEL_NUMBER (operands[2]));
18509 RET;
18510})
18511
18512 ;; Pentium III SIMD instructions.
18513
18514;; Moves for SSE/MMX regs.
18515
18516(define_insn "*movv4sf_internal"
18517 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18518 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18519 "TARGET_SSE
18520 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18521 "@
18522 xorps\t%0, %0
18523 movaps\t{%1, %0|%0, %1}
18524 movaps\t{%1, %0|%0, %1}"
18525 [(set_attr "type" "ssemov")
18526 (set_attr "mode" "V4SF")])
18527
18528(define_split
18529 [(set (match_operand:V4SF 0 "register_operand" "")
18530 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18531 "TARGET_SSE && reload_completed"
18532 [(set (match_dup 0)
18533 (vec_merge:V4SF
18534 (vec_duplicate:V4SF (match_dup 1))
18535 (match_dup 2)
18536 (const_int 1)))]
18537{
18538 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18539 operands[2] = CONST0_RTX (V4SFmode);
18540})
18541
18542(define_insn "*movv4si_internal"
18543 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18544 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18545 "TARGET_SSE
18546 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18547{
18548 switch (which_alternative)
18549 {
18550 case 0:
18551 if (get_attr_mode (insn) == MODE_V4SF)
18552 return "xorps\t%0, %0";
18553 else
18554 return "pxor\t%0, %0";
18555 case 1:
18556 case 2:
18557 if (get_attr_mode (insn) == MODE_V4SF)
18558 return "movaps\t{%1, %0|%0, %1}";
18559 else
18560 return "movdqa\t{%1, %0|%0, %1}";
18561 default:
18562 abort ();
18563 }
18564}
18565 [(set_attr "type" "ssemov")
18566 (set (attr "mode")
18567 (cond [(eq_attr "alternative" "0,1")
18568 (if_then_else
18569 (ne (symbol_ref "optimize_size")
18570 (const_int 0))
18571 (const_string "V4SF")
18572 (const_string "TI"))
18573 (eq_attr "alternative" "2")
18574 (if_then_else
18575 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18576 (const_int 0))
18577 (ne (symbol_ref "optimize_size")
18578 (const_int 0)))
18579 (const_string "V4SF")
18580 (const_string "TI"))]
18581 (const_string "TI")))])
18582
18583(define_insn "*movv2di_internal"
18584 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18585 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18586 "TARGET_SSE
18587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18588{
18589 switch (which_alternative)
18590 {
18591 case 0:
18592 if (get_attr_mode (insn) == MODE_V4SF)
18593 return "xorps\t%0, %0";
18594 else
18595 return "pxor\t%0, %0";
18596 case 1:
18597 case 2:
18598 if (get_attr_mode (insn) == MODE_V4SF)
18599 return "movaps\t{%1, %0|%0, %1}";
18600 else
18601 return "movdqa\t{%1, %0|%0, %1}";
18602 default:
18603 abort ();
18604 }
18605}
18606 [(set_attr "type" "ssemov")
18607 (set (attr "mode")
18608 (cond [(eq_attr "alternative" "0,1")
18609 (if_then_else
18610 (ne (symbol_ref "optimize_size")
18611 (const_int 0))
18612 (const_string "V4SF")
18613 (const_string "TI"))
18614 (eq_attr "alternative" "2")
18615 (if_then_else
18616 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18617 (const_int 0))
18618 (ne (symbol_ref "optimize_size")
18619 (const_int 0)))
18620 (const_string "V4SF")
18621 (const_string "TI"))]
18622 (const_string "TI")))])
18623
18624(define_split
18625 [(set (match_operand:V2DF 0 "register_operand" "")
18626 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18627 "TARGET_SSE2 && reload_completed"
18628 [(set (match_dup 0)
18629 (vec_merge:V2DF
18630 (vec_duplicate:V2DF (match_dup 1))
18631 (match_dup 2)
18632 (const_int 1)))]
18633{
18634 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18635 operands[2] = CONST0_RTX (V2DFmode);
18636})
18637
18638(define_insn "*movv2si_internal"
18639 [(set (match_operand:V2SI 0 "nonimmediate_operand"
18640 "=y,y ,m,!y,!*Y,*x,?*x,?m")
18641 (match_operand:V2SI 1 "vector_move_operand"
18642 "C ,ym,y,*Y,y ,C ,*xm,*x"))]
18643 "TARGET_MMX
18644 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18645 "@
18646 pxor\t%0, %0
18647 movq\t{%1, %0|%0, %1}
18648 movq\t{%1, %0|%0, %1}
18649 movdq2q\t{%1, %0|%0, %1}
18650 movq2dq\t{%1, %0|%0, %1}
18651 pxor\t%0, %0
18652 movq\t{%1, %0|%0, %1}
18653 movq\t{%1, %0|%0, %1}"
18654 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18655 (set_attr "mode" "DI")])
18656
18657(define_insn "*movv4hi_internal"
18658 [(set (match_operand:V4HI 0 "nonimmediate_operand"
18659 "=y,y ,m,!y,!*Y,*x,?*x,?m")
18660 (match_operand:V4HI 1 "vector_move_operand"
18661 "C ,ym,y,*Y,y ,C ,*xm,*x"))]
18662 "TARGET_MMX
18663 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18664 "@
18665 pxor\t%0, %0
18666 movq\t{%1, %0|%0, %1}
18667 movq\t{%1, %0|%0, %1}
18668 movdq2q\t{%1, %0|%0, %1}
18669 movq2dq\t{%1, %0|%0, %1}
18670 pxor\t%0, %0
18671 movq\t{%1, %0|%0, %1}
18672 movq\t{%1, %0|%0, %1}"
18673 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18674 (set_attr "mode" "DI")])
18675
18676(define_insn "*movv8qi_internal"
18677 [(set (match_operand:V8QI 0 "nonimmediate_operand"
18678 "=y,y ,m,!y,!*Y,*x,?*x,?m")
18679 (match_operand:V8QI 1 "vector_move_operand"
18680 "C ,ym,y,*Y,y ,C ,*xm,*x"))]
18681 "TARGET_MMX
18682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18683 "@
18684 pxor\t%0, %0
18685 movq\t{%1, %0|%0, %1}
18686 movq\t{%1, %0|%0, %1}
18687 movdq2q\t{%1, %0|%0, %1}
18688 movq2dq\t{%1, %0|%0, %1}
18689 pxor\t%0, %0
18690 movq\t{%1, %0|%0, %1}
18691 movq\t{%1, %0|%0, %1}"
18692 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18693 (set_attr "mode" "DI")])
18694
18695(define_insn "*movv2sf_internal"
18696 [(set (match_operand:V2SF 0 "nonimmediate_operand"
18697 "=y,y ,m,!y,!*Y,*x,?*x,?m")
18698 (match_operand:V2SF 1 "vector_move_operand"
18699 "C ,ym,y,*Y,y ,C ,*xm,*x"))]
18700 "TARGET_MMX
18701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18702 "@
18703 pxor\t%0, %0
18704 movq\t{%1, %0|%0, %1}
18705 movq\t{%1, %0|%0, %1}
18706 movdq2q\t{%1, %0|%0, %1}
18707 movq2dq\t{%1, %0|%0, %1}
18708 xorps\t%0, %0
18709 movq\t{%1, %0|%0, %1}
18710 movq\t{%1, %0|%0, %1}"
18711 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18712 (set_attr "mode" "DI")])
18713
18714(define_expand "movti"
18715 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18716 (match_operand:TI 1 "nonimmediate_operand" ""))]
18717 "TARGET_SSE || TARGET_64BIT"
18718{
18719 if (TARGET_64BIT)
18720 ix86_expand_move (TImode, operands);
18721 else
18722 ix86_expand_vector_move (TImode, operands);
18723 DONE;
18724})
18725
18726(define_expand "movtf"
18727 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18728 (match_operand:TF 1 "nonimmediate_operand" ""))]
18729 "TARGET_64BIT"
18730{
18731 ix86_expand_move (TFmode, operands);
18732 DONE;
18733})
18734
18735(define_insn "*movv2df_internal"
18736 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18737 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18738 "TARGET_SSE
18739 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18740{
18741 switch (which_alternative)
18742 {
18743 case 0:
18744 if (get_attr_mode (insn) == MODE_V4SF)
18745 return "xorps\t%0, %0";
18746 else
18747 return "xorpd\t%0, %0";
18748 case 1:
18749 case 2:
18750 if (get_attr_mode (insn) == MODE_V4SF)
18751 return "movaps\t{%1, %0|%0, %1}";
18752 else
18753 return "movapd\t{%1, %0|%0, %1}";
18754 default:
18755 abort ();
18756 }
18757}
18758 [(set_attr "type" "ssemov")
18759 (set (attr "mode")
18760 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
18761 (const_string "V4SF")
18762 (eq_attr "alternative" "0,1")
18763 (if_then_else
18764 (ne (symbol_ref "optimize_size")
18765 (const_int 0))
18766 (const_string "V4SF")
18767 (const_string "V2DF"))
18768 (eq_attr "alternative" "2")
18769 (if_then_else
18770 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18771 (const_int 0))
18772 (ne (symbol_ref "optimize_size")
18773 (const_int 0)))
18774 (const_string "V4SF")
18775 (const_string "V2DF"))]
18776 (const_string "V2DF")))])
18777
18778(define_insn "*movv8hi_internal"
18779 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18780 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18781 "TARGET_SSE
18782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18783{
18784 switch (which_alternative)
18785 {
18786 case 0:
18787 if (get_attr_mode (insn) == MODE_V4SF)
18788 return "xorps\t%0, %0";
18789 else
18790 return "pxor\t%0, %0";
18791 case 1:
18792 case 2:
18793 if (get_attr_mode (insn) == MODE_V4SF)
18794 return "movaps\t{%1, %0|%0, %1}";
18795 else
18796 return "movdqa\t{%1, %0|%0, %1}";
18797 default:
18798 abort ();
18799 }
18800}
18801 [(set_attr "type" "ssemov")
18802 (set (attr "mode")
18803 (cond [(eq_attr "alternative" "0,1")
18804 (if_then_else
18805 (ne (symbol_ref "optimize_size")
18806 (const_int 0))
18807 (const_string "V4SF")
18808 (const_string "TI"))
18809 (eq_attr "alternative" "2")
18810 (if_then_else
18811 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18812 (const_int 0))
18813 (ne (symbol_ref "optimize_size")
18814 (const_int 0)))
18815 (const_string "V4SF")
18816 (const_string "TI"))]
18817 (const_string "TI")))])
18818
18819(define_insn "*movv16qi_internal"
18820 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18821 (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
18822 "TARGET_SSE
18823 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18824{
18825 switch (which_alternative)
18826 {
18827 case 0:
18828 if (get_attr_mode (insn) == MODE_V4SF)
18829 return "xorps\t%0, %0";
18830 else
18831 return "pxor\t%0, %0";
18832 case 1:
18833 case 2:
18834 if (get_attr_mode (insn) == MODE_V4SF)
18835 return "movaps\t{%1, %0|%0, %1}";
18836 else
18837 return "movdqa\t{%1, %0|%0, %1}";
18838 default:
18839 abort ();
18840 }
18841}
18842 [(set_attr "type" "ssemov")
18843 (set (attr "mode")
18844 (cond [(eq_attr "alternative" "0,1")
18845 (if_then_else
18846 (ne (symbol_ref "optimize_size")
18847 (const_int 0))
18848 (const_string "V4SF")
18849 (const_string "TI"))
18850 (eq_attr "alternative" "2")
18851 (if_then_else
18852 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18853 (const_int 0))
18854 (ne (symbol_ref "optimize_size")
18855 (const_int 0)))
18856 (const_string "V4SF")
18857 (const_string "TI"))]
18858 (const_string "TI")))])
18859
18860(define_expand "movv2df"
18861 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18862 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18863 "TARGET_SSE"
18864{
18865 ix86_expand_vector_move (V2DFmode, operands);
18866 DONE;
18867})
18868
18869(define_expand "movv8hi"
18870 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18871 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18872 "TARGET_SSE"
18873{
18874 ix86_expand_vector_move (V8HImode, operands);
18875 DONE;
18876})
18877
18878(define_expand "movv16qi"
18879 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18880 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18881 "TARGET_SSE"
18882{
18883 ix86_expand_vector_move (V16QImode, operands);
18884 DONE;
18885})
18886
18887(define_expand "movv4sf"
18888 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18889 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18890 "TARGET_SSE"
18891{
18892 ix86_expand_vector_move (V4SFmode, operands);
18893 DONE;
18894})
18895
18896(define_expand "movv4si"
18897 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18898 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18899 "TARGET_SSE"
18900{
18901 ix86_expand_vector_move (V4SImode, operands);
18902 DONE;
18903})
18904
18905(define_expand "movv2di"
18906 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18907 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18908 "TARGET_SSE"
18909{
18910 ix86_expand_vector_move (V2DImode, operands);
18911 DONE;
18912})
18913
18914(define_expand "movv2si"
18915 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18916 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18917 "TARGET_MMX"
18918{
18919 ix86_expand_vector_move (V2SImode, operands);
18920 DONE;
18921})
18922
18923(define_expand "movv4hi"
18924 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18925 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18926 "TARGET_MMX"
18927{
18928 ix86_expand_vector_move (V4HImode, operands);
18929 DONE;
18930})
18931
18932(define_expand "movv8qi"
18933 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18934 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18935 "TARGET_MMX"
18936{
18937 ix86_expand_vector_move (V8QImode, operands);
18938 DONE;
18939})
18940
18941(define_expand "movv2sf"
18942 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18943 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18944 "TARGET_MMX"
18945{
18946 ix86_expand_vector_move (V2SFmode, operands);
18947 DONE;
18948})
18949
18950(define_insn "*pushti"
18951 [(set (match_operand:TI 0 "push_operand" "=<")
18952 (match_operand:TI 1 "register_operand" "x"))]
18953 "TARGET_SSE"
18954 "#")
18955
18956(define_insn "*pushv2df"
18957 [(set (match_operand:V2DF 0 "push_operand" "=<")
18958 (match_operand:V2DF 1 "register_operand" "x"))]
18959 "TARGET_SSE"
18960 "#")
18961
18962(define_insn "*pushv2di"
18963 [(set (match_operand:V2DI 0 "push_operand" "=<")
18964 (match_operand:V2DI 1 "register_operand" "x"))]
18965 "TARGET_SSE"
18966 "#")
18967
18968(define_insn "*pushv8hi"
18969 [(set (match_operand:V8HI 0 "push_operand" "=<")
18970 (match_operand:V8HI 1 "register_operand" "x"))]
18971 "TARGET_SSE"
18972 "#")
18973
18974(define_insn "*pushv16qi"
18975 [(set (match_operand:V16QI 0 "push_operand" "=<")
18976 (match_operand:V16QI 1 "register_operand" "x"))]
18977 "TARGET_SSE"
18978 "#")
18979
18980(define_insn "*pushv4sf"
18981 [(set (match_operand:V4SF 0 "push_operand" "=<")
18982 (match_operand:V4SF 1 "register_operand" "x"))]
18983 "TARGET_SSE"
18984 "#")
18985
18986(define_insn "*pushv4si"
18987 [(set (match_operand:V4SI 0 "push_operand" "=<")
18988 (match_operand:V4SI 1 "register_operand" "x"))]
18989 "TARGET_SSE"
18990 "#")
18991
18992(define_insn "*pushv2si"
18993 [(set (match_operand:V2SI 0 "push_operand" "=<")
18994 (match_operand:V2SI 1 "register_operand" "y"))]
18995 "TARGET_MMX"
18996 "#")
18997
18998(define_insn "*pushv4hi"
18999 [(set (match_operand:V4HI 0 "push_operand" "=<")
19000 (match_operand:V4HI 1 "register_operand" "y"))]
19001 "TARGET_MMX"
19002 "#")
19003
19004(define_insn "*pushv8qi"
19005 [(set (match_operand:V8QI 0 "push_operand" "=<")
19006 (match_operand:V8QI 1 "register_operand" "y"))]
19007 "TARGET_MMX"
19008 "#")
19009
19010(define_insn "*pushv2sf"
19011 [(set (match_operand:V2SF 0 "push_operand" "=<")
19012 (match_operand:V2SF 1 "register_operand" "y"))]
19013 "TARGET_MMX"
19014 "#")
19015
19016(define_split
19017 [(set (match_operand 0 "push_operand" "")
19018 (match_operand 1 "register_operand" ""))]
19019 "!TARGET_64BIT && reload_completed
19020 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19021 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19022 (set (match_dup 2) (match_dup 1))]
19023 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19024 stack_pointer_rtx);
19025 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19026
19027(define_split
19028 [(set (match_operand 0 "push_operand" "")
19029 (match_operand 1 "register_operand" ""))]
19030 "TARGET_64BIT && reload_completed
19031 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19032 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19033 (set (match_dup 2) (match_dup 1))]
19034 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19035 stack_pointer_rtx);
19036 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19037
19038
19039(define_insn "*movti_internal"
19040 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19041 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19042 "TARGET_SSE && !TARGET_64BIT
19043 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19044{
19045 switch (which_alternative)
19046 {
19047 case 0:
19048 if (get_attr_mode (insn) == MODE_V4SF)
19049 return "xorps\t%0, %0";
19050 else
19051 return "pxor\t%0, %0";
19052 case 1:
19053 case 2:
19054 if (get_attr_mode (insn) == MODE_V4SF)
19055 return "movaps\t{%1, %0|%0, %1}";
19056 else
19057 return "movdqa\t{%1, %0|%0, %1}";
19058 default:
19059 abort ();
19060 }
19061}
19062 [(set_attr "type" "ssemov,ssemov,ssemov")
19063 (set (attr "mode")
19064 (cond [(eq_attr "alternative" "0,1")
19065 (if_then_else
19066 (ne (symbol_ref "optimize_size")
19067 (const_int 0))
19068 (const_string "V4SF")
19069 (const_string "TI"))
19070 (eq_attr "alternative" "2")
19071 (if_then_else
19072 (ne (symbol_ref "optimize_size")
19073 (const_int 0))
19074 (const_string "V4SF")
19075 (const_string "TI"))]
19076 (const_string "TI")))])
19077
19078(define_insn "*movti_rex64"
19079 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19080 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19081 "TARGET_64BIT
19082 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19083{
19084 switch (which_alternative)
19085 {
19086 case 0:
19087 case 1:
19088 return "#";
19089 case 2:
19090 if (get_attr_mode (insn) == MODE_V4SF)
19091 return "xorps\t%0, %0";
19092 else
19093 return "pxor\t%0, %0";
19094 case 3:
19095 case 4:
19096 if (get_attr_mode (insn) == MODE_V4SF)
19097 return "movaps\t{%1, %0|%0, %1}";
19098 else
19099 return "movdqa\t{%1, %0|%0, %1}";
19100 default:
19101 abort ();
19102 }
19103}
19104 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19105 (set (attr "mode")
19106 (cond [(eq_attr "alternative" "2,3")
19107 (if_then_else
19108 (ne (symbol_ref "optimize_size")
19109 (const_int 0))
19110 (const_string "V4SF")
19111 (const_string "TI"))
19112 (eq_attr "alternative" "4")
19113 (if_then_else
19114 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19115 (const_int 0))
19116 (ne (symbol_ref "optimize_size")
19117 (const_int 0)))
19118 (const_string "V4SF")
19119 (const_string "TI"))]
19120 (const_string "DI")))])
19121
19122(define_insn "*movtf_rex64"
19123 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19124 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19125 "TARGET_64BIT
19126 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19127{
19128 switch (which_alternative)
19129 {
19130 case 0:
19131 case 1:
19132 return "#";
19133 case 2:
19134 if (get_attr_mode (insn) == MODE_V4SF)
19135 return "xorps\t%0, %0";
19136 else
19137 return "pxor\t%0, %0";
19138 case 3:
19139 case 4:
19140 if (get_attr_mode (insn) == MODE_V4SF)
19141 return "movaps\t{%1, %0|%0, %1}";
19142 else
19143 return "movdqa\t{%1, %0|%0, %1}";
19144 default:
19145 abort ();
19146 }
19147}
19148 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19149 (set (attr "mode")
19150 (cond [(eq_attr "alternative" "2,3")
19151 (if_then_else
19152 (ne (symbol_ref "optimize_size")
19153 (const_int 0))
19154 (const_string "V4SF")
19155 (const_string "TI"))
19156 (eq_attr "alternative" "4")
19157 (if_then_else
19158 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19159 (const_int 0))
19160 (ne (symbol_ref "optimize_size")
19161 (const_int 0)))
19162 (const_string "V4SF")
19163 (const_string "TI"))]
19164 (const_string "DI")))])
19165
19166(define_split
19167 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19168 (match_operand:TI 1 "general_operand" ""))]
19169 "reload_completed && !SSE_REG_P (operands[0])
19170 && !SSE_REG_P (operands[1])"
19171 [(const_int 0)]
19172 "ix86_split_long_move (operands); DONE;")
19173
19174(define_split
19175 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19176 (match_operand:TF 1 "general_operand" ""))]
19177 "reload_completed && !SSE_REG_P (operands[0])
19178 && !SSE_REG_P (operands[1])"
19179 [(const_int 0)]
19180 "ix86_split_long_move (operands); DONE;")
19181
19182;; These two patterns are useful for specifying exactly whether to use
19183;; movaps or movups
19184(define_expand "sse_movaps"
19185 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19186 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19187 UNSPEC_MOVA))]
19188 "TARGET_SSE"
19189{
19190 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19191 {
19192 rtx tmp = gen_reg_rtx (V4SFmode);
19193 emit_insn (gen_sse_movaps (tmp, operands[1]));
19194 emit_move_insn (operands[0], tmp);
19195 DONE;
19196 }
19197})
19198
19199(define_insn "*sse_movaps_1"
19200 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19201 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19202 UNSPEC_MOVA))]
19203 "TARGET_SSE
19204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19205 "movaps\t{%1, %0|%0, %1}"
19206 [(set_attr "type" "ssemov,ssemov")
19207 (set_attr "mode" "V4SF")])
19208
19209(define_expand "sse_movups"
19210 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19211 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19212 UNSPEC_MOVU))]
19213 "TARGET_SSE"
19214{
19215 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19216 {
19217 rtx tmp = gen_reg_rtx (V4SFmode);
19218 emit_insn (gen_sse_movups (tmp, operands[1]));
19219 emit_move_insn (operands[0], tmp);
19220 DONE;
19221 }
19222})
19223
19224(define_insn "*sse_movups_1"
19225 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19226 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19227 UNSPEC_MOVU))]
19228 "TARGET_SSE
19229 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19230 "movups\t{%1, %0|%0, %1}"
19231 [(set_attr "type" "ssecvt,ssecvt")
19232 (set_attr "mode" "V4SF")])
19233
19234;; SSE Strange Moves.
19235
19236(define_insn "sse_movmskps"
19237 [(set (match_operand:SI 0 "register_operand" "=r")
19238 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19239 UNSPEC_MOVMSK))]
19240 "TARGET_SSE"
19241 "movmskps\t{%1, %0|%0, %1}"
19242 [(set_attr "type" "ssecvt")
19243 (set_attr "mode" "V4SF")])
19244
19245(define_insn "mmx_pmovmskb"
19246 [(set (match_operand:SI 0 "register_operand" "=r")
19247 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19248 UNSPEC_MOVMSK))]
19249 "TARGET_SSE || TARGET_3DNOW_A"
19250 "pmovmskb\t{%1, %0|%0, %1}"
19251 [(set_attr "type" "ssecvt")
19252 (set_attr "mode" "V4SF")])
19253
19254
19255(define_insn "mmx_maskmovq"
19256 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19257 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19258 (match_operand:V8QI 2 "register_operand" "y")]
19259 UNSPEC_MASKMOV))]
19260 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19261 ;; @@@ check ordering of operands in intel/nonintel syntax
19262 "maskmovq\t{%2, %1|%1, %2}"
19263 [(set_attr "type" "mmxcvt")
19264 (set_attr "mode" "DI")])
19265
19266(define_insn "mmx_maskmovq_rex"
19267 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19268 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19269 (match_operand:V8QI 2 "register_operand" "y")]
19270 UNSPEC_MASKMOV))]
19271 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19272 ;; @@@ check ordering of operands in intel/nonintel syntax
19273 "maskmovq\t{%2, %1|%1, %2}"
19274 [(set_attr "type" "mmxcvt")
19275 (set_attr "mode" "DI")])
19276
19277(define_insn "sse_movntv4sf"
19278 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19279 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19280 UNSPEC_MOVNT))]
19281 "TARGET_SSE"
19282 "movntps\t{%1, %0|%0, %1}"
19283 [(set_attr "type" "ssemov")
19284 (set_attr "mode" "V4SF")])
19285
19286(define_insn "sse_movntdi"
19287 [(set (match_operand:DI 0 "memory_operand" "=m")
19288 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19289 UNSPEC_MOVNT))]
19290 "TARGET_SSE || TARGET_3DNOW_A"
19291 "movntq\t{%1, %0|%0, %1}"
19292 [(set_attr "type" "mmxmov")
19293 (set_attr "mode" "DI")])
19294
19295(define_insn "sse_movhlps"
19296 [(set (match_operand:V4SF 0 "register_operand" "=x")
19297 (vec_merge:V4SF
19298 (match_operand:V4SF 1 "register_operand" "0")
19299 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19300 (parallel [(const_int 2)
19301 (const_int 3)
19302 (const_int 0)
19303 (const_int 1)]))
19304 (const_int 3)))]
19305 "TARGET_SSE"
19306 "movhlps\t{%2, %0|%0, %2}"
19307 [(set_attr "type" "ssecvt")
19308 (set_attr "mode" "V4SF")])
19309
19310(define_insn "sse_movlhps"
19311 [(set (match_operand:V4SF 0 "register_operand" "=x")
19312 (vec_merge:V4SF
19313 (match_operand:V4SF 1 "register_operand" "0")
19314 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19315 (parallel [(const_int 2)
19316 (const_int 3)
19317 (const_int 0)
19318 (const_int 1)]))
19319 (const_int 12)))]
19320 "TARGET_SSE"
19321 "movlhps\t{%2, %0|%0, %2}"
19322 [(set_attr "type" "ssecvt")
19323 (set_attr "mode" "V4SF")])
19324
19325(define_insn "sse_movhps"
19326 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19327 (vec_merge:V4SF
19328 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19329 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19330 (const_int 12)))]
19331 "TARGET_SSE
19332 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19333 "movhps\t{%2, %0|%0, %2}"
19334 [(set_attr "type" "ssecvt")
19335 (set_attr "mode" "V4SF")])
19336
19337(define_insn "sse_movlps"
19338 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19339 (vec_merge:V4SF
19340 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19341 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19342 (const_int 3)))]
19343 "TARGET_SSE
19344 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19345 "movlps\t{%2, %0|%0, %2}"
19346 [(set_attr "type" "ssecvt")
19347 (set_attr "mode" "V4SF")])
19348
19349(define_expand "sse_loadss"
19350 [(match_operand:V4SF 0 "register_operand" "")
19351 (match_operand:SF 1 "memory_operand" "")]
19352 "TARGET_SSE"
19353{
19354 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19355 CONST0_RTX (V4SFmode)));
19356 DONE;
19357})
19358
19359(define_insn "sse_loadss_1"
19360 [(set (match_operand:V4SF 0 "register_operand" "=x")
19361 (vec_merge:V4SF
19362 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19363 (match_operand:V4SF 2 "const0_operand" "X")
19364 (const_int 1)))]
19365 "TARGET_SSE"
19366 "movss\t{%1, %0|%0, %1}"
19367 [(set_attr "type" "ssemov")
19368 (set_attr "mode" "SF")])
19369
19370(define_insn "sse_movss"
19371 [(set (match_operand:V4SF 0 "register_operand" "=x")
19372 (vec_merge:V4SF
19373 (match_operand:V4SF 1 "register_operand" "0")
19374 (match_operand:V4SF 2 "register_operand" "x")
19375 (const_int 1)))]
19376 "TARGET_SSE"
19377 "movss\t{%2, %0|%0, %2}"
19378 [(set_attr "type" "ssemov")
19379 (set_attr "mode" "SF")])
19380
19381(define_insn "sse_storess"
19382 [(set (match_operand:SF 0 "memory_operand" "=m")
19383 (vec_select:SF
19384 (match_operand:V4SF 1 "register_operand" "x")
19385 (parallel [(const_int 0)])))]
19386 "TARGET_SSE"
19387 "movss\t{%1, %0|%0, %1}"
19388 [(set_attr "type" "ssemov")
19389 (set_attr "mode" "SF")])
19390
19391(define_insn "sse_shufps"
19392 [(set (match_operand:V4SF 0 "register_operand" "=x")
19393 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19394 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19395 (match_operand:SI 3 "immediate_operand" "i")]
19396 UNSPEC_SHUFFLE))]
19397 "TARGET_SSE"
19398 ;; @@@ check operand order for intel/nonintel syntax
19399 "shufps\t{%3, %2, %0|%0, %2, %3}"
19400 [(set_attr "type" "ssecvt")
19401 (set_attr "mode" "V4SF")])
19402
19403
19404;; SSE arithmetic
19405
19406(define_insn "addv4sf3"
19407 [(set (match_operand:V4SF 0 "register_operand" "=x")
19408 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19409 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19410 "TARGET_SSE"
19411 "addps\t{%2, %0|%0, %2}"
19412 [(set_attr "type" "sseadd")
19413 (set_attr "mode" "V4SF")])
19414
19415(define_insn "vmaddv4sf3"
19416 [(set (match_operand:V4SF 0 "register_operand" "=x")
19417 (vec_merge:V4SF
19418 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19419 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19420 (match_dup 1)
19421 (const_int 1)))]
19422 "TARGET_SSE"
19423 "addss\t{%2, %0|%0, %2}"
19424 [(set_attr "type" "sseadd")
19425 (set_attr "mode" "SF")])
19426
19427(define_insn "subv4sf3"
19428 [(set (match_operand:V4SF 0 "register_operand" "=x")
19429 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19430 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19431 "TARGET_SSE"
19432 "subps\t{%2, %0|%0, %2}"
19433 [(set_attr "type" "sseadd")
19434 (set_attr "mode" "V4SF")])
19435
19436(define_insn "vmsubv4sf3"
19437 [(set (match_operand:V4SF 0 "register_operand" "=x")
19438 (vec_merge:V4SF
19439 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19440 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19441 (match_dup 1)
19442 (const_int 1)))]
19443 "TARGET_SSE"
19444 "subss\t{%2, %0|%0, %2}"
19445 [(set_attr "type" "sseadd")
19446 (set_attr "mode" "SF")])
19447
19448(define_insn "mulv4sf3"
19449 [(set (match_operand:V4SF 0 "register_operand" "=x")
19450 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19451 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19452 "TARGET_SSE"
19453 "mulps\t{%2, %0|%0, %2}"
19454 [(set_attr "type" "ssemul")
19455 (set_attr "mode" "V4SF")])
19456
19457(define_insn "vmmulv4sf3"
19458 [(set (match_operand:V4SF 0 "register_operand" "=x")
19459 (vec_merge:V4SF
19460 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19461 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19462 (match_dup 1)
19463 (const_int 1)))]
19464 "TARGET_SSE"
19465 "mulss\t{%2, %0|%0, %2}"
19466 [(set_attr "type" "ssemul")
19467 (set_attr "mode" "SF")])
19468
19469(define_insn "divv4sf3"
19470 [(set (match_operand:V4SF 0 "register_operand" "=x")
19471 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19472 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19473 "TARGET_SSE"
19474 "divps\t{%2, %0|%0, %2}"
19475 [(set_attr "type" "ssediv")
19476 (set_attr "mode" "V4SF")])
19477
19478(define_insn "vmdivv4sf3"
19479 [(set (match_operand:V4SF 0 "register_operand" "=x")
19480 (vec_merge:V4SF
19481 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19482 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19483 (match_dup 1)
19484 (const_int 1)))]
19485 "TARGET_SSE"
19486 "divss\t{%2, %0|%0, %2}"
19487 [(set_attr "type" "ssediv")
19488 (set_attr "mode" "SF")])
19489
19490
19491;; SSE square root/reciprocal
19492
19493(define_insn "rcpv4sf2"
19494 [(set (match_operand:V4SF 0 "register_operand" "=x")
19495 (unspec:V4SF
19496 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19497 "TARGET_SSE"
19498 "rcpps\t{%1, %0|%0, %1}"
19499 [(set_attr "type" "sse")
19500 (set_attr "mode" "V4SF")])
19501
19502(define_insn "vmrcpv4sf2"
19503 [(set (match_operand:V4SF 0 "register_operand" "=x")
19504 (vec_merge:V4SF
19505 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19506 UNSPEC_RCP)
19507 (match_operand:V4SF 2 "register_operand" "0")
19508 (const_int 1)))]
19509 "TARGET_SSE"
19510 "rcpss\t{%1, %0|%0, %1}"
19511 [(set_attr "type" "sse")
19512 (set_attr "mode" "SF")])
19513
19514(define_insn "rsqrtv4sf2"
19515 [(set (match_operand:V4SF 0 "register_operand" "=x")
19516 (unspec:V4SF
19517 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19518 "TARGET_SSE"
19519 "rsqrtps\t{%1, %0|%0, %1}"
19520 [(set_attr "type" "sse")
19521 (set_attr "mode" "V4SF")])
19522
19523(define_insn "vmrsqrtv4sf2"
19524 [(set (match_operand:V4SF 0 "register_operand" "=x")
19525 (vec_merge:V4SF
19526 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19527 UNSPEC_RSQRT)
19528 (match_operand:V4SF 2 "register_operand" "0")
19529 (const_int 1)))]
19530 "TARGET_SSE"
19531 "rsqrtss\t{%1, %0|%0, %1}"
19532 [(set_attr "type" "sse")
19533 (set_attr "mode" "SF")])
19534
19535(define_insn "sqrtv4sf2"
19536 [(set (match_operand:V4SF 0 "register_operand" "=x")
19537 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19538 "TARGET_SSE"
19539 "sqrtps\t{%1, %0|%0, %1}"
19540 [(set_attr "type" "sse")
19541 (set_attr "mode" "V4SF")])
19542
19543(define_insn "vmsqrtv4sf2"
19544 [(set (match_operand:V4SF 0 "register_operand" "=x")
19545 (vec_merge:V4SF
19546 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19547 (match_operand:V4SF 2 "register_operand" "0")
19548 (const_int 1)))]
19549 "TARGET_SSE"
19550 "sqrtss\t{%1, %0|%0, %1}"
19551 [(set_attr "type" "sse")
19552 (set_attr "mode" "SF")])
19553
19554;; SSE logical operations.
19555
19556;; SSE defines logical operations on floating point values. This brings
19557;; interesting challenge to RTL representation where logicals are only valid
19558;; on integral types. We deal with this by representing the floating point
19559;; logical as logical on arguments casted to TImode as this is what hardware
19560;; really does. Unfortunately hardware requires the type information to be
19561;; present and thus we must avoid subregs from being simplified and eliminated
19562;; in later compilation phases.
19563;;
19564;; We have following variants from each instruction:
19565;; sse_andsf3 - the operation taking V4SF vector operands
19566;; and doing TImode cast on them
19567;; *sse_andsf3_memory - the operation taking one memory operand casted to
19568;; TImode, since backend insist on eliminating casts
19569;; on memory operands
19570;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19571;; We can not accept memory operand here as instruction reads
19572;; whole scalar. This is generated only post reload by GCC
19573;; scalar float operations that expands to logicals (fabs)
19574;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19575;; memory operand. Eventually combine can be able
19576;; to synthesize these using splitter.
19577;; sse2_anddf3, *sse2_anddf3_memory
19578;;
19579;;
19580;; These are not called andti3 etc. because we really really don't want
19581;; the compiler to widen DImode ands to TImode ands and then try to move
19582;; into DImode subregs of SSE registers, and them together, and move out
19583;; of DImode subregs again!
19584;; SSE1 single precision floating point logical operation
19585(define_expand "sse_andv4sf3"
19586 [(set (match_operand:V4SF 0 "register_operand" "")
19587 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
19588 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19589 "TARGET_SSE"
19590 "")
19591
19592(define_insn "*sse_andv4sf3"
19593 [(set (match_operand:V4SF 0 "register_operand" "=x")
19594 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19595 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19596 "TARGET_SSE
19597 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19598 "andps\t{%2, %0|%0, %2}"
19599 [(set_attr "type" "sselog")
19600 (set_attr "mode" "V4SF")])
19601
19602(define_expand "sse_nandv4sf3"
19603 [(set (match_operand:V4SF 0 "register_operand" "")
19604 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
19605 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19606 "TARGET_SSE"
19607 "")
19608
19609(define_insn "*sse_nandv4sf3"
19610 [(set (match_operand:V4SF 0 "register_operand" "=x")
19611 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
19612 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19613 "TARGET_SSE"
19614 "andnps\t{%2, %0|%0, %2}"
19615 [(set_attr "type" "sselog")
19616 (set_attr "mode" "V4SF")])
19617
19618(define_expand "sse_iorv4sf3"
19619 [(set (match_operand:V4SF 0 "register_operand" "")
19620 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
19621 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19622 "TARGET_SSE"
19623 "")
19624
19625(define_insn "*sse_iorv4sf3"
19626 [(set (match_operand:V4SF 0 "register_operand" "=x")
19627 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19628 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19629 "TARGET_SSE
19630 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19631 "orps\t{%2, %0|%0, %2}"
19632 [(set_attr "type" "sselog")
19633 (set_attr "mode" "V4SF")])
19634
19635(define_expand "sse_xorv4sf3"
19636 [(set (match_operand:V4SF 0 "register_operand" "")
19637 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
19638 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19639 "TARGET_SSE"
19640 "")
19641
19642(define_insn "*sse_xorv4sf3"
19643 [(set (match_operand:V4SF 0 "register_operand" "=x")
19644 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19645 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19646 "TARGET_SSE
19647 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19648 "xorps\t{%2, %0|%0, %2}"
19649 [(set_attr "type" "sselog")
19650 (set_attr "mode" "V4SF")])
19651
19652;; SSE2 double precision floating point logical operation
19653
19654(define_expand "sse2_andv2df3"
19655 [(set (match_operand:V2DF 0 "register_operand" "")
19656 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
19657 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19658 "TARGET_SSE2"
19659 "")
19660
19661(define_insn "*sse2_andv2df3"
19662 [(set (match_operand:V2DF 0 "register_operand" "=x")
19663 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19664 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19665 "TARGET_SSE2
19666 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19667 "andpd\t{%2, %0|%0, %2}"
19668 [(set_attr "type" "sselog")
19669 (set_attr "mode" "V2DF")])
19670
19671(define_expand "sse2_nandv2df3"
19672 [(set (match_operand:V2DF 0 "register_operand" "")
19673 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
19674 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19675 "TARGET_SSE2"
19676 "")
19677
19678(define_insn "*sse2_nandv2df3"
19679 [(set (match_operand:V2DF 0 "register_operand" "=x")
19680 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
19681 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19682 "TARGET_SSE2"
19683 "andnpd\t{%2, %0|%0, %2}"
19684 [(set_attr "type" "sselog")
19685 (set_attr "mode" "V2DF")])
19686
19687(define_expand "sse2_iorv2df3"
19688 [(set (match_operand:V2DF 0 "register_operand" "")
19689 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
19690 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19691 "TARGET_SSE2"
19692 "")
19693
19694(define_insn "*sse2_iorv2df3"
19695 [(set (match_operand:V2DF 0 "register_operand" "=x")
19696 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19697 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19698 "TARGET_SSE2
19699 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19700 "orpd\t{%2, %0|%0, %2}"
19701 [(set_attr "type" "sselog")
19702 (set_attr "mode" "V2DF")])
19703
19704(define_expand "sse2_xorv2df3"
19705 [(set (match_operand:V2DF 0 "register_operand" "")
19706 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
19707 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19708 "TARGET_SSE2"
19709 "")
19710
19711(define_insn "*sse2_xorv2df3"
19712 [(set (match_operand:V2DF 0 "register_operand" "=x")
19713 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19714 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19715 "TARGET_SSE2
19716 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19717 "xorpd\t{%2, %0|%0, %2}"
19718 [(set_attr "type" "sselog")
19719 (set_attr "mode" "V2DF")])
19720
19721;; SSE2 integral logicals. These patterns must always come after floating
19722;; point ones since we don't want compiler to use integer opcodes on floating
19723;; point SSE values to avoid matching of subregs in the match_operand.
19724(define_insn "*sse2_andti3"
19725 [(set (match_operand:TI 0 "register_operand" "=x")
19726 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19727 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19728 "TARGET_SSE2
19729 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19730 "pand\t{%2, %0|%0, %2}"
19731 [(set_attr "type" "sselog")
19732 (set_attr "mode" "TI")])
19733
19734(define_insn "sse2_andv2di3"
19735 [(set (match_operand:V2DI 0 "register_operand" "=x")
19736 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19737 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19738 "TARGET_SSE2
19739 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19740 "pand\t{%2, %0|%0, %2}"
19741 [(set_attr "type" "sselog")
19742 (set_attr "mode" "TI")])
19743
19744(define_insn "*sse2_nandti3"
19745 [(set (match_operand:TI 0 "register_operand" "=x")
19746 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19747 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19748 "TARGET_SSE2"
19749 "pandn\t{%2, %0|%0, %2}"
19750 [(set_attr "type" "sselog")
19751 (set_attr "mode" "TI")])
19752
19753(define_insn "sse2_nandv2di3"
19754 [(set (match_operand:V2DI 0 "register_operand" "=x")
19755 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19756 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19757 "TARGET_SSE2
19758 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19759 "pandn\t{%2, %0|%0, %2}"
19760 [(set_attr "type" "sselog")
19761 (set_attr "mode" "TI")])
19762
19763(define_insn "*sse2_iorti3"
19764 [(set (match_operand:TI 0 "register_operand" "=x")
19765 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19766 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19767 "TARGET_SSE2
19768 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19769 "por\t{%2, %0|%0, %2}"
19770 [(set_attr "type" "sselog")
19771 (set_attr "mode" "TI")])
19772
19773(define_insn "sse2_iorv2di3"
19774 [(set (match_operand:V2DI 0 "register_operand" "=x")
19775 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19776 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19777 "TARGET_SSE2
19778 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19779 "por\t{%2, %0|%0, %2}"
19780 [(set_attr "type" "sselog")
19781 (set_attr "mode" "TI")])
19782
19783(define_insn "*sse2_xorti3"
19784 [(set (match_operand:TI 0 "register_operand" "=x")
19785 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19786 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19787 "TARGET_SSE2
19788 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19789 "pxor\t{%2, %0|%0, %2}"
19790 [(set_attr "type" "sselog")
19791 (set_attr "mode" "TI")])
19792
19793(define_insn "sse2_xorv2di3"
19794 [(set (match_operand:V2DI 0 "register_operand" "=x")
19795 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19796 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19797 "TARGET_SSE2
19798 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19799 "pxor\t{%2, %0|%0, %2}"
19800 [(set_attr "type" "sselog")
19801 (set_attr "mode" "TI")])
19802
19803;; Use xor, but don't show input operands so they aren't live before
19804;; this insn.
19805(define_insn "sse_clrv4sf"
19806 [(set (match_operand:V4SF 0 "register_operand" "=x")
19807 (match_operand:V4SF 1 "const0_operand" "X"))]
19808 "TARGET_SSE"
19809{
19810 if (get_attr_mode (insn) == MODE_TI)
19811 return "pxor\t{%0, %0|%0, %0}";
19812 else
19813 return "xorps\t{%0, %0|%0, %0}";
19814}
19815 [(set_attr "type" "sselog")
19816 (set_attr "memory" "none")
19817 (set (attr "mode")
19818 (if_then_else
19819 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19820 (const_int 0))
19821 (ne (symbol_ref "TARGET_SSE2")
19822 (const_int 0)))
19823 (eq (symbol_ref "optimize_size")
19824 (const_int 0)))
19825 (const_string "TI")
19826 (const_string "V4SF")))])
19827
19828;; Use xor, but don't show input operands so they aren't live before
19829;; this insn.
19830(define_insn "sse_clrv2df"
19831 [(set (match_operand:V2DF 0 "register_operand" "=x")
19832 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19833 "TARGET_SSE2"
19834 "xorpd\t{%0, %0|%0, %0}"
19835 [(set_attr "type" "sselog")
19836 (set_attr "memory" "none")
19837 (set_attr "mode" "V4SF")])
19838
19839;; SSE mask-generating compares
19840
19841(define_insn "maskcmpv4sf3"
19842 [(set (match_operand:V4SI 0 "register_operand" "=x")
19843 (match_operator:V4SI 3 "sse_comparison_operator"
19844 [(match_operand:V4SF 1 "register_operand" "0")
19845 (match_operand:V4SF 2 "register_operand" "x")]))]
19846 "TARGET_SSE"
19847 "cmp%D3ps\t{%2, %0|%0, %2}"
19848 [(set_attr "type" "ssecmp")
19849 (set_attr "mode" "V4SF")])
19850
19851(define_insn "maskncmpv4sf3"
19852 [(set (match_operand:V4SI 0 "register_operand" "=x")
19853 (not:V4SI
19854 (match_operator:V4SI 3 "sse_comparison_operator"
19855 [(match_operand:V4SF 1 "register_operand" "0")
19856 (match_operand:V4SF 2 "register_operand" "x")])))]
19857 "TARGET_SSE"
19858{
19859 if (GET_CODE (operands[3]) == UNORDERED)
19860 return "cmpordps\t{%2, %0|%0, %2}";
19861 else
19862 return "cmpn%D3ps\t{%2, %0|%0, %2}";
19863}
19864 [(set_attr "type" "ssecmp")
19865 (set_attr "mode" "V4SF")])
19866
19867(define_insn "vmmaskcmpv4sf3"
19868 [(set (match_operand:V4SI 0 "register_operand" "=x")
19869 (vec_merge:V4SI
19870 (match_operator:V4SI 3 "sse_comparison_operator"
19871 [(match_operand:V4SF 1 "register_operand" "0")
19872 (match_operand:V4SF 2 "register_operand" "x")])
19873 (subreg:V4SI (match_dup 1) 0)
19874 (const_int 1)))]
19875 "TARGET_SSE"
19876 "cmp%D3ss\t{%2, %0|%0, %2}"
19877 [(set_attr "type" "ssecmp")
19878 (set_attr "mode" "SF")])
19879
19880(define_insn "vmmaskncmpv4sf3"
19881 [(set (match_operand:V4SI 0 "register_operand" "=x")
19882 (vec_merge:V4SI
19883 (not:V4SI
19884 (match_operator:V4SI 3 "sse_comparison_operator"
19885 [(match_operand:V4SF 1 "register_operand" "0")
19886 (match_operand:V4SF 2 "register_operand" "x")]))
19887 (subreg:V4SI (match_dup 1) 0)
19888 (const_int 1)))]
19889 "TARGET_SSE"
19890{
19891 if (GET_CODE (operands[3]) == UNORDERED)
19892 return "cmpordss\t{%2, %0|%0, %2}";
19893 else
19894 return "cmpn%D3ss\t{%2, %0|%0, %2}";
19895}
19896 [(set_attr "type" "ssecmp")
19897 (set_attr "mode" "SF")])
19898
19899(define_insn "sse_comi"
19900 [(set (reg:CCFP 17)
19901 (compare:CCFP (vec_select:SF
19902 (match_operand:V4SF 0 "register_operand" "x")
19903 (parallel [(const_int 0)]))
19904 (vec_select:SF
19905 (match_operand:V4SF 1 "register_operand" "x")
19906 (parallel [(const_int 0)]))))]
19907 "TARGET_SSE"
19908 "comiss\t{%1, %0|%0, %1}"
19909 [(set_attr "type" "ssecomi")
19910 (set_attr "mode" "SF")])
19911
19912(define_insn "sse_ucomi"
19913 [(set (reg:CCFPU 17)
19914 (compare:CCFPU (vec_select:SF
19915 (match_operand:V4SF 0 "register_operand" "x")
19916 (parallel [(const_int 0)]))
19917 (vec_select:SF
19918 (match_operand:V4SF 1 "register_operand" "x")
19919 (parallel [(const_int 0)]))))]
19920 "TARGET_SSE"
19921 "ucomiss\t{%1, %0|%0, %1}"
19922 [(set_attr "type" "ssecomi")
19923 (set_attr "mode" "SF")])
19924
19925
19926;; SSE unpack
19927
19928(define_insn "sse_unpckhps"
19929 [(set (match_operand:V4SF 0 "register_operand" "=x")
19930 (vec_merge:V4SF
19931 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19932 (parallel [(const_int 2)
19933 (const_int 0)
19934 (const_int 3)
19935 (const_int 1)]))
19936 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19937 (parallel [(const_int 0)
19938 (const_int 2)
19939 (const_int 1)
19940 (const_int 3)]))
19941 (const_int 5)))]
19942 "TARGET_SSE"
19943 "unpckhps\t{%2, %0|%0, %2}"
19944 [(set_attr "type" "ssecvt")
19945 (set_attr "mode" "V4SF")])
19946
19947(define_insn "sse_unpcklps"
19948 [(set (match_operand:V4SF 0 "register_operand" "=x")
19949 (vec_merge:V4SF
19950 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19951 (parallel [(const_int 0)
19952 (const_int 2)
19953 (const_int 1)
19954 (const_int 3)]))
19955 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19956 (parallel [(const_int 2)
19957 (const_int 0)
19958 (const_int 3)
19959 (const_int 1)]))
19960 (const_int 5)))]
19961 "TARGET_SSE"
19962 "unpcklps\t{%2, %0|%0, %2}"
19963 [(set_attr "type" "ssecvt")
19964 (set_attr "mode" "V4SF")])
19965
19966
19967;; SSE min/max
19968
19969(define_insn "smaxv4sf3"
19970 [(set (match_operand:V4SF 0 "register_operand" "=x")
19971 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19972 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19973 "TARGET_SSE"
19974 "maxps\t{%2, %0|%0, %2}"
19975 [(set_attr "type" "sse")
19976 (set_attr "mode" "V4SF")])
19977
19978(define_insn "vmsmaxv4sf3"
19979 [(set (match_operand:V4SF 0 "register_operand" "=x")
19980 (vec_merge:V4SF
19981 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19982 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19983 (match_dup 1)
19984 (const_int 1)))]
19985 "TARGET_SSE"
19986 "maxss\t{%2, %0|%0, %2}"
19987 [(set_attr "type" "sse")
19988 (set_attr "mode" "SF")])
19989
19990(define_insn "sminv4sf3"
19991 [(set (match_operand:V4SF 0 "register_operand" "=x")
19992 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19993 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19994 "TARGET_SSE"
19995 "minps\t{%2, %0|%0, %2}"
19996 [(set_attr "type" "sse")
19997 (set_attr "mode" "V4SF")])
19998
19999(define_insn "vmsminv4sf3"
20000 [(set (match_operand:V4SF 0 "register_operand" "=x")
20001 (vec_merge:V4SF
20002 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20003 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20004 (match_dup 1)
20005 (const_int 1)))]
20006 "TARGET_SSE"
20007 "minss\t{%2, %0|%0, %2}"
20008 [(set_attr "type" "sse")
20009 (set_attr "mode" "SF")])
20010
20011;; SSE <-> integer/MMX conversions
20012
20013(define_insn "cvtpi2ps"
20014 [(set (match_operand:V4SF 0 "register_operand" "=x")
20015 (vec_merge:V4SF
20016 (match_operand:V4SF 1 "register_operand" "0")
20017 (vec_duplicate:V4SF
20018 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20019 (const_int 12)))]
20020 "TARGET_SSE"
20021 "cvtpi2ps\t{%2, %0|%0, %2}"
20022 [(set_attr "type" "ssecvt")
20023 (set_attr "mode" "V4SF")])
20024
20025(define_insn "cvtps2pi"
20026 [(set (match_operand:V2SI 0 "register_operand" "=y")
20027 (vec_select:V2SI
20028 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20029 (parallel [(const_int 0) (const_int 1)])))]
20030 "TARGET_SSE"
20031 "cvtps2pi\t{%1, %0|%0, %1}"
20032 [(set_attr "type" "ssecvt")
20033 (set_attr "mode" "V4SF")])
20034
20035(define_insn "cvttps2pi"
20036 [(set (match_operand:V2SI 0 "register_operand" "=y")
20037 (vec_select:V2SI
20038 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20039 UNSPEC_FIX)
20040 (parallel [(const_int 0) (const_int 1)])))]
20041 "TARGET_SSE"
20042 "cvttps2pi\t{%1, %0|%0, %1}"
20043 [(set_attr "type" "ssecvt")
20044 (set_attr "mode" "SF")])
20045
20046(define_insn "cvtsi2ss"
20047 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20048 (vec_merge:V4SF
20049 (match_operand:V4SF 1 "register_operand" "0,0")
20050 (vec_duplicate:V4SF
20051 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20052 (const_int 14)))]
20053 "TARGET_SSE"
20054 "cvtsi2ss\t{%2, %0|%0, %2}"
20055 [(set_attr "type" "sseicvt")
20056 (set_attr "athlon_decode" "vector,double")
20057 (set_attr "mode" "SF")])
20058
20059(define_insn "cvtsi2ssq"
20060 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20061 (vec_merge:V4SF
20062 (match_operand:V4SF 1 "register_operand" "0,0")
20063 (vec_duplicate:V4SF
20064 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20065 (const_int 14)))]
20066 "TARGET_SSE && TARGET_64BIT"
20067 "cvtsi2ssq\t{%2, %0|%0, %2}"
20068 [(set_attr "type" "sseicvt")
20069 (set_attr "athlon_decode" "vector,double")
20070 (set_attr "mode" "SF")])
20071
20072(define_insn "cvtss2si"
20073 [(set (match_operand:SI 0 "register_operand" "=r,r")
20074 (vec_select:SI
20075 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20076 (parallel [(const_int 0)])))]
20077 "TARGET_SSE"
20078 "cvtss2si\t{%1, %0|%0, %1}"
20079 [(set_attr "type" "sseicvt")
20080 (set_attr "athlon_decode" "double,vector")
20081 (set_attr "mode" "SI")])
20082
20083(define_insn "cvtss2siq"
20084 [(set (match_operand:DI 0 "register_operand" "=r,r")
20085 (vec_select:DI
20086 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20087 (parallel [(const_int 0)])))]
20088 "TARGET_SSE"
20089 "cvtss2siq\t{%1, %0|%0, %1}"
20090 [(set_attr "type" "sseicvt")
20091 (set_attr "athlon_decode" "double,vector")
20092 (set_attr "mode" "DI")])
20093
20094(define_insn "cvttss2si"
20095 [(set (match_operand:SI 0 "register_operand" "=r,r")
20096 (vec_select:SI
20097 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20098 UNSPEC_FIX)
20099 (parallel [(const_int 0)])))]
20100 "TARGET_SSE"
20101 "cvttss2si\t{%1, %0|%0, %1}"
20102 [(set_attr "type" "sseicvt")
20103 (set_attr "mode" "SF")
20104 (set_attr "athlon_decode" "double,vector")])
20105
20106(define_insn "cvttss2siq"
20107 [(set (match_operand:DI 0 "register_operand" "=r,r")
20108 (vec_select:DI
20109 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20110 UNSPEC_FIX)
20111 (parallel [(const_int 0)])))]
20112 "TARGET_SSE && TARGET_64BIT"
20113 "cvttss2siq\t{%1, %0|%0, %1}"
20114 [(set_attr "type" "sseicvt")
20115 (set_attr "mode" "SF")
20116 (set_attr "athlon_decode" "double,vector")])
20117
20118
20119;; MMX insns
20120
20121;; MMX arithmetic
20122
20123(define_insn "addv8qi3"
20124 [(set (match_operand:V8QI 0 "register_operand" "=y")
20125 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20126 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20127 "TARGET_MMX"
20128 "paddb\t{%2, %0|%0, %2}"
20129 [(set_attr "type" "mmxadd")
20130 (set_attr "mode" "DI")])
20131
20132(define_insn "addv4hi3"
20133 [(set (match_operand:V4HI 0 "register_operand" "=y")
20134 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20135 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20136 "TARGET_MMX"
20137 "paddw\t{%2, %0|%0, %2}"
20138 [(set_attr "type" "mmxadd")
20139 (set_attr "mode" "DI")])
20140
20141(define_insn "addv2si3"
20142 [(set (match_operand:V2SI 0 "register_operand" "=y")
20143 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20144 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20145 "TARGET_MMX"
20146 "paddd\t{%2, %0|%0, %2}"
20147 [(set_attr "type" "mmxadd")
20148 (set_attr "mode" "DI")])
20149
20150(define_insn "mmx_adddi3"
20151 [(set (match_operand:DI 0 "register_operand" "=y")
20152 (unspec:DI
20153 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20154 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20155 UNSPEC_NOP))]
20156 "TARGET_MMX"
20157 "paddq\t{%2, %0|%0, %2}"
20158 [(set_attr "type" "mmxadd")
20159 (set_attr "mode" "DI")])
20160
20161(define_insn "ssaddv8qi3"
20162 [(set (match_operand:V8QI 0 "register_operand" "=y")
20163 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20164 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20165 "TARGET_MMX"
20166 "paddsb\t{%2, %0|%0, %2}"
20167 [(set_attr "type" "mmxadd")
20168 (set_attr "mode" "DI")])
20169
20170(define_insn "ssaddv4hi3"
20171 [(set (match_operand:V4HI 0 "register_operand" "=y")
20172 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20173 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20174 "TARGET_MMX"
20175 "paddsw\t{%2, %0|%0, %2}"
20176 [(set_attr "type" "mmxadd")
20177 (set_attr "mode" "DI")])
20178
20179(define_insn "usaddv8qi3"
20180 [(set (match_operand:V8QI 0 "register_operand" "=y")
20181 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20182 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20183 "TARGET_MMX"
20184 "paddusb\t{%2, %0|%0, %2}"
20185 [(set_attr "type" "mmxadd")
20186 (set_attr "mode" "DI")])
20187
20188(define_insn "usaddv4hi3"
20189 [(set (match_operand:V4HI 0 "register_operand" "=y")
20190 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20191 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20192 "TARGET_MMX"
20193 "paddusw\t{%2, %0|%0, %2}"
20194 [(set_attr "type" "mmxadd")
20195 (set_attr "mode" "DI")])
20196
20197(define_insn "subv8qi3"
20198 [(set (match_operand:V8QI 0 "register_operand" "=y")
20199 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20200 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20201 "TARGET_MMX"
20202 "psubb\t{%2, %0|%0, %2}"
20203 [(set_attr "type" "mmxadd")
20204 (set_attr "mode" "DI")])
20205
20206(define_insn "subv4hi3"
20207 [(set (match_operand:V4HI 0 "register_operand" "=y")
20208 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20209 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20210 "TARGET_MMX"
20211 "psubw\t{%2, %0|%0, %2}"
20212 [(set_attr "type" "mmxadd")
20213 (set_attr "mode" "DI")])
20214
20215(define_insn "subv2si3"
20216 [(set (match_operand:V2SI 0 "register_operand" "=y")
20217 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20218 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20219 "TARGET_MMX"
20220 "psubd\t{%2, %0|%0, %2}"
20221 [(set_attr "type" "mmxadd")
20222 (set_attr "mode" "DI")])
20223
20224(define_insn "mmx_subdi3"
20225 [(set (match_operand:DI 0 "register_operand" "=y")
20226 (unspec:DI
20227 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20228 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20229 UNSPEC_NOP))]
20230 "TARGET_MMX"
20231 "psubq\t{%2, %0|%0, %2}"
20232 [(set_attr "type" "mmxadd")
20233 (set_attr "mode" "DI")])
20234
20235(define_insn "sssubv8qi3"
20236 [(set (match_operand:V8QI 0 "register_operand" "=y")
20237 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20238 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20239 "TARGET_MMX"
20240 "psubsb\t{%2, %0|%0, %2}"
20241 [(set_attr "type" "mmxadd")
20242 (set_attr "mode" "DI")])
20243
20244(define_insn "sssubv4hi3"
20245 [(set (match_operand:V4HI 0 "register_operand" "=y")
20246 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20247 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20248 "TARGET_MMX"
20249 "psubsw\t{%2, %0|%0, %2}"
20250 [(set_attr "type" "mmxadd")
20251 (set_attr "mode" "DI")])
20252
20253(define_insn "ussubv8qi3"
20254 [(set (match_operand:V8QI 0 "register_operand" "=y")
20255 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20256 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20257 "TARGET_MMX"
20258 "psubusb\t{%2, %0|%0, %2}"
20259 [(set_attr "type" "mmxadd")
20260 (set_attr "mode" "DI")])
20261
20262(define_insn "ussubv4hi3"
20263 [(set (match_operand:V4HI 0 "register_operand" "=y")
20264 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20265 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20266 "TARGET_MMX"
20267 "psubusw\t{%2, %0|%0, %2}"
20268 [(set_attr "type" "mmxadd")
20269 (set_attr "mode" "DI")])
20270
20271(define_insn "mulv4hi3"
20272 [(set (match_operand:V4HI 0 "register_operand" "=y")
20273 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20274 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20275 "TARGET_MMX"
20276 "pmullw\t{%2, %0|%0, %2}"
20277 [(set_attr "type" "mmxmul")
20278 (set_attr "mode" "DI")])
20279
20280(define_insn "smulv4hi3_highpart"
20281 [(set (match_operand:V4HI 0 "register_operand" "=y")
20282 (truncate:V4HI
20283 (lshiftrt:V4SI
20284 (mult:V4SI (sign_extend:V4SI
20285 (match_operand:V4HI 1 "register_operand" "0"))
20286 (sign_extend:V4SI
20287 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20288 (const_int 16))))]
20289 "TARGET_MMX"
20290 "pmulhw\t{%2, %0|%0, %2}"
20291 [(set_attr "type" "mmxmul")
20292 (set_attr "mode" "DI")])
20293
20294(define_insn "umulv4hi3_highpart"
20295 [(set (match_operand:V4HI 0 "register_operand" "=y")
20296 (truncate:V4HI
20297 (lshiftrt:V4SI
20298 (mult:V4SI (zero_extend:V4SI
20299 (match_operand:V4HI 1 "register_operand" "0"))
20300 (zero_extend:V4SI
20301 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20302 (const_int 16))))]
20303 "TARGET_SSE || TARGET_3DNOW_A"
20304 "pmulhuw\t{%2, %0|%0, %2}"
20305 [(set_attr "type" "mmxmul")
20306 (set_attr "mode" "DI")])
20307
20308(define_insn "mmx_pmaddwd"
20309 [(set (match_operand:V2SI 0 "register_operand" "=y")
20310 (plus:V2SI
20311 (mult:V2SI
20312 (sign_extend:V2SI
20313 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20314 (parallel [(const_int 0) (const_int 2)])))
20315 (sign_extend:V2SI
20316 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20317 (parallel [(const_int 0) (const_int 2)]))))
20318 (mult:V2SI
20319 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20320 (parallel [(const_int 1)
20321 (const_int 3)])))
20322 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20323 (parallel [(const_int 1)
20324 (const_int 3)]))))))]
20325 "TARGET_MMX"
20326 "pmaddwd\t{%2, %0|%0, %2}"
20327 [(set_attr "type" "mmxmul")
20328 (set_attr "mode" "DI")])
20329
20330
20331;; MMX logical operations
20332;; Note we don't want to declare these as regular iordi3 insns to prevent
20333;; normal code that also wants to use the FPU from getting broken.
20334;; The UNSPECs are there to prevent the combiner from getting overly clever.
20335(define_insn "mmx_iordi3"
20336 [(set (match_operand:DI 0 "register_operand" "=y")
20337 (unspec:DI
20338 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20339 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20340 UNSPEC_NOP))]
20341 "TARGET_MMX"
20342 "por\t{%2, %0|%0, %2}"
20343 [(set_attr "type" "mmxadd")
20344 (set_attr "mode" "DI")])
20345
20346(define_insn "mmx_xordi3"
20347 [(set (match_operand:DI 0 "register_operand" "=y")
20348 (unspec:DI
20349 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20350 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20351 UNSPEC_NOP))]
20352 "TARGET_MMX"
20353 "pxor\t{%2, %0|%0, %2}"
20354 [(set_attr "type" "mmxadd")
20355 (set_attr "mode" "DI")
20356 (set_attr "memory" "none")])
20357
20358;; Same as pxor, but don't show input operands so that we don't think
20359;; they are live.
20360(define_insn "mmx_clrdi"
20361 [(set (match_operand:DI 0 "register_operand" "=y")
20362 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20363 "TARGET_MMX"
20364 "pxor\t{%0, %0|%0, %0}"
20365 [(set_attr "type" "mmxadd")
20366 (set_attr "mode" "DI")
20367 (set_attr "memory" "none")])
20368
20369(define_insn "mmx_anddi3"
20370 [(set (match_operand:DI 0 "register_operand" "=y")
20371 (unspec:DI
20372 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20373 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20374 UNSPEC_NOP))]
20375 "TARGET_MMX"
20376 "pand\t{%2, %0|%0, %2}"
20377 [(set_attr "type" "mmxadd")
20378 (set_attr "mode" "DI")])
20379
20380(define_insn "mmx_nanddi3"
20381 [(set (match_operand:DI 0 "register_operand" "=y")
20382 (unspec:DI
20383 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20384 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20385 UNSPEC_NOP))]
20386 "TARGET_MMX"
20387 "pandn\t{%2, %0|%0, %2}"
20388 [(set_attr "type" "mmxadd")
20389 (set_attr "mode" "DI")])
20390
20391
20392;; MMX unsigned averages/sum of absolute differences
20393
20394(define_insn "mmx_uavgv8qi3"
20395 [(set (match_operand:V8QI 0 "register_operand" "=y")
20396 (ashiftrt:V8QI
20397 (plus:V8QI (plus:V8QI
20398 (match_operand:V8QI 1 "register_operand" "0")
20399 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20400 (const_vector:V8QI [(const_int 1)
20401 (const_int 1)
20402 (const_int 1)
20403 (const_int 1)
20404 (const_int 1)
20405 (const_int 1)
20406 (const_int 1)
20407 (const_int 1)]))
20408 (const_int 1)))]
20409 "TARGET_SSE || TARGET_3DNOW_A"
20410 "pavgb\t{%2, %0|%0, %2}"
20411 [(set_attr "type" "mmxshft")
20412 (set_attr "mode" "DI")])
20413
20414(define_insn "mmx_uavgv4hi3"
20415 [(set (match_operand:V4HI 0 "register_operand" "=y")
20416 (ashiftrt:V4HI
20417 (plus:V4HI (plus:V4HI
20418 (match_operand:V4HI 1 "register_operand" "0")
20419 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20420 (const_vector:V4HI [(const_int 1)
20421 (const_int 1)
20422 (const_int 1)
20423 (const_int 1)]))
20424 (const_int 1)))]
20425 "TARGET_SSE || TARGET_3DNOW_A"
20426 "pavgw\t{%2, %0|%0, %2}"
20427 [(set_attr "type" "mmxshft")
20428 (set_attr "mode" "DI")])
20429
20430(define_insn "mmx_psadbw"
20431 [(set (match_operand:DI 0 "register_operand" "=y")
20432 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20433 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20434 UNSPEC_PSADBW))]
20435 "TARGET_SSE || TARGET_3DNOW_A"
20436 "psadbw\t{%2, %0|%0, %2}"
20437 [(set_attr "type" "mmxshft")
20438 (set_attr "mode" "DI")])
20439
20440
20441;; MMX insert/extract/shuffle
20442
20443(define_insn "mmx_pinsrw"
20444 [(set (match_operand:V4HI 0 "register_operand" "=y")
20445 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20446 (vec_duplicate:V4HI
20447 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20448 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20449 "TARGET_SSE || TARGET_3DNOW_A"
20450 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20451 [(set_attr "type" "mmxcvt")
20452 (set_attr "mode" "DI")])
20453
20454(define_insn "mmx_pextrw"
20455 [(set (match_operand:SI 0 "register_operand" "=r")
20456 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20457 (parallel
20458 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20459 "TARGET_SSE || TARGET_3DNOW_A"
20460 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20461 [(set_attr "type" "mmxcvt")
20462 (set_attr "mode" "DI")])
20463
20464(define_insn "mmx_pshufw"
20465 [(set (match_operand:V4HI 0 "register_operand" "=y")
20466 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20467 (match_operand:SI 2 "immediate_operand" "i")]
20468 UNSPEC_SHUFFLE))]
20469 "TARGET_SSE || TARGET_3DNOW_A"
20470 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20471 [(set_attr "type" "mmxcvt")
20472 (set_attr "mode" "DI")])
20473
20474
20475;; MMX mask-generating comparisons
20476
20477(define_insn "eqv8qi3"
20478 [(set (match_operand:V8QI 0 "register_operand" "=y")
20479 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20480 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20481 "TARGET_MMX"
20482 "pcmpeqb\t{%2, %0|%0, %2}"
20483 [(set_attr "type" "mmxcmp")
20484 (set_attr "mode" "DI")])
20485
20486(define_insn "eqv4hi3"
20487 [(set (match_operand:V4HI 0 "register_operand" "=y")
20488 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20489 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20490 "TARGET_MMX"
20491 "pcmpeqw\t{%2, %0|%0, %2}"
20492 [(set_attr "type" "mmxcmp")
20493 (set_attr "mode" "DI")])
20494
20495(define_insn "eqv2si3"
20496 [(set (match_operand:V2SI 0 "register_operand" "=y")
20497 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20498 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20499 "TARGET_MMX"
20500 "pcmpeqd\t{%2, %0|%0, %2}"
20501 [(set_attr "type" "mmxcmp")
20502 (set_attr "mode" "DI")])
20503
20504(define_insn "gtv8qi3"
20505 [(set (match_operand:V8QI 0 "register_operand" "=y")
20506 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20507 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20508 "TARGET_MMX"
20509 "pcmpgtb\t{%2, %0|%0, %2}"
20510 [(set_attr "type" "mmxcmp")
20511 (set_attr "mode" "DI")])
20512
20513(define_insn "gtv4hi3"
20514 [(set (match_operand:V4HI 0 "register_operand" "=y")
20515 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20516 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20517 "TARGET_MMX"
20518 "pcmpgtw\t{%2, %0|%0, %2}"
20519 [(set_attr "type" "mmxcmp")
20520 (set_attr "mode" "DI")])
20521
20522(define_insn "gtv2si3"
20523 [(set (match_operand:V2SI 0 "register_operand" "=y")
20524 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20525 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20526 "TARGET_MMX"
20527 "pcmpgtd\t{%2, %0|%0, %2}"
20528 [(set_attr "type" "mmxcmp")
20529 (set_attr "mode" "DI")])
20530
20531
20532;; MMX max/min insns
20533
20534(define_insn "umaxv8qi3"
20535 [(set (match_operand:V8QI 0 "register_operand" "=y")
20536 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20537 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20538 "TARGET_SSE || TARGET_3DNOW_A"
20539 "pmaxub\t{%2, %0|%0, %2}"
20540 [(set_attr "type" "mmxadd")
20541 (set_attr "mode" "DI")])
20542
20543(define_insn "smaxv4hi3"
20544 [(set (match_operand:V4HI 0 "register_operand" "=y")
20545 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20546 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20547 "TARGET_SSE || TARGET_3DNOW_A"
20548 "pmaxsw\t{%2, %0|%0, %2}"
20549 [(set_attr "type" "mmxadd")
20550 (set_attr "mode" "DI")])
20551
20552(define_insn "uminv8qi3"
20553 [(set (match_operand:V8QI 0 "register_operand" "=y")
20554 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20555 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20556 "TARGET_SSE || TARGET_3DNOW_A"
20557 "pminub\t{%2, %0|%0, %2}"
20558 [(set_attr "type" "mmxadd")
20559 (set_attr "mode" "DI")])
20560
20561(define_insn "sminv4hi3"
20562 [(set (match_operand:V4HI 0 "register_operand" "=y")
20563 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20564 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20565 "TARGET_SSE || TARGET_3DNOW_A"
20566 "pminsw\t{%2, %0|%0, %2}"
20567 [(set_attr "type" "mmxadd")
20568 (set_attr "mode" "DI")])
20569
20570
20571;; MMX shifts
20572
20573(define_insn "ashrv4hi3"
20574 [(set (match_operand:V4HI 0 "register_operand" "=y")
20575 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20576 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20577 "TARGET_MMX"
20578 "psraw\t{%2, %0|%0, %2}"
20579 [(set_attr "type" "mmxshft")
20580 (set_attr "mode" "DI")])
20581
20582(define_insn "ashrv2si3"
20583 [(set (match_operand:V2SI 0 "register_operand" "=y")
20584 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20585 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20586 "TARGET_MMX"
20587 "psrad\t{%2, %0|%0, %2}"
20588 [(set_attr "type" "mmxshft")
20589 (set_attr "mode" "DI")])
20590
20591(define_insn "lshrv4hi3"
20592 [(set (match_operand:V4HI 0 "register_operand" "=y")
20593 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20594 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20595 "TARGET_MMX"
20596 "psrlw\t{%2, %0|%0, %2}"
20597 [(set_attr "type" "mmxshft")
20598 (set_attr "mode" "DI")])
20599
20600(define_insn "lshrv2si3"
20601 [(set (match_operand:V2SI 0 "register_operand" "=y")
20602 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20603 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20604 "TARGET_MMX"
20605 "psrld\t{%2, %0|%0, %2}"
20606 [(set_attr "type" "mmxshft")
20607 (set_attr "mode" "DI")])
20608
20609;; See logical MMX insns.
20610(define_insn "mmx_lshrdi3"
20611 [(set (match_operand:DI 0 "register_operand" "=y")
20612 (unspec:DI
20613 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20614 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20615 UNSPEC_NOP))]
20616 "TARGET_MMX"
20617 "psrlq\t{%2, %0|%0, %2}"
20618 [(set_attr "type" "mmxshft")
20619 (set_attr "mode" "DI")])
20620
20621(define_insn "ashlv4hi3"
20622 [(set (match_operand:V4HI 0 "register_operand" "=y")
20623 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20624 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20625 "TARGET_MMX"
20626 "psllw\t{%2, %0|%0, %2}"
20627 [(set_attr "type" "mmxshft")
20628 (set_attr "mode" "DI")])
20629
20630(define_insn "ashlv2si3"
20631 [(set (match_operand:V2SI 0 "register_operand" "=y")
20632 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20633 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20634 "TARGET_MMX"
20635 "pslld\t{%2, %0|%0, %2}"
20636 [(set_attr "type" "mmxshft")
20637 (set_attr "mode" "DI")])
20638
20639;; See logical MMX insns.
20640(define_insn "mmx_ashldi3"
20641 [(set (match_operand:DI 0 "register_operand" "=y")
20642 (unspec:DI
20643 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20644 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20645 UNSPEC_NOP))]
20646 "TARGET_MMX"
20647 "psllq\t{%2, %0|%0, %2}"
20648 [(set_attr "type" "mmxshft")
20649 (set_attr "mode" "DI")])
20650
20651
20652;; MMX pack/unpack insns.
20653
20654(define_insn "mmx_packsswb"
20655 [(set (match_operand:V8QI 0 "register_operand" "=y")
20656 (vec_concat:V8QI
20657 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20658 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20659 "TARGET_MMX"
20660 "packsswb\t{%2, %0|%0, %2}"
20661 [(set_attr "type" "mmxshft")
20662 (set_attr "mode" "DI")])
20663
20664(define_insn "mmx_packssdw"
20665 [(set (match_operand:V4HI 0 "register_operand" "=y")
20666 (vec_concat:V4HI
20667 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20668 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20669 "TARGET_MMX"
20670 "packssdw\t{%2, %0|%0, %2}"
20671 [(set_attr "type" "mmxshft")
20672 (set_attr "mode" "DI")])
20673
20674(define_insn "mmx_packuswb"
20675 [(set (match_operand:V8QI 0 "register_operand" "=y")
20676 (vec_concat:V8QI
20677 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20678 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20679 "TARGET_MMX"
20680 "packuswb\t{%2, %0|%0, %2}"
20681 [(set_attr "type" "mmxshft")
20682 (set_attr "mode" "DI")])
20683
20684(define_insn "mmx_punpckhbw"
20685 [(set (match_operand:V8QI 0 "register_operand" "=y")
20686 (vec_merge:V8QI
20687 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20688 (parallel [(const_int 4)
20689 (const_int 0)
20690 (const_int 5)
20691 (const_int 1)
20692 (const_int 6)
20693 (const_int 2)
20694 (const_int 7)
20695 (const_int 3)]))
20696 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20697 (parallel [(const_int 0)
20698 (const_int 4)
20699 (const_int 1)
20700 (const_int 5)
20701 (const_int 2)
20702 (const_int 6)
20703 (const_int 3)
20704 (const_int 7)]))
20705 (const_int 85)))]
20706 "TARGET_MMX"
20707 "punpckhbw\t{%2, %0|%0, %2}"
20708 [(set_attr "type" "mmxcvt")
20709 (set_attr "mode" "DI")])
20710
20711(define_insn "mmx_punpckhwd"
20712 [(set (match_operand:V4HI 0 "register_operand" "=y")
20713 (vec_merge:V4HI
20714 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20715 (parallel [(const_int 0)
20716 (const_int 2)
20717 (const_int 1)
20718 (const_int 3)]))
20719 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20720 (parallel [(const_int 2)
20721 (const_int 0)
20722 (const_int 3)
20723 (const_int 1)]))
20724 (const_int 5)))]
20725 "TARGET_MMX"
20726 "punpckhwd\t{%2, %0|%0, %2}"
20727 [(set_attr "type" "mmxcvt")
20728 (set_attr "mode" "DI")])
20729
20730(define_insn "mmx_punpckhdq"
20731 [(set (match_operand:V2SI 0 "register_operand" "=y")
20732 (vec_merge:V2SI
20733 (match_operand:V2SI 1 "register_operand" "0")
20734 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20735 (parallel [(const_int 1)
20736 (const_int 0)]))
20737 (const_int 1)))]
20738 "TARGET_MMX"
20739 "punpckhdq\t{%2, %0|%0, %2}"
20740 [(set_attr "type" "mmxcvt")
20741 (set_attr "mode" "DI")])
20742
20743(define_insn "mmx_punpcklbw"
20744 [(set (match_operand:V8QI 0 "register_operand" "=y")
20745 (vec_merge:V8QI
20746 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20747 (parallel [(const_int 0)
20748 (const_int 4)
20749 (const_int 1)
20750 (const_int 5)
20751 (const_int 2)
20752 (const_int 6)
20753 (const_int 3)
20754 (const_int 7)]))
20755 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20756 (parallel [(const_int 4)
20757 (const_int 0)
20758 (const_int 5)
20759 (const_int 1)
20760 (const_int 6)
20761 (const_int 2)
20762 (const_int 7)
20763 (const_int 3)]))
20764 (const_int 85)))]
20765 "TARGET_MMX"
20766 "punpcklbw\t{%2, %0|%0, %2}"
20767 [(set_attr "type" "mmxcvt")
20768 (set_attr "mode" "DI")])
20769
20770(define_insn "mmx_punpcklwd"
20771 [(set (match_operand:V4HI 0 "register_operand" "=y")
20772 (vec_merge:V4HI
20773 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20774 (parallel [(const_int 2)
20775 (const_int 0)
20776 (const_int 3)
20777 (const_int 1)]))
20778 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20779 (parallel [(const_int 0)
20780 (const_int 2)
20781 (const_int 1)
20782 (const_int 3)]))
20783 (const_int 5)))]
20784 "TARGET_MMX"
20785 "punpcklwd\t{%2, %0|%0, %2}"
20786 [(set_attr "type" "mmxcvt")
20787 (set_attr "mode" "DI")])
20788
20789(define_insn "mmx_punpckldq"
20790 [(set (match_operand:V2SI 0 "register_operand" "=y")
20791 (vec_merge:V2SI
20792 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20793 (parallel [(const_int 1)
20794 (const_int 0)]))
20795 (match_operand:V2SI 2 "register_operand" "y")
20796 (const_int 1)))]
20797 "TARGET_MMX"
20798 "punpckldq\t{%2, %0|%0, %2}"
20799 [(set_attr "type" "mmxcvt")
20800 (set_attr "mode" "DI")])
20801
20802
20803;; Miscellaneous stuff
20804
20805(define_insn "emms"
20806 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20807 (clobber (reg:XF 8))
20808 (clobber (reg:XF 9))
20809 (clobber (reg:XF 10))
20810 (clobber (reg:XF 11))
20811 (clobber (reg:XF 12))
20812 (clobber (reg:XF 13))
20813 (clobber (reg:XF 14))
20814 (clobber (reg:XF 15))
20815 (clobber (reg:DI 29))
20816 (clobber (reg:DI 30))
20817 (clobber (reg:DI 31))
20818 (clobber (reg:DI 32))
20819 (clobber (reg:DI 33))
20820 (clobber (reg:DI 34))
20821 (clobber (reg:DI 35))
20822 (clobber (reg:DI 36))]
20823 "TARGET_MMX"
20824 "emms"
20825 [(set_attr "type" "mmx")
20826 (set_attr "memory" "unknown")])
20827
20828(define_insn "ldmxcsr"
20829 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20830 UNSPECV_LDMXCSR)]
20831 "TARGET_SSE"
20832 "ldmxcsr\t%0"
20833 [(set_attr "type" "sse")
20834 (set_attr "memory" "load")])
20835
20836(define_insn "stmxcsr"
20837 [(set (match_operand:SI 0 "memory_operand" "=m")
20838 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20839 "TARGET_SSE"
20840 "stmxcsr\t%0"
20841 [(set_attr "type" "sse")
20842 (set_attr "memory" "store")])
20843
20844(define_expand "sfence"
20845 [(set (match_dup 0)
20846 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20847 "TARGET_SSE || TARGET_3DNOW_A"
20848{
20849 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20850 MEM_VOLATILE_P (operands[0]) = 1;
20851})
20852
20853(define_insn "*sfence_insn"
20854 [(set (match_operand:BLK 0 "" "")
20855 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20856 "TARGET_SSE || TARGET_3DNOW_A"
20857 "sfence"
20858 [(set_attr "type" "sse")
20859 (set_attr "memory" "unknown")])
20860
20861(define_expand "sse_prologue_save"
20862 [(parallel [(set (match_operand:BLK 0 "" "")
20863 (unspec:BLK [(reg:DI 21)
20864 (reg:DI 22)
20865 (reg:DI 23)
20866 (reg:DI 24)
20867 (reg:DI 25)
20868 (reg:DI 26)
20869 (reg:DI 27)
20870 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20871 (use (match_operand:DI 1 "register_operand" ""))
20872 (use (match_operand:DI 2 "immediate_operand" ""))
20873 (use (label_ref:DI (match_operand 3 "" "")))])]
20874 "TARGET_64BIT"
20875 "")
20876
20877(define_insn "*sse_prologue_save_insn"
20878 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20879 (match_operand:DI 4 "const_int_operand" "n")))
20880 (unspec:BLK [(reg:DI 21)
20881 (reg:DI 22)
20882 (reg:DI 23)
20883 (reg:DI 24)
20884 (reg:DI 25)
20885 (reg:DI 26)
20886 (reg:DI 27)
20887 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20888 (use (match_operand:DI 1 "register_operand" "r"))
20889 (use (match_operand:DI 2 "const_int_operand" "i"))
20890 (use (label_ref:DI (match_operand 3 "" "X")))]
20891 "TARGET_64BIT
20892 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20893 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20894 "*
20895{
20896 int i;
20897 operands[0] = gen_rtx_MEM (Pmode,
20898 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20899 output_asm_insn (\"jmp\\t%A1\", operands);
20900 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20901 {
20902 operands[4] = adjust_address (operands[0], DImode, i*16);
20903 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20904 PUT_MODE (operands[4], TImode);
20905 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20906 output_asm_insn (\"rex\", operands);
20907 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20908 }
20909 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20910 CODE_LABEL_NUMBER (operands[3]));
20911 RET;
20912}
20913 "
20914 [(set_attr "type" "other")
20915 (set_attr "length_immediate" "0")
20916 (set_attr "length_address" "0")
20917 (set_attr "length" "135")
20918 (set_attr "memory" "store")
20919 (set_attr "modrm" "0")
20920 (set_attr "mode" "DI")])
20921
20922;; 3Dnow! instructions
20923
20924(define_insn "addv2sf3"
20925 [(set (match_operand:V2SF 0 "register_operand" "=y")
20926 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20927 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20928 "TARGET_3DNOW"
20929 "pfadd\\t{%2, %0|%0, %2}"
20930 [(set_attr "type" "mmxadd")
20931 (set_attr "mode" "V2SF")])
20932
20933(define_insn "subv2sf3"
20934 [(set (match_operand:V2SF 0 "register_operand" "=y")
20935 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20936 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20937 "TARGET_3DNOW"
20938 "pfsub\\t{%2, %0|%0, %2}"
20939 [(set_attr "type" "mmxadd")
20940 (set_attr "mode" "V2SF")])
20941
20942(define_insn "subrv2sf3"
20943 [(set (match_operand:V2SF 0 "register_operand" "=y")
20944 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20945 (match_operand:V2SF 1 "register_operand" "0")))]
20946 "TARGET_3DNOW"
20947 "pfsubr\\t{%2, %0|%0, %2}"
20948 [(set_attr "type" "mmxadd")
20949 (set_attr "mode" "V2SF")])
20950
20951(define_insn "gtv2sf3"
20952 [(set (match_operand:V2SI 0 "register_operand" "=y")
20953 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20954 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20955 "TARGET_3DNOW"
20956 "pfcmpgt\\t{%2, %0|%0, %2}"
20957 [(set_attr "type" "mmxcmp")
20958 (set_attr "mode" "V2SF")])
20959
20960(define_insn "gev2sf3"
20961 [(set (match_operand:V2SI 0 "register_operand" "=y")
20962 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20963 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20964 "TARGET_3DNOW"
20965 "pfcmpge\\t{%2, %0|%0, %2}"
20966 [(set_attr "type" "mmxcmp")
20967 (set_attr "mode" "V2SF")])
20968
20969(define_insn "eqv2sf3"
20970 [(set (match_operand:V2SI 0 "register_operand" "=y")
20971 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20972 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20973 "TARGET_3DNOW"
20974 "pfcmpeq\\t{%2, %0|%0, %2}"
20975 [(set_attr "type" "mmxcmp")
20976 (set_attr "mode" "V2SF")])
20977
20978(define_insn "pfmaxv2sf3"
20979 [(set (match_operand:V2SF 0 "register_operand" "=y")
20980 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20981 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20982 "TARGET_3DNOW"
20983 "pfmax\\t{%2, %0|%0, %2}"
20984 [(set_attr "type" "mmxadd")
20985 (set_attr "mode" "V2SF")])
20986
20987(define_insn "pfminv2sf3"
20988 [(set (match_operand:V2SF 0 "register_operand" "=y")
20989 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20990 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20991 "TARGET_3DNOW"
20992 "pfmin\\t{%2, %0|%0, %2}"
20993 [(set_attr "type" "mmxadd")
20994 (set_attr "mode" "V2SF")])
20995
20996(define_insn "mulv2sf3"
20997 [(set (match_operand:V2SF 0 "register_operand" "=y")
20998 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20999 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21000 "TARGET_3DNOW"
21001 "pfmul\\t{%2, %0|%0, %2}"
21002 [(set_attr "type" "mmxmul")
21003 (set_attr "mode" "V2SF")])
21004
21005(define_insn "femms"
21006 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21007 (clobber (reg:XF 8))
21008 (clobber (reg:XF 9))
21009 (clobber (reg:XF 10))
21010 (clobber (reg:XF 11))
21011 (clobber (reg:XF 12))
21012 (clobber (reg:XF 13))
21013 (clobber (reg:XF 14))
21014 (clobber (reg:XF 15))
21015 (clobber (reg:DI 29))
21016 (clobber (reg:DI 30))
21017 (clobber (reg:DI 31))
21018 (clobber (reg:DI 32))
21019 (clobber (reg:DI 33))
21020 (clobber (reg:DI 34))
21021 (clobber (reg:DI 35))
21022 (clobber (reg:DI 36))]
21023 "TARGET_3DNOW"
21024 "femms"
21025 [(set_attr "type" "mmx")
21026 (set_attr "memory" "none")])
21027
21028(define_insn "pf2id"
21029 [(set (match_operand:V2SI 0 "register_operand" "=y")
21030 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21031 "TARGET_3DNOW"
21032 "pf2id\\t{%1, %0|%0, %1}"
21033 [(set_attr "type" "mmxcvt")
21034 (set_attr "mode" "V2SF")])
21035
21036(define_insn "pf2iw"
21037 [(set (match_operand:V2SI 0 "register_operand" "=y")
21038 (sign_extend:V2SI
21039 (ss_truncate:V2HI
21040 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21041 "TARGET_3DNOW_A"
21042 "pf2iw\\t{%1, %0|%0, %1}"
21043 [(set_attr "type" "mmxcvt")
21044 (set_attr "mode" "V2SF")])
21045
21046(define_insn "pfacc"
21047 [(set (match_operand:V2SF 0 "register_operand" "=y")
21048 (vec_concat:V2SF
21049 (plus:SF
21050 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21051 (parallel [(const_int 0)]))
21052 (vec_select:SF (match_dup 1)
21053 (parallel [(const_int 1)])))
21054 (plus:SF
21055 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21056 (parallel [(const_int 0)]))
21057 (vec_select:SF (match_dup 2)
21058 (parallel [(const_int 1)])))))]
21059 "TARGET_3DNOW"
21060 "pfacc\\t{%2, %0|%0, %2}"
21061 [(set_attr "type" "mmxadd")
21062 (set_attr "mode" "V2SF")])
21063
21064(define_insn "pfnacc"
21065 [(set (match_operand:V2SF 0 "register_operand" "=y")
21066 (vec_concat:V2SF
21067 (minus:SF
21068 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21069 (parallel [(const_int 0)]))
21070 (vec_select:SF (match_dup 1)
21071 (parallel [(const_int 1)])))
21072 (minus:SF
21073 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21074 (parallel [(const_int 0)]))
21075 (vec_select:SF (match_dup 2)
21076 (parallel [(const_int 1)])))))]
21077 "TARGET_3DNOW_A"
21078 "pfnacc\\t{%2, %0|%0, %2}"
21079 [(set_attr "type" "mmxadd")
21080 (set_attr "mode" "V2SF")])
21081
21082(define_insn "pfpnacc"
21083 [(set (match_operand:V2SF 0 "register_operand" "=y")
21084 (vec_concat:V2SF
21085 (minus:SF
21086 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21087 (parallel [(const_int 0)]))
21088 (vec_select:SF (match_dup 1)
21089 (parallel [(const_int 1)])))
21090 (plus:SF
21091 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21092 (parallel [(const_int 0)]))
21093 (vec_select:SF (match_dup 2)
21094 (parallel [(const_int 1)])))))]
21095 "TARGET_3DNOW_A"
21096 "pfpnacc\\t{%2, %0|%0, %2}"
21097 [(set_attr "type" "mmxadd")
21098 (set_attr "mode" "V2SF")])
21099
21100(define_insn "pi2fw"
21101 [(set (match_operand:V2SF 0 "register_operand" "=y")
21102 (float:V2SF
21103 (vec_concat:V2SI
21104 (sign_extend:SI
21105 (truncate:HI
21106 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21107 (parallel [(const_int 0)]))))
21108 (sign_extend:SI
21109 (truncate:HI
21110 (vec_select:SI (match_dup 1)
21111 (parallel [(const_int 1)])))))))]
21112 "TARGET_3DNOW_A"
21113 "pi2fw\\t{%1, %0|%0, %1}"
21114 [(set_attr "type" "mmxcvt")
21115 (set_attr "mode" "V2SF")])
21116
21117(define_insn "floatv2si2"
21118 [(set (match_operand:V2SF 0 "register_operand" "=y")
21119 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21120 "TARGET_3DNOW"
21121 "pi2fd\\t{%1, %0|%0, %1}"
21122 [(set_attr "type" "mmxcvt")
21123 (set_attr "mode" "V2SF")])
21124
21125;; This insn is identical to pavgb in operation, but the opcode is
21126;; different. To avoid accidentally matching pavgb, use an unspec.
21127
21128(define_insn "pavgusb"
21129 [(set (match_operand:V8QI 0 "register_operand" "=y")
21130 (unspec:V8QI
21131 [(match_operand:V8QI 1 "register_operand" "0")
21132 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21133 UNSPEC_PAVGUSB))]
21134 "TARGET_3DNOW"
21135 "pavgusb\\t{%2, %0|%0, %2}"
21136 [(set_attr "type" "mmxshft")
21137 (set_attr "mode" "TI")])
21138
21139;; 3DNow reciprocal and sqrt
21140
21141(define_insn "pfrcpv2sf2"
21142 [(set (match_operand:V2SF 0 "register_operand" "=y")
21143 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21144 UNSPEC_PFRCP))]
21145 "TARGET_3DNOW"
21146 "pfrcp\\t{%1, %0|%0, %1}"
21147 [(set_attr "type" "mmx")
21148 (set_attr "mode" "TI")])
21149
21150(define_insn "pfrcpit1v2sf3"
21151 [(set (match_operand:V2SF 0 "register_operand" "=y")
21152 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21153 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21154 UNSPEC_PFRCPIT1))]
21155 "TARGET_3DNOW"
21156 "pfrcpit1\\t{%2, %0|%0, %2}"
21157 [(set_attr "type" "mmx")
21158 (set_attr "mode" "TI")])
21159
21160(define_insn "pfrcpit2v2sf3"
21161 [(set (match_operand:V2SF 0 "register_operand" "=y")
21162 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21163 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21164 UNSPEC_PFRCPIT2))]
21165 "TARGET_3DNOW"
21166 "pfrcpit2\\t{%2, %0|%0, %2}"
21167 [(set_attr "type" "mmx")
21168 (set_attr "mode" "TI")])
21169
21170(define_insn "pfrsqrtv2sf2"
21171 [(set (match_operand:V2SF 0 "register_operand" "=y")
21172 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21173 UNSPEC_PFRSQRT))]
21174 "TARGET_3DNOW"
21175 "pfrsqrt\\t{%1, %0|%0, %1}"
21176 [(set_attr "type" "mmx")
21177 (set_attr "mode" "TI")])
21178
21179(define_insn "pfrsqit1v2sf3"
21180 [(set (match_operand:V2SF 0 "register_operand" "=y")
21181 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21182 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21183 UNSPEC_PFRSQIT1))]
21184 "TARGET_3DNOW"
21185 "pfrsqit1\\t{%2, %0|%0, %2}"
21186 [(set_attr "type" "mmx")
21187 (set_attr "mode" "TI")])
21188
21189(define_insn "pmulhrwv4hi3"
21190 [(set (match_operand:V4HI 0 "register_operand" "=y")
21191 (truncate:V4HI
21192 (lshiftrt:V4SI
21193 (plus:V4SI
21194 (mult:V4SI
21195 (sign_extend:V4SI
21196 (match_operand:V4HI 1 "register_operand" "0"))
21197 (sign_extend:V4SI
21198 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21199 (const_vector:V4SI [(const_int 32768)
21200 (const_int 32768)
21201 (const_int 32768)
21202 (const_int 32768)]))
21203 (const_int 16))))]
21204 "TARGET_3DNOW"
21205 "pmulhrw\\t{%2, %0|%0, %2}"
21206 [(set_attr "type" "mmxmul")
21207 (set_attr "mode" "TI")])
21208
21209(define_insn "pswapdv2si2"
21210 [(set (match_operand:V2SI 0 "register_operand" "=y")
21211 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21212 (parallel [(const_int 1) (const_int 0)])))]
21213 "TARGET_3DNOW_A"
21214 "pswapd\\t{%1, %0|%0, %1}"
21215 [(set_attr "type" "mmxcvt")
21216 (set_attr "mode" "TI")])
21217
21218(define_insn "pswapdv2sf2"
21219 [(set (match_operand:V2SF 0 "register_operand" "=y")
21220 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21221 (parallel [(const_int 1) (const_int 0)])))]
21222 "TARGET_3DNOW_A"
21223 "pswapd\\t{%1, %0|%0, %1}"
21224 [(set_attr "type" "mmxcvt")
21225 (set_attr "mode" "TI")])
21226
21227(define_expand "prefetch"
21228 [(prefetch (match_operand 0 "address_operand" "")
21229 (match_operand:SI 1 "const_int_operand" "")
21230 (match_operand:SI 2 "const_int_operand" ""))]
21231 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21232{
21233 int rw = INTVAL (operands[1]);
21234 int locality = INTVAL (operands[2]);
21235
21236 if (rw != 0 && rw != 1)
21237 abort ();
21238 if (locality < 0 || locality > 3)
21239 abort ();
21240 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21241 abort ();
21242
21243 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21244 suported by SSE counterpart or the SSE prefetch is not available
21245 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21246 of locality. */
21247 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21248 operands[2] = GEN_INT (3);
21249 else
21250 operands[1] = const0_rtx;
21251})
21252
21253(define_insn "*prefetch_sse"
21254 [(prefetch (match_operand:SI 0 "address_operand" "p")
21255 (const_int 0)
21256 (match_operand:SI 1 "const_int_operand" ""))]
21257 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21258{
21259 static const char * const patterns[4] = {
21260 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21261 };
21262
21263 int locality = INTVAL (operands[1]);
21264 if (locality < 0 || locality > 3)
21265 abort ();
21266
21267 return patterns[locality];
21268}
21269 [(set_attr "type" "sse")
21270 (set_attr "memory" "none")])
21271
21272(define_insn "*prefetch_sse_rex"
21273 [(prefetch (match_operand:DI 0 "address_operand" "p")
21274 (const_int 0)
21275 (match_operand:SI 1 "const_int_operand" ""))]
21276 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21277{
21278 static const char * const patterns[4] = {
21279 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21280 };
21281
21282 int locality = INTVAL (operands[1]);
21283 if (locality < 0 || locality > 3)
21284 abort ();
21285
21286 return patterns[locality];
21287}
21288 [(set_attr "type" "sse")
21289 (set_attr "memory" "none")])
21290
21291(define_insn "*prefetch_3dnow"
21292 [(prefetch (match_operand:SI 0 "address_operand" "p")
21293 (match_operand:SI 1 "const_int_operand" "n")
21294 (const_int 3))]
21295 "TARGET_3DNOW && !TARGET_64BIT"
21296{
21297 if (INTVAL (operands[1]) == 0)
21298 return "prefetch\t%a0";
21299 else
21300 return "prefetchw\t%a0";
21301}
21302 [(set_attr "type" "mmx")
21303 (set_attr "memory" "none")])
21304
21305(define_insn "*prefetch_3dnow_rex"
21306 [(prefetch (match_operand:DI 0 "address_operand" "p")
21307 (match_operand:SI 1 "const_int_operand" "n")
21308 (const_int 3))]
21309 "TARGET_3DNOW && TARGET_64BIT"
21310{
21311 if (INTVAL (operands[1]) == 0)
21312 return "prefetch\t%a0";
21313 else
21314 return "prefetchw\t%a0";
21315}
21316 [(set_attr "type" "mmx")
21317 (set_attr "memory" "none")])
21318
21319;; SSE2 support
21320
21321(define_insn "addv2df3"
21322 [(set (match_operand:V2DF 0 "register_operand" "=x")
21323 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21324 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21325 "TARGET_SSE2"
21326 "addpd\t{%2, %0|%0, %2}"
21327 [(set_attr "type" "sseadd")
21328 (set_attr "mode" "V2DF")])
21329
21330(define_insn "vmaddv2df3"
21331 [(set (match_operand:V2DF 0 "register_operand" "=x")
21332 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21333 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21334 (match_dup 1)
21335 (const_int 1)))]
21336 "TARGET_SSE2"
21337 "addsd\t{%2, %0|%0, %2}"
21338 [(set_attr "type" "sseadd")
21339 (set_attr "mode" "DF")])
21340
21341(define_insn "subv2df3"
21342 [(set (match_operand:V2DF 0 "register_operand" "=x")
21343 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21344 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21345 "TARGET_SSE2"
21346 "subpd\t{%2, %0|%0, %2}"
21347 [(set_attr "type" "sseadd")
21348 (set_attr "mode" "V2DF")])
21349
21350(define_insn "vmsubv2df3"
21351 [(set (match_operand:V2DF 0 "register_operand" "=x")
21352 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21353 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21354 (match_dup 1)
21355 (const_int 1)))]
21356 "TARGET_SSE2"
21357 "subsd\t{%2, %0|%0, %2}"
21358 [(set_attr "type" "sseadd")
21359 (set_attr "mode" "DF")])
21360
21361(define_insn "mulv2df3"
21362 [(set (match_operand:V2DF 0 "register_operand" "=x")
21363 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21364 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21365 "TARGET_SSE2"
21366 "mulpd\t{%2, %0|%0, %2}"
21367 [(set_attr "type" "ssemul")
21368 (set_attr "mode" "V2DF")])
21369
21370(define_insn "vmmulv2df3"
21371 [(set (match_operand:V2DF 0 "register_operand" "=x")
21372 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21373 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21374 (match_dup 1)
21375 (const_int 1)))]
21376 "TARGET_SSE2"
21377 "mulsd\t{%2, %0|%0, %2}"
21378 [(set_attr "type" "ssemul")
21379 (set_attr "mode" "DF")])
21380
21381(define_insn "divv2df3"
21382 [(set (match_operand:V2DF 0 "register_operand" "=x")
21383 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21384 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21385 "TARGET_SSE2"
21386 "divpd\t{%2, %0|%0, %2}"
21387 [(set_attr "type" "ssediv")
21388 (set_attr "mode" "V2DF")])
21389
21390(define_insn "vmdivv2df3"
21391 [(set (match_operand:V2DF 0 "register_operand" "=x")
21392 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21393 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21394 (match_dup 1)
21395 (const_int 1)))]
21396 "TARGET_SSE2"
21397 "divsd\t{%2, %0|%0, %2}"
21398 [(set_attr "type" "ssediv")
21399 (set_attr "mode" "DF")])
21400
21401;; SSE min/max
21402
21403(define_insn "smaxv2df3"
21404 [(set (match_operand:V2DF 0 "register_operand" "=x")
21405 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21406 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21407 "TARGET_SSE2"
21408 "maxpd\t{%2, %0|%0, %2}"
21409 [(set_attr "type" "sseadd")
21410 (set_attr "mode" "V2DF")])
21411
21412(define_insn "vmsmaxv2df3"
21413 [(set (match_operand:V2DF 0 "register_operand" "=x")
21414 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21415 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21416 (match_dup 1)
21417 (const_int 1)))]
21418 "TARGET_SSE2"
21419 "maxsd\t{%2, %0|%0, %2}"
21420 [(set_attr "type" "sseadd")
21421 (set_attr "mode" "DF")])
21422
21423(define_insn "sminv2df3"
21424 [(set (match_operand:V2DF 0 "register_operand" "=x")
21425 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21426 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21427 "TARGET_SSE2"
21428 "minpd\t{%2, %0|%0, %2}"
21429 [(set_attr "type" "sseadd")
21430 (set_attr "mode" "V2DF")])
21431
21432(define_insn "vmsminv2df3"
21433 [(set (match_operand:V2DF 0 "register_operand" "=x")
21434 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21435 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21436 (match_dup 1)
21437 (const_int 1)))]
21438 "TARGET_SSE2"
21439 "minsd\t{%2, %0|%0, %2}"
21440 [(set_attr "type" "sseadd")
21441 (set_attr "mode" "DF")])
21442;; SSE2 square root. There doesn't appear to be an extension for the
21443;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21444
21445(define_insn "sqrtv2df2"
21446 [(set (match_operand:V2DF 0 "register_operand" "=x")
21447 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21448 "TARGET_SSE2"
21449 "sqrtpd\t{%1, %0|%0, %1}"
21450 [(set_attr "type" "sse")
21451 (set_attr "mode" "V2DF")])
21452
21453(define_insn "vmsqrtv2df2"
21454 [(set (match_operand:V2DF 0 "register_operand" "=x")
21455 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21456 (match_operand:V2DF 2 "register_operand" "0")
21457 (const_int 1)))]
21458 "TARGET_SSE2"
21459 "sqrtsd\t{%1, %0|%0, %1}"
21460 [(set_attr "type" "sse")
21461 (set_attr "mode" "SF")])
21462
21463;; SSE mask-generating compares
21464
21465(define_insn "maskcmpv2df3"
21466 [(set (match_operand:V2DI 0 "register_operand" "=x")
21467 (match_operator:V2DI 3 "sse_comparison_operator"
21468 [(match_operand:V2DF 1 "register_operand" "0")
21469 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21470 "TARGET_SSE2"
21471 "cmp%D3pd\t{%2, %0|%0, %2}"
21472 [(set_attr "type" "ssecmp")
21473 (set_attr "mode" "V2DF")])
21474
21475(define_insn "maskncmpv2df3"
21476 [(set (match_operand:V2DI 0 "register_operand" "=x")
21477 (not:V2DI
21478 (match_operator:V2DI 3 "sse_comparison_operator"
21479 [(match_operand:V2DF 1 "register_operand" "0")
21480 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21481 "TARGET_SSE2"
21482{
21483 if (GET_CODE (operands[3]) == UNORDERED)
21484 return "cmpordps\t{%2, %0|%0, %2}";
21485 else
21486 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21487}
21488 [(set_attr "type" "ssecmp")
21489 (set_attr "mode" "V2DF")])
21490
21491(define_insn "vmmaskcmpv2df3"
21492 [(set (match_operand:V2DI 0 "register_operand" "=x")
21493 (vec_merge:V2DI
21494 (match_operator:V2DI 3 "sse_comparison_operator"
21495 [(match_operand:V2DF 1 "register_operand" "0")
21496 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21497 (subreg:V2DI (match_dup 1) 0)
21498 (const_int 1)))]
21499 "TARGET_SSE2"
21500 "cmp%D3sd\t{%2, %0|%0, %2}"
21501 [(set_attr "type" "ssecmp")
21502 (set_attr "mode" "DF")])
21503
21504(define_insn "vmmaskncmpv2df3"
21505 [(set (match_operand:V2DI 0 "register_operand" "=x")
21506 (vec_merge:V2DI
21507 (not:V2DI
21508 (match_operator:V2DI 3 "sse_comparison_operator"
21509 [(match_operand:V2DF 1 "register_operand" "0")
21510 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21511 (subreg:V2DI (match_dup 1) 0)
21512 (const_int 1)))]
21513 "TARGET_SSE2"
21514{
21515 if (GET_CODE (operands[3]) == UNORDERED)
21516 return "cmpordsd\t{%2, %0|%0, %2}";
21517 else
21518 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21519}
21520 [(set_attr "type" "ssecmp")
21521 (set_attr "mode" "DF")])
21522
21523(define_insn "sse2_comi"
21524 [(set (reg:CCFP 17)
21525 (compare:CCFP (vec_select:DF
21526 (match_operand:V2DF 0 "register_operand" "x")
21527 (parallel [(const_int 0)]))
21528 (vec_select:DF
21529 (match_operand:V2DF 1 "register_operand" "x")
21530 (parallel [(const_int 0)]))))]
21531 "TARGET_SSE2"
21532 "comisd\t{%1, %0|%0, %1}"
21533 [(set_attr "type" "ssecomi")
21534 (set_attr "mode" "DF")])
21535
21536(define_insn "sse2_ucomi"
21537 [(set (reg:CCFPU 17)
21538 (compare:CCFPU (vec_select:DF
21539 (match_operand:V2DF 0 "register_operand" "x")
21540 (parallel [(const_int 0)]))
21541 (vec_select:DF
21542 (match_operand:V2DF 1 "register_operand" "x")
21543 (parallel [(const_int 0)]))))]
21544 "TARGET_SSE2"
21545 "ucomisd\t{%1, %0|%0, %1}"
21546 [(set_attr "type" "ssecomi")
21547 (set_attr "mode" "DF")])
21548
21549;; SSE Strange Moves.
21550
21551(define_insn "sse2_movmskpd"
21552 [(set (match_operand:SI 0 "register_operand" "=r")
21553 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21554 UNSPEC_MOVMSK))]
21555 "TARGET_SSE2"
21556 "movmskpd\t{%1, %0|%0, %1}"
21557 [(set_attr "type" "ssecvt")
21558 (set_attr "mode" "V2DF")])
21559
21560(define_insn "sse2_pmovmskb"
21561 [(set (match_operand:SI 0 "register_operand" "=r")
21562 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21563 UNSPEC_MOVMSK))]
21564 "TARGET_SSE2"
21565 "pmovmskb\t{%1, %0|%0, %1}"
21566 [(set_attr "type" "ssecvt")
21567 (set_attr "mode" "V2DF")])
21568
21569(define_insn "sse2_maskmovdqu"
21570 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21571 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21572 (match_operand:V16QI 2 "register_operand" "x")]
21573 UNSPEC_MASKMOV))]
21574 "TARGET_SSE2"
21575 ;; @@@ check ordering of operands in intel/nonintel syntax
21576 "maskmovdqu\t{%2, %1|%1, %2}"
21577 [(set_attr "type" "ssecvt")
21578 (set_attr "mode" "TI")])
21579
21580(define_insn "sse2_maskmovdqu_rex64"
21581 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21582 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21583 (match_operand:V16QI 2 "register_operand" "x")]
21584 UNSPEC_MASKMOV))]
21585 "TARGET_SSE2"
21586 ;; @@@ check ordering of operands in intel/nonintel syntax
21587 "maskmovdqu\t{%2, %1|%1, %2}"
21588 [(set_attr "type" "ssecvt")
21589 (set_attr "mode" "TI")])
21590
21591(define_insn "sse2_movntv2df"
21592 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21593 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21594 UNSPEC_MOVNT))]
21595 "TARGET_SSE2"
21596 "movntpd\t{%1, %0|%0, %1}"
21597 [(set_attr "type" "ssecvt")
21598 (set_attr "mode" "V2DF")])
21599
21600(define_insn "sse2_movntv2di"
21601 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21602 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21603 UNSPEC_MOVNT))]
21604 "TARGET_SSE2"
21605 "movntdq\t{%1, %0|%0, %1}"
21606 [(set_attr "type" "ssecvt")
21607 (set_attr "mode" "TI")])
21608
21609(define_insn "sse2_movntsi"
21610 [(set (match_operand:SI 0 "memory_operand" "=m")
21611 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21612 UNSPEC_MOVNT))]
21613 "TARGET_SSE2"
21614 "movnti\t{%1, %0|%0, %1}"
21615 [(set_attr "type" "ssecvt")
21616 (set_attr "mode" "V2DF")])
21617
21618;; SSE <-> integer/MMX conversions
21619
21620;; Conversions between SI and SF
21621
21622(define_insn "cvtdq2ps"
21623 [(set (match_operand:V4SF 0 "register_operand" "=x")
21624 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21625 "TARGET_SSE2"
21626 "cvtdq2ps\t{%1, %0|%0, %1}"
21627 [(set_attr "type" "ssecvt")
21628 (set_attr "mode" "V2DF")])
21629
21630(define_insn "cvtps2dq"
21631 [(set (match_operand:V4SI 0 "register_operand" "=x")
21632 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21633 "TARGET_SSE2"
21634 "cvtps2dq\t{%1, %0|%0, %1}"
21635 [(set_attr "type" "ssecvt")
21636 (set_attr "mode" "TI")])
21637
21638(define_insn "cvttps2dq"
21639 [(set (match_operand:V4SI 0 "register_operand" "=x")
21640 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21641 UNSPEC_FIX))]
21642 "TARGET_SSE2"
21643 "cvttps2dq\t{%1, %0|%0, %1}"
21644 [(set_attr "type" "ssecvt")
21645 (set_attr "mode" "TI")])
21646
21647;; Conversions between SI and DF
21648
21649(define_insn "cvtdq2pd"
21650 [(set (match_operand:V2DF 0 "register_operand" "=x")
21651 (float:V2DF (vec_select:V2SI
21652 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21653 (parallel
21654 [(const_int 0)
21655 (const_int 1)]))))]
21656 "TARGET_SSE2"
21657 "cvtdq2pd\t{%1, %0|%0, %1}"
21658 [(set_attr "type" "ssecvt")
21659 (set_attr "mode" "V2DF")])
21660
21661(define_insn "cvtpd2dq"
21662 [(set (match_operand:V4SI 0 "register_operand" "=x")
21663 (vec_concat:V4SI
21664 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21665 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21666 "TARGET_SSE2"
21667 "cvtpd2dq\t{%1, %0|%0, %1}"
21668 [(set_attr "type" "ssecvt")
21669 (set_attr "mode" "TI")])
21670
21671(define_insn "cvttpd2dq"
21672 [(set (match_operand:V4SI 0 "register_operand" "=x")
21673 (vec_concat:V4SI
21674 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21675 UNSPEC_FIX)
21676 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21677 "TARGET_SSE2"
21678 "cvttpd2dq\t{%1, %0|%0, %1}"
21679 [(set_attr "type" "ssecvt")
21680 (set_attr "mode" "TI")])
21681
21682(define_insn "cvtpd2pi"
21683 [(set (match_operand:V2SI 0 "register_operand" "=y")
21684 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21685 "TARGET_SSE2"
21686 "cvtpd2pi\t{%1, %0|%0, %1}"
21687 [(set_attr "type" "ssecvt")
21688 (set_attr "mode" "TI")])
21689
21690(define_insn "cvttpd2pi"
21691 [(set (match_operand:V2SI 0 "register_operand" "=y")
21692 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21693 UNSPEC_FIX))]
21694 "TARGET_SSE2"
21695 "cvttpd2pi\t{%1, %0|%0, %1}"
21696 [(set_attr "type" "ssecvt")
21697 (set_attr "mode" "TI")])
21698
21699(define_insn "cvtpi2pd"
21700 [(set (match_operand:V2DF 0 "register_operand" "=x")
21701 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21702 "TARGET_SSE2"
21703 "cvtpi2pd\t{%1, %0|%0, %1}"
21704 [(set_attr "type" "ssecvt")
21705 (set_attr "mode" "TI")])
21706
21707;; Conversions between SI and DF
21708
21709(define_insn "cvtsd2si"
21710 [(set (match_operand:SI 0 "register_operand" "=r,r")
21711 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21712 (parallel [(const_int 0)]))))]
21713 "TARGET_SSE2"
21714 "cvtsd2si\t{%1, %0|%0, %1}"
21715 [(set_attr "type" "sseicvt")
21716 (set_attr "athlon_decode" "double,vector")
21717 (set_attr "mode" "SI")])
21718
21719(define_insn "cvtsd2siq"
21720 [(set (match_operand:DI 0 "register_operand" "=r,r")
21721 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21722 (parallel [(const_int 0)]))))]
21723 "TARGET_SSE2 && TARGET_64BIT"
21724 "cvtsd2siq\t{%1, %0|%0, %1}"
21725 [(set_attr "type" "sseicvt")
21726 (set_attr "athlon_decode" "double,vector")
21727 (set_attr "mode" "DI")])
21728
21729(define_insn "cvttsd2si"
21730 [(set (match_operand:SI 0 "register_operand" "=r,r")
21731 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21732 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21733 "TARGET_SSE2"
21734 "cvttsd2si\t{%1, %0|%0, %1}"
21735 [(set_attr "type" "sseicvt")
21736 (set_attr "mode" "SI")
21737 (set_attr "athlon_decode" "double,vector")])
21738
21739(define_insn "cvttsd2siq"
21740 [(set (match_operand:DI 0 "register_operand" "=r,r")
21741 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21742 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21743 "TARGET_SSE2 && TARGET_64BIT"
21744 "cvttsd2siq\t{%1, %0|%0, %1}"
21745 [(set_attr "type" "sseicvt")
21746 (set_attr "mode" "DI")
21747 (set_attr "athlon_decode" "double,vector")])
21748
21749(define_insn "cvtsi2sd"
21750 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21751 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21752 (vec_duplicate:V2DF
21753 (float:DF
21754 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21755 (const_int 2)))]
21756 "TARGET_SSE2"
21757 "cvtsi2sd\t{%2, %0|%0, %2}"
21758 [(set_attr "type" "sseicvt")
21759 (set_attr "mode" "DF")
21760 (set_attr "athlon_decode" "double,direct")])
21761
21762(define_insn "cvtsi2sdq"
21763 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21764 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21765 (vec_duplicate:V2DF
21766 (float:DF
21767 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21768 (const_int 2)))]
21769 "TARGET_SSE2 && TARGET_64BIT"
21770 "cvtsi2sdq\t{%2, %0|%0, %2}"
21771 [(set_attr "type" "sseicvt")
21772 (set_attr "mode" "DF")
21773 (set_attr "athlon_decode" "double,direct")])
21774
21775;; Conversions between SF and DF
21776
21777(define_insn "cvtsd2ss"
21778 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21779 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21780 (vec_duplicate:V4SF
21781 (float_truncate:V2SF
21782 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21783 (const_int 14)))]
21784 "TARGET_SSE2"
21785 "cvtsd2ss\t{%2, %0|%0, %2}"
21786 [(set_attr "type" "ssecvt")
21787 (set_attr "athlon_decode" "vector,double")
21788 (set_attr "mode" "SF")])
21789
21790(define_insn "cvtss2sd"
21791 [(set (match_operand:V2DF 0 "register_operand" "=x")
21792 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21793 (float_extend:V2DF
21794 (vec_select:V2SF
21795 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21796 (parallel [(const_int 0)
21797 (const_int 1)])))
21798 (const_int 2)))]
21799 "TARGET_SSE2"
21800 "cvtss2sd\t{%2, %0|%0, %2}"
21801 [(set_attr "type" "ssecvt")
21802 (set_attr "mode" "DF")])
21803
21804(define_insn "cvtpd2ps"
21805 [(set (match_operand:V4SF 0 "register_operand" "=x")
21806 (subreg:V4SF
21807 (vec_concat:V4SI
21808 (subreg:V2SI (float_truncate:V2SF
21809 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21810 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21811 "TARGET_SSE2"
21812 "cvtpd2ps\t{%1, %0|%0, %1}"
21813 [(set_attr "type" "ssecvt")
21814 (set_attr "mode" "V4SF")])
21815
21816(define_insn "cvtps2pd"
21817 [(set (match_operand:V2DF 0 "register_operand" "=x")
21818 (float_extend:V2DF
21819 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21820 (parallel [(const_int 0)
21821 (const_int 1)]))))]
21822 "TARGET_SSE2"
21823 "cvtps2pd\t{%1, %0|%0, %1}"
21824 [(set_attr "type" "ssecvt")
21825 (set_attr "mode" "V2DF")])
21826
21827;; SSE2 variants of MMX insns
21828
21829;; MMX arithmetic
21830
21831(define_insn "addv16qi3"
21832 [(set (match_operand:V16QI 0 "register_operand" "=x")
21833 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21834 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21835 "TARGET_SSE2"
21836 "paddb\t{%2, %0|%0, %2}"
21837 [(set_attr "type" "sseiadd")
21838 (set_attr "mode" "TI")])
21839
21840(define_insn "addv8hi3"
21841 [(set (match_operand:V8HI 0 "register_operand" "=x")
21842 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21843 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21844 "TARGET_SSE2"
21845 "paddw\t{%2, %0|%0, %2}"
21846 [(set_attr "type" "sseiadd")
21847 (set_attr "mode" "TI")])
21848
21849(define_insn "addv4si3"
21850 [(set (match_operand:V4SI 0 "register_operand" "=x")
21851 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21852 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21853 "TARGET_SSE2"
21854 "paddd\t{%2, %0|%0, %2}"
21855 [(set_attr "type" "sseiadd")
21856 (set_attr "mode" "TI")])
21857
21858(define_insn "addv2di3"
21859 [(set (match_operand:V2DI 0 "register_operand" "=x")
21860 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21861 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21862 "TARGET_SSE2"
21863 "paddq\t{%2, %0|%0, %2}"
21864 [(set_attr "type" "sseiadd")
21865 (set_attr "mode" "TI")])
21866
21867(define_insn "ssaddv16qi3"
21868 [(set (match_operand:V16QI 0 "register_operand" "=x")
21869 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21870 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21871 "TARGET_SSE2"
21872 "paddsb\t{%2, %0|%0, %2}"
21873 [(set_attr "type" "sseiadd")
21874 (set_attr "mode" "TI")])
21875
21876(define_insn "ssaddv8hi3"
21877 [(set (match_operand:V8HI 0 "register_operand" "=x")
21878 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21879 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21880 "TARGET_SSE2"
21881 "paddsw\t{%2, %0|%0, %2}"
21882 [(set_attr "type" "sseiadd")
21883 (set_attr "mode" "TI")])
21884
21885(define_insn "usaddv16qi3"
21886 [(set (match_operand:V16QI 0 "register_operand" "=x")
21887 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21888 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21889 "TARGET_SSE2"
21890 "paddusb\t{%2, %0|%0, %2}"
21891 [(set_attr "type" "sseiadd")
21892 (set_attr "mode" "TI")])
21893
21894(define_insn "usaddv8hi3"
21895 [(set (match_operand:V8HI 0 "register_operand" "=x")
21896 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21897 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21898 "TARGET_SSE2"
21899 "paddusw\t{%2, %0|%0, %2}"
21900 [(set_attr "type" "sseiadd")
21901 (set_attr "mode" "TI")])
21902
21903(define_insn "subv16qi3"
21904 [(set (match_operand:V16QI 0 "register_operand" "=x")
21905 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21906 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21907 "TARGET_SSE2"
21908 "psubb\t{%2, %0|%0, %2}"
21909 [(set_attr "type" "sseiadd")
21910 (set_attr "mode" "TI")])
21911
21912(define_insn "subv8hi3"
21913 [(set (match_operand:V8HI 0 "register_operand" "=x")
21914 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21915 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21916 "TARGET_SSE2"
21917 "psubw\t{%2, %0|%0, %2}"
21918 [(set_attr "type" "sseiadd")
21919 (set_attr "mode" "TI")])
21920
21921(define_insn "subv4si3"
21922 [(set (match_operand:V4SI 0 "register_operand" "=x")
21923 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21924 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21925 "TARGET_SSE2"
21926 "psubd\t{%2, %0|%0, %2}"
21927 [(set_attr "type" "sseiadd")
21928 (set_attr "mode" "TI")])
21929
21930(define_insn "subv2di3"
21931 [(set (match_operand:V2DI 0 "register_operand" "=x")
21932 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21933 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21934 "TARGET_SSE2"
21935 "psubq\t{%2, %0|%0, %2}"
21936 [(set_attr "type" "sseiadd")
21937 (set_attr "mode" "TI")])
21938
21939(define_insn "sssubv16qi3"
21940 [(set (match_operand:V16QI 0 "register_operand" "=x")
21941 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21942 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21943 "TARGET_SSE2"
21944 "psubsb\t{%2, %0|%0, %2}"
21945 [(set_attr "type" "sseiadd")
21946 (set_attr "mode" "TI")])
21947
21948(define_insn "sssubv8hi3"
21949 [(set (match_operand:V8HI 0 "register_operand" "=x")
21950 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21951 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21952 "TARGET_SSE2"
21953 "psubsw\t{%2, %0|%0, %2}"
21954 [(set_attr "type" "sseiadd")
21955 (set_attr "mode" "TI")])
21956
21957(define_insn "ussubv16qi3"
21958 [(set (match_operand:V16QI 0 "register_operand" "=x")
21959 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21960 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21961 "TARGET_SSE2"
21962 "psubusb\t{%2, %0|%0, %2}"
21963 [(set_attr "type" "sseiadd")
21964 (set_attr "mode" "TI")])
21965
21966(define_insn "ussubv8hi3"
21967 [(set (match_operand:V8HI 0 "register_operand" "=x")
21968 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21969 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21970 "TARGET_SSE2"
21971 "psubusw\t{%2, %0|%0, %2}"
21972 [(set_attr "type" "sseiadd")
21973 (set_attr "mode" "TI")])
21974
21975(define_insn "mulv8hi3"
21976 [(set (match_operand:V8HI 0 "register_operand" "=x")
21977 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21978 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21979 "TARGET_SSE2"
21980 "pmullw\t{%2, %0|%0, %2}"
21981 [(set_attr "type" "sseimul")
21982 (set_attr "mode" "TI")])
21983
21984(define_insn "smulv8hi3_highpart"
21985 [(set (match_operand:V8HI 0 "register_operand" "=x")
21986 (truncate:V8HI
21987 (lshiftrt:V8SI
21988 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21989 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21990 (const_int 16))))]
21991 "TARGET_SSE2"
21992 "pmulhw\t{%2, %0|%0, %2}"
21993 [(set_attr "type" "sseimul")
21994 (set_attr "mode" "TI")])
21995
21996(define_insn "umulv8hi3_highpart"
21997 [(set (match_operand:V8HI 0 "register_operand" "=x")
21998 (truncate:V8HI
21999 (lshiftrt:V8SI
22000 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22001 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22002 (const_int 16))))]
22003 "TARGET_SSE2"
22004 "pmulhuw\t{%2, %0|%0, %2}"
22005 [(set_attr "type" "sseimul")
22006 (set_attr "mode" "TI")])
22007
22008(define_insn "sse2_umulsidi3"
22009 [(set (match_operand:DI 0 "register_operand" "=y")
22010 (mult:DI (zero_extend:DI (vec_select:SI
22011 (match_operand:V2SI 1 "register_operand" "0")
22012 (parallel [(const_int 0)])))
22013 (zero_extend:DI (vec_select:SI
22014 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22015 (parallel [(const_int 0)])))))]
22016 "TARGET_SSE2"
22017 "pmuludq\t{%2, %0|%0, %2}"
22018 [(set_attr "type" "sseimul")
22019 (set_attr "mode" "TI")])
22020
22021(define_insn "sse2_umulv2siv2di3"
22022 [(set (match_operand:V2DI 0 "register_operand" "=x")
22023 (mult:V2DI (zero_extend:V2DI
22024 (vec_select:V2SI
22025 (match_operand:V4SI 1 "register_operand" "0")
22026 (parallel [(const_int 0) (const_int 2)])))
22027 (zero_extend:V2DI
22028 (vec_select:V2SI
22029 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22030 (parallel [(const_int 0) (const_int 2)])))))]
22031 "TARGET_SSE2"
22032 "pmuludq\t{%2, %0|%0, %2}"
22033 [(set_attr "type" "sseimul")
22034 (set_attr "mode" "TI")])
22035
22036(define_insn "sse2_pmaddwd"
22037 [(set (match_operand:V4SI 0 "register_operand" "=x")
22038 (plus:V4SI
22039 (mult:V4SI
22040 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22041 (parallel [(const_int 0)
22042 (const_int 2)
22043 (const_int 4)
22044 (const_int 6)])))
22045 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22046 (parallel [(const_int 0)
22047 (const_int 2)
22048 (const_int 4)
22049 (const_int 6)]))))
22050 (mult:V4SI
22051 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22052 (parallel [(const_int 1)
22053 (const_int 3)
22054 (const_int 5)
22055 (const_int 7)])))
22056 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22057 (parallel [(const_int 1)
22058 (const_int 3)
22059 (const_int 5)
22060 (const_int 7)]))))))]
22061 "TARGET_SSE2"
22062 "pmaddwd\t{%2, %0|%0, %2}"
22063 [(set_attr "type" "sseiadd")
22064 (set_attr "mode" "TI")])
22065
22066;; Same as pxor, but don't show input operands so that we don't think
22067;; they are live.
22068(define_insn "sse2_clrti"
22069 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22070 "TARGET_SSE2"
22071{
22072 if (get_attr_mode (insn) == MODE_TI)
22073 return "pxor\t%0, %0";
22074 else
22075 return "xorps\t%0, %0";
22076}
22077 [(set_attr "type" "ssemov")
22078 (set_attr "memory" "none")
22079 (set (attr "mode")
22080 (if_then_else
22081 (ne (symbol_ref "optimize_size")
22082 (const_int 0))
22083 (const_string "V4SF")
22084 (const_string "TI")))])
22085
22086;; MMX unsigned averages/sum of absolute differences
22087
22088(define_insn "sse2_uavgv16qi3"
22089 [(set (match_operand:V16QI 0 "register_operand" "=x")
22090 (ashiftrt:V16QI
22091 (plus:V16QI (plus:V16QI
22092 (match_operand:V16QI 1 "register_operand" "0")
22093 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22094 (const_vector:V16QI [(const_int 1) (const_int 1)
22095 (const_int 1) (const_int 1)
22096 (const_int 1) (const_int 1)
22097 (const_int 1) (const_int 1)
22098 (const_int 1) (const_int 1)
22099 (const_int 1) (const_int 1)
22100 (const_int 1) (const_int 1)
22101 (const_int 1) (const_int 1)]))
22102 (const_int 1)))]
22103 "TARGET_SSE2"
22104 "pavgb\t{%2, %0|%0, %2}"
22105 [(set_attr "type" "sseiadd")
22106 (set_attr "mode" "TI")])
22107
22108(define_insn "sse2_uavgv8hi3"
22109 [(set (match_operand:V8HI 0 "register_operand" "=x")
22110 (ashiftrt:V8HI
22111 (plus:V8HI (plus:V8HI
22112 (match_operand:V8HI 1 "register_operand" "0")
22113 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22114 (const_vector:V8HI [(const_int 1) (const_int 1)
22115 (const_int 1) (const_int 1)
22116 (const_int 1) (const_int 1)
22117 (const_int 1) (const_int 1)]))
22118 (const_int 1)))]
22119 "TARGET_SSE2"
22120 "pavgw\t{%2, %0|%0, %2}"
22121 [(set_attr "type" "sseiadd")
22122 (set_attr "mode" "TI")])
22123
22124;; @@@ this isn't the right representation.
22125(define_insn "sse2_psadbw"
22126 [(set (match_operand:V2DI 0 "register_operand" "=x")
22127 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22128 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22129 UNSPEC_PSADBW))]
22130 "TARGET_SSE2"
22131 "psadbw\t{%2, %0|%0, %2}"
22132 [(set_attr "type" "sseiadd")
22133 (set_attr "mode" "TI")])
22134
22135
22136;; MMX insert/extract/shuffle
22137
22138(define_insn "sse2_pinsrw"
22139 [(set (match_operand:V8HI 0 "register_operand" "=x")
22140 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22141 (vec_duplicate:V8HI
22142 (truncate:HI
22143 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22144 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22145 "TARGET_SSE2"
22146 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22147 [(set_attr "type" "ssecvt")
22148 (set_attr "mode" "TI")])
22149
22150(define_insn "sse2_pextrw"
22151 [(set (match_operand:SI 0 "register_operand" "=r")
22152 (zero_extend:SI
22153 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22154 (parallel
22155 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22156 "TARGET_SSE2"
22157 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22158 [(set_attr "type" "ssecvt")
22159 (set_attr "mode" "TI")])
22160
22161(define_insn "sse2_pshufd"
22162 [(set (match_operand:V4SI 0 "register_operand" "=x")
22163 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22164 (match_operand:SI 2 "immediate_operand" "i")]
22165 UNSPEC_SHUFFLE))]
22166 "TARGET_SSE2"
22167 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22168 [(set_attr "type" "ssecvt")
22169 (set_attr "mode" "TI")])
22170
22171(define_insn "sse2_pshuflw"
22172 [(set (match_operand:V8HI 0 "register_operand" "=x")
22173 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22174 (match_operand:SI 2 "immediate_operand" "i")]
22175 UNSPEC_PSHUFLW))]
22176 "TARGET_SSE2"
22177 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22178 [(set_attr "type" "ssecvt")
22179 (set_attr "mode" "TI")])
22180
22181(define_insn "sse2_pshufhw"
22182 [(set (match_operand:V8HI 0 "register_operand" "=x")
22183 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22184 (match_operand:SI 2 "immediate_operand" "i")]
22185 UNSPEC_PSHUFHW))]
22186 "TARGET_SSE2"
22187 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22188 [(set_attr "type" "ssecvt")
22189 (set_attr "mode" "TI")])
22190
22191;; MMX mask-generating comparisons
22192
22193(define_insn "eqv16qi3"
22194 [(set (match_operand:V16QI 0 "register_operand" "=x")
22195 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22196 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22197 "TARGET_SSE2"
22198 "pcmpeqb\t{%2, %0|%0, %2}"
22199 [(set_attr "type" "ssecmp")
22200 (set_attr "mode" "TI")])
22201
22202(define_insn "eqv8hi3"
22203 [(set (match_operand:V8HI 0 "register_operand" "=x")
22204 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22205 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22206 "TARGET_SSE2"
22207 "pcmpeqw\t{%2, %0|%0, %2}"
22208 [(set_attr "type" "ssecmp")
22209 (set_attr "mode" "TI")])
22210
22211(define_insn "eqv4si3"
22212 [(set (match_operand:V4SI 0 "register_operand" "=x")
22213 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22214 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22215 "TARGET_SSE2"
22216 "pcmpeqd\t{%2, %0|%0, %2}"
22217 [(set_attr "type" "ssecmp")
22218 (set_attr "mode" "TI")])
22219
22220(define_insn "gtv16qi3"
22221 [(set (match_operand:V16QI 0 "register_operand" "=x")
22222 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22223 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22224 "TARGET_SSE2"
22225 "pcmpgtb\t{%2, %0|%0, %2}"
22226 [(set_attr "type" "ssecmp")
22227 (set_attr "mode" "TI")])
22228
22229(define_insn "gtv8hi3"
22230 [(set (match_operand:V8HI 0 "register_operand" "=x")
22231 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22232 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22233 "TARGET_SSE2"
22234 "pcmpgtw\t{%2, %0|%0, %2}"
22235 [(set_attr "type" "ssecmp")
22236 (set_attr "mode" "TI")])
22237
22238(define_insn "gtv4si3"
22239 [(set (match_operand:V4SI 0 "register_operand" "=x")
22240 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22241 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22242 "TARGET_SSE2"
22243 "pcmpgtd\t{%2, %0|%0, %2}"
22244 [(set_attr "type" "ssecmp")
22245 (set_attr "mode" "TI")])
22246
22247
22248;; MMX max/min insns
22249
22250(define_insn "umaxv16qi3"
22251 [(set (match_operand:V16QI 0 "register_operand" "=x")
22252 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22253 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22254 "TARGET_SSE2"
22255 "pmaxub\t{%2, %0|%0, %2}"
22256 [(set_attr "type" "sseiadd")
22257 (set_attr "mode" "TI")])
22258
22259(define_insn "smaxv8hi3"
22260 [(set (match_operand:V8HI 0 "register_operand" "=x")
22261 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22262 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22263 "TARGET_SSE2"
22264 "pmaxsw\t{%2, %0|%0, %2}"
22265 [(set_attr "type" "sseiadd")
22266 (set_attr "mode" "TI")])
22267
22268(define_insn "uminv16qi3"
22269 [(set (match_operand:V16QI 0 "register_operand" "=x")
22270 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22271 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22272 "TARGET_SSE2"
22273 "pminub\t{%2, %0|%0, %2}"
22274 [(set_attr "type" "sseiadd")
22275 (set_attr "mode" "TI")])
22276
22277(define_insn "sminv8hi3"
22278 [(set (match_operand:V8HI 0 "register_operand" "=x")
22279 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22280 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22281 "TARGET_SSE2"
22282 "pminsw\t{%2, %0|%0, %2}"
22283 [(set_attr "type" "sseiadd")
22284 (set_attr "mode" "TI")])
22285
22286
22287;; MMX shifts
22288
22289(define_insn "ashrv8hi3"
22290 [(set (match_operand:V8HI 0 "register_operand" "=x")
22291 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22292 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22293 "TARGET_SSE2"
22294 "psraw\t{%2, %0|%0, %2}"
22295 [(set_attr "type" "sseishft")
22296 (set_attr "mode" "TI")])
22297
22298(define_insn "ashrv4si3"
22299 [(set (match_operand:V4SI 0 "register_operand" "=x")
22300 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22301 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22302 "TARGET_SSE2"
22303 "psrad\t{%2, %0|%0, %2}"
22304 [(set_attr "type" "sseishft")
22305 (set_attr "mode" "TI")])
22306
22307(define_insn "lshrv8hi3"
22308 [(set (match_operand:V8HI 0 "register_operand" "=x")
22309 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22310 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22311 "TARGET_SSE2"
22312 "psrlw\t{%2, %0|%0, %2}"
22313 [(set_attr "type" "sseishft")
22314 (set_attr "mode" "TI")])
22315
22316(define_insn "lshrv4si3"
22317 [(set (match_operand:V4SI 0 "register_operand" "=x")
22318 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22319 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22320 "TARGET_SSE2"
22321 "psrld\t{%2, %0|%0, %2}"
22322 [(set_attr "type" "sseishft")
22323 (set_attr "mode" "TI")])
22324
22325(define_insn "lshrv2di3"
22326 [(set (match_operand:V2DI 0 "register_operand" "=x")
22327 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22328 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22329 "TARGET_SSE2"
22330 "psrlq\t{%2, %0|%0, %2}"
22331 [(set_attr "type" "sseishft")
22332 (set_attr "mode" "TI")])
22333
22334(define_insn "ashlv8hi3"
22335 [(set (match_operand:V8HI 0 "register_operand" "=x")
22336 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22337 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22338 "TARGET_SSE2"
22339 "psllw\t{%2, %0|%0, %2}"
22340 [(set_attr "type" "sseishft")
22341 (set_attr "mode" "TI")])
22342
22343(define_insn "ashlv4si3"
22344 [(set (match_operand:V4SI 0 "register_operand" "=x")
22345 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22346 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22347 "TARGET_SSE2"
22348 "pslld\t{%2, %0|%0, %2}"
22349 [(set_attr "type" "sseishft")
22350 (set_attr "mode" "TI")])
22351
22352(define_insn "ashlv2di3"
22353 [(set (match_operand:V2DI 0 "register_operand" "=x")
22354 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22355 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22356 "TARGET_SSE2"
22357 "psllq\t{%2, %0|%0, %2}"
22358 [(set_attr "type" "sseishft")
22359 (set_attr "mode" "TI")])
22360
22361(define_insn "ashrv8hi3_ti"
22362 [(set (match_operand:V8HI 0 "register_operand" "=x")
22363 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22364 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22365 "TARGET_SSE2"
22366 "psraw\t{%2, %0|%0, %2}"
22367 [(set_attr "type" "sseishft")
22368 (set_attr "mode" "TI")])
22369
22370(define_insn "ashrv4si3_ti"
22371 [(set (match_operand:V4SI 0 "register_operand" "=x")
22372 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22373 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22374 "TARGET_SSE2"
22375 "psrad\t{%2, %0|%0, %2}"
22376 [(set_attr "type" "sseishft")
22377 (set_attr "mode" "TI")])
22378
22379(define_insn "lshrv8hi3_ti"
22380 [(set (match_operand:V8HI 0 "register_operand" "=x")
22381 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22382 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22383 "TARGET_SSE2"
22384 "psrlw\t{%2, %0|%0, %2}"
22385 [(set_attr "type" "sseishft")
22386 (set_attr "mode" "TI")])
22387
22388(define_insn "lshrv4si3_ti"
22389 [(set (match_operand:V4SI 0 "register_operand" "=x")
22390 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22391 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22392 "TARGET_SSE2"
22393 "psrld\t{%2, %0|%0, %2}"
22394 [(set_attr "type" "sseishft")
22395 (set_attr "mode" "TI")])
22396
22397(define_insn "lshrv2di3_ti"
22398 [(set (match_operand:V2DI 0 "register_operand" "=x")
22399 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22400 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22401 "TARGET_SSE2"
22402 "psrlq\t{%2, %0|%0, %2}"
22403 [(set_attr "type" "sseishft")
22404 (set_attr "mode" "TI")])
22405
22406(define_insn "ashlv8hi3_ti"
22407 [(set (match_operand:V8HI 0 "register_operand" "=x")
22408 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22409 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22410 "TARGET_SSE2"
22411 "psllw\t{%2, %0|%0, %2}"
22412 [(set_attr "type" "sseishft")
22413 (set_attr "mode" "TI")])
22414
22415(define_insn "ashlv4si3_ti"
22416 [(set (match_operand:V4SI 0 "register_operand" "=x")
22417 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22418 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22419 "TARGET_SSE2"
22420 "pslld\t{%2, %0|%0, %2}"
22421 [(set_attr "type" "sseishft")
22422 (set_attr "mode" "TI")])
22423
22424(define_insn "ashlv2di3_ti"
22425 [(set (match_operand:V2DI 0 "register_operand" "=x")
22426 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22427 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22428 "TARGET_SSE2"
22429 "psllq\t{%2, %0|%0, %2}"
22430 [(set_attr "type" "sseishft")
22431 (set_attr "mode" "TI")])
22432
22433;; See logical MMX insns for the reason for the unspec. Strictly speaking
22434;; we wouldn't need here it since we never generate TImode arithmetic.
22435
22436;; There has to be some kind of prize for the weirdest new instruction...
22437(define_insn "sse2_ashlti3"
22438 [(set (match_operand:TI 0 "register_operand" "=x")
22439 (unspec:TI
22440 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22441 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22442 (const_int 8)))] UNSPEC_NOP))]
22443 "TARGET_SSE2"
22444 "pslldq\t{%2, %0|%0, %2}"
22445 [(set_attr "type" "sseishft")
22446 (set_attr "mode" "TI")])
22447
22448(define_insn "sse2_lshrti3"
22449 [(set (match_operand:TI 0 "register_operand" "=x")
22450 (unspec:TI
22451 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22452 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22453 (const_int 8)))] UNSPEC_NOP))]
22454 "TARGET_SSE2"
22455 "psrldq\t{%2, %0|%0, %2}"
22456 [(set_attr "type" "sseishft")
22457 (set_attr "mode" "TI")])
22458
22459;; SSE unpack
22460
22461(define_insn "sse2_unpckhpd"
22462 [(set (match_operand:V2DF 0 "register_operand" "=x")
22463 (vec_concat:V2DF
22464 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22465 (parallel [(const_int 1)]))
22466 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22467 (parallel [(const_int 1)]))))]
22468 "TARGET_SSE2"
22469 "unpckhpd\t{%2, %0|%0, %2}"
22470 [(set_attr "type" "ssecvt")
22471 (set_attr "mode" "V2DF")])
22472
22473(define_insn "sse2_unpcklpd"
22474 [(set (match_operand:V2DF 0 "register_operand" "=x")
22475 (vec_concat:V2DF
22476 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22477 (parallel [(const_int 0)]))
22478 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22479 (parallel [(const_int 0)]))))]
22480 "TARGET_SSE2"
22481 "unpcklpd\t{%2, %0|%0, %2}"
22482 [(set_attr "type" "ssecvt")
22483 (set_attr "mode" "V2DF")])
22484
22485;; MMX pack/unpack insns.
22486
22487(define_insn "sse2_packsswb"
22488 [(set (match_operand:V16QI 0 "register_operand" "=x")
22489 (vec_concat:V16QI
22490 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22491 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22492 "TARGET_SSE2"
22493 "packsswb\t{%2, %0|%0, %2}"
22494 [(set_attr "type" "ssecvt")
22495 (set_attr "mode" "TI")])
22496
22497(define_insn "sse2_packssdw"
22498 [(set (match_operand:V8HI 0 "register_operand" "=x")
22499 (vec_concat:V8HI
22500 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22501 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22502 "TARGET_SSE2"
22503 "packssdw\t{%2, %0|%0, %2}"
22504 [(set_attr "type" "ssecvt")
22505 (set_attr "mode" "TI")])
22506
22507(define_insn "sse2_packuswb"
22508 [(set (match_operand:V16QI 0 "register_operand" "=x")
22509 (vec_concat:V16QI
22510 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22511 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22512 "TARGET_SSE2"
22513 "packuswb\t{%2, %0|%0, %2}"
22514 [(set_attr "type" "ssecvt")
22515 (set_attr "mode" "TI")])
22516
22517(define_insn "sse2_punpckhbw"
22518 [(set (match_operand:V16QI 0 "register_operand" "=x")
22519 (vec_merge:V16QI
22520 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22521 (parallel [(const_int 8) (const_int 0)
22522 (const_int 9) (const_int 1)
22523 (const_int 10) (const_int 2)
22524 (const_int 11) (const_int 3)
22525 (const_int 12) (const_int 4)
22526 (const_int 13) (const_int 5)
22527 (const_int 14) (const_int 6)
22528 (const_int 15) (const_int 7)]))
22529 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22530 (parallel [(const_int 0) (const_int 8)
22531 (const_int 1) (const_int 9)
22532 (const_int 2) (const_int 10)
22533 (const_int 3) (const_int 11)
22534 (const_int 4) (const_int 12)
22535 (const_int 5) (const_int 13)
22536 (const_int 6) (const_int 14)
22537 (const_int 7) (const_int 15)]))
22538 (const_int 21845)))]
22539 "TARGET_SSE2"
22540 "punpckhbw\t{%2, %0|%0, %2}"
22541 [(set_attr "type" "ssecvt")
22542 (set_attr "mode" "TI")])
22543
22544(define_insn "sse2_punpckhwd"
22545 [(set (match_operand:V8HI 0 "register_operand" "=x")
22546 (vec_merge:V8HI
22547 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22548 (parallel [(const_int 4) (const_int 0)
22549 (const_int 5) (const_int 1)
22550 (const_int 6) (const_int 2)
22551 (const_int 7) (const_int 3)]))
22552 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22553 (parallel [(const_int 0) (const_int 4)
22554 (const_int 1) (const_int 5)
22555 (const_int 2) (const_int 6)
22556 (const_int 3) (const_int 7)]))
22557 (const_int 85)))]
22558 "TARGET_SSE2"
22559 "punpckhwd\t{%2, %0|%0, %2}"
22560 [(set_attr "type" "ssecvt")
22561 (set_attr "mode" "TI")])
22562
22563(define_insn "sse2_punpckhdq"
22564 [(set (match_operand:V4SI 0 "register_operand" "=x")
22565 (vec_merge:V4SI
22566 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22567 (parallel [(const_int 2) (const_int 0)
22568 (const_int 3) (const_int 1)]))
22569 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22570 (parallel [(const_int 0) (const_int 2)
22571 (const_int 1) (const_int 3)]))
22572 (const_int 5)))]
22573 "TARGET_SSE2"
22574 "punpckhdq\t{%2, %0|%0, %2}"
22575 [(set_attr "type" "ssecvt")
22576 (set_attr "mode" "TI")])
22577
22578(define_insn "sse2_punpcklbw"
22579 [(set (match_operand:V16QI 0 "register_operand" "=x")
22580 (vec_merge:V16QI
22581 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22582 (parallel [(const_int 0) (const_int 8)
22583 (const_int 1) (const_int 9)
22584 (const_int 2) (const_int 10)
22585 (const_int 3) (const_int 11)
22586 (const_int 4) (const_int 12)
22587 (const_int 5) (const_int 13)
22588 (const_int 6) (const_int 14)
22589 (const_int 7) (const_int 15)]))
22590 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22591 (parallel [(const_int 8) (const_int 0)
22592 (const_int 9) (const_int 1)
22593 (const_int 10) (const_int 2)
22594 (const_int 11) (const_int 3)
22595 (const_int 12) (const_int 4)
22596 (const_int 13) (const_int 5)
22597 (const_int 14) (const_int 6)
22598 (const_int 15) (const_int 7)]))
22599 (const_int 21845)))]
22600 "TARGET_SSE2"
22601 "punpcklbw\t{%2, %0|%0, %2}"
22602 [(set_attr "type" "ssecvt")
22603 (set_attr "mode" "TI")])
22604
22605(define_insn "sse2_punpcklwd"
22606 [(set (match_operand:V8HI 0 "register_operand" "=x")
22607 (vec_merge:V8HI
22608 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22609 (parallel [(const_int 0) (const_int 4)
22610 (const_int 1) (const_int 5)
22611 (const_int 2) (const_int 6)
22612 (const_int 3) (const_int 7)]))
22613 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22614 (parallel [(const_int 4) (const_int 0)
22615 (const_int 5) (const_int 1)
22616 (const_int 6) (const_int 2)
22617 (const_int 7) (const_int 3)]))
22618 (const_int 85)))]
22619 "TARGET_SSE2"
22620 "punpcklwd\t{%2, %0|%0, %2}"
22621 [(set_attr "type" "ssecvt")
22622 (set_attr "mode" "TI")])
22623
22624(define_insn "sse2_punpckldq"
22625 [(set (match_operand:V4SI 0 "register_operand" "=x")
22626 (vec_merge:V4SI
22627 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22628 (parallel [(const_int 0) (const_int 2)
22629 (const_int 1) (const_int 3)]))
22630 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22631 (parallel [(const_int 2) (const_int 0)
22632 (const_int 3) (const_int 1)]))
22633 (const_int 5)))]
22634 "TARGET_SSE2"
22635 "punpckldq\t{%2, %0|%0, %2}"
22636 [(set_attr "type" "ssecvt")
22637 (set_attr "mode" "TI")])
22638
22639(define_insn "sse2_punpcklqdq"
22640 [(set (match_operand:V2DI 0 "register_operand" "=x")
22641 (vec_merge:V2DI
22642 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22643 (parallel [(const_int 1)
22644 (const_int 0)]))
22645 (match_operand:V2DI 1 "register_operand" "0")
22646 (const_int 1)))]
22647 "TARGET_SSE2"
22648 "punpcklqdq\t{%2, %0|%0, %2}"
22649 [(set_attr "type" "ssecvt")
22650 (set_attr "mode" "TI")])
22651
22652(define_insn "sse2_punpckhqdq"
22653 [(set (match_operand:V2DI 0 "register_operand" "=x")
22654 (vec_merge:V2DI
22655 (match_operand:V2DI 1 "register_operand" "0")
22656 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22657 (parallel [(const_int 1)
22658 (const_int 0)]))
22659 (const_int 1)))]
22660 "TARGET_SSE2"
22661 "punpckhqdq\t{%2, %0|%0, %2}"
22662 [(set_attr "type" "ssecvt")
22663 (set_attr "mode" "TI")])
22664
22665;; SSE2 moves
22666
22667(define_insn "sse2_movapd"
22668 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22669 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22670 UNSPEC_MOVA))]
22671 "TARGET_SSE2
22672 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22673 "movapd\t{%1, %0|%0, %1}"
22674 [(set_attr "type" "ssemov")
22675 (set_attr "mode" "V2DF")])
22676
22677(define_insn "sse2_movupd"
22678 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22679 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22680 UNSPEC_MOVU))]
22681 "TARGET_SSE2
22682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22683 "movupd\t{%1, %0|%0, %1}"
22684 [(set_attr "type" "ssecvt")
22685 (set_attr "mode" "V2DF")])
22686
22687(define_insn "sse2_movdqa"
22688 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22689 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22690 UNSPEC_MOVA))]
22691 "TARGET_SSE2
22692 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22693 "movdqa\t{%1, %0|%0, %1}"
22694 [(set_attr "type" "ssemov")
22695 (set_attr "mode" "TI")])
22696
22697(define_insn "sse2_movdqu"
22698 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22699 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22700 UNSPEC_MOVU))]
22701 "TARGET_SSE2
22702 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22703 "movdqu\t{%1, %0|%0, %1}"
22704 [(set_attr "type" "ssecvt")
22705 (set_attr "mode" "TI")])
22706
22707(define_insn "sse2_movdq2q"
22708 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22709 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22710 (parallel [(const_int 0)])))]
22711 "TARGET_SSE2 && !TARGET_64BIT"
22712 "@
22713 movq\t{%1, %0|%0, %1}
22714 movdq2q\t{%1, %0|%0, %1}"
22715 [(set_attr "type" "ssecvt")
22716 (set_attr "mode" "TI")])
22717
22718(define_insn "sse2_movdq2q_rex64"
22719 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22720 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22721 (parallel [(const_int 0)])))]
22722 "TARGET_SSE2 && TARGET_64BIT"
22723 "@
22724 movq\t{%1, %0|%0, %1}
22725 movdq2q\t{%1, %0|%0, %1}
22726 movd\t{%1, %0|%0, %1}"
22727 [(set_attr "type" "ssecvt")
22728 (set_attr "mode" "TI")])
22729
22730(define_insn "sse2_movq2dq"
22731 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22732 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22733 (const_int 0)))]
22734 "TARGET_SSE2 && !TARGET_64BIT"
22735 "@
22736 movq\t{%1, %0|%0, %1}
22737 movq2dq\t{%1, %0|%0, %1}"
22738 [(set_attr "type" "ssecvt,ssemov")
22739 (set_attr "mode" "TI")])
22740
22741(define_insn "sse2_movq2dq_rex64"
22742 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22743 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22744 (const_int 0)))]
22745 "TARGET_SSE2 && TARGET_64BIT"
22746 "@
22747 movq\t{%1, %0|%0, %1}
22748 movq2dq\t{%1, %0|%0, %1}
22749 movd\t{%1, %0|%0, %1}"
22750 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22751 (set_attr "mode" "TI")])
22752
22753(define_insn "sse2_movq"
22754 [(set (match_operand:V2DI 0 "register_operand" "=x")
22755 (vec_concat:V2DI (vec_select:DI
22756 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22757 (parallel [(const_int 0)]))
22758 (const_int 0)))]
22759 "TARGET_SSE2"
22760 "movq\t{%1, %0|%0, %1}"
22761 [(set_attr "type" "ssemov")
22762 (set_attr "mode" "TI")])
22763
22764(define_insn "sse2_loadd"
22765 [(set (match_operand:V4SI 0 "register_operand" "=x")
22766 (vec_merge:V4SI
22767 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22768 (const_vector:V4SI [(const_int 0)
22769 (const_int 0)
22770 (const_int 0)
22771 (const_int 0)])
22772 (const_int 1)))]
22773 "TARGET_SSE2"
22774 "movd\t{%1, %0|%0, %1}"
22775 [(set_attr "type" "ssemov")
22776 (set_attr "mode" "TI")])
22777
22778(define_insn "sse2_stored"
22779 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22780 (vec_select:SI
22781 (match_operand:V4SI 1 "register_operand" "x")
22782 (parallel [(const_int 0)])))]
22783 "TARGET_SSE2"
22784 "movd\t{%1, %0|%0, %1}"
22785 [(set_attr "type" "ssemov")
22786 (set_attr "mode" "TI")])
22787
22788(define_insn "sse2_movhpd"
22789 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22790 (vec_merge:V2DF
22791 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22792 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22793 (const_int 2)))]
22794 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22795 "movhpd\t{%2, %0|%0, %2}"
22796 [(set_attr "type" "ssecvt")
22797 (set_attr "mode" "V2DF")])
22798
22799(define_expand "sse2_loadsd"
22800 [(match_operand:V2DF 0 "register_operand" "")
22801 (match_operand:DF 1 "memory_operand" "")]
22802 "TARGET_SSE2"
22803{
22804 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22805 CONST0_RTX (V2DFmode)));
22806 DONE;
22807})
22808
22809(define_insn "sse2_loadsd_1"
22810 [(set (match_operand:V2DF 0 "register_operand" "=x")
22811 (vec_merge:V2DF
22812 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22813 (match_operand:V2DF 2 "const0_operand" "X")
22814 (const_int 1)))]
22815 "TARGET_SSE2"
22816 "movsd\t{%1, %0|%0, %1}"
22817 [(set_attr "type" "ssecvt")
22818 (set_attr "mode" "DF")])
22819
22820(define_insn "sse2_movsd"
22821 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22822 (vec_merge:V2DF
22823 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22824 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22825 (const_int 1)))]
22826 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22827 "@movsd\t{%2, %0|%0, %2}
22828 movlpd\t{%2, %0|%0, %2}
22829 movlpd\t{%2, %0|%0, %2}"
22830 [(set_attr "type" "ssecvt")
22831 (set_attr "mode" "DF,V2DF,V2DF")])
22832
22833(define_insn "sse2_storesd"
22834 [(set (match_operand:DF 0 "memory_operand" "=m")
22835 (vec_select:DF
22836 (match_operand:V2DF 1 "register_operand" "x")
22837 (parallel [(const_int 0)])))]
22838 "TARGET_SSE2"
22839 "movsd\t{%1, %0|%0, %1}"
22840 [(set_attr "type" "ssecvt")
22841 (set_attr "mode" "DF")])
22842
22843(define_insn "sse2_shufpd"
22844 [(set (match_operand:V2DF 0 "register_operand" "=x")
22845 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22846 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22847 (match_operand:SI 3 "immediate_operand" "i")]
22848 UNSPEC_SHUFFLE))]
22849 "TARGET_SSE2"
22850 ;; @@@ check operand order for intel/nonintel syntax
22851 "shufpd\t{%3, %2, %0|%0, %2, %3}"
22852 [(set_attr "type" "ssecvt")
22853 (set_attr "mode" "V2DF")])
22854
22855(define_insn "sse2_clflush"
22856 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22857 UNSPECV_CLFLUSH)]
22858 "TARGET_SSE2"
22859 "clflush %0"
22860 [(set_attr "type" "sse")
22861 (set_attr "memory" "unknown")])
22862
22863(define_expand "sse2_mfence"
22864 [(set (match_dup 0)
22865 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22866 "TARGET_SSE2"
22867{
22868 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22869 MEM_VOLATILE_P (operands[0]) = 1;
22870})
22871
22872(define_insn "*mfence_insn"
22873 [(set (match_operand:BLK 0 "" "")
22874 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22875 "TARGET_SSE2"
22876 "mfence"
22877 [(set_attr "type" "sse")
22878 (set_attr "memory" "unknown")])
22879
22880(define_expand "sse2_lfence"
22881 [(set (match_dup 0)
22882 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22883 "TARGET_SSE2"
22884{
22885 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22886 MEM_VOLATILE_P (operands[0]) = 1;
22887})
22888
22889(define_insn "*lfence_insn"
22890 [(set (match_operand:BLK 0 "" "")
22891 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22892 "TARGET_SSE2"
22893 "lfence"
22894 [(set_attr "type" "sse")
22895 (set_attr "memory" "unknown")])
22896
22897;; SSE3
22898
22899(define_insn "mwait"
22900 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22901 (match_operand:SI 1 "register_operand" "c")]
22902 UNSPECV_MWAIT)]
22903 "TARGET_SSE3"
22904 "mwait\t%0, %1"
22905 [(set_attr "length" "3")])
22906
22907(define_insn "monitor"
22908 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22909 (match_operand:SI 1 "register_operand" "c")
22910 (match_operand:SI 2 "register_operand" "d")]
22911 UNSPECV_MONITOR)]
22912 "TARGET_SSE3"
22913 "monitor\t%0, %1, %2"
22914 [(set_attr "length" "3")])
22915
22916;; SSE3 arithmetic
22917
22918(define_insn "addsubv4sf3"
22919 [(set (match_operand:V4SF 0 "register_operand" "=x")
22920 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22921 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22922 UNSPEC_ADDSUB))]
22923 "TARGET_SSE3"
22924 "addsubps\t{%2, %0|%0, %2}"
22925 [(set_attr "type" "sseadd")
22926 (set_attr "mode" "V4SF")])
22927
22928(define_insn "addsubv2df3"
22929 [(set (match_operand:V2DF 0 "register_operand" "=x")
22930 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22931 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22932 UNSPEC_ADDSUB))]
22933 "TARGET_SSE3"
22934 "addsubpd\t{%2, %0|%0, %2}"
22935 [(set_attr "type" "sseadd")
22936 (set_attr "mode" "V2DF")])
22937
22938(define_insn "haddv4sf3"
22939 [(set (match_operand:V4SF 0 "register_operand" "=x")
22940 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22941 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22942 UNSPEC_HADD))]
22943 "TARGET_SSE3"
22944 "haddps\t{%2, %0|%0, %2}"
22945 [(set_attr "type" "sseadd")
22946 (set_attr "mode" "V4SF")])
22947
22948(define_insn "haddv2df3"
22949 [(set (match_operand:V2DF 0 "register_operand" "=x")
22950 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22951 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22952 UNSPEC_HADD))]
22953 "TARGET_SSE3"
22954 "haddpd\t{%2, %0|%0, %2}"
22955 [(set_attr "type" "sseadd")
22956 (set_attr "mode" "V2DF")])
22957
22958(define_insn "hsubv4sf3"
22959 [(set (match_operand:V4SF 0 "register_operand" "=x")
22960 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22961 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22962 UNSPEC_HSUB))]
22963 "TARGET_SSE3"
22964 "hsubps\t{%2, %0|%0, %2}"
22965 [(set_attr "type" "sseadd")
22966 (set_attr "mode" "V4SF")])
22967
22968(define_insn "hsubv2df3"
22969 [(set (match_operand:V2DF 0 "register_operand" "=x")
22970 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22971 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22972 UNSPEC_HSUB))]
22973 "TARGET_SSE3"
22974 "hsubpd\t{%2, %0|%0, %2}"
22975 [(set_attr "type" "sseadd")
22976 (set_attr "mode" "V2DF")])
22977
22978(define_insn "movshdup"
22979 [(set (match_operand:V4SF 0 "register_operand" "=x")
22980 (unspec:V4SF
22981 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22982 "TARGET_SSE3"
22983 "movshdup\t{%1, %0|%0, %1}"
22984 [(set_attr "type" "sse")
22985 (set_attr "mode" "V4SF")])
22986
22987(define_insn "movsldup"
22988 [(set (match_operand:V4SF 0 "register_operand" "=x")
22989 (unspec:V4SF
22990 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22991 "TARGET_SSE3"
22992 "movsldup\t{%1, %0|%0, %1}"
22993 [(set_attr "type" "sse")
22994 (set_attr "mode" "V4SF")])
22995
22996(define_insn "lddqu"
22997 [(set (match_operand:V16QI 0 "register_operand" "=x")
22998 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22999 UNSPEC_LDQQU))]
23000 "TARGET_SSE3"
23001 "lddqu\t{%1, %0|%0, %1}"
23002 [(set_attr "type" "ssecvt")
23003 (set_attr "mode" "TI")])
23004
23005(define_insn "loadddup"
23006 [(set (match_operand:V2DF 0 "register_operand" "=x")
23007 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23008 "TARGET_SSE3"
23009 "movddup\t{%1, %0|%0, %1}"
23010 [(set_attr "type" "ssecvt")
23011 (set_attr "mode" "DF")])
23012
23013(define_insn "movddup"
23014 [(set (match_operand:V2DF 0 "register_operand" "=x")
23015 (vec_duplicate:V2DF
23016 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23017 (parallel [(const_int 0)]))))]
23018 "TARGET_SSE3"
23019 "movddup\t{%1, %0|%0, %1}"
23020 [(set_attr "type" "ssecvt")
23021 (set_attr "mode" "DF")])
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
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)
129 (UNSPECV_STACK_PROBE 10)
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
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
404(include "pentium.md")
405(include "ppro.md")
406(include "k6.md")
407(include "athlon.md")
408
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
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")
1264 (set_attr "mode" "SI")
1265 (set_attr "pent_pair" "np")
1266 (set_attr "athlon_decode" "vector")
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))]
1379 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1380 "xchg{l}\t%k1, %k0"
1381 [(set_attr "type" "imov")
1382 (set_attr "mode" "SI")
1383 (set_attr "pent_pair" "np")
1384 (set_attr "athlon_decode" "vector")
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))]
1392 "TARGET_PARTIAL_REG_STALL"
1393 "xchg{w}\t%1, %0"
1394 [(set_attr "type" "imov")
1395 (set_attr "mode" "HI")
1396 (set_attr "pent_pair" "np")
1397 (set_attr "athlon_decode" "vector")
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
1545(define_insn "*swapqi_1"
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))]
1550 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1551 "xchg{l}\t%k1, %k0"
1552 [(set_attr "type" "imov")
1553 (set_attr "mode" "SI")
1554 (set_attr "pent_pair" "np")
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")
1566 (set_attr "mode" "QI")
1567 (set_attr "pent_pair" "np")
1568 (set_attr "athlon_decode" "vector")
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" ""))]
1853 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1854 && !symbolic_operand (operands[1], DImode)
1855 && !x86_64_immediate_operand (operands[1], DImode)"
1856 [(set (match_dup 0) (match_dup 1))
1857 (set (match_dup 2) (match_dup 3))]
1858 "split_di (operands + 1, 1, operands + 2, operands + 3);
1859 operands[1] = gen_lowpart (DImode, operands[2]);
1860 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1861 GEN_INT (4)));
1862 ")
1863
1864(define_insn "*pushdi2_prologue_rex64"
1865 [(set (match_operand:DI 0 "push_operand" "=<")
1866 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1867 (clobber (mem:BLK (scratch)))]
1868 "TARGET_64BIT"
1869 "push{q}\t%1"
1870 [(set_attr "type" "push")
1871 (set_attr "mode" "DI")])
1872
1873(define_insn "*popdi1_epilogue_rex64"
1874 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1875 (mem:DI (reg:DI 7)))
1876 (set (reg:DI 7)
1877 (plus:DI (reg:DI 7) (const_int 8)))
1878 (clobber (mem:BLK (scratch)))]
1879 "TARGET_64BIT"
1880 "pop{q}\t%0"
1881 [(set_attr "type" "pop")
1882 (set_attr "mode" "DI")])
1883
1884(define_insn "popdi1"
1885 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1886 (mem:DI (reg:DI 7)))
1887 (set (reg:DI 7)
1888 (plus:DI (reg:DI 7) (const_int 8)))]
1889 "TARGET_64BIT"
1890 "pop{q}\t%0"
1891 [(set_attr "type" "pop")
1892 (set_attr "mode" "DI")])
1893
1894(define_insn "*movdi_xor_rex64"
1895 [(set (match_operand:DI 0 "register_operand" "=r")
1896 (match_operand:DI 1 "const0_operand" "i"))
1897 (clobber (reg:CC 17))]
1898 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1899 && reload_completed"
1900 "xor{l}\t{%k0, %k0|%k0, %k0}"
1901 [(set_attr "type" "alu1")
1902 (set_attr "mode" "SI")
1903 (set_attr "length_immediate" "0")])
1904
1905(define_insn "*movdi_or_rex64"
1906 [(set (match_operand:DI 0 "register_operand" "=r")
1907 (match_operand:DI 1 "const_int_operand" "i"))
1908 (clobber (reg:CC 17))]
1909 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1910 && reload_completed
1911 && operands[1] == constm1_rtx"
1912{
1913 operands[1] = constm1_rtx;
1914 return "or{q}\t{%1, %0|%0, %1}";
1915}
1916 [(set_attr "type" "alu1")
1917 (set_attr "mode" "DI")
1918 (set_attr "length_immediate" "1")])
1919
1920(define_insn "*movdi_2"
1921 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1922 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1923 "!TARGET_64BIT
1924 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1925 "@
1926 #
1927 #
1928 movq\t{%1, %0|%0, %1}
1929 movq\t{%1, %0|%0, %1}
1930 movq\t{%1, %0|%0, %1}
1931 movdqa\t{%1, %0|%0, %1}
1932 movq\t{%1, %0|%0, %1}"
1933 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1934 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1935
1936(define_split
1937 [(set (match_operand:DI 0 "push_operand" "")
1938 (match_operand:DI 1 "general_operand" ""))]
1939 "!TARGET_64BIT && reload_completed
1940 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1941 [(const_int 0)]
1942 "ix86_split_long_move (operands); DONE;")
1943
1944;; %%% This multiword shite has got to go.
1945(define_split
1946 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1947 (match_operand:DI 1 "general_operand" ""))]
1948 "!TARGET_64BIT && reload_completed
1949 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1950 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1951 [(const_int 0)]
1952 "ix86_split_long_move (operands); DONE;")
1953
1954(define_insn "*movdi_1_rex64"
1955 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1956 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1957 "TARGET_64BIT
1958 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1959 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1960{
1961 switch (get_attr_type (insn))
1962 {
1963 case TYPE_SSEMOV:
1964 if (get_attr_mode (insn) == MODE_TI)
1965 return "movdqa\t{%1, %0|%0, %1}";
1966 /* FALLTHRU */
1967 case TYPE_MMXMOV:
1968 /* Moves from and into integer register is done using movd opcode with
1969 REX prefix. */
1970 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1971 return "movd\t{%1, %0|%0, %1}";
1972 return "movq\t{%1, %0|%0, %1}";
1973 case TYPE_MULTI:
1974 return "#";
1975 case TYPE_LEA:
1976 return "lea{q}\t{%a1, %0|%0, %a1}";
1977 default:
1978 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1979 abort ();
1980 if (get_attr_mode (insn) == MODE_SI)
1981 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1982 else if (which_alternative == 2)
1983 return "movabs{q}\t{%1, %0|%0, %1}";
1984 else
1985 return "mov{q}\t{%1, %0|%0, %1}";
1986 }
1987}
1988 [(set (attr "type")
1989 (cond [(eq_attr "alternative" "5,6,7")
1990 (const_string "mmxmov")
1991 (eq_attr "alternative" "8,9,10")
1992 (const_string "ssemov")
1993 (eq_attr "alternative" "4")
1994 (const_string "multi")
1995 (and (ne (symbol_ref "flag_pic") (const_int 0))
1996 (match_operand:DI 1 "symbolic_operand" ""))
1997 (const_string "lea")
1998 ]
1999 (const_string "imov")))
2000 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2001 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2002 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2003
2004(define_insn "*movdi_1_rex64_nointerunit"
2005 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2006 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2007 "TARGET_64BIT
2008 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2009 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2010{
2011 switch (get_attr_type (insn))
2012 {
2013 case TYPE_SSEMOV:
2014 if (get_attr_mode (insn) == MODE_TI)
2015 return "movdqa\t{%1, %0|%0, %1}";
2016 /* FALLTHRU */
2017 case TYPE_MMXMOV:
2018 return "movq\t{%1, %0|%0, %1}";
2019 case TYPE_MULTI:
2020 return "#";
2021 case TYPE_LEA:
2022 return "lea{q}\t{%a1, %0|%0, %a1}";
2023 default:
2024 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2025 abort ();
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 2)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2030 else
2031 return "mov{q}\t{%1, %0|%0, %1}";
2032 }
2033}
2034 [(set (attr "type")
2035 (cond [(eq_attr "alternative" "5,6,7")
2036 (const_string "mmxmov")
2037 (eq_attr "alternative" "8,9,10")
2038 (const_string "ssemov")
2039 (eq_attr "alternative" "4")
2040 (const_string "multi")
2041 (and (ne (symbol_ref "flag_pic") (const_int 0))
2042 (match_operand:DI 1 "symbolic_operand" ""))
2043 (const_string "lea")
2044 ]
2045 (const_string "imov")))
2046 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2047 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2048 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2049
2050;; Stores and loads of ax to arbitrary constant address.
2051;; We fake an second form of instruction to force reload to load address
2052;; into register when rax is not available
2053(define_insn "*movabsdi_1_rex64"
2054 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2055 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2056 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2057 "@
2058 movabs{q}\t{%1, %P0|%P0, %1}
2059 mov{q}\t{%1, %a0|%a0, %1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "modrm" "0,*")
2062 (set_attr "length_address" "8,0")
2063 (set_attr "length_immediate" "0,*")
2064 (set_attr "memory" "store")
2065 (set_attr "mode" "DI")])
2066
2067(define_insn "*movabsdi_2_rex64"
2068 [(set (match_operand:DI 0 "register_operand" "=a,r")
2069 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2070 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2071 "@
2072 movabs{q}\t{%P1, %0|%0, %P1}
2073 mov{q}\t{%a1, %0|%0, %a1}"
2074 [(set_attr "type" "imov")
2075 (set_attr "modrm" "0,*")
2076 (set_attr "length_address" "8,0")
2077 (set_attr "length_immediate" "0")
2078 (set_attr "memory" "load")
2079 (set_attr "mode" "DI")])
2080
2081;; Convert impossible stores of immediate to existing instructions.
2082;; First try to get scratch register and go through it. In case this
2083;; fails, move by 32bit parts.
2084(define_peephole2
2085 [(match_scratch:DI 2 "r")
2086 (set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode)"
2090 [(set (match_dup 2) (match_dup 1))
2091 (set (match_dup 0) (match_dup 2))]
2092 "")
2093
2094;; We need to define this as both peepholer and splitter for case
2095;; peephole2 pass is not run.
2096(define_peephole2
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2101 [(set (match_dup 2) (match_dup 3))
2102 (set (match_dup 4) (match_dup 5))]
2103 "split_di (operands, 2, operands + 2, operands + 4);")
2104
2105(define_split
2106 [(set (match_operand:DI 0 "memory_operand" "")
2107 (match_operand:DI 1 "immediate_operand" ""))]
2108 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2109 && !symbolic_operand (operands[1], DImode)
2110 && !x86_64_immediate_operand (operands[1], DImode)"
2111 [(set (match_dup 2) (match_dup 3))
2112 (set (match_dup 4) (match_dup 5))]
2113 "split_di (operands, 2, operands + 2, operands + 4);")
2114
2115(define_insn "*swapdi_rex64"
2116 [(set (match_operand:DI 0 "register_operand" "+r")
2117 (match_operand:DI 1 "register_operand" "+r"))
2118 (set (match_dup 1)
2119 (match_dup 0))]
2120 "TARGET_64BIT"
2121 "xchg{q}\t%1, %0"
2122 [(set_attr "type" "imov")
2123 (set_attr "mode" "DI")
2124 (set_attr "pent_pair" "np")
2125 (set_attr "athlon_decode" "vector")
2126 (set_attr "ppro_uops" "few")])
2127
2128(define_expand "movsf"
2129 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2130 (match_operand:SF 1 "general_operand" ""))]
2131 ""
2132 "ix86_expand_move (SFmode, operands); DONE;")
2133
2134(define_insn "*pushsf"
2135 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2136 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2137 "!TARGET_64BIT"
2138{
2139 switch (which_alternative)
2140 {
2141 case 1:
2142 return "push{l}\t%1";
2143
2144 default:
2145 /* This insn should be already split before reg-stack. */
2146 abort ();
2147 }
2148}
2149 [(set_attr "type" "multi,push,multi")
2150 (set_attr "mode" "SF,SI,SF")])
2151
2152(define_insn "*pushsf_rex64"
2153 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2154 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2155 "TARGET_64BIT"
2156{
2157 switch (which_alternative)
2158 {
2159 case 1:
2160 return "push{q}\t%q1";
2161
2162 default:
2163 /* This insn should be already split before reg-stack. */
2164 abort ();
2165 }
2166}
2167 [(set_attr "type" "multi,push,multi")
2168 (set_attr "mode" "SF,DI,SF")])
2169
2170(define_split
2171 [(set (match_operand:SF 0 "push_operand" "")
2172 (match_operand:SF 1 "memory_operand" ""))]
2173 "reload_completed
2174 && GET_CODE (operands[1]) == MEM
2175 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2176 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2177 [(set (match_dup 0)
2178 (match_dup 1))]
2179 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2180
2181
2182;; %%% Kill this when call knows how to work this out.
2183(define_split
2184 [(set (match_operand:SF 0 "push_operand" "")
2185 (match_operand:SF 1 "any_fp_register_operand" ""))]
2186 "!TARGET_64BIT"
2187 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2188 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2189
2190(define_split
2191 [(set (match_operand:SF 0 "push_operand" "")
2192 (match_operand:SF 1 "any_fp_register_operand" ""))]
2193 "TARGET_64BIT"
2194 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2195 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2196
2197(define_insn "*movsf_1"
2198 [(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")
2199 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2200 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2201 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2202 && (reload_in_progress || reload_completed
2203 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2204 || GET_CODE (operands[1]) != CONST_DOUBLE
2205 || memory_operand (operands[0], SFmode))"
2206{
2207 switch (which_alternative)
2208 {
2209 case 0:
2210 if (REG_P (operands[1])
2211 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2212 return "fstp\t%y0";
2213 else if (STACK_TOP_P (operands[0]))
2214 return "fld%z1\t%y1";
2215 else
2216 return "fst\t%y0";
2217
2218 case 1:
2219 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2220 return "fstp%z0\t%y0";
2221 else
2222 return "fst%z0\t%y0";
2223
2224 case 2:
2225 return standard_80387_constant_opcode (operands[1]);
2226
2227 case 3:
2228 case 4:
2229 return "mov{l}\t{%1, %0|%0, %1}";
2230 case 5:
2231 if (get_attr_mode (insn) == MODE_TI)
2232 return "pxor\t%0, %0";
2233 else
2234 return "xorps\t%0, %0";
2235 case 6:
2236 if (get_attr_mode (insn) == MODE_V4SF)
2237 return "movaps\t{%1, %0|%0, %1}";
2238 else
2239 return "movss\t{%1, %0|%0, %1}";
2240 case 7:
2241 case 8:
2242 return "movss\t{%1, %0|%0, %1}";
2243
2244 case 9:
2245 case 10:
2246 return "movd\t{%1, %0|%0, %1}";
2247
2248 case 11:
2249 return "movq\t{%1, %0|%0, %1}";
2250
2251 default:
2252 abort();
2253 }
2254}
2255 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2256 (set (attr "mode")
2257 (cond [(eq_attr "alternative" "3,4,9,10")
2258 (const_string "SI")
2259 (eq_attr "alternative" "5")
2260 (if_then_else
2261 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2262 (const_int 0))
2263 (ne (symbol_ref "TARGET_SSE2")
2264 (const_int 0)))
2265 (eq (symbol_ref "optimize_size")
2266 (const_int 0)))
2267 (const_string "TI")
2268 (const_string "V4SF"))
2269 /* For architectures resolving dependencies on
2270 whole SSE registers use APS move to break dependency
2271 chains, otherwise use short move to avoid extra work.
2272
2273 Do the same for architectures resolving dependencies on
2274 the parts. While in DF mode it is better to always handle
2275 just register parts, the SF mode is different due to lack
2276 of instructions to load just part of the register. It is
2277 better to maintain the whole registers in single format
2278 to avoid problems on using packed logical operations. */
2279 (eq_attr "alternative" "6")
2280 (if_then_else
2281 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2282 (const_int 0))
2283 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2284 (const_int 0)))
2285 (const_string "V4SF")
2286 (const_string "SF"))
2287 (eq_attr "alternative" "11")
2288 (const_string "DI")]
2289 (const_string "SF")))])
2290
2291(define_insn "*movsf_1_nointerunit"
2292 [(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")
2293 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2294 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2295 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2296 && (reload_in_progress || reload_completed
2297 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2298 || GET_CODE (operands[1]) != CONST_DOUBLE
2299 || memory_operand (operands[0], SFmode))"
2300{
2301 switch (which_alternative)
2302 {
2303 case 0:
2304 if (REG_P (operands[1])
2305 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2306 {
2307 if (REGNO (operands[0]) == FIRST_STACK_REG
2308 && TARGET_USE_FFREEP)
2309 return "ffreep\t%y0";
2310 return "fstp\t%y0";
2311 }
2312 else if (STACK_TOP_P (operands[0]))
2313 return "fld%z1\t%y1";
2314 else
2315 return "fst\t%y0";
2316
2317 case 1:
2318 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319 return "fstp%z0\t%y0";
2320 else
2321 return "fst%z0\t%y0";
2322
2323 case 2:
2324 return standard_80387_constant_opcode (operands[1]);
2325
2326 case 3:
2327 case 4:
2328 return "mov{l}\t{%1, %0|%0, %1}";
2329 case 5:
2330 if (get_attr_mode (insn) == MODE_TI)
2331 return "pxor\t%0, %0";
2332 else
2333 return "xorps\t%0, %0";
2334 case 6:
2335 if (get_attr_mode (insn) == MODE_V4SF)
2336 return "movaps\t{%1, %0|%0, %1}";
2337 else
2338 return "movss\t{%1, %0|%0, %1}";
2339 case 7:
2340 case 8:
2341 return "movss\t{%1, %0|%0, %1}";
2342
2343 case 9:
2344 case 10:
2345 return "movd\t{%1, %0|%0, %1}";
2346
2347 case 11:
2348 return "movq\t{%1, %0|%0, %1}";
2349
2350 default:
2351 abort();
2352 }
2353}
2354 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2355 (set (attr "mode")
2356 (cond [(eq_attr "alternative" "3,4,9,10")
2357 (const_string "SI")
2358 (eq_attr "alternative" "5")
2359 (if_then_else
2360 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2361 (const_int 0))
2362 (ne (symbol_ref "TARGET_SSE2")
2363 (const_int 0)))
2364 (eq (symbol_ref "optimize_size")
2365 (const_int 0)))
2366 (const_string "TI")
2367 (const_string "V4SF"))
2368 /* For architectures resolving dependencies on
2369 whole SSE registers use APS move to break dependency
2370 chains, otherwise use short move to avoid extra work.
2371
2372 Do the same for architectures resolving dependencies on
2373 the parts. While in DF mode it is better to always handle
2374 just register parts, the SF mode is different due to lack
2375 of instructions to load just part of the register. It is
2376 better to maintain the whole registers in single format
2377 to avoid problems on using packed logical operations. */
2378 (eq_attr "alternative" "6")
2379 (if_then_else
2380 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2381 (const_int 0))
2382 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2383 (const_int 0)))
2384 (const_string "V4SF")
2385 (const_string "SF"))
2386 (eq_attr "alternative" "11")
2387 (const_string "DI")]
2388 (const_string "SF")))])
2389
2390(define_insn "*swapsf"
2391 [(set (match_operand:SF 0 "register_operand" "+f")
2392 (match_operand:SF 1 "register_operand" "+f"))
2393 (set (match_dup 1)
2394 (match_dup 0))]
2395 "reload_completed || !TARGET_SSE"
2396{
2397 if (STACK_TOP_P (operands[0]))
2398 return "fxch\t%1";
2399 else
2400 return "fxch\t%0";
2401}
2402 [(set_attr "type" "fxch")
2403 (set_attr "mode" "SF")])
2404
2405(define_expand "movdf"
2406 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2407 (match_operand:DF 1 "general_operand" ""))]
2408 ""
2409 "ix86_expand_move (DFmode, operands); DONE;")
2410
2411;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2412;; Size of pushdf using integer instructions is 2+2*memory operand size
2413;; On the average, pushdf using integers can be still shorter. Allow this
2414;; pattern for optimize_size too.
2415
2416(define_insn "*pushdf_nointeger"
2417 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2418 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2419 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2420{
2421 /* This insn should be already split before reg-stack. */
2422 abort ();
2423}
2424 [(set_attr "type" "multi")
2425 (set_attr "mode" "DF,SI,SI,DF")])
2426
2427(define_insn "*pushdf_integer"
2428 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2429 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2430 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2431{
2432 /* This insn should be already split before reg-stack. */
2433 abort ();
2434}
2435 [(set_attr "type" "multi")
2436 (set_attr "mode" "DF,SI,DF")])
2437
2438;; %%% Kill this when call knows how to work this out.
2439(define_split
2440 [(set (match_operand:DF 0 "push_operand" "")
2441 (match_operand:DF 1 "any_fp_register_operand" ""))]
2442 "!TARGET_64BIT && reload_completed"
2443 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2444 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2445 "")
2446
2447(define_split
2448 [(set (match_operand:DF 0 "push_operand" "")
2449 (match_operand:DF 1 "any_fp_register_operand" ""))]
2450 "TARGET_64BIT && reload_completed"
2451 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2452 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2453 "")
2454
2455(define_split
2456 [(set (match_operand:DF 0 "push_operand" "")
2457 (match_operand:DF 1 "general_operand" ""))]
2458 "reload_completed"
2459 [(const_int 0)]
2460 "ix86_split_long_move (operands); DONE;")
2461
2462;; Moving is usually shorter when only FP registers are used. This separate
2463;; movdf pattern avoids the use of integer registers for FP operations
2464;; when optimizing for size.
2465
2466(define_insn "*movdf_nointeger"
2467 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2468 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2469 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2470 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2471 && (reload_in_progress || reload_completed
2472 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2473 || GET_CODE (operands[1]) != CONST_DOUBLE
2474 || memory_operand (operands[0], DFmode))"
2475{
2476 switch (which_alternative)
2477 {
2478 case 0:
2479 if (REG_P (operands[1])
2480 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2481 {
2482 if (REGNO (operands[0]) == FIRST_STACK_REG
2483 && TARGET_USE_FFREEP)
2484 return "ffreep\t%y0";
2485 return "fstp\t%y0";
2486 }
2487 else if (STACK_TOP_P (operands[0]))
2488 return "fld%z1\t%y1";
2489 else
2490 return "fst\t%y0";
2491
2492 case 1:
2493 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2494 return "fstp%z0\t%y0";
2495 else
2496 return "fst%z0\t%y0";
2497
2498 case 2:
2499 return standard_80387_constant_opcode (operands[1]);
2500
2501 case 3:
2502 case 4:
2503 return "#";
2504 case 5:
2505 switch (get_attr_mode (insn))
2506 {
2507 case MODE_V4SF:
2508 return "xorps\t%0, %0";
2509 case MODE_V2DF:
2510 return "xorpd\t%0, %0";
2511 case MODE_TI:
2512 return "pxor\t%0, %0";
2513 default:
2514 abort ();
2515 }
2516 case 6:
2517 switch (get_attr_mode (insn))
2518 {
2519 case MODE_V4SF:
2520 return "movaps\t{%1, %0|%0, %1}";
2521 case MODE_V2DF:
2522 return "movapd\t{%1, %0|%0, %1}";
2523 case MODE_DF:
2524 return "movsd\t{%1, %0|%0, %1}";
2525 default:
2526 abort ();
2527 }
2528 case 7:
2529 if (get_attr_mode (insn) == MODE_V2DF)
2530 return "movlpd\t{%1, %0|%0, %1}";
2531 else
2532 return "movsd\t{%1, %0|%0, %1}";
2533 case 8:
2534 return "movsd\t{%1, %0|%0, %1}";
2535
2536 default:
2537 abort();
2538 }
2539}
2540 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2541 (set (attr "mode")
2542 (cond [(eq_attr "alternative" "3,4")
2543 (const_string "SI")
2544 /* xorps is one byte shorter. */
2545 (eq_attr "alternative" "5")
2546 (cond [(ne (symbol_ref "optimize_size")
2547 (const_int 0))
2548 (const_string "V4SF")
2549 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2550 (const_int 0))
2551 (const_string "TI")]
2552 (const_string "V2DF"))
2553 /* For architectures resolving dependencies on
2554 whole SSE registers use APD move to break dependency
2555 chains, otherwise use short move to avoid extra work.
2556
2557 movaps encodes one byte shorter. */
2558 (eq_attr "alternative" "6")
2559 (cond
2560 [(ne (symbol_ref "optimize_size")
2561 (const_int 0))
2562 (const_string "V4SF")
2563 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2564 (const_int 0))
2565 (const_string "V2DF")]
2566 (const_string "DF"))
2567 /* For architectures resolving dependencies on register
2568 parts we may avoid extra work to zero out upper part
2569 of register. */
2570 (eq_attr "alternative" "7")
2571 (if_then_else
2572 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2573 (const_int 0))
2574 (const_string "V2DF")
2575 (const_string "DF"))]
2576 (const_string "DF")))])
2577
2578(define_insn "*movdf_integer"
2579 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2580 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2581 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2582 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2583 && (reload_in_progress || reload_completed
2584 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2585 || GET_CODE (operands[1]) != CONST_DOUBLE
2586 || memory_operand (operands[0], DFmode))"
2587{
2588 switch (which_alternative)
2589 {
2590 case 0:
2591 if (REG_P (operands[1])
2592 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2593 {
2594 if (REGNO (operands[0]) == FIRST_STACK_REG
2595 && TARGET_USE_FFREEP)
2596 return "ffreep\t%y0";
2597 return "fstp\t%y0";
2598 }
2599 else if (STACK_TOP_P (operands[0]))
2600 return "fld%z1\t%y1";
2601 else
2602 return "fst\t%y0";
2603
2604 case 1:
2605 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2606 return "fstp%z0\t%y0";
2607 else
2608 return "fst%z0\t%y0";
2609
2610 case 2:
2611 return standard_80387_constant_opcode (operands[1]);
2612
2613 case 3:
2614 case 4:
2615 return "#";
2616
2617 case 5:
2618 switch (get_attr_mode (insn))
2619 {
2620 case MODE_V4SF:
2621 return "xorps\t%0, %0";
2622 case MODE_V2DF:
2623 return "xorpd\t%0, %0";
2624 case MODE_TI:
2625 return "pxor\t%0, %0";
2626 default:
2627 abort ();
2628 }
2629 case 6:
2630 switch (get_attr_mode (insn))
2631 {
2632 case MODE_V4SF:
2633 return "movaps\t{%1, %0|%0, %1}";
2634 case MODE_V2DF:
2635 return "movapd\t{%1, %0|%0, %1}";
2636 case MODE_DF:
2637 return "movsd\t{%1, %0|%0, %1}";
2638 default:
2639 abort ();
2640 }
2641 case 7:
2642 if (get_attr_mode (insn) == MODE_V2DF)
2643 return "movlpd\t{%1, %0|%0, %1}";
2644 else
2645 return "movsd\t{%1, %0|%0, %1}";
2646 case 8:
2647 return "movsd\t{%1, %0|%0, %1}";
2648
2649 default:
2650 abort();
2651 }
2652}
2653 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2654 (set (attr "mode")
2655 (cond [(eq_attr "alternative" "3,4")
2656 (const_string "SI")
2657 /* xorps is one byte shorter. */
2658 (eq_attr "alternative" "5")
2659 (cond [(ne (symbol_ref "optimize_size")
2660 (const_int 0))
2661 (const_string "V4SF")
2662 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2663 (const_int 0))
2664 (const_string "TI")]
2665 (const_string "V2DF"))
2666 /* For architectures resolving dependencies on
2667 whole SSE registers use APD move to break dependency
2668 chains, otherwise use short move to avoid extra work.
2669
2670 movaps encodes one byte shorter. */
2671 (eq_attr "alternative" "6")
2672 (cond
2673 [(ne (symbol_ref "optimize_size")
2674 (const_int 0))
2675 (const_string "V4SF")
2676 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2677 (const_int 0))
2678 (const_string "V2DF")]
2679 (const_string "DF"))
2680 /* For architectures resolving dependencies on register
2681 parts we may avoid extra work to zero out upper part
2682 of register. */
2683 (eq_attr "alternative" "7")
2684 (if_then_else
2685 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2686 (const_int 0))
2687 (const_string "V2DF")
2688 (const_string "DF"))]
2689 (const_string "DF")))])
2690
2691(define_split
2692 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2693 (match_operand:DF 1 "general_operand" ""))]
2694 "reload_completed
2695 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2696 && ! (ANY_FP_REG_P (operands[0]) ||
2697 (GET_CODE (operands[0]) == SUBREG
2698 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2699 && ! (ANY_FP_REG_P (operands[1]) ||
2700 (GET_CODE (operands[1]) == SUBREG
2701 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2702 [(const_int 0)]
2703 "ix86_split_long_move (operands); DONE;")
2704
2705(define_insn "*swapdf"
2706 [(set (match_operand:DF 0 "register_operand" "+f")
2707 (match_operand:DF 1 "register_operand" "+f"))
2708 (set (match_dup 1)
2709 (match_dup 0))]
2710 "reload_completed || !TARGET_SSE2"
2711{
2712 if (STACK_TOP_P (operands[0]))
2713 return "fxch\t%1";
2714 else
2715 return "fxch\t%0";
2716}
2717 [(set_attr "type" "fxch")
2718 (set_attr "mode" "DF")])
2719
2720(define_expand "movxf"
2721 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2722 (match_operand:XF 1 "general_operand" ""))]
2723 ""
2724 "ix86_expand_move (XFmode, operands); DONE;")
2725
2726;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727;; Size of pushdf using integer instructions is 3+3*memory operand size
2728;; Pushing using integer instructions is longer except for constants
2729;; and direct memory references.
2730;; (assuming that any given constant is pushed only once, but this ought to be
2731;; handled elsewhere).
2732
2733(define_insn "*pushxf_nointeger"
2734 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2735 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2736 "optimize_size"
2737{
2738 /* This insn should be already split before reg-stack. */
2739 abort ();
2740}
2741 [(set_attr "type" "multi")
2742 (set_attr "mode" "XF,SI,SI")])
2743
2744(define_insn "*pushxf_integer"
2745 [(set (match_operand:XF 0 "push_operand" "=<,<")
2746 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2747 "!optimize_size"
2748{
2749 /* This insn should be already split before reg-stack. */
2750 abort ();
2751}
2752 [(set_attr "type" "multi")
2753 (set_attr "mode" "XF,SI")])
2754
2755(define_split
2756 [(set (match_operand 0 "push_operand" "")
2757 (match_operand 1 "general_operand" ""))]
2758 "reload_completed
2759 && (GET_MODE (operands[0]) == XFmode
2760 || GET_MODE (operands[0]) == DFmode)
2761 && !ANY_FP_REG_P (operands[1])"
2762 [(const_int 0)]
2763 "ix86_split_long_move (operands); DONE;")
2764
2765(define_split
2766 [(set (match_operand:XF 0 "push_operand" "")
2767 (match_operand:XF 1 "any_fp_register_operand" ""))]
2768 "!TARGET_64BIT"
2769 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2770 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2771 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772
2773(define_split
2774 [(set (match_operand:XF 0 "push_operand" "")
2775 (match_operand:XF 1 "any_fp_register_operand" ""))]
2776 "TARGET_64BIT"
2777 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2778 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2779 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2780
2781;; Do not use integer registers when optimizing for size
2782(define_insn "*movxf_nointeger"
2783 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2784 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785 "optimize_size
2786 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2787 && (reload_in_progress || reload_completed
2788 || GET_CODE (operands[1]) != CONST_DOUBLE
2789 || memory_operand (operands[0], XFmode))"
2790{
2791 switch (which_alternative)
2792 {
2793 case 0:
2794 if (REG_P (operands[1])
2795 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2796 {
2797 if (REGNO (operands[0]) == FIRST_STACK_REG
2798 && TARGET_USE_FFREEP)
2799 return "ffreep\t%y0";
2800 return "fstp\t%y0";
2801 }
2802 else if (STACK_TOP_P (operands[0]))
2803 return "fld%z1\t%y1";
2804 else
2805 return "fst\t%y0";
2806
2807 case 1:
2808 /* There is no non-popping store to memory for XFmode. So if
2809 we need one, follow the store with a load. */
2810 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2811 return "fstp%z0\t%y0\;fld%z0\t%y0";
2812 else
2813 return "fstp%z0\t%y0";
2814
2815 case 2:
2816 return standard_80387_constant_opcode (operands[1]);
2817
2818 case 3: case 4:
2819 return "#";
2820 }
2821 abort();
2822}
2823 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824 (set_attr "mode" "XF,XF,XF,SI,SI")])
2825
2826(define_insn "*movxf_integer"
2827 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2828 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2829 "!optimize_size
2830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831 && (reload_in_progress || reload_completed
2832 || GET_CODE (operands[1]) != CONST_DOUBLE
2833 || memory_operand (operands[0], XFmode))"
2834{
2835 switch (which_alternative)
2836 {
2837 case 0:
2838 if (REG_P (operands[1])
2839 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2840 {
2841 if (REGNO (operands[0]) == FIRST_STACK_REG
2842 && TARGET_USE_FFREEP)
2843 return "ffreep\t%y0";
2844 return "fstp\t%y0";
2845 }
2846 else if (STACK_TOP_P (operands[0]))
2847 return "fld%z1\t%y1";
2848 else
2849 return "fst\t%y0";
2850
2851 case 1:
2852 /* There is no non-popping store to memory for XFmode. So if
2853 we need one, follow the store with a load. */
2854 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2855 return "fstp%z0\t%y0\;fld%z0\t%y0";
2856 else
2857 return "fstp%z0\t%y0";
2858
2859 case 2:
2860 return standard_80387_constant_opcode (operands[1]);
2861
2862 case 3: case 4:
2863 return "#";
2864 }
2865 abort();
2866}
2867 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2868 (set_attr "mode" "XF,XF,XF,SI,SI")])
2869
2870(define_split
2871 [(set (match_operand 0 "nonimmediate_operand" "")
2872 (match_operand 1 "general_operand" ""))]
2873 "reload_completed
2874 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2875 && GET_MODE (operands[0]) == XFmode
2876 && ! (ANY_FP_REG_P (operands[0]) ||
2877 (GET_CODE (operands[0]) == SUBREG
2878 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2879 && ! (ANY_FP_REG_P (operands[1]) ||
2880 (GET_CODE (operands[1]) == SUBREG
2881 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2882 [(const_int 0)]
2883 "ix86_split_long_move (operands); DONE;")
2884
2885(define_split
2886 [(set (match_operand 0 "register_operand" "")
2887 (match_operand 1 "memory_operand" ""))]
2888 "reload_completed
2889 && GET_CODE (operands[1]) == MEM
2890 && (GET_MODE (operands[0]) == XFmode
2891 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2892 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2893 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2894 [(set (match_dup 0) (match_dup 1))]
2895{
2896 rtx c = get_pool_constant (XEXP (operands[1], 0));
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
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
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
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:
3542 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3543 return "fstp%z0\t%y0";
3544
3545 else
3546 return "fst%z0\t%y0";
3547 case 2:
3548 return "cvtss2sd\t{%1, %0|%0, %1}";
3549
3550 default:
3551 abort ();
3552 }
3553}
3554 [(set_attr "type" "fmov,fmov,ssecvt")
3555 (set_attr "mode" "SF,XF,DF")])
3556
3557(define_insn "*extendsfdf2_1_sse_only"
3558 [(set (match_operand:DF 0 "register_operand" "=Y")
3559 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3560 "!TARGET_80387 && TARGET_SSE2
3561 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3562 "cvtss2sd\t{%1, %0|%0, %1}"
3563 [(set_attr "type" "ssecvt")
3564 (set_attr "mode" "DF")])
3565
3566(define_expand "extendsfxf2"
3567 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3568 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3569 "TARGET_80387"
3570{
3571 /* ??? Needed for compress_float_constant since all fp constants
3572 are LEGITIMATE_CONSTANT_P. */
3573 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3574 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3575 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3576 operands[1] = force_reg (SFmode, operands[1]);
3577})
3578
3579(define_insn "*extendsfxf2_1"
3580 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3581 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3582 "TARGET_80387
3583 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3584{
3585 switch (which_alternative)
3586 {
3587 case 0:
3588 if (REG_P (operands[1])
3589 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3590 return "fstp\t%y0";
3591 else if (STACK_TOP_P (operands[0]))
3592 return "fld%z1\t%y1";
3593 else
3594 return "fst\t%y0";
3595
3596 case 1:
3597 /* There is no non-popping store to memory for XFmode. So if
3598 we need one, follow the store with a load. */
3599 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3600 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3601 else
3602 return "fstp%z0\t%y0";
3603
3604 default:
3605 abort ();
3606 }
3607}
3608 [(set_attr "type" "fmov")
3609 (set_attr "mode" "SF,XF")])
3610
3611(define_expand "extenddfxf2"
3612 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3613 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3614 "TARGET_80387"
3615{
3616 /* ??? Needed for compress_float_constant since all fp constants
3617 are LEGITIMATE_CONSTANT_P. */
3618 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3619 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3620 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3621 operands[1] = force_reg (DFmode, operands[1]);
3622})
3623
3624(define_insn "*extenddfxf2_1"
3625 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3626 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3627 "TARGET_80387
3628 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3629{
3630 switch (which_alternative)
3631 {
3632 case 0:
3633 if (REG_P (operands[1])
3634 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635 return "fstp\t%y0";
3636 else if (STACK_TOP_P (operands[0]))
3637 return "fld%z1\t%y1";
3638 else
3639 return "fst\t%y0";
3640
3641 case 1:
3642 /* There is no non-popping store to memory for XFmode. So if
3643 we need one, follow the store with a load. */
3644 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3645 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3646 else
3647 return "fstp%z0\t%y0";
3648
3649 default:
3650 abort ();
3651 }
3652}
3653 [(set_attr "type" "fmov")
3654 (set_attr "mode" "DF,XF")])
3655
3656;; %%% This seems bad bad news.
3657;; This cannot output into an f-reg because there is no way to be sure
3658;; of truncating in that case. Otherwise this is just like a simple move
3659;; insn. So we pretend we can output to a reg in order to get better
3660;; register preferencing, but we really use a stack slot.
3661
3662(define_expand "truncdfsf2"
3663 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3664 (float_truncate:SF
3665 (match_operand:DF 1 "register_operand" "")))
3666 (clobber (match_dup 2))])]
3667 "TARGET_80387 || TARGET_SSE2"
3668 "
3669 if (TARGET_80387)
3670 operands[2] = assign_386_stack_local (SFmode, 0);
3671 else
3672 {
3673 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3674 DONE;
3675 }
3676")
3677
3678(define_insn "*truncdfsf2_1"
3679 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3680 (float_truncate:SF
3681 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3682 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3683 "TARGET_80387 && !TARGET_SSE2"
3684{
3685 switch (which_alternative)
3686 {
3687 case 0:
3688 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689 return "fstp%z0\t%y0";
3690 else
3691 return "fst%z0\t%y0";
3692 default:
3693 abort ();
3694 }
3695}
3696 [(set_attr "type" "fmov,multi,multi,multi")
3697 (set_attr "mode" "SF,SF,SF,SF")])
3698
3699(define_insn "*truncdfsf2_1_sse"
3700 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3701 (float_truncate:SF
3702 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3703 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3704 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3705{
3706 switch (which_alternative)
3707 {
3708 case 0:
3709 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3710 return "fstp%z0\t%y0";
3711 else
3712 return "fst%z0\t%y0";
3713 case 4:
3714 return "#";
3715 default:
3716 abort ();
3717 }
3718}
3719 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3720 (set_attr "mode" "SF,SF,SF,SF,DF")])
3721
3722(define_insn "*truncdfsf2_1_sse_nooverlap"
3723 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3724 (float_truncate:SF
3725 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3726 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3727 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3728{
3729 switch (which_alternative)
3730 {
3731 case 0:
3732 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3733 return "fstp%z0\t%y0";
3734 else
3735 return "fst%z0\t%y0";
3736 case 4:
3737 return "#";
3738 default:
3739 abort ();
3740 }
3741}
3742 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3743 (set_attr "mode" "SF,SF,SF,SF,DF")])
3744
3745(define_insn "*truncdfsf2_2"
3746 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3747 (float_truncate:SF
3748 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3749 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3750 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3751{
3752 switch (which_alternative)
3753 {
3754 case 0:
3755 case 1:
3756 return "cvtsd2ss\t{%1, %0|%0, %1}";
3757 case 2:
3758 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3759 return "fstp%z0\t%y0";
3760 else
3761 return "fst%z0\t%y0";
3762 default:
3763 abort ();
3764 }
3765}
3766 [(set_attr "type" "ssecvt,ssecvt,fmov")
3767 (set_attr "athlon_decode" "vector,double,*")
3768 (set_attr "mode" "SF,SF,SF")])
3769
3770(define_insn "*truncdfsf2_2_nooverlap"
3771 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3772 (float_truncate:SF
3773 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3774 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3775 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3776{
3777 switch (which_alternative)
3778 {
3779 case 0:
3780 return "#";
3781 case 1:
3782 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783 return "fstp%z0\t%y0";
3784 else
3785 return "fst%z0\t%y0";
3786 default:
3787 abort ();
3788 }
3789}
3790 [(set_attr "type" "ssecvt,fmov")
3791 (set_attr "mode" "DF,SF")])
3792
3793(define_insn "*truncdfsf2_3"
3794 [(set (match_operand:SF 0 "memory_operand" "=m")
3795 (float_truncate:SF
3796 (match_operand:DF 1 "register_operand" "f")))]
3797 "TARGET_80387"
3798{
3799 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3800 return "fstp%z0\t%y0";
3801 else
3802 return "fst%z0\t%y0";
3803}
3804 [(set_attr "type" "fmov")
3805 (set_attr "mode" "SF")])
3806
3807(define_insn "truncdfsf2_sse_only"
3808 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3809 (float_truncate:SF
3810 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3811 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3812 "cvtsd2ss\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "ssecvt")
3814 (set_attr "athlon_decode" "vector,double")
3815 (set_attr "mode" "SF")])
3816
3817(define_insn "*truncdfsf2_sse_only_nooverlap"
3818 [(set (match_operand:SF 0 "register_operand" "=&Y")
3819 (float_truncate:SF
3820 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3821 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3822 "#"
3823 [(set_attr "type" "ssecvt")
3824 (set_attr "mode" "DF")])
3825
3826(define_split
3827 [(set (match_operand:SF 0 "memory_operand" "")
3828 (float_truncate:SF
3829 (match_operand:DF 1 "register_operand" "")))
3830 (clobber (match_operand:SF 2 "memory_operand" ""))]
3831 "TARGET_80387"
3832 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3833 "")
3834
3835; Avoid possible reformatting penalty on the destination by first
3836; zeroing it out
3837(define_split
3838 [(set (match_operand:SF 0 "register_operand" "")
3839 (float_truncate:SF
3840 (match_operand:DF 1 "nonimmediate_operand" "")))
3841 (clobber (match_operand 2 "" ""))]
3842 "TARGET_80387 && reload_completed
3843 && SSE_REG_P (operands[0])
3844 && !STACK_REG_P (operands[1])"
3845 [(const_int 0)]
3846{
3847 rtx src, dest;
3848 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3849 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3850 else
3851 {
3852 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3853 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3854 /* simplify_gen_subreg refuses to widen memory references. */
3855 if (GET_CODE (src) == SUBREG)
3856 alter_subreg (&src);
3857 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3858 abort ();
3859 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3860 emit_insn (gen_cvtsd2ss (dest, dest, src));
3861 }
3862 DONE;
3863})
3864
3865(define_split
3866 [(set (match_operand:SF 0 "register_operand" "")
3867 (float_truncate:SF
3868 (match_operand:DF 1 "nonimmediate_operand" "")))]
3869 "TARGET_80387 && reload_completed
3870 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3871 [(const_int 0)]
3872{
3873 rtx src, dest;
3874 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3875 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3876 /* simplify_gen_subreg refuses to widen memory references. */
3877 if (GET_CODE (src) == SUBREG)
3878 alter_subreg (&src);
3879 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3880 abort ();
3881 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3882 emit_insn (gen_cvtsd2ss (dest, dest, src));
3883 DONE;
3884})
3885
3886(define_split
3887 [(set (match_operand:SF 0 "register_operand" "")
3888 (float_truncate:SF
3889 (match_operand:DF 1 "fp_register_operand" "")))
3890 (clobber (match_operand:SF 2 "memory_operand" ""))]
3891 "TARGET_80387 && reload_completed"
3892 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3893 (set (match_dup 0) (match_dup 2))]
3894 "")
3895
3896(define_expand "truncxfsf2"
3897 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3898 (float_truncate:SF
3899 (match_operand:XF 1 "register_operand" "")))
3900 (clobber (match_dup 2))])]
3901 "TARGET_80387"
3902 "operands[2] = assign_386_stack_local (SFmode, 0);")
3903
3904(define_insn "*truncxfsf2_1"
3905 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3906 (float_truncate:SF
3907 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3908 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3909 "TARGET_80387"
3910{
3911 switch (which_alternative)
3912 {
3913 case 0:
3914 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3915 return "fstp%z0\t%y0";
3916 else
3917 return "fst%z0\t%y0";
3918 default:
3919 abort();
3920 }
3921}
3922 [(set_attr "type" "fmov,multi,multi,multi")
3923 (set_attr "mode" "SF")])
3924
3925(define_insn "*truncxfsf2_2"
3926 [(set (match_operand:SF 0 "memory_operand" "=m")
3927 (float_truncate:SF
3928 (match_operand:XF 1 "register_operand" "f")))]
3929 "TARGET_80387"
3930{
3931 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3932 return "fstp%z0\t%y0";
3933 else
3934 return "fst%z0\t%y0";
3935}
3936 [(set_attr "type" "fmov")
3937 (set_attr "mode" "SF")])
3938
3939(define_split
3940 [(set (match_operand:SF 0 "memory_operand" "")
3941 (float_truncate:SF
3942 (match_operand:XF 1 "register_operand" "")))
3943 (clobber (match_operand:SF 2 "memory_operand" ""))]
3944 "TARGET_80387"
3945 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3946 "")
3947
3948(define_split
3949 [(set (match_operand:SF 0 "register_operand" "")
3950 (float_truncate:SF
3951 (match_operand:XF 1 "register_operand" "")))
3952 (clobber (match_operand:SF 2 "memory_operand" ""))]
3953 "TARGET_80387 && reload_completed"
3954 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3955 (set (match_dup 0) (match_dup 2))]
3956 "")
3957
3958(define_expand "truncxfdf2"
3959 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3960 (float_truncate:DF
3961 (match_operand:XF 1 "register_operand" "")))
3962 (clobber (match_dup 2))])]
3963 "TARGET_80387"
3964 "operands[2] = assign_386_stack_local (DFmode, 0);")
3965
3966(define_insn "*truncxfdf2_1"
3967 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3968 (float_truncate:DF
3969 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971 "TARGET_80387"
3972{
3973 switch (which_alternative)
3974 {
3975 case 0:
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3978 else
3979 return "fst%z0\t%y0";
3980 default:
3981 abort();
3982 }
3983 abort ();
3984}
3985 [(set_attr "type" "fmov,multi,multi,multi")
3986 (set_attr "mode" "DF")])
3987
3988(define_insn "*truncxfdf2_2"
3989 [(set (match_operand:DF 0 "memory_operand" "=m")
3990 (float_truncate:DF
3991 (match_operand:XF 1 "register_operand" "f")))]
3992 "TARGET_80387"
3993{
3994 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3995 return "fstp%z0\t%y0";
3996 else
3997 return "fst%z0\t%y0";
3998}
3999 [(set_attr "type" "fmov")
4000 (set_attr "mode" "DF")])
4001
4002(define_split
4003 [(set (match_operand:DF 0 "memory_operand" "")
4004 (float_truncate:DF
4005 (match_operand:XF 1 "register_operand" "")))
4006 (clobber (match_operand:DF 2 "memory_operand" ""))]
4007 "TARGET_80387"
4008 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4009 "")
4010
4011(define_split
4012 [(set (match_operand:DF 0 "register_operand" "")
4013 (float_truncate:DF
4014 (match_operand:XF 1 "register_operand" "")))
4015 (clobber (match_operand:DF 2 "memory_operand" ""))]
4016 "TARGET_80387 && reload_completed"
4017 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4018 (set (match_dup 0) (match_dup 2))]
4019 "")
4020
4021
4022;; %%% Break up all these bad boys.
4023
4024;; Signed conversion to DImode.
4025
4026(define_expand "fix_truncxfdi2"
4027 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4029 "TARGET_80387"
4030 "")
4031
4032(define_expand "fix_truncdfdi2"
4033 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4034 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4035 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4036{
4037 if (TARGET_64BIT && TARGET_SSE2)
4038 {
4039 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4040 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4041 if (out != operands[0])
4042 emit_move_insn (operands[0], out);
4043 DONE;
4044 }
4045})
4046
4047(define_expand "fix_truncsfdi2"
4048 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4049 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4050 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4051{
4052 if (TARGET_SSE && TARGET_64BIT)
4053 {
4054 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4055 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4056 if (out != operands[0])
4057 emit_move_insn (operands[0], out);
4058 DONE;
4059 }
4060})
4061
4062;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4063;; of the machinery.
4064(define_insn_and_split "*fix_truncdi_1"
4065 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4066 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4067 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4068 && !reload_completed && !reload_in_progress
4069 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4070 "#"
4071 "&& 1"
4072 [(const_int 0)]
4073{
4074 ix86_optimize_mode_switching = 1;
4075 operands[2] = assign_386_stack_local (HImode, 1);
4076 operands[3] = assign_386_stack_local (HImode, 2);
4077 if (memory_operand (operands[0], VOIDmode))
4078 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4079 operands[2], operands[3]));
4080 else
4081 {
4082 operands[4] = assign_386_stack_local (DImode, 0);
4083 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4084 operands[2], operands[3],
4085 operands[4]));
4086 }
4087 DONE;
4088}
4089 [(set_attr "type" "fistp")
4090 (set_attr "mode" "DI")])
4091
4092(define_insn "fix_truncdi_nomemory"
4093 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4094 (fix:DI (match_operand 1 "register_operand" "f,f")))
4095 (use (match_operand:HI 2 "memory_operand" "m,m"))
4096 (use (match_operand:HI 3 "memory_operand" "m,m"))
4097 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4098 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4099 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4100 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4101 "#"
4102 [(set_attr "type" "fistp")
4103 (set_attr "mode" "DI")])
4104
4105(define_insn "fix_truncdi_memory"
4106 [(set (match_operand:DI 0 "memory_operand" "=m")
4107 (fix:DI (match_operand 1 "register_operand" "f")))
4108 (use (match_operand:HI 2 "memory_operand" "m"))
4109 (use (match_operand:HI 3 "memory_operand" "m"))
4110 (clobber (match_scratch:DF 4 "=&1f"))]
4111 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4112 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4113 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4114 [(set_attr "type" "fistp")
4115 (set_attr "mode" "DI")])
4116
4117(define_split
4118 [(set (match_operand:DI 0 "register_operand" "")
4119 (fix:DI (match_operand 1 "register_operand" "")))
4120 (use (match_operand:HI 2 "memory_operand" ""))
4121 (use (match_operand:HI 3 "memory_operand" ""))
4122 (clobber (match_operand:DI 4 "memory_operand" ""))
4123 (clobber (match_scratch 5 ""))]
4124 "reload_completed"
4125 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4126 (use (match_dup 2))
4127 (use (match_dup 3))
4128 (clobber (match_dup 5))])
4129 (set (match_dup 0) (match_dup 4))]
4130 "")
4131
4132(define_split
4133 [(set (match_operand:DI 0 "memory_operand" "")
4134 (fix:DI (match_operand 1 "register_operand" "")))
4135 (use (match_operand:HI 2 "memory_operand" ""))
4136 (use (match_operand:HI 3 "memory_operand" ""))
4137 (clobber (match_operand:DI 4 "memory_operand" ""))
4138 (clobber (match_scratch 5 ""))]
4139 "reload_completed"
4140 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4141 (use (match_dup 2))
4142 (use (match_dup 3))
4143 (clobber (match_dup 5))])]
4144 "")
4145
4146;; When SSE available, it is always faster to use it!
4147(define_insn "fix_truncsfdi_sse"
4148 [(set (match_operand:DI 0 "register_operand" "=r,r")
4149 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4150 "TARGET_64BIT && TARGET_SSE"
4151 "cvttss2si{q}\t{%1, %0|%0, %1}"
4152 [(set_attr "type" "sseicvt")
4153 (set_attr "mode" "SF")
4154 (set_attr "athlon_decode" "double,vector")])
4155
4156;; Avoid vector decoded form of the instruction.
4157(define_peephole2
4158 [(match_scratch:SF 2 "x")
4159 (set (match_operand:DI 0 "register_operand" "")
4160 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4161 "TARGET_K8 && !optimize_size"
4162 [(set (match_dup 2) (match_dup 1))
4163 (set (match_dup 0) (fix:DI (match_dup 2)))]
4164 "")
4165
4166(define_insn "fix_truncdfdi_sse"
4167 [(set (match_operand:DI 0 "register_operand" "=r,r")
4168 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4169 "TARGET_64BIT && TARGET_SSE2"
4170 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4171 [(set_attr "type" "sseicvt,sseicvt")
4172 (set_attr "mode" "DF")
4173 (set_attr "athlon_decode" "double,vector")])
4174
4175;; Avoid vector decoded form of the instruction.
4176(define_peephole2
4177 [(match_scratch:DF 2 "Y")
4178 (set (match_operand:DI 0 "register_operand" "")
4179 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4180 "TARGET_K8 && !optimize_size"
4181 [(set (match_dup 2) (match_dup 1))
4182 (set (match_dup 0) (fix:DI (match_dup 2)))]
4183 "")
4184
4185;; Signed conversion to SImode.
4186
4187(define_expand "fix_truncxfsi2"
4188 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4189 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4190 "TARGET_80387"
4191 "")
4192
4193(define_expand "fix_truncdfsi2"
4194 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4195 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4196 "TARGET_80387 || TARGET_SSE2"
4197{
4198 if (TARGET_SSE2)
4199 {
4200 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4201 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4202 if (out != operands[0])
4203 emit_move_insn (operands[0], out);
4204 DONE;
4205 }
4206})
4207
4208(define_expand "fix_truncsfsi2"
4209 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4210 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4211 "TARGET_80387 || TARGET_SSE"
4212{
4213 if (TARGET_SSE)
4214 {
4215 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4216 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4217 if (out != operands[0])
4218 emit_move_insn (operands[0], out);
4219 DONE;
4220 }
4221})
4222
4223;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4224;; of the machinery.
4225(define_insn_and_split "*fix_truncsi_1"
4226 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4227 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4228 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4229 && !reload_completed && !reload_in_progress
4230 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4231 "#"
4232 "&& 1"
4233 [(const_int 0)]
4234{
4235 ix86_optimize_mode_switching = 1;
4236 operands[2] = assign_386_stack_local (HImode, 1);
4237 operands[3] = assign_386_stack_local (HImode, 2);
4238 if (memory_operand (operands[0], VOIDmode))
4239 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4240 operands[2], operands[3]));
4241 else
4242 {
4243 operands[4] = assign_386_stack_local (SImode, 0);
4244 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4245 operands[2], operands[3],
4246 operands[4]));
4247 }
4248 DONE;
4249}
4250 [(set_attr "type" "fistp")
4251 (set_attr "mode" "SI")])
4252
4253(define_insn "fix_truncsi_nomemory"
4254 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4255 (fix:SI (match_operand 1 "register_operand" "f,f")))
4256 (use (match_operand:HI 2 "memory_operand" "m,m"))
4257 (use (match_operand:HI 3 "memory_operand" "m,m"))
4258 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4259 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4260 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4261 "#"
4262 [(set_attr "type" "fistp")
4263 (set_attr "mode" "SI")])
4264
4265(define_insn "fix_truncsi_memory"
4266 [(set (match_operand:SI 0 "memory_operand" "=m")
4267 (fix:SI (match_operand 1 "register_operand" "f")))
4268 (use (match_operand:HI 2 "memory_operand" "m"))
4269 (use (match_operand:HI 3 "memory_operand" "m"))]
4270 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4271 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4272 "* return output_fix_trunc (insn, operands);"
4273 [(set_attr "type" "fistp")
4274 (set_attr "mode" "SI")])
4275
4276;; When SSE available, it is always faster to use it!
4277(define_insn "fix_truncsfsi_sse"
4278 [(set (match_operand:SI 0 "register_operand" "=r,r")
4279 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4280 "TARGET_SSE"
4281 "cvttss2si\t{%1, %0|%0, %1}"
4282 [(set_attr "type" "sseicvt")
4283 (set_attr "mode" "DF")
4284 (set_attr "athlon_decode" "double,vector")])
4285
4286;; Avoid vector decoded form of the instruction.
4287(define_peephole2
4288 [(match_scratch:SF 2 "x")
4289 (set (match_operand:SI 0 "register_operand" "")
4290 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4291 "TARGET_K8 && !optimize_size"
4292 [(set (match_dup 2) (match_dup 1))
4293 (set (match_dup 0) (fix:SI (match_dup 2)))]
4294 "")
4295
4296(define_insn "fix_truncdfsi_sse"
4297 [(set (match_operand:SI 0 "register_operand" "=r,r")
4298 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4299 "TARGET_SSE2"
4300 "cvttsd2si\t{%1, %0|%0, %1}"
4301 [(set_attr "type" "sseicvt")
4302 (set_attr "mode" "DF")
4303 (set_attr "athlon_decode" "double,vector")])
4304
4305;; Avoid vector decoded form of the instruction.
4306(define_peephole2
4307 [(match_scratch:DF 2 "Y")
4308 (set (match_operand:SI 0 "register_operand" "")
4309 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4310 "TARGET_K8 && !optimize_size"
4311 [(set (match_dup 2) (match_dup 1))
4312 (set (match_dup 0) (fix:SI (match_dup 2)))]
4313 "")
4314
4315(define_split
4316 [(set (match_operand:SI 0 "register_operand" "")
4317 (fix:SI (match_operand 1 "register_operand" "")))
4318 (use (match_operand:HI 2 "memory_operand" ""))
4319 (use (match_operand:HI 3 "memory_operand" ""))
4320 (clobber (match_operand:SI 4 "memory_operand" ""))]
4321 "reload_completed"
4322 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4323 (use (match_dup 2))
4324 (use (match_dup 3))])
4325 (set (match_dup 0) (match_dup 4))]
4326 "")
4327
4328(define_split
4329 [(set (match_operand:SI 0 "memory_operand" "")
4330 (fix:SI (match_operand 1 "register_operand" "")))
4331 (use (match_operand:HI 2 "memory_operand" ""))
4332 (use (match_operand:HI 3 "memory_operand" ""))
4333 (clobber (match_operand:SI 4 "memory_operand" ""))]
4334 "reload_completed"
4335 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4336 (use (match_dup 2))
4337 (use (match_dup 3))])]
4338 "")
4339
4340;; Signed conversion to HImode.
4341
4342(define_expand "fix_truncxfhi2"
4343 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4344 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4345 "TARGET_80387"
4346 "")
4347
4348(define_expand "fix_truncdfhi2"
4349 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4350 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4351 "TARGET_80387 && !TARGET_SSE2"
4352 "")
4353
4354(define_expand "fix_truncsfhi2"
4355 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4356 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4357 "TARGET_80387 && !TARGET_SSE"
4358 "")
4359
4360;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4361;; of the machinery.
4362(define_insn_and_split "*fix_trunchi_1"
4363 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4364 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4365 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4366 && !reload_completed && !reload_in_progress
4367 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4368 "#"
4369 ""
4370 [(const_int 0)]
4371{
4372 ix86_optimize_mode_switching = 1;
4373 operands[2] = assign_386_stack_local (HImode, 1);
4374 operands[3] = assign_386_stack_local (HImode, 2);
4375 if (memory_operand (operands[0], VOIDmode))
4376 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4377 operands[2], operands[3]));
4378 else
4379 {
4380 operands[4] = assign_386_stack_local (HImode, 0);
4381 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4382 operands[2], operands[3],
4383 operands[4]));
4384 }
4385 DONE;
4386}
4387 [(set_attr "type" "fistp")
4388 (set_attr "mode" "HI")])
4389
4390(define_insn "fix_trunchi_nomemory"
4391 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4392 (fix:HI (match_operand 1 "register_operand" "f,f")))
4393 (use (match_operand:HI 2 "memory_operand" "m,m"))
4394 (use (match_operand:HI 3 "memory_operand" "m,m"))
4395 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4396 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4397 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4398 "#"
4399 [(set_attr "type" "fistp")
4400 (set_attr "mode" "HI")])
4401
4402(define_insn "fix_trunchi_memory"
4403 [(set (match_operand:HI 0 "memory_operand" "=m")
4404 (fix:HI (match_operand 1 "register_operand" "f")))
4405 (use (match_operand:HI 2 "memory_operand" "m"))
4406 (use (match_operand:HI 3 "memory_operand" "m"))]
4407 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4408 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4409 "* return output_fix_trunc (insn, operands);"
4410 [(set_attr "type" "fistp")
4411 (set_attr "mode" "HI")])
4412
4413(define_split
4414 [(set (match_operand:HI 0 "memory_operand" "")
4415 (fix:HI (match_operand 1 "register_operand" "")))
4416 (use (match_operand:HI 2 "memory_operand" ""))
4417 (use (match_operand:HI 3 "memory_operand" ""))
4418 (clobber (match_operand:HI 4 "memory_operand" ""))]
4419 "reload_completed"
4420 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4421 (use (match_dup 2))
4422 (use (match_dup 3))])]
4423 "")
4424
4425(define_split
4426 [(set (match_operand:HI 0 "register_operand" "")
4427 (fix:HI (match_operand 1 "register_operand" "")))
4428 (use (match_operand:HI 2 "memory_operand" ""))
4429 (use (match_operand:HI 3 "memory_operand" ""))
4430 (clobber (match_operand:HI 4 "memory_operand" ""))]
4431 "reload_completed"
4432 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4433 (use (match_dup 2))
4434 (use (match_dup 3))
4435 (clobber (match_dup 4))])
4436 (set (match_dup 0) (match_dup 4))]
4437 "")
4438
4439;; %% Not used yet.
4440(define_insn "x86_fnstcw_1"
4441 [(set (match_operand:HI 0 "memory_operand" "=m")
4442 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4443 "TARGET_80387"
4444 "fnstcw\t%0"
4445 [(set_attr "length" "2")
4446 (set_attr "mode" "HI")
4447 (set_attr "unit" "i387")
4448 (set_attr "ppro_uops" "few")])
4449
4450(define_insn "x86_fldcw_1"
4451 [(set (reg:HI 18)
4452 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4453 "TARGET_80387"
4454 "fldcw\t%0"
4455 [(set_attr "length" "2")
4456 (set_attr "mode" "HI")
4457 (set_attr "unit" "i387")
4458 (set_attr "athlon_decode" "vector")
4459 (set_attr "ppro_uops" "few")])
4460
4461;; Conversion between fixed point and floating point.
4462
4463;; Even though we only accept memory inputs, the backend _really_
4464;; wants to be able to do this between registers.
4465
4466(define_expand "floathisf2"
4467 [(set (match_operand:SF 0 "register_operand" "")
4468 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4469 "TARGET_SSE || TARGET_80387"
4470{
4471 if (TARGET_SSE && TARGET_SSE_MATH)
4472 {
4473 emit_insn (gen_floatsisf2 (operands[0],
4474 convert_to_mode (SImode, operands[1], 0)));
4475 DONE;
4476 }
4477})
4478
4479(define_insn "*floathisf2_1"
4480 [(set (match_operand:SF 0 "register_operand" "=f,f")
4481 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4482 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4483 "@
4484 fild%z1\t%1
4485 #"
4486 [(set_attr "type" "fmov,multi")
4487 (set_attr "mode" "SF")
4488 (set_attr "fp_int_src" "true")])
4489
4490(define_expand "floatsisf2"
4491 [(set (match_operand:SF 0 "register_operand" "")
4492 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4493 "TARGET_SSE || TARGET_80387"
4494 "")
4495
4496(define_insn "*floatsisf2_i387"
4497 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4498 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4499 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4500 "@
4501 fild%z1\t%1
4502 #
4503 cvtsi2ss\t{%1, %0|%0, %1}
4504 cvtsi2ss\t{%1, %0|%0, %1}"
4505 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4506 (set_attr "mode" "SF")
4507 (set_attr "athlon_decode" "*,*,vector,double")
4508 (set_attr "fp_int_src" "true")])
4509
4510(define_insn "*floatsisf2_sse"
4511 [(set (match_operand:SF 0 "register_operand" "=x,x")
4512 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4513 "TARGET_SSE"
4514 "cvtsi2ss\t{%1, %0|%0, %1}"
4515 [(set_attr "type" "sseicvt")
4516 (set_attr "mode" "SF")
4517 (set_attr "athlon_decode" "vector,double")
4518 (set_attr "fp_int_src" "true")])
4519
4520; Avoid possible reformatting penalty on the destination by first
4521; zeroing it out
4522(define_split
4523 [(set (match_operand:SF 0 "register_operand" "")
4524 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4526 && SSE_REG_P (operands[0])"
4527 [(const_int 0)]
4528{
4529 rtx dest;
4530 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4531 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4532 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4533 DONE;
4534})
4535
4536(define_expand "floatdisf2"
4537 [(set (match_operand:SF 0 "register_operand" "")
4538 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4539 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4540 "")
4541
4542(define_insn "*floatdisf2_i387_only"
4543 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4544 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4545 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4546 "@
4547 fild%z1\t%1
4548 #"
4549 [(set_attr "type" "fmov,multi")
4550 (set_attr "mode" "SF")
4551 (set_attr "fp_int_src" "true")])
4552
4553(define_insn "*floatdisf2_i387"
4554 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4555 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4556 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4557 "@
4558 fild%z1\t%1
4559 #
4560 cvtsi2ss{q}\t{%1, %0|%0, %1}
4561 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4563 (set_attr "mode" "SF")
4564 (set_attr "athlon_decode" "*,*,vector,double")
4565 (set_attr "fp_int_src" "true")])
4566
4567(define_insn "*floatdisf2_sse"
4568 [(set (match_operand:SF 0 "register_operand" "=x,x")
4569 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4570 "TARGET_64BIT && TARGET_SSE"
4571 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4572 [(set_attr "type" "sseicvt")
4573 (set_attr "mode" "SF")
4574 (set_attr "athlon_decode" "vector,double")
4575 (set_attr "fp_int_src" "true")])
4576
4577; Avoid possible reformatting penalty on the destination by first
4578; zeroing it out
4579(define_split
4580 [(set (match_operand:SF 0 "register_operand" "")
4581 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4582 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4583 && SSE_REG_P (operands[0])"
4584 [(const_int 0)]
4585{
4586 rtx dest;
4587 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4588 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4589 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4590 DONE;
4591})
4592
4593(define_expand "floathidf2"
4594 [(set (match_operand:DF 0 "register_operand" "")
4595 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4596 "TARGET_SSE2 || TARGET_80387"
4597{
4598 if (TARGET_SSE && TARGET_SSE_MATH)
4599 {
4600 emit_insn (gen_floatsidf2 (operands[0],
4601 convert_to_mode (SImode, operands[1], 0)));
4602 DONE;
4603 }
4604})
4605
4606(define_insn "*floathidf2_1"
4607 [(set (match_operand:DF 0 "register_operand" "=f,f")
4608 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4609 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4610 "@
4611 fild%z1\t%1
4612 #"
4613 [(set_attr "type" "fmov,multi")
4614 (set_attr "mode" "DF")
4615 (set_attr "fp_int_src" "true")])
4616
4617(define_expand "floatsidf2"
4618 [(set (match_operand:DF 0 "register_operand" "")
4619 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4620 "TARGET_80387 || TARGET_SSE2"
4621 "")
4622
4623(define_insn "*floatsidf2_i387"
4624 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4625 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4626 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4627 "@
4628 fild%z1\t%1
4629 #
4630 cvtsi2sd\t{%1, %0|%0, %1}
4631 cvtsi2sd\t{%1, %0|%0, %1}"
4632 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4633 (set_attr "mode" "DF")
4634 (set_attr "athlon_decode" "*,*,double,direct")
4635 (set_attr "fp_int_src" "true")])
4636
4637(define_insn "*floatsidf2_sse"
4638 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4639 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4640 "TARGET_SSE2"
4641 "cvtsi2sd\t{%1, %0|%0, %1}"
4642 [(set_attr "type" "sseicvt")
4643 (set_attr "mode" "DF")
4644 (set_attr "athlon_decode" "double,direct")
4645 (set_attr "fp_int_src" "true")])
4646
4647(define_expand "floatdidf2"
4648 [(set (match_operand:DF 0 "register_operand" "")
4649 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4650 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4651 "")
4652
4653(define_insn "*floatdidf2_i387_only"
4654 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4655 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4656 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4657 "@
4658 fild%z1\t%1
4659 #"
4660 [(set_attr "type" "fmov,multi")
4661 (set_attr "mode" "DF")
4662 (set_attr "fp_int_src" "true")])
4663
4664(define_insn "*floatdidf2_i387"
4665 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4666 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4667 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4668 "@
4669 fild%z1\t%1
4670 #
4671 cvtsi2sd{q}\t{%1, %0|%0, %1}
4672 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4674 (set_attr "mode" "DF")
4675 (set_attr "athlon_decode" "*,*,double,direct")
4676 (set_attr "fp_int_src" "true")])
4677
4678(define_insn "*floatdidf2_sse"
4679 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4680 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4681 "TARGET_SSE2"
4682 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4683 [(set_attr "type" "sseicvt")
4684 (set_attr "mode" "DF")
4685 (set_attr "athlon_decode" "double,direct")
4686 (set_attr "fp_int_src" "true")])
4687
4688(define_insn "floathixf2"
4689 [(set (match_operand:XF 0 "register_operand" "=f,f")
4690 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4691 "TARGET_80387"
4692 "@
4693 fild%z1\t%1
4694 #"
4695 [(set_attr "type" "fmov,multi")
4696 (set_attr "mode" "XF")
4697 (set_attr "fp_int_src" "true")])
4698
4699(define_insn "floatsixf2"
4700 [(set (match_operand:XF 0 "register_operand" "=f,f")
4701 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4702 "TARGET_80387"
4703 "@
4704 fild%z1\t%1
4705 #"
4706 [(set_attr "type" "fmov,multi")
4707 (set_attr "mode" "XF")
4708 (set_attr "fp_int_src" "true")])
4709
4710(define_insn "floatdixf2"
4711 [(set (match_operand:XF 0 "register_operand" "=f,f")
4712 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4713 "TARGET_80387"
4714 "@
4715 fild%z1\t%1
4716 #"
4717 [(set_attr "type" "fmov,multi")
4718 (set_attr "mode" "XF")
4719 (set_attr "fp_int_src" "true")])
4720
4721;; %%% Kill these when reload knows how to do it.
4722(define_split
4723 [(set (match_operand 0 "fp_register_operand" "")
4724 (float (match_operand 1 "register_operand" "")))]
4725 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4726 [(const_int 0)]
4727{
4728 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4729 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4730 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4731 ix86_free_from_memory (GET_MODE (operands[1]));
4732 DONE;
4733})
4734
4735(define_expand "floatunssisf2"
4736 [(use (match_operand:SF 0 "register_operand" ""))
4737 (use (match_operand:SI 1 "register_operand" ""))]
4738 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4739 "x86_emit_floatuns (operands); DONE;")
4740
4741(define_expand "floatunsdisf2"
4742 [(use (match_operand:SF 0 "register_operand" ""))
4743 (use (match_operand:DI 1 "register_operand" ""))]
4744 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4745 "x86_emit_floatuns (operands); DONE;")
4746
4747(define_expand "floatunsdidf2"
4748 [(use (match_operand:DF 0 "register_operand" ""))
4749 (use (match_operand:DI 1 "register_operand" ""))]
4750 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4751 "x86_emit_floatuns (operands); DONE;")
4752
4753;; SSE extract/set expanders
4754
4755(define_expand "vec_setv2df"
4756 [(match_operand:V2DF 0 "register_operand" "")
4757 (match_operand:DF 1 "register_operand" "")
4758 (match_operand 2 "const_int_operand" "")]
4759 "TARGET_SSE2"
4760{
4761 switch (INTVAL (operands[2]))
4762 {
4763 case 0:
4764 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4765 simplify_gen_subreg (V2DFmode, operands[1],
4766 DFmode, 0)));
4767 break;
4768 case 1:
4769 {
4770 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4771
4772 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4773 }
4774 break;
4775 default:
4776 abort ();
4777 }
4778 DONE;
4779})
4780
4781(define_expand "vec_extractv2df"
4782 [(match_operand:DF 0 "register_operand" "")
4783 (match_operand:V2DF 1 "register_operand" "")
4784 (match_operand 2 "const_int_operand" "")]
4785 "TARGET_SSE2"
4786{
4787 switch (INTVAL (operands[2]))
4788 {
4789 case 0:
4790 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4791 break;
4792 case 1:
4793 {
4794 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4795
4796 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4797 }
4798 break;
4799 default:
4800 abort ();
4801 }
4802 DONE;
4803})
4804
4805(define_expand "vec_initv2df"
4806 [(match_operand:V2DF 0 "register_operand" "")
4807 (match_operand 1 "" "")]
4808 "TARGET_SSE2"
4809{
4810 ix86_expand_vector_init (operands[0], operands[1]);
4811 DONE;
4812})
4813
4814(define_expand "vec_setv4sf"
4815 [(match_operand:V4SF 0 "register_operand" "")
4816 (match_operand:SF 1 "register_operand" "")
4817 (match_operand 2 "const_int_operand" "")]
4818 "TARGET_SSE"
4819{
4820 switch (INTVAL (operands[2]))
4821 {
4822 case 0:
4823 emit_insn (gen_sse_movss (operands[0], operands[0],
4824 simplify_gen_subreg (V4SFmode, operands[1],
4825 SFmode, 0)));
4826 break;
4827 case 1:
4828 {
4829 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4830 rtx tmp = gen_reg_rtx (V4SFmode);
4831
4832 emit_move_insn (tmp, operands[0]);
4833 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4834 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4835 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4836 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4837 }
4838 case 2:
4839 {
4840 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4841 rtx tmp = gen_reg_rtx (V4SFmode);
4842
4843 emit_move_insn (tmp, operands[0]);
4844 emit_insn (gen_sse_movss (tmp, tmp, op1));
4845 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4846 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4847 }
4848 break;
4849 case 3:
4850 {
4851 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4852 rtx tmp = gen_reg_rtx (V4SFmode);
4853
4854 emit_move_insn (tmp, operands[0]);
4855 emit_insn (gen_sse_movss (tmp, tmp, op1));
4856 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4857 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4858 }
4859 break;
4860 default:
4861 abort ();
4862 }
4863 DONE;
4864})
4865
4866(define_expand "vec_extractv4sf"
4867 [(match_operand:SF 0 "register_operand" "")
4868 (match_operand:V4SF 1 "register_operand" "")
4869 (match_operand 2 "const_int_operand" "")]
4870 "TARGET_SSE"
4871{
4872 switch (INTVAL (operands[2]))
4873 {
4874 case 0:
4875 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4876 break;
4877 case 1:
4878 {
4879 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4880 rtx tmp = gen_reg_rtx (V4SFmode);
4881
4882 emit_move_insn (tmp, operands[1]);
4883 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4884 GEN_INT (1)));
4885 }
4886 case 2:
4887 {
4888 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4889 rtx tmp = gen_reg_rtx (V4SFmode);
4890
4891 emit_move_insn (tmp, operands[1]);
4892 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4893 }
4894 case 3:
4895 {
4896 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4897 rtx tmp = gen_reg_rtx (V4SFmode);
4898
4899 emit_move_insn (tmp, operands[1]);
4900 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4901 GEN_INT (3)));
4902 }
4903 default:
4904 abort ();
4905 }
4906 DONE;
4907})
4908
4909(define_expand "vec_initv4sf"
4910 [(match_operand:V4SF 0 "register_operand" "")
4911 (match_operand 1 "" "")]
4912 "TARGET_SSE"
4913{
4914 ix86_expand_vector_init (operands[0], operands[1]);
4915 DONE;
4916})
4917
4918;; Add instructions
4919
4920;; %%% splits for addsidi3
4921; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4922; (plus:DI (match_operand:DI 1 "general_operand" "")
4923; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4924
4925(define_expand "adddi3"
4926 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4927 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4928 (match_operand:DI 2 "x86_64_general_operand" "")))
4929 (clobber (reg:CC 17))]
4930 ""
4931 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4932
4933(define_insn "*adddi3_1"
4934 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4935 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4936 (match_operand:DI 2 "general_operand" "roiF,riF")))
4937 (clobber (reg:CC 17))]
4938 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4939 "#")
4940
4941(define_split
4942 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4943 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4944 (match_operand:DI 2 "general_operand" "")))
4945 (clobber (reg:CC 17))]
4946 "!TARGET_64BIT && reload_completed"
4947 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4948 UNSPEC_ADD_CARRY))
4949 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4950 (parallel [(set (match_dup 3)
4951 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4952 (match_dup 4))
4953 (match_dup 5)))
4954 (clobber (reg:CC 17))])]
4955 "split_di (operands+0, 1, operands+0, operands+3);
4956 split_di (operands+1, 1, operands+1, operands+4);
4957 split_di (operands+2, 1, operands+2, operands+5);")
4958
4959(define_insn "adddi3_carry_rex64"
4960 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4961 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4962 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4963 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4964 (clobber (reg:CC 17))]
4965 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4966 "adc{q}\t{%2, %0|%0, %2}"
4967 [(set_attr "type" "alu")
4968 (set_attr "pent_pair" "pu")
4969 (set_attr "mode" "DI")
4970 (set_attr "ppro_uops" "few")])
4971
4972(define_insn "*adddi3_cc_rex64"
4973 [(set (reg:CC 17)
4974 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4975 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4976 UNSPEC_ADD_CARRY))
4977 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4978 (plus:DI (match_dup 1) (match_dup 2)))]
4979 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4980 "add{q}\t{%2, %0|%0, %2}"
4981 [(set_attr "type" "alu")
4982 (set_attr "mode" "DI")])
4983
4984(define_insn "addqi3_carry"
4985 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4986 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4987 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4988 (match_operand:QI 2 "general_operand" "qi,qm")))
4989 (clobber (reg:CC 17))]
4990 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4991 "adc{b}\t{%2, %0|%0, %2}"
4992 [(set_attr "type" "alu")
4993 (set_attr "pent_pair" "pu")
4994 (set_attr "mode" "QI")
4995 (set_attr "ppro_uops" "few")])
4996
4997(define_insn "addhi3_carry"
4998 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4999 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5000 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5001 (match_operand:HI 2 "general_operand" "ri,rm")))
5002 (clobber (reg:CC 17))]
5003 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5004 "adc{w}\t{%2, %0|%0, %2}"
5005 [(set_attr "type" "alu")
5006 (set_attr "pent_pair" "pu")
5007 (set_attr "mode" "HI")
5008 (set_attr "ppro_uops" "few")])
5009
5010(define_insn "addsi3_carry"
5011 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5012 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5013 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5014 (match_operand:SI 2 "general_operand" "ri,rm")))
5015 (clobber (reg:CC 17))]
5016 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5017 "adc{l}\t{%2, %0|%0, %2}"
5018 [(set_attr "type" "alu")
5019 (set_attr "pent_pair" "pu")
5020 (set_attr "mode" "SI")
5021 (set_attr "ppro_uops" "few")])
5022
5023(define_insn "*addsi3_carry_zext"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (zero_extend:DI
5026 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5027 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5028 (match_operand:SI 2 "general_operand" "rim"))))
5029 (clobber (reg:CC 17))]
5030 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5031 "adc{l}\t{%2, %k0|%k0, %2}"
5032 [(set_attr "type" "alu")
5033 (set_attr "pent_pair" "pu")
5034 (set_attr "mode" "SI")
5035 (set_attr "ppro_uops" "few")])
5036
5037(define_insn "*addsi3_cc"
5038 [(set (reg:CC 17)
5039 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5040 (match_operand:SI 2 "general_operand" "ri,rm")]
5041 UNSPEC_ADD_CARRY))
5042 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5043 (plus:SI (match_dup 1) (match_dup 2)))]
5044 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5045 "add{l}\t{%2, %0|%0, %2}"
5046 [(set_attr "type" "alu")
5047 (set_attr "mode" "SI")])
5048
5049(define_insn "addqi3_cc"
5050 [(set (reg:CC 17)
5051 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5052 (match_operand:QI 2 "general_operand" "qi,qm")]
5053 UNSPEC_ADD_CARRY))
5054 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5055 (plus:QI (match_dup 1) (match_dup 2)))]
5056 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5057 "add{b}\t{%2, %0|%0, %2}"
5058 [(set_attr "type" "alu")
5059 (set_attr "mode" "QI")])
5060
5061(define_expand "addsi3"
5062 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5063 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5064 (match_operand:SI 2 "general_operand" "")))
5065 (clobber (reg:CC 17))])]
5066 ""
5067 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5068
5069(define_insn "*lea_1"
5070 [(set (match_operand:SI 0 "register_operand" "=r")
5071 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5072 "!TARGET_64BIT"
5073 "lea{l}\t{%a1, %0|%0, %a1}"
5074 [(set_attr "type" "lea")
5075 (set_attr "mode" "SI")])
5076
5077(define_insn "*lea_1_rex64"
5078 [(set (match_operand:SI 0 "register_operand" "=r")
5079 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5080 "TARGET_64BIT"
5081 "lea{l}\t{%a1, %0|%0, %a1}"
5082 [(set_attr "type" "lea")
5083 (set_attr "mode" "SI")])
5084
5085(define_insn "*lea_1_zext"
5086 [(set (match_operand:DI 0 "register_operand" "=r")
5087 (zero_extend:DI
5088 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5089 "TARGET_64BIT"
5090 "lea{l}\t{%a1, %k0|%k0, %a1}"
5091 [(set_attr "type" "lea")
5092 (set_attr "mode" "SI")])
5093
5094(define_insn "*lea_2_rex64"
5095 [(set (match_operand:DI 0 "register_operand" "=r")
5096 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5097 "TARGET_64BIT"
5098 "lea{q}\t{%a1, %0|%0, %a1}"
5099 [(set_attr "type" "lea")
5100 (set_attr "mode" "DI")])
5101
5102;; The lea patterns for non-Pmodes needs to be matched by several
5103;; insns converted to real lea by splitters.
5104
5105(define_insn_and_split "*lea_general_1"
5106 [(set (match_operand 0 "register_operand" "=r")
5107 (plus (plus (match_operand 1 "index_register_operand" "r")
5108 (match_operand 2 "register_operand" "r"))
5109 (match_operand 3 "immediate_operand" "i")))]
5110 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5111 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5112 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5113 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5114 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5115 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5116 || GET_MODE (operands[3]) == VOIDmode)"
5117 "#"
5118 "&& reload_completed"
5119 [(const_int 0)]
5120{
5121 rtx pat;
5122 operands[0] = gen_lowpart (SImode, operands[0]);
5123 operands[1] = gen_lowpart (Pmode, operands[1]);
5124 operands[2] = gen_lowpart (Pmode, operands[2]);
5125 operands[3] = gen_lowpart (Pmode, operands[3]);
5126 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5127 operands[3]);
5128 if (Pmode != SImode)
5129 pat = gen_rtx_SUBREG (SImode, pat, 0);
5130 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5131 DONE;
5132}
5133 [(set_attr "type" "lea")
5134 (set_attr "mode" "SI")])
5135
5136(define_insn_and_split "*lea_general_1_zext"
5137 [(set (match_operand:DI 0 "register_operand" "=r")
5138 (zero_extend:DI
5139 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5140 (match_operand:SI 2 "register_operand" "r"))
5141 (match_operand:SI 3 "immediate_operand" "i"))))]
5142 "TARGET_64BIT"
5143 "#"
5144 "&& reload_completed"
5145 [(set (match_dup 0)
5146 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5147 (match_dup 2))
5148 (match_dup 3)) 0)))]
5149{
5150 operands[1] = gen_lowpart (Pmode, operands[1]);
5151 operands[2] = gen_lowpart (Pmode, operands[2]);
5152 operands[3] = gen_lowpart (Pmode, operands[3]);
5153}
5154 [(set_attr "type" "lea")
5155 (set_attr "mode" "SI")])
5156
5157(define_insn_and_split "*lea_general_2"
5158 [(set (match_operand 0 "register_operand" "=r")
5159 (plus (mult (match_operand 1 "index_register_operand" "r")
5160 (match_operand 2 "const248_operand" "i"))
5161 (match_operand 3 "nonmemory_operand" "ri")))]
5162 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5163 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5164 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5165 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5166 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5167 || GET_MODE (operands[3]) == VOIDmode)"
5168 "#"
5169 "&& reload_completed"
5170 [(const_int 0)]
5171{
5172 rtx pat;
5173 operands[0] = gen_lowpart (SImode, operands[0]);
5174 operands[1] = gen_lowpart (Pmode, operands[1]);
5175 operands[3] = gen_lowpart (Pmode, operands[3]);
5176 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5177 operands[3]);
5178 if (Pmode != SImode)
5179 pat = gen_rtx_SUBREG (SImode, pat, 0);
5180 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5181 DONE;
5182}
5183 [(set_attr "type" "lea")
5184 (set_attr "mode" "SI")])
5185
5186(define_insn_and_split "*lea_general_2_zext"
5187 [(set (match_operand:DI 0 "register_operand" "=r")
5188 (zero_extend:DI
5189 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5190 (match_operand:SI 2 "const248_operand" "n"))
5191 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5192 "TARGET_64BIT"
5193 "#"
5194 "&& reload_completed"
5195 [(set (match_dup 0)
5196 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5197 (match_dup 2))
5198 (match_dup 3)) 0)))]
5199{
5200 operands[1] = gen_lowpart (Pmode, operands[1]);
5201 operands[3] = gen_lowpart (Pmode, operands[3]);
5202}
5203 [(set_attr "type" "lea")
5204 (set_attr "mode" "SI")])
5205
5206(define_insn_and_split "*lea_general_3"
5207 [(set (match_operand 0 "register_operand" "=r")
5208 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5209 (match_operand 2 "const248_operand" "i"))
5210 (match_operand 3 "register_operand" "r"))
5211 (match_operand 4 "immediate_operand" "i")))]
5212 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5213 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5214 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5215 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5216 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5217 "#"
5218 "&& reload_completed"
5219 [(const_int 0)]
5220{
5221 rtx pat;
5222 operands[0] = gen_lowpart (SImode, operands[0]);
5223 operands[1] = gen_lowpart (Pmode, operands[1]);
5224 operands[3] = gen_lowpart (Pmode, operands[3]);
5225 operands[4] = gen_lowpart (Pmode, operands[4]);
5226 pat = gen_rtx_PLUS (Pmode,
5227 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5228 operands[2]),
5229 operands[3]),
5230 operands[4]);
5231 if (Pmode != SImode)
5232 pat = gen_rtx_SUBREG (SImode, pat, 0);
5233 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5234 DONE;
5235}
5236 [(set_attr "type" "lea")
5237 (set_attr "mode" "SI")])
5238
5239(define_insn_and_split "*lea_general_3_zext"
5240 [(set (match_operand:DI 0 "register_operand" "=r")
5241 (zero_extend:DI
5242 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5243 (match_operand:SI 2 "const248_operand" "n"))
5244 (match_operand:SI 3 "register_operand" "r"))
5245 (match_operand:SI 4 "immediate_operand" "i"))))]
5246 "TARGET_64BIT"
5247 "#"
5248 "&& reload_completed"
5249 [(set (match_dup 0)
5250 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5251 (match_dup 2))
5252 (match_dup 3))
5253 (match_dup 4)) 0)))]
5254{
5255 operands[1] = gen_lowpart (Pmode, operands[1]);
5256 operands[3] = gen_lowpart (Pmode, operands[3]);
5257 operands[4] = gen_lowpart (Pmode, operands[4]);
5258}
5259 [(set_attr "type" "lea")
5260 (set_attr "mode" "SI")])
5261
5262(define_insn "*adddi_1_rex64"
5263 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5264 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5265 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5266 (clobber (reg:CC 17))]
5267 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5268{
5269 switch (get_attr_type (insn))
5270 {
5271 case TYPE_LEA:
5272 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5273 return "lea{q}\t{%a2, %0|%0, %a2}";
5274
5275 case TYPE_INCDEC:
5276 if (! rtx_equal_p (operands[0], operands[1]))
5277 abort ();
5278 if (operands[2] == const1_rtx)
5279 return "inc{q}\t%0";
5280 else if (operands[2] == constm1_rtx)
5281 return "dec{q}\t%0";
5282 else
5283 abort ();
5284
5285 default:
5286 if (! rtx_equal_p (operands[0], operands[1]))
5287 abort ();
5288
5289 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5290 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5291 if (GET_CODE (operands[2]) == CONST_INT
5292 /* Avoid overflows. */
5293 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5294 && (INTVAL (operands[2]) == 128
5295 || (INTVAL (operands[2]) < 0
5296 && INTVAL (operands[2]) != -128)))
5297 {
5298 operands[2] = GEN_INT (-INTVAL (operands[2]));
5299 return "sub{q}\t{%2, %0|%0, %2}";
5300 }
5301 return "add{q}\t{%2, %0|%0, %2}";
5302 }
5303}
5304 [(set (attr "type")
5305 (cond [(eq_attr "alternative" "2")
5306 (const_string "lea")
5307 ; Current assemblers are broken and do not allow @GOTOFF in
5308 ; ought but a memory context.
5309 (match_operand:DI 2 "pic_symbolic_operand" "")
5310 (const_string "lea")
5311 (match_operand:DI 2 "incdec_operand" "")
5312 (const_string "incdec")
5313 ]
5314 (const_string "alu")))
5315 (set_attr "mode" "DI")])
5316
5317;; Convert lea to the lea pattern to avoid flags dependency.
5318(define_split
5319 [(set (match_operand:DI 0 "register_operand" "")
5320 (plus:DI (match_operand:DI 1 "register_operand" "")
5321 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5322 (clobber (reg:CC 17))]
5323 "TARGET_64BIT && reload_completed
5324 && true_regnum (operands[0]) != true_regnum (operands[1])"
5325 [(set (match_dup 0)
5326 (plus:DI (match_dup 1)
5327 (match_dup 2)))]
5328 "")
5329
5330(define_insn "*adddi_2_rex64"
5331 [(set (reg 17)
5332 (compare
5333 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5334 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5335 (const_int 0)))
5336 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5337 (plus:DI (match_dup 1) (match_dup 2)))]
5338 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5339 && ix86_binary_operator_ok (PLUS, DImode, operands)
5340 /* Current assemblers are broken and do not allow @GOTOFF in
5341 ought but a memory context. */
5342 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5343{
5344 switch (get_attr_type (insn))
5345 {
5346 case TYPE_INCDEC:
5347 if (! rtx_equal_p (operands[0], operands[1]))
5348 abort ();
5349 if (operands[2] == const1_rtx)
5350 return "inc{q}\t%0";
5351 else if (operands[2] == constm1_rtx)
5352 return "dec{q}\t%0";
5353 else
5354 abort ();
5355
5356 default:
5357 if (! rtx_equal_p (operands[0], operands[1]))
5358 abort ();
5359 /* ???? We ought to handle there the 32bit case too
5360 - do we need new constraint? */
5361 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5363 if (GET_CODE (operands[2]) == CONST_INT
5364 /* Avoid overflows. */
5365 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366 && (INTVAL (operands[2]) == 128
5367 || (INTVAL (operands[2]) < 0
5368 && INTVAL (operands[2]) != -128)))
5369 {
5370 operands[2] = GEN_INT (-INTVAL (operands[2]));
5371 return "sub{q}\t{%2, %0|%0, %2}";
5372 }
5373 return "add{q}\t{%2, %0|%0, %2}";
5374 }
5375}
5376 [(set (attr "type")
5377 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378 (const_string "incdec")
5379 (const_string "alu")))
5380 (set_attr "mode" "DI")])
5381
5382(define_insn "*adddi_3_rex64"
5383 [(set (reg 17)
5384 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5385 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5386 (clobber (match_scratch:DI 0 "=r"))]
5387 "TARGET_64BIT
5388 && ix86_match_ccmode (insn, CCZmode)
5389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390 /* Current assemblers are broken and do not allow @GOTOFF in
5391 ought but a memory context. */
5392 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5393{
5394 switch (get_attr_type (insn))
5395 {
5396 case TYPE_INCDEC:
5397 if (! rtx_equal_p (operands[0], operands[1]))
5398 abort ();
5399 if (operands[2] == const1_rtx)
5400 return "inc{q}\t%0";
5401 else if (operands[2] == constm1_rtx)
5402 return "dec{q}\t%0";
5403 else
5404 abort ();
5405
5406 default:
5407 if (! rtx_equal_p (operands[0], operands[1]))
5408 abort ();
5409 /* ???? We ought to handle there the 32bit case too
5410 - do we need new constraint? */
5411 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5413 if (GET_CODE (operands[2]) == CONST_INT
5414 /* Avoid overflows. */
5415 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5416 && (INTVAL (operands[2]) == 128
5417 || (INTVAL (operands[2]) < 0
5418 && INTVAL (operands[2]) != -128)))
5419 {
5420 operands[2] = GEN_INT (-INTVAL (operands[2]));
5421 return "sub{q}\t{%2, %0|%0, %2}";
5422 }
5423 return "add{q}\t{%2, %0|%0, %2}";
5424 }
5425}
5426 [(set (attr "type")
5427 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5428 (const_string "incdec")
5429 (const_string "alu")))
5430 (set_attr "mode" "DI")])
5431
5432; For comparisons against 1, -1 and 128, we may generate better code
5433; by converting cmp to add, inc or dec as done by peephole2. This pattern
5434; is matched then. We can't accept general immediate, because for
5435; case of overflows, the result is messed up.
5436; This pattern also don't hold of 0x8000000000000000, since the value overflows
5437; when negated.
5438; Also carry flag is reversed compared to cmp, so this conversion is valid
5439; only for comparisons not depending on it.
5440(define_insn "*adddi_4_rex64"
5441 [(set (reg 17)
5442 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5443 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5444 (clobber (match_scratch:DI 0 "=rm"))]
5445 "TARGET_64BIT
5446 && ix86_match_ccmode (insn, CCGCmode)"
5447{
5448 switch (get_attr_type (insn))
5449 {
5450 case TYPE_INCDEC:
5451 if (operands[2] == constm1_rtx)
5452 return "inc{q}\t%0";
5453 else if (operands[2] == const1_rtx)
5454 return "dec{q}\t%0";
5455 else
5456 abort();
5457
5458 default:
5459 if (! rtx_equal_p (operands[0], operands[1]))
5460 abort ();
5461 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5462 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5463 if ((INTVAL (operands[2]) == -128
5464 || (INTVAL (operands[2]) > 0
5465 && INTVAL (operands[2]) != 128))
5466 /* Avoid overflows. */
5467 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5468 return "sub{q}\t{%2, %0|%0, %2}";
5469 operands[2] = GEN_INT (-INTVAL (operands[2]));
5470 return "add{q}\t{%2, %0|%0, %2}";
5471 }
5472}
5473 [(set (attr "type")
5474 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5475 (const_string "incdec")
5476 (const_string "alu")))
5477 (set_attr "mode" "DI")])
5478
5479(define_insn "*adddi_5_rex64"
5480 [(set (reg 17)
5481 (compare
5482 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5483 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5484 (const_int 0)))
5485 (clobber (match_scratch:DI 0 "=r"))]
5486 "TARGET_64BIT
5487 && ix86_match_ccmode (insn, CCGOCmode)
5488 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5489 /* Current assemblers are broken and do not allow @GOTOFF in
5490 ought but a memory context. */
5491 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5492{
5493 switch (get_attr_type (insn))
5494 {
5495 case TYPE_INCDEC:
5496 if (! rtx_equal_p (operands[0], operands[1]))
5497 abort ();
5498 if (operands[2] == const1_rtx)
5499 return "inc{q}\t%0";
5500 else if (operands[2] == constm1_rtx)
5501 return "dec{q}\t%0";
5502 else
5503 abort();
5504
5505 default:
5506 if (! rtx_equal_p (operands[0], operands[1]))
5507 abort ();
5508 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5509 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5510 if (GET_CODE (operands[2]) == CONST_INT
5511 /* Avoid overflows. */
5512 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5513 && (INTVAL (operands[2]) == 128
5514 || (INTVAL (operands[2]) < 0
5515 && INTVAL (operands[2]) != -128)))
5516 {
5517 operands[2] = GEN_INT (-INTVAL (operands[2]));
5518 return "sub{q}\t{%2, %0|%0, %2}";
5519 }
5520 return "add{q}\t{%2, %0|%0, %2}";
5521 }
5522}
5523 [(set (attr "type")
5524 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5525 (const_string "incdec")
5526 (const_string "alu")))
5527 (set_attr "mode" "DI")])
5528
5529
5530(define_insn "*addsi_1"
5531 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5533 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5534 (clobber (reg:CC 17))]
5535 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5536{
5537 switch (get_attr_type (insn))
5538 {
5539 case TYPE_LEA:
5540 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5541 return "lea{l}\t{%a2, %0|%0, %a2}";
5542
5543 case TYPE_INCDEC:
5544 if (! rtx_equal_p (operands[0], operands[1]))
5545 abort ();
5546 if (operands[2] == const1_rtx)
5547 return "inc{l}\t%0";
5548 else if (operands[2] == constm1_rtx)
5549 return "dec{l}\t%0";
5550 else
5551 abort();
5552
5553 default:
5554 if (! rtx_equal_p (operands[0], operands[1]))
5555 abort ();
5556
5557 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5558 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5559 if (GET_CODE (operands[2]) == CONST_INT
5560 && (INTVAL (operands[2]) == 128
5561 || (INTVAL (operands[2]) < 0
5562 && INTVAL (operands[2]) != -128)))
5563 {
5564 operands[2] = GEN_INT (-INTVAL (operands[2]));
5565 return "sub{l}\t{%2, %0|%0, %2}";
5566 }
5567 return "add{l}\t{%2, %0|%0, %2}";
5568 }
5569}
5570 [(set (attr "type")
5571 (cond [(eq_attr "alternative" "2")
5572 (const_string "lea")
5573 ; Current assemblers are broken and do not allow @GOTOFF in
5574 ; ought but a memory context.
5575 (match_operand:SI 2 "pic_symbolic_operand" "")
5576 (const_string "lea")
5577 (match_operand:SI 2 "incdec_operand" "")
5578 (const_string "incdec")
5579 ]
5580 (const_string "alu")))
5581 (set_attr "mode" "SI")])
5582
5583;; Convert lea to the lea pattern to avoid flags dependency.
5584(define_split
5585 [(set (match_operand 0 "register_operand" "")
5586 (plus (match_operand 1 "register_operand" "")
5587 (match_operand 2 "nonmemory_operand" "")))
5588 (clobber (reg:CC 17))]
5589 "reload_completed
5590 && true_regnum (operands[0]) != true_regnum (operands[1])"
5591 [(const_int 0)]
5592{
5593 rtx pat;
5594 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5595 may confuse gen_lowpart. */
5596 if (GET_MODE (operands[0]) != Pmode)
5597 {
5598 operands[1] = gen_lowpart (Pmode, operands[1]);
5599 operands[2] = gen_lowpart (Pmode, operands[2]);
5600 }
5601 operands[0] = gen_lowpart (SImode, operands[0]);
5602 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5603 if (Pmode != SImode)
5604 pat = gen_rtx_SUBREG (SImode, pat, 0);
5605 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5606 DONE;
5607})
5608
5609;; It may seem that nonimmediate operand is proper one for operand 1.
5610;; The addsi_1 pattern allows nonimmediate operand at that place and
5611;; we take care in ix86_binary_operator_ok to not allow two memory
5612;; operands so proper swapping will be done in reload. This allow
5613;; patterns constructed from addsi_1 to match.
5614(define_insn "addsi_1_zext"
5615 [(set (match_operand:DI 0 "register_operand" "=r,r")
5616 (zero_extend:DI
5617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5618 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5619 (clobber (reg:CC 17))]
5620 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5621{
5622 switch (get_attr_type (insn))
5623 {
5624 case TYPE_LEA:
5625 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5626 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5627
5628 case TYPE_INCDEC:
5629 if (operands[2] == const1_rtx)
5630 return "inc{l}\t%k0";
5631 else if (operands[2] == constm1_rtx)
5632 return "dec{l}\t%k0";
5633 else
5634 abort();
5635
5636 default:
5637 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5639 if (GET_CODE (operands[2]) == CONST_INT
5640 && (INTVAL (operands[2]) == 128
5641 || (INTVAL (operands[2]) < 0
5642 && INTVAL (operands[2]) != -128)))
5643 {
5644 operands[2] = GEN_INT (-INTVAL (operands[2]));
5645 return "sub{l}\t{%2, %k0|%k0, %2}";
5646 }
5647 return "add{l}\t{%2, %k0|%k0, %2}";
5648 }
5649}
5650 [(set (attr "type")
5651 (cond [(eq_attr "alternative" "1")
5652 (const_string "lea")
5653 ; Current assemblers are broken and do not allow @GOTOFF in
5654 ; ought but a memory context.
5655 (match_operand:SI 2 "pic_symbolic_operand" "")
5656 (const_string "lea")
5657 (match_operand:SI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 ]
5660 (const_string "alu")))
5661 (set_attr "mode" "SI")])
5662
5663;; Convert lea to the lea pattern to avoid flags dependency.
5664(define_split
5665 [(set (match_operand:DI 0 "register_operand" "")
5666 (zero_extend:DI
5667 (plus:SI (match_operand:SI 1 "register_operand" "")
5668 (match_operand:SI 2 "nonmemory_operand" ""))))
5669 (clobber (reg:CC 17))]
5670 "TARGET_64BIT && reload_completed
5671 && true_regnum (operands[0]) != true_regnum (operands[1])"
5672 [(set (match_dup 0)
5673 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5674{
5675 operands[1] = gen_lowpart (Pmode, operands[1]);
5676 operands[2] = gen_lowpart (Pmode, operands[2]);
5677})
5678
5679(define_insn "*addsi_2"
5680 [(set (reg 17)
5681 (compare
5682 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5683 (match_operand:SI 2 "general_operand" "rmni,rni"))
5684 (const_int 0)))
5685 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5686 (plus:SI (match_dup 1) (match_dup 2)))]
5687 "ix86_match_ccmode (insn, CCGOCmode)
5688 && ix86_binary_operator_ok (PLUS, SImode, operands)
5689 /* Current assemblers are broken and do not allow @GOTOFF in
5690 ought but a memory context. */
5691 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5692{
5693 switch (get_attr_type (insn))
5694 {
5695 case TYPE_INCDEC:
5696 if (! rtx_equal_p (operands[0], operands[1]))
5697 abort ();
5698 if (operands[2] == const1_rtx)
5699 return "inc{l}\t%0";
5700 else if (operands[2] == constm1_rtx)
5701 return "dec{l}\t%0";
5702 else
5703 abort();
5704
5705 default:
5706 if (! rtx_equal_p (operands[0], operands[1]))
5707 abort ();
5708 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5709 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5710 if (GET_CODE (operands[2]) == CONST_INT
5711 && (INTVAL (operands[2]) == 128
5712 || (INTVAL (operands[2]) < 0
5713 && INTVAL (operands[2]) != -128)))
5714 {
5715 operands[2] = GEN_INT (-INTVAL (operands[2]));
5716 return "sub{l}\t{%2, %0|%0, %2}";
5717 }
5718 return "add{l}\t{%2, %0|%0, %2}";
5719 }
5720}
5721 [(set (attr "type")
5722 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723 (const_string "incdec")
5724 (const_string "alu")))
5725 (set_attr "mode" "SI")])
5726
5727;; See comment for addsi_1_zext why we do use nonimmediate_operand
5728(define_insn "*addsi_2_zext"
5729 [(set (reg 17)
5730 (compare
5731 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5732 (match_operand:SI 2 "general_operand" "rmni"))
5733 (const_int 0)))
5734 (set (match_operand:DI 0 "register_operand" "=r")
5735 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5736 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5737 && ix86_binary_operator_ok (PLUS, SImode, operands)
5738 /* Current assemblers are broken and do not allow @GOTOFF in
5739 ought but a memory context. */
5740 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5741{
5742 switch (get_attr_type (insn))
5743 {
5744 case TYPE_INCDEC:
5745 if (operands[2] == const1_rtx)
5746 return "inc{l}\t%k0";
5747 else if (operands[2] == constm1_rtx)
5748 return "dec{l}\t%k0";
5749 else
5750 abort();
5751
5752 default:
5753 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5754 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5755 if (GET_CODE (operands[2]) == CONST_INT
5756 && (INTVAL (operands[2]) == 128
5757 || (INTVAL (operands[2]) < 0
5758 && INTVAL (operands[2]) != -128)))
5759 {
5760 operands[2] = GEN_INT (-INTVAL (operands[2]));
5761 return "sub{l}\t{%2, %k0|%k0, %2}";
5762 }
5763 return "add{l}\t{%2, %k0|%k0, %2}";
5764 }
5765}
5766 [(set (attr "type")
5767 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5768 (const_string "incdec")
5769 (const_string "alu")))
5770 (set_attr "mode" "SI")])
5771
5772(define_insn "*addsi_3"
5773 [(set (reg 17)
5774 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5775 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5776 (clobber (match_scratch:SI 0 "=r"))]
5777 "ix86_match_ccmode (insn, CCZmode)
5778 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5779 /* Current assemblers are broken and do not allow @GOTOFF in
5780 ought but a memory context. */
5781 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5782{
5783 switch (get_attr_type (insn))
5784 {
5785 case TYPE_INCDEC:
5786 if (! rtx_equal_p (operands[0], operands[1]))
5787 abort ();
5788 if (operands[2] == const1_rtx)
5789 return "inc{l}\t%0";
5790 else if (operands[2] == constm1_rtx)
5791 return "dec{l}\t%0";
5792 else
5793 abort();
5794
5795 default:
5796 if (! rtx_equal_p (operands[0], operands[1]))
5797 abort ();
5798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5800 if (GET_CODE (operands[2]) == CONST_INT
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5804 {
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
5806 return "sub{l}\t{%2, %0|%0, %2}";
5807 }
5808 return "add{l}\t{%2, %0|%0, %2}";
5809 }
5810}
5811 [(set (attr "type")
5812 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "SI")])
5816
5817;; See comment for addsi_1_zext why we do use nonimmediate_operand
5818(define_insn "*addsi_3_zext"
5819 [(set (reg 17)
5820 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5821 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5822 (set (match_operand:DI 0 "register_operand" "=r")
5823 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5824 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5825 && ix86_binary_operator_ok (PLUS, SImode, operands)
5826 /* Current assemblers are broken and do not allow @GOTOFF in
5827 ought but a memory context. */
5828 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5829{
5830 switch (get_attr_type (insn))
5831 {
5832 case TYPE_INCDEC:
5833 if (operands[2] == const1_rtx)
5834 return "inc{l}\t%k0";
5835 else if (operands[2] == constm1_rtx)
5836 return "dec{l}\t%k0";
5837 else
5838 abort();
5839
5840 default:
5841 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5842 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5843 if (GET_CODE (operands[2]) == CONST_INT
5844 && (INTVAL (operands[2]) == 128
5845 || (INTVAL (operands[2]) < 0
5846 && INTVAL (operands[2]) != -128)))
5847 {
5848 operands[2] = GEN_INT (-INTVAL (operands[2]));
5849 return "sub{l}\t{%2, %k0|%k0, %2}";
5850 }
5851 return "add{l}\t{%2, %k0|%k0, %2}";
5852 }
5853}
5854 [(set (attr "type")
5855 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5856 (const_string "incdec")
5857 (const_string "alu")))
5858 (set_attr "mode" "SI")])
5859
5860; For comparisons against 1, -1 and 128, we may generate better code
5861; by converting cmp to add, inc or dec as done by peephole2. This pattern
5862; is matched then. We can't accept general immediate, because for
5863; case of overflows, the result is messed up.
5864; This pattern also don't hold of 0x80000000, since the value overflows
5865; when negated.
5866; Also carry flag is reversed compared to cmp, so this conversion is valid
5867; only for comparisons not depending on it.
5868(define_insn "*addsi_4"
5869 [(set (reg 17)
5870 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5871 (match_operand:SI 2 "const_int_operand" "n")))
5872 (clobber (match_scratch:SI 0 "=rm"))]
5873 "ix86_match_ccmode (insn, CCGCmode)
5874 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5875{
5876 switch (get_attr_type (insn))
5877 {
5878 case TYPE_INCDEC:
5879 if (operands[2] == constm1_rtx)
5880 return "inc{l}\t%0";
5881 else if (operands[2] == const1_rtx)
5882 return "dec{l}\t%0";
5883 else
5884 abort();
5885
5886 default:
5887 if (! rtx_equal_p (operands[0], operands[1]))
5888 abort ();
5889 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5890 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5891 if ((INTVAL (operands[2]) == -128
5892 || (INTVAL (operands[2]) > 0
5893 && INTVAL (operands[2]) != 128)))
5894 return "sub{l}\t{%2, %0|%0, %2}";
5895 operands[2] = GEN_INT (-INTVAL (operands[2]));
5896 return "add{l}\t{%2, %0|%0, %2}";
5897 }
5898}
5899 [(set (attr "type")
5900 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "SI")])
5904
5905(define_insn "*addsi_5"
5906 [(set (reg 17)
5907 (compare
5908 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5909 (match_operand:SI 2 "general_operand" "rmni"))
5910 (const_int 0)))
5911 (clobber (match_scratch:SI 0 "=r"))]
5912 "ix86_match_ccmode (insn, CCGOCmode)
5913 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5914 /* Current assemblers are broken and do not allow @GOTOFF in
5915 ought but a memory context. */
5916 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5917{
5918 switch (get_attr_type (insn))
5919 {
5920 case TYPE_INCDEC:
5921 if (! rtx_equal_p (operands[0], operands[1]))
5922 abort ();
5923 if (operands[2] == const1_rtx)
5924 return "inc{l}\t%0";
5925 else if (operands[2] == constm1_rtx)
5926 return "dec{l}\t%0";
5927 else
5928 abort();
5929
5930 default:
5931 if (! rtx_equal_p (operands[0], operands[1]))
5932 abort ();
5933 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5934 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5935 if (GET_CODE (operands[2]) == CONST_INT
5936 && (INTVAL (operands[2]) == 128
5937 || (INTVAL (operands[2]) < 0
5938 && INTVAL (operands[2]) != -128)))
5939 {
5940 operands[2] = GEN_INT (-INTVAL (operands[2]));
5941 return "sub{l}\t{%2, %0|%0, %2}";
5942 }
5943 return "add{l}\t{%2, %0|%0, %2}";
5944 }
5945}
5946 [(set (attr "type")
5947 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5948 (const_string "incdec")
5949 (const_string "alu")))
5950 (set_attr "mode" "SI")])
5951
5952(define_expand "addhi3"
5953 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5954 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5955 (match_operand:HI 2 "general_operand" "")))
5956 (clobber (reg:CC 17))])]
5957 "TARGET_HIMODE_MATH"
5958 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5959
5960;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5961;; type optimizations enabled by define-splits. This is not important
5962;; for PII, and in fact harmful because of partial register stalls.
5963
5964(define_insn "*addhi_1_lea"
5965 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5966 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5967 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5968 (clobber (reg:CC 17))]
5969 "!TARGET_PARTIAL_REG_STALL
5970 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5971{
5972 switch (get_attr_type (insn))
5973 {
5974 case TYPE_LEA:
5975 return "#";
5976 case TYPE_INCDEC:
5977 if (operands[2] == const1_rtx)
5978 return "inc{w}\t%0";
5979 else if (operands[2] == constm1_rtx)
5980 return "dec{w}\t%0";
5981 abort();
5982
5983 default:
5984 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5985 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5986 if (GET_CODE (operands[2]) == CONST_INT
5987 && (INTVAL (operands[2]) == 128
5988 || (INTVAL (operands[2]) < 0
5989 && INTVAL (operands[2]) != -128)))
5990 {
5991 operands[2] = GEN_INT (-INTVAL (operands[2]));
5992 return "sub{w}\t{%2, %0|%0, %2}";
5993 }
5994 return "add{w}\t{%2, %0|%0, %2}";
5995 }
5996}
5997 [(set (attr "type")
5998 (if_then_else (eq_attr "alternative" "2")
5999 (const_string "lea")
6000 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6001 (const_string "incdec")
6002 (const_string "alu"))))
6003 (set_attr "mode" "HI,HI,SI")])
6004
6005(define_insn "*addhi_1"
6006 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6007 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6008 (match_operand:HI 2 "general_operand" "ri,rm")))
6009 (clobber (reg:CC 17))]
6010 "TARGET_PARTIAL_REG_STALL
6011 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6012{
6013 switch (get_attr_type (insn))
6014 {
6015 case TYPE_INCDEC:
6016 if (operands[2] == const1_rtx)
6017 return "inc{w}\t%0";
6018 else if (operands[2] == constm1_rtx)
6019 return "dec{w}\t%0";
6020 abort();
6021
6022 default:
6023 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6025 if (GET_CODE (operands[2]) == CONST_INT
6026 && (INTVAL (operands[2]) == 128
6027 || (INTVAL (operands[2]) < 0
6028 && INTVAL (operands[2]) != -128)))
6029 {
6030 operands[2] = GEN_INT (-INTVAL (operands[2]));
6031 return "sub{w}\t{%2, %0|%0, %2}";
6032 }
6033 return "add{w}\t{%2, %0|%0, %2}";
6034 }
6035}
6036 [(set (attr "type")
6037 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6038 (const_string "incdec")
6039 (const_string "alu")))
6040 (set_attr "mode" "HI")])
6041
6042(define_insn "*addhi_2"
6043 [(set (reg 17)
6044 (compare
6045 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6046 (match_operand:HI 2 "general_operand" "rmni,rni"))
6047 (const_int 0)))
6048 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6049 (plus:HI (match_dup 1) (match_dup 2)))]
6050 "ix86_match_ccmode (insn, CCGOCmode)
6051 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6052{
6053 switch (get_attr_type (insn))
6054 {
6055 case TYPE_INCDEC:
6056 if (operands[2] == const1_rtx)
6057 return "inc{w}\t%0";
6058 else if (operands[2] == constm1_rtx)
6059 return "dec{w}\t%0";
6060 abort();
6061
6062 default:
6063 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6065 if (GET_CODE (operands[2]) == CONST_INT
6066 && (INTVAL (operands[2]) == 128
6067 || (INTVAL (operands[2]) < 0
6068 && INTVAL (operands[2]) != -128)))
6069 {
6070 operands[2] = GEN_INT (-INTVAL (operands[2]));
6071 return "sub{w}\t{%2, %0|%0, %2}";
6072 }
6073 return "add{w}\t{%2, %0|%0, %2}";
6074 }
6075}
6076 [(set (attr "type")
6077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078 (const_string "incdec")
6079 (const_string "alu")))
6080 (set_attr "mode" "HI")])
6081
6082(define_insn "*addhi_3"
6083 [(set (reg 17)
6084 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6085 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6086 (clobber (match_scratch:HI 0 "=r"))]
6087 "ix86_match_ccmode (insn, CCZmode)
6088 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6089{
6090 switch (get_attr_type (insn))
6091 {
6092 case TYPE_INCDEC:
6093 if (operands[2] == const1_rtx)
6094 return "inc{w}\t%0";
6095 else if (operands[2] == constm1_rtx)
6096 return "dec{w}\t%0";
6097 abort();
6098
6099 default:
6100 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6102 if (GET_CODE (operands[2]) == CONST_INT
6103 && (INTVAL (operands[2]) == 128
6104 || (INTVAL (operands[2]) < 0
6105 && INTVAL (operands[2]) != -128)))
6106 {
6107 operands[2] = GEN_INT (-INTVAL (operands[2]));
6108 return "sub{w}\t{%2, %0|%0, %2}";
6109 }
6110 return "add{w}\t{%2, %0|%0, %2}";
6111 }
6112}
6113 [(set (attr "type")
6114 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6115 (const_string "incdec")
6116 (const_string "alu")))
6117 (set_attr "mode" "HI")])
6118
6119; See comments above addsi_3_imm for details.
6120(define_insn "*addhi_4"
6121 [(set (reg 17)
6122 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6123 (match_operand:HI 2 "const_int_operand" "n")))
6124 (clobber (match_scratch:HI 0 "=rm"))]
6125 "ix86_match_ccmode (insn, CCGCmode)
6126 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6127{
6128 switch (get_attr_type (insn))
6129 {
6130 case TYPE_INCDEC:
6131 if (operands[2] == constm1_rtx)
6132 return "inc{w}\t%0";
6133 else if (operands[2] == const1_rtx)
6134 return "dec{w}\t%0";
6135 else
6136 abort();
6137
6138 default:
6139 if (! rtx_equal_p (operands[0], operands[1]))
6140 abort ();
6141 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6143 if ((INTVAL (operands[2]) == -128
6144 || (INTVAL (operands[2]) > 0
6145 && INTVAL (operands[2]) != 128)))
6146 return "sub{w}\t{%2, %0|%0, %2}";
6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 return "add{w}\t{%2, %0|%0, %2}";
6149 }
6150}
6151 [(set (attr "type")
6152 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6153 (const_string "incdec")
6154 (const_string "alu")))
6155 (set_attr "mode" "SI")])
6156
6157
6158(define_insn "*addhi_5"
6159 [(set (reg 17)
6160 (compare
6161 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6162 (match_operand:HI 2 "general_operand" "rmni"))
6163 (const_int 0)))
6164 (clobber (match_scratch:HI 0 "=r"))]
6165 "ix86_match_ccmode (insn, CCGOCmode)
6166 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6167{
6168 switch (get_attr_type (insn))
6169 {
6170 case TYPE_INCDEC:
6171 if (operands[2] == const1_rtx)
6172 return "inc{w}\t%0";
6173 else if (operands[2] == constm1_rtx)
6174 return "dec{w}\t%0";
6175 abort();
6176
6177 default:
6178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6179 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6180 if (GET_CODE (operands[2]) == CONST_INT
6181 && (INTVAL (operands[2]) == 128
6182 || (INTVAL (operands[2]) < 0
6183 && INTVAL (operands[2]) != -128)))
6184 {
6185 operands[2] = GEN_INT (-INTVAL (operands[2]));
6186 return "sub{w}\t{%2, %0|%0, %2}";
6187 }
6188 return "add{w}\t{%2, %0|%0, %2}";
6189 }
6190}
6191 [(set (attr "type")
6192 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6193 (const_string "incdec")
6194 (const_string "alu")))
6195 (set_attr "mode" "HI")])
6196
6197(define_expand "addqi3"
6198 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6199 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6200 (match_operand:QI 2 "general_operand" "")))
6201 (clobber (reg:CC 17))])]
6202 "TARGET_QIMODE_MATH"
6203 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6204
6205;; %%% Potential partial reg stall on alternative 2. What to do?
6206(define_insn "*addqi_1_lea"
6207 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6208 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6209 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6210 (clobber (reg:CC 17))]
6211 "!TARGET_PARTIAL_REG_STALL
6212 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6213{
6214 int widen = (which_alternative == 2);
6215 switch (get_attr_type (insn))
6216 {
6217 case TYPE_LEA:
6218 return "#";
6219 case TYPE_INCDEC:
6220 if (operands[2] == const1_rtx)
6221 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6222 else if (operands[2] == constm1_rtx)
6223 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6224 abort();
6225
6226 default:
6227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6229 if (GET_CODE (operands[2]) == CONST_INT
6230 && (INTVAL (operands[2]) == 128
6231 || (INTVAL (operands[2]) < 0
6232 && INTVAL (operands[2]) != -128)))
6233 {
6234 operands[2] = GEN_INT (-INTVAL (operands[2]));
6235 if (widen)
6236 return "sub{l}\t{%2, %k0|%k0, %2}";
6237 else
6238 return "sub{b}\t{%2, %0|%0, %2}";
6239 }
6240 if (widen)
6241 return "add{l}\t{%k2, %k0|%k0, %k2}";
6242 else
6243 return "add{b}\t{%2, %0|%0, %2}";
6244 }
6245}
6246 [(set (attr "type")
6247 (if_then_else (eq_attr "alternative" "3")
6248 (const_string "lea")
6249 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250 (const_string "incdec")
6251 (const_string "alu"))))
6252 (set_attr "mode" "QI,QI,SI,SI")])
6253
6254(define_insn "*addqi_1"
6255 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6256 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6257 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6258 (clobber (reg:CC 17))]
6259 "TARGET_PARTIAL_REG_STALL
6260 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6261{
6262 int widen = (which_alternative == 2);
6263 switch (get_attr_type (insn))
6264 {
6265 case TYPE_INCDEC:
6266 if (operands[2] == const1_rtx)
6267 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6268 else if (operands[2] == constm1_rtx)
6269 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6270 abort();
6271
6272 default:
6273 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6274 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6275 if (GET_CODE (operands[2]) == CONST_INT
6276 && (INTVAL (operands[2]) == 128
6277 || (INTVAL (operands[2]) < 0
6278 && INTVAL (operands[2]) != -128)))
6279 {
6280 operands[2] = GEN_INT (-INTVAL (operands[2]));
6281 if (widen)
6282 return "sub{l}\t{%2, %k0|%k0, %2}";
6283 else
6284 return "sub{b}\t{%2, %0|%0, %2}";
6285 }
6286 if (widen)
6287 return "add{l}\t{%k2, %k0|%k0, %k2}";
6288 else
6289 return "add{b}\t{%2, %0|%0, %2}";
6290 }
6291}
6292 [(set (attr "type")
6293 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set_attr "mode" "QI,QI,SI")])
6297
6298(define_insn "*addqi_1_slp"
6299 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6300 (plus:QI (match_dup 0)
6301 (match_operand:QI 1 "general_operand" "qn,qnm")))
6302 (clobber (reg:CC 17))]
6303 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6304 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6305{
6306 switch (get_attr_type (insn))
6307 {
6308 case TYPE_INCDEC:
6309 if (operands[1] == const1_rtx)
6310 return "inc{b}\t%0";
6311 else if (operands[1] == constm1_rtx)
6312 return "dec{b}\t%0";
6313 abort();
6314
6315 default:
6316 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6317 if (GET_CODE (operands[1]) == CONST_INT
6318 && INTVAL (operands[1]) < 0)
6319 {
6320 operands[1] = GEN_INT (-INTVAL (operands[1]));
6321 return "sub{b}\t{%1, %0|%0, %1}";
6322 }
6323 return "add{b}\t{%1, %0|%0, %1}";
6324 }
6325}
6326 [(set (attr "type")
6327 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6328 (const_string "incdec")
6329 (const_string "alu1")))
6330 (set (attr "memory")
6331 (if_then_else (match_operand 1 "memory_operand" "")
6332 (const_string "load")
6333 (const_string "none")))
6334 (set_attr "mode" "QI")])
6335
6336(define_insn "*addqi_2"
6337 [(set (reg 17)
6338 (compare
6339 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6340 (match_operand:QI 2 "general_operand" "qmni,qni"))
6341 (const_int 0)))
6342 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6343 (plus:QI (match_dup 1) (match_dup 2)))]
6344 "ix86_match_ccmode (insn, CCGOCmode)
6345 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6346{
6347 switch (get_attr_type (insn))
6348 {
6349 case TYPE_INCDEC:
6350 if (operands[2] == const1_rtx)
6351 return "inc{b}\t%0";
6352 else if (operands[2] == constm1_rtx
6353 || (GET_CODE (operands[2]) == CONST_INT
6354 && INTVAL (operands[2]) == 255))
6355 return "dec{b}\t%0";
6356 abort();
6357
6358 default:
6359 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6360 if (GET_CODE (operands[2]) == CONST_INT
6361 && INTVAL (operands[2]) < 0)
6362 {
6363 operands[2] = GEN_INT (-INTVAL (operands[2]));
6364 return "sub{b}\t{%2, %0|%0, %2}";
6365 }
6366 return "add{b}\t{%2, %0|%0, %2}";
6367 }
6368}
6369 [(set (attr "type")
6370 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6371 (const_string "incdec")
6372 (const_string "alu")))
6373 (set_attr "mode" "QI")])
6374
6375(define_insn "*addqi_3"
6376 [(set (reg 17)
6377 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6378 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6379 (clobber (match_scratch:QI 0 "=q"))]
6380 "ix86_match_ccmode (insn, CCZmode)
6381 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6382{
6383 switch (get_attr_type (insn))
6384 {
6385 case TYPE_INCDEC:
6386 if (operands[2] == const1_rtx)
6387 return "inc{b}\t%0";
6388 else if (operands[2] == constm1_rtx
6389 || (GET_CODE (operands[2]) == CONST_INT
6390 && INTVAL (operands[2]) == 255))
6391 return "dec{b}\t%0";
6392 abort();
6393
6394 default:
6395 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6396 if (GET_CODE (operands[2]) == CONST_INT
6397 && INTVAL (operands[2]) < 0)
6398 {
6399 operands[2] = GEN_INT (-INTVAL (operands[2]));
6400 return "sub{b}\t{%2, %0|%0, %2}";
6401 }
6402 return "add{b}\t{%2, %0|%0, %2}";
6403 }
6404}
6405 [(set (attr "type")
6406 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407 (const_string "incdec")
6408 (const_string "alu")))
6409 (set_attr "mode" "QI")])
6410
6411; See comments above addsi_3_imm for details.
6412(define_insn "*addqi_4"
6413 [(set (reg 17)
6414 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6415 (match_operand:QI 2 "const_int_operand" "n")))
6416 (clobber (match_scratch:QI 0 "=qm"))]
6417 "ix86_match_ccmode (insn, CCGCmode)
6418 && (INTVAL (operands[2]) & 0xff) != 0x80"
6419{
6420 switch (get_attr_type (insn))
6421 {
6422 case TYPE_INCDEC:
6423 if (operands[2] == constm1_rtx
6424 || (GET_CODE (operands[2]) == CONST_INT
6425 && INTVAL (operands[2]) == 255))
6426 return "inc{b}\t%0";
6427 else if (operands[2] == const1_rtx)
6428 return "dec{b}\t%0";
6429 else
6430 abort();
6431
6432 default:
6433 if (! rtx_equal_p (operands[0], operands[1]))
6434 abort ();
6435 if (INTVAL (operands[2]) < 0)
6436 {
6437 operands[2] = GEN_INT (-INTVAL (operands[2]));
6438 return "add{b}\t{%2, %0|%0, %2}";
6439 }
6440 return "sub{b}\t{%2, %0|%0, %2}";
6441 }
6442}
6443 [(set (attr "type")
6444 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6445 (const_string "incdec")
6446 (const_string "alu")))
6447 (set_attr "mode" "QI")])
6448
6449
6450(define_insn "*addqi_5"
6451 [(set (reg 17)
6452 (compare
6453 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6454 (match_operand:QI 2 "general_operand" "qmni"))
6455 (const_int 0)))
6456 (clobber (match_scratch:QI 0 "=q"))]
6457 "ix86_match_ccmode (insn, CCGOCmode)
6458 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6459{
6460 switch (get_attr_type (insn))
6461 {
6462 case TYPE_INCDEC:
6463 if (operands[2] == const1_rtx)
6464 return "inc{b}\t%0";
6465 else if (operands[2] == constm1_rtx
6466 || (GET_CODE (operands[2]) == CONST_INT
6467 && INTVAL (operands[2]) == 255))
6468 return "dec{b}\t%0";
6469 abort();
6470
6471 default:
6472 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6473 if (GET_CODE (operands[2]) == CONST_INT
6474 && INTVAL (operands[2]) < 0)
6475 {
6476 operands[2] = GEN_INT (-INTVAL (operands[2]));
6477 return "sub{b}\t{%2, %0|%0, %2}";
6478 }
6479 return "add{b}\t{%2, %0|%0, %2}";
6480 }
6481}
6482 [(set (attr "type")
6483 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6484 (const_string "incdec")
6485 (const_string "alu")))
6486 (set_attr "mode" "QI")])
6487
6488
6489(define_insn "addqi_ext_1"
6490 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6491 (const_int 8)
6492 (const_int 8))
6493 (plus:SI
6494 (zero_extract:SI
6495 (match_operand 1 "ext_register_operand" "0")
6496 (const_int 8)
6497 (const_int 8))
6498 (match_operand:QI 2 "general_operand" "Qmn")))
6499 (clobber (reg:CC 17))]
6500 "!TARGET_64BIT"
6501{
6502 switch (get_attr_type (insn))
6503 {
6504 case TYPE_INCDEC:
6505 if (operands[2] == const1_rtx)
6506 return "inc{b}\t%h0";
6507 else if (operands[2] == constm1_rtx
6508 || (GET_CODE (operands[2]) == CONST_INT
6509 && INTVAL (operands[2]) == 255))
6510 return "dec{b}\t%h0";
6511 abort();
6512
6513 default:
6514 return "add{b}\t{%2, %h0|%h0, %2}";
6515 }
6516}
6517 [(set (attr "type")
6518 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6519 (const_string "incdec")
6520 (const_string "alu")))
6521 (set_attr "mode" "QI")])
6522
6523(define_insn "*addqi_ext_1_rex64"
6524 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6525 (const_int 8)
6526 (const_int 8))
6527 (plus:SI
6528 (zero_extract:SI
6529 (match_operand 1 "ext_register_operand" "0")
6530 (const_int 8)
6531 (const_int 8))
6532 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6533 (clobber (reg:CC 17))]
6534 "TARGET_64BIT"
6535{
6536 switch (get_attr_type (insn))
6537 {
6538 case TYPE_INCDEC:
6539 if (operands[2] == const1_rtx)
6540 return "inc{b}\t%h0";
6541 else if (operands[2] == constm1_rtx
6542 || (GET_CODE (operands[2]) == CONST_INT
6543 && INTVAL (operands[2]) == 255))
6544 return "dec{b}\t%h0";
6545 abort();
6546
6547 default:
6548 return "add{b}\t{%2, %h0|%h0, %2}";
6549 }
6550}
6551 [(set (attr "type")
6552 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6553 (const_string "incdec")
6554 (const_string "alu")))
6555 (set_attr "mode" "QI")])
6556
6557(define_insn "*addqi_ext_2"
6558 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6559 (const_int 8)
6560 (const_int 8))
6561 (plus:SI
6562 (zero_extract:SI
6563 (match_operand 1 "ext_register_operand" "%0")
6564 (const_int 8)
6565 (const_int 8))
6566 (zero_extract:SI
6567 (match_operand 2 "ext_register_operand" "Q")
6568 (const_int 8)
6569 (const_int 8))))
6570 (clobber (reg:CC 17))]
6571 ""
6572 "add{b}\t{%h2, %h0|%h0, %h2}"
6573 [(set_attr "type" "alu")
6574 (set_attr "mode" "QI")])
6575
6576;; The patterns that match these are at the end of this file.
6577
6578(define_expand "addxf3"
6579 [(set (match_operand:XF 0 "register_operand" "")
6580 (plus:XF (match_operand:XF 1 "register_operand" "")
6581 (match_operand:XF 2 "register_operand" "")))]
6582 "TARGET_80387"
6583 "")
6584
6585(define_expand "adddf3"
6586 [(set (match_operand:DF 0 "register_operand" "")
6587 (plus:DF (match_operand:DF 1 "register_operand" "")
6588 (match_operand:DF 2 "nonimmediate_operand" "")))]
6589 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6590 "")
6591
6592(define_expand "addsf3"
6593 [(set (match_operand:SF 0 "register_operand" "")
6594 (plus:SF (match_operand:SF 1 "register_operand" "")
6595 (match_operand:SF 2 "nonimmediate_operand" "")))]
6596 "TARGET_80387 || TARGET_SSE_MATH"
6597 "")
6598
6599;; Subtract instructions
6600
6601;; %%% splits for subsidi3
6602
6603(define_expand "subdi3"
6604 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6605 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6606 (match_operand:DI 2 "x86_64_general_operand" "")))
6607 (clobber (reg:CC 17))])]
6608 ""
6609 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6610
6611(define_insn "*subdi3_1"
6612 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6613 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6614 (match_operand:DI 2 "general_operand" "roiF,riF")))
6615 (clobber (reg:CC 17))]
6616 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6617 "#")
6618
6619(define_split
6620 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6621 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6622 (match_operand:DI 2 "general_operand" "")))
6623 (clobber (reg:CC 17))]
6624 "!TARGET_64BIT && reload_completed"
6625 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6626 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6627 (parallel [(set (match_dup 3)
6628 (minus:SI (match_dup 4)
6629 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6630 (match_dup 5))))
6631 (clobber (reg:CC 17))])]
6632 "split_di (operands+0, 1, operands+0, operands+3);
6633 split_di (operands+1, 1, operands+1, operands+4);
6634 split_di (operands+2, 1, operands+2, operands+5);")
6635
6636(define_insn "subdi3_carry_rex64"
6637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6638 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6639 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6640 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6641 (clobber (reg:CC 17))]
6642 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6643 "sbb{q}\t{%2, %0|%0, %2}"
6644 [(set_attr "type" "alu")
6645 (set_attr "pent_pair" "pu")
6646 (set_attr "ppro_uops" "few")
6647 (set_attr "mode" "DI")])
6648
6649(define_insn "*subdi_1_rex64"
6650 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6651 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6652 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6653 (clobber (reg:CC 17))]
6654 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6655 "sub{q}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "mode" "DI")])
6658
6659(define_insn "*subdi_2_rex64"
6660 [(set (reg 17)
6661 (compare
6662 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6663 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6664 (const_int 0)))
6665 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6666 (minus:DI (match_dup 1) (match_dup 2)))]
6667 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6668 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6669 "sub{q}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "DI")])
6672
6673(define_insn "*subdi_3_rex63"
6674 [(set (reg 17)
6675 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6676 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6677 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6678 (minus:DI (match_dup 1) (match_dup 2)))]
6679 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6680 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6681 "sub{q}\t{%2, %0|%0, %2}"
6682 [(set_attr "type" "alu")
6683 (set_attr "mode" "DI")])
6684
6685(define_insn "subqi3_carry"
6686 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6687 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6688 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6689 (match_operand:QI 2 "general_operand" "qi,qm"))))
6690 (clobber (reg:CC 17))]
6691 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6692 "sbb{b}\t{%2, %0|%0, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "pent_pair" "pu")
6695 (set_attr "ppro_uops" "few")
6696 (set_attr "mode" "QI")])
6697
6698(define_insn "subhi3_carry"
6699 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6700 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6701 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6702 (match_operand:HI 2 "general_operand" "ri,rm"))))
6703 (clobber (reg:CC 17))]
6704 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6705 "sbb{w}\t{%2, %0|%0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "pent_pair" "pu")
6708 (set_attr "ppro_uops" "few")
6709 (set_attr "mode" "HI")])
6710
6711(define_insn "subsi3_carry"
6712 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6714 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6715 (match_operand:SI 2 "general_operand" "ri,rm"))))
6716 (clobber (reg:CC 17))]
6717 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6718 "sbb{l}\t{%2, %0|%0, %2}"
6719 [(set_attr "type" "alu")
6720 (set_attr "pent_pair" "pu")
6721 (set_attr "ppro_uops" "few")
6722 (set_attr "mode" "SI")])
6723
6724(define_insn "subsi3_carry_zext"
6725 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6726 (zero_extend:DI
6727 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6728 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6729 (match_operand:SI 2 "general_operand" "ri,rm")))))
6730 (clobber (reg:CC 17))]
6731 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6732 "sbb{l}\t{%2, %k0|%k0, %2}"
6733 [(set_attr "type" "alu")
6734 (set_attr "pent_pair" "pu")
6735 (set_attr "ppro_uops" "few")
6736 (set_attr "mode" "SI")])
6737
6738(define_expand "subsi3"
6739 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6740 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6741 (match_operand:SI 2 "general_operand" "")))
6742 (clobber (reg:CC 17))])]
6743 ""
6744 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6745
6746(define_insn "*subsi_1"
6747 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6748 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6749 (match_operand:SI 2 "general_operand" "ri,rm")))
6750 (clobber (reg:CC 17))]
6751 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6752 "sub{l}\t{%2, %0|%0, %2}"
6753 [(set_attr "type" "alu")
6754 (set_attr "mode" "SI")])
6755
6756(define_insn "*subsi_1_zext"
6757 [(set (match_operand:DI 0 "register_operand" "=r")
6758 (zero_extend:DI
6759 (minus:SI (match_operand:SI 1 "register_operand" "0")
6760 (match_operand:SI 2 "general_operand" "rim"))))
6761 (clobber (reg:CC 17))]
6762 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763 "sub{l}\t{%2, %k0|%k0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "SI")])
6766
6767(define_insn "*subsi_2"
6768 [(set (reg 17)
6769 (compare
6770 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6771 (match_operand:SI 2 "general_operand" "ri,rm"))
6772 (const_int 0)))
6773 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6774 (minus:SI (match_dup 1) (match_dup 2)))]
6775 "ix86_match_ccmode (insn, CCGOCmode)
6776 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777 "sub{l}\t{%2, %0|%0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "mode" "SI")])
6780
6781(define_insn "*subsi_2_zext"
6782 [(set (reg 17)
6783 (compare
6784 (minus:SI (match_operand:SI 1 "register_operand" "0")
6785 (match_operand:SI 2 "general_operand" "rim"))
6786 (const_int 0)))
6787 (set (match_operand:DI 0 "register_operand" "=r")
6788 (zero_extend:DI
6789 (minus:SI (match_dup 1)
6790 (match_dup 2))))]
6791 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6792 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6793 "sub{l}\t{%2, %k0|%k0, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "mode" "SI")])
6796
6797(define_insn "*subsi_3"
6798 [(set (reg 17)
6799 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6800 (match_operand:SI 2 "general_operand" "ri,rm")))
6801 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6802 (minus:SI (match_dup 1) (match_dup 2)))]
6803 "ix86_match_ccmode (insn, CCmode)
6804 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6805 "sub{l}\t{%2, %0|%0, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "SI")])
6808
6809(define_insn "*subsi_3_zext"
6810 [(set (reg 17)
6811 (compare (match_operand:SI 1 "register_operand" "0")
6812 (match_operand:SI 2 "general_operand" "rim")))
6813 (set (match_operand:DI 0 "register_operand" "=r")
6814 (zero_extend:DI
6815 (minus:SI (match_dup 1)
6816 (match_dup 2))))]
6817 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6818 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6819 "sub{q}\t{%2, %0|%0, %2}"
6820 [(set_attr "type" "alu")
6821 (set_attr "mode" "DI")])
6822
6823(define_expand "subhi3"
6824 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6825 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6826 (match_operand:HI 2 "general_operand" "")))
6827 (clobber (reg:CC 17))])]
6828 "TARGET_HIMODE_MATH"
6829 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6830
6831(define_insn "*subhi_1"
6832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6833 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6834 (match_operand:HI 2 "general_operand" "ri,rm")))
6835 (clobber (reg:CC 17))]
6836 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6837 "sub{w}\t{%2, %0|%0, %2}"
6838 [(set_attr "type" "alu")
6839 (set_attr "mode" "HI")])
6840
6841(define_insn "*subhi_2"
6842 [(set (reg 17)
6843 (compare
6844 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6845 (match_operand:HI 2 "general_operand" "ri,rm"))
6846 (const_int 0)))
6847 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6848 (minus:HI (match_dup 1) (match_dup 2)))]
6849 "ix86_match_ccmode (insn, CCGOCmode)
6850 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6851 "sub{w}\t{%2, %0|%0, %2}"
6852 [(set_attr "type" "alu")
6853 (set_attr "mode" "HI")])
6854
6855(define_insn "*subhi_3"
6856 [(set (reg 17)
6857 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6858 (match_operand:HI 2 "general_operand" "ri,rm")))
6859 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6860 (minus:HI (match_dup 1) (match_dup 2)))]
6861 "ix86_match_ccmode (insn, CCmode)
6862 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6863 "sub{w}\t{%2, %0|%0, %2}"
6864 [(set_attr "type" "alu")
6865 (set_attr "mode" "HI")])
6866
6867(define_expand "subqi3"
6868 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6869 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6870 (match_operand:QI 2 "general_operand" "")))
6871 (clobber (reg:CC 17))])]
6872 "TARGET_QIMODE_MATH"
6873 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6874
6875(define_insn "*subqi_1"
6876 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6877 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6878 (match_operand:QI 2 "general_operand" "qn,qmn")))
6879 (clobber (reg:CC 17))]
6880 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6881 "sub{b}\t{%2, %0|%0, %2}"
6882 [(set_attr "type" "alu")
6883 (set_attr "mode" "QI")])
6884
6885(define_insn "*subqi_1_slp"
6886 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6887 (minus:QI (match_dup 0)
6888 (match_operand:QI 1 "general_operand" "qn,qmn")))
6889 (clobber (reg:CC 17))]
6890 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6891 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6892 "sub{b}\t{%1, %0|%0, %1}"
6893 [(set_attr "type" "alu1")
6894 (set_attr "mode" "QI")])
6895
6896(define_insn "*subqi_2"
6897 [(set (reg 17)
6898 (compare
6899 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6900 (match_operand:QI 2 "general_operand" "qi,qm"))
6901 (const_int 0)))
6902 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6903 (minus:HI (match_dup 1) (match_dup 2)))]
6904 "ix86_match_ccmode (insn, CCGOCmode)
6905 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6906 "sub{b}\t{%2, %0|%0, %2}"
6907 [(set_attr "type" "alu")
6908 (set_attr "mode" "QI")])
6909
6910(define_insn "*subqi_3"
6911 [(set (reg 17)
6912 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6913 (match_operand:QI 2 "general_operand" "qi,qm")))
6914 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6915 (minus:HI (match_dup 1) (match_dup 2)))]
6916 "ix86_match_ccmode (insn, CCmode)
6917 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6918 "sub{b}\t{%2, %0|%0, %2}"
6919 [(set_attr "type" "alu")
6920 (set_attr "mode" "QI")])
6921
6922;; The patterns that match these are at the end of this file.
6923
6924(define_expand "subxf3"
6925 [(set (match_operand:XF 0 "register_operand" "")
6926 (minus:XF (match_operand:XF 1 "register_operand" "")
6927 (match_operand:XF 2 "register_operand" "")))]
6928 "TARGET_80387"
6929 "")
6930
6931(define_expand "subdf3"
6932 [(set (match_operand:DF 0 "register_operand" "")
6933 (minus:DF (match_operand:DF 1 "register_operand" "")
6934 (match_operand:DF 2 "nonimmediate_operand" "")))]
6935 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6936 "")
6937
6938(define_expand "subsf3"
6939 [(set (match_operand:SF 0 "register_operand" "")
6940 (minus:SF (match_operand:SF 1 "register_operand" "")
6941 (match_operand:SF 2 "nonimmediate_operand" "")))]
6942 "TARGET_80387 || TARGET_SSE_MATH"
6943 "")
6944
6945;; Multiply instructions
6946
6947(define_expand "muldi3"
6948 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6949 (mult:DI (match_operand:DI 1 "register_operand" "")
6950 (match_operand:DI 2 "x86_64_general_operand" "")))
6951 (clobber (reg:CC 17))])]
6952 "TARGET_64BIT"
6953 "")
6954
6955(define_insn "*muldi3_1_rex64"
6956 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6958 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6959 (clobber (reg:CC 17))]
6960 "TARGET_64BIT
6961 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6962 "@
6963 imul{q}\t{%2, %1, %0|%0, %1, %2}
6964 imul{q}\t{%2, %1, %0|%0, %1, %2}
6965 imul{q}\t{%2, %0|%0, %2}"
6966 [(set_attr "type" "imul")
6967 (set_attr "prefix_0f" "0,0,1")
6968 (set (attr "athlon_decode")
6969 (cond [(eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (eq_attr "alternative" "1")
6972 (const_string "vector")
6973 (and (eq_attr "alternative" "2")
6974 (match_operand 1 "memory_operand" ""))
6975 (const_string "vector")]
6976 (const_string "direct")))
6977 (set_attr "mode" "DI")])
6978
6979(define_expand "mulsi3"
6980 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6981 (mult:SI (match_operand:SI 1 "register_operand" "")
6982 (match_operand:SI 2 "general_operand" "")))
6983 (clobber (reg:CC 17))])]
6984 ""
6985 "")
6986
6987(define_insn "*mulsi3_1"
6988 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6989 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6990 (match_operand:SI 2 "general_operand" "K,i,mr")))
6991 (clobber (reg:CC 17))]
6992 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6993 "@
6994 imul{l}\t{%2, %1, %0|%0, %1, %2}
6995 imul{l}\t{%2, %1, %0|%0, %1, %2}
6996 imul{l}\t{%2, %0|%0, %2}"
6997 [(set_attr "type" "imul")
6998 (set_attr "prefix_0f" "0,0,1")
6999 (set (attr "athlon_decode")
7000 (cond [(eq_attr "cpu" "athlon")
7001 (const_string "vector")
7002 (eq_attr "alternative" "1")
7003 (const_string "vector")
7004 (and (eq_attr "alternative" "2")
7005 (match_operand 1 "memory_operand" ""))
7006 (const_string "vector")]
7007 (const_string "direct")))
7008 (set_attr "mode" "SI")])
7009
7010(define_insn "*mulsi3_1_zext"
7011 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7012 (zero_extend:DI
7013 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7014 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7015 (clobber (reg:CC 17))]
7016 "TARGET_64BIT
7017 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7018 "@
7019 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7020 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7021 imul{l}\t{%2, %k0|%k0, %2}"
7022 [(set_attr "type" "imul")
7023 (set_attr "prefix_0f" "0,0,1")
7024 (set (attr "athlon_decode")
7025 (cond [(eq_attr "cpu" "athlon")
7026 (const_string "vector")
7027 (eq_attr "alternative" "1")
7028 (const_string "vector")
7029 (and (eq_attr "alternative" "2")
7030 (match_operand 1 "memory_operand" ""))
7031 (const_string "vector")]
7032 (const_string "direct")))
7033 (set_attr "mode" "SI")])
7034
7035(define_expand "mulhi3"
7036 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7037 (mult:HI (match_operand:HI 1 "register_operand" "")
7038 (match_operand:HI 2 "general_operand" "")))
7039 (clobber (reg:CC 17))])]
7040 "TARGET_HIMODE_MATH"
7041 "")
7042
7043(define_insn "*mulhi3_1"
7044 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7045 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7046 (match_operand:HI 2 "general_operand" "K,i,mr")))
7047 (clobber (reg:CC 17))]
7048 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7049 "@
7050 imul{w}\t{%2, %1, %0|%0, %1, %2}
7051 imul{w}\t{%2, %1, %0|%0, %1, %2}
7052 imul{w}\t{%2, %0|%0, %2}"
7053 [(set_attr "type" "imul")
7054 (set_attr "prefix_0f" "0,0,1")
7055 (set (attr "athlon_decode")
7056 (cond [(eq_attr "cpu" "athlon")
7057 (const_string "vector")
7058 (eq_attr "alternative" "1,2")
7059 (const_string "vector")]
7060 (const_string "direct")))
7061 (set_attr "mode" "HI")])
7062
7063(define_expand "mulqi3"
7064 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7065 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7066 (match_operand:QI 2 "register_operand" "")))
7067 (clobber (reg:CC 17))])]
7068 "TARGET_QIMODE_MATH"
7069 "")
7070
7071(define_insn "*mulqi3_1"
7072 [(set (match_operand:QI 0 "register_operand" "=a")
7073 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7074 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7075 (clobber (reg:CC 17))]
7076 "TARGET_QIMODE_MATH
7077 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7078 "mul{b}\t%2"
7079 [(set_attr "type" "imul")
7080 (set_attr "length_immediate" "0")
7081 (set (attr "athlon_decode")
7082 (if_then_else (eq_attr "cpu" "athlon")
7083 (const_string "vector")
7084 (const_string "direct")))
7085 (set_attr "mode" "QI")])
7086
7087(define_expand "umulqihi3"
7088 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7089 (mult:HI (zero_extend:HI
7090 (match_operand:QI 1 "nonimmediate_operand" ""))
7091 (zero_extend:HI
7092 (match_operand:QI 2 "register_operand" ""))))
7093 (clobber (reg:CC 17))])]
7094 "TARGET_QIMODE_MATH"
7095 "")
7096
7097(define_insn "*umulqihi3_1"
7098 [(set (match_operand:HI 0 "register_operand" "=a")
7099 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7100 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7101 (clobber (reg:CC 17))]
7102 "TARGET_QIMODE_MATH
7103 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7104 "mul{b}\t%2"
7105 [(set_attr "type" "imul")
7106 (set_attr "length_immediate" "0")
7107 (set (attr "athlon_decode")
7108 (if_then_else (eq_attr "cpu" "athlon")
7109 (const_string "vector")
7110 (const_string "direct")))
7111 (set_attr "mode" "QI")])
7112
7113(define_expand "mulqihi3"
7114 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7115 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7116 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7117 (clobber (reg:CC 17))])]
7118 "TARGET_QIMODE_MATH"
7119 "")
7120
7121(define_insn "*mulqihi3_insn"
7122 [(set (match_operand:HI 0 "register_operand" "=a")
7123 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7124 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7125 (clobber (reg:CC 17))]
7126 "TARGET_QIMODE_MATH
7127 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7128 "imul{b}\t%2"
7129 [(set_attr "type" "imul")
7130 (set_attr "length_immediate" "0")
7131 (set (attr "athlon_decode")
7132 (if_then_else (eq_attr "cpu" "athlon")
7133 (const_string "vector")
7134 (const_string "direct")))
7135 (set_attr "mode" "QI")])
7136
7137(define_expand "umulditi3"
7138 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7139 (mult:TI (zero_extend:TI
7140 (match_operand:DI 1 "nonimmediate_operand" ""))
7141 (zero_extend:TI
7142 (match_operand:DI 2 "register_operand" ""))))
7143 (clobber (reg:CC 17))])]
7144 "TARGET_64BIT"
7145 "")
7146
7147(define_insn "*umulditi3_insn"
7148 [(set (match_operand:TI 0 "register_operand" "=A")
7149 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7150 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7151 (clobber (reg:CC 17))]
7152 "TARGET_64BIT
7153 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7154 "mul{q}\t%2"
7155 [(set_attr "type" "imul")
7156 (set_attr "ppro_uops" "few")
7157 (set_attr "length_immediate" "0")
7158 (set (attr "athlon_decode")
7159 (if_then_else (eq_attr "cpu" "athlon")
7160 (const_string "vector")
7161 (const_string "double")))
7162 (set_attr "mode" "DI")])
7163
7164;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7165(define_expand "umulsidi3"
7166 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7167 (mult:DI (zero_extend:DI
7168 (match_operand:SI 1 "nonimmediate_operand" ""))
7169 (zero_extend:DI
7170 (match_operand:SI 2 "register_operand" ""))))
7171 (clobber (reg:CC 17))])]
7172 "!TARGET_64BIT"
7173 "")
7174
7175(define_insn "*umulsidi3_insn"
7176 [(set (match_operand:DI 0 "register_operand" "=A")
7177 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7178 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7179 (clobber (reg:CC 17))]
7180 "!TARGET_64BIT
7181 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7182 "mul{l}\t%2"
7183 [(set_attr "type" "imul")
7184 (set_attr "ppro_uops" "few")
7185 (set_attr "length_immediate" "0")
7186 (set (attr "athlon_decode")
7187 (if_then_else (eq_attr "cpu" "athlon")
7188 (const_string "vector")
7189 (const_string "double")))
7190 (set_attr "mode" "SI")])
7191
7192(define_expand "mulditi3"
7193 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7194 (mult:TI (sign_extend:TI
7195 (match_operand:DI 1 "nonimmediate_operand" ""))
7196 (sign_extend:TI
7197 (match_operand:DI 2 "register_operand" ""))))
7198 (clobber (reg:CC 17))])]
7199 "TARGET_64BIT"
7200 "")
7201
7202(define_insn "*mulditi3_insn"
7203 [(set (match_operand:TI 0 "register_operand" "=A")
7204 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7205 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7206 (clobber (reg:CC 17))]
7207 "TARGET_64BIT
7208 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7209 "imul{q}\t%2"
7210 [(set_attr "type" "imul")
7211 (set_attr "length_immediate" "0")
7212 (set (attr "athlon_decode")
7213 (if_then_else (eq_attr "cpu" "athlon")
7214 (const_string "vector")
7215 (const_string "double")))
7216 (set_attr "mode" "DI")])
7217
7218(define_expand "mulsidi3"
7219 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7220 (mult:DI (sign_extend:DI
7221 (match_operand:SI 1 "nonimmediate_operand" ""))
7222 (sign_extend:DI
7223 (match_operand:SI 2 "register_operand" ""))))
7224 (clobber (reg:CC 17))])]
7225 "!TARGET_64BIT"
7226 "")
7227
7228(define_insn "*mulsidi3_insn"
7229 [(set (match_operand:DI 0 "register_operand" "=A")
7230 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7231 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7232 (clobber (reg:CC 17))]
7233 "!TARGET_64BIT
7234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235 "imul{l}\t%2"
7236 [(set_attr "type" "imul")
7237 (set_attr "length_immediate" "0")
7238 (set (attr "athlon_decode")
7239 (if_then_else (eq_attr "cpu" "athlon")
7240 (const_string "vector")
7241 (const_string "double")))
7242 (set_attr "mode" "SI")])
7243
7244(define_expand "umuldi3_highpart"
7245 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7246 (truncate:DI
7247 (lshiftrt:TI
7248 (mult:TI (zero_extend:TI
7249 (match_operand:DI 1 "nonimmediate_operand" ""))
7250 (zero_extend:TI
7251 (match_operand:DI 2 "register_operand" "")))
7252 (const_int 64))))
7253 (clobber (match_scratch:DI 3 ""))
7254 (clobber (reg:CC 17))])]
7255 "TARGET_64BIT"
7256 "")
7257
7258(define_insn "*umuldi3_highpart_rex64"
7259 [(set (match_operand:DI 0 "register_operand" "=d")
7260 (truncate:DI
7261 (lshiftrt:TI
7262 (mult:TI (zero_extend:TI
7263 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7264 (zero_extend:TI
7265 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7266 (const_int 64))))
7267 (clobber (match_scratch:DI 3 "=1"))
7268 (clobber (reg:CC 17))]
7269 "TARGET_64BIT
7270 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7271 "mul{q}\t%2"
7272 [(set_attr "type" "imul")
7273 (set_attr "ppro_uops" "few")
7274 (set_attr "length_immediate" "0")
7275 (set (attr "athlon_decode")
7276 (if_then_else (eq_attr "cpu" "athlon")
7277 (const_string "vector")
7278 (const_string "double")))
7279 (set_attr "mode" "DI")])
7280
7281(define_expand "umulsi3_highpart"
7282 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7283 (truncate:SI
7284 (lshiftrt:DI
7285 (mult:DI (zero_extend:DI
7286 (match_operand:SI 1 "nonimmediate_operand" ""))
7287 (zero_extend:DI
7288 (match_operand:SI 2 "register_operand" "")))
7289 (const_int 32))))
7290 (clobber (match_scratch:SI 3 ""))
7291 (clobber (reg:CC 17))])]
7292 ""
7293 "")
7294
7295(define_insn "*umulsi3_highpart_insn"
7296 [(set (match_operand:SI 0 "register_operand" "=d")
7297 (truncate:SI
7298 (lshiftrt:DI
7299 (mult:DI (zero_extend:DI
7300 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7301 (zero_extend:DI
7302 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7303 (const_int 32))))
7304 (clobber (match_scratch:SI 3 "=1"))
7305 (clobber (reg:CC 17))]
7306 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7307 "mul{l}\t%2"
7308 [(set_attr "type" "imul")
7309 (set_attr "ppro_uops" "few")
7310 (set_attr "length_immediate" "0")
7311 (set (attr "athlon_decode")
7312 (if_then_else (eq_attr "cpu" "athlon")
7313 (const_string "vector")
7314 (const_string "double")))
7315 (set_attr "mode" "SI")])
7316
7317(define_insn "*umulsi3_highpart_zext"
7318 [(set (match_operand:DI 0 "register_operand" "=d")
7319 (zero_extend:DI (truncate:SI
7320 (lshiftrt:DI
7321 (mult:DI (zero_extend:DI
7322 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7323 (zero_extend:DI
7324 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7325 (const_int 32)))))
7326 (clobber (match_scratch:SI 3 "=1"))
7327 (clobber (reg:CC 17))]
7328 "TARGET_64BIT
7329 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7330 "mul{l}\t%2"
7331 [(set_attr "type" "imul")
7332 (set_attr "ppro_uops" "few")
7333 (set_attr "length_immediate" "0")
7334 (set (attr "athlon_decode")
7335 (if_then_else (eq_attr "cpu" "athlon")
7336 (const_string "vector")
7337 (const_string "double")))
7338 (set_attr "mode" "SI")])
7339
7340(define_expand "smuldi3_highpart"
7341 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7342 (truncate:DI
7343 (lshiftrt:TI
7344 (mult:TI (sign_extend:TI
7345 (match_operand:DI 1 "nonimmediate_operand" ""))
7346 (sign_extend:TI
7347 (match_operand:DI 2 "register_operand" "")))
7348 (const_int 64))))
7349 (clobber (match_scratch:DI 3 ""))
7350 (clobber (reg:CC 17))])]
7351 "TARGET_64BIT"
7352 "")
7353
7354(define_insn "*smuldi3_highpart_rex64"
7355 [(set (match_operand:DI 0 "register_operand" "=d")
7356 (truncate:DI
7357 (lshiftrt:TI
7358 (mult:TI (sign_extend:TI
7359 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7360 (sign_extend:TI
7361 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7362 (const_int 64))))
7363 (clobber (match_scratch:DI 3 "=1"))
7364 (clobber (reg:CC 17))]
7365 "TARGET_64BIT
7366 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7367 "imul{q}\t%2"
7368 [(set_attr "type" "imul")
7369 (set_attr "ppro_uops" "few")
7370 (set (attr "athlon_decode")
7371 (if_then_else (eq_attr "cpu" "athlon")
7372 (const_string "vector")
7373 (const_string "double")))
7374 (set_attr "mode" "DI")])
7375
7376(define_expand "smulsi3_highpart"
7377 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7378 (truncate:SI
7379 (lshiftrt:DI
7380 (mult:DI (sign_extend:DI
7381 (match_operand:SI 1 "nonimmediate_operand" ""))
7382 (sign_extend:DI
7383 (match_operand:SI 2 "register_operand" "")))
7384 (const_int 32))))
7385 (clobber (match_scratch:SI 3 ""))
7386 (clobber (reg:CC 17))])]
7387 ""
7388 "")
7389
7390(define_insn "*smulsi3_highpart_insn"
7391 [(set (match_operand:SI 0 "register_operand" "=d")
7392 (truncate:SI
7393 (lshiftrt:DI
7394 (mult:DI (sign_extend:DI
7395 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7396 (sign_extend:DI
7397 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7398 (const_int 32))))
7399 (clobber (match_scratch:SI 3 "=1"))
7400 (clobber (reg:CC 17))]
7401 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7402 "imul{l}\t%2"
7403 [(set_attr "type" "imul")
7404 (set_attr "ppro_uops" "few")
7405 (set (attr "athlon_decode")
7406 (if_then_else (eq_attr "cpu" "athlon")
7407 (const_string "vector")
7408 (const_string "double")))
7409 (set_attr "mode" "SI")])
7410
7411(define_insn "*smulsi3_highpart_zext"
7412 [(set (match_operand:DI 0 "register_operand" "=d")
7413 (zero_extend:DI (truncate:SI
7414 (lshiftrt:DI
7415 (mult:DI (sign_extend:DI
7416 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7417 (sign_extend:DI
7418 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7419 (const_int 32)))))
7420 (clobber (match_scratch:SI 3 "=1"))
7421 (clobber (reg:CC 17))]
7422 "TARGET_64BIT
7423 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7424 "imul{l}\t%2"
7425 [(set_attr "type" "imul")
7426 (set_attr "ppro_uops" "few")
7427 (set (attr "athlon_decode")
7428 (if_then_else (eq_attr "cpu" "athlon")
7429 (const_string "vector")
7430 (const_string "double")))
7431 (set_attr "mode" "SI")])
7432
7433;; The patterns that match these are at the end of this file.
7434
7435(define_expand "mulxf3"
7436 [(set (match_operand:XF 0 "register_operand" "")
7437 (mult:XF (match_operand:XF 1 "register_operand" "")
7438 (match_operand:XF 2 "register_operand" "")))]
7439 "TARGET_80387"
7440 "")
7441
7442(define_expand "muldf3"
7443 [(set (match_operand:DF 0 "register_operand" "")
7444 (mult:DF (match_operand:DF 1 "register_operand" "")
7445 (match_operand:DF 2 "nonimmediate_operand" "")))]
7446 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7447 "")
7448
7449(define_expand "mulsf3"
7450 [(set (match_operand:SF 0 "register_operand" "")
7451 (mult:SF (match_operand:SF 1 "register_operand" "")
7452 (match_operand:SF 2 "nonimmediate_operand" "")))]
7453 "TARGET_80387 || TARGET_SSE_MATH"
7454 "")
7455
7456;; Divide instructions
7457
7458(define_insn "divqi3"
7459 [(set (match_operand:QI 0 "register_operand" "=a")
7460 (div:QI (match_operand:HI 1 "register_operand" "0")
7461 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7462 (clobber (reg:CC 17))]
7463 "TARGET_QIMODE_MATH"
7464 "idiv{b}\t%2"
7465 [(set_attr "type" "idiv")
7466 (set_attr "mode" "QI")
7467 (set_attr "ppro_uops" "few")])
7468
7469(define_insn "udivqi3"
7470 [(set (match_operand:QI 0 "register_operand" "=a")
7471 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7472 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7473 (clobber (reg:CC 17))]
7474 "TARGET_QIMODE_MATH"
7475 "div{b}\t%2"
7476 [(set_attr "type" "idiv")
7477 (set_attr "mode" "QI")
7478 (set_attr "ppro_uops" "few")])
7479
7480;; The patterns that match these are at the end of this file.
7481
7482(define_expand "divxf3"
7483 [(set (match_operand:XF 0 "register_operand" "")
7484 (div:XF (match_operand:XF 1 "register_operand" "")
7485 (match_operand:XF 2 "register_operand" "")))]
7486 "TARGET_80387"
7487 "")
7488
7489(define_expand "divdf3"
7490 [(set (match_operand:DF 0 "register_operand" "")
7491 (div:DF (match_operand:DF 1 "register_operand" "")
7492 (match_operand:DF 2 "nonimmediate_operand" "")))]
7493 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7494 "")
7495
7496(define_expand "divsf3"
7497 [(set (match_operand:SF 0 "register_operand" "")
7498 (div:SF (match_operand:SF 1 "register_operand" "")
7499 (match_operand:SF 2 "nonimmediate_operand" "")))]
7500 "TARGET_80387 || TARGET_SSE_MATH"
7501 "")
7502
7503;; Remainder instructions.
7504
7505(define_expand "divmoddi4"
7506 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7507 (div:DI (match_operand:DI 1 "register_operand" "")
7508 (match_operand:DI 2 "nonimmediate_operand" "")))
7509 (set (match_operand:DI 3 "register_operand" "")
7510 (mod:DI (match_dup 1) (match_dup 2)))
7511 (clobber (reg:CC 17))])]
7512 "TARGET_64BIT"
7513 "")
7514
7515;; Allow to come the parameter in eax or edx to avoid extra moves.
7516;; Penalize eax case slightly because it results in worse scheduling
7517;; of code.
7518(define_insn "*divmoddi4_nocltd_rex64"
7519 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7520 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7521 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7522 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7523 (mod:DI (match_dup 2) (match_dup 3)))
7524 (clobber (reg:CC 17))]
7525 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7526 "#"
7527 [(set_attr "type" "multi")])
7528
7529(define_insn "*divmoddi4_cltd_rex64"
7530 [(set (match_operand:DI 0 "register_operand" "=a")
7531 (div:DI (match_operand:DI 2 "register_operand" "a")
7532 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7533 (set (match_operand:DI 1 "register_operand" "=&d")
7534 (mod:DI (match_dup 2) (match_dup 3)))
7535 (clobber (reg:CC 17))]
7536 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7537 "#"
7538 [(set_attr "type" "multi")])
7539
7540(define_insn "*divmoddi_noext_rex64"
7541 [(set (match_operand:DI 0 "register_operand" "=a")
7542 (div:DI (match_operand:DI 1 "register_operand" "0")
7543 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7544 (set (match_operand:DI 3 "register_operand" "=d")
7545 (mod:DI (match_dup 1) (match_dup 2)))
7546 (use (match_operand:DI 4 "register_operand" "3"))
7547 (clobber (reg:CC 17))]
7548 "TARGET_64BIT"
7549 "idiv{q}\t%2"
7550 [(set_attr "type" "idiv")
7551 (set_attr "mode" "DI")
7552 (set_attr "ppro_uops" "few")])
7553
7554(define_split
7555 [(set (match_operand:DI 0 "register_operand" "")
7556 (div:DI (match_operand:DI 1 "register_operand" "")
7557 (match_operand:DI 2 "nonimmediate_operand" "")))
7558 (set (match_operand:DI 3 "register_operand" "")
7559 (mod:DI (match_dup 1) (match_dup 2)))
7560 (clobber (reg:CC 17))]
7561 "TARGET_64BIT && reload_completed"
7562 [(parallel [(set (match_dup 3)
7563 (ashiftrt:DI (match_dup 4) (const_int 63)))
7564 (clobber (reg:CC 17))])
7565 (parallel [(set (match_dup 0)
7566 (div:DI (reg:DI 0) (match_dup 2)))
7567 (set (match_dup 3)
7568 (mod:DI (reg:DI 0) (match_dup 2)))
7569 (use (match_dup 3))
7570 (clobber (reg:CC 17))])]
7571{
7572 /* Avoid use of cltd in favor of a mov+shift. */
7573 if (!TARGET_USE_CLTD && !optimize_size)
7574 {
7575 if (true_regnum (operands[1]))
7576 emit_move_insn (operands[0], operands[1]);
7577 else
7578 emit_move_insn (operands[3], operands[1]);
7579 operands[4] = operands[3];
7580 }
7581 else
7582 {
7583 if (true_regnum (operands[1]))
7584 abort();
7585 operands[4] = operands[1];
7586 }
7587})
7588
7589
7590(define_expand "divmodsi4"
7591 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7592 (div:SI (match_operand:SI 1 "register_operand" "")
7593 (match_operand:SI 2 "nonimmediate_operand" "")))
7594 (set (match_operand:SI 3 "register_operand" "")
7595 (mod:SI (match_dup 1) (match_dup 2)))
7596 (clobber (reg:CC 17))])]
7597 ""
7598 "")
7599
7600;; Allow to come the parameter in eax or edx to avoid extra moves.
7601;; Penalize eax case slightly because it results in worse scheduling
7602;; of code.
7603(define_insn "*divmodsi4_nocltd"
7604 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7605 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7606 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7607 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7608 (mod:SI (match_dup 2) (match_dup 3)))
7609 (clobber (reg:CC 17))]
7610 "!optimize_size && !TARGET_USE_CLTD"
7611 "#"
7612 [(set_attr "type" "multi")])
7613
7614(define_insn "*divmodsi4_cltd"
7615 [(set (match_operand:SI 0 "register_operand" "=a")
7616 (div:SI (match_operand:SI 2 "register_operand" "a")
7617 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7618 (set (match_operand:SI 1 "register_operand" "=&d")
7619 (mod:SI (match_dup 2) (match_dup 3)))
7620 (clobber (reg:CC 17))]
7621 "optimize_size || TARGET_USE_CLTD"
7622 "#"
7623 [(set_attr "type" "multi")])
7624
7625(define_insn "*divmodsi_noext"
7626 [(set (match_operand:SI 0 "register_operand" "=a")
7627 (div:SI (match_operand:SI 1 "register_operand" "0")
7628 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7629 (set (match_operand:SI 3 "register_operand" "=d")
7630 (mod:SI (match_dup 1) (match_dup 2)))
7631 (use (match_operand:SI 4 "register_operand" "3"))
7632 (clobber (reg:CC 17))]
7633 ""
7634 "idiv{l}\t%2"
7635 [(set_attr "type" "idiv")
7636 (set_attr "mode" "SI")
7637 (set_attr "ppro_uops" "few")])
7638
7639(define_split
7640 [(set (match_operand:SI 0 "register_operand" "")
7641 (div:SI (match_operand:SI 1 "register_operand" "")
7642 (match_operand:SI 2 "nonimmediate_operand" "")))
7643 (set (match_operand:SI 3 "register_operand" "")
7644 (mod:SI (match_dup 1) (match_dup 2)))
7645 (clobber (reg:CC 17))]
7646 "reload_completed"
7647 [(parallel [(set (match_dup 3)
7648 (ashiftrt:SI (match_dup 4) (const_int 31)))
7649 (clobber (reg:CC 17))])
7650 (parallel [(set (match_dup 0)
7651 (div:SI (reg:SI 0) (match_dup 2)))
7652 (set (match_dup 3)
7653 (mod:SI (reg:SI 0) (match_dup 2)))
7654 (use (match_dup 3))
7655 (clobber (reg:CC 17))])]
7656{
7657 /* Avoid use of cltd in favor of a mov+shift. */
7658 if (!TARGET_USE_CLTD && !optimize_size)
7659 {
7660 if (true_regnum (operands[1]))
7661 emit_move_insn (operands[0], operands[1]);
7662 else
7663 emit_move_insn (operands[3], operands[1]);
7664 operands[4] = operands[3];
7665 }
7666 else
7667 {
7668 if (true_regnum (operands[1]))
7669 abort();
7670 operands[4] = operands[1];
7671 }
7672})
7673;; %%% Split me.
7674(define_insn "divmodhi4"
7675 [(set (match_operand:HI 0 "register_operand" "=a")
7676 (div:HI (match_operand:HI 1 "register_operand" "0")
7677 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7678 (set (match_operand:HI 3 "register_operand" "=&d")
7679 (mod:HI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC 17))]
7681 "TARGET_HIMODE_MATH"
7682 "cwtd\;idiv{w}\t%2"
7683 [(set_attr "type" "multi")
7684 (set_attr "length_immediate" "0")
7685 (set_attr "mode" "SI")])
7686
7687(define_insn "udivmoddi4"
7688 [(set (match_operand:DI 0 "register_operand" "=a")
7689 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7690 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7691 (set (match_operand:DI 3 "register_operand" "=&d")
7692 (umod:DI (match_dup 1) (match_dup 2)))
7693 (clobber (reg:CC 17))]
7694 "TARGET_64BIT"
7695 "xor{q}\t%3, %3\;div{q}\t%2"
7696 [(set_attr "type" "multi")
7697 (set_attr "length_immediate" "0")
7698 (set_attr "mode" "DI")])
7699
7700(define_insn "*udivmoddi4_noext"
7701 [(set (match_operand:DI 0 "register_operand" "=a")
7702 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7703 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7704 (set (match_operand:DI 3 "register_operand" "=d")
7705 (umod:DI (match_dup 1) (match_dup 2)))
7706 (use (match_dup 3))
7707 (clobber (reg:CC 17))]
7708 "TARGET_64BIT"
7709 "div{q}\t%2"
7710 [(set_attr "type" "idiv")
7711 (set_attr "ppro_uops" "few")
7712 (set_attr "mode" "DI")])
7713
7714(define_split
7715 [(set (match_operand:DI 0 "register_operand" "")
7716 (udiv:DI (match_operand:DI 1 "register_operand" "")
7717 (match_operand:DI 2 "nonimmediate_operand" "")))
7718 (set (match_operand:DI 3 "register_operand" "")
7719 (umod:DI (match_dup 1) (match_dup 2)))
7720 (clobber (reg:CC 17))]
7721 "TARGET_64BIT && reload_completed"
7722 [(set (match_dup 3) (const_int 0))
7723 (parallel [(set (match_dup 0)
7724 (udiv:DI (match_dup 1) (match_dup 2)))
7725 (set (match_dup 3)
7726 (umod:DI (match_dup 1) (match_dup 2)))
7727 (use (match_dup 3))
7728 (clobber (reg:CC 17))])]
7729 "")
7730
7731(define_insn "udivmodsi4"
7732 [(set (match_operand:SI 0 "register_operand" "=a")
7733 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7734 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7735 (set (match_operand:SI 3 "register_operand" "=&d")
7736 (umod:SI (match_dup 1) (match_dup 2)))
7737 (clobber (reg:CC 17))]
7738 ""
7739 "xor{l}\t%3, %3\;div{l}\t%2"
7740 [(set_attr "type" "multi")
7741 (set_attr "length_immediate" "0")
7742 (set_attr "mode" "SI")])
7743
7744(define_insn "*udivmodsi4_noext"
7745 [(set (match_operand:SI 0 "register_operand" "=a")
7746 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7747 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7748 (set (match_operand:SI 3 "register_operand" "=d")
7749 (umod:SI (match_dup 1) (match_dup 2)))
7750 (use (match_dup 3))
7751 (clobber (reg:CC 17))]
7752 ""
7753 "div{l}\t%2"
7754 [(set_attr "type" "idiv")
7755 (set_attr "ppro_uops" "few")
7756 (set_attr "mode" "SI")])
7757
7758(define_split
7759 [(set (match_operand:SI 0 "register_operand" "")
7760 (udiv:SI (match_operand:SI 1 "register_operand" "")
7761 (match_operand:SI 2 "nonimmediate_operand" "")))
7762 (set (match_operand:SI 3 "register_operand" "")
7763 (umod:SI (match_dup 1) (match_dup 2)))
7764 (clobber (reg:CC 17))]
7765 "reload_completed"
7766 [(set (match_dup 3) (const_int 0))
7767 (parallel [(set (match_dup 0)
7768 (udiv:SI (match_dup 1) (match_dup 2)))
7769 (set (match_dup 3)
7770 (umod:SI (match_dup 1) (match_dup 2)))
7771 (use (match_dup 3))
7772 (clobber (reg:CC 17))])]
7773 "")
7774
7775(define_expand "udivmodhi4"
7776 [(set (match_dup 4) (const_int 0))
7777 (parallel [(set (match_operand:HI 0 "register_operand" "")
7778 (udiv:HI (match_operand:HI 1 "register_operand" "")
7779 (match_operand:HI 2 "nonimmediate_operand" "")))
7780 (set (match_operand:HI 3 "register_operand" "")
7781 (umod:HI (match_dup 1) (match_dup 2)))
7782 (use (match_dup 4))
7783 (clobber (reg:CC 17))])]
7784 "TARGET_HIMODE_MATH"
7785 "operands[4] = gen_reg_rtx (HImode);")
7786
7787(define_insn "*udivmodhi_noext"
7788 [(set (match_operand:HI 0 "register_operand" "=a")
7789 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7790 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7791 (set (match_operand:HI 3 "register_operand" "=d")
7792 (umod:HI (match_dup 1) (match_dup 2)))
7793 (use (match_operand:HI 4 "register_operand" "3"))
7794 (clobber (reg:CC 17))]
7795 ""
7796 "div{w}\t%2"
7797 [(set_attr "type" "idiv")
7798 (set_attr "mode" "HI")
7799 (set_attr "ppro_uops" "few")])
7800
7801;; We can not use div/idiv for double division, because it causes
7802;; "division by zero" on the overflow and that's not what we expect
7803;; from truncate. Because true (non truncating) double division is
7804;; never generated, we can't create this insn anyway.
7805;
7806;(define_insn ""
7807; [(set (match_operand:SI 0 "register_operand" "=a")
7808; (truncate:SI
7809; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7810; (zero_extend:DI
7811; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7812; (set (match_operand:SI 3 "register_operand" "=d")
7813; (truncate:SI
7814; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7815; (clobber (reg:CC 17))]
7816; ""
7817; "div{l}\t{%2, %0|%0, %2}"
7818; [(set_attr "type" "idiv")
7819; (set_attr "ppro_uops" "few")])
7820
7821;;- Logical AND instructions
7822
7823;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7824;; Note that this excludes ah.
7825
7826(define_insn "*testdi_1_rex64"
7827 [(set (reg 17)
7828 (compare
7829 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7830 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7831 (const_int 0)))]
7832 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7834 "@
7835 test{l}\t{%k1, %k0|%k0, %k1}
7836 test{l}\t{%k1, %k0|%k0, %k1}
7837 test{q}\t{%1, %0|%0, %1}
7838 test{q}\t{%1, %0|%0, %1}
7839 test{q}\t{%1, %0|%0, %1}"
7840 [(set_attr "type" "test")
7841 (set_attr "modrm" "0,1,0,1,1")
7842 (set_attr "mode" "SI,SI,DI,DI,DI")
7843 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7844
7845(define_insn "testsi_1"
7846 [(set (reg 17)
7847 (compare
7848 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7849 (match_operand:SI 1 "general_operand" "in,in,rin"))
7850 (const_int 0)))]
7851 "ix86_match_ccmode (insn, CCNOmode)
7852 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7853 "test{l}\t{%1, %0|%0, %1}"
7854 [(set_attr "type" "test")
7855 (set_attr "modrm" "0,1,1")
7856 (set_attr "mode" "SI")
7857 (set_attr "pent_pair" "uv,np,uv")])
7858
7859(define_expand "testsi_ccno_1"
7860 [(set (reg:CCNO 17)
7861 (compare:CCNO
7862 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7863 (match_operand:SI 1 "nonmemory_operand" ""))
7864 (const_int 0)))]
7865 ""
7866 "")
7867
7868(define_insn "*testhi_1"
7869 [(set (reg 17)
7870 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7871 (match_operand:HI 1 "general_operand" "n,n,rn"))
7872 (const_int 0)))]
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7875 "test{w}\t{%1, %0|%0, %1}"
7876 [(set_attr "type" "test")
7877 (set_attr "modrm" "0,1,1")
7878 (set_attr "mode" "HI")
7879 (set_attr "pent_pair" "uv,np,uv")])
7880
7881(define_expand "testqi_ccz_1"
7882 [(set (reg:CCZ 17)
7883 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7884 (match_operand:QI 1 "nonmemory_operand" ""))
7885 (const_int 0)))]
7886 ""
7887 "")
7888
7889(define_insn "*testqi_1_maybe_si"
7890 [(set (reg 17)
7891 (compare
7892 (and:QI
7893 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7894 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7895 (const_int 0)))]
7896 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7897 && ix86_match_ccmode (insn,
7898 GET_CODE (operands[1]) == CONST_INT
7899 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7900{
7901 if (which_alternative == 3)
7902 {
7903 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7904 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7905 return "test{l}\t{%1, %k0|%k0, %1}";
7906 }
7907 return "test{b}\t{%1, %0|%0, %1}";
7908}
7909 [(set_attr "type" "test")
7910 (set_attr "modrm" "0,1,1,1")
7911 (set_attr "mode" "QI,QI,QI,SI")
7912 (set_attr "pent_pair" "uv,np,uv,np")])
7913
7914(define_insn "*testqi_1"
7915 [(set (reg 17)
7916 (compare
7917 (and:QI
7918 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7919 (match_operand:QI 1 "general_operand" "n,n,qn"))
7920 (const_int 0)))]
7921 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7922 && ix86_match_ccmode (insn, CCNOmode)"
7923 "test{b}\t{%1, %0|%0, %1}"
7924 [(set_attr "type" "test")
7925 (set_attr "modrm" "0,1,1")
7926 (set_attr "mode" "QI")
7927 (set_attr "pent_pair" "uv,np,uv")])
7928
7929(define_expand "testqi_ext_ccno_0"
7930 [(set (reg:CCNO 17)
7931 (compare:CCNO
7932 (and:SI
7933 (zero_extract:SI
7934 (match_operand 0 "ext_register_operand" "")
7935 (const_int 8)
7936 (const_int 8))
7937 (match_operand 1 "const_int_operand" ""))
7938 (const_int 0)))]
7939 ""
7940 "")
7941
7942(define_insn "*testqi_ext_0"
7943 [(set (reg 17)
7944 (compare
7945 (and:SI
7946 (zero_extract:SI
7947 (match_operand 0 "ext_register_operand" "Q")
7948 (const_int 8)
7949 (const_int 8))
7950 (match_operand 1 "const_int_operand" "n"))
7951 (const_int 0)))]
7952 "ix86_match_ccmode (insn, CCNOmode)"
7953 "test{b}\t{%1, %h0|%h0, %1}"
7954 [(set_attr "type" "test")
7955 (set_attr "mode" "QI")
7956 (set_attr "length_immediate" "1")
7957 (set_attr "pent_pair" "np")])
7958
7959(define_insn "*testqi_ext_1"
7960 [(set (reg 17)
7961 (compare
7962 (and:SI
7963 (zero_extract:SI
7964 (match_operand 0 "ext_register_operand" "Q")
7965 (const_int 8)
7966 (const_int 8))
7967 (zero_extend:SI
7968 (match_operand:QI 1 "general_operand" "Qm")))
7969 (const_int 0)))]
7970 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7971 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7972 "test{b}\t{%1, %h0|%h0, %1}"
7973 [(set_attr "type" "test")
7974 (set_attr "mode" "QI")])
7975
7976(define_insn "*testqi_ext_1_rex64"
7977 [(set (reg 17)
7978 (compare
7979 (and:SI
7980 (zero_extract:SI
7981 (match_operand 0 "ext_register_operand" "Q")
7982 (const_int 8)
7983 (const_int 8))
7984 (zero_extend:SI
7985 (match_operand:QI 1 "register_operand" "Q")))
7986 (const_int 0)))]
7987 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7988 "test{b}\t{%1, %h0|%h0, %1}"
7989 [(set_attr "type" "test")
7990 (set_attr "mode" "QI")])
7991
7992(define_insn "*testqi_ext_2"
7993 [(set (reg 17)
7994 (compare
7995 (and:SI
7996 (zero_extract:SI
7997 (match_operand 0 "ext_register_operand" "Q")
7998 (const_int 8)
7999 (const_int 8))
8000 (zero_extract:SI
8001 (match_operand 1 "ext_register_operand" "Q")
8002 (const_int 8)
8003 (const_int 8)))
8004 (const_int 0)))]
8005 "ix86_match_ccmode (insn, CCNOmode)"
8006 "test{b}\t{%h1, %h0|%h0, %h1}"
8007 [(set_attr "type" "test")
8008 (set_attr "mode" "QI")])
8009
8010;; Combine likes to form bit extractions for some tests. Humor it.
8011(define_insn "*testqi_ext_3"
8012 [(set (reg 17)
8013 (compare (zero_extract:SI
8014 (match_operand 0 "nonimmediate_operand" "rm")
8015 (match_operand:SI 1 "const_int_operand" "")
8016 (match_operand:SI 2 "const_int_operand" ""))
8017 (const_int 0)))]
8018 "ix86_match_ccmode (insn, CCNOmode)
8019 && (GET_MODE (operands[0]) == SImode
8020 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8021 || GET_MODE (operands[0]) == HImode
8022 || GET_MODE (operands[0]) == QImode)"
8023 "#")
8024
8025(define_insn "*testqi_ext_3_rex64"
8026 [(set (reg 17)
8027 (compare (zero_extract:DI
8028 (match_operand 0 "nonimmediate_operand" "rm")
8029 (match_operand:DI 1 "const_int_operand" "")
8030 (match_operand:DI 2 "const_int_operand" ""))
8031 (const_int 0)))]
8032 "TARGET_64BIT
8033 && ix86_match_ccmode (insn, CCNOmode)
8034 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8035 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8036 /* Ensure that resulting mask is zero or sign extended operand. */
8037 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8038 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8039 && INTVAL (operands[1]) > 32))
8040 && (GET_MODE (operands[0]) == SImode
8041 || GET_MODE (operands[0]) == DImode
8042 || GET_MODE (operands[0]) == HImode
8043 || GET_MODE (operands[0]) == QImode)"
8044 "#")
8045
8046(define_split
8047 [(set (match_operand 0 "flags_reg_operand" "")
8048 (match_operator 1 "compare_operator"
8049 [(zero_extract
8050 (match_operand 2 "nonimmediate_operand" "")
8051 (match_operand 3 "const_int_operand" "")
8052 (match_operand 4 "const_int_operand" ""))
8053 (const_int 0)]))]
8054 "ix86_match_ccmode (insn, CCNOmode)"
8055 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8056{
8057 rtx val = operands[2];
8058 HOST_WIDE_INT len = INTVAL (operands[3]);
8059 HOST_WIDE_INT pos = INTVAL (operands[4]);
8060 HOST_WIDE_INT mask;
8061 enum machine_mode mode, submode;
8062
8063 mode = GET_MODE (val);
8064 if (GET_CODE (val) == MEM)
8065 {
8066 /* ??? Combine likes to put non-volatile mem extractions in QImode
8067 no matter the size of the test. So find a mode that works. */
8068 if (! MEM_VOLATILE_P (val))
8069 {
8070 mode = smallest_mode_for_size (pos + len, MODE_INT);
8071 val = adjust_address (val, mode, 0);
8072 }
8073 }
8074 else if (GET_CODE (val) == SUBREG
8075 && (submode = GET_MODE (SUBREG_REG (val)),
8076 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8077 && pos + len <= GET_MODE_BITSIZE (submode))
8078 {
8079 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8080 mode = submode;
8081 val = SUBREG_REG (val);
8082 }
8083 else if (mode == HImode && pos + len <= 8)
8084 {
8085 /* Small HImode tests can be converted to QImode. */
8086 mode = QImode;
8087 val = gen_lowpart (QImode, val);
8088 }
8089
8090 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8091 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8092
8093 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8094})
8095
8096;; Convert HImode/SImode test instructions with immediate to QImode ones.
8097;; i386 does not allow to encode test with 8bit sign extended immediate, so
8098;; this is relatively important trick.
8099;; Do the conversion only post-reload to avoid limiting of the register class
8100;; to QI regs.
8101(define_split
8102 [(set (match_operand 0 "flags_reg_operand" "")
8103 (match_operator 1 "compare_operator"
8104 [(and (match_operand 2 "register_operand" "")
8105 (match_operand 3 "const_int_operand" ""))
8106 (const_int 0)]))]
8107 "reload_completed
8108 && QI_REG_P (operands[2])
8109 && GET_MODE (operands[2]) != QImode
8110 && ((ix86_match_ccmode (insn, CCZmode)
8111 && !(INTVAL (operands[3]) & ~(255 << 8)))
8112 || (ix86_match_ccmode (insn, CCNOmode)
8113 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8114 [(set (match_dup 0)
8115 (match_op_dup 1
8116 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8117 (match_dup 3))
8118 (const_int 0)]))]
8119 "operands[2] = gen_lowpart (SImode, operands[2]);
8120 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8121
8122(define_split
8123 [(set (match_operand 0 "flags_reg_operand" "")
8124 (match_operator 1 "compare_operator"
8125 [(and (match_operand 2 "nonimmediate_operand" "")
8126 (match_operand 3 "const_int_operand" ""))
8127 (const_int 0)]))]
8128 "reload_completed
8129 && GET_MODE (operands[2]) != QImode
8130 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8131 && ((ix86_match_ccmode (insn, CCZmode)
8132 && !(INTVAL (operands[3]) & ~255))
8133 || (ix86_match_ccmode (insn, CCNOmode)
8134 && !(INTVAL (operands[3]) & ~127)))"
8135 [(set (match_dup 0)
8136 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8137 (const_int 0)]))]
8138 "operands[2] = gen_lowpart (QImode, operands[2]);
8139 operands[3] = gen_lowpart (QImode, operands[3]);")
8140
8141
8142;; %%% This used to optimize known byte-wide and operations to memory,
8143;; and sometimes to QImode registers. If this is considered useful,
8144;; it should be done with splitters.
8145
8146(define_expand "anddi3"
8147 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8148 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8149 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8150 (clobber (reg:CC 17))]
8151 "TARGET_64BIT"
8152 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8153
8154(define_insn "*anddi_1_rex64"
8155 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8156 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8157 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8158 (clobber (reg:CC 17))]
8159 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8160{
8161 switch (get_attr_type (insn))
8162 {
8163 case TYPE_IMOVX:
8164 {
8165 enum machine_mode mode;
8166
8167 if (GET_CODE (operands[2]) != CONST_INT)
8168 abort ();
8169 if (INTVAL (operands[2]) == 0xff)
8170 mode = QImode;
8171 else if (INTVAL (operands[2]) == 0xffff)
8172 mode = HImode;
8173 else
8174 abort ();
8175
8176 operands[1] = gen_lowpart (mode, operands[1]);
8177 if (mode == QImode)
8178 return "movz{bq|x}\t{%1,%0|%0, %1}";
8179 else
8180 return "movz{wq|x}\t{%1,%0|%0, %1}";
8181 }
8182
8183 default:
8184 if (! rtx_equal_p (operands[0], operands[1]))
8185 abort ();
8186 if (get_attr_mode (insn) == MODE_SI)
8187 return "and{l}\t{%k2, %k0|%k0, %k2}";
8188 else
8189 return "and{q}\t{%2, %0|%0, %2}";
8190 }
8191}
8192 [(set_attr "type" "alu,alu,alu,imovx")
8193 (set_attr "length_immediate" "*,*,*,0")
8194 (set_attr "mode" "SI,DI,DI,DI")])
8195
8196(define_insn "*anddi_2"
8197 [(set (reg 17)
8198 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8199 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8200 (const_int 0)))
8201 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8202 (and:DI (match_dup 1) (match_dup 2)))]
8203 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8204 && ix86_binary_operator_ok (AND, DImode, operands)"
8205 "@
8206 and{l}\t{%k2, %k0|%k0, %k2}
8207 and{q}\t{%2, %0|%0, %2}
8208 and{q}\t{%2, %0|%0, %2}"
8209 [(set_attr "type" "alu")
8210 (set_attr "mode" "SI,DI,DI")])
8211
8212(define_expand "andsi3"
8213 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8214 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8215 (match_operand:SI 2 "general_operand" "")))
8216 (clobber (reg:CC 17))]
8217 ""
8218 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8219
8220(define_insn "*andsi_1"
8221 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8222 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8223 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8224 (clobber (reg:CC 17))]
8225 "ix86_binary_operator_ok (AND, SImode, operands)"
8226{
8227 switch (get_attr_type (insn))
8228 {
8229 case TYPE_IMOVX:
8230 {
8231 enum machine_mode mode;
8232
8233 if (GET_CODE (operands[2]) != CONST_INT)
8234 abort ();
8235 if (INTVAL (operands[2]) == 0xff)
8236 mode = QImode;
8237 else if (INTVAL (operands[2]) == 0xffff)
8238 mode = HImode;
8239 else
8240 abort ();
8241
8242 operands[1] = gen_lowpart (mode, operands[1]);
8243 if (mode == QImode)
8244 return "movz{bl|x}\t{%1,%0|%0, %1}";
8245 else
8246 return "movz{wl|x}\t{%1,%0|%0, %1}";
8247 }
8248
8249 default:
8250 if (! rtx_equal_p (operands[0], operands[1]))
8251 abort ();
8252 return "and{l}\t{%2, %0|%0, %2}";
8253 }
8254}
8255 [(set_attr "type" "alu,alu,imovx")
8256 (set_attr "length_immediate" "*,*,0")
8257 (set_attr "mode" "SI")])
8258
8259(define_split
8260 [(set (match_operand 0 "register_operand" "")
8261 (and (match_dup 0)
8262 (const_int -65536)))
8263 (clobber (reg:CC 17))]
8264 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8265 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8266 "operands[1] = gen_lowpart (HImode, operands[0]);")
8267
8268(define_split
8269 [(set (match_operand 0 "ext_register_operand" "")
8270 (and (match_dup 0)
8271 (const_int -256)))
8272 (clobber (reg:CC 17))]
8273 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8274 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8275 "operands[1] = gen_lowpart (QImode, operands[0]);")
8276
8277(define_split
8278 [(set (match_operand 0 "ext_register_operand" "")
8279 (and (match_dup 0)
8280 (const_int -65281)))
8281 (clobber (reg:CC 17))]
8282 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8283 [(parallel [(set (zero_extract:SI (match_dup 0)
8284 (const_int 8)
8285 (const_int 8))
8286 (xor:SI
8287 (zero_extract:SI (match_dup 0)
8288 (const_int 8)
8289 (const_int 8))
8290 (zero_extract:SI (match_dup 0)
8291 (const_int 8)
8292 (const_int 8))))
8293 (clobber (reg:CC 17))])]
8294 "operands[0] = gen_lowpart (SImode, operands[0]);")
8295
8296;; See comment for addsi_1_zext why we do use nonimmediate_operand
8297(define_insn "*andsi_1_zext"
8298 [(set (match_operand:DI 0 "register_operand" "=r")
8299 (zero_extend:DI
8300 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8301 (match_operand:SI 2 "general_operand" "rim"))))
8302 (clobber (reg:CC 17))]
8303 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8304 "and{l}\t{%2, %k0|%k0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "SI")])
8307
8308(define_insn "*andsi_2"
8309 [(set (reg 17)
8310 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8311 (match_operand:SI 2 "general_operand" "rim,ri"))
8312 (const_int 0)))
8313 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8314 (and:SI (match_dup 1) (match_dup 2)))]
8315 "ix86_match_ccmode (insn, CCNOmode)
8316 && ix86_binary_operator_ok (AND, SImode, operands)"
8317 "and{l}\t{%2, %0|%0, %2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "SI")])
8320
8321;; See comment for addsi_1_zext why we do use nonimmediate_operand
8322(define_insn "*andsi_2_zext"
8323 [(set (reg 17)
8324 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8325 (match_operand:SI 2 "general_operand" "rim"))
8326 (const_int 0)))
8327 (set (match_operand:DI 0 "register_operand" "=r")
8328 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8329 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8330 && ix86_binary_operator_ok (AND, SImode, operands)"
8331 "and{l}\t{%2, %k0|%k0, %2}"
8332 [(set_attr "type" "alu")
8333 (set_attr "mode" "SI")])
8334
8335(define_expand "andhi3"
8336 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8337 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8338 (match_operand:HI 2 "general_operand" "")))
8339 (clobber (reg:CC 17))]
8340 "TARGET_HIMODE_MATH"
8341 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8342
8343(define_insn "*andhi_1"
8344 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8345 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8346 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8347 (clobber (reg:CC 17))]
8348 "ix86_binary_operator_ok (AND, HImode, operands)"
8349{
8350 switch (get_attr_type (insn))
8351 {
8352 case TYPE_IMOVX:
8353 if (GET_CODE (operands[2]) != CONST_INT)
8354 abort ();
8355 if (INTVAL (operands[2]) == 0xff)
8356 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8357 abort ();
8358
8359 default:
8360 if (! rtx_equal_p (operands[0], operands[1]))
8361 abort ();
8362
8363 return "and{w}\t{%2, %0|%0, %2}";
8364 }
8365}
8366 [(set_attr "type" "alu,alu,imovx")
8367 (set_attr "length_immediate" "*,*,0")
8368 (set_attr "mode" "HI,HI,SI")])
8369
8370(define_insn "*andhi_2"
8371 [(set (reg 17)
8372 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8373 (match_operand:HI 2 "general_operand" "rim,ri"))
8374 (const_int 0)))
8375 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8376 (and:HI (match_dup 1) (match_dup 2)))]
8377 "ix86_match_ccmode (insn, CCNOmode)
8378 && ix86_binary_operator_ok (AND, HImode, operands)"
8379 "and{w}\t{%2, %0|%0, %2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "mode" "HI")])
8382
8383(define_expand "andqi3"
8384 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8385 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8386 (match_operand:QI 2 "general_operand" "")))
8387 (clobber (reg:CC 17))]
8388 "TARGET_QIMODE_MATH"
8389 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8390
8391;; %%% Potential partial reg stall on alternative 2. What to do?
8392(define_insn "*andqi_1"
8393 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8394 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8395 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8396 (clobber (reg:CC 17))]
8397 "ix86_binary_operator_ok (AND, QImode, operands)"
8398 "@
8399 and{b}\t{%2, %0|%0, %2}
8400 and{b}\t{%2, %0|%0, %2}
8401 and{l}\t{%k2, %k0|%k0, %k2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "mode" "QI,QI,SI")])
8404
8405(define_insn "*andqi_1_slp"
8406 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8407 (and:QI (match_dup 0)
8408 (match_operand:QI 1 "general_operand" "qi,qmi")))
8409 (clobber (reg:CC 17))]
8410 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8411 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8412 "and{b}\t{%1, %0|%0, %1}"
8413 [(set_attr "type" "alu1")
8414 (set_attr "mode" "QI")])
8415
8416(define_insn "*andqi_2_maybe_si"
8417 [(set (reg 17)
8418 (compare (and:QI
8419 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8420 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8421 (const_int 0)))
8422 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8423 (and:QI (match_dup 1) (match_dup 2)))]
8424 "ix86_binary_operator_ok (AND, QImode, operands)
8425 && ix86_match_ccmode (insn,
8426 GET_CODE (operands[2]) == CONST_INT
8427 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8428{
8429 if (which_alternative == 2)
8430 {
8431 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8432 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8433 return "and{l}\t{%2, %k0|%k0, %2}";
8434 }
8435 return "and{b}\t{%2, %0|%0, %2}";
8436}
8437 [(set_attr "type" "alu")
8438 (set_attr "mode" "QI,QI,SI")])
8439
8440(define_insn "*andqi_2"
8441 [(set (reg 17)
8442 (compare (and:QI
8443 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8444 (match_operand:QI 2 "general_operand" "qim,qi"))
8445 (const_int 0)))
8446 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8447 (and:QI (match_dup 1) (match_dup 2)))]
8448 "ix86_match_ccmode (insn, CCNOmode)
8449 && ix86_binary_operator_ok (AND, QImode, operands)"
8450 "and{b}\t{%2, %0|%0, %2}"
8451 [(set_attr "type" "alu")
8452 (set_attr "mode" "QI")])
8453
8454(define_insn "*andqi_2_slp"
8455 [(set (reg 17)
8456 (compare (and:QI
8457 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8458 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8459 (const_int 0)))
8460 (set (strict_low_part (match_dup 0))
8461 (and:QI (match_dup 0) (match_dup 1)))]
8462 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8463 && ix86_match_ccmode (insn, CCNOmode)
8464 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8465 "and{b}\t{%1, %0|%0, %1}"
8466 [(set_attr "type" "alu1")
8467 (set_attr "mode" "QI")])
8468
8469;; ??? A bug in recog prevents it from recognizing a const_int as an
8470;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8471;; for a QImode operand, which of course failed.
8472
8473(define_insn "andqi_ext_0"
8474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 (const_int 8)
8476 (const_int 8))
8477 (and:SI
8478 (zero_extract:SI
8479 (match_operand 1 "ext_register_operand" "0")
8480 (const_int 8)
8481 (const_int 8))
8482 (match_operand 2 "const_int_operand" "n")))
8483 (clobber (reg:CC 17))]
8484 ""
8485 "and{b}\t{%2, %h0|%h0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "length_immediate" "1")
8488 (set_attr "mode" "QI")])
8489
8490;; Generated by peephole translating test to and. This shows up
8491;; often in fp comparisons.
8492
8493(define_insn "*andqi_ext_0_cc"
8494 [(set (reg 17)
8495 (compare
8496 (and:SI
8497 (zero_extract:SI
8498 (match_operand 1 "ext_register_operand" "0")
8499 (const_int 8)
8500 (const_int 8))
8501 (match_operand 2 "const_int_operand" "n"))
8502 (const_int 0)))
8503 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504 (const_int 8)
8505 (const_int 8))
8506 (and:SI
8507 (zero_extract:SI
8508 (match_dup 1)
8509 (const_int 8)
8510 (const_int 8))
8511 (match_dup 2)))]
8512 "ix86_match_ccmode (insn, CCNOmode)"
8513 "and{b}\t{%2, %h0|%h0, %2}"
8514 [(set_attr "type" "alu")
8515 (set_attr "length_immediate" "1")
8516 (set_attr "mode" "QI")])
8517
8518(define_insn "*andqi_ext_1"
8519 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8520 (const_int 8)
8521 (const_int 8))
8522 (and:SI
8523 (zero_extract:SI
8524 (match_operand 1 "ext_register_operand" "0")
8525 (const_int 8)
8526 (const_int 8))
8527 (zero_extend:SI
8528 (match_operand:QI 2 "general_operand" "Qm"))))
8529 (clobber (reg:CC 17))]
8530 "!TARGET_64BIT"
8531 "and{b}\t{%2, %h0|%h0, %2}"
8532 [(set_attr "type" "alu")
8533 (set_attr "length_immediate" "0")
8534 (set_attr "mode" "QI")])
8535
8536(define_insn "*andqi_ext_1_rex64"
8537 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8538 (const_int 8)
8539 (const_int 8))
8540 (and:SI
8541 (zero_extract:SI
8542 (match_operand 1 "ext_register_operand" "0")
8543 (const_int 8)
8544 (const_int 8))
8545 (zero_extend:SI
8546 (match_operand 2 "ext_register_operand" "Q"))))
8547 (clobber (reg:CC 17))]
8548 "TARGET_64BIT"
8549 "and{b}\t{%2, %h0|%h0, %2}"
8550 [(set_attr "type" "alu")
8551 (set_attr "length_immediate" "0")
8552 (set_attr "mode" "QI")])
8553
8554(define_insn "*andqi_ext_2"
8555 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8556 (const_int 8)
8557 (const_int 8))
8558 (and:SI
8559 (zero_extract:SI
8560 (match_operand 1 "ext_register_operand" "%0")
8561 (const_int 8)
8562 (const_int 8))
8563 (zero_extract:SI
8564 (match_operand 2 "ext_register_operand" "Q")
8565 (const_int 8)
8566 (const_int 8))))
8567 (clobber (reg:CC 17))]
8568 ""
8569 "and{b}\t{%h2, %h0|%h0, %h2}"
8570 [(set_attr "type" "alu")
8571 (set_attr "length_immediate" "0")
8572 (set_attr "mode" "QI")])
8573
8574;; Convert wide AND instructions with immediate operand to shorter QImode
8575;; equivalents when possible.
8576;; Don't do the splitting with memory operands, since it introduces risk
8577;; of memory mismatch stalls. We may want to do the splitting for optimizing
8578;; for size, but that can (should?) be handled by generic code instead.
8579(define_split
8580 [(set (match_operand 0 "register_operand" "")
8581 (and (match_operand 1 "register_operand" "")
8582 (match_operand 2 "const_int_operand" "")))
8583 (clobber (reg:CC 17))]
8584 "reload_completed
8585 && QI_REG_P (operands[0])
8586 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8587 && !(~INTVAL (operands[2]) & ~(255 << 8))
8588 && GET_MODE (operands[0]) != QImode"
8589 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8590 (and:SI (zero_extract:SI (match_dup 1)
8591 (const_int 8) (const_int 8))
8592 (match_dup 2)))
8593 (clobber (reg:CC 17))])]
8594 "operands[0] = gen_lowpart (SImode, operands[0]);
8595 operands[1] = gen_lowpart (SImode, operands[1]);
8596 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8597
8598;; Since AND can be encoded with sign extended immediate, this is only
8599;; profitable when 7th bit is not set.
8600(define_split
8601 [(set (match_operand 0 "register_operand" "")
8602 (and (match_operand 1 "general_operand" "")
8603 (match_operand 2 "const_int_operand" "")))
8604 (clobber (reg:CC 17))]
8605 "reload_completed
8606 && ANY_QI_REG_P (operands[0])
8607 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8608 && !(~INTVAL (operands[2]) & ~255)
8609 && !(INTVAL (operands[2]) & 128)
8610 && GET_MODE (operands[0]) != QImode"
8611 [(parallel [(set (strict_low_part (match_dup 0))
8612 (and:QI (match_dup 1)
8613 (match_dup 2)))
8614 (clobber (reg:CC 17))])]
8615 "operands[0] = gen_lowpart (QImode, operands[0]);
8616 operands[1] = gen_lowpart (QImode, operands[1]);
8617 operands[2] = gen_lowpart (QImode, operands[2]);")
8618
8619;; Logical inclusive OR instructions
8620
8621;; %%% This used to optimize known byte-wide and operations to memory.
8622;; If this is considered useful, it should be done with splitters.
8623
8624(define_expand "iordi3"
8625 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8626 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8627 (match_operand:DI 2 "x86_64_general_operand" "")))
8628 (clobber (reg:CC 17))]
8629 "TARGET_64BIT"
8630 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8631
8632(define_insn "*iordi_1_rex64"
8633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8634 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8636 (clobber (reg:CC 17))]
8637 "TARGET_64BIT
8638 && ix86_binary_operator_ok (IOR, DImode, operands)"
8639 "or{q}\t{%2, %0|%0, %2}"
8640 [(set_attr "type" "alu")
8641 (set_attr "mode" "DI")])
8642
8643(define_insn "*iordi_2_rex64"
8644 [(set (reg 17)
8645 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8646 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8647 (const_int 0)))
8648 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8649 (ior:DI (match_dup 1) (match_dup 2)))]
8650 "TARGET_64BIT
8651 && ix86_match_ccmode (insn, CCNOmode)
8652 && ix86_binary_operator_ok (IOR, DImode, operands)"
8653 "or{q}\t{%2, %0|%0, %2}"
8654 [(set_attr "type" "alu")
8655 (set_attr "mode" "DI")])
8656
8657(define_insn "*iordi_3_rex64"
8658 [(set (reg 17)
8659 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8660 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8661 (const_int 0)))
8662 (clobber (match_scratch:DI 0 "=r"))]
8663 "TARGET_64BIT
8664 && ix86_match_ccmode (insn, CCNOmode)
8665 && ix86_binary_operator_ok (IOR, DImode, operands)"
8666 "or{q}\t{%2, %0|%0, %2}"
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "DI")])
8669
8670
8671(define_expand "iorsi3"
8672 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8673 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8674 (match_operand:SI 2 "general_operand" "")))
8675 (clobber (reg:CC 17))]
8676 ""
8677 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8678
8679(define_insn "*iorsi_1"
8680 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8681 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8682 (match_operand:SI 2 "general_operand" "ri,rmi")))
8683 (clobber (reg:CC 17))]
8684 "ix86_binary_operator_ok (IOR, SImode, operands)"
8685 "or{l}\t{%2, %0|%0, %2}"
8686 [(set_attr "type" "alu")
8687 (set_attr "mode" "SI")])
8688
8689;; See comment for addsi_1_zext why we do use nonimmediate_operand
8690(define_insn "*iorsi_1_zext"
8691 [(set (match_operand:DI 0 "register_operand" "=rm")
8692 (zero_extend:DI
8693 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8694 (match_operand:SI 2 "general_operand" "rim"))))
8695 (clobber (reg:CC 17))]
8696 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8697 "or{l}\t{%2, %k0|%k0, %2}"
8698 [(set_attr "type" "alu")
8699 (set_attr "mode" "SI")])
8700
8701(define_insn "*iorsi_1_zext_imm"
8702 [(set (match_operand:DI 0 "register_operand" "=rm")
8703 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8704 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8705 (clobber (reg:CC 17))]
8706 "TARGET_64BIT"
8707 "or{l}\t{%2, %k0|%k0, %2}"
8708 [(set_attr "type" "alu")
8709 (set_attr "mode" "SI")])
8710
8711(define_insn "*iorsi_2"
8712 [(set (reg 17)
8713 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8714 (match_operand:SI 2 "general_operand" "rim,ri"))
8715 (const_int 0)))
8716 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8717 (ior:SI (match_dup 1) (match_dup 2)))]
8718 "ix86_match_ccmode (insn, CCNOmode)
8719 && ix86_binary_operator_ok (IOR, SImode, operands)"
8720 "or{l}\t{%2, %0|%0, %2}"
8721 [(set_attr "type" "alu")
8722 (set_attr "mode" "SI")])
8723
8724;; See comment for addsi_1_zext why we do use nonimmediate_operand
8725;; ??? Special case for immediate operand is missing - it is tricky.
8726(define_insn "*iorsi_2_zext"
8727 [(set (reg 17)
8728 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8729 (match_operand:SI 2 "general_operand" "rim"))
8730 (const_int 0)))
8731 (set (match_operand:DI 0 "register_operand" "=r")
8732 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8733 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8734 && ix86_binary_operator_ok (IOR, SImode, operands)"
8735 "or{l}\t{%2, %k0|%k0, %2}"
8736 [(set_attr "type" "alu")
8737 (set_attr "mode" "SI")])
8738
8739(define_insn "*iorsi_2_zext_imm"
8740 [(set (reg 17)
8741 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8742 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8743 (const_int 0)))
8744 (set (match_operand:DI 0 "register_operand" "=r")
8745 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8746 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8747 && ix86_binary_operator_ok (IOR, SImode, operands)"
8748 "or{l}\t{%2, %k0|%k0, %2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "mode" "SI")])
8751
8752(define_insn "*iorsi_3"
8753 [(set (reg 17)
8754 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8755 (match_operand:SI 2 "general_operand" "rim"))
8756 (const_int 0)))
8757 (clobber (match_scratch:SI 0 "=r"))]
8758 "ix86_match_ccmode (insn, CCNOmode)
8759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760 "or{l}\t{%2, %0|%0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "SI")])
8763
8764(define_expand "iorhi3"
8765 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8766 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8767 (match_operand:HI 2 "general_operand" "")))
8768 (clobber (reg:CC 17))]
8769 "TARGET_HIMODE_MATH"
8770 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8771
8772(define_insn "*iorhi_1"
8773 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8774 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8775 (match_operand:HI 2 "general_operand" "rmi,ri")))
8776 (clobber (reg:CC 17))]
8777 "ix86_binary_operator_ok (IOR, HImode, operands)"
8778 "or{w}\t{%2, %0|%0, %2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "mode" "HI")])
8781
8782(define_insn "*iorhi_2"
8783 [(set (reg 17)
8784 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8785 (match_operand:HI 2 "general_operand" "rim,ri"))
8786 (const_int 0)))
8787 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8788 (ior:HI (match_dup 1) (match_dup 2)))]
8789 "ix86_match_ccmode (insn, CCNOmode)
8790 && ix86_binary_operator_ok (IOR, HImode, operands)"
8791 "or{w}\t{%2, %0|%0, %2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "mode" "HI")])
8794
8795(define_insn "*iorhi_3"
8796 [(set (reg 17)
8797 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8798 (match_operand:HI 2 "general_operand" "rim"))
8799 (const_int 0)))
8800 (clobber (match_scratch:HI 0 "=r"))]
8801 "ix86_match_ccmode (insn, CCNOmode)
8802 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8803 "or{w}\t{%2, %0|%0, %2}"
8804 [(set_attr "type" "alu")
8805 (set_attr "mode" "HI")])
8806
8807(define_expand "iorqi3"
8808 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8809 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8810 (match_operand:QI 2 "general_operand" "")))
8811 (clobber (reg:CC 17))]
8812 "TARGET_QIMODE_MATH"
8813 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8814
8815;; %%% Potential partial reg stall on alternative 2. What to do?
8816(define_insn "*iorqi_1"
8817 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8818 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8819 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8820 (clobber (reg:CC 17))]
8821 "ix86_binary_operator_ok (IOR, QImode, operands)"
8822 "@
8823 or{b}\t{%2, %0|%0, %2}
8824 or{b}\t{%2, %0|%0, %2}
8825 or{l}\t{%k2, %k0|%k0, %k2}"
8826 [(set_attr "type" "alu")
8827 (set_attr "mode" "QI,QI,SI")])
8828
8829(define_insn "*iorqi_1_slp"
8830 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8831 (ior:QI (match_dup 0)
8832 (match_operand:QI 1 "general_operand" "qmi,qi")))
8833 (clobber (reg:CC 17))]
8834 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8835 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8836 "or{b}\t{%1, %0|%0, %1}"
8837 [(set_attr "type" "alu1")
8838 (set_attr "mode" "QI")])
8839
8840(define_insn "*iorqi_2"
8841 [(set (reg 17)
8842 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8843 (match_operand:QI 2 "general_operand" "qim,qi"))
8844 (const_int 0)))
8845 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8846 (ior:QI (match_dup 1) (match_dup 2)))]
8847 "ix86_match_ccmode (insn, CCNOmode)
8848 && ix86_binary_operator_ok (IOR, QImode, operands)"
8849 "or{b}\t{%2, %0|%0, %2}"
8850 [(set_attr "type" "alu")
8851 (set_attr "mode" "QI")])
8852
8853(define_insn "*iorqi_2_slp"
8854 [(set (reg 17)
8855 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8856 (match_operand:QI 1 "general_operand" "qim,qi"))
8857 (const_int 0)))
8858 (set (strict_low_part (match_dup 0))
8859 (ior:QI (match_dup 0) (match_dup 1)))]
8860 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8861 && ix86_match_ccmode (insn, CCNOmode)
8862 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8863 "or{b}\t{%1, %0|%0, %1}"
8864 [(set_attr "type" "alu1")
8865 (set_attr "mode" "QI")])
8866
8867(define_insn "*iorqi_3"
8868 [(set (reg 17)
8869 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8870 (match_operand:QI 2 "general_operand" "qim"))
8871 (const_int 0)))
8872 (clobber (match_scratch:QI 0 "=q"))]
8873 "ix86_match_ccmode (insn, CCNOmode)
8874 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8875 "or{b}\t{%2, %0|%0, %2}"
8876 [(set_attr "type" "alu")
8877 (set_attr "mode" "QI")])
8878
8879(define_insn "iorqi_ext_0"
8880 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8881 (const_int 8)
8882 (const_int 8))
8883 (ior:SI
8884 (zero_extract:SI
8885 (match_operand 1 "ext_register_operand" "0")
8886 (const_int 8)
8887 (const_int 8))
8888 (match_operand 2 "const_int_operand" "n")))
8889 (clobber (reg:CC 17))]
8890 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8891 "or{b}\t{%2, %h0|%h0, %2}"
8892 [(set_attr "type" "alu")
8893 (set_attr "length_immediate" "1")
8894 (set_attr "mode" "QI")])
8895
8896(define_insn "*iorqi_ext_1"
8897 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8898 (const_int 8)
8899 (const_int 8))
8900 (ior:SI
8901 (zero_extract:SI
8902 (match_operand 1 "ext_register_operand" "0")
8903 (const_int 8)
8904 (const_int 8))
8905 (zero_extend:SI
8906 (match_operand:QI 2 "general_operand" "Qm"))))
8907 (clobber (reg:CC 17))]
8908 "!TARGET_64BIT
8909 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910 "or{b}\t{%2, %h0|%h0, %2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "length_immediate" "0")
8913 (set_attr "mode" "QI")])
8914
8915(define_insn "*iorqi_ext_1_rex64"
8916 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8917 (const_int 8)
8918 (const_int 8))
8919 (ior:SI
8920 (zero_extract:SI
8921 (match_operand 1 "ext_register_operand" "0")
8922 (const_int 8)
8923 (const_int 8))
8924 (zero_extend:SI
8925 (match_operand 2 "ext_register_operand" "Q"))))
8926 (clobber (reg:CC 17))]
8927 "TARGET_64BIT
8928 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8929 "or{b}\t{%2, %h0|%h0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "length_immediate" "0")
8932 (set_attr "mode" "QI")])
8933
8934(define_insn "*iorqi_ext_2"
8935 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8936 (const_int 8)
8937 (const_int 8))
8938 (ior:SI
8939 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8940 (const_int 8)
8941 (const_int 8))
8942 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8943 (const_int 8)
8944 (const_int 8))))
8945 (clobber (reg:CC 17))]
8946 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8947 "ior{b}\t{%h2, %h0|%h0, %h2}"
8948 [(set_attr "type" "alu")
8949 (set_attr "length_immediate" "0")
8950 (set_attr "mode" "QI")])
8951
8952(define_split
8953 [(set (match_operand 0 "register_operand" "")
8954 (ior (match_operand 1 "register_operand" "")
8955 (match_operand 2 "const_int_operand" "")))
8956 (clobber (reg:CC 17))]
8957 "reload_completed
8958 && QI_REG_P (operands[0])
8959 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8960 && !(INTVAL (operands[2]) & ~(255 << 8))
8961 && GET_MODE (operands[0]) != QImode"
8962 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8963 (ior:SI (zero_extract:SI (match_dup 1)
8964 (const_int 8) (const_int 8))
8965 (match_dup 2)))
8966 (clobber (reg:CC 17))])]
8967 "operands[0] = gen_lowpart (SImode, operands[0]);
8968 operands[1] = gen_lowpart (SImode, operands[1]);
8969 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8970
8971;; Since OR can be encoded with sign extended immediate, this is only
8972;; profitable when 7th bit is set.
8973(define_split
8974 [(set (match_operand 0 "register_operand" "")
8975 (ior (match_operand 1 "general_operand" "")
8976 (match_operand 2 "const_int_operand" "")))
8977 (clobber (reg:CC 17))]
8978 "reload_completed
8979 && ANY_QI_REG_P (operands[0])
8980 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8981 && !(INTVAL (operands[2]) & ~255)
8982 && (INTVAL (operands[2]) & 128)
8983 && GET_MODE (operands[0]) != QImode"
8984 [(parallel [(set (strict_low_part (match_dup 0))
8985 (ior:QI (match_dup 1)
8986 (match_dup 2)))
8987 (clobber (reg:CC 17))])]
8988 "operands[0] = gen_lowpart (QImode, operands[0]);
8989 operands[1] = gen_lowpart (QImode, operands[1]);
8990 operands[2] = gen_lowpart (QImode, operands[2]);")
8991
8992;; Logical XOR instructions
8993
8994;; %%% This used to optimize known byte-wide and operations to memory.
8995;; If this is considered useful, it should be done with splitters.
8996
8997(define_expand "xordi3"
8998 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8999 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9000 (match_operand:DI 2 "x86_64_general_operand" "")))
9001 (clobber (reg:CC 17))]
9002 "TARGET_64BIT"
9003 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9004
9005(define_insn "*xordi_1_rex64"
9006 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9007 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9008 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9009 (clobber (reg:CC 17))]
9010 "TARGET_64BIT
9011 && ix86_binary_operator_ok (XOR, DImode, operands)"
9012 "@
9013 xor{q}\t{%2, %0|%0, %2}
9014 xor{q}\t{%2, %0|%0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "DI,DI")])
9017
9018(define_insn "*xordi_2_rex64"
9019 [(set (reg 17)
9020 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9021 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9022 (const_int 0)))
9023 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9024 (xor:DI (match_dup 1) (match_dup 2)))]
9025 "TARGET_64BIT
9026 && ix86_match_ccmode (insn, CCNOmode)
9027 && ix86_binary_operator_ok (XOR, DImode, operands)"
9028 "@
9029 xor{q}\t{%2, %0|%0, %2}
9030 xor{q}\t{%2, %0|%0, %2}"
9031 [(set_attr "type" "alu")
9032 (set_attr "mode" "DI,DI")])
9033
9034(define_insn "*xordi_3_rex64"
9035 [(set (reg 17)
9036 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9037 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9038 (const_int 0)))
9039 (clobber (match_scratch:DI 0 "=r"))]
9040 "TARGET_64BIT
9041 && ix86_match_ccmode (insn, CCNOmode)
9042 && ix86_binary_operator_ok (XOR, DImode, operands)"
9043 "xor{q}\t{%2, %0|%0, %2}"
9044 [(set_attr "type" "alu")
9045 (set_attr "mode" "DI")])
9046
9047(define_expand "xorsi3"
9048 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9049 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9050 (match_operand:SI 2 "general_operand" "")))
9051 (clobber (reg:CC 17))]
9052 ""
9053 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9054
9055(define_insn "*xorsi_1"
9056 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9057 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9058 (match_operand:SI 2 "general_operand" "ri,rm")))
9059 (clobber (reg:CC 17))]
9060 "ix86_binary_operator_ok (XOR, SImode, operands)"
9061 "xor{l}\t{%2, %0|%0, %2}"
9062 [(set_attr "type" "alu")
9063 (set_attr "mode" "SI")])
9064
9065;; See comment for addsi_1_zext why we do use nonimmediate_operand
9066;; Add speccase for immediates
9067(define_insn "*xorsi_1_zext"
9068 [(set (match_operand:DI 0 "register_operand" "=r")
9069 (zero_extend:DI
9070 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9071 (match_operand:SI 2 "general_operand" "rim"))))
9072 (clobber (reg:CC 17))]
9073 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9074 "xor{l}\t{%2, %k0|%k0, %2}"
9075 [(set_attr "type" "alu")
9076 (set_attr "mode" "SI")])
9077
9078(define_insn "*xorsi_1_zext_imm"
9079 [(set (match_operand:DI 0 "register_operand" "=r")
9080 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9081 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9082 (clobber (reg:CC 17))]
9083 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9084 "xor{l}\t{%2, %k0|%k0, %2}"
9085 [(set_attr "type" "alu")
9086 (set_attr "mode" "SI")])
9087
9088(define_insn "*xorsi_2"
9089 [(set (reg 17)
9090 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9091 (match_operand:SI 2 "general_operand" "rim,ri"))
9092 (const_int 0)))
9093 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9094 (xor:SI (match_dup 1) (match_dup 2)))]
9095 "ix86_match_ccmode (insn, CCNOmode)
9096 && ix86_binary_operator_ok (XOR, SImode, operands)"
9097 "xor{l}\t{%2, %0|%0, %2}"
9098 [(set_attr "type" "alu")
9099 (set_attr "mode" "SI")])
9100
9101;; See comment for addsi_1_zext why we do use nonimmediate_operand
9102;; ??? Special case for immediate operand is missing - it is tricky.
9103(define_insn "*xorsi_2_zext"
9104 [(set (reg 17)
9105 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9106 (match_operand:SI 2 "general_operand" "rim"))
9107 (const_int 0)))
9108 (set (match_operand:DI 0 "register_operand" "=r")
9109 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9110 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9111 && ix86_binary_operator_ok (XOR, SImode, operands)"
9112 "xor{l}\t{%2, %k0|%k0, %2}"
9113 [(set_attr "type" "alu")
9114 (set_attr "mode" "SI")])
9115
9116(define_insn "*xorsi_2_zext_imm"
9117 [(set (reg 17)
9118 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9119 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9120 (const_int 0)))
9121 (set (match_operand:DI 0 "register_operand" "=r")
9122 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9123 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9124 && ix86_binary_operator_ok (XOR, SImode, operands)"
9125 "xor{l}\t{%2, %k0|%k0, %2}"
9126 [(set_attr "type" "alu")
9127 (set_attr "mode" "SI")])
9128
9129(define_insn "*xorsi_3"
9130 [(set (reg 17)
9131 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9132 (match_operand:SI 2 "general_operand" "rim"))
9133 (const_int 0)))
9134 (clobber (match_scratch:SI 0 "=r"))]
9135 "ix86_match_ccmode (insn, CCNOmode)
9136 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9137 "xor{l}\t{%2, %0|%0, %2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "mode" "SI")])
9140
9141(define_expand "xorhi3"
9142 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9143 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9144 (match_operand:HI 2 "general_operand" "")))
9145 (clobber (reg:CC 17))]
9146 "TARGET_HIMODE_MATH"
9147 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9148
9149(define_insn "*xorhi_1"
9150 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9151 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9152 (match_operand:HI 2 "general_operand" "rmi,ri")))
9153 (clobber (reg:CC 17))]
9154 "ix86_binary_operator_ok (XOR, HImode, operands)"
9155 "xor{w}\t{%2, %0|%0, %2}"
9156 [(set_attr "type" "alu")
9157 (set_attr "mode" "HI")])
9158
9159(define_insn "*xorhi_2"
9160 [(set (reg 17)
9161 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9162 (match_operand:HI 2 "general_operand" "rim,ri"))
9163 (const_int 0)))
9164 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9165 (xor:HI (match_dup 1) (match_dup 2)))]
9166 "ix86_match_ccmode (insn, CCNOmode)
9167 && ix86_binary_operator_ok (XOR, HImode, operands)"
9168 "xor{w}\t{%2, %0|%0, %2}"
9169 [(set_attr "type" "alu")
9170 (set_attr "mode" "HI")])
9171
9172(define_insn "*xorhi_3"
9173 [(set (reg 17)
9174 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9175 (match_operand:HI 2 "general_operand" "rim"))
9176 (const_int 0)))
9177 (clobber (match_scratch:HI 0 "=r"))]
9178 "ix86_match_ccmode (insn, CCNOmode)
9179 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9180 "xor{w}\t{%2, %0|%0, %2}"
9181 [(set_attr "type" "alu")
9182 (set_attr "mode" "HI")])
9183
9184(define_expand "xorqi3"
9185 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9186 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9187 (match_operand:QI 2 "general_operand" "")))
9188 (clobber (reg:CC 17))]
9189 "TARGET_QIMODE_MATH"
9190 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9191
9192;; %%% Potential partial reg stall on alternative 2. What to do?
9193(define_insn "*xorqi_1"
9194 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9195 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9196 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9197 (clobber (reg:CC 17))]
9198 "ix86_binary_operator_ok (XOR, QImode, operands)"
9199 "@
9200 xor{b}\t{%2, %0|%0, %2}
9201 xor{b}\t{%2, %0|%0, %2}
9202 xor{l}\t{%k2, %k0|%k0, %k2}"
9203 [(set_attr "type" "alu")
9204 (set_attr "mode" "QI,QI,SI")])
9205
9206(define_insn "*xorqi_1_slp"
9207 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9208 (xor:QI (match_dup 0)
9209 (match_operand:QI 1 "general_operand" "qi,qmi")))
9210 (clobber (reg:CC 17))]
9211 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9212 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9213 "xor{b}\t{%1, %0|%0, %1}"
9214 [(set_attr "type" "alu1")
9215 (set_attr "mode" "QI")])
9216
9217(define_insn "xorqi_ext_0"
9218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9219 (const_int 8)
9220 (const_int 8))
9221 (xor:SI
9222 (zero_extract:SI
9223 (match_operand 1 "ext_register_operand" "0")
9224 (const_int 8)
9225 (const_int 8))
9226 (match_operand 2 "const_int_operand" "n")))
9227 (clobber (reg:CC 17))]
9228 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9229 "xor{b}\t{%2, %h0|%h0, %2}"
9230 [(set_attr "type" "alu")
9231 (set_attr "length_immediate" "1")
9232 (set_attr "mode" "QI")])
9233
9234(define_insn "*xorqi_ext_1"
9235 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9236 (const_int 8)
9237 (const_int 8))
9238 (xor:SI
9239 (zero_extract:SI
9240 (match_operand 1 "ext_register_operand" "0")
9241 (const_int 8)
9242 (const_int 8))
9243 (zero_extend:SI
9244 (match_operand:QI 2 "general_operand" "Qm"))))
9245 (clobber (reg:CC 17))]
9246 "!TARGET_64BIT
9247 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248 "xor{b}\t{%2, %h0|%h0, %2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "length_immediate" "0")
9251 (set_attr "mode" "QI")])
9252
9253(define_insn "*xorqi_ext_1_rex64"
9254 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9255 (const_int 8)
9256 (const_int 8))
9257 (xor:SI
9258 (zero_extract:SI
9259 (match_operand 1 "ext_register_operand" "0")
9260 (const_int 8)
9261 (const_int 8))
9262 (zero_extend:SI
9263 (match_operand 2 "ext_register_operand" "Q"))))
9264 (clobber (reg:CC 17))]
9265 "TARGET_64BIT
9266 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9267 "xor{b}\t{%2, %h0|%h0, %2}"
9268 [(set_attr "type" "alu")
9269 (set_attr "length_immediate" "0")
9270 (set_attr "mode" "QI")])
9271
9272(define_insn "*xorqi_ext_2"
9273 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274 (const_int 8)
9275 (const_int 8))
9276 (xor:SI
9277 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9278 (const_int 8)
9279 (const_int 8))
9280 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9281 (const_int 8)
9282 (const_int 8))))
9283 (clobber (reg:CC 17))]
9284 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9285 "xor{b}\t{%h2, %h0|%h0, %h2}"
9286 [(set_attr "type" "alu")
9287 (set_attr "length_immediate" "0")
9288 (set_attr "mode" "QI")])
9289
9290(define_insn "*xorqi_cc_1"
9291 [(set (reg 17)
9292 (compare
9293 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9294 (match_operand:QI 2 "general_operand" "qim,qi"))
9295 (const_int 0)))
9296 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9297 (xor:QI (match_dup 1) (match_dup 2)))]
9298 "ix86_match_ccmode (insn, CCNOmode)
9299 && ix86_binary_operator_ok (XOR, QImode, operands)"
9300 "xor{b}\t{%2, %0|%0, %2}"
9301 [(set_attr "type" "alu")
9302 (set_attr "mode" "QI")])
9303
9304(define_insn "*xorqi_2_slp"
9305 [(set (reg 17)
9306 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9307 (match_operand:QI 1 "general_operand" "qim,qi"))
9308 (const_int 0)))
9309 (set (strict_low_part (match_dup 0))
9310 (xor:QI (match_dup 0) (match_dup 1)))]
9311 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9312 && ix86_match_ccmode (insn, CCNOmode)
9313 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9314 "xor{b}\t{%1, %0|%0, %1}"
9315 [(set_attr "type" "alu1")
9316 (set_attr "mode" "QI")])
9317
9318(define_insn "*xorqi_cc_2"
9319 [(set (reg 17)
9320 (compare
9321 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9322 (match_operand:QI 2 "general_operand" "qim"))
9323 (const_int 0)))
9324 (clobber (match_scratch:QI 0 "=q"))]
9325 "ix86_match_ccmode (insn, CCNOmode)
9326 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9327 "xor{b}\t{%2, %0|%0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "QI")])
9330
9331(define_insn "*xorqi_cc_ext_1"
9332 [(set (reg 17)
9333 (compare
9334 (xor:SI
9335 (zero_extract:SI
9336 (match_operand 1 "ext_register_operand" "0")
9337 (const_int 8)
9338 (const_int 8))
9339 (match_operand:QI 2 "general_operand" "qmn"))
9340 (const_int 0)))
9341 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9342 (const_int 8)
9343 (const_int 8))
9344 (xor:SI
9345 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9346 (match_dup 2)))]
9347 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9348 "xor{b}\t{%2, %h0|%h0, %2}"
9349 [(set_attr "type" "alu")
9350 (set_attr "mode" "QI")])
9351
9352(define_insn "*xorqi_cc_ext_1_rex64"
9353 [(set (reg 17)
9354 (compare
9355 (xor:SI
9356 (zero_extract:SI
9357 (match_operand 1 "ext_register_operand" "0")
9358 (const_int 8)
9359 (const_int 8))
9360 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9361 (const_int 0)))
9362 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9363 (const_int 8)
9364 (const_int 8))
9365 (xor:SI
9366 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9367 (match_dup 2)))]
9368 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9369 "xor{b}\t{%2, %h0|%h0, %2}"
9370 [(set_attr "type" "alu")
9371 (set_attr "mode" "QI")])
9372
9373(define_expand "xorqi_cc_ext_1"
9374 [(parallel [
9375 (set (reg:CCNO 17)
9376 (compare:CCNO
9377 (xor:SI
9378 (zero_extract:SI
9379 (match_operand 1 "ext_register_operand" "")
9380 (const_int 8)
9381 (const_int 8))
9382 (match_operand:QI 2 "general_operand" ""))
9383 (const_int 0)))
9384 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9385 (const_int 8)
9386 (const_int 8))
9387 (xor:SI
9388 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9389 (match_dup 2)))])]
9390 ""
9391 "")
9392
9393(define_split
9394 [(set (match_operand 0 "register_operand" "")
9395 (xor (match_operand 1 "register_operand" "")
9396 (match_operand 2 "const_int_operand" "")))
9397 (clobber (reg:CC 17))]
9398 "reload_completed
9399 && QI_REG_P (operands[0])
9400 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9401 && !(INTVAL (operands[2]) & ~(255 << 8))
9402 && GET_MODE (operands[0]) != QImode"
9403 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9404 (xor:SI (zero_extract:SI (match_dup 1)
9405 (const_int 8) (const_int 8))
9406 (match_dup 2)))
9407 (clobber (reg:CC 17))])]
9408 "operands[0] = gen_lowpart (SImode, operands[0]);
9409 operands[1] = gen_lowpart (SImode, operands[1]);
9410 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9411
9412;; Since XOR can be encoded with sign extended immediate, this is only
9413;; profitable when 7th bit is set.
9414(define_split
9415 [(set (match_operand 0 "register_operand" "")
9416 (xor (match_operand 1 "general_operand" "")
9417 (match_operand 2 "const_int_operand" "")))
9418 (clobber (reg:CC 17))]
9419 "reload_completed
9420 && ANY_QI_REG_P (operands[0])
9421 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9422 && !(INTVAL (operands[2]) & ~255)
9423 && (INTVAL (operands[2]) & 128)
9424 && GET_MODE (operands[0]) != QImode"
9425 [(parallel [(set (strict_low_part (match_dup 0))
9426 (xor:QI (match_dup 1)
9427 (match_dup 2)))
9428 (clobber (reg:CC 17))])]
9429 "operands[0] = gen_lowpart (QImode, operands[0]);
9430 operands[1] = gen_lowpart (QImode, operands[1]);
9431 operands[2] = gen_lowpart (QImode, operands[2]);")
9432
9433;; Negation instructions
9434
9435(define_expand "negdi2"
9436 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9437 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9438 (clobber (reg:CC 17))])]
9439 ""
9440 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9441
9442(define_insn "*negdi2_1"
9443 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9444 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9445 (clobber (reg:CC 17))]
9446 "!TARGET_64BIT
9447 && ix86_unary_operator_ok (NEG, DImode, operands)"
9448 "#")
9449
9450(define_split
9451 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9452 (neg:DI (match_operand:DI 1 "general_operand" "")))
9453 (clobber (reg:CC 17))]
9454 "!TARGET_64BIT && reload_completed"
9455 [(parallel
9456 [(set (reg:CCZ 17)
9457 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9458 (set (match_dup 0) (neg:SI (match_dup 2)))])
9459 (parallel
9460 [(set (match_dup 1)
9461 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9462 (match_dup 3))
9463 (const_int 0)))
9464 (clobber (reg:CC 17))])
9465 (parallel
9466 [(set (match_dup 1)
9467 (neg:SI (match_dup 1)))
9468 (clobber (reg:CC 17))])]
9469 "split_di (operands+1, 1, operands+2, operands+3);
9470 split_di (operands+0, 1, operands+0, operands+1);")
9471
9472(define_insn "*negdi2_1_rex64"
9473 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9474 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9475 (clobber (reg:CC 17))]
9476 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9477 "neg{q}\t%0"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "DI")])
9480
9481;; The problem with neg is that it does not perform (compare x 0),
9482;; it really performs (compare 0 x), which leaves us with the zero
9483;; flag being the only useful item.
9484
9485(define_insn "*negdi2_cmpz_rex64"
9486 [(set (reg:CCZ 17)
9487 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9488 (const_int 0)))
9489 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9490 (neg:DI (match_dup 1)))]
9491 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9492 "neg{q}\t%0"
9493 [(set_attr "type" "negnot")
9494 (set_attr "mode" "DI")])
9495
9496
9497(define_expand "negsi2"
9498 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9499 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9500 (clobber (reg:CC 17))])]
9501 ""
9502 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9503
9504(define_insn "*negsi2_1"
9505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9506 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9507 (clobber (reg:CC 17))]
9508 "ix86_unary_operator_ok (NEG, SImode, operands)"
9509 "neg{l}\t%0"
9510 [(set_attr "type" "negnot")
9511 (set_attr "mode" "SI")])
9512
9513;; Combine is quite creative about this pattern.
9514(define_insn "*negsi2_1_zext"
9515 [(set (match_operand:DI 0 "register_operand" "=r")
9516 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9517 (const_int 32)))
9518 (const_int 32)))
9519 (clobber (reg:CC 17))]
9520 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9521 "neg{l}\t%k0"
9522 [(set_attr "type" "negnot")
9523 (set_attr "mode" "SI")])
9524
9525;; The problem with neg is that it does not perform (compare x 0),
9526;; it really performs (compare 0 x), which leaves us with the zero
9527;; flag being the only useful item.
9528
9529(define_insn "*negsi2_cmpz"
9530 [(set (reg:CCZ 17)
9531 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9532 (const_int 0)))
9533 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9534 (neg:SI (match_dup 1)))]
9535 "ix86_unary_operator_ok (NEG, SImode, operands)"
9536 "neg{l}\t%0"
9537 [(set_attr "type" "negnot")
9538 (set_attr "mode" "SI")])
9539
9540(define_insn "*negsi2_cmpz_zext"
9541 [(set (reg:CCZ 17)
9542 (compare:CCZ (lshiftrt:DI
9543 (neg:DI (ashift:DI
9544 (match_operand:DI 1 "register_operand" "0")
9545 (const_int 32)))
9546 (const_int 32))
9547 (const_int 0)))
9548 (set (match_operand:DI 0 "register_operand" "=r")
9549 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9550 (const_int 32)))
9551 (const_int 32)))]
9552 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9553 "neg{l}\t%k0"
9554 [(set_attr "type" "negnot")
9555 (set_attr "mode" "SI")])
9556
9557(define_expand "neghi2"
9558 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9559 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9560 (clobber (reg:CC 17))])]
9561 "TARGET_HIMODE_MATH"
9562 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9563
9564(define_insn "*neghi2_1"
9565 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9566 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9567 (clobber (reg:CC 17))]
9568 "ix86_unary_operator_ok (NEG, HImode, operands)"
9569 "neg{w}\t%0"
9570 [(set_attr "type" "negnot")
9571 (set_attr "mode" "HI")])
9572
9573(define_insn "*neghi2_cmpz"
9574 [(set (reg:CCZ 17)
9575 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9576 (const_int 0)))
9577 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9578 (neg:HI (match_dup 1)))]
9579 "ix86_unary_operator_ok (NEG, HImode, operands)"
9580 "neg{w}\t%0"
9581 [(set_attr "type" "negnot")
9582 (set_attr "mode" "HI")])
9583
9584(define_expand "negqi2"
9585 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9586 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9587 (clobber (reg:CC 17))])]
9588 "TARGET_QIMODE_MATH"
9589 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9590
9591(define_insn "*negqi2_1"
9592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9593 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9594 (clobber (reg:CC 17))]
9595 "ix86_unary_operator_ok (NEG, QImode, operands)"
9596 "neg{b}\t%0"
9597 [(set_attr "type" "negnot")
9598 (set_attr "mode" "QI")])
9599
9600(define_insn "*negqi2_cmpz"
9601 [(set (reg:CCZ 17)
9602 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9603 (const_int 0)))
9604 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9605 (neg:QI (match_dup 1)))]
9606 "ix86_unary_operator_ok (NEG, QImode, operands)"
9607 "neg{b}\t%0"
9608 [(set_attr "type" "negnot")
9609 (set_attr "mode" "QI")])
9610
9611;; Changing of sign for FP values is doable using integer unit too.
9612
9613(define_expand "negsf2"
9614 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9615 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9616 (clobber (reg:CC 17))])]
9617 "TARGET_80387 || TARGET_SSE_MATH"
9618 "if (TARGET_SSE_MATH)
9619 {
9620 /* In case operand is in memory, we will not use SSE. */
9621 if (memory_operand (operands[0], VOIDmode)
9622 && rtx_equal_p (operands[0], operands[1]))
9623 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9624 else
9625 {
9626 /* Using SSE is tricky, since we need bitwise negation of -0
9627 in register. */
9628 rtx reg = gen_reg_rtx (SFmode);
9629 rtx dest = operands[0];
9630 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9631
9632 operands[1] = force_reg (SFmode, operands[1]);
9633 operands[0] = force_reg (SFmode, operands[0]);
9634 reg = force_reg (V4SFmode,
9635 gen_rtx_CONST_VECTOR (V4SFmode,
9636 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9637 CONST0_RTX (SFmode),
9638 CONST0_RTX (SFmode))));
9639 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9640 if (dest != operands[0])
9641 emit_move_insn (dest, operands[0]);
9642 }
9643 DONE;
9644 }
9645 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9646
9647(define_insn "negsf2_memory"
9648 [(set (match_operand:SF 0 "memory_operand" "=m")
9649 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9650 (clobber (reg:CC 17))]
9651 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9652 "#")
9653
9654(define_insn "negsf2_ifs"
9655 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9656 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9657 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9658 (clobber (reg:CC 17))]
9659 "TARGET_SSE
9660 && (reload_in_progress || reload_completed
9661 || (register_operand (operands[0], VOIDmode)
9662 && register_operand (operands[1], VOIDmode)))"
9663 "#")
9664
9665(define_split
9666 [(set (match_operand:SF 0 "memory_operand" "")
9667 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9668 (use (match_operand:SF 2 "" ""))
9669 (clobber (reg:CC 17))]
9670 ""
9671 [(parallel [(set (match_dup 0)
9672 (neg:SF (match_dup 1)))
9673 (clobber (reg:CC 17))])])
9674
9675(define_split
9676 [(set (match_operand:SF 0 "register_operand" "")
9677 (neg:SF (match_operand:SF 1 "register_operand" "")))
9678 (use (match_operand:V4SF 2 "" ""))
9679 (clobber (reg:CC 17))]
9680 "reload_completed && !SSE_REG_P (operands[0])"
9681 [(parallel [(set (match_dup 0)
9682 (neg:SF (match_dup 1)))
9683 (clobber (reg:CC 17))])])
9684
9685(define_split
9686 [(set (match_operand:SF 0 "register_operand" "")
9687 (neg:SF (match_operand:SF 1 "register_operand" "")))
9688 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9689 (clobber (reg:CC 17))]
9690 "reload_completed && SSE_REG_P (operands[0])"
9691 [(set (match_dup 0)
9692 (xor:V4SF (match_dup 1)
9693 (match_dup 2)))]
9694{
9695 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9696 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9697 if (operands_match_p (operands[0], operands[2]))
9698 {
9699 rtx tmp;
9700 tmp = operands[1];
9701 operands[1] = operands[2];
9702 operands[2] = tmp;
9703 }
9704})
9705
9706
9707;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9708;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9709;; to itself.
9710(define_insn "*negsf2_if"
9711 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9712 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9713 (clobber (reg:CC 17))]
9714 "TARGET_80387
9715 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9716 "#")
9717
9718(define_split
9719 [(set (match_operand:SF 0 "fp_register_operand" "")
9720 (neg:SF (match_operand:SF 1 "register_operand" "")))
9721 (clobber (reg:CC 17))]
9722 "TARGET_80387 && reload_completed"
9723 [(set (match_dup 0)
9724 (neg:SF (match_dup 1)))]
9725 "")
9726
9727(define_split
9728 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9729 (neg:SF (match_operand:SF 1 "register_operand" "")))
9730 (clobber (reg:CC 17))]
9731 "TARGET_80387 && reload_completed"
9732 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9733 (clobber (reg:CC 17))])]
9734 "operands[1] = gen_int_mode (0x80000000, SImode);
9735 operands[0] = gen_lowpart (SImode, operands[0]);")
9736
9737(define_split
9738 [(set (match_operand 0 "memory_operand" "")
9739 (neg (match_operand 1 "memory_operand" "")))
9740 (clobber (reg:CC 17))]
9741 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9742 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9743 (clobber (reg:CC 17))])]
9744{
9745 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9746
9747 if (GET_MODE (operands[1]) == XFmode)
9748 size = 10;
9749 operands[0] = adjust_address (operands[0], QImode, size - 1);
9750 operands[1] = gen_int_mode (0x80, QImode);
9751})
9752
9753(define_expand "negdf2"
9754 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9755 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9756 (clobber (reg:CC 17))])]
9757 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9758 "if (TARGET_SSE2 && TARGET_SSE_MATH)
9759 {
9760 /* In case operand is in memory, we will not use SSE. */
9761 if (memory_operand (operands[0], VOIDmode)
9762 && rtx_equal_p (operands[0], operands[1]))
9763 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9764 else
9765 {
9766 /* Using SSE is tricky, since we need bitwise negation of -0
9767 in register. */
9768 rtx reg;
9769#if HOST_BITS_PER_WIDE_INT >= 64
9770 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9771#else
9772 rtx imm = immed_double_const (0, 0x80000000, DImode);
9773#endif
9774 rtx dest = operands[0];
9775
9776 operands[1] = force_reg (DFmode, operands[1]);
9777 operands[0] = force_reg (DFmode, operands[0]);
9778 imm = gen_lowpart (DFmode, imm);
9779 reg = force_reg (V2DFmode,
9780 gen_rtx_CONST_VECTOR (V2DFmode,
9781 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9782 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9783 if (dest != operands[0])
9784 emit_move_insn (dest, operands[0]);
9785 }
9786 DONE;
9787 }
9788 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9789
9790(define_insn "negdf2_memory"
9791 [(set (match_operand:DF 0 "memory_operand" "=m")
9792 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9793 (clobber (reg:CC 17))]
9794 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9795 "#")
9796
9797(define_insn "negdf2_ifs"
9798 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9799 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9800 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9801 (clobber (reg:CC 17))]
9802 "!TARGET_64BIT && TARGET_SSE2
9803 && (reload_in_progress || reload_completed
9804 || (register_operand (operands[0], VOIDmode)
9805 && register_operand (operands[1], VOIDmode)))"
9806 "#")
9807
9808(define_insn "*negdf2_ifs_rex64"
9809 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9810 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9811 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9812 (clobber (reg:CC 17))]
9813 "TARGET_64BIT && TARGET_SSE2
9814 && (reload_in_progress || reload_completed
9815 || (register_operand (operands[0], VOIDmode)
9816 && register_operand (operands[1], VOIDmode)))"
9817 "#")
9818
9819(define_split
9820 [(set (match_operand:DF 0 "memory_operand" "")
9821 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9822 (use (match_operand:V2DF 2 "" ""))
9823 (clobber (reg:CC 17))]
9824 ""
9825 [(parallel [(set (match_dup 0)
9826 (neg:DF (match_dup 1)))
9827 (clobber (reg:CC 17))])])
9828
9829(define_split
9830 [(set (match_operand:DF 0 "register_operand" "")
9831 (neg:DF (match_operand:DF 1 "register_operand" "")))
9832 (use (match_operand:V2DF 2 "" ""))
9833 (clobber (reg:CC 17))]
9834 "reload_completed && !SSE_REG_P (operands[0])
9835 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9836 [(parallel [(set (match_dup 0)
9837 (neg:DF (match_dup 1)))
9838 (clobber (reg:CC 17))])])
9839
9840(define_split
9841 [(set (match_operand:DF 0 "register_operand" "")
9842 (neg:DF (match_operand:DF 1 "register_operand" "")))
9843 (use (match_operand:V2DF 2 "" ""))
9844 (clobber (reg:CC 17))]
9845 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9846 [(parallel [(set (match_dup 0)
9847 (xor:DI (match_dup 1) (match_dup 2)))
9848 (clobber (reg:CC 17))])]
9849 "operands[0] = gen_lowpart (DImode, operands[0]);
9850 operands[1] = gen_lowpart (DImode, operands[1]);
9851 operands[2] = gen_lowpart (DImode, operands[2]);")
9852
9853(define_split
9854 [(set (match_operand:DF 0 "register_operand" "")
9855 (neg:DF (match_operand:DF 1 "register_operand" "")))
9856 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9857 (clobber (reg:CC 17))]
9858 "reload_completed && SSE_REG_P (operands[0])"
9859 [(set (match_dup 0)
9860 (xor:V2DF (match_dup 1)
9861 (match_dup 2)))]
9862{
9863 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9864 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9865 /* Avoid possible reformatting on the operands. */
9866 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9867 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9868 if (operands_match_p (operands[0], operands[2]))
9869 {
9870 rtx tmp;
9871 tmp = operands[1];
9872 operands[1] = operands[2];
9873 operands[2] = tmp;
9874 }
9875})
9876
9877;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9878;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9879;; to itself.
9880(define_insn "*negdf2_if"
9881 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9882 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9883 (clobber (reg:CC 17))]
9884 "!TARGET_64BIT && TARGET_80387
9885 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9886 "#")
9887
9888;; FIXME: We should to allow integer registers here. Problem is that
9889;; we need another scratch register to get constant from.
9890;; Forcing constant to mem if no register available in peep2 should be
9891;; safe even for PIC mode, because of RIP relative addressing.
9892(define_insn "*negdf2_if_rex64"
9893 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9894 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9895 (clobber (reg:CC 17))]
9896 "TARGET_64BIT && TARGET_80387
9897 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9898 "#")
9899
9900(define_split
9901 [(set (match_operand:DF 0 "fp_register_operand" "")
9902 (neg:DF (match_operand:DF 1 "register_operand" "")))
9903 (clobber (reg:CC 17))]
9904 "TARGET_80387 && reload_completed"
9905 [(set (match_dup 0)
9906 (neg:DF (match_dup 1)))]
9907 "")
9908
9909(define_split
9910 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9911 (neg:DF (match_operand:DF 1 "register_operand" "")))
9912 (clobber (reg:CC 17))]
9913 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9914 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9915 (clobber (reg:CC 17))])]
9916 "operands[4] = gen_int_mode (0x80000000, SImode);
9917 split_di (operands+0, 1, operands+2, operands+3);")
9918
9919(define_expand "negxf2"
9920 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9921 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9922 (clobber (reg:CC 17))])]
9923 "TARGET_80387"
9924 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9925
9926;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9927;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9928;; to itself.
9929(define_insn "*negxf2_if"
9930 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9931 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9932 (clobber (reg:CC 17))]
9933 "TARGET_80387
9934 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9935 "#")
9936
9937(define_split
9938 [(set (match_operand:XF 0 "fp_register_operand" "")
9939 (neg:XF (match_operand:XF 1 "register_operand" "")))
9940 (clobber (reg:CC 17))]
9941 "TARGET_80387 && reload_completed"
9942 [(set (match_dup 0)
9943 (neg:XF (match_dup 1)))]
9944 "")
9945
9946(define_split
9947 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9948 (neg:XF (match_operand:XF 1 "register_operand" "")))
9949 (clobber (reg:CC 17))]
9950 "TARGET_80387 && reload_completed"
9951 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9952 (clobber (reg:CC 17))])]
9953 "operands[1] = GEN_INT (0x8000);
9954 operands[0] = gen_rtx_REG (SImode,
9955 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9956
9957;; Conditionalize these after reload. If they matches before reload, we
9958;; lose the clobber and ability to use integer instructions.
9959
9960(define_insn "*negsf2_1"
9961 [(set (match_operand:SF 0 "register_operand" "=f")
9962 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9963 "TARGET_80387 && reload_completed"
9964 "fchs"
9965 [(set_attr "type" "fsgn")
9966 (set_attr "mode" "SF")
9967 (set_attr "ppro_uops" "few")])
9968
9969(define_insn "*negdf2_1"
9970 [(set (match_operand:DF 0 "register_operand" "=f")
9971 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9972 "TARGET_80387 && reload_completed"
9973 "fchs"
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "DF")
9976 (set_attr "ppro_uops" "few")])
9977
9978(define_insn "*negextendsfdf2"
9979 [(set (match_operand:DF 0 "register_operand" "=f")
9980 (neg:DF (float_extend:DF
9981 (match_operand:SF 1 "register_operand" "0"))))]
9982 "TARGET_80387"
9983 "fchs"
9984 [(set_attr "type" "fsgn")
9985 (set_attr "mode" "DF")
9986 (set_attr "ppro_uops" "few")])
9987
9988(define_insn "*negxf2_1"
9989 [(set (match_operand:XF 0 "register_operand" "=f")
9990 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9991 "TARGET_80387 && reload_completed"
9992 "fchs"
9993 [(set_attr "type" "fsgn")
9994 (set_attr "mode" "XF")
9995 (set_attr "ppro_uops" "few")])
9996
9997(define_insn "*negextenddfxf2"
9998 [(set (match_operand:XF 0 "register_operand" "=f")
9999 (neg:XF (float_extend:XF
10000 (match_operand:DF 1 "register_operand" "0"))))]
10001 "TARGET_80387"
10002 "fchs"
10003 [(set_attr "type" "fsgn")
10004 (set_attr "mode" "XF")
10005 (set_attr "ppro_uops" "few")])
10006
10007(define_insn "*negextendsfxf2"
10008 [(set (match_operand:XF 0 "register_operand" "=f")
10009 (neg:XF (float_extend:XF
10010 (match_operand:SF 1 "register_operand" "0"))))]
10011 "TARGET_80387"
10012 "fchs"
10013 [(set_attr "type" "fsgn")
10014 (set_attr "mode" "XF")
10015 (set_attr "ppro_uops" "few")])
10016
10017;; Absolute value instructions
10018
10019(define_expand "abssf2"
10020 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10021 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10022 (clobber (reg:CC 17))])]
10023 "TARGET_80387 || TARGET_SSE_MATH"
10024 "if (TARGET_SSE_MATH)
10025 {
10026 /* In case operand is in memory, we will not use SSE. */
10027 if (memory_operand (operands[0], VOIDmode)
10028 && rtx_equal_p (operands[0], operands[1]))
10029 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10030 else
10031 {
10032 /* Using SSE is tricky, since we need bitwise negation of -0
10033 in register. */
10034 rtx reg = gen_reg_rtx (V4SFmode);
10035 rtx dest = operands[0];
10036 rtx imm;
10037
10038 operands[1] = force_reg (SFmode, operands[1]);
10039 operands[0] = force_reg (SFmode, operands[0]);
10040 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10041 reg = force_reg (V4SFmode,
10042 gen_rtx_CONST_VECTOR (V4SFmode,
10043 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10044 CONST0_RTX (SFmode),
10045 CONST0_RTX (SFmode))));
10046 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10047 if (dest != operands[0])
10048 emit_move_insn (dest, operands[0]);
10049 }
10050 DONE;
10051 }
10052 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10053
10054(define_insn "abssf2_memory"
10055 [(set (match_operand:SF 0 "memory_operand" "=m")
10056 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10057 (clobber (reg:CC 17))]
10058 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10059 "#")
10060
10061(define_insn "abssf2_ifs"
10062 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10063 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10064 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10065 (clobber (reg:CC 17))]
10066 "TARGET_SSE
10067 && (reload_in_progress || reload_completed
10068 || (register_operand (operands[0], VOIDmode)
10069 && register_operand (operands[1], VOIDmode)))"
10070 "#")
10071
10072(define_split
10073 [(set (match_operand:SF 0 "memory_operand" "")
10074 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10075 (use (match_operand:V4SF 2 "" ""))
10076 (clobber (reg:CC 17))]
10077 ""
10078 [(parallel [(set (match_dup 0)
10079 (abs:SF (match_dup 1)))
10080 (clobber (reg:CC 17))])])
10081
10082(define_split
10083 [(set (match_operand:SF 0 "register_operand" "")
10084 (abs:SF (match_operand:SF 1 "register_operand" "")))
10085 (use (match_operand:V4SF 2 "" ""))
10086 (clobber (reg:CC 17))]
10087 "reload_completed && !SSE_REG_P (operands[0])"
10088 [(parallel [(set (match_dup 0)
10089 (abs:SF (match_dup 1)))
10090 (clobber (reg:CC 17))])])
10091
10092(define_split
10093 [(set (match_operand:SF 0 "register_operand" "")
10094 (abs:SF (match_operand:SF 1 "register_operand" "")))
10095 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10096 (clobber (reg:CC 17))]
10097 "reload_completed && SSE_REG_P (operands[0])"
10098 [(set (match_dup 0)
10099 (and:V4SF (match_dup 1)
10100 (match_dup 2)))]
10101{
10102 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10103 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10104 if (operands_match_p (operands[0], operands[2]))
10105 {
10106 rtx tmp;
10107 tmp = operands[1];
10108 operands[1] = operands[2];
10109 operands[2] = tmp;
10110 }
10111})
10112
10113;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10114;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10115;; to itself.
10116(define_insn "*abssf2_if"
10117 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10118 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10119 (clobber (reg:CC 17))]
10120 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
10121 "#")
10122
10123(define_split
10124 [(set (match_operand:SF 0 "fp_register_operand" "")
10125 (abs:SF (match_operand:SF 1 "register_operand" "")))
10126 (clobber (reg:CC 17))]
10127 "TARGET_80387 && reload_completed"
10128 [(set (match_dup 0)
10129 (abs:SF (match_dup 1)))]
10130 "")
10131
10132(define_split
10133 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10134 (abs:SF (match_operand:SF 1 "register_operand" "")))
10135 (clobber (reg:CC 17))]
10136 "TARGET_80387 && reload_completed"
10137 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10138 (clobber (reg:CC 17))])]
10139 "operands[1] = gen_int_mode (~0x80000000, SImode);
10140 operands[0] = gen_lowpart (SImode, operands[0]);")
10141
10142(define_split
10143 [(set (match_operand 0 "memory_operand" "")
10144 (abs (match_operand 1 "memory_operand" "")))
10145 (clobber (reg:CC 17))]
10146 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10147 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10148 (clobber (reg:CC 17))])]
10149{
10150 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10151
10152 if (GET_MODE (operands[1]) == XFmode)
10153 size = 10;
10154 operands[0] = adjust_address (operands[0], QImode, size - 1);
10155 operands[1] = gen_int_mode (~0x80, QImode);
10156})
10157
10158(define_expand "absdf2"
10159 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10160 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10161 (clobber (reg:CC 17))])]
10162 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10163 "if (TARGET_SSE2 && TARGET_SSE_MATH)
10164 {
10165 /* In case operand is in memory, we will not use SSE. */
10166 if (memory_operand (operands[0], VOIDmode)
10167 && rtx_equal_p (operands[0], operands[1]))
10168 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10169 else
10170 {
10171 /* Using SSE is tricky, since we need bitwise negation of -0
10172 in register. */
10173 rtx reg = gen_reg_rtx (V2DFmode);
10174#if HOST_BITS_PER_WIDE_INT >= 64
10175 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10176#else
10177 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10178#endif
10179 rtx dest = operands[0];
10180
10181 operands[1] = force_reg (DFmode, operands[1]);
10182 operands[0] = force_reg (DFmode, operands[0]);
10183
10184 /* Produce LONG_DOUBLE with the proper immediate argument. */
10185 imm = gen_lowpart (DFmode, imm);
10186 reg = force_reg (V2DFmode,
10187 gen_rtx_CONST_VECTOR (V2DFmode,
10188 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10189 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10190 if (dest != operands[0])
10191 emit_move_insn (dest, operands[0]);
10192 }
10193 DONE;
10194 }
10195 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10196
10197(define_insn "absdf2_memory"
10198 [(set (match_operand:DF 0 "memory_operand" "=m")
10199 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10200 (clobber (reg:CC 17))]
10201 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10202 "#")
10203
10204(define_insn "absdf2_ifs"
10205 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10206 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10207 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10208 (clobber (reg:CC 17))]
10209 "!TARGET_64BIT && TARGET_SSE2
10210 && (reload_in_progress || reload_completed
10211 || (register_operand (operands[0], VOIDmode)
10212 && register_operand (operands[1], VOIDmode)))"
10213 "#")
10214
10215(define_insn "*absdf2_ifs_rex64"
10216 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10217 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10218 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10219 (clobber (reg:CC 17))]
10220 "TARGET_64BIT && TARGET_SSE2
10221 && (reload_in_progress || reload_completed
10222 || (register_operand (operands[0], VOIDmode)
10223 && register_operand (operands[1], VOIDmode)))"
10224 "#")
10225
10226(define_split
10227 [(set (match_operand:DF 0 "memory_operand" "")
10228 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10229 (use (match_operand:V2DF 2 "" ""))
10230 (clobber (reg:CC 17))]
10231 ""
10232 [(parallel [(set (match_dup 0)
10233 (abs:DF (match_dup 1)))
10234 (clobber (reg:CC 17))])])
10235
10236(define_split
10237 [(set (match_operand:DF 0 "register_operand" "")
10238 (abs:DF (match_operand:DF 1 "register_operand" "")))
10239 (use (match_operand:V2DF 2 "" ""))
10240 (clobber (reg:CC 17))]
10241 "reload_completed && !SSE_REG_P (operands[0])"
10242 [(parallel [(set (match_dup 0)
10243 (abs:DF (match_dup 1)))
10244 (clobber (reg:CC 17))])])
10245
10246(define_split
10247 [(set (match_operand:DF 0 "register_operand" "")
10248 (abs:DF (match_operand:DF 1 "register_operand" "")))
10249 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10250 (clobber (reg:CC 17))]
10251 "reload_completed && SSE_REG_P (operands[0])"
10252 [(set (match_dup 0)
10253 (and:V2DF (match_dup 1)
10254 (match_dup 2)))]
10255{
10256 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10257 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10258 /* Avoid possible reformatting on the operands. */
10259 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10260 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10261 if (operands_match_p (operands[0], operands[2]))
10262 {
10263 rtx tmp;
10264 tmp = operands[1];
10265 operands[1] = operands[2];
10266 operands[2] = tmp;
10267 }
10268})
10269
10270
10271;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10272;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10273;; to itself.
10274(define_insn "*absdf2_if"
10275 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10276 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10277 (clobber (reg:CC 17))]
10278 "!TARGET_64BIT && TARGET_80387
10279 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10280 "#")
10281
10282;; FIXME: We should to allow integer registers here. Problem is that
10283;; we need another scratch register to get constant from.
10284;; Forcing constant to mem if no register available in peep2 should be
10285;; safe even for PIC mode, because of RIP relative addressing.
10286(define_insn "*absdf2_if_rex64"
10287 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10288 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10289 (clobber (reg:CC 17))]
10290 "TARGET_64BIT && TARGET_80387
10291 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10292 "#")
10293
10294(define_split
10295 [(set (match_operand:DF 0 "fp_register_operand" "")
10296 (abs:DF (match_operand:DF 1 "register_operand" "")))
10297 (clobber (reg:CC 17))]
10298 "TARGET_80387 && reload_completed"
10299 [(set (match_dup 0)
10300 (abs:DF (match_dup 1)))]
10301 "")
10302
10303(define_split
10304 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10305 (abs:DF (match_operand:DF 1 "register_operand" "")))
10306 (clobber (reg:CC 17))]
10307 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10308 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10309 (clobber (reg:CC 17))])]
10310 "operands[4] = gen_int_mode (~0x80000000, SImode);
10311 split_di (operands+0, 1, operands+2, operands+3);")
10312
10313(define_expand "absxf2"
10314 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10315 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10316 (clobber (reg:CC 17))])]
10317 "TARGET_80387"
10318 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10319
10320;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10321;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10322;; to itself.
10323(define_insn "*absxf2_if"
10324 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10325 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10326 (clobber (reg:CC 17))]
10327 "TARGET_80387
10328 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10329 "#")
10330
10331(define_split
10332 [(set (match_operand:XF 0 "fp_register_operand" "")
10333 (abs:XF (match_operand:XF 1 "register_operand" "")))
10334 (clobber (reg:CC 17))]
10335 "TARGET_80387 && reload_completed"
10336 [(set (match_dup 0)
10337 (abs:XF (match_dup 1)))]
10338 "")
10339
10340(define_split
10341 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10342 (abs:XF (match_operand:XF 1 "register_operand" "")))
10343 (clobber (reg:CC 17))]
10344 "TARGET_80387 && reload_completed"
10345 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10346 (clobber (reg:CC 17))])]
10347 "operands[1] = GEN_INT (~0x8000);
10348 operands[0] = gen_rtx_REG (SImode,
10349 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10350
10351(define_insn "*abssf2_1"
10352 [(set (match_operand:SF 0 "register_operand" "=f")
10353 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10354 "TARGET_80387 && reload_completed"
10355 "fabs"
10356 [(set_attr "type" "fsgn")
10357 (set_attr "mode" "SF")])
10358
10359(define_insn "*absdf2_1"
10360 [(set (match_operand:DF 0 "register_operand" "=f")
10361 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10362 "TARGET_80387 && reload_completed"
10363 "fabs"
10364 [(set_attr "type" "fsgn")
10365 (set_attr "mode" "DF")])
10366
10367(define_insn "*absextendsfdf2"
10368 [(set (match_operand:DF 0 "register_operand" "=f")
10369 (abs:DF (float_extend:DF
10370 (match_operand:SF 1 "register_operand" "0"))))]
10371 "TARGET_80387"
10372 "fabs"
10373 [(set_attr "type" "fsgn")
10374 (set_attr "mode" "DF")])
10375
10376(define_insn "*absxf2_1"
10377 [(set (match_operand:XF 0 "register_operand" "=f")
10378 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10379 "TARGET_80387 && reload_completed"
10380 "fabs"
10381 [(set_attr "type" "fsgn")
10382 (set_attr "mode" "DF")])
10383
10384(define_insn "*absextenddfxf2"
10385 [(set (match_operand:XF 0 "register_operand" "=f")
10386 (abs:XF (float_extend:XF
10387 (match_operand:DF 1 "register_operand" "0"))))]
10388 "TARGET_80387"
10389 "fabs"
10390 [(set_attr "type" "fsgn")
10391 (set_attr "mode" "XF")])
10392
10393(define_insn "*absextendsfxf2"
10394 [(set (match_operand:XF 0 "register_operand" "=f")
10395 (abs:XF (float_extend:XF
10396 (match_operand:SF 1 "register_operand" "0"))))]
10397 "TARGET_80387"
10398 "fabs"
10399 [(set_attr "type" "fsgn")
10400 (set_attr "mode" "XF")])
10401
10402;; One complement instructions
10403
10404(define_expand "one_cmpldi2"
10405 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10406 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10407 "TARGET_64BIT"
10408 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10409
10410(define_insn "*one_cmpldi2_1_rex64"
10411 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10412 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10413 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10414 "not{q}\t%0"
10415 [(set_attr "type" "negnot")
10416 (set_attr "mode" "DI")])
10417
10418(define_insn "*one_cmpldi2_2_rex64"
10419 [(set (reg 17)
10420 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10421 (const_int 0)))
10422 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10423 (not:DI (match_dup 1)))]
10424 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10425 && ix86_unary_operator_ok (NOT, DImode, operands)"
10426 "#"
10427 [(set_attr "type" "alu1")
10428 (set_attr "mode" "DI")])
10429
10430(define_split
10431 [(set (match_operand 0 "flags_reg_operand" "")
10432 (match_operator 2 "compare_operator"
10433 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10434 (const_int 0)]))
10435 (set (match_operand:DI 1 "nonimmediate_operand" "")
10436 (not:DI (match_dup 3)))]
10437 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10438 [(parallel [(set (match_dup 0)
10439 (match_op_dup 2
10440 [(xor:DI (match_dup 3) (const_int -1))
10441 (const_int 0)]))
10442 (set (match_dup 1)
10443 (xor:DI (match_dup 3) (const_int -1)))])]
10444 "")
10445
10446(define_expand "one_cmplsi2"
10447 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10448 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10449 ""
10450 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10451
10452(define_insn "*one_cmplsi2_1"
10453 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10454 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10455 "ix86_unary_operator_ok (NOT, SImode, operands)"
10456 "not{l}\t%0"
10457 [(set_attr "type" "negnot")
10458 (set_attr "mode" "SI")])
10459
10460;; ??? Currently never generated - xor is used instead.
10461(define_insn "*one_cmplsi2_1_zext"
10462 [(set (match_operand:DI 0 "register_operand" "=r")
10463 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10464 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10465 "not{l}\t%k0"
10466 [(set_attr "type" "negnot")
10467 (set_attr "mode" "SI")])
10468
10469(define_insn "*one_cmplsi2_2"
10470 [(set (reg 17)
10471 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10472 (const_int 0)))
10473 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10474 (not:SI (match_dup 1)))]
10475 "ix86_match_ccmode (insn, CCNOmode)
10476 && ix86_unary_operator_ok (NOT, SImode, operands)"
10477 "#"
10478 [(set_attr "type" "alu1")
10479 (set_attr "mode" "SI")])
10480
10481(define_split
10482 [(set (match_operand 0 "flags_reg_operand" "")
10483 (match_operator 2 "compare_operator"
10484 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10485 (const_int 0)]))
10486 (set (match_operand:SI 1 "nonimmediate_operand" "")
10487 (not:SI (match_dup 3)))]
10488 "ix86_match_ccmode (insn, CCNOmode)"
10489 [(parallel [(set (match_dup 0)
10490 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10491 (const_int 0)]))
10492 (set (match_dup 1)
10493 (xor:SI (match_dup 3) (const_int -1)))])]
10494 "")
10495
10496;; ??? Currently never generated - xor is used instead.
10497(define_insn "*one_cmplsi2_2_zext"
10498 [(set (reg 17)
10499 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10500 (const_int 0)))
10501 (set (match_operand:DI 0 "register_operand" "=r")
10502 (zero_extend:DI (not:SI (match_dup 1))))]
10503 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10504 && ix86_unary_operator_ok (NOT, SImode, operands)"
10505 "#"
10506 [(set_attr "type" "alu1")
10507 (set_attr "mode" "SI")])
10508
10509(define_split
10510 [(set (match_operand 0 "flags_reg_operand" "")
10511 (match_operator 2 "compare_operator"
10512 [(not:SI (match_operand:SI 3 "register_operand" ""))
10513 (const_int 0)]))
10514 (set (match_operand:DI 1 "register_operand" "")
10515 (zero_extend:DI (not:SI (match_dup 3))))]
10516 "ix86_match_ccmode (insn, CCNOmode)"
10517 [(parallel [(set (match_dup 0)
10518 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10519 (const_int 0)]))
10520 (set (match_dup 1)
10521 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10522 "")
10523
10524(define_expand "one_cmplhi2"
10525 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10526 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10527 "TARGET_HIMODE_MATH"
10528 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10529
10530(define_insn "*one_cmplhi2_1"
10531 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10532 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10533 "ix86_unary_operator_ok (NOT, HImode, operands)"
10534 "not{w}\t%0"
10535 [(set_attr "type" "negnot")
10536 (set_attr "mode" "HI")])
10537
10538(define_insn "*one_cmplhi2_2"
10539 [(set (reg 17)
10540 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10541 (const_int 0)))
10542 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10543 (not:HI (match_dup 1)))]
10544 "ix86_match_ccmode (insn, CCNOmode)
10545 && ix86_unary_operator_ok (NEG, HImode, operands)"
10546 "#"
10547 [(set_attr "type" "alu1")
10548 (set_attr "mode" "HI")])
10549
10550(define_split
10551 [(set (match_operand 0 "flags_reg_operand" "")
10552 (match_operator 2 "compare_operator"
10553 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10554 (const_int 0)]))
10555 (set (match_operand:HI 1 "nonimmediate_operand" "")
10556 (not:HI (match_dup 3)))]
10557 "ix86_match_ccmode (insn, CCNOmode)"
10558 [(parallel [(set (match_dup 0)
10559 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10560 (const_int 0)]))
10561 (set (match_dup 1)
10562 (xor:HI (match_dup 3) (const_int -1)))])]
10563 "")
10564
10565;; %%% Potential partial reg stall on alternative 1. What to do?
10566(define_expand "one_cmplqi2"
10567 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10568 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10569 "TARGET_QIMODE_MATH"
10570 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10571
10572(define_insn "*one_cmplqi2_1"
10573 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10574 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10575 "ix86_unary_operator_ok (NOT, QImode, operands)"
10576 "@
10577 not{b}\t%0
10578 not{l}\t%k0"
10579 [(set_attr "type" "negnot")
10580 (set_attr "mode" "QI,SI")])
10581
10582(define_insn "*one_cmplqi2_2"
10583 [(set (reg 17)
10584 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10585 (const_int 0)))
10586 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10587 (not:QI (match_dup 1)))]
10588 "ix86_match_ccmode (insn, CCNOmode)
10589 && ix86_unary_operator_ok (NOT, QImode, operands)"
10590 "#"
10591 [(set_attr "type" "alu1")
10592 (set_attr "mode" "QI")])
10593
10594(define_split
10595 [(set (match_operand 0 "flags_reg_operand" "")
10596 (match_operator 2 "compare_operator"
10597 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10598 (const_int 0)]))
10599 (set (match_operand:QI 1 "nonimmediate_operand" "")
10600 (not:QI (match_dup 3)))]
10601 "ix86_match_ccmode (insn, CCNOmode)"
10602 [(parallel [(set (match_dup 0)
10603 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10604 (const_int 0)]))
10605 (set (match_dup 1)
10606 (xor:QI (match_dup 3) (const_int -1)))])]
10607 "")
10608
10609;; Arithmetic shift instructions
10610
10611;; DImode shifts are implemented using the i386 "shift double" opcode,
10612;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10613;; is variable, then the count is in %cl and the "imm" operand is dropped
10614;; from the assembler input.
10615;;
10616;; This instruction shifts the target reg/mem as usual, but instead of
10617;; shifting in zeros, bits are shifted in from reg operand. If the insn
10618;; is a left shift double, bits are taken from the high order bits of
10619;; reg, else if the insn is a shift right double, bits are taken from the
10620;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10621;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10622;;
10623;; Since sh[lr]d does not change the `reg' operand, that is done
10624;; separately, making all shifts emit pairs of shift double and normal
10625;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10626;; support a 63 bit shift, each shift where the count is in a reg expands
10627;; to a pair of shifts, a branch, a shift by 32 and a label.
10628;;
10629;; If the shift count is a constant, we need never emit more than one
10630;; shift pair, instead using moves and sign extension for counts greater
10631;; than 31.
10632
10633(define_expand "ashldi3"
10634 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10635 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10636 (match_operand:QI 2 "nonmemory_operand" "")))
10637 (clobber (reg:CC 17))])]
10638 ""
10639{
10640 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10641 {
10642 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10643 DONE;
10644 }
10645 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10646 DONE;
10647})
10648
10649(define_insn "*ashldi3_1_rex64"
10650 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10651 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10652 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10653 (clobber (reg:CC 17))]
10654 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10655{
10656 switch (get_attr_type (insn))
10657 {
10658 case TYPE_ALU:
10659 if (operands[2] != const1_rtx)
10660 abort ();
10661 if (!rtx_equal_p (operands[0], operands[1]))
10662 abort ();
10663 return "add{q}\t{%0, %0|%0, %0}";
10664
10665 case TYPE_LEA:
10666 if (GET_CODE (operands[2]) != CONST_INT
10667 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10668 abort ();
10669 operands[1] = gen_rtx_MULT (DImode, operands[1],
10670 GEN_INT (1 << INTVAL (operands[2])));
10671 return "lea{q}\t{%a1, %0|%0, %a1}";
10672
10673 default:
10674 if (REG_P (operands[2]))
10675 return "sal{q}\t{%b2, %0|%0, %b2}";
10676 else if (GET_CODE (operands[2]) == CONST_INT
10677 && INTVAL (operands[2]) == 1
10678 && (TARGET_SHIFT1 || optimize_size))
10679 return "sal{q}\t%0";
10680 else
10681 return "sal{q}\t{%2, %0|%0, %2}";
10682 }
10683}
10684 [(set (attr "type")
10685 (cond [(eq_attr "alternative" "1")
10686 (const_string "lea")
10687 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10688 (const_int 0))
10689 (match_operand 0 "register_operand" ""))
10690 (match_operand 2 "const1_operand" ""))
10691 (const_string "alu")
10692 ]
10693 (const_string "ishift")))
10694 (set_attr "mode" "DI")])
10695
10696;; Convert lea to the lea pattern to avoid flags dependency.
10697(define_split
10698 [(set (match_operand:DI 0 "register_operand" "")
10699 (ashift:DI (match_operand:DI 1 "register_operand" "")
10700 (match_operand:QI 2 "immediate_operand" "")))
10701 (clobber (reg:CC 17))]
10702 "TARGET_64BIT && reload_completed
10703 && true_regnum (operands[0]) != true_regnum (operands[1])"
10704 [(set (match_dup 0)
10705 (mult:DI (match_dup 1)
10706 (match_dup 2)))]
10707 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10708
10709;; This pattern can't accept a variable shift count, since shifts by
10710;; zero don't affect the flags. We assume that shifts by constant
10711;; zero are optimized away.
10712(define_insn "*ashldi3_cmp_rex64"
10713 [(set (reg 17)
10714 (compare
10715 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10716 (match_operand:QI 2 "immediate_operand" "e"))
10717 (const_int 0)))
10718 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10719 (ashift:DI (match_dup 1) (match_dup 2)))]
10720 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10721 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10722{
10723 switch (get_attr_type (insn))
10724 {
10725 case TYPE_ALU:
10726 if (operands[2] != const1_rtx)
10727 abort ();
10728 return "add{q}\t{%0, %0|%0, %0}";
10729
10730 default:
10731 if (REG_P (operands[2]))
10732 return "sal{q}\t{%b2, %0|%0, %b2}";
10733 else if (GET_CODE (operands[2]) == CONST_INT
10734 && INTVAL (operands[2]) == 1
10735 && (TARGET_SHIFT1 || optimize_size))
10736 return "sal{q}\t%0";
10737 else
10738 return "sal{q}\t{%2, %0|%0, %2}";
10739 }
10740}
10741 [(set (attr "type")
10742 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10743 (const_int 0))
10744 (match_operand 0 "register_operand" ""))
10745 (match_operand 2 "const1_operand" ""))
10746 (const_string "alu")
10747 ]
10748 (const_string "ishift")))
10749 (set_attr "mode" "DI")])
10750
10751(define_insn "ashldi3_1"
10752 [(set (match_operand:DI 0 "register_operand" "=r")
10753 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10754 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10755 (clobber (match_scratch:SI 3 "=&r"))
10756 (clobber (reg:CC 17))]
10757 "!TARGET_64BIT && TARGET_CMOVE"
10758 "#"
10759 [(set_attr "type" "multi")])
10760
10761(define_insn "*ashldi3_2"
10762 [(set (match_operand:DI 0 "register_operand" "=r")
10763 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10764 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10765 (clobber (reg:CC 17))]
10766 "!TARGET_64BIT"
10767 "#"
10768 [(set_attr "type" "multi")])
10769
10770(define_split
10771 [(set (match_operand:DI 0 "register_operand" "")
10772 (ashift:DI (match_operand:DI 1 "register_operand" "")
10773 (match_operand:QI 2 "nonmemory_operand" "")))
10774 (clobber (match_scratch:SI 3 ""))
10775 (clobber (reg:CC 17))]
10776 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10777 [(const_int 0)]
10778 "ix86_split_ashldi (operands, operands[3]); DONE;")
10779
10780(define_split
10781 [(set (match_operand:DI 0 "register_operand" "")
10782 (ashift:DI (match_operand:DI 1 "register_operand" "")
10783 (match_operand:QI 2 "nonmemory_operand" "")))
10784 (clobber (reg:CC 17))]
10785 "!TARGET_64BIT && reload_completed"
10786 [(const_int 0)]
10787 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10788
10789(define_insn "x86_shld_1"
10790 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10791 (ior:SI (ashift:SI (match_dup 0)
10792 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10793 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10794 (minus:QI (const_int 32) (match_dup 2)))))
10795 (clobber (reg:CC 17))]
10796 ""
10797 "@
10798 shld{l}\t{%2, %1, %0|%0, %1, %2}
10799 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10800 [(set_attr "type" "ishift")
10801 (set_attr "prefix_0f" "1")
10802 (set_attr "mode" "SI")
10803 (set_attr "pent_pair" "np")
10804 (set_attr "athlon_decode" "vector")
10805 (set_attr "ppro_uops" "few")])
10806
10807(define_expand "x86_shift_adj_1"
10808 [(set (reg:CCZ 17)
10809 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10810 (const_int 32))
10811 (const_int 0)))
10812 (set (match_operand:SI 0 "register_operand" "")
10813 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10814 (match_operand:SI 1 "register_operand" "")
10815 (match_dup 0)))
10816 (set (match_dup 1)
10817 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10818 (match_operand:SI 3 "register_operand" "r")
10819 (match_dup 1)))]
10820 "TARGET_CMOVE"
10821 "")
10822
10823(define_expand "x86_shift_adj_2"
10824 [(use (match_operand:SI 0 "register_operand" ""))
10825 (use (match_operand:SI 1 "register_operand" ""))
10826 (use (match_operand:QI 2 "register_operand" ""))]
10827 ""
10828{
10829 rtx label = gen_label_rtx ();
10830 rtx tmp;
10831
10832 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10833
10834 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10835 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10836 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10837 gen_rtx_LABEL_REF (VOIDmode, label),
10838 pc_rtx);
10839 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10840 JUMP_LABEL (tmp) = label;
10841
10842 emit_move_insn (operands[0], operands[1]);
10843 emit_move_insn (operands[1], const0_rtx);
10844
10845 emit_label (label);
10846 LABEL_NUSES (label) = 1;
10847
10848 DONE;
10849})
10850
10851(define_expand "ashlsi3"
10852 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10853 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10854 (match_operand:QI 2 "nonmemory_operand" "")))
10855 (clobber (reg:CC 17))]
10856 ""
10857 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10858
10859(define_insn "*ashlsi3_1"
10860 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10861 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10862 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10863 (clobber (reg:CC 17))]
10864 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10865{
10866 switch (get_attr_type (insn))
10867 {
10868 case TYPE_ALU:
10869 if (operands[2] != const1_rtx)
10870 abort ();
10871 if (!rtx_equal_p (operands[0], operands[1]))
10872 abort ();
10873 return "add{l}\t{%0, %0|%0, %0}";
10874
10875 case TYPE_LEA:
10876 return "#";
10877
10878 default:
10879 if (REG_P (operands[2]))
10880 return "sal{l}\t{%b2, %0|%0, %b2}";
10881 else if (GET_CODE (operands[2]) == CONST_INT
10882 && INTVAL (operands[2]) == 1
10883 && (TARGET_SHIFT1 || optimize_size))
10884 return "sal{l}\t%0";
10885 else
10886 return "sal{l}\t{%2, %0|%0, %2}";
10887 }
10888}
10889 [(set (attr "type")
10890 (cond [(eq_attr "alternative" "1")
10891 (const_string "lea")
10892 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893 (const_int 0))
10894 (match_operand 0 "register_operand" ""))
10895 (match_operand 2 "const1_operand" ""))
10896 (const_string "alu")
10897 ]
10898 (const_string "ishift")))
10899 (set_attr "mode" "SI")])
10900
10901;; Convert lea to the lea pattern to avoid flags dependency.
10902(define_split
10903 [(set (match_operand 0 "register_operand" "")
10904 (ashift (match_operand 1 "index_register_operand" "")
10905 (match_operand:QI 2 "const_int_operand" "")))
10906 (clobber (reg:CC 17))]
10907 "reload_completed
10908 && true_regnum (operands[0]) != true_regnum (operands[1])"
10909 [(const_int 0)]
10910{
10911 rtx pat;
10912 operands[0] = gen_lowpart (SImode, operands[0]);
10913 operands[1] = gen_lowpart (Pmode, operands[1]);
10914 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10915 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10916 if (Pmode != SImode)
10917 pat = gen_rtx_SUBREG (SImode, pat, 0);
10918 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10919 DONE;
10920})
10921
10922;; Rare case of shifting RSP is handled by generating move and shift
10923(define_split
10924 [(set (match_operand 0 "register_operand" "")
10925 (ashift (match_operand 1 "register_operand" "")
10926 (match_operand:QI 2 "const_int_operand" "")))
10927 (clobber (reg:CC 17))]
10928 "reload_completed
10929 && true_regnum (operands[0]) != true_regnum (operands[1])"
10930 [(const_int 0)]
10931{
10932 rtx pat, clob;
10933 emit_move_insn (operands[1], operands[0]);
10934 pat = gen_rtx_SET (VOIDmode, operands[0],
10935 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10936 operands[0], operands[2]));
10937 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10938 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10939 DONE;
10940})
10941
10942(define_insn "*ashlsi3_1_zext"
10943 [(set (match_operand:DI 0 "register_operand" "=r,r")
10944 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10945 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10946 (clobber (reg:CC 17))]
10947 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10948{
10949 switch (get_attr_type (insn))
10950 {
10951 case TYPE_ALU:
10952 if (operands[2] != const1_rtx)
10953 abort ();
10954 return "add{l}\t{%k0, %k0|%k0, %k0}";
10955
10956 case TYPE_LEA:
10957 return "#";
10958
10959 default:
10960 if (REG_P (operands[2]))
10961 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10962 else if (GET_CODE (operands[2]) == CONST_INT
10963 && INTVAL (operands[2]) == 1
10964 && (TARGET_SHIFT1 || optimize_size))
10965 return "sal{l}\t%k0";
10966 else
10967 return "sal{l}\t{%2, %k0|%k0, %2}";
10968 }
10969}
10970 [(set (attr "type")
10971 (cond [(eq_attr "alternative" "1")
10972 (const_string "lea")
10973 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974 (const_int 0))
10975 (match_operand 2 "const1_operand" ""))
10976 (const_string "alu")
10977 ]
10978 (const_string "ishift")))
10979 (set_attr "mode" "SI")])
10980
10981;; Convert lea to the lea pattern to avoid flags dependency.
10982(define_split
10983 [(set (match_operand:DI 0 "register_operand" "")
10984 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10985 (match_operand:QI 2 "const_int_operand" ""))))
10986 (clobber (reg:CC 17))]
10987 "TARGET_64BIT && reload_completed
10988 && true_regnum (operands[0]) != true_regnum (operands[1])"
10989 [(set (match_dup 0) (zero_extend:DI
10990 (subreg:SI (mult:SI (match_dup 1)
10991 (match_dup 2)) 0)))]
10992{
10993 operands[1] = gen_lowpart (Pmode, operands[1]);
10994 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10995})
10996
10997;; This pattern can't accept a variable shift count, since shifts by
10998;; zero don't affect the flags. We assume that shifts by constant
10999;; zero are optimized away.
11000(define_insn "*ashlsi3_cmp"
11001 [(set (reg 17)
11002 (compare
11003 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11004 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11005 (const_int 0)))
11006 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11007 (ashift:SI (match_dup 1) (match_dup 2)))]
11008 "ix86_match_ccmode (insn, CCGOCmode)
11009 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11010{
11011 switch (get_attr_type (insn))
11012 {
11013 case TYPE_ALU:
11014 if (operands[2] != const1_rtx)
11015 abort ();
11016 return "add{l}\t{%0, %0|%0, %0}";
11017
11018 default:
11019 if (REG_P (operands[2]))
11020 return "sal{l}\t{%b2, %0|%0, %b2}";
11021 else if (GET_CODE (operands[2]) == CONST_INT
11022 && INTVAL (operands[2]) == 1
11023 && (TARGET_SHIFT1 || optimize_size))
11024 return "sal{l}\t%0";
11025 else
11026 return "sal{l}\t{%2, %0|%0, %2}";
11027 }
11028}
11029 [(set (attr "type")
11030 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11031 (const_int 0))
11032 (match_operand 0 "register_operand" ""))
11033 (match_operand 2 "const1_operand" ""))
11034 (const_string "alu")
11035 ]
11036 (const_string "ishift")))
11037 (set_attr "mode" "SI")])
11038
11039(define_insn "*ashlsi3_cmp_zext"
11040 [(set (reg 17)
11041 (compare
11042 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11043 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11044 (const_int 0)))
11045 (set (match_operand:DI 0 "register_operand" "=r")
11046 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11047 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11048 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11049{
11050 switch (get_attr_type (insn))
11051 {
11052 case TYPE_ALU:
11053 if (operands[2] != const1_rtx)
11054 abort ();
11055 return "add{l}\t{%k0, %k0|%k0, %k0}";
11056
11057 default:
11058 if (REG_P (operands[2]))
11059 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11060 else if (GET_CODE (operands[2]) == CONST_INT
11061 && INTVAL (operands[2]) == 1
11062 && (TARGET_SHIFT1 || optimize_size))
11063 return "sal{l}\t%k0";
11064 else
11065 return "sal{l}\t{%2, %k0|%k0, %2}";
11066 }
11067}
11068 [(set (attr "type")
11069 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11070 (const_int 0))
11071 (match_operand 2 "const1_operand" ""))
11072 (const_string "alu")
11073 ]
11074 (const_string "ishift")))
11075 (set_attr "mode" "SI")])
11076
11077(define_expand "ashlhi3"
11078 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11079 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11080 (match_operand:QI 2 "nonmemory_operand" "")))
11081 (clobber (reg:CC 17))]
11082 "TARGET_HIMODE_MATH"
11083 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11084
11085(define_insn "*ashlhi3_1_lea"
11086 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11087 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11088 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11089 (clobber (reg:CC 17))]
11090 "!TARGET_PARTIAL_REG_STALL
11091 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11092{
11093 switch (get_attr_type (insn))
11094 {
11095 case TYPE_LEA:
11096 return "#";
11097 case TYPE_ALU:
11098 if (operands[2] != const1_rtx)
11099 abort ();
11100 return "add{w}\t{%0, %0|%0, %0}";
11101
11102 default:
11103 if (REG_P (operands[2]))
11104 return "sal{w}\t{%b2, %0|%0, %b2}";
11105 else if (GET_CODE (operands[2]) == CONST_INT
11106 && INTVAL (operands[2]) == 1
11107 && (TARGET_SHIFT1 || optimize_size))
11108 return "sal{w}\t%0";
11109 else
11110 return "sal{w}\t{%2, %0|%0, %2}";
11111 }
11112}
11113 [(set (attr "type")
11114 (cond [(eq_attr "alternative" "1")
11115 (const_string "lea")
11116 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11117 (const_int 0))
11118 (match_operand 0 "register_operand" ""))
11119 (match_operand 2 "const1_operand" ""))
11120 (const_string "alu")
11121 ]
11122 (const_string "ishift")))
11123 (set_attr "mode" "HI,SI")])
11124
11125(define_insn "*ashlhi3_1"
11126 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11127 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11128 (match_operand:QI 2 "nonmemory_operand" "cI")))
11129 (clobber (reg:CC 17))]
11130 "TARGET_PARTIAL_REG_STALL
11131 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11132{
11133 switch (get_attr_type (insn))
11134 {
11135 case TYPE_ALU:
11136 if (operands[2] != const1_rtx)
11137 abort ();
11138 return "add{w}\t{%0, %0|%0, %0}";
11139
11140 default:
11141 if (REG_P (operands[2]))
11142 return "sal{w}\t{%b2, %0|%0, %b2}";
11143 else if (GET_CODE (operands[2]) == CONST_INT
11144 && INTVAL (operands[2]) == 1
11145 && (TARGET_SHIFT1 || optimize_size))
11146 return "sal{w}\t%0";
11147 else
11148 return "sal{w}\t{%2, %0|%0, %2}";
11149 }
11150}
11151 [(set (attr "type")
11152 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11153 (const_int 0))
11154 (match_operand 0 "register_operand" ""))
11155 (match_operand 2 "const1_operand" ""))
11156 (const_string "alu")
11157 ]
11158 (const_string "ishift")))
11159 (set_attr "mode" "HI")])
11160
11161;; This pattern can't accept a variable shift count, since shifts by
11162;; zero don't affect the flags. We assume that shifts by constant
11163;; zero are optimized away.
11164(define_insn "*ashlhi3_cmp"
11165 [(set (reg 17)
11166 (compare
11167 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11168 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11169 (const_int 0)))
11170 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11171 (ashift:HI (match_dup 1) (match_dup 2)))]
11172 "ix86_match_ccmode (insn, CCGOCmode)
11173 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11174{
11175 switch (get_attr_type (insn))
11176 {
11177 case TYPE_ALU:
11178 if (operands[2] != const1_rtx)
11179 abort ();
11180 return "add{w}\t{%0, %0|%0, %0}";
11181
11182 default:
11183 if (REG_P (operands[2]))
11184 return "sal{w}\t{%b2, %0|%0, %b2}";
11185 else if (GET_CODE (operands[2]) == CONST_INT
11186 && INTVAL (operands[2]) == 1
11187 && (TARGET_SHIFT1 || optimize_size))
11188 return "sal{w}\t%0";
11189 else
11190 return "sal{w}\t{%2, %0|%0, %2}";
11191 }
11192}
11193 [(set (attr "type")
11194 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11195 (const_int 0))
11196 (match_operand 0 "register_operand" ""))
11197 (match_operand 2 "const1_operand" ""))
11198 (const_string "alu")
11199 ]
11200 (const_string "ishift")))
11201 (set_attr "mode" "HI")])
11202
11203(define_expand "ashlqi3"
11204 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11205 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11206 (match_operand:QI 2 "nonmemory_operand" "")))
11207 (clobber (reg:CC 17))]
11208 "TARGET_QIMODE_MATH"
11209 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11210
11211;; %%% Potential partial reg stall on alternative 2. What to do?
11212
11213(define_insn "*ashlqi3_1_lea"
11214 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11215 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11216 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11217 (clobber (reg:CC 17))]
11218 "!TARGET_PARTIAL_REG_STALL
11219 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11220{
11221 switch (get_attr_type (insn))
11222 {
11223 case TYPE_LEA:
11224 return "#";
11225 case TYPE_ALU:
11226 if (operands[2] != const1_rtx)
11227 abort ();
11228 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11229 return "add{l}\t{%k0, %k0|%k0, %k0}";
11230 else
11231 return "add{b}\t{%0, %0|%0, %0}";
11232
11233 default:
11234 if (REG_P (operands[2]))
11235 {
11236 if (get_attr_mode (insn) == MODE_SI)
11237 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11238 else
11239 return "sal{b}\t{%b2, %0|%0, %b2}";
11240 }
11241 else if (GET_CODE (operands[2]) == CONST_INT
11242 && INTVAL (operands[2]) == 1
11243 && (TARGET_SHIFT1 || optimize_size))
11244 {
11245 if (get_attr_mode (insn) == MODE_SI)
11246 return "sal{l}\t%0";
11247 else
11248 return "sal{b}\t%0";
11249 }
11250 else
11251 {
11252 if (get_attr_mode (insn) == MODE_SI)
11253 return "sal{l}\t{%2, %k0|%k0, %2}";
11254 else
11255 return "sal{b}\t{%2, %0|%0, %2}";
11256 }
11257 }
11258}
11259 [(set (attr "type")
11260 (cond [(eq_attr "alternative" "2")
11261 (const_string "lea")
11262 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11263 (const_int 0))
11264 (match_operand 0 "register_operand" ""))
11265 (match_operand 2 "const1_operand" ""))
11266 (const_string "alu")
11267 ]
11268 (const_string "ishift")))
11269 (set_attr "mode" "QI,SI,SI")])
11270
11271(define_insn "*ashlqi3_1"
11272 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11273 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11274 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11275 (clobber (reg:CC 17))]
11276 "TARGET_PARTIAL_REG_STALL
11277 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11278{
11279 switch (get_attr_type (insn))
11280 {
11281 case TYPE_ALU:
11282 if (operands[2] != const1_rtx)
11283 abort ();
11284 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11285 return "add{l}\t{%k0, %k0|%k0, %k0}";
11286 else
11287 return "add{b}\t{%0, %0|%0, %0}";
11288
11289 default:
11290 if (REG_P (operands[2]))
11291 {
11292 if (get_attr_mode (insn) == MODE_SI)
11293 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11294 else
11295 return "sal{b}\t{%b2, %0|%0, %b2}";
11296 }
11297 else if (GET_CODE (operands[2]) == CONST_INT
11298 && INTVAL (operands[2]) == 1
11299 && (TARGET_SHIFT1 || optimize_size))
11300 {
11301 if (get_attr_mode (insn) == MODE_SI)
11302 return "sal{l}\t%0";
11303 else
11304 return "sal{b}\t%0";
11305 }
11306 else
11307 {
11308 if (get_attr_mode (insn) == MODE_SI)
11309 return "sal{l}\t{%2, %k0|%k0, %2}";
11310 else
11311 return "sal{b}\t{%2, %0|%0, %2}";
11312 }
11313 }
11314}
11315 [(set (attr "type")
11316 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11317 (const_int 0))
11318 (match_operand 0 "register_operand" ""))
11319 (match_operand 2 "const1_operand" ""))
11320 (const_string "alu")
11321 ]
11322 (const_string "ishift")))
11323 (set_attr "mode" "QI,SI")])
11324
11325;; This pattern can't accept a variable shift count, since shifts by
11326;; zero don't affect the flags. We assume that shifts by constant
11327;; zero are optimized away.
11328(define_insn "*ashlqi3_cmp"
11329 [(set (reg 17)
11330 (compare
11331 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11332 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11333 (const_int 0)))
11334 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11335 (ashift:QI (match_dup 1) (match_dup 2)))]
11336 "ix86_match_ccmode (insn, CCGOCmode)
11337 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11338{
11339 switch (get_attr_type (insn))
11340 {
11341 case TYPE_ALU:
11342 if (operands[2] != const1_rtx)
11343 abort ();
11344 return "add{b}\t{%0, %0|%0, %0}";
11345
11346 default:
11347 if (REG_P (operands[2]))
11348 return "sal{b}\t{%b2, %0|%0, %b2}";
11349 else if (GET_CODE (operands[2]) == CONST_INT
11350 && INTVAL (operands[2]) == 1
11351 && (TARGET_SHIFT1 || optimize_size))
11352 return "sal{b}\t%0";
11353 else
11354 return "sal{b}\t{%2, %0|%0, %2}";
11355 }
11356}
11357 [(set (attr "type")
11358 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11359 (const_int 0))
11360 (match_operand 0 "register_operand" ""))
11361 (match_operand 2 "const1_operand" ""))
11362 (const_string "alu")
11363 ]
11364 (const_string "ishift")))
11365 (set_attr "mode" "QI")])
11366
11367;; See comment above `ashldi3' about how this works.
11368
11369(define_expand "ashrdi3"
11370 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11371 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11372 (match_operand:QI 2 "nonmemory_operand" "")))
11373 (clobber (reg:CC 17))])]
11374 ""
11375{
11376 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11377 {
11378 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11379 DONE;
11380 }
11381 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11382 DONE;
11383})
11384
11385(define_insn "ashrdi3_63_rex64"
11386 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11387 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11388 (match_operand:DI 2 "const_int_operand" "i,i")))
11389 (clobber (reg:CC 17))]
11390 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11391 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11392 "@
11393 {cqto|cqo}
11394 sar{q}\t{%2, %0|%0, %2}"
11395 [(set_attr "type" "imovx,ishift")
11396 (set_attr "prefix_0f" "0,*")
11397 (set_attr "length_immediate" "0,*")
11398 (set_attr "modrm" "0,1")
11399 (set_attr "mode" "DI")])
11400
11401(define_insn "*ashrdi3_1_one_bit_rex64"
11402 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11403 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11404 (match_operand:QI 2 "const1_operand" "")))
11405 (clobber (reg:CC 17))]
11406 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11407 && (TARGET_SHIFT1 || optimize_size)"
11408 "sar{q}\t%0"
11409 [(set_attr "type" "ishift")
11410 (set (attr "length")
11411 (if_then_else (match_operand:DI 0 "register_operand" "")
11412 (const_string "2")
11413 (const_string "*")))])
11414
11415(define_insn "*ashrdi3_1_rex64"
11416 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11417 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11418 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11419 (clobber (reg:CC 17))]
11420 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11421 "@
11422 sar{q}\t{%2, %0|%0, %2}
11423 sar{q}\t{%b2, %0|%0, %b2}"
11424 [(set_attr "type" "ishift")
11425 (set_attr "mode" "DI")])
11426
11427;; This pattern can't accept a variable shift count, since shifts by
11428;; zero don't affect the flags. We assume that shifts by constant
11429;; zero are optimized away.
11430(define_insn "*ashrdi3_one_bit_cmp_rex64"
11431 [(set (reg 17)
11432 (compare
11433 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434 (match_operand:QI 2 "const1_operand" ""))
11435 (const_int 0)))
11436 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439 && (TARGET_SHIFT1 || optimize_size)
11440 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11441 "sar{q}\t%0"
11442 [(set_attr "type" "ishift")
11443 (set (attr "length")
11444 (if_then_else (match_operand:DI 0 "register_operand" "")
11445 (const_string "2")
11446 (const_string "*")))])
11447
11448;; This pattern can't accept a variable shift count, since shifts by
11449;; zero don't affect the flags. We assume that shifts by constant
11450;; zero are optimized away.
11451(define_insn "*ashrdi3_cmp_rex64"
11452 [(set (reg 17)
11453 (compare
11454 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11455 (match_operand:QI 2 "const_int_operand" "n"))
11456 (const_int 0)))
11457 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11458 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11459 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11460 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11461 "sar{q}\t{%2, %0|%0, %2}"
11462 [(set_attr "type" "ishift")
11463 (set_attr "mode" "DI")])
11464
11465
11466(define_insn "ashrdi3_1"
11467 [(set (match_operand:DI 0 "register_operand" "=r")
11468 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11469 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11470 (clobber (match_scratch:SI 3 "=&r"))
11471 (clobber (reg:CC 17))]
11472 "!TARGET_64BIT && TARGET_CMOVE"
11473 "#"
11474 [(set_attr "type" "multi")])
11475
11476(define_insn "*ashrdi3_2"
11477 [(set (match_operand:DI 0 "register_operand" "=r")
11478 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11479 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11480 (clobber (reg:CC 17))]
11481 "!TARGET_64BIT"
11482 "#"
11483 [(set_attr "type" "multi")])
11484
11485(define_split
11486 [(set (match_operand:DI 0 "register_operand" "")
11487 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11488 (match_operand:QI 2 "nonmemory_operand" "")))
11489 (clobber (match_scratch:SI 3 ""))
11490 (clobber (reg:CC 17))]
11491 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11492 [(const_int 0)]
11493 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11494
11495(define_split
11496 [(set (match_operand:DI 0 "register_operand" "")
11497 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11498 (match_operand:QI 2 "nonmemory_operand" "")))
11499 (clobber (reg:CC 17))]
11500 "!TARGET_64BIT && reload_completed"
11501 [(const_int 0)]
11502 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11503
11504(define_insn "x86_shrd_1"
11505 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11506 (ior:SI (ashiftrt:SI (match_dup 0)
11507 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11508 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11509 (minus:QI (const_int 32) (match_dup 2)))))
11510 (clobber (reg:CC 17))]
11511 ""
11512 "@
11513 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11514 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11515 [(set_attr "type" "ishift")
11516 (set_attr "prefix_0f" "1")
11517 (set_attr "pent_pair" "np")
11518 (set_attr "ppro_uops" "few")
11519 (set_attr "mode" "SI")])
11520
11521(define_expand "x86_shift_adj_3"
11522 [(use (match_operand:SI 0 "register_operand" ""))
11523 (use (match_operand:SI 1 "register_operand" ""))
11524 (use (match_operand:QI 2 "register_operand" ""))]
11525 ""
11526{
11527 rtx label = gen_label_rtx ();
11528 rtx tmp;
11529
11530 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11531
11532 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11533 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11534 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11535 gen_rtx_LABEL_REF (VOIDmode, label),
11536 pc_rtx);
11537 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11538 JUMP_LABEL (tmp) = label;
11539
11540 emit_move_insn (operands[0], operands[1]);
11541 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11542
11543 emit_label (label);
11544 LABEL_NUSES (label) = 1;
11545
11546 DONE;
11547})
11548
11549(define_insn "ashrsi3_31"
11550 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11551 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11552 (match_operand:SI 2 "const_int_operand" "i,i")))
11553 (clobber (reg:CC 17))]
11554 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11555 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11556 "@
11557 {cltd|cdq}
11558 sar{l}\t{%2, %0|%0, %2}"
11559 [(set_attr "type" "imovx,ishift")
11560 (set_attr "prefix_0f" "0,*")
11561 (set_attr "length_immediate" "0,*")
11562 (set_attr "modrm" "0,1")
11563 (set_attr "mode" "SI")])
11564
11565(define_insn "*ashrsi3_31_zext"
11566 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11567 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11568 (match_operand:SI 2 "const_int_operand" "i,i"))))
11569 (clobber (reg:CC 17))]
11570 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11571 && INTVAL (operands[2]) == 31
11572 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11573 "@
11574 {cltd|cdq}
11575 sar{l}\t{%2, %k0|%k0, %2}"
11576 [(set_attr "type" "imovx,ishift")
11577 (set_attr "prefix_0f" "0,*")
11578 (set_attr "length_immediate" "0,*")
11579 (set_attr "modrm" "0,1")
11580 (set_attr "mode" "SI")])
11581
11582(define_expand "ashrsi3"
11583 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11584 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11585 (match_operand:QI 2 "nonmemory_operand" "")))
11586 (clobber (reg:CC 17))]
11587 ""
11588 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11589
11590(define_insn "*ashrsi3_1_one_bit"
11591 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11592 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11593 (match_operand:QI 2 "const1_operand" "")))
11594 (clobber (reg:CC 17))]
11595 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11596 && (TARGET_SHIFT1 || optimize_size)"
11597 "sar{l}\t%0"
11598 [(set_attr "type" "ishift")
11599 (set (attr "length")
11600 (if_then_else (match_operand:SI 0 "register_operand" "")
11601 (const_string "2")
11602 (const_string "*")))])
11603
11604(define_insn "*ashrsi3_1_one_bit_zext"
11605 [(set (match_operand:DI 0 "register_operand" "=r")
11606 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11607 (match_operand:QI 2 "const1_operand" ""))))
11608 (clobber (reg:CC 17))]
11609 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11610 && (TARGET_SHIFT1 || optimize_size)"
11611 "sar{l}\t%k0"
11612 [(set_attr "type" "ishift")
11613 (set_attr "length" "2")])
11614
11615(define_insn "*ashrsi3_1"
11616 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11617 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11618 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11619 (clobber (reg:CC 17))]
11620 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11621 "@
11622 sar{l}\t{%2, %0|%0, %2}
11623 sar{l}\t{%b2, %0|%0, %b2}"
11624 [(set_attr "type" "ishift")
11625 (set_attr "mode" "SI")])
11626
11627(define_insn "*ashrsi3_1_zext"
11628 [(set (match_operand:DI 0 "register_operand" "=r,r")
11629 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11630 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11631 (clobber (reg:CC 17))]
11632 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11633 "@
11634 sar{l}\t{%2, %k0|%k0, %2}
11635 sar{l}\t{%b2, %k0|%k0, %b2}"
11636 [(set_attr "type" "ishift")
11637 (set_attr "mode" "SI")])
11638
11639;; This pattern can't accept a variable shift count, since shifts by
11640;; zero don't affect the flags. We assume that shifts by constant
11641;; zero are optimized away.
11642(define_insn "*ashrsi3_one_bit_cmp"
11643 [(set (reg 17)
11644 (compare
11645 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11646 (match_operand:QI 2 "const1_operand" ""))
11647 (const_int 0)))
11648 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11649 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11650 "ix86_match_ccmode (insn, CCGOCmode)
11651 && (TARGET_SHIFT1 || optimize_size)
11652 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653 "sar{l}\t%0"
11654 [(set_attr "type" "ishift")
11655 (set (attr "length")
11656 (if_then_else (match_operand:SI 0 "register_operand" "")
11657 (const_string "2")
11658 (const_string "*")))])
11659
11660(define_insn "*ashrsi3_one_bit_cmp_zext"
11661 [(set (reg 17)
11662 (compare
11663 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11664 (match_operand:QI 2 "const1_operand" ""))
11665 (const_int 0)))
11666 (set (match_operand:DI 0 "register_operand" "=r")
11667 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11668 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11669 && (TARGET_SHIFT1 || optimize_size)
11670 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11671 "sar{l}\t%k0"
11672 [(set_attr "type" "ishift")
11673 (set_attr "length" "2")])
11674
11675;; This pattern can't accept a variable shift count, since shifts by
11676;; zero don't affect the flags. We assume that shifts by constant
11677;; zero are optimized away.
11678(define_insn "*ashrsi3_cmp"
11679 [(set (reg 17)
11680 (compare
11681 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11683 (const_int 0)))
11684 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11685 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11686 "ix86_match_ccmode (insn, CCGOCmode)
11687 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11688 "sar{l}\t{%2, %0|%0, %2}"
11689 [(set_attr "type" "ishift")
11690 (set_attr "mode" "SI")])
11691
11692(define_insn "*ashrsi3_cmp_zext"
11693 [(set (reg 17)
11694 (compare
11695 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11696 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11697 (const_int 0)))
11698 (set (match_operand:DI 0 "register_operand" "=r")
11699 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11700 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11702 "sar{l}\t{%2, %k0|%k0, %2}"
11703 [(set_attr "type" "ishift")
11704 (set_attr "mode" "SI")])
11705
11706(define_expand "ashrhi3"
11707 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709 (match_operand:QI 2 "nonmemory_operand" "")))
11710 (clobber (reg:CC 17))]
11711 "TARGET_HIMODE_MATH"
11712 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11713
11714(define_insn "*ashrhi3_1_one_bit"
11715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11716 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717 (match_operand:QI 2 "const1_operand" "")))
11718 (clobber (reg:CC 17))]
11719 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11720 && (TARGET_SHIFT1 || optimize_size)"
11721 "sar{w}\t%0"
11722 [(set_attr "type" "ishift")
11723 (set (attr "length")
11724 (if_then_else (match_operand 0 "register_operand" "")
11725 (const_string "2")
11726 (const_string "*")))])
11727
11728(define_insn "*ashrhi3_1"
11729 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11730 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11731 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11732 (clobber (reg:CC 17))]
11733 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11734 "@
11735 sar{w}\t{%2, %0|%0, %2}
11736 sar{w}\t{%b2, %0|%0, %b2}"
11737 [(set_attr "type" "ishift")
11738 (set_attr "mode" "HI")])
11739
11740;; This pattern can't accept a variable shift count, since shifts by
11741;; zero don't affect the flags. We assume that shifts by constant
11742;; zero are optimized away.
11743(define_insn "*ashrhi3_one_bit_cmp"
11744 [(set (reg 17)
11745 (compare
11746 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747 (match_operand:QI 2 "const1_operand" ""))
11748 (const_int 0)))
11749 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11750 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11751 "ix86_match_ccmode (insn, CCGOCmode)
11752 && (TARGET_SHIFT1 || optimize_size)
11753 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11754 "sar{w}\t%0"
11755 [(set_attr "type" "ishift")
11756 (set (attr "length")
11757 (if_then_else (match_operand 0 "register_operand" "")
11758 (const_string "2")
11759 (const_string "*")))])
11760
11761;; This pattern can't accept a variable shift count, since shifts by
11762;; zero don't affect the flags. We assume that shifts by constant
11763;; zero are optimized away.
11764(define_insn "*ashrhi3_cmp"
11765 [(set (reg 17)
11766 (compare
11767 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11768 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11769 (const_int 0)))
11770 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11771 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11772 "ix86_match_ccmode (insn, CCGOCmode)
11773 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11774 "sar{w}\t{%2, %0|%0, %2}"
11775 [(set_attr "type" "ishift")
11776 (set_attr "mode" "HI")])
11777
11778(define_expand "ashrqi3"
11779 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11780 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11781 (match_operand:QI 2 "nonmemory_operand" "")))
11782 (clobber (reg:CC 17))]
11783 "TARGET_QIMODE_MATH"
11784 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11785
11786(define_insn "*ashrqi3_1_one_bit"
11787 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789 (match_operand:QI 2 "const1_operand" "")))
11790 (clobber (reg:CC 17))]
11791 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11792 && (TARGET_SHIFT1 || optimize_size)"
11793 "sar{b}\t%0"
11794 [(set_attr "type" "ishift")
11795 (set (attr "length")
11796 (if_then_else (match_operand 0 "register_operand" "")
11797 (const_string "2")
11798 (const_string "*")))])
11799
11800(define_insn "*ashrqi3_1_one_bit_slp"
11801 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11802 (ashiftrt:QI (match_dup 0)
11803 (match_operand:QI 1 "const1_operand" "")))
11804 (clobber (reg:CC 17))]
11805 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11806 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11807 && (TARGET_SHIFT1 || optimize_size)"
11808 "sar{b}\t%0"
11809 [(set_attr "type" "ishift1")
11810 (set (attr "length")
11811 (if_then_else (match_operand 0 "register_operand" "")
11812 (const_string "2")
11813 (const_string "*")))])
11814
11815(define_insn "*ashrqi3_1"
11816 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11817 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11818 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11819 (clobber (reg:CC 17))]
11820 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11821 "@
11822 sar{b}\t{%2, %0|%0, %2}
11823 sar{b}\t{%b2, %0|%0, %b2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "QI")])
11826
11827(define_insn "*ashrqi3_1_slp"
11828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11829 (ashiftrt:QI (match_dup 0)
11830 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11831 (clobber (reg:CC 17))]
11832 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11834 "@
11835 sar{b}\t{%1, %0|%0, %1}
11836 sar{b}\t{%b1, %0|%0, %b1}"
11837 [(set_attr "type" "ishift1")
11838 (set_attr "mode" "QI")])
11839
11840;; This pattern can't accept a variable shift count, since shifts by
11841;; zero don't affect the flags. We assume that shifts by constant
11842;; zero are optimized away.
11843(define_insn "*ashrqi3_one_bit_cmp"
11844 [(set (reg 17)
11845 (compare
11846 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11847 (match_operand:QI 2 "const1_operand" "I"))
11848 (const_int 0)))
11849 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11850 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11851 "ix86_match_ccmode (insn, CCGOCmode)
11852 && (TARGET_SHIFT1 || optimize_size)
11853 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11854 "sar{b}\t%0"
11855 [(set_attr "type" "ishift")
11856 (set (attr "length")
11857 (if_then_else (match_operand 0 "register_operand" "")
11858 (const_string "2")
11859 (const_string "*")))])
11860
11861;; This pattern can't accept a variable shift count, since shifts by
11862;; zero don't affect the flags. We assume that shifts by constant
11863;; zero are optimized away.
11864(define_insn "*ashrqi3_cmp"
11865 [(set (reg 17)
11866 (compare
11867 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11868 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11869 (const_int 0)))
11870 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11871 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11872 "ix86_match_ccmode (insn, CCGOCmode)
11873 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11874 "sar{b}\t{%2, %0|%0, %2}"
11875 [(set_attr "type" "ishift")
11876 (set_attr "mode" "QI")])
11877
11878;; Logical shift instructions
11879
11880;; See comment above `ashldi3' about how this works.
11881
11882(define_expand "lshrdi3"
11883 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11884 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11885 (match_operand:QI 2 "nonmemory_operand" "")))
11886 (clobber (reg:CC 17))])]
11887 ""
11888{
11889 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11890 {
11891 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11892 DONE;
11893 }
11894 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11895 DONE;
11896})
11897
11898(define_insn "*lshrdi3_1_one_bit_rex64"
11899 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11900 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11901 (match_operand:QI 2 "const1_operand" "")))
11902 (clobber (reg:CC 17))]
11903 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11904 && (TARGET_SHIFT1 || optimize_size)"
11905 "shr{q}\t%0"
11906 [(set_attr "type" "ishift")
11907 (set (attr "length")
11908 (if_then_else (match_operand:DI 0 "register_operand" "")
11909 (const_string "2")
11910 (const_string "*")))])
11911
11912(define_insn "*lshrdi3_1_rex64"
11913 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11914 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11915 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11916 (clobber (reg:CC 17))]
11917 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11918 "@
11919 shr{q}\t{%2, %0|%0, %2}
11920 shr{q}\t{%b2, %0|%0, %b2}"
11921 [(set_attr "type" "ishift")
11922 (set_attr "mode" "DI")])
11923
11924;; This pattern can't accept a variable shift count, since shifts by
11925;; zero don't affect the flags. We assume that shifts by constant
11926;; zero are optimized away.
11927(define_insn "*lshrdi3_cmp_one_bit_rex64"
11928 [(set (reg 17)
11929 (compare
11930 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11931 (match_operand:QI 2 "const1_operand" ""))
11932 (const_int 0)))
11933 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11934 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11935 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11936 && (TARGET_SHIFT1 || optimize_size)
11937 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11938 "shr{q}\t%0"
11939 [(set_attr "type" "ishift")
11940 (set (attr "length")
11941 (if_then_else (match_operand:DI 0 "register_operand" "")
11942 (const_string "2")
11943 (const_string "*")))])
11944
11945;; This pattern can't accept a variable shift count, since shifts by
11946;; zero don't affect the flags. We assume that shifts by constant
11947;; zero are optimized away.
11948(define_insn "*lshrdi3_cmp_rex64"
11949 [(set (reg 17)
11950 (compare
11951 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11952 (match_operand:QI 2 "const_int_operand" "e"))
11953 (const_int 0)))
11954 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11955 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11956 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11957 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11958 "shr{q}\t{%2, %0|%0, %2}"
11959 [(set_attr "type" "ishift")
11960 (set_attr "mode" "DI")])
11961
11962(define_insn "lshrdi3_1"
11963 [(set (match_operand:DI 0 "register_operand" "=r")
11964 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11965 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11966 (clobber (match_scratch:SI 3 "=&r"))
11967 (clobber (reg:CC 17))]
11968 "!TARGET_64BIT && TARGET_CMOVE"
11969 "#"
11970 [(set_attr "type" "multi")])
11971
11972(define_insn "*lshrdi3_2"
11973 [(set (match_operand:DI 0 "register_operand" "=r")
11974 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11975 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11976 (clobber (reg:CC 17))]
11977 "!TARGET_64BIT"
11978 "#"
11979 [(set_attr "type" "multi")])
11980
11981(define_split
11982 [(set (match_operand:DI 0 "register_operand" "")
11983 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11984 (match_operand:QI 2 "nonmemory_operand" "")))
11985 (clobber (match_scratch:SI 3 ""))
11986 (clobber (reg:CC 17))]
11987 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11988 [(const_int 0)]
11989 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11990
11991(define_split
11992 [(set (match_operand:DI 0 "register_operand" "")
11993 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11994 (match_operand:QI 2 "nonmemory_operand" "")))
11995 (clobber (reg:CC 17))]
11996 "!TARGET_64BIT && reload_completed"
11997 [(const_int 0)]
11998 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11999
12000(define_expand "lshrsi3"
12001 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12002 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12003 (match_operand:QI 2 "nonmemory_operand" "")))
12004 (clobber (reg:CC 17))]
12005 ""
12006 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12007
12008(define_insn "*lshrsi3_1_one_bit"
12009 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12010 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12011 (match_operand:QI 2 "const1_operand" "")))
12012 (clobber (reg:CC 17))]
12013 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12014 && (TARGET_SHIFT1 || optimize_size)"
12015 "shr{l}\t%0"
12016 [(set_attr "type" "ishift")
12017 (set (attr "length")
12018 (if_then_else (match_operand:SI 0 "register_operand" "")
12019 (const_string "2")
12020 (const_string "*")))])
12021
12022(define_insn "*lshrsi3_1_one_bit_zext"
12023 [(set (match_operand:DI 0 "register_operand" "=r")
12024 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12025 (match_operand:QI 2 "const1_operand" "")))
12026 (clobber (reg:CC 17))]
12027 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12028 && (TARGET_SHIFT1 || optimize_size)"
12029 "shr{l}\t%k0"
12030 [(set_attr "type" "ishift")
12031 (set_attr "length" "2")])
12032
12033(define_insn "*lshrsi3_1"
12034 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12035 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12036 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12037 (clobber (reg:CC 17))]
12038 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12039 "@
12040 shr{l}\t{%2, %0|%0, %2}
12041 shr{l}\t{%b2, %0|%0, %b2}"
12042 [(set_attr "type" "ishift")
12043 (set_attr "mode" "SI")])
12044
12045(define_insn "*lshrsi3_1_zext"
12046 [(set (match_operand:DI 0 "register_operand" "=r,r")
12047 (zero_extend:DI
12048 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12049 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12050 (clobber (reg:CC 17))]
12051 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12052 "@
12053 shr{l}\t{%2, %k0|%k0, %2}
12054 shr{l}\t{%b2, %k0|%k0, %b2}"
12055 [(set_attr "type" "ishift")
12056 (set_attr "mode" "SI")])
12057
12058;; This pattern can't accept a variable shift count, since shifts by
12059;; zero don't affect the flags. We assume that shifts by constant
12060;; zero are optimized away.
12061(define_insn "*lshrsi3_one_bit_cmp"
12062 [(set (reg 17)
12063 (compare
12064 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12065 (match_operand:QI 2 "const1_operand" ""))
12066 (const_int 0)))
12067 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12068 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12069 "ix86_match_ccmode (insn, CCGOCmode)
12070 && (TARGET_SHIFT1 || optimize_size)
12071 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12072 "shr{l}\t%0"
12073 [(set_attr "type" "ishift")
12074 (set (attr "length")
12075 (if_then_else (match_operand:SI 0 "register_operand" "")
12076 (const_string "2")
12077 (const_string "*")))])
12078
12079(define_insn "*lshrsi3_cmp_one_bit_zext"
12080 [(set (reg 17)
12081 (compare
12082 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12083 (match_operand:QI 2 "const1_operand" ""))
12084 (const_int 0)))
12085 (set (match_operand:DI 0 "register_operand" "=r")
12086 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12087 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12088 && (TARGET_SHIFT1 || optimize_size)
12089 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12090 "shr{l}\t%k0"
12091 [(set_attr "type" "ishift")
12092 (set_attr "length" "2")])
12093
12094;; This pattern can't accept a variable shift count, since shifts by
12095;; zero don't affect the flags. We assume that shifts by constant
12096;; zero are optimized away.
12097(define_insn "*lshrsi3_cmp"
12098 [(set (reg 17)
12099 (compare
12100 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12101 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12102 (const_int 0)))
12103 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12104 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12105 "ix86_match_ccmode (insn, CCGOCmode)
12106 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12107 "shr{l}\t{%2, %0|%0, %2}"
12108 [(set_attr "type" "ishift")
12109 (set_attr "mode" "SI")])
12110
12111(define_insn "*lshrsi3_cmp_zext"
12112 [(set (reg 17)
12113 (compare
12114 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12115 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12116 (const_int 0)))
12117 (set (match_operand:DI 0 "register_operand" "=r")
12118 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12119 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12120 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12121 "shr{l}\t{%2, %k0|%k0, %2}"
12122 [(set_attr "type" "ishift")
12123 (set_attr "mode" "SI")])
12124
12125(define_expand "lshrhi3"
12126 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12127 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12128 (match_operand:QI 2 "nonmemory_operand" "")))
12129 (clobber (reg:CC 17))]
12130 "TARGET_HIMODE_MATH"
12131 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12132
12133(define_insn "*lshrhi3_1_one_bit"
12134 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12135 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136 (match_operand:QI 2 "const1_operand" "")))
12137 (clobber (reg:CC 17))]
12138 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12139 && (TARGET_SHIFT1 || optimize_size)"
12140 "shr{w}\t%0"
12141 [(set_attr "type" "ishift")
12142 (set (attr "length")
12143 (if_then_else (match_operand 0 "register_operand" "")
12144 (const_string "2")
12145 (const_string "*")))])
12146
12147(define_insn "*lshrhi3_1"
12148 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12149 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12150 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12151 (clobber (reg:CC 17))]
12152 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12153 "@
12154 shr{w}\t{%2, %0|%0, %2}
12155 shr{w}\t{%b2, %0|%0, %b2}"
12156 [(set_attr "type" "ishift")
12157 (set_attr "mode" "HI")])
12158
12159;; This pattern can't accept a variable shift count, since shifts by
12160;; zero don't affect the flags. We assume that shifts by constant
12161;; zero are optimized away.
12162(define_insn "*lshrhi3_one_bit_cmp"
12163 [(set (reg 17)
12164 (compare
12165 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12166 (match_operand:QI 2 "const1_operand" ""))
12167 (const_int 0)))
12168 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12169 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12170 "ix86_match_ccmode (insn, CCGOCmode)
12171 && (TARGET_SHIFT1 || optimize_size)
12172 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12173 "shr{w}\t%0"
12174 [(set_attr "type" "ishift")
12175 (set (attr "length")
12176 (if_then_else (match_operand:SI 0 "register_operand" "")
12177 (const_string "2")
12178 (const_string "*")))])
12179
12180;; This pattern can't accept a variable shift count, since shifts by
12181;; zero don't affect the flags. We assume that shifts by constant
12182;; zero are optimized away.
12183(define_insn "*lshrhi3_cmp"
12184 [(set (reg 17)
12185 (compare
12186 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12187 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12188 (const_int 0)))
12189 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12190 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12191 "ix86_match_ccmode (insn, CCGOCmode)
12192 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12193 "shr{w}\t{%2, %0|%0, %2}"
12194 [(set_attr "type" "ishift")
12195 (set_attr "mode" "HI")])
12196
12197(define_expand "lshrqi3"
12198 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12199 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12200 (match_operand:QI 2 "nonmemory_operand" "")))
12201 (clobber (reg:CC 17))]
12202 "TARGET_QIMODE_MATH"
12203 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12204
12205(define_insn "*lshrqi3_1_one_bit"
12206 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12207 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12208 (match_operand:QI 2 "const1_operand" "")))
12209 (clobber (reg:CC 17))]
12210 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12211 && (TARGET_SHIFT1 || optimize_size)"
12212 "shr{b}\t%0"
12213 [(set_attr "type" "ishift")
12214 (set (attr "length")
12215 (if_then_else (match_operand 0 "register_operand" "")
12216 (const_string "2")
12217 (const_string "*")))])
12218
12219(define_insn "*lshrqi3_1_one_bit_slp"
12220 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221 (lshiftrt:QI (match_dup 0)
12222 (match_operand:QI 1 "const1_operand" "")))
12223 (clobber (reg:CC 17))]
12224 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225 && (TARGET_SHIFT1 || optimize_size)"
12226 "shr{b}\t%0"
12227 [(set_attr "type" "ishift1")
12228 (set (attr "length")
12229 (if_then_else (match_operand 0 "register_operand" "")
12230 (const_string "2")
12231 (const_string "*")))])
12232
12233(define_insn "*lshrqi3_1"
12234 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12235 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12236 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12237 (clobber (reg:CC 17))]
12238 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12239 "@
12240 shr{b}\t{%2, %0|%0, %2}
12241 shr{b}\t{%b2, %0|%0, %b2}"
12242 [(set_attr "type" "ishift")
12243 (set_attr "mode" "QI")])
12244
12245(define_insn "*lshrqi3_1_slp"
12246 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12247 (lshiftrt:QI (match_dup 0)
12248 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12249 (clobber (reg:CC 17))]
12250 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12251 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12252 "@
12253 shr{b}\t{%1, %0|%0, %1}
12254 shr{b}\t{%b1, %0|%0, %b1}"
12255 [(set_attr "type" "ishift1")
12256 (set_attr "mode" "QI")])
12257
12258;; This pattern can't accept a variable shift count, since shifts by
12259;; zero don't affect the flags. We assume that shifts by constant
12260;; zero are optimized away.
12261(define_insn "*lshrqi2_one_bit_cmp"
12262 [(set (reg 17)
12263 (compare
12264 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12265 (match_operand:QI 2 "const1_operand" ""))
12266 (const_int 0)))
12267 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12268 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12269 "ix86_match_ccmode (insn, CCGOCmode)
12270 && (TARGET_SHIFT1 || optimize_size)
12271 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12272 "shr{b}\t%0"
12273 [(set_attr "type" "ishift")
12274 (set (attr "length")
12275 (if_then_else (match_operand:SI 0 "register_operand" "")
12276 (const_string "2")
12277 (const_string "*")))])
12278
12279;; This pattern can't accept a variable shift count, since shifts by
12280;; zero don't affect the flags. We assume that shifts by constant
12281;; zero are optimized away.
12282(define_insn "*lshrqi2_cmp"
12283 [(set (reg 17)
12284 (compare
12285 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12286 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12287 (const_int 0)))
12288 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12289 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12290 "ix86_match_ccmode (insn, CCGOCmode)
12291 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12292 "shr{b}\t{%2, %0|%0, %2}"
12293 [(set_attr "type" "ishift")
12294 (set_attr "mode" "QI")])
12295
12296;; Rotate instructions
12297
12298(define_expand "rotldi3"
12299 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12300 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12301 (match_operand:QI 2 "nonmemory_operand" "")))
12302 (clobber (reg:CC 17))]
12303 "TARGET_64BIT"
12304 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12305
12306(define_insn "*rotlsi3_1_one_bit_rex64"
12307 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12308 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12309 (match_operand:QI 2 "const1_operand" "")))
12310 (clobber (reg:CC 17))]
12311 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12312 && (TARGET_SHIFT1 || optimize_size)"
12313 "rol{q}\t%0"
12314 [(set_attr "type" "rotate")
12315 (set (attr "length")
12316 (if_then_else (match_operand:DI 0 "register_operand" "")
12317 (const_string "2")
12318 (const_string "*")))])
12319
12320(define_insn "*rotldi3_1_rex64"
12321 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12322 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12323 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12324 (clobber (reg:CC 17))]
12325 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12326 "@
12327 rol{q}\t{%2, %0|%0, %2}
12328 rol{q}\t{%b2, %0|%0, %b2}"
12329 [(set_attr "type" "rotate")
12330 (set_attr "mode" "DI")])
12331
12332(define_expand "rotlsi3"
12333 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12334 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12335 (match_operand:QI 2 "nonmemory_operand" "")))
12336 (clobber (reg:CC 17))]
12337 ""
12338 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12339
12340(define_insn "*rotlsi3_1_one_bit"
12341 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12342 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12343 (match_operand:QI 2 "const1_operand" "")))
12344 (clobber (reg:CC 17))]
12345 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12346 && (TARGET_SHIFT1 || optimize_size)"
12347 "rol{l}\t%0"
12348 [(set_attr "type" "rotate")
12349 (set (attr "length")
12350 (if_then_else (match_operand:SI 0 "register_operand" "")
12351 (const_string "2")
12352 (const_string "*")))])
12353
12354(define_insn "*rotlsi3_1_one_bit_zext"
12355 [(set (match_operand:DI 0 "register_operand" "=r")
12356 (zero_extend:DI
12357 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12358 (match_operand:QI 2 "const1_operand" ""))))
12359 (clobber (reg:CC 17))]
12360 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12361 && (TARGET_SHIFT1 || optimize_size)"
12362 "rol{l}\t%k0"
12363 [(set_attr "type" "rotate")
12364 (set_attr "length" "2")])
12365
12366(define_insn "*rotlsi3_1"
12367 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12368 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12369 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12370 (clobber (reg:CC 17))]
12371 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12372 "@
12373 rol{l}\t{%2, %0|%0, %2}
12374 rol{l}\t{%b2, %0|%0, %b2}"
12375 [(set_attr "type" "rotate")
12376 (set_attr "mode" "SI")])
12377
12378(define_insn "*rotlsi3_1_zext"
12379 [(set (match_operand:DI 0 "register_operand" "=r,r")
12380 (zero_extend:DI
12381 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12382 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12383 (clobber (reg:CC 17))]
12384 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12385 "@
12386 rol{l}\t{%2, %k0|%k0, %2}
12387 rol{l}\t{%b2, %k0|%k0, %b2}"
12388 [(set_attr "type" "rotate")
12389 (set_attr "mode" "SI")])
12390
12391(define_expand "rotlhi3"
12392 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12393 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12394 (match_operand:QI 2 "nonmemory_operand" "")))
12395 (clobber (reg:CC 17))]
12396 "TARGET_HIMODE_MATH"
12397 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12398
12399(define_insn "*rotlhi3_1_one_bit"
12400 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402 (match_operand:QI 2 "const1_operand" "")))
12403 (clobber (reg:CC 17))]
12404 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12405 && (TARGET_SHIFT1 || optimize_size)"
12406 "rol{w}\t%0"
12407 [(set_attr "type" "rotate")
12408 (set (attr "length")
12409 (if_then_else (match_operand 0 "register_operand" "")
12410 (const_string "2")
12411 (const_string "*")))])
12412
12413(define_insn "*rotlhi3_1"
12414 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12415 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12416 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12417 (clobber (reg:CC 17))]
12418 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12419 "@
12420 rol{w}\t{%2, %0|%0, %2}
12421 rol{w}\t{%b2, %0|%0, %b2}"
12422 [(set_attr "type" "rotate")
12423 (set_attr "mode" "HI")])
12424
12425(define_expand "rotlqi3"
12426 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12427 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12428 (match_operand:QI 2 "nonmemory_operand" "")))
12429 (clobber (reg:CC 17))]
12430 "TARGET_QIMODE_MATH"
12431 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12432
12433(define_insn "*rotlqi3_1_one_bit_slp"
12434 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12435 (rotate:QI (match_dup 0)
12436 (match_operand:QI 1 "const1_operand" "")))
12437 (clobber (reg:CC 17))]
12438 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12439 && (TARGET_SHIFT1 || optimize_size)"
12440 "rol{b}\t%0"
12441 [(set_attr "type" "rotate1")
12442 (set (attr "length")
12443 (if_then_else (match_operand 0 "register_operand" "")
12444 (const_string "2")
12445 (const_string "*")))])
12446
12447(define_insn "*rotlqi3_1_one_bit"
12448 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12449 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450 (match_operand:QI 2 "const1_operand" "")))
12451 (clobber (reg:CC 17))]
12452 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12453 && (TARGET_SHIFT1 || optimize_size)"
12454 "rol{b}\t%0"
12455 [(set_attr "type" "rotate")
12456 (set (attr "length")
12457 (if_then_else (match_operand 0 "register_operand" "")
12458 (const_string "2")
12459 (const_string "*")))])
12460
12461(define_insn "*rotlqi3_1_slp"
12462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463 (rotate:QI (match_dup 0)
12464 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465 (clobber (reg:CC 17))]
12466 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12468 "@
12469 rol{b}\t{%1, %0|%0, %1}
12470 rol{b}\t{%b1, %0|%0, %b1}"
12471 [(set_attr "type" "rotate1")
12472 (set_attr "mode" "QI")])
12473
12474(define_insn "*rotlqi3_1"
12475 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12476 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12477 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478 (clobber (reg:CC 17))]
12479 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12480 "@
12481 rol{b}\t{%2, %0|%0, %2}
12482 rol{b}\t{%b2, %0|%0, %b2}"
12483 [(set_attr "type" "rotate")
12484 (set_attr "mode" "QI")])
12485
12486(define_expand "rotrdi3"
12487 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12488 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12489 (match_operand:QI 2 "nonmemory_operand" "")))
12490 (clobber (reg:CC 17))]
12491 "TARGET_64BIT"
12492 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12493
12494(define_insn "*rotrdi3_1_one_bit_rex64"
12495 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12496 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12497 (match_operand:QI 2 "const1_operand" "")))
12498 (clobber (reg:CC 17))]
12499 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12500 && (TARGET_SHIFT1 || optimize_size)"
12501 "ror{q}\t%0"
12502 [(set_attr "type" "rotate")
12503 (set (attr "length")
12504 (if_then_else (match_operand:DI 0 "register_operand" "")
12505 (const_string "2")
12506 (const_string "*")))])
12507
12508(define_insn "*rotrdi3_1_rex64"
12509 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12510 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12511 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12512 (clobber (reg:CC 17))]
12513 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12514 "@
12515 ror{q}\t{%2, %0|%0, %2}
12516 ror{q}\t{%b2, %0|%0, %b2}"
12517 [(set_attr "type" "rotate")
12518 (set_attr "mode" "DI")])
12519
12520(define_expand "rotrsi3"
12521 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12522 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12523 (match_operand:QI 2 "nonmemory_operand" "")))
12524 (clobber (reg:CC 17))]
12525 ""
12526 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12527
12528(define_insn "*rotrsi3_1_one_bit"
12529 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12530 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12531 (match_operand:QI 2 "const1_operand" "")))
12532 (clobber (reg:CC 17))]
12533 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12534 && (TARGET_SHIFT1 || optimize_size)"
12535 "ror{l}\t%0"
12536 [(set_attr "type" "rotate")
12537 (set (attr "length")
12538 (if_then_else (match_operand:SI 0 "register_operand" "")
12539 (const_string "2")
12540 (const_string "*")))])
12541
12542(define_insn "*rotrsi3_1_one_bit_zext"
12543 [(set (match_operand:DI 0 "register_operand" "=r")
12544 (zero_extend:DI
12545 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12546 (match_operand:QI 2 "const1_operand" ""))))
12547 (clobber (reg:CC 17))]
12548 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12549 && (TARGET_SHIFT1 || optimize_size)"
12550 "ror{l}\t%k0"
12551 [(set_attr "type" "rotate")
12552 (set (attr "length")
12553 (if_then_else (match_operand:SI 0 "register_operand" "")
12554 (const_string "2")
12555 (const_string "*")))])
12556
12557(define_insn "*rotrsi3_1"
12558 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12559 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12560 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12561 (clobber (reg:CC 17))]
12562 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12563 "@
12564 ror{l}\t{%2, %0|%0, %2}
12565 ror{l}\t{%b2, %0|%0, %b2}"
12566 [(set_attr "type" "rotate")
12567 (set_attr "mode" "SI")])
12568
12569(define_insn "*rotrsi3_1_zext"
12570 [(set (match_operand:DI 0 "register_operand" "=r,r")
12571 (zero_extend:DI
12572 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12573 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12574 (clobber (reg:CC 17))]
12575 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12576 "@
12577 ror{l}\t{%2, %k0|%k0, %2}
12578 ror{l}\t{%b2, %k0|%k0, %b2}"
12579 [(set_attr "type" "rotate")
12580 (set_attr "mode" "SI")])
12581
12582(define_expand "rotrhi3"
12583 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12584 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12585 (match_operand:QI 2 "nonmemory_operand" "")))
12586 (clobber (reg:CC 17))]
12587 "TARGET_HIMODE_MATH"
12588 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12589
12590(define_insn "*rotrhi3_one_bit"
12591 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12592 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12593 (match_operand:QI 2 "const1_operand" "")))
12594 (clobber (reg:CC 17))]
12595 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12596 && (TARGET_SHIFT1 || optimize_size)"
12597 "ror{w}\t%0"
12598 [(set_attr "type" "rotate")
12599 (set (attr "length")
12600 (if_then_else (match_operand 0 "register_operand" "")
12601 (const_string "2")
12602 (const_string "*")))])
12603
12604(define_insn "*rotrhi3"
12605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12606 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12607 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12608 (clobber (reg:CC 17))]
12609 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12610 "@
12611 ror{w}\t{%2, %0|%0, %2}
12612 ror{w}\t{%b2, %0|%0, %b2}"
12613 [(set_attr "type" "rotate")
12614 (set_attr "mode" "HI")])
12615
12616(define_expand "rotrqi3"
12617 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12618 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12619 (match_operand:QI 2 "nonmemory_operand" "")))
12620 (clobber (reg:CC 17))]
12621 "TARGET_QIMODE_MATH"
12622 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12623
12624(define_insn "*rotrqi3_1_one_bit"
12625 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12626 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12627 (match_operand:QI 2 "const1_operand" "")))
12628 (clobber (reg:CC 17))]
12629 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12630 && (TARGET_SHIFT1 || optimize_size)"
12631 "ror{b}\t%0"
12632 [(set_attr "type" "rotate")
12633 (set (attr "length")
12634 (if_then_else (match_operand 0 "register_operand" "")
12635 (const_string "2")
12636 (const_string "*")))])
12637
12638(define_insn "*rotrqi3_1_one_bit_slp"
12639 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12640 (rotatert:QI (match_dup 0)
12641 (match_operand:QI 1 "const1_operand" "")))
12642 (clobber (reg:CC 17))]
12643 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12644 && (TARGET_SHIFT1 || optimize_size)"
12645 "ror{b}\t%0"
12646 [(set_attr "type" "rotate1")
12647 (set (attr "length")
12648 (if_then_else (match_operand 0 "register_operand" "")
12649 (const_string "2")
12650 (const_string "*")))])
12651
12652(define_insn "*rotrqi3_1"
12653 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12654 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12655 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12656 (clobber (reg:CC 17))]
12657 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12658 "@
12659 ror{b}\t{%2, %0|%0, %2}
12660 ror{b}\t{%b2, %0|%0, %b2}"
12661 [(set_attr "type" "rotate")
12662 (set_attr "mode" "QI")])
12663
12664(define_insn "*rotrqi3_1_slp"
12665 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12666 (rotatert:QI (match_dup 0)
12667 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12668 (clobber (reg:CC 17))]
12669 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12670 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12671 "@
12672 ror{b}\t{%1, %0|%0, %1}
12673 ror{b}\t{%b1, %0|%0, %b1}"
12674 [(set_attr "type" "rotate1")
12675 (set_attr "mode" "QI")])
12676
12677;; Bit set / bit test instructions
12678
12679(define_expand "extv"
12680 [(set (match_operand:SI 0 "register_operand" "")
12681 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12682 (match_operand:SI 2 "immediate_operand" "")
12683 (match_operand:SI 3 "immediate_operand" "")))]
12684 ""
12685{
12686 /* Handle extractions from %ah et al. */
12687 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12688 FAIL;
12689
12690 /* From mips.md: extract_bit_field doesn't verify that our source
12691 matches the predicate, so check it again here. */
12692 if (! register_operand (operands[1], VOIDmode))
12693 FAIL;
12694})
12695
12696(define_expand "extzv"
12697 [(set (match_operand:SI 0 "register_operand" "")
12698 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12699 (match_operand:SI 2 "immediate_operand" "")
12700 (match_operand:SI 3 "immediate_operand" "")))]
12701 ""
12702{
12703 /* Handle extractions from %ah et al. */
12704 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12705 FAIL;
12706
12707 /* From mips.md: extract_bit_field doesn't verify that our source
12708 matches the predicate, so check it again here. */
12709 if (! register_operand (operands[1], VOIDmode))
12710 FAIL;
12711})
12712
12713(define_expand "insv"
12714 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12715 (match_operand 1 "immediate_operand" "")
12716 (match_operand 2 "immediate_operand" ""))
12717 (match_operand 3 "register_operand" ""))]
12718 ""
12719{
12720 /* Handle extractions from %ah et al. */
12721 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12722 FAIL;
12723
12724 /* From mips.md: insert_bit_field doesn't verify that our source
12725 matches the predicate, so check it again here. */
12726 if (! register_operand (operands[0], VOIDmode))
12727 FAIL;
12728
12729 if (TARGET_64BIT)
12730 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12731 else
12732 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12733
12734 DONE;
12735})
12736
12737;; %%% bts, btr, btc, bt.
12738
12739;; Store-flag instructions.
12740
12741;; For all sCOND expanders, also expand the compare or test insn that
12742;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12743
12744;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12745;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12746;; way, which can later delete the movzx if only QImode is needed.
12747
12748(define_expand "seq"
12749 [(set (match_operand:QI 0 "register_operand" "")
12750 (eq:QI (reg:CC 17) (const_int 0)))]
12751 ""
12752 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12753
12754(define_expand "sne"
12755 [(set (match_operand:QI 0 "register_operand" "")
12756 (ne:QI (reg:CC 17) (const_int 0)))]
12757 ""
12758 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12759
12760(define_expand "sgt"
12761 [(set (match_operand:QI 0 "register_operand" "")
12762 (gt:QI (reg:CC 17) (const_int 0)))]
12763 ""
12764 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12765
12766(define_expand "sgtu"
12767 [(set (match_operand:QI 0 "register_operand" "")
12768 (gtu:QI (reg:CC 17) (const_int 0)))]
12769 ""
12770 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12771
12772(define_expand "slt"
12773 [(set (match_operand:QI 0 "register_operand" "")
12774 (lt:QI (reg:CC 17) (const_int 0)))]
12775 ""
12776 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12777
12778(define_expand "sltu"
12779 [(set (match_operand:QI 0 "register_operand" "")
12780 (ltu:QI (reg:CC 17) (const_int 0)))]
12781 ""
12782 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12783
12784(define_expand "sge"
12785 [(set (match_operand:QI 0 "register_operand" "")
12786 (ge:QI (reg:CC 17) (const_int 0)))]
12787 ""
12788 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12789
12790(define_expand "sgeu"
12791 [(set (match_operand:QI 0 "register_operand" "")
12792 (geu:QI (reg:CC 17) (const_int 0)))]
12793 ""
12794 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12795
12796(define_expand "sle"
12797 [(set (match_operand:QI 0 "register_operand" "")
12798 (le:QI (reg:CC 17) (const_int 0)))]
12799 ""
12800 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12801
12802(define_expand "sleu"
12803 [(set (match_operand:QI 0 "register_operand" "")
12804 (leu:QI (reg:CC 17) (const_int 0)))]
12805 ""
12806 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12807
12808(define_expand "sunordered"
12809 [(set (match_operand:QI 0 "register_operand" "")
12810 (unordered:QI (reg:CC 17) (const_int 0)))]
12811 "TARGET_80387 || TARGET_SSE"
12812 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12813
12814(define_expand "sordered"
12815 [(set (match_operand:QI 0 "register_operand" "")
12816 (ordered:QI (reg:CC 17) (const_int 0)))]
12817 "TARGET_80387"
12818 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12819
12820(define_expand "suneq"
12821 [(set (match_operand:QI 0 "register_operand" "")
12822 (uneq:QI (reg:CC 17) (const_int 0)))]
12823 "TARGET_80387 || TARGET_SSE"
12824 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12825
12826(define_expand "sunge"
12827 [(set (match_operand:QI 0 "register_operand" "")
12828 (unge:QI (reg:CC 17) (const_int 0)))]
12829 "TARGET_80387 || TARGET_SSE"
12830 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12831
12832(define_expand "sungt"
12833 [(set (match_operand:QI 0 "register_operand" "")
12834 (ungt:QI (reg:CC 17) (const_int 0)))]
12835 "TARGET_80387 || TARGET_SSE"
12836 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12837
12838(define_expand "sunle"
12839 [(set (match_operand:QI 0 "register_operand" "")
12840 (unle:QI (reg:CC 17) (const_int 0)))]
12841 "TARGET_80387 || TARGET_SSE"
12842 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12843
12844(define_expand "sunlt"
12845 [(set (match_operand:QI 0 "register_operand" "")
12846 (unlt:QI (reg:CC 17) (const_int 0)))]
12847 "TARGET_80387 || TARGET_SSE"
12848 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12849
12850(define_expand "sltgt"
12851 [(set (match_operand:QI 0 "register_operand" "")
12852 (ltgt:QI (reg:CC 17) (const_int 0)))]
12853 "TARGET_80387 || TARGET_SSE"
12854 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12855
12856(define_insn "*setcc_1"
12857 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12858 (match_operator:QI 1 "ix86_comparison_operator"
12859 [(reg 17) (const_int 0)]))]
12860 ""
12861 "set%C1\t%0"
12862 [(set_attr "type" "setcc")
12863 (set_attr "mode" "QI")])
12864
12865(define_insn "setcc_2"
12866 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12867 (match_operator:QI 1 "ix86_comparison_operator"
12868 [(reg 17) (const_int 0)]))]
12869 ""
12870 "set%C1\t%0"
12871 [(set_attr "type" "setcc")
12872 (set_attr "mode" "QI")])
12873
12874;; In general it is not safe to assume too much about CCmode registers,
12875;; so simplify-rtx stops when it sees a second one. Under certain
12876;; conditions this is safe on x86, so help combine not create
12877;;
12878;; seta %al
12879;; testb %al, %al
12880;; sete %al
12881
12882(define_split
12883 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12884 (ne:QI (match_operator 1 "ix86_comparison_operator"
12885 [(reg 17) (const_int 0)])
12886 (const_int 0)))]
12887 ""
12888 [(set (match_dup 0) (match_dup 1))]
12889{
12890 PUT_MODE (operands[1], QImode);
12891})
12892
12893(define_split
12894 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12895 (ne:QI (match_operator 1 "ix86_comparison_operator"
12896 [(reg 17) (const_int 0)])
12897 (const_int 0)))]
12898 ""
12899 [(set (match_dup 0) (match_dup 1))]
12900{
12901 PUT_MODE (operands[1], QImode);
12902})
12903
12904(define_split
12905 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12906 (eq:QI (match_operator 1 "ix86_comparison_operator"
12907 [(reg 17) (const_int 0)])
12908 (const_int 0)))]
12909 ""
12910 [(set (match_dup 0) (match_dup 1))]
12911{
12912 rtx new_op1 = copy_rtx (operands[1]);
12913 operands[1] = new_op1;
12914 PUT_MODE (new_op1, QImode);
12915 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12916 GET_MODE (XEXP (new_op1, 0))));
12917
12918 /* Make sure that (a) the CCmode we have for the flags is strong
12919 enough for the reversed compare or (b) we have a valid FP compare. */
12920 if (! ix86_comparison_operator (new_op1, VOIDmode))
12921 FAIL;
12922})
12923
12924(define_split
12925 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12926 (eq:QI (match_operator 1 "ix86_comparison_operator"
12927 [(reg 17) (const_int 0)])
12928 (const_int 0)))]
12929 ""
12930 [(set (match_dup 0) (match_dup 1))]
12931{
12932 rtx new_op1 = copy_rtx (operands[1]);
12933 operands[1] = new_op1;
12934 PUT_MODE (new_op1, QImode);
12935 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12936 GET_MODE (XEXP (new_op1, 0))));
12937
12938 /* Make sure that (a) the CCmode we have for the flags is strong
12939 enough for the reversed compare or (b) we have a valid FP compare. */
12940 if (! ix86_comparison_operator (new_op1, VOIDmode))
12941 FAIL;
12942})
12943
12944;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12945;; subsequent logical operations are used to imitate conditional moves.
12946;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12947;; it directly. Further holding this value in pseudo register might bring
12948;; problem in implicit normalization in spill code.
12949;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12950;; instructions after reload by splitting the conditional move patterns.
12951
12952(define_insn "*sse_setccsf"
12953 [(set (match_operand:SF 0 "register_operand" "=x")
12954 (match_operator:SF 1 "sse_comparison_operator"
12955 [(match_operand:SF 2 "register_operand" "0")
12956 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12957 "TARGET_SSE && reload_completed"
12958 "cmp%D1ss\t{%3, %0|%0, %3}"
12959 [(set_attr "type" "ssecmp")
12960 (set_attr "mode" "SF")])
12961
12962(define_insn "*sse_setccdf"
12963 [(set (match_operand:DF 0 "register_operand" "=Y")
12964 (match_operator:DF 1 "sse_comparison_operator"
12965 [(match_operand:DF 2 "register_operand" "0")
12966 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12967 "TARGET_SSE2 && reload_completed"
12968 "cmp%D1sd\t{%3, %0|%0, %3}"
12969 [(set_attr "type" "ssecmp")
12970 (set_attr "mode" "DF")])
12971
12972;; Basic conditional jump instructions.
12973;; We ignore the overflow flag for signed branch instructions.
12974
12975;; For all bCOND expanders, also expand the compare or test insn that
12976;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12977
12978(define_expand "beq"
12979 [(set (pc)
12980 (if_then_else (match_dup 1)
12981 (label_ref (match_operand 0 "" ""))
12982 (pc)))]
12983 ""
12984 "ix86_expand_branch (EQ, operands[0]); DONE;")
12985
12986(define_expand "bne"
12987 [(set (pc)
12988 (if_then_else (match_dup 1)
12989 (label_ref (match_operand 0 "" ""))
12990 (pc)))]
12991 ""
12992 "ix86_expand_branch (NE, operands[0]); DONE;")
12993
12994(define_expand "bgt"
12995 [(set (pc)
12996 (if_then_else (match_dup 1)
12997 (label_ref (match_operand 0 "" ""))
12998 (pc)))]
12999 ""
13000 "ix86_expand_branch (GT, operands[0]); DONE;")
13001
13002(define_expand "bgtu"
13003 [(set (pc)
13004 (if_then_else (match_dup 1)
13005 (label_ref (match_operand 0 "" ""))
13006 (pc)))]
13007 ""
13008 "ix86_expand_branch (GTU, operands[0]); DONE;")
13009
13010(define_expand "blt"
13011 [(set (pc)
13012 (if_then_else (match_dup 1)
13013 (label_ref (match_operand 0 "" ""))
13014 (pc)))]
13015 ""
13016 "ix86_expand_branch (LT, operands[0]); DONE;")
13017
13018(define_expand "bltu"
13019 [(set (pc)
13020 (if_then_else (match_dup 1)
13021 (label_ref (match_operand 0 "" ""))
13022 (pc)))]
13023 ""
13024 "ix86_expand_branch (LTU, operands[0]); DONE;")
13025
13026(define_expand "bge"
13027 [(set (pc)
13028 (if_then_else (match_dup 1)
13029 (label_ref (match_operand 0 "" ""))
13030 (pc)))]
13031 ""
13032 "ix86_expand_branch (GE, operands[0]); DONE;")
13033
13034(define_expand "bgeu"
13035 [(set (pc)
13036 (if_then_else (match_dup 1)
13037 (label_ref (match_operand 0 "" ""))
13038 (pc)))]
13039 ""
13040 "ix86_expand_branch (GEU, operands[0]); DONE;")
13041
13042(define_expand "ble"
13043 [(set (pc)
13044 (if_then_else (match_dup 1)
13045 (label_ref (match_operand 0 "" ""))
13046 (pc)))]
13047 ""
13048 "ix86_expand_branch (LE, operands[0]); DONE;")
13049
13050(define_expand "bleu"
13051 [(set (pc)
13052 (if_then_else (match_dup 1)
13053 (label_ref (match_operand 0 "" ""))
13054 (pc)))]
13055 ""
13056 "ix86_expand_branch (LEU, operands[0]); DONE;")
13057
13058(define_expand "bunordered"
13059 [(set (pc)
13060 (if_then_else (match_dup 1)
13061 (label_ref (match_operand 0 "" ""))
13062 (pc)))]
13063 "TARGET_80387 || TARGET_SSE"
13064 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13065
13066(define_expand "bordered"
13067 [(set (pc)
13068 (if_then_else (match_dup 1)
13069 (label_ref (match_operand 0 "" ""))
13070 (pc)))]
13071 "TARGET_80387 || TARGET_SSE"
13072 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13073
13074(define_expand "buneq"
13075 [(set (pc)
13076 (if_then_else (match_dup 1)
13077 (label_ref (match_operand 0 "" ""))
13078 (pc)))]
13079 "TARGET_80387 || TARGET_SSE"
13080 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13081
13082(define_expand "bunge"
13083 [(set (pc)
13084 (if_then_else (match_dup 1)
13085 (label_ref (match_operand 0 "" ""))
13086 (pc)))]
13087 "TARGET_80387 || TARGET_SSE"
13088 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13089
13090(define_expand "bungt"
13091 [(set (pc)
13092 (if_then_else (match_dup 1)
13093 (label_ref (match_operand 0 "" ""))
13094 (pc)))]
13095 "TARGET_80387 || TARGET_SSE"
13096 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13097
13098(define_expand "bunle"
13099 [(set (pc)
13100 (if_then_else (match_dup 1)
13101 (label_ref (match_operand 0 "" ""))
13102 (pc)))]
13103 "TARGET_80387 || TARGET_SSE"
13104 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13105
13106(define_expand "bunlt"
13107 [(set (pc)
13108 (if_then_else (match_dup 1)
13109 (label_ref (match_operand 0 "" ""))
13110 (pc)))]
13111 "TARGET_80387 || TARGET_SSE"
13112 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13113
13114(define_expand "bltgt"
13115 [(set (pc)
13116 (if_then_else (match_dup 1)
13117 (label_ref (match_operand 0 "" ""))
13118 (pc)))]
13119 "TARGET_80387 || TARGET_SSE"
13120 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13121
13122(define_insn "*jcc_1"
13123 [(set (pc)
13124 (if_then_else (match_operator 1 "ix86_comparison_operator"
13125 [(reg 17) (const_int 0)])
13126 (label_ref (match_operand 0 "" ""))
13127 (pc)))]
13128 ""
13129 "%+j%C1\t%l0"
13130 [(set_attr "type" "ibr")
13131 (set_attr "modrm" "0")
13132 (set (attr "length")
13133 (if_then_else (and (ge (minus (match_dup 0) (pc))
13134 (const_int -126))
13135 (lt (minus (match_dup 0) (pc))
13136 (const_int 128)))
13137 (const_int 2)
13138 (const_int 6)))])
13139
13140(define_insn "*jcc_2"
13141 [(set (pc)
13142 (if_then_else (match_operator 1 "ix86_comparison_operator"
13143 [(reg 17) (const_int 0)])
13144 (pc)
13145 (label_ref (match_operand 0 "" ""))))]
13146 ""
13147 "%+j%c1\t%l0"
13148 [(set_attr "type" "ibr")
13149 (set_attr "modrm" "0")
13150 (set (attr "length")
13151 (if_then_else (and (ge (minus (match_dup 0) (pc))
13152 (const_int -126))
13153 (lt (minus (match_dup 0) (pc))
13154 (const_int 128)))
13155 (const_int 2)
13156 (const_int 6)))])
13157
13158;; In general it is not safe to assume too much about CCmode registers,
13159;; so simplify-rtx stops when it sees a second one. Under certain
13160;; conditions this is safe on x86, so help combine not create
13161;;
13162;; seta %al
13163;; testb %al, %al
13164;; je Lfoo
13165
13166(define_split
13167 [(set (pc)
13168 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13169 [(reg 17) (const_int 0)])
13170 (const_int 0))
13171 (label_ref (match_operand 1 "" ""))
13172 (pc)))]
13173 ""
13174 [(set (pc)
13175 (if_then_else (match_dup 0)
13176 (label_ref (match_dup 1))
13177 (pc)))]
13178{
13179 PUT_MODE (operands[0], VOIDmode);
13180})
13181
13182(define_split
13183 [(set (pc)
13184 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13185 [(reg 17) (const_int 0)])
13186 (const_int 0))
13187 (label_ref (match_operand 1 "" ""))
13188 (pc)))]
13189 ""
13190 [(set (pc)
13191 (if_then_else (match_dup 0)
13192 (label_ref (match_dup 1))
13193 (pc)))]
13194{
13195 rtx new_op0 = copy_rtx (operands[0]);
13196 operands[0] = new_op0;
13197 PUT_MODE (new_op0, VOIDmode);
13198 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13199 GET_MODE (XEXP (new_op0, 0))));
13200
13201 /* Make sure that (a) the CCmode we have for the flags is strong
13202 enough for the reversed compare or (b) we have a valid FP compare. */
13203 if (! ix86_comparison_operator (new_op0, VOIDmode))
13204 FAIL;
13205})
13206
13207;; Define combination compare-and-branch fp compare instructions to use
13208;; during early optimization. Splitting the operation apart early makes
13209;; for bad code when we want to reverse the operation.
13210
13211(define_insn "*fp_jcc_1"
13212 [(set (pc)
13213 (if_then_else (match_operator 0 "comparison_operator"
13214 [(match_operand 1 "register_operand" "f")
13215 (match_operand 2 "register_operand" "f")])
13216 (label_ref (match_operand 3 "" ""))
13217 (pc)))
13218 (clobber (reg:CCFP 18))
13219 (clobber (reg:CCFP 17))]
13220 "TARGET_CMOVE && TARGET_80387
13221 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13222 && FLOAT_MODE_P (GET_MODE (operands[1]))
13223 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13224 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13225 "#")
13226
13227(define_insn "*fp_jcc_1_sse"
13228 [(set (pc)
13229 (if_then_else (match_operator 0 "comparison_operator"
13230 [(match_operand 1 "register_operand" "f#x,x#f")
13231 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13232 (label_ref (match_operand 3 "" ""))
13233 (pc)))
13234 (clobber (reg:CCFP 18))
13235 (clobber (reg:CCFP 17))]
13236 "TARGET_80387
13237 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13238 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13239 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13240 "#")
13241
13242(define_insn "*fp_jcc_1_sse_only"
13243 [(set (pc)
13244 (if_then_else (match_operator 0 "comparison_operator"
13245 [(match_operand 1 "register_operand" "x")
13246 (match_operand 2 "nonimmediate_operand" "xm")])
13247 (label_ref (match_operand 3 "" ""))
13248 (pc)))
13249 (clobber (reg:CCFP 18))
13250 (clobber (reg:CCFP 17))]
13251 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13252 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13253 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13254 "#")
13255
13256(define_insn "*fp_jcc_2"
13257 [(set (pc)
13258 (if_then_else (match_operator 0 "comparison_operator"
13259 [(match_operand 1 "register_operand" "f")
13260 (match_operand 2 "register_operand" "f")])
13261 (pc)
13262 (label_ref (match_operand 3 "" ""))))
13263 (clobber (reg:CCFP 18))
13264 (clobber (reg:CCFP 17))]
13265 "TARGET_CMOVE && TARGET_80387
13266 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13267 && FLOAT_MODE_P (GET_MODE (operands[1]))
13268 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13269 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13270 "#")
13271
13272(define_insn "*fp_jcc_2_sse"
13273 [(set (pc)
13274 (if_then_else (match_operator 0 "comparison_operator"
13275 [(match_operand 1 "register_operand" "f#x,x#f")
13276 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13277 (pc)
13278 (label_ref (match_operand 3 "" ""))))
13279 (clobber (reg:CCFP 18))
13280 (clobber (reg:CCFP 17))]
13281 "TARGET_80387
13282 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13283 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13284 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13285 "#")
13286
13287(define_insn "*fp_jcc_2_sse_only"
13288 [(set (pc)
13289 (if_then_else (match_operator 0 "comparison_operator"
13290 [(match_operand 1 "register_operand" "x")
13291 (match_operand 2 "nonimmediate_operand" "xm")])
13292 (pc)
13293 (label_ref (match_operand 3 "" ""))))
13294 (clobber (reg:CCFP 18))
13295 (clobber (reg:CCFP 17))]
13296 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13297 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13298 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13299 "#")
13300
13301(define_insn "*fp_jcc_3"
13302 [(set (pc)
13303 (if_then_else (match_operator 0 "comparison_operator"
13304 [(match_operand 1 "register_operand" "f")
13305 (match_operand 2 "nonimmediate_operand" "fm")])
13306 (label_ref (match_operand 3 "" ""))
13307 (pc)))
13308 (clobber (reg:CCFP 18))
13309 (clobber (reg:CCFP 17))
13310 (clobber (match_scratch:HI 4 "=a"))]
13311 "TARGET_80387
13312 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13313 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13314 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13315 && SELECT_CC_MODE (GET_CODE (operands[0]),
13316 operands[1], operands[2]) == CCFPmode
13317 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13318 "#")
13319
13320(define_insn "*fp_jcc_4"
13321 [(set (pc)
13322 (if_then_else (match_operator 0 "comparison_operator"
13323 [(match_operand 1 "register_operand" "f")
13324 (match_operand 2 "nonimmediate_operand" "fm")])
13325 (pc)
13326 (label_ref (match_operand 3 "" ""))))
13327 (clobber (reg:CCFP 18))
13328 (clobber (reg:CCFP 17))
13329 (clobber (match_scratch:HI 4 "=a"))]
13330 "TARGET_80387
13331 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13332 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13333 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13334 && SELECT_CC_MODE (GET_CODE (operands[0]),
13335 operands[1], operands[2]) == CCFPmode
13336 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13337 "#")
13338
13339(define_insn "*fp_jcc_5"
13340 [(set (pc)
13341 (if_then_else (match_operator 0 "comparison_operator"
13342 [(match_operand 1 "register_operand" "f")
13343 (match_operand 2 "register_operand" "f")])
13344 (label_ref (match_operand 3 "" ""))
13345 (pc)))
13346 (clobber (reg:CCFP 18))
13347 (clobber (reg:CCFP 17))
13348 (clobber (match_scratch:HI 4 "=a"))]
13349 "TARGET_80387
13350 && FLOAT_MODE_P (GET_MODE (operands[1]))
13351 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13352 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13353 "#")
13354
13355(define_insn "*fp_jcc_6"
13356 [(set (pc)
13357 (if_then_else (match_operator 0 "comparison_operator"
13358 [(match_operand 1 "register_operand" "f")
13359 (match_operand 2 "register_operand" "f")])
13360 (pc)
13361 (label_ref (match_operand 3 "" ""))))
13362 (clobber (reg:CCFP 18))
13363 (clobber (reg:CCFP 17))
13364 (clobber (match_scratch:HI 4 "=a"))]
13365 "TARGET_80387
13366 && FLOAT_MODE_P (GET_MODE (operands[1]))
13367 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13368 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13369 "#")
13370
13371(define_split
13372 [(set (pc)
13373 (if_then_else (match_operator 0 "comparison_operator"
13374 [(match_operand 1 "register_operand" "")
13375 (match_operand 2 "nonimmediate_operand" "")])
13376 (match_operand 3 "" "")
13377 (match_operand 4 "" "")))
13378 (clobber (reg:CCFP 18))
13379 (clobber (reg:CCFP 17))]
13380 "reload_completed"
13381 [(const_int 0)]
13382{
13383 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13384 operands[3], operands[4], NULL_RTX);
13385 DONE;
13386})
13387
13388(define_split
13389 [(set (pc)
13390 (if_then_else (match_operator 0 "comparison_operator"
13391 [(match_operand 1 "register_operand" "")
13392 (match_operand 2 "nonimmediate_operand" "")])
13393 (match_operand 3 "" "")
13394 (match_operand 4 "" "")))
13395 (clobber (reg:CCFP 18))
13396 (clobber (reg:CCFP 17))
13397 (clobber (match_scratch:HI 5 "=a"))]
13398 "reload_completed"
13399 [(set (pc)
13400 (if_then_else (match_dup 6)
13401 (match_dup 3)
13402 (match_dup 4)))]
13403{
13404 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13405 operands[3], operands[4], operands[5]);
13406 DONE;
13407})
13408
13409;; Unconditional and other jump instructions
13410
13411(define_insn "jump"
13412 [(set (pc)
13413 (label_ref (match_operand 0 "" "")))]
13414 ""
13415 "jmp\t%l0"
13416 [(set_attr "type" "ibr")
13417 (set (attr "length")
13418 (if_then_else (and (ge (minus (match_dup 0) (pc))
13419 (const_int -126))
13420 (lt (minus (match_dup 0) (pc))
13421 (const_int 128)))
13422 (const_int 2)
13423 (const_int 5)))
13424 (set_attr "modrm" "0")])
13425
13426(define_expand "indirect_jump"
13427 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13428 ""
13429 "")
13430
13431(define_insn "*indirect_jump"
13432 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13433 "!TARGET_64BIT"
13434 "jmp\t%A0"
13435 [(set_attr "type" "ibr")
13436 (set_attr "length_immediate" "0")])
13437
13438(define_insn "*indirect_jump_rtx64"
13439 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13440 "TARGET_64BIT"
13441 "jmp\t%A0"
13442 [(set_attr "type" "ibr")
13443 (set_attr "length_immediate" "0")])
13444
13445(define_expand "tablejump"
13446 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13447 (use (label_ref (match_operand 1 "" "")))])]
13448 ""
13449{
13450 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13451 relative. Convert the relative address to an absolute address. */
13452 if (flag_pic)
13453 {
13454 rtx op0, op1;
13455 enum rtx_code code;
13456
13457 if (TARGET_64BIT)
13458 {
13459 code = PLUS;
13460 op0 = operands[0];
13461 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13462 }
13463 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13464 {
13465 code = PLUS;
13466 op0 = operands[0];
13467 op1 = pic_offset_table_rtx;
13468 }
13469 else
13470 {
13471 code = MINUS;
13472 op0 = pic_offset_table_rtx;
13473 op1 = operands[0];
13474 }
13475
13476 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13477 OPTAB_DIRECT);
13478 }
13479})
13480
13481(define_insn "*tablejump_1"
13482 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13483 (use (label_ref (match_operand 1 "" "")))]
13484 "!TARGET_64BIT"
13485 "jmp\t%A0"
13486 [(set_attr "type" "ibr")
13487 (set_attr "length_immediate" "0")])
13488
13489(define_insn "*tablejump_1_rtx64"
13490 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13491 (use (label_ref (match_operand 1 "" "")))]
13492 "TARGET_64BIT"
13493 "jmp\t%A0"
13494 [(set_attr "type" "ibr")
13495 (set_attr "length_immediate" "0")])
13496
13497;; Loop instruction
13498;;
13499;; This is all complicated by the fact that since this is a jump insn
13500;; we must handle our own reloads.
13501
13502(define_expand "doloop_end"
13503 [(use (match_operand 0 "" "")) ; loop pseudo
13504 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13505 (use (match_operand 2 "" "")) ; max iterations
13506 (use (match_operand 3 "" "")) ; loop level
13507 (use (match_operand 4 "" ""))] ; label
13508 "!TARGET_64BIT && TARGET_USE_LOOP"
13509 "
13510{
13511 /* Only use cloop on innermost loops. */
13512 if (INTVAL (operands[3]) > 1)
13513 FAIL;
13514 if (GET_MODE (operands[0]) != SImode)
13515 FAIL;
13516 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13517 operands[0]));
13518 DONE;
13519}")
13520
13521(define_insn "doloop_end_internal"
13522 [(set (pc)
13523 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13524 (const_int 1))
13525 (label_ref (match_operand 0 "" ""))
13526 (pc)))
13527 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13528 (plus:SI (match_dup 1)
13529 (const_int -1)))
13530 (clobber (match_scratch:SI 3 "=X,X,r"))
13531 (clobber (reg:CC 17))]
13532 "!TARGET_64BIT && TARGET_USE_LOOP"
13533{
13534 if (which_alternative != 0)
13535 return "#";
13536 if (get_attr_length (insn) == 2)
13537 return "%+loop\t%l0";
13538 else
13539 return "dec{l}\t%1\;%+jne\t%l0";
13540}
13541 [(set_attr "ppro_uops" "many")
13542 (set (attr "length")
13543 (if_then_else (and (eq_attr "alternative" "0")
13544 (and (ge (minus (match_dup 0) (pc))
13545 (const_int -126))
13546 (lt (minus (match_dup 0) (pc))
13547 (const_int 128))))
13548 (const_int 2)
13549 (const_int 16)))
13550 ;; We don't know the type before shorten branches. Optimistically expect
13551 ;; the loop instruction to match.
13552 (set (attr "type") (const_string "ibr"))])
13553
13554(define_split
13555 [(set (pc)
13556 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13557 (const_int 1))
13558 (match_operand 0 "" "")
13559 (pc)))
13560 (set (match_dup 1)
13561 (plus:SI (match_dup 1)
13562 (const_int -1)))
13563 (clobber (match_scratch:SI 2 ""))
13564 (clobber (reg:CC 17))]
13565 "!TARGET_64BIT && TARGET_USE_LOOP
13566 && reload_completed
13567 && REGNO (operands[1]) != 2"
13568 [(parallel [(set (reg:CCZ 17)
13569 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13570 (const_int 0)))
13571 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13572 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13573 (match_dup 0)
13574 (pc)))]
13575 "")
13576
13577(define_split
13578 [(set (pc)
13579 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13580 (const_int 1))
13581 (match_operand 0 "" "")
13582 (pc)))
13583 (set (match_operand:SI 2 "nonimmediate_operand" "")
13584 (plus:SI (match_dup 1)
13585 (const_int -1)))
13586 (clobber (match_scratch:SI 3 ""))
13587 (clobber (reg:CC 17))]
13588 "!TARGET_64BIT && TARGET_USE_LOOP
13589 && reload_completed
13590 && (! REG_P (operands[2])
13591 || ! rtx_equal_p (operands[1], operands[2]))"
13592 [(set (match_dup 3) (match_dup 1))
13593 (parallel [(set (reg:CCZ 17)
13594 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13595 (const_int 0)))
13596 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13597 (set (match_dup 2) (match_dup 3))
13598 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13599 (match_dup 0)
13600 (pc)))]
13601 "")
13602
13603;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13604
13605(define_peephole2
13606 [(set (reg 17) (match_operand 0 "" ""))
13607 (set (match_operand:QI 1 "register_operand" "")
13608 (match_operator:QI 2 "ix86_comparison_operator"
13609 [(reg 17) (const_int 0)]))
13610 (set (match_operand 3 "q_regs_operand" "")
13611 (zero_extend (match_dup 1)))]
13612 "(peep2_reg_dead_p (3, operands[1])
13613 || operands_match_p (operands[1], operands[3]))
13614 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13615 [(set (match_dup 4) (match_dup 0))
13616 (set (strict_low_part (match_dup 5))
13617 (match_dup 2))]
13618{
13619 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13620 operands[5] = gen_lowpart (QImode, operands[3]);
13621 ix86_expand_clear (operands[3]);
13622})
13623
13624;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13625
13626(define_peephole2
13627 [(set (reg 17) (match_operand 0 "" ""))
13628 (set (match_operand:QI 1 "register_operand" "")
13629 (match_operator:QI 2 "ix86_comparison_operator"
13630 [(reg 17) (const_int 0)]))
13631 (parallel [(set (match_operand 3 "q_regs_operand" "")
13632 (zero_extend (match_dup 1)))
13633 (clobber (reg:CC 17))])]
13634 "(peep2_reg_dead_p (3, operands[1])
13635 || operands_match_p (operands[1], operands[3]))
13636 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13637 [(set (match_dup 4) (match_dup 0))
13638 (set (strict_low_part (match_dup 5))
13639 (match_dup 2))]
13640{
13641 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13642 operands[5] = gen_lowpart (QImode, operands[3]);
13643 ix86_expand_clear (operands[3]);
13644})
13645
13646;; Call instructions.
13647
13648;; The predicates normally associated with named expanders are not properly
13649;; checked for calls. This is a bug in the generic code, but it isn't that
13650;; easy to fix. Ignore it for now and be prepared to fix things up.
13651
13652;; Call subroutine returning no value.
13653
13654(define_expand "call_pop"
13655 [(parallel [(call (match_operand:QI 0 "" "")
13656 (match_operand:SI 1 "" ""))
13657 (set (reg:SI 7)
13658 (plus:SI (reg:SI 7)
13659 (match_operand:SI 3 "" "")))])]
13660 "!TARGET_64BIT"
13661{
13662 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13663 DONE;
13664})
13665
13666(define_insn "*call_pop_0"
13667 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13668 (match_operand:SI 1 "" ""))
13669 (set (reg:SI 7) (plus:SI (reg:SI 7)
13670 (match_operand:SI 2 "immediate_operand" "")))]
13671 "!TARGET_64BIT"
13672{
13673 if (SIBLING_CALL_P (insn))
13674 return "jmp\t%P0";
13675 else
13676 return "call\t%P0";
13677}
13678 [(set_attr "type" "call")])
13679
13680(define_insn "*call_pop_1"
13681 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13682 (match_operand:SI 1 "" ""))
13683 (set (reg:SI 7) (plus:SI (reg:SI 7)
13684 (match_operand:SI 2 "immediate_operand" "i")))]
13685 "!TARGET_64BIT"
13686{
13687 if (constant_call_address_operand (operands[0], Pmode))
13688 {
13689 if (SIBLING_CALL_P (insn))
13690 return "jmp\t%P0";
13691 else
13692 return "call\t%P0";
13693 }
13694 if (SIBLING_CALL_P (insn))
13695 return "jmp\t%A0";
13696 else
13697 return "call\t%A0";
13698}
13699 [(set_attr "type" "call")])
13700
13701(define_expand "call"
13702 [(call (match_operand:QI 0 "" "")
13703 (match_operand 1 "" ""))
13704 (use (match_operand 2 "" ""))]
13705 ""
13706{
13707 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13708 DONE;
13709})
13710
13711(define_expand "sibcall"
13712 [(call (match_operand:QI 0 "" "")
13713 (match_operand 1 "" ""))
13714 (use (match_operand 2 "" ""))]
13715 ""
13716{
13717 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13718 DONE;
13719})
13720
13721(define_insn "*call_0"
13722 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13723 (match_operand 1 "" ""))]
13724 ""
13725{
13726 if (SIBLING_CALL_P (insn))
13727 return "jmp\t%P0";
13728 else
13729 return "call\t%P0";
13730}
13731 [(set_attr "type" "call")])
13732
13733(define_insn "*call_1"
13734 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13735 (match_operand 1 "" ""))]
13736 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13737{
13738 if (constant_call_address_operand (operands[0], QImode))
13739 return "call\t%P0";
13740 return "call\t%A0";
13741}
13742 [(set_attr "type" "call")])
13743
13744(define_insn "*sibcall_1"
13745 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13746 (match_operand 1 "" ""))]
13747 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13748{
13749 if (constant_call_address_operand (operands[0], QImode))
13750 return "jmp\t%P0";
13751 return "jmp\t%A0";
13752}
13753 [(set_attr "type" "call")])
13754
13755(define_insn "*call_1_rex64"
13756 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13757 (match_operand 1 "" ""))]
13758 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13759{
13760 if (constant_call_address_operand (operands[0], QImode))
13761 return "call\t%P0";
13762 return "call\t%A0";
13763}
13764 [(set_attr "type" "call")])
13765
13766(define_insn "*sibcall_1_rex64"
13767 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13768 (match_operand 1 "" ""))]
13769 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13770 "jmp\t%P0"
13771 [(set_attr "type" "call")])
13772
13773(define_insn "*sibcall_1_rex64_v"
13774 [(call (mem:QI (reg:DI 40))
13775 (match_operand 0 "" ""))]
13776 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13777 "jmp\t*%%r11"
13778 [(set_attr "type" "call")])
13779
13780
13781;; Call subroutine, returning value in operand 0
13782
13783(define_expand "call_value_pop"
13784 [(parallel [(set (match_operand 0 "" "")
13785 (call (match_operand:QI 1 "" "")
13786 (match_operand:SI 2 "" "")))
13787 (set (reg:SI 7)
13788 (plus:SI (reg:SI 7)
13789 (match_operand:SI 4 "" "")))])]
13790 "!TARGET_64BIT"
13791{
13792 ix86_expand_call (operands[0], operands[1], operands[2],
13793 operands[3], operands[4], 0);
13794 DONE;
13795})
13796
13797(define_expand "call_value"
13798 [(set (match_operand 0 "" "")
13799 (call (match_operand:QI 1 "" "")
13800 (match_operand:SI 2 "" "")))
13801 (use (match_operand:SI 3 "" ""))]
13802 ;; Operand 2 not used on the i386.
13803 ""
13804{
13805 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13806 DONE;
13807})
13808
13809(define_expand "sibcall_value"
13810 [(set (match_operand 0 "" "")
13811 (call (match_operand:QI 1 "" "")
13812 (match_operand:SI 2 "" "")))
13813 (use (match_operand:SI 3 "" ""))]
13814 ;; Operand 2 not used on the i386.
13815 ""
13816{
13817 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13818 DONE;
13819})
13820
13821;; Call subroutine returning any type.
13822
13823(define_expand "untyped_call"
13824 [(parallel [(call (match_operand 0 "" "")
13825 (const_int 0))
13826 (match_operand 1 "" "")
13827 (match_operand 2 "" "")])]
13828 ""
13829{
13830 int i;
13831
13832 /* In order to give reg-stack an easier job in validating two
13833 coprocessor registers as containing a possible return value,
13834 simply pretend the untyped call returns a complex long double
13835 value. */
13836
13837 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13838 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13839 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13840 NULL, 0);
13841
13842 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13843 {
13844 rtx set = XVECEXP (operands[2], 0, i);
13845 emit_move_insn (SET_DEST (set), SET_SRC (set));
13846 }
13847
13848 /* The optimizer does not know that the call sets the function value
13849 registers we stored in the result block. We avoid problems by
13850 claiming that all hard registers are used and clobbered at this
13851 point. */
13852 emit_insn (gen_blockage (const0_rtx));
13853
13854 DONE;
13855})
13856
13857;; Prologue and epilogue instructions
13858
13859;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13860;; all of memory. This blocks insns from being moved across this point.
13861
13862(define_insn "blockage"
13863 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13864 ""
13865 ""
13866 [(set_attr "length" "0")])
13867
13868;; Insn emitted into the body of a function to return from a function.
13869;; This is only done if the function's epilogue is known to be simple.
13870;; See comments for ix86_can_use_return_insn_p in i386.c.
13871
13872(define_expand "return"
13873 [(return)]
13874 "ix86_can_use_return_insn_p ()"
13875{
13876 if (current_function_pops_args)
13877 {
13878 rtx popc = GEN_INT (current_function_pops_args);
13879 emit_jump_insn (gen_return_pop_internal (popc));
13880 DONE;
13881 }
13882})
13883
13884(define_insn "return_internal"
13885 [(return)]
13886 "reload_completed"
13887 "ret"
13888 [(set_attr "length" "1")
13889 (set_attr "length_immediate" "0")
13890 (set_attr "modrm" "0")])
13891
13892;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13893;; instruction Athlon and K8 have.
13894
13895(define_insn "return_internal_long"
13896 [(return)
13897 (unspec [(const_int 0)] UNSPEC_REP)]
13898 "reload_completed"
13899 "rep {;} ret"
13900 [(set_attr "length" "1")
13901 (set_attr "length_immediate" "0")
13902 (set_attr "prefix_rep" "1")
13903 (set_attr "modrm" "0")])
13904
13905(define_insn "return_pop_internal"
13906 [(return)
13907 (use (match_operand:SI 0 "const_int_operand" ""))]
13908 "reload_completed"
13909 "ret\t%0"
13910 [(set_attr "length" "3")
13911 (set_attr "length_immediate" "2")
13912 (set_attr "modrm" "0")])
13913
13914(define_insn "return_indirect_internal"
13915 [(return)
13916 (use (match_operand:SI 0 "register_operand" "r"))]
13917 "reload_completed"
13918 "jmp\t%A0"
13919 [(set_attr "type" "ibr")
13920 (set_attr "length_immediate" "0")])
13921
13922(define_insn "nop"
13923 [(const_int 0)]
13924 ""
13925 "nop"
13926 [(set_attr "length" "1")
13927 (set_attr "length_immediate" "0")
13928 (set_attr "modrm" "0")
13929 (set_attr "ppro_uops" "one")])
13930
13931;; Align to 16-byte boundary, max skip in op0. Used to avoid
13932;; branch prediction penalty for the third jump in a 16-byte
13933;; block on K8.
13934
13935(define_insn "align"
13936 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13937 ""
13938{
13939#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13940 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13941#else
13942 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13943 The align insn is used to avoid 3 jump instructions in the row to improve
13944 branch prediction and the benefits hardly outweight the cost of extra 8
13945 nops on the average inserted by full alignment pseudo operation. */
13946#endif
13947 return "";
13948}
13949 [(set_attr "length" "16")])
13950
13951(define_expand "prologue"
13952 [(const_int 1)]
13953 ""
13954 "ix86_expand_prologue (); DONE;")
13955
13956(define_insn "set_got"
13957 [(set (match_operand:SI 0 "register_operand" "=r")
13958 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13959 (clobber (reg:CC 17))]
13960 "!TARGET_64BIT"
13961 { return output_set_got (operands[0]); }
13962 [(set_attr "type" "multi")
13963 (set_attr "length" "12")])
13964
13965(define_expand "epilogue"
13966 [(const_int 1)]
13967 ""
13968 "ix86_expand_epilogue (1); DONE;")
13969
13970(define_expand "sibcall_epilogue"
13971 [(const_int 1)]
13972 ""
13973 "ix86_expand_epilogue (0); DONE;")
13974
13975(define_expand "eh_return"
13976 [(use (match_operand 0 "register_operand" ""))]
13977 ""
13978{
13979 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13980
13981 /* Tricky bit: we write the address of the handler to which we will
13982 be returning into someone else's stack frame, one word below the
13983 stack address we wish to restore. */
13984 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13985 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13986 tmp = gen_rtx_MEM (Pmode, tmp);
13987 emit_move_insn (tmp, ra);
13988
13989 if (Pmode == SImode)
13990 emit_insn (gen_eh_return_si (sa));
13991 else
13992 emit_insn (gen_eh_return_di (sa));
13993 emit_barrier ();
13994 DONE;
13995})
13996
13997(define_insn_and_split "eh_return_si"
13998 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13999 UNSPECV_EH_RETURN)]
14000 "!TARGET_64BIT"
14001 "#"
14002 "reload_completed"
14003 [(const_int 1)]
14004 "ix86_expand_epilogue (2); DONE;")
14005
14006(define_insn_and_split "eh_return_di"
14007 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14008 UNSPECV_EH_RETURN)]
14009 "TARGET_64BIT"
14010 "#"
14011 "reload_completed"
14012 [(const_int 1)]
14013 "ix86_expand_epilogue (2); DONE;")
14014
14015(define_insn "leave"
14016 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14017 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14018 (clobber (mem:BLK (scratch)))]
14019 "!TARGET_64BIT"
14020 "leave"
14021 [(set_attr "type" "leave")])
14022
14023(define_insn "leave_rex64"
14024 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14025 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14026 (clobber (mem:BLK (scratch)))]
14027 "TARGET_64BIT"
14028 "leave"
14029 [(set_attr "type" "leave")])
14030
14031(define_expand "ffssi2"
14032 [(parallel
14033 [(set (match_operand:SI 0 "register_operand" "")
14034 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14035 (clobber (match_scratch:SI 2 ""))
14036 (clobber (reg:CC 17))])]
14037 ""
14038 "")
14039
14040(define_insn_and_split "*ffs_cmove"
14041 [(set (match_operand:SI 0 "register_operand" "=r")
14042 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14043 (clobber (match_scratch:SI 2 "=&r"))
14044 (clobber (reg:CC 17))]
14045 "TARGET_CMOVE"
14046 "#"
14047 "&& reload_completed"
14048 [(set (match_dup 2) (const_int -1))
14049 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14050 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14051 (set (match_dup 0) (if_then_else:SI
14052 (eq (reg:CCZ 17) (const_int 0))
14053 (match_dup 2)
14054 (match_dup 0)))
14055 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14056 (clobber (reg:CC 17))])]
14057 "")
14058
14059(define_insn_and_split "*ffs_no_cmove"
14060 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14061 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14062 (clobber (match_scratch:SI 2 "=&q"))
14063 (clobber (reg:CC 17))]
14064 ""
14065 "#"
14066 "reload_completed"
14067 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14068 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14069 (set (strict_low_part (match_dup 3))
14070 (eq:QI (reg:CCZ 17) (const_int 0)))
14071 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14072 (clobber (reg:CC 17))])
14073 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14074 (clobber (reg:CC 17))])
14075 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14076 (clobber (reg:CC 17))])]
14077{
14078 operands[3] = gen_lowpart (QImode, operands[2]);
14079 ix86_expand_clear (operands[2]);
14080})
14081
14082(define_insn "*ffssi_1"
14083 [(set (reg:CCZ 17)
14084 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14085 (const_int 0)))
14086 (set (match_operand:SI 0 "register_operand" "=r")
14087 (ctz:SI (match_dup 1)))]
14088 ""
14089 "bsf{l}\t{%1, %0|%0, %1}"
14090 [(set_attr "prefix_0f" "1")
14091 (set_attr "ppro_uops" "few")])
14092
14093(define_insn "ctzsi2"
14094 [(set (match_operand:SI 0 "register_operand" "=r")
14095 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14096 (clobber (reg:CC 17))]
14097 ""
14098 "bsf{l}\t{%1, %0|%0, %1}"
14099 [(set_attr "prefix_0f" "1")
14100 (set_attr "ppro_uops" "few")])
14101
14102(define_expand "clzsi2"
14103 [(parallel
14104 [(set (match_operand:SI 0 "register_operand" "")
14105 (minus:SI (const_int 31)
14106 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14107 (clobber (reg:CC 17))])
14108 (parallel
14109 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14110 (clobber (reg:CC 17))])]
14111 ""
14112 "")
14113
14114(define_insn "*bsr"
14115 [(set (match_operand:SI 0 "register_operand" "=r")
14116 (minus:SI (const_int 31)
14117 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14118 (clobber (reg:CC 17))]
14119 ""
14120 "bsr{l}\t{%1, %0|%0, %1}"
14121 [(set_attr "prefix_0f" "1")
14122 (set_attr "ppro_uops" "few")])
14123
14124;; Thread-local storage patterns for ELF.
14125;;
14126;; Note that these code sequences must appear exactly as shown
14127;; in order to allow linker relaxation.
14128
14129(define_insn "*tls_global_dynamic_32_gnu"
14130 [(set (match_operand:SI 0 "register_operand" "=a")
14131 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14132 (match_operand:SI 2 "tls_symbolic_operand" "")
14133 (match_operand:SI 3 "call_insn_operand" "")]
14134 UNSPEC_TLS_GD))
14135 (clobber (match_scratch:SI 4 "=d"))
14136 (clobber (match_scratch:SI 5 "=c"))
14137 (clobber (reg:CC 17))]
14138 "!TARGET_64BIT && TARGET_GNU_TLS"
14139 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14140 [(set_attr "type" "multi")
14141 (set_attr "length" "12")])
14142
14143(define_insn "*tls_global_dynamic_32_sun"
14144 [(set (match_operand:SI 0 "register_operand" "=a")
14145 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14146 (match_operand:SI 2 "tls_symbolic_operand" "")
14147 (match_operand:SI 3 "call_insn_operand" "")]
14148 UNSPEC_TLS_GD))
14149 (clobber (match_scratch:SI 4 "=d"))
14150 (clobber (match_scratch:SI 5 "=c"))
14151 (clobber (reg:CC 17))]
14152 "!TARGET_64BIT && TARGET_SUN_TLS"
14153 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14154 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14155 [(set_attr "type" "multi")
14156 (set_attr "length" "14")])
14157
14158(define_expand "tls_global_dynamic_32"
14159 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14160 (unspec:SI
14161 [(match_dup 2)
14162 (match_operand:SI 1 "tls_symbolic_operand" "")
14163 (match_dup 3)]
14164 UNSPEC_TLS_GD))
14165 (clobber (match_scratch:SI 4 ""))
14166 (clobber (match_scratch:SI 5 ""))
14167 (clobber (reg:CC 17))])]
14168 ""
14169{
14170 if (flag_pic)
14171 operands[2] = pic_offset_table_rtx;
14172 else
14173 {
14174 operands[2] = gen_reg_rtx (Pmode);
14175 emit_insn (gen_set_got (operands[2]));
14176 }
14177 operands[3] = ix86_tls_get_addr ();
14178})
14179
14180(define_insn "*tls_global_dynamic_64"
14181 [(set (match_operand:DI 0 "register_operand" "=a")
14182 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14183 (match_operand:DI 3 "" "")))
14184 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14185 UNSPEC_TLS_GD)]
14186 "TARGET_64BIT"
14187 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14188 [(set_attr "type" "multi")
14189 (set_attr "length" "16")])
14190
14191(define_expand "tls_global_dynamic_64"
14192 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14193 (call (mem:QI (match_dup 2)) (const_int 0)))
14194 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14195 UNSPEC_TLS_GD)])]
14196 ""
14197{
14198 operands[2] = ix86_tls_get_addr ();
14199})
14200
14201(define_insn "*tls_local_dynamic_base_32_gnu"
14202 [(set (match_operand:SI 0 "register_operand" "=a")
14203 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14204 (match_operand:SI 2 "call_insn_operand" "")]
14205 UNSPEC_TLS_LD_BASE))
14206 (clobber (match_scratch:SI 3 "=d"))
14207 (clobber (match_scratch:SI 4 "=c"))
14208 (clobber (reg:CC 17))]
14209 "!TARGET_64BIT && TARGET_GNU_TLS"
14210 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14211 [(set_attr "type" "multi")
14212 (set_attr "length" "11")])
14213
14214(define_insn "*tls_local_dynamic_base_32_sun"
14215 [(set (match_operand:SI 0 "register_operand" "=a")
14216 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14217 (match_operand:SI 2 "call_insn_operand" "")]
14218 UNSPEC_TLS_LD_BASE))
14219 (clobber (match_scratch:SI 3 "=d"))
14220 (clobber (match_scratch:SI 4 "=c"))
14221 (clobber (reg:CC 17))]
14222 "!TARGET_64BIT && TARGET_SUN_TLS"
14223 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14224 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14225 [(set_attr "type" "multi")
14226 (set_attr "length" "13")])
14227
14228(define_expand "tls_local_dynamic_base_32"
14229 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14230 (unspec:SI [(match_dup 1) (match_dup 2)]
14231 UNSPEC_TLS_LD_BASE))
14232 (clobber (match_scratch:SI 3 ""))
14233 (clobber (match_scratch:SI 4 ""))
14234 (clobber (reg:CC 17))])]
14235 ""
14236{
14237 if (flag_pic)
14238 operands[1] = pic_offset_table_rtx;
14239 else
14240 {
14241 operands[1] = gen_reg_rtx (Pmode);
14242 emit_insn (gen_set_got (operands[1]));
14243 }
14244 operands[2] = ix86_tls_get_addr ();
14245})
14246
14247(define_insn "*tls_local_dynamic_base_64"
14248 [(set (match_operand:DI 0 "register_operand" "=a")
14249 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14250 (match_operand:DI 2 "" "")))
14251 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14252 "TARGET_64BIT"
14253 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14254 [(set_attr "type" "multi")
14255 (set_attr "length" "12")])
14256
14257(define_expand "tls_local_dynamic_base_64"
14258 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14259 (call (mem:QI (match_dup 1)) (const_int 0)))
14260 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14261 ""
14262{
14263 operands[1] = ix86_tls_get_addr ();
14264})
14265
14266;; Local dynamic of a single variable is a lose. Show combine how
14267;; to convert that back to global dynamic.
14268
14269(define_insn_and_split "*tls_local_dynamic_32_once"
14270 [(set (match_operand:SI 0 "register_operand" "=a")
14271 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14272 (match_operand:SI 2 "call_insn_operand" "")]
14273 UNSPEC_TLS_LD_BASE)
14274 (const:SI (unspec:SI
14275 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14276 UNSPEC_DTPOFF))))
14277 (clobber (match_scratch:SI 4 "=d"))
14278 (clobber (match_scratch:SI 5 "=c"))
14279 (clobber (reg:CC 17))]
14280 ""
14281 "#"
14282 ""
14283 [(parallel [(set (match_dup 0)
14284 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14285 UNSPEC_TLS_GD))
14286 (clobber (match_dup 4))
14287 (clobber (match_dup 5))
14288 (clobber (reg:CC 17))])]
14289 "")
14290
14291;; Load and add the thread base pointer from %gs:0.
14292
14293(define_insn "*load_tp_si"
14294 [(set (match_operand:SI 0 "register_operand" "=r")
14295 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14296 "!TARGET_64BIT"
14297 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14298 [(set_attr "type" "imov")
14299 (set_attr "modrm" "0")
14300 (set_attr "length" "7")
14301 (set_attr "memory" "load")
14302 (set_attr "imm_disp" "false")])
14303
14304(define_insn "*add_tp_si"
14305 [(set (match_operand:SI 0 "register_operand" "=r")
14306 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14307 (match_operand:SI 1 "register_operand" "0")))
14308 (clobber (reg:CC 17))]
14309 "!TARGET_64BIT"
14310 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14311 [(set_attr "type" "alu")
14312 (set_attr "modrm" "0")
14313 (set_attr "length" "7")
14314 (set_attr "memory" "load")
14315 (set_attr "imm_disp" "false")])
14316
14317(define_insn "*load_tp_di"
14318 [(set (match_operand:DI 0 "register_operand" "=r")
14319 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14320 "TARGET_64BIT"
14321 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14322 [(set_attr "type" "imov")
14323 (set_attr "modrm" "0")
14324 (set_attr "length" "7")
14325 (set_attr "memory" "load")
14326 (set_attr "imm_disp" "false")])
14327
14328(define_insn "*add_tp_di"
14329 [(set (match_operand:DI 0 "register_operand" "=r")
14330 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14331 (match_operand:DI 1 "register_operand" "0")))
14332 (clobber (reg:CC 17))]
14333 "TARGET_64BIT"
14334 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14335 [(set_attr "type" "alu")
14336 (set_attr "modrm" "0")
14337 (set_attr "length" "7")
14338 (set_attr "memory" "load")
14339 (set_attr "imm_disp" "false")])
14340
14341;; These patterns match the binary 387 instructions for addM3, subM3,
14342;; mulM3 and divM3. There are three patterns for each of DFmode and
14343;; SFmode. The first is the normal insn, the second the same insn but
14344;; with one operand a conversion, and the third the same insn but with
14345;; the other operand a conversion. The conversion may be SFmode or
14346;; SImode if the target mode DFmode, but only SImode if the target mode
14347;; is SFmode.
14348
14349;; Gcc is slightly more smart about handling normal two address instructions
14350;; so use special patterns for add and mull.
14351(define_insn "*fop_sf_comm_nosse"
14352 [(set (match_operand:SF 0 "register_operand" "=f")
14353 (match_operator:SF 3 "binary_fp_operator"
14354 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14355 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14356 "TARGET_80387 && !TARGET_SSE_MATH
14357 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14358 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14359 "* return output_387_binary_op (insn, operands);"
14360 [(set (attr "type")
14361 (if_then_else (match_operand:SF 3 "mult_operator" "")
14362 (const_string "fmul")
14363 (const_string "fop")))
14364 (set_attr "mode" "SF")])
14365
14366(define_insn "*fop_sf_comm"
14367 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14368 (match_operator:SF 3 "binary_fp_operator"
14369 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14370 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14371 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14372 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14374 "* return output_387_binary_op (insn, operands);"
14375 [(set (attr "type")
14376 (if_then_else (eq_attr "alternative" "1")
14377 (if_then_else (match_operand:SF 3 "mult_operator" "")
14378 (const_string "ssemul")
14379 (const_string "sseadd"))
14380 (if_then_else (match_operand:SF 3 "mult_operator" "")
14381 (const_string "fmul")
14382 (const_string "fop"))))
14383 (set_attr "mode" "SF")])
14384
14385(define_insn "*fop_sf_comm_sse"
14386 [(set (match_operand:SF 0 "register_operand" "=x")
14387 (match_operator:SF 3 "binary_fp_operator"
14388 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14389 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14390 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14391 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14392 "* return output_387_binary_op (insn, operands);"
14393 [(set (attr "type")
14394 (if_then_else (match_operand:SF 3 "mult_operator" "")
14395 (const_string "ssemul")
14396 (const_string "sseadd")))
14397 (set_attr "mode" "SF")])
14398
14399(define_insn "*fop_df_comm_nosse"
14400 [(set (match_operand:DF 0 "register_operand" "=f")
14401 (match_operator:DF 3 "binary_fp_operator"
14402 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14403 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14404 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14405 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14406 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14407 "* return output_387_binary_op (insn, operands);"
14408 [(set (attr "type")
14409 (if_then_else (match_operand:SF 3 "mult_operator" "")
14410 (const_string "fmul")
14411 (const_string "fop")))
14412 (set_attr "mode" "DF")])
14413
14414(define_insn "*fop_df_comm"
14415 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14416 (match_operator:DF 3 "binary_fp_operator"
14417 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14418 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14419 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14420 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14421 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14422 "* return output_387_binary_op (insn, operands);"
14423 [(set (attr "type")
14424 (if_then_else (eq_attr "alternative" "1")
14425 (if_then_else (match_operand:SF 3 "mult_operator" "")
14426 (const_string "ssemul")
14427 (const_string "sseadd"))
14428 (if_then_else (match_operand:SF 3 "mult_operator" "")
14429 (const_string "fmul")
14430 (const_string "fop"))))
14431 (set_attr "mode" "DF")])
14432
14433(define_insn "*fop_df_comm_sse"
14434 [(set (match_operand:DF 0 "register_operand" "=Y")
14435 (match_operator:DF 3 "binary_fp_operator"
14436 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14437 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14438 "TARGET_SSE2 && TARGET_SSE_MATH
14439 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14440 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14441 "* return output_387_binary_op (insn, operands);"
14442 [(set (attr "type")
14443 (if_then_else (match_operand:SF 3 "mult_operator" "")
14444 (const_string "ssemul")
14445 (const_string "sseadd")))
14446 (set_attr "mode" "DF")])
14447
14448(define_insn "*fop_xf_comm"
14449 [(set (match_operand:XF 0 "register_operand" "=f")
14450 (match_operator:XF 3 "binary_fp_operator"
14451 [(match_operand:XF 1 "register_operand" "%0")
14452 (match_operand:XF 2 "register_operand" "f")]))]
14453 "TARGET_80387
14454 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14455 "* return output_387_binary_op (insn, operands);"
14456 [(set (attr "type")
14457 (if_then_else (match_operand:XF 3 "mult_operator" "")
14458 (const_string "fmul")
14459 (const_string "fop")))
14460 (set_attr "mode" "XF")])
14461
14462(define_insn "*fop_sf_1_nosse"
14463 [(set (match_operand:SF 0 "register_operand" "=f,f")
14464 (match_operator:SF 3 "binary_fp_operator"
14465 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14466 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14467 "TARGET_80387 && !TARGET_SSE_MATH
14468 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14469 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14470 "* return output_387_binary_op (insn, operands);"
14471 [(set (attr "type")
14472 (cond [(match_operand:SF 3 "mult_operator" "")
14473 (const_string "fmul")
14474 (match_operand:SF 3 "div_operator" "")
14475 (const_string "fdiv")
14476 ]
14477 (const_string "fop")))
14478 (set_attr "mode" "SF")])
14479
14480(define_insn "*fop_sf_1"
14481 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14482 (match_operator:SF 3 "binary_fp_operator"
14483 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14484 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14485 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14486 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14487 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14488 "* return output_387_binary_op (insn, operands);"
14489 [(set (attr "type")
14490 (cond [(and (eq_attr "alternative" "2")
14491 (match_operand:SF 3 "mult_operator" ""))
14492 (const_string "ssemul")
14493 (and (eq_attr "alternative" "2")
14494 (match_operand:SF 3 "div_operator" ""))
14495 (const_string "ssediv")
14496 (eq_attr "alternative" "2")
14497 (const_string "sseadd")
14498 (match_operand:SF 3 "mult_operator" "")
14499 (const_string "fmul")
14500 (match_operand:SF 3 "div_operator" "")
14501 (const_string "fdiv")
14502 ]
14503 (const_string "fop")))
14504 (set_attr "mode" "SF")])
14505
14506(define_insn "*fop_sf_1_sse"
14507 [(set (match_operand:SF 0 "register_operand" "=x")
14508 (match_operator:SF 3 "binary_fp_operator"
14509 [(match_operand:SF 1 "register_operand" "0")
14510 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14511 "TARGET_SSE_MATH
14512 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14513 "* return output_387_binary_op (insn, operands);"
14514 [(set (attr "type")
14515 (cond [(match_operand:SF 3 "mult_operator" "")
14516 (const_string "ssemul")
14517 (match_operand:SF 3 "div_operator" "")
14518 (const_string "ssediv")
14519 ]
14520 (const_string "sseadd")))
14521 (set_attr "mode" "SF")])
14522
14523;; ??? Add SSE splitters for these!
14524(define_insn "*fop_sf_2"
14525 [(set (match_operand:SF 0 "register_operand" "=f,f")
14526 (match_operator:SF 3 "binary_fp_operator"
14527 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14528 (match_operand:SF 2 "register_operand" "0,0")]))]
14529 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14530 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14531 [(set (attr "type")
14532 (cond [(match_operand:SF 3 "mult_operator" "")
14533 (const_string "fmul")
14534 (match_operand:SF 3 "div_operator" "")
14535 (const_string "fdiv")
14536 ]
14537 (const_string "fop")))
14538 (set_attr "fp_int_src" "true")
14539 (set_attr "ppro_uops" "many")
14540 (set_attr "mode" "SI")])
14541
14542(define_insn "*fop_sf_3"
14543 [(set (match_operand:SF 0 "register_operand" "=f,f")
14544 (match_operator:SF 3 "binary_fp_operator"
14545 [(match_operand:SF 1 "register_operand" "0,0")
14546 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14547 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14548 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14549 [(set (attr "type")
14550 (cond [(match_operand:SF 3 "mult_operator" "")
14551 (const_string "fmul")
14552 (match_operand:SF 3 "div_operator" "")
14553 (const_string "fdiv")
14554 ]
14555 (const_string "fop")))
14556 (set_attr "fp_int_src" "true")
14557 (set_attr "ppro_uops" "many")
14558 (set_attr "mode" "SI")])
14559
14560(define_insn "*fop_df_1_nosse"
14561 [(set (match_operand:DF 0 "register_operand" "=f,f")
14562 (match_operator:DF 3 "binary_fp_operator"
14563 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14564 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14565 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14566 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14567 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14568 "* return output_387_binary_op (insn, operands);"
14569 [(set (attr "type")
14570 (cond [(match_operand:DF 3 "mult_operator" "")
14571 (const_string "fmul")
14572 (match_operand:DF 3 "div_operator" "")
14573 (const_string "fdiv")
14574 ]
14575 (const_string "fop")))
14576 (set_attr "mode" "DF")])
14577
14578
14579(define_insn "*fop_df_1"
14580 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14581 (match_operator:DF 3 "binary_fp_operator"
14582 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14583 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14584 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14585 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14586 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14587 "* return output_387_binary_op (insn, operands);"
14588 [(set (attr "type")
14589 (cond [(and (eq_attr "alternative" "2")
14590 (match_operand:SF 3 "mult_operator" ""))
14591 (const_string "ssemul")
14592 (and (eq_attr "alternative" "2")
14593 (match_operand:SF 3 "div_operator" ""))
14594 (const_string "ssediv")
14595 (eq_attr "alternative" "2")
14596 (const_string "sseadd")
14597 (match_operand:DF 3 "mult_operator" "")
14598 (const_string "fmul")
14599 (match_operand:DF 3 "div_operator" "")
14600 (const_string "fdiv")
14601 ]
14602 (const_string "fop")))
14603 (set_attr "mode" "DF")])
14604
14605(define_insn "*fop_df_1_sse"
14606 [(set (match_operand:DF 0 "register_operand" "=Y")
14607 (match_operator:DF 3 "binary_fp_operator"
14608 [(match_operand:DF 1 "register_operand" "0")
14609 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14610 "TARGET_SSE2 && TARGET_SSE_MATH
14611 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14612 "* return output_387_binary_op (insn, operands);"
14613 [(set_attr "mode" "DF")
14614 (set (attr "type")
14615 (cond [(match_operand:SF 3 "mult_operator" "")
14616 (const_string "ssemul")
14617 (match_operand:SF 3 "div_operator" "")
14618 (const_string "ssediv")
14619 ]
14620 (const_string "sseadd")))])
14621
14622;; ??? Add SSE splitters for these!
14623(define_insn "*fop_df_2"
14624 [(set (match_operand:DF 0 "register_operand" "=f,f")
14625 (match_operator:DF 3 "binary_fp_operator"
14626 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14627 (match_operand:DF 2 "register_operand" "0,0")]))]
14628 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14629 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14630 [(set (attr "type")
14631 (cond [(match_operand:DF 3 "mult_operator" "")
14632 (const_string "fmul")
14633 (match_operand:DF 3 "div_operator" "")
14634 (const_string "fdiv")
14635 ]
14636 (const_string "fop")))
14637 (set_attr "fp_int_src" "true")
14638 (set_attr "ppro_uops" "many")
14639 (set_attr "mode" "SI")])
14640
14641(define_insn "*fop_df_3"
14642 [(set (match_operand:DF 0 "register_operand" "=f,f")
14643 (match_operator:DF 3 "binary_fp_operator"
14644 [(match_operand:DF 1 "register_operand" "0,0")
14645 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14646 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14647 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14648 [(set (attr "type")
14649 (cond [(match_operand:DF 3 "mult_operator" "")
14650 (const_string "fmul")
14651 (match_operand:DF 3 "div_operator" "")
14652 (const_string "fdiv")
14653 ]
14654 (const_string "fop")))
14655 (set_attr "fp_int_src" "true")
14656 (set_attr "ppro_uops" "many")
14657 (set_attr "mode" "SI")])
14658
14659(define_insn "*fop_df_4"
14660 [(set (match_operand:DF 0 "register_operand" "=f,f")
14661 (match_operator:DF 3 "binary_fp_operator"
14662 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14663 (match_operand:DF 2 "register_operand" "0,f")]))]
14664 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14666 "* return output_387_binary_op (insn, operands);"
14667 [(set (attr "type")
14668 (cond [(match_operand:DF 3 "mult_operator" "")
14669 (const_string "fmul")
14670 (match_operand:DF 3 "div_operator" "")
14671 (const_string "fdiv")
14672 ]
14673 (const_string "fop")))
14674 (set_attr "mode" "SF")])
14675
14676(define_insn "*fop_df_5"
14677 [(set (match_operand:DF 0 "register_operand" "=f,f")
14678 (match_operator:DF 3 "binary_fp_operator"
14679 [(match_operand:DF 1 "register_operand" "0,f")
14680 (float_extend:DF
14681 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14682 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14683 "* return output_387_binary_op (insn, operands);"
14684 [(set (attr "type")
14685 (cond [(match_operand:DF 3 "mult_operator" "")
14686 (const_string "fmul")
14687 (match_operand:DF 3 "div_operator" "")
14688 (const_string "fdiv")
14689 ]
14690 (const_string "fop")))
14691 (set_attr "mode" "SF")])
14692
14693(define_insn "*fop_df_6"
14694 [(set (match_operand:DF 0 "register_operand" "=f,f")
14695 (match_operator:DF 3 "binary_fp_operator"
14696 [(float_extend:DF
14697 (match_operand:SF 1 "register_operand" "0,f"))
14698 (float_extend:DF
14699 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14700 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14701 "* return output_387_binary_op (insn, operands);"
14702 [(set (attr "type")
14703 (cond [(match_operand:DF 3 "mult_operator" "")
14704 (const_string "fmul")
14705 (match_operand:DF 3 "div_operator" "")
14706 (const_string "fdiv")
14707 ]
14708 (const_string "fop")))
14709 (set_attr "mode" "SF")])
14710
14711(define_insn "*fop_xf_1"
14712 [(set (match_operand:XF 0 "register_operand" "=f,f")
14713 (match_operator:XF 3 "binary_fp_operator"
14714 [(match_operand:XF 1 "register_operand" "0,f")
14715 (match_operand:XF 2 "register_operand" "f,0")]))]
14716 "TARGET_80387
14717 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14718 "* return output_387_binary_op (insn, operands);"
14719 [(set (attr "type")
14720 (cond [(match_operand:XF 3 "mult_operator" "")
14721 (const_string "fmul")
14722 (match_operand:XF 3 "div_operator" "")
14723 (const_string "fdiv")
14724 ]
14725 (const_string "fop")))
14726 (set_attr "mode" "XF")])
14727
14728(define_insn "*fop_xf_2"
14729 [(set (match_operand:XF 0 "register_operand" "=f,f")
14730 (match_operator:XF 3 "binary_fp_operator"
14731 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14732 (match_operand:XF 2 "register_operand" "0,0")]))]
14733 "TARGET_80387 && TARGET_USE_FIOP"
14734 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14735 [(set (attr "type")
14736 (cond [(match_operand:XF 3 "mult_operator" "")
14737 (const_string "fmul")
14738 (match_operand:XF 3 "div_operator" "")
14739 (const_string "fdiv")
14740 ]
14741 (const_string "fop")))
14742 (set_attr "fp_int_src" "true")
14743 (set_attr "mode" "SI")
14744 (set_attr "ppro_uops" "many")])
14745
14746(define_insn "*fop_xf_3"
14747 [(set (match_operand:XF 0 "register_operand" "=f,f")
14748 (match_operator:XF 3 "binary_fp_operator"
14749 [(match_operand:XF 1 "register_operand" "0,0")
14750 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14751 "TARGET_80387 && TARGET_USE_FIOP"
14752 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14753 [(set (attr "type")
14754 (cond [(match_operand:XF 3 "mult_operator" "")
14755 (const_string "fmul")
14756 (match_operand:XF 3 "div_operator" "")
14757 (const_string "fdiv")
14758 ]
14759 (const_string "fop")))
14760 (set_attr "fp_int_src" "true")
14761 (set_attr "mode" "SI")
14762 (set_attr "ppro_uops" "many")])
14763
14764(define_insn "*fop_xf_4"
14765 [(set (match_operand:XF 0 "register_operand" "=f,f")
14766 (match_operator:XF 3 "binary_fp_operator"
14767 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14768 (match_operand:XF 2 "register_operand" "0,f")]))]
14769 "TARGET_80387"
14770 "* return output_387_binary_op (insn, operands);"
14771 [(set (attr "type")
14772 (cond [(match_operand:XF 3 "mult_operator" "")
14773 (const_string "fmul")
14774 (match_operand:XF 3 "div_operator" "")
14775 (const_string "fdiv")
14776 ]
14777 (const_string "fop")))
14778 (set_attr "mode" "SF")])
14779
14780(define_insn "*fop_xf_5"
14781 [(set (match_operand:XF 0 "register_operand" "=f,f")
14782 (match_operator:XF 3 "binary_fp_operator"
14783 [(match_operand:XF 1 "register_operand" "0,f")
14784 (float_extend:XF
14785 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14786 "TARGET_80387"
14787 "* return output_387_binary_op (insn, operands);"
14788 [(set (attr "type")
14789 (cond [(match_operand:XF 3 "mult_operator" "")
14790 (const_string "fmul")
14791 (match_operand:XF 3 "div_operator" "")
14792 (const_string "fdiv")
14793 ]
14794 (const_string "fop")))
14795 (set_attr "mode" "SF")])
14796
14797(define_insn "*fop_xf_6"
14798 [(set (match_operand:XF 0 "register_operand" "=f,f")
14799 (match_operator:XF 3 "binary_fp_operator"
14800 [(float_extend:XF
14801 (match_operand 1 "register_operand" "0,f"))
14802 (float_extend:XF
14803 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14804 "TARGET_80387"
14805 "* return output_387_binary_op (insn, operands);"
14806 [(set (attr "type")
14807 (cond [(match_operand:XF 3 "mult_operator" "")
14808 (const_string "fmul")
14809 (match_operand:XF 3 "div_operator" "")
14810 (const_string "fdiv")
14811 ]
14812 (const_string "fop")))
14813 (set_attr "mode" "SF")])
14814
14815(define_split
14816 [(set (match_operand 0 "register_operand" "")
14817 (match_operator 3 "binary_fp_operator"
14818 [(float (match_operand:SI 1 "register_operand" ""))
14819 (match_operand 2 "register_operand" "")]))]
14820 "TARGET_80387 && reload_completed
14821 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14822 [(const_int 0)]
14823{
14824 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14825 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14826 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14827 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14828 GET_MODE (operands[3]),
14829 operands[4],
14830 operands[2])));
14831 ix86_free_from_memory (GET_MODE (operands[1]));
14832 DONE;
14833})
14834
14835(define_split
14836 [(set (match_operand 0 "register_operand" "")
14837 (match_operator 3 "binary_fp_operator"
14838 [(match_operand 1 "register_operand" "")
14839 (float (match_operand:SI 2 "register_operand" ""))]))]
14840 "TARGET_80387 && reload_completed
14841 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14842 [(const_int 0)]
14843{
14844 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14845 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14846 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14847 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14848 GET_MODE (operands[3]),
14849 operands[1],
14850 operands[4])));
14851 ix86_free_from_memory (GET_MODE (operands[2]));
14852 DONE;
14853})
14854
14855;; FPU special functions.
14856
14857(define_expand "sqrtsf2"
14858 [(set (match_operand:SF 0 "register_operand" "")
14859 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14860 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14861{
14862 if (!TARGET_SSE_MATH)
14863 operands[1] = force_reg (SFmode, operands[1]);
14864})
14865
14866(define_insn "sqrtsf2_1"
14867 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14868 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14869 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14870 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14871 "@
14872 fsqrt
14873 sqrtss\t{%1, %0|%0, %1}"
14874 [(set_attr "type" "fpspc,sse")
14875 (set_attr "mode" "SF,SF")
14876 (set_attr "athlon_decode" "direct,*")])
14877
14878(define_insn "sqrtsf2_1_sse_only"
14879 [(set (match_operand:SF 0 "register_operand" "=x")
14880 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14881 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14882 "sqrtss\t{%1, %0|%0, %1}"
14883 [(set_attr "type" "sse")
14884 (set_attr "mode" "SF")
14885 (set_attr "athlon_decode" "*")])
14886
14887(define_insn "sqrtsf2_i387"
14888 [(set (match_operand:SF 0 "register_operand" "=f")
14889 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14890 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14891 && !TARGET_SSE_MATH"
14892 "fsqrt"
14893 [(set_attr "type" "fpspc")
14894 (set_attr "mode" "SF")
14895 (set_attr "athlon_decode" "direct")])
14896
14897(define_expand "sqrtdf2"
14898 [(set (match_operand:DF 0 "register_operand" "")
14899 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14900 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14901 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14902{
14903 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14904 operands[1] = force_reg (DFmode, operands[1]);
14905})
14906
14907(define_insn "sqrtdf2_1"
14908 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14909 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14910 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14911 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14912 "@
14913 fsqrt
14914 sqrtsd\t{%1, %0|%0, %1}"
14915 [(set_attr "type" "fpspc,sse")
14916 (set_attr "mode" "DF,DF")
14917 (set_attr "athlon_decode" "direct,*")])
14918
14919(define_insn "sqrtdf2_1_sse_only"
14920 [(set (match_operand:DF 0 "register_operand" "=Y")
14921 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14922 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14923 "sqrtsd\t{%1, %0|%0, %1}"
14924 [(set_attr "type" "sse")
14925 (set_attr "mode" "DF")
14926 (set_attr "athlon_decode" "*")])
14927
14928(define_insn "sqrtdf2_i387"
14929 [(set (match_operand:DF 0 "register_operand" "=f")
14930 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14931 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14932 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14933 "fsqrt"
14934 [(set_attr "type" "fpspc")
14935 (set_attr "mode" "DF")
14936 (set_attr "athlon_decode" "direct")])
14937
14938(define_insn "*sqrtextendsfdf2"
14939 [(set (match_operand:DF 0 "register_operand" "=f")
14940 (sqrt:DF (float_extend:DF
14941 (match_operand:SF 1 "register_operand" "0"))))]
14942 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14943 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14944 "fsqrt"
14945 [(set_attr "type" "fpspc")
14946 (set_attr "mode" "DF")
14947 (set_attr "athlon_decode" "direct")])
14948
14949(define_insn "sqrtxf2"
14950 [(set (match_operand:XF 0 "register_operand" "=f")
14951 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14952 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14953 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14954 "fsqrt"
14955 [(set_attr "type" "fpspc")
14956 (set_attr "mode" "XF")
14957 (set_attr "athlon_decode" "direct")])
14958
14959(define_insn "*sqrtextenddfxf2"
14960 [(set (match_operand:XF 0 "register_operand" "=f")
14961 (sqrt:XF (float_extend:XF
14962 (match_operand:DF 1 "register_operand" "0"))))]
14963 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14964 "fsqrt"
14965 [(set_attr "type" "fpspc")
14966 (set_attr "mode" "XF")
14967 (set_attr "athlon_decode" "direct")])
14968
14969(define_insn "*sqrtextendsfxf2"
14970 [(set (match_operand:XF 0 "register_operand" "=f")
14971 (sqrt:XF (float_extend:XF
14972 (match_operand:SF 1 "register_operand" "0"))))]
14973 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14974 "fsqrt"
14975 [(set_attr "type" "fpspc")
14976 (set_attr "mode" "XF")
14977 (set_attr "athlon_decode" "direct")])
14978
14979(define_insn "sindf2"
14980 [(set (match_operand:DF 0 "register_operand" "=f")
14981 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14982 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14983 && flag_unsafe_math_optimizations"
14984 "fsin"
14985 [(set_attr "type" "fpspc")
14986 (set_attr "mode" "DF")])
14987
14988(define_insn "sinsf2"
14989 [(set (match_operand:SF 0 "register_operand" "=f")
14990 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14991 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14992 && flag_unsafe_math_optimizations"
14993 "fsin"
14994 [(set_attr "type" "fpspc")
14995 (set_attr "mode" "SF")])
14996
14997(define_insn "*sinextendsfdf2"
14998 [(set (match_operand:DF 0 "register_operand" "=f")
14999 (unspec:DF [(float_extend:DF
15000 (match_operand:SF 1 "register_operand" "0"))]
15001 UNSPEC_SIN))]
15002 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15003 && flag_unsafe_math_optimizations"
15004 "fsin"
15005 [(set_attr "type" "fpspc")
15006 (set_attr "mode" "DF")])
15007
15008(define_insn "sinxf2"
15009 [(set (match_operand:XF 0 "register_operand" "=f")
15010 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15011 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15012 && flag_unsafe_math_optimizations"
15013 "fsin"
15014 [(set_attr "type" "fpspc")
15015 (set_attr "mode" "XF")])
15016
15017(define_insn "cosdf2"
15018 [(set (match_operand:DF 0 "register_operand" "=f")
15019 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15020 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15021 && flag_unsafe_math_optimizations"
15022 "fcos"
15023 [(set_attr "type" "fpspc")
15024 (set_attr "mode" "DF")])
15025
15026(define_insn "cossf2"
15027 [(set (match_operand:SF 0 "register_operand" "=f")
15028 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15029 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15030 && flag_unsafe_math_optimizations"
15031 "fcos"
15032 [(set_attr "type" "fpspc")
15033 (set_attr "mode" "SF")])
15034
15035(define_insn "*cosextendsfdf2"
15036 [(set (match_operand:DF 0 "register_operand" "=f")
15037 (unspec:DF [(float_extend:DF
15038 (match_operand:SF 1 "register_operand" "0"))]
15039 UNSPEC_COS))]
15040 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15041 && flag_unsafe_math_optimizations"
15042 "fcos"
15043 [(set_attr "type" "fpspc")
15044 (set_attr "mode" "DF")])
15045
15046(define_insn "cosxf2"
15047 [(set (match_operand:XF 0 "register_operand" "=f")
15048 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15049 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15050 && flag_unsafe_math_optimizations"
15051 "fcos"
15052 [(set_attr "type" "fpspc")
15053 (set_attr "mode" "XF")])
15054
15055(define_insn "atan2df3_1"
15056 [(set (match_operand:DF 0 "register_operand" "=f")
15057 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15058 (match_operand:DF 1 "register_operand" "u")]
15059 UNSPEC_FPATAN))
15060 (clobber (match_scratch:DF 3 "=1"))]
15061 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15062 && flag_unsafe_math_optimizations"
15063 "fpatan"
15064 [(set_attr "type" "fpspc")
15065 (set_attr "mode" "DF")])
15066
15067(define_expand "atan2df3"
15068 [(use (match_operand:DF 0 "register_operand" "=f"))
15069 (use (match_operand:DF 2 "register_operand" "0"))
15070 (use (match_operand:DF 1 "register_operand" "u"))]
15071 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15072 && flag_unsafe_math_optimizations"
15073{
15074 rtx copy = gen_reg_rtx (DFmode);
15075 emit_move_insn (copy, operands[1]);
15076 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15077 DONE;
15078})
15079
15080(define_insn "atan2sf3_1"
15081 [(set (match_operand:SF 0 "register_operand" "=f")
15082 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15083 (match_operand:SF 1 "register_operand" "u")]
15084 UNSPEC_FPATAN))
15085 (clobber (match_scratch:SF 3 "=1"))]
15086 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15087 && flag_unsafe_math_optimizations"
15088 "fpatan"
15089 [(set_attr "type" "fpspc")
15090 (set_attr "mode" "SF")])
15091
15092(define_expand "atan2sf3"
15093 [(use (match_operand:SF 0 "register_operand" "=f"))
15094 (use (match_operand:SF 2 "register_operand" "0"))
15095 (use (match_operand:SF 1 "register_operand" "u"))]
15096 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15097 && flag_unsafe_math_optimizations"
15098{
15099 rtx copy = gen_reg_rtx (SFmode);
15100 emit_move_insn (copy, operands[1]);
15101 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15102 DONE;
15103})
15104
15105(define_insn "atan2xf3_1"
15106 [(set (match_operand:XF 0 "register_operand" "=f")
15107 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15108 (match_operand:XF 1 "register_operand" "u")]
15109 UNSPEC_FPATAN))
15110 (clobber (match_scratch:XF 3 "=1"))]
15111 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15112 && flag_unsafe_math_optimizations"
15113 "fpatan"
15114 [(set_attr "type" "fpspc")
15115 (set_attr "mode" "XF")])
15116
15117(define_expand "atan2xf3"
15118 [(use (match_operand:XF 0 "register_operand" "=f"))
15119 (use (match_operand:XF 2 "register_operand" "0"))
15120 (use (match_operand:XF 1 "register_operand" "u"))]
15121 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15122 && flag_unsafe_math_optimizations"
15123{
15124 rtx copy = gen_reg_rtx (XFmode);
15125 emit_move_insn (copy, operands[1]);
15126 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15127 DONE;
15128})
15129
15130(define_insn "*fyl2x_sfxf3"
15131 [(set (match_operand:SF 0 "register_operand" "=f")
15132 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15133 (match_operand:XF 1 "register_operand" "u")]
15134 UNSPEC_FYL2X))
15135 (clobber (match_scratch:SF 3 "=1"))]
15136 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15137 && flag_unsafe_math_optimizations"
15138 "fyl2x"
15139 [(set_attr "type" "fpspc")
15140 (set_attr "mode" "SF")])
15141
15142(define_insn "*fyl2x_dfxf3"
15143 [(set (match_operand:DF 0 "register_operand" "=f")
15144 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15145 (match_operand:XF 1 "register_operand" "u")]
15146 UNSPEC_FYL2X))
15147 (clobber (match_scratch:DF 3 "=1"))]
15148 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15149 && flag_unsafe_math_optimizations"
15150 "fyl2x"
15151 [(set_attr "type" "fpspc")
15152 (set_attr "mode" "DF")])
15153
15154(define_insn "*fyl2x_xf3"
15155 [(set (match_operand:XF 0 "register_operand" "=f")
15156 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15157 (match_operand:XF 1 "register_operand" "u")]
15158 UNSPEC_FYL2X))
15159 (clobber (match_scratch:XF 3 "=1"))]
15160 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15161 && flag_unsafe_math_optimizations"
15162 "fyl2x"
15163 [(set_attr "type" "fpspc")
15164 (set_attr "mode" "XF")])
15165
15166(define_expand "logsf2"
15167 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15168 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15169 (match_dup 2)] UNSPEC_FYL2X))
15170 (clobber (match_scratch:SF 3 ""))])]
15171 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15172 && flag_unsafe_math_optimizations"
15173{
15174 rtx temp;
15175
15176 operands[2] = gen_reg_rtx (XFmode);
15177 temp = standard_80387_constant_rtx (4); /* fldln2 */
15178 emit_move_insn (operands[2], temp);
15179})
15180
15181(define_expand "logdf2"
15182 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15183 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15184 (match_dup 2)] UNSPEC_FYL2X))
15185 (clobber (match_scratch:DF 3 ""))])]
15186 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15187 && flag_unsafe_math_optimizations"
15188{
15189 rtx temp;
15190
15191 operands[2] = gen_reg_rtx (XFmode);
15192 temp = standard_80387_constant_rtx (4); /* fldln2 */
15193 emit_move_insn (operands[2], temp);
15194})
15195
15196(define_expand "logxf2"
15197 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15198 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15199 (match_dup 2)] UNSPEC_FYL2X))
15200 (clobber (match_scratch:XF 3 ""))])]
15201 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15202 && flag_unsafe_math_optimizations"
15203{
15204 rtx temp;
15205
15206 operands[2] = gen_reg_rtx (XFmode);
15207 temp = standard_80387_constant_rtx (4); /* fldln2 */
15208 emit_move_insn (operands[2], temp);
15209})
15210
15211(define_insn "*fscale_sfxf3"
15212 [(set (match_operand:SF 0 "register_operand" "=f")
15213 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15214 (match_operand:XF 1 "register_operand" "u")]
15215 UNSPEC_FSCALE))
15216 (clobber (match_scratch:SF 3 "=1"))]
15217 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15218 && flag_unsafe_math_optimizations"
15219 "fscale\;fstp\t%y1"
15220 [(set_attr "type" "fpspc")
15221 (set_attr "mode" "SF")])
15222
15223(define_insn "*fscale_dfxf3"
15224 [(set (match_operand:DF 0 "register_operand" "=f")
15225 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15226 (match_operand:XF 1 "register_operand" "u")]
15227 UNSPEC_FSCALE))
15228 (clobber (match_scratch:DF 3 "=1"))]
15229 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15230 && flag_unsafe_math_optimizations"
15231 "fscale\;fstp\t%y1"
15232 [(set_attr "type" "fpspc")
15233 (set_attr "mode" "DF")])
15234
15235(define_insn "*fscale_xf3"
15236 [(set (match_operand:XF 0 "register_operand" "=f")
15237 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15238 (match_operand:XF 1 "register_operand" "u")]
15239 UNSPEC_FSCALE))
15240 (clobber (match_scratch:XF 3 "=1"))]
15241 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15242 && flag_unsafe_math_optimizations"
15243 "fscale\;fstp\t%y1"
15244 [(set_attr "type" "fpspc")
15245 (set_attr "mode" "XF")])
15246
15247(define_insn "*frndintxf2"
15248 [(set (match_operand:XF 0 "register_operand" "=f")
15249 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15250 UNSPEC_FRNDINT))]
15251 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15252 && flag_unsafe_math_optimizations"
15253 "frndint"
15254 [(set_attr "type" "fpspc")
15255 (set_attr "mode" "XF")])
15256
15257(define_insn "*f2xm1xf2"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15260 UNSPEC_F2XM1))]
15261 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15262 && flag_unsafe_math_optimizations"
15263 "f2xm1"
15264 [(set_attr "type" "fpspc")
15265 (set_attr "mode" "XF")])
15266
15267(define_expand "expsf2"
15268 [(set (match_dup 2)
15269 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15270 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15271 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15272 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15273 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15274 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15275 (parallel [(set (match_operand:SF 0 "register_operand" "")
15276 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15277 (clobber (match_scratch:SF 5 ""))])]
15278 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15279 && flag_unsafe_math_optimizations"
15280{
15281 rtx temp;
15282 int i;
15283
15284 for (i=2; i<10; i++)
15285 operands[i] = gen_reg_rtx (XFmode);
15286 temp = standard_80387_constant_rtx (5); /* fldl2e */
15287 emit_move_insn (operands[3], temp);
15288 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15289})
15290
15291(define_expand "expdf2"
15292 [(set (match_dup 2)
15293 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15294 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15295 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15296 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15297 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15298 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15299 (parallel [(set (match_operand:DF 0 "register_operand" "")
15300 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15301 (clobber (match_scratch:DF 5 ""))])]
15302 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15303 && flag_unsafe_math_optimizations"
15304{
15305 rtx temp;
15306 int i;
15307
15308 for (i=2; i<10; i++)
15309 operands[i] = gen_reg_rtx (XFmode);
15310 temp = standard_80387_constant_rtx (5); /* fldl2e */
15311 emit_move_insn (operands[3], temp);
15312 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15313})
15314
15315(define_expand "expxf2"
15316 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15317 (match_dup 2)))
15318 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15319 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15320 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15321 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15322 (parallel [(set (match_operand:XF 0 "register_operand" "")
15323 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15324 (clobber (match_scratch:XF 5 ""))])]
15325 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15326 && flag_unsafe_math_optimizations"
15327{
15328 rtx temp;
15329 int i;
15330
15331 for (i=2; i<9; i++)
15332 operands[i] = gen_reg_rtx (XFmode);
15333 temp = standard_80387_constant_rtx (5); /* fldl2e */
15334 emit_move_insn (operands[2], temp);
15335 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15336})
15337
15338(define_expand "atansf2"
15339 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15340 (unspec:SF [(match_dup 2)
15341 (match_operand:SF 1 "register_operand" "")]
15342 UNSPEC_FPATAN))
15343 (clobber (match_scratch:SF 3 ""))])]
15344 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15345 && flag_unsafe_math_optimizations"
15346{
15347 operands[2] = gen_reg_rtx (SFmode);
15348 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15349})
15350
15351(define_expand "atandf2"
15352 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15353 (unspec:DF [(match_dup 2)
15354 (match_operand:DF 1 "register_operand" "")]
15355 UNSPEC_FPATAN))
15356 (clobber (match_scratch:DF 3 ""))])]
15357 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15358 && flag_unsafe_math_optimizations"
15359{
15360 operands[2] = gen_reg_rtx (DFmode);
15361 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15362})
15363
15364(define_expand "atanxf2"
15365 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15366 (unspec:XF [(match_dup 2)
15367 (match_operand:XF 1 "register_operand" "")]
15368 UNSPEC_FPATAN))
15369 (clobber (match_scratch:XF 3 ""))])]
15370 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15371 && flag_unsafe_math_optimizations"
15372{
15373 operands[2] = gen_reg_rtx (XFmode);
15374 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15375})
15376
15377;; Block operation instructions
15378
15379(define_insn "cld"
15380 [(set (reg:SI 19) (const_int 0))]
15381 ""
15382 "cld"
15383 [(set_attr "type" "cld")])
15384
15385(define_expand "movstrsi"
15386 [(use (match_operand:BLK 0 "memory_operand" ""))
15387 (use (match_operand:BLK 1 "memory_operand" ""))
15388 (use (match_operand:SI 2 "nonmemory_operand" ""))
15389 (use (match_operand:SI 3 "const_int_operand" ""))]
15390 "! optimize_size"
15391{
15392 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15393 DONE;
15394 else
15395 FAIL;
15396})
15397
15398(define_expand "movstrdi"
15399 [(use (match_operand:BLK 0 "memory_operand" ""))
15400 (use (match_operand:BLK 1 "memory_operand" ""))
15401 (use (match_operand:DI 2 "nonmemory_operand" ""))
15402 (use (match_operand:DI 3 "const_int_operand" ""))]
15403 "TARGET_64BIT"
15404{
15405 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15406 DONE;
15407 else
15408 FAIL;
15409})
15410
15411;; Most CPUs don't like single string operations
15412;; Handle this case here to simplify previous expander.
15413
15414(define_expand "strmov"
15415 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15416 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15417 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15418 (clobber (reg:CC 17))])
15419 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15420 (clobber (reg:CC 17))])]
15421 ""
15422{
15423 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15424
15425 /* If .md ever supports :P for Pmode, these can be directly
15426 in the pattern above. */
15427 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15428 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15429
15430 if (TARGET_SINGLE_STRINGOP || optimize_size)
15431 {
15432 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15433 operands[2], operands[3],
15434 operands[5], operands[6]));
15435 DONE;
15436 }
15437
15438 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15439})
15440
15441(define_expand "strmov_singleop"
15442 [(parallel [(set (match_operand 1 "memory_operand" "")
15443 (match_operand 3 "memory_operand" ""))
15444 (set (match_operand 0 "register_operand" "")
15445 (match_operand 4 "" ""))
15446 (set (match_operand 2 "register_operand" "")
15447 (match_operand 5 "" ""))
15448 (use (reg:SI 19))])]
15449 "TARGET_SINGLE_STRINGOP || optimize_size"
15450 "")
15451
15452(define_insn "*strmovdi_rex_1"
15453 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15454 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15455 (set (match_operand:DI 0 "register_operand" "=D")
15456 (plus:DI (match_dup 2)
15457 (const_int 8)))
15458 (set (match_operand:DI 1 "register_operand" "=S")
15459 (plus:DI (match_dup 3)
15460 (const_int 8)))
15461 (use (reg:SI 19))]
15462 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15463 "movsq"
15464 [(set_attr "type" "str")
15465 (set_attr "mode" "DI")
15466 (set_attr "memory" "both")])
15467
15468(define_insn "*strmovsi_1"
15469 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15470 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15471 (set (match_operand:SI 0 "register_operand" "=D")
15472 (plus:SI (match_dup 2)
15473 (const_int 4)))
15474 (set (match_operand:SI 1 "register_operand" "=S")
15475 (plus:SI (match_dup 3)
15476 (const_int 4)))
15477 (use (reg:SI 19))]
15478 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15479 "{movsl|movsd}"
15480 [(set_attr "type" "str")
15481 (set_attr "mode" "SI")
15482 (set_attr "memory" "both")])
15483
15484(define_insn "*strmovsi_rex_1"
15485 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15486 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15487 (set (match_operand:DI 0 "register_operand" "=D")
15488 (plus:DI (match_dup 2)
15489 (const_int 4)))
15490 (set (match_operand:DI 1 "register_operand" "=S")
15491 (plus:DI (match_dup 3)
15492 (const_int 4)))
15493 (use (reg:SI 19))]
15494 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15495 "{movsl|movsd}"
15496 [(set_attr "type" "str")
15497 (set_attr "mode" "SI")
15498 (set_attr "memory" "both")])
15499
15500(define_insn "*strmovhi_1"
15501 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15502 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15503 (set (match_operand:SI 0 "register_operand" "=D")
15504 (plus:SI (match_dup 2)
15505 (const_int 2)))
15506 (set (match_operand:SI 1 "register_operand" "=S")
15507 (plus:SI (match_dup 3)
15508 (const_int 2)))
15509 (use (reg:SI 19))]
15510 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15511 "movsw"
15512 [(set_attr "type" "str")
15513 (set_attr "memory" "both")
15514 (set_attr "mode" "HI")])
15515
15516(define_insn "*strmovhi_rex_1"
15517 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15518 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15519 (set (match_operand:DI 0 "register_operand" "=D")
15520 (plus:DI (match_dup 2)
15521 (const_int 2)))
15522 (set (match_operand:DI 1 "register_operand" "=S")
15523 (plus:DI (match_dup 3)
15524 (const_int 2)))
15525 (use (reg:SI 19))]
15526 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15527 "movsw"
15528 [(set_attr "type" "str")
15529 (set_attr "memory" "both")
15530 (set_attr "mode" "HI")])
15531
15532(define_insn "*strmovqi_1"
15533 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15534 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15535 (set (match_operand:SI 0 "register_operand" "=D")
15536 (plus:SI (match_dup 2)
15537 (const_int 1)))
15538 (set (match_operand:SI 1 "register_operand" "=S")
15539 (plus:SI (match_dup 3)
15540 (const_int 1)))
15541 (use (reg:SI 19))]
15542 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15543 "movsb"
15544 [(set_attr "type" "str")
15545 (set_attr "memory" "both")
15546 (set_attr "mode" "QI")])
15547
15548(define_insn "*strmovqi_rex_1"
15549 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15550 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15551 (set (match_operand:DI 0 "register_operand" "=D")
15552 (plus:DI (match_dup 2)
15553 (const_int 1)))
15554 (set (match_operand:DI 1 "register_operand" "=S")
15555 (plus:DI (match_dup 3)
15556 (const_int 1)))
15557 (use (reg:SI 19))]
15558 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15559 "movsb"
15560 [(set_attr "type" "str")
15561 (set_attr "memory" "both")
15562 (set_attr "mode" "QI")])
15563
15564(define_expand "rep_mov"
15565 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15566 (set (match_operand 0 "register_operand" "")
15567 (match_operand 5 "" ""))
15568 (set (match_operand 2 "register_operand" "")
15569 (match_operand 6 "" ""))
15570 (set (match_operand 1 "memory_operand" "")
15571 (match_operand 3 "memory_operand" ""))
15572 (use (match_dup 4))
15573 (use (reg:SI 19))])]
15574 ""
15575 "")
15576
15577(define_insn "*rep_movdi_rex64"
15578 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15579 (set (match_operand:DI 0 "register_operand" "=D")
15580 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15581 (const_int 3))
15582 (match_operand:DI 3 "register_operand" "0")))
15583 (set (match_operand:DI 1 "register_operand" "=S")
15584 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15585 (match_operand:DI 4 "register_operand" "1")))
15586 (set (mem:BLK (match_dup 3))
15587 (mem:BLK (match_dup 4)))
15588 (use (match_dup 5))
15589 (use (reg:SI 19))]
15590 "TARGET_64BIT"
15591 "{rep\;movsq|rep movsq}"
15592 [(set_attr "type" "str")
15593 (set_attr "prefix_rep" "1")
15594 (set_attr "memory" "both")
15595 (set_attr "mode" "DI")])
15596
15597(define_insn "*rep_movsi"
15598 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15599 (set (match_operand:SI 0 "register_operand" "=D")
15600 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15601 (const_int 2))
15602 (match_operand:SI 3 "register_operand" "0")))
15603 (set (match_operand:SI 1 "register_operand" "=S")
15604 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15605 (match_operand:SI 4 "register_operand" "1")))
15606 (set (mem:BLK (match_dup 3))
15607 (mem:BLK (match_dup 4)))
15608 (use (match_dup 5))
15609 (use (reg:SI 19))]
15610 "!TARGET_64BIT"
15611 "{rep\;movsl|rep movsd}"
15612 [(set_attr "type" "str")
15613 (set_attr "prefix_rep" "1")
15614 (set_attr "memory" "both")
15615 (set_attr "mode" "SI")])
15616
15617(define_insn "*rep_movsi_rex64"
15618 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15619 (set (match_operand:DI 0 "register_operand" "=D")
15620 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15621 (const_int 2))
15622 (match_operand:DI 3 "register_operand" "0")))
15623 (set (match_operand:DI 1 "register_operand" "=S")
15624 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15625 (match_operand:DI 4 "register_operand" "1")))
15626 (set (mem:BLK (match_dup 3))
15627 (mem:BLK (match_dup 4)))
15628 (use (match_dup 5))
15629 (use (reg:SI 19))]
15630 "TARGET_64BIT"
15631 "{rep\;movsl|rep movsd}"
15632 [(set_attr "type" "str")
15633 (set_attr "prefix_rep" "1")
15634 (set_attr "memory" "both")
15635 (set_attr "mode" "SI")])
15636
15637(define_insn "*rep_movqi"
15638 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15639 (set (match_operand:SI 0 "register_operand" "=D")
15640 (plus:SI (match_operand:SI 3 "register_operand" "0")
15641 (match_operand:SI 5 "register_operand" "2")))
15642 (set (match_operand:SI 1 "register_operand" "=S")
15643 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15644 (set (mem:BLK (match_dup 3))
15645 (mem:BLK (match_dup 4)))
15646 (use (match_dup 5))
15647 (use (reg:SI 19))]
15648 "!TARGET_64BIT"
15649 "{rep\;movsb|rep movsb}"
15650 [(set_attr "type" "str")
15651 (set_attr "prefix_rep" "1")
15652 (set_attr "memory" "both")
15653 (set_attr "mode" "SI")])
15654
15655(define_insn "*rep_movqi_rex64"
15656 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15657 (set (match_operand:DI 0 "register_operand" "=D")
15658 (plus:DI (match_operand:DI 3 "register_operand" "0")
15659 (match_operand:DI 5 "register_operand" "2")))
15660 (set (match_operand:DI 1 "register_operand" "=S")
15661 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15662 (set (mem:BLK (match_dup 3))
15663 (mem:BLK (match_dup 4)))
15664 (use (match_dup 5))
15665 (use (reg:SI 19))]
15666 "TARGET_64BIT"
15667 "{rep\;movsb|rep movsb}"
15668 [(set_attr "type" "str")
15669 (set_attr "prefix_rep" "1")
15670 (set_attr "memory" "both")
15671 (set_attr "mode" "SI")])
15672
15673(define_expand "clrstrsi"
15674 [(use (match_operand:BLK 0 "memory_operand" ""))
15675 (use (match_operand:SI 1 "nonmemory_operand" ""))
15676 (use (match_operand 2 "const_int_operand" ""))]
15677 ""
15678{
15679 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15680 DONE;
15681 else
15682 FAIL;
15683})
15684
15685(define_expand "clrstrdi"
15686 [(use (match_operand:BLK 0 "memory_operand" ""))
15687 (use (match_operand:DI 1 "nonmemory_operand" ""))
15688 (use (match_operand 2 "const_int_operand" ""))]
15689 "TARGET_64BIT"
15690{
15691 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15692 DONE;
15693 else
15694 FAIL;
15695})
15696
15697;; Most CPUs don't like single string operations
15698;; Handle this case here to simplify previous expander.
15699
15700(define_expand "strset"
15701 [(set (match_operand 1 "memory_operand" "")
15702 (match_operand 2 "register_operand" ""))
15703 (parallel [(set (match_operand 0 "register_operand" "")
15704 (match_dup 3))
15705 (clobber (reg:CC 17))])]
15706 ""
15707{
15708 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15709 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15710
15711 /* If .md ever supports :P for Pmode, this can be directly
15712 in the pattern above. */
15713 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15714 GEN_INT (GET_MODE_SIZE (GET_MODE
15715 (operands[2]))));
15716 if (TARGET_SINGLE_STRINGOP || optimize_size)
15717 {
15718 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15719 operands[3]));
15720 DONE;
15721 }
15722})
15723
15724(define_expand "strset_singleop"
15725 [(parallel [(set (match_operand 1 "memory_operand" "")
15726 (match_operand 2 "register_operand" ""))
15727 (set (match_operand 0 "register_operand" "")
15728 (match_operand 3 "" ""))
15729 (use (reg:SI 19))])]
15730 "TARGET_SINGLE_STRINGOP || optimize_size"
15731 "")
15732
15733(define_insn "*strsetdi_rex_1"
15734 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15735 (match_operand:SI 2 "register_operand" "a"))
15736 (set (match_operand:DI 0 "register_operand" "=D")
15737 (plus:DI (match_dup 1)
15738 (const_int 8)))
15739 (use (reg:SI 19))]
15740 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15741 "stosq"
15742 [(set_attr "type" "str")
15743 (set_attr "memory" "store")
15744 (set_attr "mode" "DI")])
15745
15746(define_insn "*strsetsi_1"
15747 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15748 (match_operand:SI 2 "register_operand" "a"))
15749 (set (match_operand:SI 0 "register_operand" "=D")
15750 (plus:SI (match_dup 1)
15751 (const_int 4)))
15752 (use (reg:SI 19))]
15753 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15754 "{stosl|stosd}"
15755 [(set_attr "type" "str")
15756 (set_attr "memory" "store")
15757 (set_attr "mode" "SI")])
15758
15759(define_insn "*strsetsi_rex_1"
15760 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15761 (match_operand:SI 2 "register_operand" "a"))
15762 (set (match_operand:DI 0 "register_operand" "=D")
15763 (plus:DI (match_dup 1)
15764 (const_int 4)))
15765 (use (reg:SI 19))]
15766 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15767 "{stosl|stosd}"
15768 [(set_attr "type" "str")
15769 (set_attr "memory" "store")
15770 (set_attr "mode" "SI")])
15771
15772(define_insn "*strsethi_1"
15773 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15774 (match_operand:HI 2 "register_operand" "a"))
15775 (set (match_operand:SI 0 "register_operand" "=D")
15776 (plus:SI (match_dup 1)
15777 (const_int 2)))
15778 (use (reg:SI 19))]
15779 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15780 "stosw"
15781 [(set_attr "type" "str")
15782 (set_attr "memory" "store")
15783 (set_attr "mode" "HI")])
15784
15785(define_insn "*strsethi_rex_1"
15786 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15787 (match_operand:HI 2 "register_operand" "a"))
15788 (set (match_operand:DI 0 "register_operand" "=D")
15789 (plus:DI (match_dup 1)
15790 (const_int 2)))
15791 (use (reg:SI 19))]
15792 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15793 "stosw"
15794 [(set_attr "type" "str")
15795 (set_attr "memory" "store")
15796 (set_attr "mode" "HI")])
15797
15798(define_insn "*strsetqi_1"
15799 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15800 (match_operand:QI 2 "register_operand" "a"))
15801 (set (match_operand:SI 0 "register_operand" "=D")
15802 (plus:SI (match_dup 1)
15803 (const_int 1)))
15804 (use (reg:SI 19))]
15805 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15806 "stosb"
15807 [(set_attr "type" "str")
15808 (set_attr "memory" "store")
15809 (set_attr "mode" "QI")])
15810
15811(define_insn "*strsetqi_rex_1"
15812 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15813 (match_operand:QI 2 "register_operand" "a"))
15814 (set (match_operand:DI 0 "register_operand" "=D")
15815 (plus:DI (match_dup 1)
15816 (const_int 1)))
15817 (use (reg:SI 19))]
15818 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15819 "stosb"
15820 [(set_attr "type" "str")
15821 (set_attr "memory" "store")
15822 (set_attr "mode" "QI")])
15823
15824(define_expand "rep_stos"
15825 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15826 (set (match_operand 0 "register_operand" "")
15827 (match_operand 4 "" ""))
15828 (set (match_operand 2 "memory_operand" "") (const_int 0))
15829 (use (match_operand 3 "register_operand" ""))
15830 (use (match_dup 1))
15831 (use (reg:SI 19))])]
15832 ""
15833 "")
15834
15835(define_insn "*rep_stosdi_rex64"
15836 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15837 (set (match_operand:DI 0 "register_operand" "=D")
15838 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15839 (const_int 3))
15840 (match_operand:DI 3 "register_operand" "0")))
15841 (set (mem:BLK (match_dup 3))
15842 (const_int 0))
15843 (use (match_operand:DI 2 "register_operand" "a"))
15844 (use (match_dup 4))
15845 (use (reg:SI 19))]
15846 "TARGET_64BIT"
15847 "{rep\;stosq|rep stosq}"
15848 [(set_attr "type" "str")
15849 (set_attr "prefix_rep" "1")
15850 (set_attr "memory" "store")
15851 (set_attr "mode" "DI")])
15852
15853(define_insn "*rep_stossi"
15854 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15855 (set (match_operand:SI 0 "register_operand" "=D")
15856 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15857 (const_int 2))
15858 (match_operand:SI 3 "register_operand" "0")))
15859 (set (mem:BLK (match_dup 3))
15860 (const_int 0))
15861 (use (match_operand:SI 2 "register_operand" "a"))
15862 (use (match_dup 4))
15863 (use (reg:SI 19))]
15864 "!TARGET_64BIT"
15865 "{rep\;stosl|rep stosd}"
15866 [(set_attr "type" "str")
15867 (set_attr "prefix_rep" "1")
15868 (set_attr "memory" "store")
15869 (set_attr "mode" "SI")])
15870
15871(define_insn "*rep_stossi_rex64"
15872 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15873 (set (match_operand:DI 0 "register_operand" "=D")
15874 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15875 (const_int 2))
15876 (match_operand:DI 3 "register_operand" "0")))
15877 (set (mem:BLK (match_dup 3))
15878 (const_int 0))
15879 (use (match_operand:SI 2 "register_operand" "a"))
15880 (use (match_dup 4))
15881 (use (reg:SI 19))]
15882 "TARGET_64BIT"
15883 "{rep\;stosl|rep stosd}"
15884 [(set_attr "type" "str")
15885 (set_attr "prefix_rep" "1")
15886 (set_attr "memory" "store")
15887 (set_attr "mode" "SI")])
15888
15889(define_insn "*rep_stosqi"
15890 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15891 (set (match_operand:SI 0 "register_operand" "=D")
15892 (plus:SI (match_operand:SI 3 "register_operand" "0")
15893 (match_operand:SI 4 "register_operand" "1")))
15894 (set (mem:BLK (match_dup 3))
15895 (const_int 0))
15896 (use (match_operand:QI 2 "register_operand" "a"))
15897 (use (match_dup 4))
15898 (use (reg:SI 19))]
15899 "!TARGET_64BIT"
15900 "{rep\;stosb|rep stosb}"
15901 [(set_attr "type" "str")
15902 (set_attr "prefix_rep" "1")
15903 (set_attr "memory" "store")
15904 (set_attr "mode" "QI")])
15905
15906(define_insn "*rep_stosqi_rex64"
15907 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15908 (set (match_operand:DI 0 "register_operand" "=D")
15909 (plus:DI (match_operand:DI 3 "register_operand" "0")
15910 (match_operand:DI 4 "register_operand" "1")))
15911 (set (mem:BLK (match_dup 3))
15912 (const_int 0))
15913 (use (match_operand:QI 2 "register_operand" "a"))
15914 (use (match_dup 4))
15915 (use (reg:SI 19))]
15916 "TARGET_64BIT"
15917 "{rep\;stosb|rep stosb}"
15918 [(set_attr "type" "str")
15919 (set_attr "prefix_rep" "1")
15920 (set_attr "memory" "store")
15921 (set_attr "mode" "QI")])
15922
15923(define_expand "cmpstrsi"
15924 [(set (match_operand:SI 0 "register_operand" "")
15925 (compare:SI (match_operand:BLK 1 "general_operand" "")
15926 (match_operand:BLK 2 "general_operand" "")))
15927 (use (match_operand 3 "general_operand" ""))
15928 (use (match_operand 4 "immediate_operand" ""))]
15929 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15930{
15931 rtx addr1, addr2, out, outlow, count, countreg, align;
15932
15933 /* Can't use this if the user has appropriated esi or edi. */
15934 if (global_regs[4] || global_regs[5])
15935 FAIL;
15936
15937 out = operands[0];
15938 if (GET_CODE (out) != REG)
15939 out = gen_reg_rtx (SImode);
15940
15941 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15942 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15943 if (addr1 != XEXP (operands[1], 0))
15944 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15945 if (addr2 != XEXP (operands[2], 0))
15946 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15947
15948 count = operands[3];
15949 countreg = ix86_zero_extend_to_Pmode (count);
15950
15951 /* %%% Iff we are testing strict equality, we can use known alignment
15952 to good advantage. This may be possible with combine, particularly
15953 once cc0 is dead. */
15954 align = operands[4];
15955
15956 emit_insn (gen_cld ());
15957 if (GET_CODE (count) == CONST_INT)
15958 {
15959 if (INTVAL (count) == 0)
15960 {
15961 emit_move_insn (operands[0], const0_rtx);
15962 DONE;
15963 }
15964 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15965 operands[1], operands[2]));
15966 }
15967 else
15968 {
15969 if (TARGET_64BIT)
15970 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15971 else
15972 emit_insn (gen_cmpsi_1 (countreg, countreg));
15973 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15974 operands[1], operands[2]));
15975 }
15976
15977 outlow = gen_lowpart (QImode, out);
15978 emit_insn (gen_cmpintqi (outlow));
15979 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15980
15981 if (operands[0] != out)
15982 emit_move_insn (operands[0], out);
15983
15984 DONE;
15985})
15986
15987;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15988
15989(define_expand "cmpintqi"
15990 [(set (match_dup 1)
15991 (gtu:QI (reg:CC 17) (const_int 0)))
15992 (set (match_dup 2)
15993 (ltu:QI (reg:CC 17) (const_int 0)))
15994 (parallel [(set (match_operand:QI 0 "register_operand" "")
15995 (minus:QI (match_dup 1)
15996 (match_dup 2)))
15997 (clobber (reg:CC 17))])]
15998 ""
15999 "operands[1] = gen_reg_rtx (QImode);
16000 operands[2] = gen_reg_rtx (QImode);")
16001
16002;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16003;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16004
16005(define_expand "cmpstrqi_nz_1"
16006 [(parallel [(set (reg:CC 17)
16007 (compare:CC (match_operand 4 "memory_operand" "")
16008 (match_operand 5 "memory_operand" "")))
16009 (use (match_operand 2 "register_operand" ""))
16010 (use (match_operand:SI 3 "immediate_operand" ""))
16011 (use (reg:SI 19))
16012 (clobber (match_operand 0 "register_operand" ""))
16013 (clobber (match_operand 1 "register_operand" ""))
16014 (clobber (match_dup 2))])]
16015 ""
16016 "")
16017
16018(define_insn "*cmpstrqi_nz_1"
16019 [(set (reg:CC 17)
16020 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16021 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16022 (use (match_operand:SI 6 "register_operand" "2"))
16023 (use (match_operand:SI 3 "immediate_operand" "i"))
16024 (use (reg:SI 19))
16025 (clobber (match_operand:SI 0 "register_operand" "=S"))
16026 (clobber (match_operand:SI 1 "register_operand" "=D"))
16027 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16028 "!TARGET_64BIT"
16029 "repz{\;| }cmpsb"
16030 [(set_attr "type" "str")
16031 (set_attr "mode" "QI")
16032 (set_attr "prefix_rep" "1")])
16033
16034(define_insn "*cmpstrqi_nz_rex_1"
16035 [(set (reg:CC 17)
16036 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16037 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16038 (use (match_operand:DI 6 "register_operand" "2"))
16039 (use (match_operand:SI 3 "immediate_operand" "i"))
16040 (use (reg:SI 19))
16041 (clobber (match_operand:DI 0 "register_operand" "=S"))
16042 (clobber (match_operand:DI 1 "register_operand" "=D"))
16043 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16044 "TARGET_64BIT"
16045 "repz{\;| }cmpsb"
16046 [(set_attr "type" "str")
16047 (set_attr "mode" "QI")
16048 (set_attr "prefix_rep" "1")])
16049
16050;; The same, but the count is not known to not be zero.
16051
16052(define_expand "cmpstrqi_1"
16053 [(parallel [(set (reg:CC 17)
16054 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16055 (const_int 0))
16056 (compare:CC (match_operand 4 "memory_operand" "")
16057 (match_operand 5 "memory_operand" ""))
16058 (const_int 0)))
16059 (use (match_operand:SI 3 "immediate_operand" ""))
16060 (use (reg:CC 17))
16061 (use (reg:SI 19))
16062 (clobber (match_operand 0 "register_operand" ""))
16063 (clobber (match_operand 1 "register_operand" ""))
16064 (clobber (match_dup 2))])]
16065 ""
16066 "")
16067
16068(define_insn "*cmpstrqi_1"
16069 [(set (reg:CC 17)
16070 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16071 (const_int 0))
16072 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16073 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16074 (const_int 0)))
16075 (use (match_operand:SI 3 "immediate_operand" "i"))
16076 (use (reg:CC 17))
16077 (use (reg:SI 19))
16078 (clobber (match_operand:SI 0 "register_operand" "=S"))
16079 (clobber (match_operand:SI 1 "register_operand" "=D"))
16080 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16081 "!TARGET_64BIT"
16082 "repz{\;| }cmpsb"
16083 [(set_attr "type" "str")
16084 (set_attr "mode" "QI")
16085 (set_attr "prefix_rep" "1")])
16086
16087(define_insn "*cmpstrqi_rex_1"
16088 [(set (reg:CC 17)
16089 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16090 (const_int 0))
16091 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16092 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16093 (const_int 0)))
16094 (use (match_operand:SI 3 "immediate_operand" "i"))
16095 (use (reg:CC 17))
16096 (use (reg:SI 19))
16097 (clobber (match_operand:DI 0 "register_operand" "=S"))
16098 (clobber (match_operand:DI 1 "register_operand" "=D"))
16099 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16100 "TARGET_64BIT"
16101 "repz{\;| }cmpsb"
16102 [(set_attr "type" "str")
16103 (set_attr "mode" "QI")
16104 (set_attr "prefix_rep" "1")])
16105
16106(define_expand "strlensi"
16107 [(set (match_operand:SI 0 "register_operand" "")
16108 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16109 (match_operand:QI 2 "immediate_operand" "")
16110 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16111 ""
16112{
16113 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16114 DONE;
16115 else
16116 FAIL;
16117})
16118
16119(define_expand "strlendi"
16120 [(set (match_operand:DI 0 "register_operand" "")
16121 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16122 (match_operand:QI 2 "immediate_operand" "")
16123 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16124 ""
16125{
16126 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16127 DONE;
16128 else
16129 FAIL;
16130})
16131
16132(define_expand "strlenqi_1"
16133 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16134 (use (reg:SI 19))
16135 (clobber (match_operand 1 "register_operand" ""))
16136 (clobber (reg:CC 17))])]
16137 ""
16138 "")
16139
16140(define_insn "*strlenqi_1"
16141 [(set (match_operand:SI 0 "register_operand" "=&c")
16142 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16143 (match_operand:QI 2 "register_operand" "a")
16144 (match_operand:SI 3 "immediate_operand" "i")
16145 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16146 (use (reg:SI 19))
16147 (clobber (match_operand:SI 1 "register_operand" "=D"))
16148 (clobber (reg:CC 17))]
16149 "!TARGET_64BIT"
16150 "repnz{\;| }scasb"
16151 [(set_attr "type" "str")
16152 (set_attr "mode" "QI")
16153 (set_attr "prefix_rep" "1")])
16154
16155(define_insn "*strlenqi_rex_1"
16156 [(set (match_operand:DI 0 "register_operand" "=&c")
16157 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16158 (match_operand:QI 2 "register_operand" "a")
16159 (match_operand:DI 3 "immediate_operand" "i")
16160 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16161 (use (reg:SI 19))
16162 (clobber (match_operand:DI 1 "register_operand" "=D"))
16163 (clobber (reg:CC 17))]
16164 "TARGET_64BIT"
16165 "repnz{\;| }scasb"
16166 [(set_attr "type" "str")
16167 (set_attr "mode" "QI")
16168 (set_attr "prefix_rep" "1")])
16169
16170;; Peephole optimizations to clean up after cmpstr*. This should be
16171;; handled in combine, but it is not currently up to the task.
16172;; When used for their truth value, the cmpstr* expanders generate
16173;; code like this:
16174;;
16175;; repz cmpsb
16176;; seta %al
16177;; setb %dl
16178;; cmpb %al, %dl
16179;; jcc label
16180;;
16181;; The intermediate three instructions are unnecessary.
16182
16183;; This one handles cmpstr*_nz_1...
16184(define_peephole2
16185 [(parallel[
16186 (set (reg:CC 17)
16187 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16188 (mem:BLK (match_operand 5 "register_operand" ""))))
16189 (use (match_operand 6 "register_operand" ""))
16190 (use (match_operand:SI 3 "immediate_operand" ""))
16191 (use (reg:SI 19))
16192 (clobber (match_operand 0 "register_operand" ""))
16193 (clobber (match_operand 1 "register_operand" ""))
16194 (clobber (match_operand 2 "register_operand" ""))])
16195 (set (match_operand:QI 7 "register_operand" "")
16196 (gtu:QI (reg:CC 17) (const_int 0)))
16197 (set (match_operand:QI 8 "register_operand" "")
16198 (ltu:QI (reg:CC 17) (const_int 0)))
16199 (set (reg 17)
16200 (compare (match_dup 7) (match_dup 8)))
16201 ]
16202 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16203 [(parallel[
16204 (set (reg:CC 17)
16205 (compare:CC (mem:BLK (match_dup 4))
16206 (mem:BLK (match_dup 5))))
16207 (use (match_dup 6))
16208 (use (match_dup 3))
16209 (use (reg:SI 19))
16210 (clobber (match_dup 0))
16211 (clobber (match_dup 1))
16212 (clobber (match_dup 2))])]
16213 "")
16214
16215;; ...and this one handles cmpstr*_1.
16216(define_peephole2
16217 [(parallel[
16218 (set (reg:CC 17)
16219 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16220 (const_int 0))
16221 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16222 (mem:BLK (match_operand 5 "register_operand" "")))
16223 (const_int 0)))
16224 (use (match_operand:SI 3 "immediate_operand" ""))
16225 (use (reg:CC 17))
16226 (use (reg:SI 19))
16227 (clobber (match_operand 0 "register_operand" ""))
16228 (clobber (match_operand 1 "register_operand" ""))
16229 (clobber (match_operand 2 "register_operand" ""))])
16230 (set (match_operand:QI 7 "register_operand" "")
16231 (gtu:QI (reg:CC 17) (const_int 0)))
16232 (set (match_operand:QI 8 "register_operand" "")
16233 (ltu:QI (reg:CC 17) (const_int 0)))
16234 (set (reg 17)
16235 (compare (match_dup 7) (match_dup 8)))
16236 ]
16237 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16238 [(parallel[
16239 (set (reg:CC 17)
16240 (if_then_else:CC (ne (match_dup 6)
16241 (const_int 0))
16242 (compare:CC (mem:BLK (match_dup 4))
16243 (mem:BLK (match_dup 5)))
16244 (const_int 0)))
16245 (use (match_dup 3))
16246 (use (reg:CC 17))
16247 (use (reg:SI 19))
16248 (clobber (match_dup 0))
16249 (clobber (match_dup 1))
16250 (clobber (match_dup 2))])]
16251 "")
16252
16253
16254
16255;; Conditional move instructions.
16256
16257(define_expand "movdicc"
16258 [(set (match_operand:DI 0 "register_operand" "")
16259 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16260 (match_operand:DI 2 "general_operand" "")
16261 (match_operand:DI 3 "general_operand" "")))]
16262 "TARGET_64BIT"
16263 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16264
16265(define_insn "x86_movdicc_0_m1_rex64"
16266 [(set (match_operand:DI 0 "register_operand" "=r")
16267 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16268 (const_int -1)
16269 (const_int 0)))
16270 (clobber (reg:CC 17))]
16271 "TARGET_64BIT"
16272 "sbb{q}\t%0, %0"
16273 ; Since we don't have the proper number of operands for an alu insn,
16274 ; fill in all the blanks.
16275 [(set_attr "type" "alu")
16276 (set_attr "pent_pair" "pu")
16277 (set_attr "memory" "none")
16278 (set_attr "imm_disp" "false")
16279 (set_attr "mode" "DI")
16280 (set_attr "length_immediate" "0")])
16281
16282(define_insn "movdicc_c_rex64"
16283 [(set (match_operand:DI 0 "register_operand" "=r,r")
16284 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16285 [(reg 17) (const_int 0)])
16286 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16287 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16288 "TARGET_64BIT && TARGET_CMOVE
16289 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16290 "@
16291 cmov%O2%C1\t{%2, %0|%0, %2}
16292 cmov%O2%c1\t{%3, %0|%0, %3}"
16293 [(set_attr "type" "icmov")
16294 (set_attr "mode" "DI")])
16295
16296(define_expand "movsicc"
16297 [(set (match_operand:SI 0 "register_operand" "")
16298 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16299 (match_operand:SI 2 "general_operand" "")
16300 (match_operand:SI 3 "general_operand" "")))]
16301 ""
16302 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16303
16304;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16305;; the register first winds up with `sbbl $0,reg', which is also weird.
16306;; So just document what we're doing explicitly.
16307
16308(define_insn "x86_movsicc_0_m1"
16309 [(set (match_operand:SI 0 "register_operand" "=r")
16310 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16311 (const_int -1)
16312 (const_int 0)))
16313 (clobber (reg:CC 17))]
16314 ""
16315 "sbb{l}\t%0, %0"
16316 ; Since we don't have the proper number of operands for an alu insn,
16317 ; fill in all the blanks.
16318 [(set_attr "type" "alu")
16319 (set_attr "pent_pair" "pu")
16320 (set_attr "memory" "none")
16321 (set_attr "imm_disp" "false")
16322 (set_attr "mode" "SI")
16323 (set_attr "length_immediate" "0")])
16324
16325(define_insn "*movsicc_noc"
16326 [(set (match_operand:SI 0 "register_operand" "=r,r")
16327 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16328 [(reg 17) (const_int 0)])
16329 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16330 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16331 "TARGET_CMOVE
16332 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16333 "@
16334 cmov%O2%C1\t{%2, %0|%0, %2}
16335 cmov%O2%c1\t{%3, %0|%0, %3}"
16336 [(set_attr "type" "icmov")
16337 (set_attr "mode" "SI")])
16338
16339(define_expand "movhicc"
16340 [(set (match_operand:HI 0 "register_operand" "")
16341 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16342 (match_operand:HI 2 "general_operand" "")
16343 (match_operand:HI 3 "general_operand" "")))]
16344 "TARGET_HIMODE_MATH"
16345 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16346
16347(define_insn "*movhicc_noc"
16348 [(set (match_operand:HI 0 "register_operand" "=r,r")
16349 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16350 [(reg 17) (const_int 0)])
16351 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16352 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16353 "TARGET_CMOVE
16354 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16355 "@
16356 cmov%O2%C1\t{%2, %0|%0, %2}
16357 cmov%O2%c1\t{%3, %0|%0, %3}"
16358 [(set_attr "type" "icmov")
16359 (set_attr "mode" "HI")])
16360
16361(define_expand "movqicc"
16362 [(set (match_operand:QI 0 "register_operand" "")
16363 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16364 (match_operand:QI 2 "general_operand" "")
16365 (match_operand:QI 3 "general_operand" "")))]
16366 "TARGET_QIMODE_MATH"
16367 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16368
16369(define_insn_and_split "*movqicc_noc"
16370 [(set (match_operand:QI 0 "register_operand" "=r,r")
16371 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16372 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16373 (match_operand:QI 2 "register_operand" "r,0")
16374 (match_operand:QI 3 "register_operand" "0,r")))]
16375 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16376 "#"
16377 "&& reload_completed"
16378 [(set (match_dup 0)
16379 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16380 (match_dup 2)
16381 (match_dup 3)))]
16382 "operands[0] = gen_lowpart (SImode, operands[0]);
16383 operands[2] = gen_lowpart (SImode, operands[2]);
16384 operands[3] = gen_lowpart (SImode, operands[3]);"
16385 [(set_attr "type" "icmov")
16386 (set_attr "mode" "SI")])
16387
16388(define_expand "movsfcc"
16389 [(set (match_operand:SF 0 "register_operand" "")
16390 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16391 (match_operand:SF 2 "register_operand" "")
16392 (match_operand:SF 3 "register_operand" "")))]
16393 "TARGET_CMOVE"
16394 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16395
16396(define_insn "*movsfcc_1"
16397 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16398 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16399 [(reg 17) (const_int 0)])
16400 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16401 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16402 "TARGET_CMOVE
16403 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16404 "@
16405 fcmov%F1\t{%2, %0|%0, %2}
16406 fcmov%f1\t{%3, %0|%0, %3}
16407 cmov%O2%C1\t{%2, %0|%0, %2}
16408 cmov%O2%c1\t{%3, %0|%0, %3}"
16409 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16410 (set_attr "mode" "SF,SF,SI,SI")])
16411
16412(define_expand "movdfcc"
16413 [(set (match_operand:DF 0 "register_operand" "")
16414 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16415 (match_operand:DF 2 "register_operand" "")
16416 (match_operand:DF 3 "register_operand" "")))]
16417 "TARGET_CMOVE"
16418 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16419
16420(define_insn "*movdfcc_1"
16421 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16422 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16423 [(reg 17) (const_int 0)])
16424 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16425 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16426 "!TARGET_64BIT && TARGET_CMOVE
16427 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16428 "@
16429 fcmov%F1\t{%2, %0|%0, %2}
16430 fcmov%f1\t{%3, %0|%0, %3}
16431 #
16432 #"
16433 [(set_attr "type" "fcmov,fcmov,multi,multi")
16434 (set_attr "mode" "DF")])
16435
16436(define_insn "*movdfcc_1_rex64"
16437 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16438 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16439 [(reg 17) (const_int 0)])
16440 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16441 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16442 "TARGET_64BIT && TARGET_CMOVE
16443 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16444 "@
16445 fcmov%F1\t{%2, %0|%0, %2}
16446 fcmov%f1\t{%3, %0|%0, %3}
16447 cmov%O2%C1\t{%2, %0|%0, %2}
16448 cmov%O2%c1\t{%3, %0|%0, %3}"
16449 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16450 (set_attr "mode" "DF")])
16451
16452(define_split
16453 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16454 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16455 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16456 (match_operand:DF 2 "nonimmediate_operand" "")
16457 (match_operand:DF 3 "nonimmediate_operand" "")))]
16458 "!TARGET_64BIT && reload_completed"
16459 [(set (match_dup 2)
16460 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16461 (match_dup 5)
16462 (match_dup 7)))
16463 (set (match_dup 3)
16464 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16465 (match_dup 6)
16466 (match_dup 8)))]
16467 "split_di (operands+2, 1, operands+5, operands+6);
16468 split_di (operands+3, 1, operands+7, operands+8);
16469 split_di (operands, 1, operands+2, operands+3);")
16470
16471(define_expand "movxfcc"
16472 [(set (match_operand:XF 0 "register_operand" "")
16473 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16474 (match_operand:XF 2 "register_operand" "")
16475 (match_operand:XF 3 "register_operand" "")))]
16476 "TARGET_CMOVE"
16477 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16478
16479(define_insn "*movxfcc_1"
16480 [(set (match_operand:XF 0 "register_operand" "=f,f")
16481 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16482 [(reg 17) (const_int 0)])
16483 (match_operand:XF 2 "register_operand" "f,0")
16484 (match_operand:XF 3 "register_operand" "0,f")))]
16485 "TARGET_CMOVE"
16486 "@
16487 fcmov%F1\t{%2, %0|%0, %2}
16488 fcmov%f1\t{%3, %0|%0, %3}"
16489 [(set_attr "type" "fcmov")
16490 (set_attr "mode" "XF")])
16491
16492(define_expand "minsf3"
16493 [(parallel [
16494 (set (match_operand:SF 0 "register_operand" "")
16495 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16496 (match_operand:SF 2 "nonimmediate_operand" ""))
16497 (match_dup 1)
16498 (match_dup 2)))
16499 (clobber (reg:CC 17))])]
16500 "TARGET_SSE"
16501 "")
16502
16503(define_insn "*minsf"
16504 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16505 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16506 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16507 (match_dup 1)
16508 (match_dup 2)))
16509 (clobber (reg:CC 17))]
16510 "TARGET_SSE && TARGET_IEEE_FP"
16511 "#")
16512
16513(define_insn "*minsf_nonieee"
16514 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16515 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16516 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16517 (match_dup 1)
16518 (match_dup 2)))
16519 (clobber (reg:CC 17))]
16520 "TARGET_SSE && !TARGET_IEEE_FP
16521 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16522 "#")
16523
16524(define_split
16525 [(set (match_operand:SF 0 "register_operand" "")
16526 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16527 (match_operand:SF 2 "nonimmediate_operand" ""))
16528 (match_operand:SF 3 "register_operand" "")
16529 (match_operand:SF 4 "nonimmediate_operand" "")))
16530 (clobber (reg:CC 17))]
16531 "SSE_REG_P (operands[0]) && reload_completed
16532 && ((operands_match_p (operands[1], operands[3])
16533 && operands_match_p (operands[2], operands[4]))
16534 || (operands_match_p (operands[1], operands[4])
16535 && operands_match_p (operands[2], operands[3])))"
16536 [(set (match_dup 0)
16537 (if_then_else:SF (lt (match_dup 1)
16538 (match_dup 2))
16539 (match_dup 1)
16540 (match_dup 2)))])
16541
16542;; Conditional addition patterns
16543(define_expand "addqicc"
16544 [(match_operand:QI 0 "register_operand" "")
16545 (match_operand 1 "comparison_operator" "")
16546 (match_operand:QI 2 "register_operand" "")
16547 (match_operand:QI 3 "const_int_operand" "")]
16548 ""
16549 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16550
16551(define_expand "addhicc"
16552 [(match_operand:HI 0 "register_operand" "")
16553 (match_operand 1 "comparison_operator" "")
16554 (match_operand:HI 2 "register_operand" "")
16555 (match_operand:HI 3 "const_int_operand" "")]
16556 ""
16557 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16558
16559(define_expand "addsicc"
16560 [(match_operand:SI 0 "register_operand" "")
16561 (match_operand 1 "comparison_operator" "")
16562 (match_operand:SI 2 "register_operand" "")
16563 (match_operand:SI 3 "const_int_operand" "")]
16564 ""
16565 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16566
16567(define_expand "adddicc"
16568 [(match_operand:DI 0 "register_operand" "")
16569 (match_operand 1 "comparison_operator" "")
16570 (match_operand:DI 2 "register_operand" "")
16571 (match_operand:DI 3 "const_int_operand" "")]
16572 "TARGET_64BIT"
16573 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16574
16575;; We can't represent the LT test directly. Do this by swapping the operands.
16576
16577(define_split
16578 [(set (match_operand:SF 0 "fp_register_operand" "")
16579 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16580 (match_operand:SF 2 "register_operand" ""))
16581 (match_operand:SF 3 "register_operand" "")
16582 (match_operand:SF 4 "register_operand" "")))
16583 (clobber (reg:CC 17))]
16584 "reload_completed
16585 && ((operands_match_p (operands[1], operands[3])
16586 && operands_match_p (operands[2], operands[4]))
16587 || (operands_match_p (operands[1], operands[4])
16588 && operands_match_p (operands[2], operands[3])))"
16589 [(set (reg:CCFP 17)
16590 (compare:CCFP (match_dup 2)
16591 (match_dup 1)))
16592 (set (match_dup 0)
16593 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16594 (match_dup 1)
16595 (match_dup 2)))])
16596
16597(define_insn "*minsf_sse"
16598 [(set (match_operand:SF 0 "register_operand" "=x")
16599 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16600 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16601 (match_dup 1)
16602 (match_dup 2)))]
16603 "TARGET_SSE && reload_completed"
16604 "minss\t{%2, %0|%0, %2}"
16605 [(set_attr "type" "sse")
16606 (set_attr "mode" "SF")])
16607
16608(define_expand "mindf3"
16609 [(parallel [
16610 (set (match_operand:DF 0 "register_operand" "")
16611 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16612 (match_operand:DF 2 "nonimmediate_operand" ""))
16613 (match_dup 1)
16614 (match_dup 2)))
16615 (clobber (reg:CC 17))])]
16616 "TARGET_SSE2 && TARGET_SSE_MATH"
16617 "#")
16618
16619(define_insn "*mindf"
16620 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16621 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16622 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16623 (match_dup 1)
16624 (match_dup 2)))
16625 (clobber (reg:CC 17))]
16626 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16627 "#")
16628
16629(define_insn "*mindf_nonieee"
16630 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16631 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16632 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16633 (match_dup 1)
16634 (match_dup 2)))
16635 (clobber (reg:CC 17))]
16636 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16637 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16638 "#")
16639
16640(define_split
16641 [(set (match_operand:DF 0 "register_operand" "")
16642 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16643 (match_operand:DF 2 "nonimmediate_operand" ""))
16644 (match_operand:DF 3 "register_operand" "")
16645 (match_operand:DF 4 "nonimmediate_operand" "")))
16646 (clobber (reg:CC 17))]
16647 "SSE_REG_P (operands[0]) && reload_completed
16648 && ((operands_match_p (operands[1], operands[3])
16649 && operands_match_p (operands[2], operands[4]))
16650 || (operands_match_p (operands[1], operands[4])
16651 && operands_match_p (operands[2], operands[3])))"
16652 [(set (match_dup 0)
16653 (if_then_else:DF (lt (match_dup 1)
16654 (match_dup 2))
16655 (match_dup 1)
16656 (match_dup 2)))])
16657
16658;; We can't represent the LT test directly. Do this by swapping the operands.
16659(define_split
16660 [(set (match_operand:DF 0 "fp_register_operand" "")
16661 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16662 (match_operand:DF 2 "register_operand" ""))
16663 (match_operand:DF 3 "register_operand" "")
16664 (match_operand:DF 4 "register_operand" "")))
16665 (clobber (reg:CC 17))]
16666 "reload_completed
16667 && ((operands_match_p (operands[1], operands[3])
16668 && operands_match_p (operands[2], operands[4]))
16669 || (operands_match_p (operands[1], operands[4])
16670 && operands_match_p (operands[2], operands[3])))"
16671 [(set (reg:CCFP 17)
16672 (compare:CCFP (match_dup 2)
16673 (match_dup 1)))
16674 (set (match_dup 0)
16675 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16676 (match_dup 1)
16677 (match_dup 2)))])
16678
16679(define_insn "*mindf_sse"
16680 [(set (match_operand:DF 0 "register_operand" "=Y")
16681 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16682 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16683 (match_dup 1)
16684 (match_dup 2)))]
16685 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16686 "minsd\t{%2, %0|%0, %2}"
16687 [(set_attr "type" "sse")
16688 (set_attr "mode" "DF")])
16689
16690(define_expand "maxsf3"
16691 [(parallel [
16692 (set (match_operand:SF 0 "register_operand" "")
16693 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16694 (match_operand:SF 2 "nonimmediate_operand" ""))
16695 (match_dup 1)
16696 (match_dup 2)))
16697 (clobber (reg:CC 17))])]
16698 "TARGET_SSE"
16699 "#")
16700
16701(define_insn "*maxsf"
16702 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16703 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16704 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16705 (match_dup 1)
16706 (match_dup 2)))
16707 (clobber (reg:CC 17))]
16708 "TARGET_SSE && TARGET_IEEE_FP"
16709 "#")
16710
16711(define_insn "*maxsf_nonieee"
16712 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16713 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16714 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16715 (match_dup 1)
16716 (match_dup 2)))
16717 (clobber (reg:CC 17))]
16718 "TARGET_SSE && !TARGET_IEEE_FP
16719 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16720 "#")
16721
16722(define_split
16723 [(set (match_operand:SF 0 "register_operand" "")
16724 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16725 (match_operand:SF 2 "nonimmediate_operand" ""))
16726 (match_operand:SF 3 "register_operand" "")
16727 (match_operand:SF 4 "nonimmediate_operand" "")))
16728 (clobber (reg:CC 17))]
16729 "SSE_REG_P (operands[0]) && reload_completed
16730 && ((operands_match_p (operands[1], operands[3])
16731 && operands_match_p (operands[2], operands[4]))
16732 || (operands_match_p (operands[1], operands[4])
16733 && operands_match_p (operands[2], operands[3])))"
16734 [(set (match_dup 0)
16735 (if_then_else:SF (gt (match_dup 1)
16736 (match_dup 2))
16737 (match_dup 1)
16738 (match_dup 2)))])
16739
16740(define_split
16741 [(set (match_operand:SF 0 "fp_register_operand" "")
16742 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16743 (match_operand:SF 2 "register_operand" ""))
16744 (match_operand:SF 3 "register_operand" "")
16745 (match_operand:SF 4 "register_operand" "")))
16746 (clobber (reg:CC 17))]
16747 "reload_completed
16748 && ((operands_match_p (operands[1], operands[3])
16749 && operands_match_p (operands[2], operands[4]))
16750 || (operands_match_p (operands[1], operands[4])
16751 && operands_match_p (operands[2], operands[3])))"
16752 [(set (reg:CCFP 17)
16753 (compare:CCFP (match_dup 1)
16754 (match_dup 2)))
16755 (set (match_dup 0)
16756 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16757 (match_dup 1)
16758 (match_dup 2)))])
16759
16760(define_insn "*maxsf_sse"
16761 [(set (match_operand:SF 0 "register_operand" "=x")
16762 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16763 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16764 (match_dup 1)
16765 (match_dup 2)))]
16766 "TARGET_SSE && reload_completed"
16767 "maxss\t{%2, %0|%0, %2}"
16768 [(set_attr "type" "sse")
16769 (set_attr "mode" "SF")])
16770
16771(define_expand "maxdf3"
16772 [(parallel [
16773 (set (match_operand:DF 0 "register_operand" "")
16774 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16775 (match_operand:DF 2 "nonimmediate_operand" ""))
16776 (match_dup 1)
16777 (match_dup 2)))
16778 (clobber (reg:CC 17))])]
16779 "TARGET_SSE2 && TARGET_SSE_MATH"
16780 "#")
16781
16782(define_insn "*maxdf"
16783 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16784 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16785 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16786 (match_dup 1)
16787 (match_dup 2)))
16788 (clobber (reg:CC 17))]
16789 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16790 "#")
16791
16792(define_insn "*maxdf_nonieee"
16793 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16794 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16795 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16796 (match_dup 1)
16797 (match_dup 2)))
16798 (clobber (reg:CC 17))]
16799 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16800 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16801 "#")
16802
16803(define_split
16804 [(set (match_operand:DF 0 "register_operand" "")
16805 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16806 (match_operand:DF 2 "nonimmediate_operand" ""))
16807 (match_operand:DF 3 "register_operand" "")
16808 (match_operand:DF 4 "nonimmediate_operand" "")))
16809 (clobber (reg:CC 17))]
16810 "SSE_REG_P (operands[0]) && reload_completed
16811 && ((operands_match_p (operands[1], operands[3])
16812 && operands_match_p (operands[2], operands[4]))
16813 || (operands_match_p (operands[1], operands[4])
16814 && operands_match_p (operands[2], operands[3])))"
16815 [(set (match_dup 0)
16816 (if_then_else:DF (gt (match_dup 1)
16817 (match_dup 2))
16818 (match_dup 1)
16819 (match_dup 2)))])
16820
16821(define_split
16822 [(set (match_operand:DF 0 "fp_register_operand" "")
16823 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16824 (match_operand:DF 2 "register_operand" ""))
16825 (match_operand:DF 3 "register_operand" "")
16826 (match_operand:DF 4 "register_operand" "")))
16827 (clobber (reg:CC 17))]
16828 "reload_completed
16829 && ((operands_match_p (operands[1], operands[3])
16830 && operands_match_p (operands[2], operands[4]))
16831 || (operands_match_p (operands[1], operands[4])
16832 && operands_match_p (operands[2], operands[3])))"
16833 [(set (reg:CCFP 17)
16834 (compare:CCFP (match_dup 1)
16835 (match_dup 2)))
16836 (set (match_dup 0)
16837 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16838 (match_dup 1)
16839 (match_dup 2)))])
16840
16841(define_insn "*maxdf_sse"
16842 [(set (match_operand:DF 0 "register_operand" "=Y")
16843 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16844 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16845 (match_dup 1)
16846 (match_dup 2)))]
16847 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16848 "maxsd\t{%2, %0|%0, %2}"
16849 [(set_attr "type" "sse")
16850 (set_attr "mode" "DF")])
16851
16852;; Misc patterns (?)
16853
16854;; This pattern exists to put a dependency on all ebp-based memory accesses.
16855;; Otherwise there will be nothing to keep
16856;;
16857;; [(set (reg ebp) (reg esp))]
16858;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16859;; (clobber (eflags)]
16860;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16861;;
16862;; in proper program order.
16863(define_insn "pro_epilogue_adjust_stack_1"
16864 [(set (match_operand:SI 0 "register_operand" "=r,r")
16865 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16866 (match_operand:SI 2 "immediate_operand" "i,i")))
16867 (clobber (reg:CC 17))
16868 (clobber (mem:BLK (scratch)))]
16869 "!TARGET_64BIT"
16870{
16871 switch (get_attr_type (insn))
16872 {
16873 case TYPE_IMOV:
16874 return "mov{l}\t{%1, %0|%0, %1}";
16875
16876 case TYPE_ALU:
16877 if (GET_CODE (operands[2]) == CONST_INT
16878 && (INTVAL (operands[2]) == 128
16879 || (INTVAL (operands[2]) < 0
16880 && INTVAL (operands[2]) != -128)))
16881 {
16882 operands[2] = GEN_INT (-INTVAL (operands[2]));
16883 return "sub{l}\t{%2, %0|%0, %2}";
16884 }
16885 return "add{l}\t{%2, %0|%0, %2}";
16886
16887 case TYPE_LEA:
16888 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16889 return "lea{l}\t{%a2, %0|%0, %a2}";
16890
16891 default:
16892 abort ();
16893 }
16894}
16895 [(set (attr "type")
16896 (cond [(eq_attr "alternative" "0")
16897 (const_string "alu")
16898 (match_operand:SI 2 "const0_operand" "")
16899 (const_string "imov")
16900 ]
16901 (const_string "lea")))
16902 (set_attr "mode" "SI")])
16903
16904(define_insn "pro_epilogue_adjust_stack_rex64"
16905 [(set (match_operand:DI 0 "register_operand" "=r,r")
16906 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16907 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16908 (clobber (reg:CC 17))
16909 (clobber (mem:BLK (scratch)))]
16910 "TARGET_64BIT"
16911{
16912 switch (get_attr_type (insn))
16913 {
16914 case TYPE_IMOV:
16915 return "mov{q}\t{%1, %0|%0, %1}";
16916
16917 case TYPE_ALU:
16918 if (GET_CODE (operands[2]) == CONST_INT
16919 /* Avoid overflows. */
16920 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16921 && (INTVAL (operands[2]) == 128
16922 || (INTVAL (operands[2]) < 0
16923 && INTVAL (operands[2]) != -128)))
16924 {
16925 operands[2] = GEN_INT (-INTVAL (operands[2]));
16926 return "sub{q}\t{%2, %0|%0, %2}";
16927 }
16928 return "add{q}\t{%2, %0|%0, %2}";
16929
16930 case TYPE_LEA:
16931 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16932 return "lea{q}\t{%a2, %0|%0, %a2}";
16933
16934 default:
16935 abort ();
16936 }
16937}
16938 [(set (attr "type")
16939 (cond [(eq_attr "alternative" "0")
16940 (const_string "alu")
16941 (match_operand:DI 2 "const0_operand" "")
16942 (const_string "imov")
16943 ]
16944 (const_string "lea")))
16945 (set_attr "mode" "DI")])
16946
16947(define_insn "pro_epilogue_adjust_stack_rex64_2"
16948 [(set (match_operand:DI 0 "register_operand" "=r,r")
16949 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16950 (match_operand:DI 3 "immediate_operand" "i,i")))
16951 (use (match_operand:DI 2 "register_operand" "r,r"))
16952 (clobber (reg:CC 17))
16953 (clobber (mem:BLK (scratch)))]
16954 "TARGET_64BIT"
16955{
16956 switch (get_attr_type (insn))
16957 {
16958 case TYPE_ALU:
16959 return "add{q}\t{%2, %0|%0, %2}";
16960
16961 case TYPE_LEA:
16962 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16963 return "lea{q}\t{%a2, %0|%0, %a2}";
16964
16965 default:
16966 abort ();
16967 }
16968}
16969 [(set_attr "type" "alu,lea")
16970 (set_attr "mode" "DI")])
16971
16972;; Placeholder for the conditional moves. This one is split either to SSE
16973;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16974;; fact is that compares supported by the cmp??ss instructions are exactly
16975;; swapped of those supported by cmove sequence.
16976;; The EQ/NE comparisons also needs bit care, since they are not directly
16977;; supported by i387 comparisons and we do need to emit two conditional moves
16978;; in tandem.
16979
16980(define_insn "sse_movsfcc"
16981 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16982 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16983 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16984 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16985 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16986 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16987 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16988 (clobber (reg:CC 17))]
16989 "TARGET_SSE
16990 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16991 /* Avoid combine from being smart and converting min/max
16992 instruction patterns into conditional moves. */
16993 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16994 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16995 || !rtx_equal_p (operands[4], operands[2])
16996 || !rtx_equal_p (operands[5], operands[3]))
16997 && (!TARGET_IEEE_FP
16998 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16999 "#")
17000
17001(define_insn "sse_movsfcc_eq"
17002 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17003 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17004 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17005 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17006 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17007 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17008 (clobber (reg:CC 17))]
17009 "TARGET_SSE
17010 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17011 "#")
17012
17013(define_insn "sse_movdfcc"
17014 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
17015 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17016 [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
17017 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
17018 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
17019 (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
17020 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17021 (clobber (reg:CC 17))]
17022 "TARGET_SSE2
17023 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17024 /* Avoid combine from being smart and converting min/max
17025 instruction patterns into conditional moves. */
17026 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17027 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17028 || !rtx_equal_p (operands[4], operands[2])
17029 || !rtx_equal_p (operands[5], operands[3]))
17030 && (!TARGET_IEEE_FP
17031 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17032 "#")
17033
17034(define_insn "sse_movdfcc_eq"
17035 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17036 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17037 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17038 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17039 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17040 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17041 (clobber (reg:CC 17))]
17042 "TARGET_SSE
17043 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17044 "#")
17045
17046;; For non-sse moves just expand the usual cmove sequence.
17047(define_split
17048 [(set (match_operand 0 "register_operand" "")
17049 (if_then_else (match_operator 1 "comparison_operator"
17050 [(match_operand 4 "nonimmediate_operand" "")
17051 (match_operand 5 "register_operand" "")])
17052 (match_operand 2 "nonimmediate_operand" "")
17053 (match_operand 3 "nonimmediate_operand" "")))
17054 (clobber (match_operand 6 "" ""))
17055 (clobber (reg:CC 17))]
17056 "!SSE_REG_P (operands[0]) && reload_completed
17057 && (GET_MODE (operands[0]) == SFmode
17058 || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
17059 [(const_int 0)]
17060{
17061 ix86_compare_op0 = operands[5];
17062 ix86_compare_op1 = operands[4];
17063 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17064 VOIDmode, operands[5], operands[4]);
17065 ix86_expand_fp_movcc (operands);
17066 DONE;
17067})
17068
17069;; Split SSE based conditional move into sequence:
17070;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17071;; and op2, op0 - zero op2 if comparison was false
17072;; nand op0, op3 - load op3 to op0 if comparison was false
17073;; or op2, op0 - get the nonzero one into the result.
17074(define_split
17075 [(set (match_operand:SF 0 "register_operand" "")
17076 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17077 [(match_operand:SF 4 "register_operand" "")
17078 (match_operand:SF 5 "nonimmediate_operand" "")])
17079 (match_operand:SF 2 "register_operand" "")
17080 (match_operand:SF 3 "register_operand" "")))
17081 (clobber (match_operand 6 "" ""))
17082 (clobber (reg:CC 17))]
17083 "SSE_REG_P (operands[0]) && reload_completed"
17084 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17085 (set (match_dup 2) (and:V4SF (match_dup 2)
17086 (match_dup 8)))
17087 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17088 (match_dup 3)))
17089 (set (match_dup 0) (ior:V4SF (match_dup 6)
17090 (match_dup 7)))]
17091{
17092 /* If op2 == op3, op3 would be clobbered before it is used. */
17093 if (operands_match_p (operands[2], operands[3]))
17094 {
17095 emit_move_insn (operands[0], operands[2]);
17096 DONE;
17097 }
17098
17099 PUT_MODE (operands[1], GET_MODE (operands[0]));
17100 if (operands_match_p (operands[0], operands[4]))
17101 operands[6] = operands[4], operands[7] = operands[2];
17102 else
17103 operands[6] = operands[2], operands[7] = operands[4];
17104 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17105 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17106 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17107 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17108 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17109 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17110})
17111
17112(define_split
17113 [(set (match_operand:DF 0 "register_operand" "")
17114 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17115 [(match_operand:DF 4 "register_operand" "")
17116 (match_operand:DF 5 "nonimmediate_operand" "")])
17117 (match_operand:DF 2 "register_operand" "")
17118 (match_operand:DF 3 "register_operand" "")))
17119 (clobber (match_operand 6 "" ""))
17120 (clobber (reg:CC 17))]
17121 "SSE_REG_P (operands[0]) && reload_completed"
17122 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17123 (set (match_dup 2) (and:V2DF (match_dup 2)
17124 (match_dup 8)))
17125 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17126 (match_dup 3)))
17127 (set (match_dup 0) (ior:V2DF (match_dup 6)
17128 (match_dup 7)))]
17129{
17130 if (GET_MODE (operands[2]) == DFmode
17131 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17132 {
17133 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17134 emit_insn (gen_sse2_unpcklpd (op, op, op));
17135 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17136 emit_insn (gen_sse2_unpcklpd (op, op, op));
17137 }
17138
17139 /* If op2 == op3, op3 would be clobbered before it is used. */
17140 if (operands_match_p (operands[2], operands[3]))
17141 {
17142 emit_move_insn (operands[0], operands[2]);
17143 DONE;
17144 }
17145
17146 PUT_MODE (operands[1], GET_MODE (operands[0]));
17147 if (operands_match_p (operands[0], operands[4]))
17148 operands[6] = operands[4], operands[7] = operands[2];
17149 else
17150 operands[6] = operands[2], operands[7] = operands[4];
17151 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17152 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17153 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17154 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17155 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17156 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17157})
17158
17159;; Special case of conditional move we can handle effectively.
17160;; Do not brother with the integer/floating point case, since these are
17161;; bot considerably slower, unlike in the generic case.
17162(define_insn "*sse_movsfcc_const0_1"
17163 [(set (match_operand:SF 0 "register_operand" "=&x")
17164 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17165 [(match_operand:SF 4 "register_operand" "0")
17166 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17167 (match_operand:SF 2 "register_operand" "x")
17168 (match_operand:SF 3 "const0_operand" "X")))]
17169 "TARGET_SSE"
17170 "#")
17171
17172(define_insn "*sse_movsfcc_const0_2"
17173 [(set (match_operand:SF 0 "register_operand" "=&x")
17174 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17175 [(match_operand:SF 4 "register_operand" "0")
17176 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17177 (match_operand:SF 2 "const0_operand" "X")
17178 (match_operand:SF 3 "register_operand" "x")))]
17179 "TARGET_SSE"
17180 "#")
17181
17182(define_insn "*sse_movsfcc_const0_3"
17183 [(set (match_operand:SF 0 "register_operand" "=&x")
17184 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17185 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17186 (match_operand:SF 5 "register_operand" "0")])
17187 (match_operand:SF 2 "register_operand" "x")
17188 (match_operand:SF 3 "const0_operand" "X")))]
17189 "TARGET_SSE"
17190 "#")
17191
17192(define_insn "*sse_movsfcc_const0_4"
17193 [(set (match_operand:SF 0 "register_operand" "=&x")
17194 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17195 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17196 (match_operand:SF 5 "register_operand" "0")])
17197 (match_operand:SF 2 "const0_operand" "X")
17198 (match_operand:SF 3 "register_operand" "x")))]
17199 "TARGET_SSE"
17200 "#")
17201
17202(define_insn "*sse_movdfcc_const0_1"
17203 [(set (match_operand:DF 0 "register_operand" "=&Y")
17204 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17205 [(match_operand:DF 4 "register_operand" "0")
17206 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17207 (match_operand:DF 2 "register_operand" "Y")
17208 (match_operand:DF 3 "const0_operand" "X")))]
17209 "TARGET_SSE2"
17210 "#")
17211
17212(define_insn "*sse_movdfcc_const0_2"
17213 [(set (match_operand:DF 0 "register_operand" "=&Y")
17214 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17215 [(match_operand:DF 4 "register_operand" "0")
17216 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17217 (match_operand:DF 2 "const0_operand" "X")
17218 (match_operand:DF 3 "register_operand" "Y")))]
17219 "TARGET_SSE2"
17220 "#")
17221
17222(define_insn "*sse_movdfcc_const0_3"
17223 [(set (match_operand:DF 0 "register_operand" "=&Y")
17224 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17225 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17226 (match_operand:DF 5 "register_operand" "0")])
17227 (match_operand:DF 2 "register_operand" "Y")
17228 (match_operand:DF 3 "const0_operand" "X")))]
17229 "TARGET_SSE2"
17230 "#")
17231
17232(define_insn "*sse_movdfcc_const0_4"
17233 [(set (match_operand:DF 0 "register_operand" "=&Y")
17234 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17235 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17236 (match_operand:DF 5 "register_operand" "0")])
17237 (match_operand:DF 2 "const0_operand" "X")
17238 (match_operand:DF 3 "register_operand" "Y")))]
17239 "TARGET_SSE2"
17240 "#")
17241
17242(define_split
17243 [(set (match_operand:SF 0 "register_operand" "")
17244 (if_then_else:SF (match_operator 1 "comparison_operator"
17245 [(match_operand:SF 4 "nonimmediate_operand" "")
17246 (match_operand:SF 5 "nonimmediate_operand" "")])
17247 (match_operand:SF 2 "nonmemory_operand" "")
17248 (match_operand:SF 3 "nonmemory_operand" "")))]
17249 "SSE_REG_P (operands[0]) && reload_completed
17250 && (const0_operand (operands[2], GET_MODE (operands[0]))
17251 || const0_operand (operands[3], GET_MODE (operands[0])))"
17252 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17253 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17254{
17255 PUT_MODE (operands[1], GET_MODE (operands[0]));
17256 if (!sse_comparison_operator (operands[1], VOIDmode)
17257 || !rtx_equal_p (operands[0], operands[4]))
17258 {
17259 rtx tmp = operands[5];
17260 operands[5] = operands[4];
17261 operands[4] = tmp;
17262 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17263 }
17264 if (!rtx_equal_p (operands[0], operands[4]))
17265 abort ();
17266 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17267 if (const0_operand (operands[2], GET_MODE (operands[2])))
17268 {
17269 operands[7] = operands[3];
17270 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17271 }
17272 else
17273 {
17274 operands[7] = operands[2];
17275 operands[6] = operands[8];
17276 }
17277 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17278})
17279
17280(define_split
17281 [(set (match_operand:DF 0 "register_operand" "")
17282 (if_then_else:DF (match_operator 1 "comparison_operator"
17283 [(match_operand:DF 4 "nonimmediate_operand" "")
17284 (match_operand:DF 5 "nonimmediate_operand" "")])
17285 (match_operand:DF 2 "nonmemory_operand" "")
17286 (match_operand:DF 3 "nonmemory_operand" "")))]
17287 "SSE_REG_P (operands[0]) && reload_completed
17288 && (const0_operand (operands[2], GET_MODE (operands[0]))
17289 || const0_operand (operands[3], GET_MODE (operands[0])))"
17290 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17291 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17292{
17293 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17294 && GET_MODE (operands[2]) == DFmode)
17295 {
17296 if (REG_P (operands[2]))
17297 {
17298 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17299 emit_insn (gen_sse2_unpcklpd (op, op, op));
17300 }
17301 if (REG_P (operands[3]))
17302 {
17303 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17304 emit_insn (gen_sse2_unpcklpd (op, op, op));
17305 }
17306 }
17307 PUT_MODE (operands[1], GET_MODE (operands[0]));
17308 if (!sse_comparison_operator (operands[1], VOIDmode)
17309 || !rtx_equal_p (operands[0], operands[4]))
17310 {
17311 rtx tmp = operands[5];
17312 operands[5] = operands[4];
17313 operands[4] = tmp;
17314 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17315 }
17316 if (!rtx_equal_p (operands[0], operands[4]))
17317 abort ();
17318 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17319 if (const0_operand (operands[2], GET_MODE (operands[2])))
17320 {
17321 operands[7] = operands[3];
17322 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
17323 }
17324 else
17325 {
17326 operands[7] = operands[2];
17327 operands[6] = operands[8];
17328 }
17329 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17330})
17331
17332(define_expand "allocate_stack_worker"
17333 [(match_operand:SI 0 "register_operand" "")]
17334 "TARGET_STACK_PROBE"
17335{
17336 if (reload_completed)
17337 {
17338 if (TARGET_64BIT)
17339 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17340 else
17341 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17342 }
17343 else
17344 {
17345 if (TARGET_64BIT)
17346 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17347 else
17348 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17349 }
17350 DONE;
17351})
17352
17353(define_insn "allocate_stack_worker_1"
17354 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17355 UNSPECV_STACK_PROBE)
17356 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17357 (clobber (match_scratch:SI 1 "=0"))
17358 (clobber (reg:CC 17))]
17359 "!TARGET_64BIT && TARGET_STACK_PROBE"
17360 "call\t__alloca"
17361 [(set_attr "type" "multi")
17362 (set_attr "length" "5")])
17363
17364(define_expand "allocate_stack_worker_postreload"
17365 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
17366 UNSPECV_STACK_PROBE)
17367 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17368 (clobber (match_dup 0))
17369 (clobber (reg:CC 17))])]
17370 ""
17371 "")
17372
17373(define_insn "allocate_stack_worker_rex64"
17374 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17375 UNSPECV_STACK_PROBE)
17376 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17377 (clobber (match_scratch:DI 1 "=0"))
17378 (clobber (reg:CC 17))]
17379 "TARGET_64BIT && TARGET_STACK_PROBE"
17380 "call\t__alloca"
17381 [(set_attr "type" "multi")
17382 (set_attr "length" "5")])
17383
17384(define_expand "allocate_stack_worker_rex64_postreload"
17385 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
17386 UNSPECV_STACK_PROBE)
17387 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17388 (clobber (match_dup 0))
17389 (clobber (reg:CC 17))])]
17390 ""
17391 "")
17392
17393(define_expand "allocate_stack"
17394 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17395 (minus:SI (reg:SI 7)
17396 (match_operand:SI 1 "general_operand" "")))
17397 (clobber (reg:CC 17))])
17398 (parallel [(set (reg:SI 7)
17399 (minus:SI (reg:SI 7) (match_dup 1)))
17400 (clobber (reg:CC 17))])]
17401 "TARGET_STACK_PROBE"
17402{
17403#ifdef CHECK_STACK_LIMIT
17404 if (GET_CODE (operands[1]) == CONST_INT
17405 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17406 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17407 operands[1]));
17408 else
17409#endif
17410 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17411 operands[1])));
17412
17413 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17414 DONE;
17415})
17416
17417(define_expand "builtin_setjmp_receiver"
17418 [(label_ref (match_operand 0 "" ""))]
17419 "!TARGET_64BIT && flag_pic"
17420{
17421 emit_insn (gen_set_got (pic_offset_table_rtx));
17422 DONE;
17423})
17424
17425;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17426
17427(define_split
17428 [(set (match_operand 0 "register_operand" "")
17429 (match_operator 3 "promotable_binary_operator"
17430 [(match_operand 1 "register_operand" "")
17431 (match_operand 2 "aligned_operand" "")]))
17432 (clobber (reg:CC 17))]
17433 "! TARGET_PARTIAL_REG_STALL && reload_completed
17434 && ((GET_MODE (operands[0]) == HImode
17435 && ((!optimize_size && !TARGET_FAST_PREFIX)
17436 || GET_CODE (operands[2]) != CONST_INT
17437 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17438 || (GET_MODE (operands[0]) == QImode
17439 && (TARGET_PROMOTE_QImode || optimize_size)))"
17440 [(parallel [(set (match_dup 0)
17441 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17442 (clobber (reg:CC 17))])]
17443 "operands[0] = gen_lowpart (SImode, operands[0]);
17444 operands[1] = gen_lowpart (SImode, operands[1]);
17445 if (GET_CODE (operands[3]) != ASHIFT)
17446 operands[2] = gen_lowpart (SImode, operands[2]);
17447 PUT_MODE (operands[3], SImode);")
17448
17449; Promote the QImode tests, as i386 has encoding of the AND
17450; instruction with 32-bit sign-extended immediate and thus the
17451; instruction size is unchanged, except in the %eax case for
17452; which it is increased by one byte, hence the ! optimize_size.
17453(define_split
17454 [(set (match_operand 0 "flags_reg_operand" "")
17455 (match_operator 2 "compare_operator"
17456 [(and (match_operand 3 "aligned_operand" "")
17457 (match_operand 4 "const_int_operand" ""))
17458 (const_int 0)]))
17459 (set (match_operand 1 "register_operand" "")
17460 (and (match_dup 3) (match_dup 4)))]
17461 "! TARGET_PARTIAL_REG_STALL && reload_completed
17462 /* Ensure that the operand will remain sign-extended immediate. */
17463 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
17464 && ! optimize_size
17465 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17466 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
17467 [(parallel [(set (match_dup 0)
17468 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17469 (const_int 0)]))
17470 (set (match_dup 1)
17471 (and:SI (match_dup 3) (match_dup 4)))])]
17472{
17473 operands[4]
17474 = gen_int_mode (INTVAL (operands[4])
17475 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17476 operands[1] = gen_lowpart (SImode, operands[1]);
17477 operands[3] = gen_lowpart (SImode, operands[3]);
17478})
17479
17480; Don't promote the QImode tests, as i386 doesn't have encoding of
17481; the TEST instruction with 32-bit sign-extended immediate and thus
17482; the instruction size would at least double, which is not what we
17483; want even with ! optimize_size.
17484(define_split
17485 [(set (match_operand 0 "flags_reg_operand" "")
17486 (match_operator 1 "compare_operator"
17487 [(and (match_operand:HI 2 "aligned_operand" "")
17488 (match_operand:HI 3 "const_int_operand" ""))
17489 (const_int 0)]))]
17490 "! TARGET_PARTIAL_REG_STALL && reload_completed
17491 /* Ensure that the operand will remain sign-extended immediate. */
17492 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
17493 && ! TARGET_FAST_PREFIX
17494 && ! optimize_size"
17495 [(set (match_dup 0)
17496 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17497 (const_int 0)]))]
17498{
17499 operands[3]
17500 = gen_int_mode (INTVAL (operands[3])
17501 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17502 operands[2] = gen_lowpart (SImode, operands[2]);
17503})
17504
17505(define_split
17506 [(set (match_operand 0 "register_operand" "")
17507 (neg (match_operand 1 "register_operand" "")))
17508 (clobber (reg:CC 17))]
17509 "! TARGET_PARTIAL_REG_STALL && reload_completed
17510 && (GET_MODE (operands[0]) == HImode
17511 || (GET_MODE (operands[0]) == QImode
17512 && (TARGET_PROMOTE_QImode || optimize_size)))"
17513 [(parallel [(set (match_dup 0)
17514 (neg:SI (match_dup 1)))
17515 (clobber (reg:CC 17))])]
17516 "operands[0] = gen_lowpart (SImode, operands[0]);
17517 operands[1] = gen_lowpart (SImode, operands[1]);")
17518
17519(define_split
17520 [(set (match_operand 0 "register_operand" "")
17521 (not (match_operand 1 "register_operand" "")))]
17522 "! TARGET_PARTIAL_REG_STALL && reload_completed
17523 && (GET_MODE (operands[0]) == HImode
17524 || (GET_MODE (operands[0]) == QImode
17525 && (TARGET_PROMOTE_QImode || optimize_size)))"
17526 [(set (match_dup 0)
17527 (not:SI (match_dup 1)))]
17528 "operands[0] = gen_lowpart (SImode, operands[0]);
17529 operands[1] = gen_lowpart (SImode, operands[1]);")
17530
17531(define_split
17532 [(set (match_operand 0 "register_operand" "")
17533 (if_then_else (match_operator 1 "comparison_operator"
17534 [(reg 17) (const_int 0)])
17535 (match_operand 2 "register_operand" "")
17536 (match_operand 3 "register_operand" "")))]
17537 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17538 && (GET_MODE (operands[0]) == HImode
17539 || (GET_MODE (operands[0]) == QImode
17540 && (TARGET_PROMOTE_QImode || optimize_size)))"
17541 [(set (match_dup 0)
17542 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17543 "operands[0] = gen_lowpart (SImode, operands[0]);
17544 operands[2] = gen_lowpart (SImode, operands[2]);
17545 operands[3] = gen_lowpart (SImode, operands[3]);")
17546
17547
17548;; RTL Peephole optimizations, run before sched2. These primarily look to
17549;; transform a complex memory operation into two memory to register operations.
17550
17551;; Don't push memory operands
17552(define_peephole2
17553 [(set (match_operand:SI 0 "push_operand" "")
17554 (match_operand:SI 1 "memory_operand" ""))
17555 (match_scratch:SI 2 "r")]
17556 "! optimize_size && ! TARGET_PUSH_MEMORY"
17557 [(set (match_dup 2) (match_dup 1))
17558 (set (match_dup 0) (match_dup 2))]
17559 "")
17560
17561(define_peephole2
17562 [(set (match_operand:DI 0 "push_operand" "")
17563 (match_operand:DI 1 "memory_operand" ""))
17564 (match_scratch:DI 2 "r")]
17565 "! optimize_size && ! TARGET_PUSH_MEMORY"
17566 [(set (match_dup 2) (match_dup 1))
17567 (set (match_dup 0) (match_dup 2))]
17568 "")
17569
17570;; We need to handle SFmode only, because DFmode and XFmode is split to
17571;; SImode pushes.
17572(define_peephole2
17573 [(set (match_operand:SF 0 "push_operand" "")
17574 (match_operand:SF 1 "memory_operand" ""))
17575 (match_scratch:SF 2 "r")]
17576 "! optimize_size && ! TARGET_PUSH_MEMORY"
17577 [(set (match_dup 2) (match_dup 1))
17578 (set (match_dup 0) (match_dup 2))]
17579 "")
17580
17581(define_peephole2
17582 [(set (match_operand:HI 0 "push_operand" "")
17583 (match_operand:HI 1 "memory_operand" ""))
17584 (match_scratch:HI 2 "r")]
17585 "! optimize_size && ! TARGET_PUSH_MEMORY"
17586 [(set (match_dup 2) (match_dup 1))
17587 (set (match_dup 0) (match_dup 2))]
17588 "")
17589
17590(define_peephole2
17591 [(set (match_operand:QI 0 "push_operand" "")
17592 (match_operand:QI 1 "memory_operand" ""))
17593 (match_scratch:QI 2 "q")]
17594 "! optimize_size && ! TARGET_PUSH_MEMORY"
17595 [(set (match_dup 2) (match_dup 1))
17596 (set (match_dup 0) (match_dup 2))]
17597 "")
17598
17599;; Don't move an immediate directly to memory when the instruction
17600;; gets too big.
17601(define_peephole2
17602 [(match_scratch:SI 1 "r")
17603 (set (match_operand:SI 0 "memory_operand" "")
17604 (const_int 0))]
17605 "! optimize_size
17606 && ! TARGET_USE_MOV0
17607 && TARGET_SPLIT_LONG_MOVES
17608 && get_attr_length (insn) >= ix86_cost->large_insn
17609 && peep2_regno_dead_p (0, FLAGS_REG)"
17610 [(parallel [(set (match_dup 1) (const_int 0))
17611 (clobber (reg:CC 17))])
17612 (set (match_dup 0) (match_dup 1))]
17613 "")
17614
17615(define_peephole2
17616 [(match_scratch:HI 1 "r")
17617 (set (match_operand:HI 0 "memory_operand" "")
17618 (const_int 0))]
17619 "! optimize_size
17620 && ! TARGET_USE_MOV0
17621 && TARGET_SPLIT_LONG_MOVES
17622 && get_attr_length (insn) >= ix86_cost->large_insn
17623 && peep2_regno_dead_p (0, FLAGS_REG)"
17624 [(parallel [(set (match_dup 2) (const_int 0))
17625 (clobber (reg:CC 17))])
17626 (set (match_dup 0) (match_dup 1))]
17627 "operands[2] = gen_lowpart (SImode, operands[1]);")
17628
17629(define_peephole2
17630 [(match_scratch:QI 1 "q")
17631 (set (match_operand:QI 0 "memory_operand" "")
17632 (const_int 0))]
17633 "! optimize_size
17634 && ! TARGET_USE_MOV0
17635 && TARGET_SPLIT_LONG_MOVES
17636 && get_attr_length (insn) >= ix86_cost->large_insn
17637 && peep2_regno_dead_p (0, FLAGS_REG)"
17638 [(parallel [(set (match_dup 2) (const_int 0))
17639 (clobber (reg:CC 17))])
17640 (set (match_dup 0) (match_dup 1))]
17641 "operands[2] = gen_lowpart (SImode, operands[1]);")
17642
17643(define_peephole2
17644 [(match_scratch:SI 2 "r")
17645 (set (match_operand:SI 0 "memory_operand" "")
17646 (match_operand:SI 1 "immediate_operand" ""))]
17647 "! optimize_size
17648 && get_attr_length (insn) >= ix86_cost->large_insn
17649 && TARGET_SPLIT_LONG_MOVES"
17650 [(set (match_dup 2) (match_dup 1))
17651 (set (match_dup 0) (match_dup 2))]
17652 "")
17653
17654(define_peephole2
17655 [(match_scratch:HI 2 "r")
17656 (set (match_operand:HI 0 "memory_operand" "")
17657 (match_operand:HI 1 "immediate_operand" ""))]
17658 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17659 && TARGET_SPLIT_LONG_MOVES"
17660 [(set (match_dup 2) (match_dup 1))
17661 (set (match_dup 0) (match_dup 2))]
17662 "")
17663
17664(define_peephole2
17665 [(match_scratch:QI 2 "q")
17666 (set (match_operand:QI 0 "memory_operand" "")
17667 (match_operand:QI 1 "immediate_operand" ""))]
17668 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17669 && TARGET_SPLIT_LONG_MOVES"
17670 [(set (match_dup 2) (match_dup 1))
17671 (set (match_dup 0) (match_dup 2))]
17672 "")
17673
17674;; Don't compare memory with zero, load and use a test instead.
17675(define_peephole2
17676 [(set (match_operand 0 "flags_reg_operand" "")
17677 (match_operator 1 "compare_operator"
17678 [(match_operand:SI 2 "memory_operand" "")
17679 (const_int 0)]))
17680 (match_scratch:SI 3 "r")]
17681 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17682 [(set (match_dup 3) (match_dup 2))
17683 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17684 "")
17685
17686;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17687;; Don't split NOTs with a displacement operand, because resulting XOR
17688;; will not be pairable anyway.
17689;;
17690;; On AMD K6, NOT is vector decoded with memory operand that can not be
17691;; represented using a modRM byte. The XOR replacement is long decoded,
17692;; so this split helps here as well.
17693;;
17694;; Note: Can't do this as a regular split because we can't get proper
17695;; lifetime information then.
17696
17697(define_peephole2
17698 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17699 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17700 "!optimize_size
17701 && peep2_regno_dead_p (0, FLAGS_REG)
17702 && ((TARGET_PENTIUM
17703 && (GET_CODE (operands[0]) != MEM
17704 || !memory_displacement_operand (operands[0], SImode)))
17705 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17706 [(parallel [(set (match_dup 0)
17707 (xor:SI (match_dup 1) (const_int -1)))
17708 (clobber (reg:CC 17))])]
17709 "")
17710
17711(define_peephole2
17712 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17713 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17714 "!optimize_size
17715 && peep2_regno_dead_p (0, FLAGS_REG)
17716 && ((TARGET_PENTIUM
17717 && (GET_CODE (operands[0]) != MEM
17718 || !memory_displacement_operand (operands[0], HImode)))
17719 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17720 [(parallel [(set (match_dup 0)
17721 (xor:HI (match_dup 1) (const_int -1)))
17722 (clobber (reg:CC 17))])]
17723 "")
17724
17725(define_peephole2
17726 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17727 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17728 "!optimize_size
17729 && peep2_regno_dead_p (0, FLAGS_REG)
17730 && ((TARGET_PENTIUM
17731 && (GET_CODE (operands[0]) != MEM
17732 || !memory_displacement_operand (operands[0], QImode)))
17733 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17734 [(parallel [(set (match_dup 0)
17735 (xor:QI (match_dup 1) (const_int -1)))
17736 (clobber (reg:CC 17))])]
17737 "")
17738
17739;; Non pairable "test imm, reg" instructions can be translated to
17740;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17741;; byte opcode instead of two, have a short form for byte operands),
17742;; so do it for other CPUs as well. Given that the value was dead,
17743;; this should not create any new dependencies. Pass on the sub-word
17744;; versions if we're concerned about partial register stalls.
17745
17746(define_peephole2
17747 [(set (match_operand 0 "flags_reg_operand" "")
17748 (match_operator 1 "compare_operator"
17749 [(and:SI (match_operand:SI 2 "register_operand" "")
17750 (match_operand:SI 3 "immediate_operand" ""))
17751 (const_int 0)]))]
17752 "ix86_match_ccmode (insn, CCNOmode)
17753 && (true_regnum (operands[2]) != 0
17754 || (GET_CODE (operands[3]) == CONST_INT
17755 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
17756 && peep2_reg_dead_p (1, operands[2])"
17757 [(parallel
17758 [(set (match_dup 0)
17759 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17760 (const_int 0)]))
17761 (set (match_dup 2)
17762 (and:SI (match_dup 2) (match_dup 3)))])]
17763 "")
17764
17765;; We don't need to handle HImode case, because it will be promoted to SImode
17766;; on ! TARGET_PARTIAL_REG_STALL
17767
17768(define_peephole2
17769 [(set (match_operand 0 "flags_reg_operand" "")
17770 (match_operator 1 "compare_operator"
17771 [(and:QI (match_operand:QI 2 "register_operand" "")
17772 (match_operand:QI 3 "immediate_operand" ""))
17773 (const_int 0)]))]
17774 "! TARGET_PARTIAL_REG_STALL
17775 && ix86_match_ccmode (insn, CCNOmode)
17776 && true_regnum (operands[2]) != 0
17777 && peep2_reg_dead_p (1, operands[2])"
17778 [(parallel
17779 [(set (match_dup 0)
17780 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17781 (const_int 0)]))
17782 (set (match_dup 2)
17783 (and:QI (match_dup 2) (match_dup 3)))])]
17784 "")
17785
17786(define_peephole2
17787 [(set (match_operand 0 "flags_reg_operand" "")
17788 (match_operator 1 "compare_operator"
17789 [(and:SI
17790 (zero_extract:SI
17791 (match_operand 2 "ext_register_operand" "")
17792 (const_int 8)
17793 (const_int 8))
17794 (match_operand 3 "const_int_operand" ""))
17795 (const_int 0)]))]
17796 "! TARGET_PARTIAL_REG_STALL
17797 && ix86_match_ccmode (insn, CCNOmode)
17798 && true_regnum (operands[2]) != 0
17799 && peep2_reg_dead_p (1, operands[2])"
17800 [(parallel [(set (match_dup 0)
17801 (match_op_dup 1
17802 [(and:SI
17803 (zero_extract:SI
17804 (match_dup 2)
17805 (const_int 8)
17806 (const_int 8))
17807 (match_dup 3))
17808 (const_int 0)]))
17809 (set (zero_extract:SI (match_dup 2)
17810 (const_int 8)
17811 (const_int 8))
17812 (and:SI
17813 (zero_extract:SI
17814 (match_dup 2)
17815 (const_int 8)
17816 (const_int 8))
17817 (match_dup 3)))])]
17818 "")
17819
17820;; Don't do logical operations with memory inputs.
17821(define_peephole2
17822 [(match_scratch:SI 2 "r")
17823 (parallel [(set (match_operand:SI 0 "register_operand" "")
17824 (match_operator:SI 3 "arith_or_logical_operator"
17825 [(match_dup 0)
17826 (match_operand:SI 1 "memory_operand" "")]))
17827 (clobber (reg:CC 17))])]
17828 "! optimize_size && ! TARGET_READ_MODIFY"
17829 [(set (match_dup 2) (match_dup 1))
17830 (parallel [(set (match_dup 0)
17831 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17832 (clobber (reg:CC 17))])]
17833 "")
17834
17835(define_peephole2
17836 [(match_scratch:SI 2 "r")
17837 (parallel [(set (match_operand:SI 0 "register_operand" "")
17838 (match_operator:SI 3 "arith_or_logical_operator"
17839 [(match_operand:SI 1 "memory_operand" "")
17840 (match_dup 0)]))
17841 (clobber (reg:CC 17))])]
17842 "! optimize_size && ! TARGET_READ_MODIFY"
17843 [(set (match_dup 2) (match_dup 1))
17844 (parallel [(set (match_dup 0)
17845 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17846 (clobber (reg:CC 17))])]
17847 "")
17848
17849; Don't do logical operations with memory outputs
17850;
17851; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17852; instruction into two 1-uop insns plus a 2-uop insn. That last has
17853; the same decoder scheduling characteristics as the original.
17854
17855(define_peephole2
17856 [(match_scratch:SI 2 "r")
17857 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17858 (match_operator:SI 3 "arith_or_logical_operator"
17859 [(match_dup 0)
17860 (match_operand:SI 1 "nonmemory_operand" "")]))
17861 (clobber (reg:CC 17))])]
17862 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17863 [(set (match_dup 2) (match_dup 0))
17864 (parallel [(set (match_dup 2)
17865 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17866 (clobber (reg:CC 17))])
17867 (set (match_dup 0) (match_dup 2))]
17868 "")
17869
17870(define_peephole2
17871 [(match_scratch:SI 2 "r")
17872 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17873 (match_operator:SI 3 "arith_or_logical_operator"
17874 [(match_operand:SI 1 "nonmemory_operand" "")
17875 (match_dup 0)]))
17876 (clobber (reg:CC 17))])]
17877 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17878 [(set (match_dup 2) (match_dup 0))
17879 (parallel [(set (match_dup 2)
17880 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17881 (clobber (reg:CC 17))])
17882 (set (match_dup 0) (match_dup 2))]
17883 "")
17884
17885;; Attempt to always use XOR for zeroing registers.
17886(define_peephole2
17887 [(set (match_operand 0 "register_operand" "")
17888 (const_int 0))]
17889 "(GET_MODE (operands[0]) == QImode
17890 || GET_MODE (operands[0]) == HImode
17891 || GET_MODE (operands[0]) == SImode
17892 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17893 && (! TARGET_USE_MOV0 || optimize_size)
17894 && peep2_regno_dead_p (0, FLAGS_REG)"
17895 [(parallel [(set (match_dup 0) (const_int 0))
17896 (clobber (reg:CC 17))])]
17897 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17898 operands[0]);")
17899
17900(define_peephole2
17901 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17902 (const_int 0))]
17903 "(GET_MODE (operands[0]) == QImode
17904 || GET_MODE (operands[0]) == HImode)
17905 && (! TARGET_USE_MOV0 || optimize_size)
17906 && peep2_regno_dead_p (0, FLAGS_REG)"
17907 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17908 (clobber (reg:CC 17))])])
17909
17910;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17911(define_peephole2
17912 [(set (match_operand 0 "register_operand" "")
17913 (const_int -1))]
17914 "(GET_MODE (operands[0]) == HImode
17915 || GET_MODE (operands[0]) == SImode
17916 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17917 && (optimize_size || TARGET_PENTIUM)
17918 && peep2_regno_dead_p (0, FLAGS_REG)"
17919 [(parallel [(set (match_dup 0) (const_int -1))
17920 (clobber (reg:CC 17))])]
17921 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17922 operands[0]);")
17923
17924;; Attempt to convert simple leas to adds. These can be created by
17925;; move expanders.
17926(define_peephole2
17927 [(set (match_operand:SI 0 "register_operand" "")
17928 (plus:SI (match_dup 0)
17929 (match_operand:SI 1 "nonmemory_operand" "")))]
17930 "peep2_regno_dead_p (0, FLAGS_REG)"
17931 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17932 (clobber (reg:CC 17))])]
17933 "")
17934
17935(define_peephole2
17936 [(set (match_operand:SI 0 "register_operand" "")
17937 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17938 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17939 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17940 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17941 (clobber (reg:CC 17))])]
17942 "operands[2] = gen_lowpart (SImode, operands[2]);")
17943
17944(define_peephole2
17945 [(set (match_operand:DI 0 "register_operand" "")
17946 (plus:DI (match_dup 0)
17947 (match_operand:DI 1 "x86_64_general_operand" "")))]
17948 "peep2_regno_dead_p (0, FLAGS_REG)"
17949 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17950 (clobber (reg:CC 17))])]
17951 "")
17952
17953(define_peephole2
17954 [(set (match_operand:SI 0 "register_operand" "")
17955 (mult:SI (match_dup 0)
17956 (match_operand:SI 1 "const_int_operand" "")))]
17957 "exact_log2 (INTVAL (operands[1])) >= 0
17958 && peep2_regno_dead_p (0, FLAGS_REG)"
17959 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17960 (clobber (reg:CC 17))])]
17961 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17962
17963(define_peephole2
17964 [(set (match_operand:DI 0 "register_operand" "")
17965 (mult:DI (match_dup 0)
17966 (match_operand:DI 1 "const_int_operand" "")))]
17967 "exact_log2 (INTVAL (operands[1])) >= 0
17968 && peep2_regno_dead_p (0, FLAGS_REG)"
17969 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17970 (clobber (reg:CC 17))])]
17971 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17972
17973(define_peephole2
17974 [(set (match_operand:SI 0 "register_operand" "")
17975 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17976 (match_operand:DI 2 "const_int_operand" "")) 0))]
17977 "exact_log2 (INTVAL (operands[2])) >= 0
17978 && REGNO (operands[0]) == REGNO (operands[1])
17979 && peep2_regno_dead_p (0, FLAGS_REG)"
17980 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17981 (clobber (reg:CC 17))])]
17982 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17983
17984;; The ESP adjustments can be done by the push and pop instructions. Resulting
17985;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17986;; many CPUs it is also faster, since special hardware to avoid esp
17987;; dependencies is present.
17988
17989;; While some of these conversions may be done using splitters, we use peepholes
17990;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17991
17992;; Convert prologue esp subtractions to push.
17993;; We need register to push. In order to keep verify_flow_info happy we have
17994;; two choices
17995;; - use scratch and clobber it in order to avoid dependencies
17996;; - use already live register
17997;; We can't use the second way right now, since there is no reliable way how to
17998;; verify that given register is live. First choice will also most likely in
17999;; fewer dependencies. On the place of esp adjustments it is very likely that
18000;; call clobbered registers are dead. We may want to use base pointer as an
18001;; alternative when no register is available later.
18002
18003(define_peephole2
18004 [(match_scratch:SI 0 "r")
18005 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18006 (clobber (reg:CC 17))
18007 (clobber (mem:BLK (scratch)))])]
18008 "optimize_size || !TARGET_SUB_ESP_4"
18009 [(clobber (match_dup 0))
18010 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18011 (clobber (mem:BLK (scratch)))])])
18012
18013(define_peephole2
18014 [(match_scratch:SI 0 "r")
18015 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18016 (clobber (reg:CC 17))
18017 (clobber (mem:BLK (scratch)))])]
18018 "optimize_size || !TARGET_SUB_ESP_8"
18019 [(clobber (match_dup 0))
18020 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18021 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18022 (clobber (mem:BLK (scratch)))])])
18023
18024;; Convert esp subtractions to push.
18025(define_peephole2
18026 [(match_scratch:SI 0 "r")
18027 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18028 (clobber (reg:CC 17))])]
18029 "optimize_size || !TARGET_SUB_ESP_4"
18030 [(clobber (match_dup 0))
18031 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18032
18033(define_peephole2
18034 [(match_scratch:SI 0 "r")
18035 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18036 (clobber (reg:CC 17))])]
18037 "optimize_size || !TARGET_SUB_ESP_8"
18038 [(clobber (match_dup 0))
18039 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18040 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18041
18042;; Convert epilogue deallocator to pop.
18043(define_peephole2
18044 [(match_scratch:SI 0 "r")
18045 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18046 (clobber (reg:CC 17))
18047 (clobber (mem:BLK (scratch)))])]
18048 "optimize_size || !TARGET_ADD_ESP_4"
18049 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18050 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18051 (clobber (mem:BLK (scratch)))])]
18052 "")
18053
18054;; Two pops case is tricky, since pop causes dependency on destination register.
18055;; We use two registers if available.
18056(define_peephole2
18057 [(match_scratch:SI 0 "r")
18058 (match_scratch:SI 1 "r")
18059 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18060 (clobber (reg:CC 17))
18061 (clobber (mem:BLK (scratch)))])]
18062 "optimize_size || !TARGET_ADD_ESP_8"
18063 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18064 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18065 (clobber (mem:BLK (scratch)))])
18066 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18067 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18068 "")
18069
18070(define_peephole2
18071 [(match_scratch:SI 0 "r")
18072 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18073 (clobber (reg:CC 17))
18074 (clobber (mem:BLK (scratch)))])]
18075 "optimize_size"
18076 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18077 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18078 (clobber (mem:BLK (scratch)))])
18079 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18080 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18081 "")
18082
18083;; Convert esp additions to pop.
18084(define_peephole2
18085 [(match_scratch:SI 0 "r")
18086 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18087 (clobber (reg:CC 17))])]
18088 ""
18089 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18090 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18091 "")
18092
18093;; Two pops case is tricky, since pop causes dependency on destination register.
18094;; We use two registers if available.
18095(define_peephole2
18096 [(match_scratch:SI 0 "r")
18097 (match_scratch:SI 1 "r")
18098 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18099 (clobber (reg:CC 17))])]
18100 ""
18101 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18102 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18103 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18104 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18105 "")
18106
18107(define_peephole2
18108 [(match_scratch:SI 0 "r")
18109 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18110 (clobber (reg:CC 17))])]
18111 "optimize_size"
18112 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18113 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18114 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18115 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18116 "")
18117
18118;; Convert compares with 1 to shorter inc/dec operations when CF is not
18119;; required and register dies. Similarly for 128 to plus -128.
18120(define_peephole2
18121 [(set (match_operand 0 "flags_reg_operand" "")
18122 (match_operator 1 "compare_operator"
18123 [(match_operand 2 "register_operand" "")
18124 (match_operand 3 "const_int_operand" "")]))]
18125 "(INTVAL (operands[3]) == -1
18126 || INTVAL (operands[3]) == 1
18127 || INTVAL (operands[3]) == 128)
18128 && ix86_match_ccmode (insn, CCGCmode)
18129 && peep2_reg_dead_p (1, operands[2])"
18130 [(parallel [(set (match_dup 0)
18131 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18132 (clobber (match_dup 2))])]
18133 "")
18134
18135(define_peephole2
18136 [(match_scratch:DI 0 "r")
18137 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18138 (clobber (reg:CC 17))
18139 (clobber (mem:BLK (scratch)))])]
18140 "optimize_size || !TARGET_SUB_ESP_4"
18141 [(clobber (match_dup 0))
18142 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18143 (clobber (mem:BLK (scratch)))])])
18144
18145(define_peephole2
18146 [(match_scratch:DI 0 "r")
18147 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18148 (clobber (reg:CC 17))
18149 (clobber (mem:BLK (scratch)))])]
18150 "optimize_size || !TARGET_SUB_ESP_8"
18151 [(clobber (match_dup 0))
18152 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18153 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18154 (clobber (mem:BLK (scratch)))])])
18155
18156;; Convert esp subtractions to push.
18157(define_peephole2
18158 [(match_scratch:DI 0 "r")
18159 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18160 (clobber (reg:CC 17))])]
18161 "optimize_size || !TARGET_SUB_ESP_4"
18162 [(clobber (match_dup 0))
18163 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18164
18165(define_peephole2
18166 [(match_scratch:DI 0 "r")
18167 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18168 (clobber (reg:CC 17))])]
18169 "optimize_size || !TARGET_SUB_ESP_8"
18170 [(clobber (match_dup 0))
18171 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18172 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18173
18174;; Convert epilogue deallocator to pop.
18175(define_peephole2
18176 [(match_scratch:DI 0 "r")
18177 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18178 (clobber (reg:CC 17))
18179 (clobber (mem:BLK (scratch)))])]
18180 "optimize_size || !TARGET_ADD_ESP_4"
18181 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18182 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18183 (clobber (mem:BLK (scratch)))])]
18184 "")
18185
18186;; Two pops case is tricky, since pop causes dependency on destination register.
18187;; We use two registers if available.
18188(define_peephole2
18189 [(match_scratch:DI 0 "r")
18190 (match_scratch:DI 1 "r")
18191 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18192 (clobber (reg:CC 17))
18193 (clobber (mem:BLK (scratch)))])]
18194 "optimize_size || !TARGET_ADD_ESP_8"
18195 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18196 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18197 (clobber (mem:BLK (scratch)))])
18198 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18199 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18200 "")
18201
18202(define_peephole2
18203 [(match_scratch:DI 0 "r")
18204 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18205 (clobber (reg:CC 17))
18206 (clobber (mem:BLK (scratch)))])]
18207 "optimize_size"
18208 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18209 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18210 (clobber (mem:BLK (scratch)))])
18211 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18212 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18213 "")
18214
18215;; Convert esp additions to pop.
18216(define_peephole2
18217 [(match_scratch:DI 0 "r")
18218 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18219 (clobber (reg:CC 17))])]
18220 ""
18221 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18222 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18223 "")
18224
18225;; Two pops case is tricky, since pop causes dependency on destination register.
18226;; We use two registers if available.
18227(define_peephole2
18228 [(match_scratch:DI 0 "r")
18229 (match_scratch:DI 1 "r")
18230 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18231 (clobber (reg:CC 17))])]
18232 ""
18233 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18234 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18235 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18236 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18237 "")
18238
18239(define_peephole2
18240 [(match_scratch:DI 0 "r")
18241 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18242 (clobber (reg:CC 17))])]
18243 "optimize_size"
18244 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18245 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18246 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18247 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18248 "")
18249
18250;; Imul $32bit_imm, mem, reg is vector decoded, while
18251;; imul $32bit_imm, reg, reg is direct decoded.
18252(define_peephole2
18253 [(match_scratch:DI 3 "r")
18254 (parallel [(set (match_operand:DI 0 "register_operand" "")
18255 (mult:DI (match_operand:DI 1 "memory_operand" "")
18256 (match_operand:DI 2 "immediate_operand" "")))
18257 (clobber (reg:CC 17))])]
18258 "TARGET_K8 && !optimize_size
18259 && (GET_CODE (operands[2]) != CONST_INT
18260 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18261 [(set (match_dup 3) (match_dup 1))
18262 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18263 (clobber (reg:CC 17))])]
18264"")
18265
18266(define_peephole2
18267 [(match_scratch:SI 3 "r")
18268 (parallel [(set (match_operand:SI 0 "register_operand" "")
18269 (mult:SI (match_operand:SI 1 "memory_operand" "")
18270 (match_operand:SI 2 "immediate_operand" "")))
18271 (clobber (reg:CC 17))])]
18272 "TARGET_K8 && !optimize_size
18273 && (GET_CODE (operands[2]) != CONST_INT
18274 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18275 [(set (match_dup 3) (match_dup 1))
18276 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18277 (clobber (reg:CC 17))])]
18278"")
18279
18280(define_peephole2
18281 [(match_scratch:SI 3 "r")
18282 (parallel [(set (match_operand:DI 0 "register_operand" "")
18283 (zero_extend:DI
18284 (mult:SI (match_operand:SI 1 "memory_operand" "")
18285 (match_operand:SI 2 "immediate_operand" ""))))
18286 (clobber (reg:CC 17))])]
18287 "TARGET_K8 && !optimize_size
18288 && (GET_CODE (operands[2]) != CONST_INT
18289 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18290 [(set (match_dup 3) (match_dup 1))
18291 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18292 (clobber (reg:CC 17))])]
18293"")
18294
18295;; imul $8/16bit_imm, regmem, reg is vector decoded.
18296;; Convert it into imul reg, reg
18297;; It would be better to force assembler to encode instruction using long
18298;; immediate, but there is apparently no way to do so.
18299(define_peephole2
18300 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18301 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18302 (match_operand:DI 2 "const_int_operand" "")))
18303 (clobber (reg:CC 17))])
18304 (match_scratch:DI 3 "r")]
18305 "TARGET_K8 && !optimize_size
18306 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18307 [(set (match_dup 3) (match_dup 2))
18308 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18309 (clobber (reg:CC 17))])]
18310{
18311 if (!rtx_equal_p (operands[0], operands[1]))
18312 emit_move_insn (operands[0], operands[1]);
18313})
18314
18315(define_peephole2
18316 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18317 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18318 (match_operand:SI 2 "const_int_operand" "")))
18319 (clobber (reg:CC 17))])
18320 (match_scratch:SI 3 "r")]
18321 "TARGET_K8 && !optimize_size
18322 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18323 [(set (match_dup 3) (match_dup 2))
18324 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18325 (clobber (reg:CC 17))])]
18326{
18327 if (!rtx_equal_p (operands[0], operands[1]))
18328 emit_move_insn (operands[0], operands[1]);
18329})
18330
18331(define_peephole2
18332 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18333 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18334 (match_operand:HI 2 "immediate_operand" "")))
18335 (clobber (reg:CC 17))])
18336 (match_scratch:HI 3 "r")]
18337 "TARGET_K8 && !optimize_size"
18338 [(set (match_dup 3) (match_dup 2))
18339 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18340 (clobber (reg:CC 17))])]
18341{
18342 if (!rtx_equal_p (operands[0], operands[1]))
18343 emit_move_insn (operands[0], operands[1]);
18344})
18345
18346;; Call-value patterns last so that the wildcard operand does not
18347;; disrupt insn-recog's switch tables.
18348
18349(define_insn "*call_value_pop_0"
18350 [(set (match_operand 0 "" "")
18351 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18352 (match_operand:SI 2 "" "")))
18353 (set (reg:SI 7) (plus:SI (reg:SI 7)
18354 (match_operand:SI 3 "immediate_operand" "")))]
18355 "!TARGET_64BIT"
18356{
18357 if (SIBLING_CALL_P (insn))
18358 return "jmp\t%P1";
18359 else
18360 return "call\t%P1";
18361}
18362 [(set_attr "type" "callv")])
18363
18364(define_insn "*call_value_pop_1"
18365 [(set (match_operand 0 "" "")
18366 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18367 (match_operand:SI 2 "" "")))
18368 (set (reg:SI 7) (plus:SI (reg:SI 7)
18369 (match_operand:SI 3 "immediate_operand" "i")))]
18370 "!TARGET_64BIT"
18371{
18372 if (constant_call_address_operand (operands[1], QImode))
18373 {
18374 if (SIBLING_CALL_P (insn))
18375 return "jmp\t%P1";
18376 else
18377 return "call\t%P1";
18378 }
18379 if (SIBLING_CALL_P (insn))
18380 return "jmp\t%A1";
18381 else
18382 return "call\t%A1";
18383}
18384 [(set_attr "type" "callv")])
18385
18386(define_insn "*call_value_0"
18387 [(set (match_operand 0 "" "")
18388 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18389 (match_operand:SI 2 "" "")))]
18390 "!TARGET_64BIT"
18391{
18392 if (SIBLING_CALL_P (insn))
18393 return "jmp\t%P1";
18394 else
18395 return "call\t%P1";
18396}
18397 [(set_attr "type" "callv")])
18398
18399(define_insn "*call_value_0_rex64"
18400 [(set (match_operand 0 "" "")
18401 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18402 (match_operand:DI 2 "const_int_operand" "")))]
18403 "TARGET_64BIT"
18404{
18405 if (SIBLING_CALL_P (insn))
18406 return "jmp\t%P1";
18407 else
18408 return "call\t%P1";
18409}
18410 [(set_attr "type" "callv")])
18411
18412(define_insn "*call_value_1"
18413 [(set (match_operand 0 "" "")
18414 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18415 (match_operand:SI 2 "" "")))]
18416 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18417{
18418 if (constant_call_address_operand (operands[1], QImode))
18419 return "call\t%P1";
18420 return "call\t%A1";
18421}
18422 [(set_attr "type" "callv")])
18423
18424(define_insn "*sibcall_value_1"
18425 [(set (match_operand 0 "" "")
18426 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18427 (match_operand:SI 2 "" "")))]
18428 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18429{
18430 if (constant_call_address_operand (operands[1], QImode))
18431 return "jmp\t%P1";
18432 return "jmp\t%A1";
18433}
18434 [(set_attr "type" "callv")])
18435
18436(define_insn "*call_value_1_rex64"
18437 [(set (match_operand 0 "" "")
18438 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18439 (match_operand:DI 2 "" "")))]
18440 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18441{
18442 if (constant_call_address_operand (operands[1], QImode))
18443 return "call\t%P1";
18444 return "call\t%A1";
18445}
18446 [(set_attr "type" "callv")])
18447
18448(define_insn "*sibcall_value_1_rex64"
18449 [(set (match_operand 0 "" "")
18450 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18451 (match_operand:DI 2 "" "")))]
18452 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18453 "jmp\t%P1"
18454 [(set_attr "type" "callv")])
18455
18456(define_insn "*sibcall_value_1_rex64_v"
18457 [(set (match_operand 0 "" "")
18458 (call (mem:QI (reg:DI 40))
18459 (match_operand:DI 1 "" "")))]
18460 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18461 "jmp\t*%%r11"
18462 [(set_attr "type" "callv")])
18463
18464(define_insn "trap"
18465 [(trap_if (const_int 1) (const_int 5))]
18466 ""
18467 "int\t$5")
18468
18469;;; ix86 doesn't have conditional trap instructions, but we fake them
18470;;; for the sake of bounds checking. By emitting bounds checks as
18471;;; conditional traps rather than as conditional jumps around
18472;;; unconditional traps we avoid introducing spurious basic-block
18473;;; boundaries and facilitate elimination of redundant checks. In
18474;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18475;;; interrupt 5.
18476;;;
18477;;; FIXME: Static branch prediction rules for ix86 are such that
18478;;; forward conditional branches predict as untaken. As implemented
18479;;; below, pseudo conditional traps violate that rule. We should use
18480;;; .pushsection/.popsection to place all of the `int 5's in a special
18481;;; section loaded at the end of the text segment and branch forward
18482;;; there on bounds-failure, and then jump back immediately (in case
18483;;; the system chooses to ignore bounds violations, or to report
18484;;; violations and continue execution).
18485
18486(define_expand "conditional_trap"
18487 [(trap_if (match_operator 0 "comparison_operator"
18488 [(match_dup 2) (const_int 0)])
18489 (match_operand 1 "const_int_operand" ""))]
18490 ""
18491{
18492 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18493 ix86_expand_compare (GET_CODE (operands[0]),
18494 NULL, NULL),
18495 operands[1]));
18496 DONE;
18497})
18498
18499(define_insn "*conditional_trap_1"
18500 [(trap_if (match_operator 0 "comparison_operator"
18501 [(reg 17) (const_int 0)])
18502 (match_operand 1 "const_int_operand" ""))]
18503 ""
18504{
18505 operands[2] = gen_label_rtx ();
18506 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18507 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18508 CODE_LABEL_NUMBER (operands[2]));
18509 RET;
18510})
18511
18512 ;; Pentium III SIMD instructions.
18513
18514;; Moves for SSE/MMX regs.
18515
18516(define_insn "*movv4sf_internal"
18517 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18518 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18519 "TARGET_SSE
18520 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18521 "@
18522 xorps\t%0, %0
18523 movaps\t{%1, %0|%0, %1}
18524 movaps\t{%1, %0|%0, %1}"
18525 [(set_attr "type" "ssemov")
18526 (set_attr "mode" "V4SF")])
18527
18528(define_split
18529 [(set (match_operand:V4SF 0 "register_operand" "")
18530 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18531 "TARGET_SSE && reload_completed"
18532 [(set (match_dup 0)
18533 (vec_merge:V4SF
18534 (vec_duplicate:V4SF (match_dup 1))
18535 (match_dup 2)
18536 (const_int 1)))]
18537{
18538 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18539 operands[2] = CONST0_RTX (V4SFmode);
18540})
18541
18542(define_insn "*movv4si_internal"
18543 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18544 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18545 "TARGET_SSE
18546 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18547{
18548 switch (which_alternative)
18549 {
18550 case 0:
18551 if (get_attr_mode (insn) == MODE_V4SF)
18552 return "xorps\t%0, %0";
18553 else
18554 return "pxor\t%0, %0";
18555 case 1:
18556 case 2:
18557 if (get_attr_mode (insn) == MODE_V4SF)
18558 return "movaps\t{%1, %0|%0, %1}";
18559 else
18560 return "movdqa\t{%1, %0|%0, %1}";
18561 default:
18562 abort ();
18563 }
18564}
18565 [(set_attr "type" "ssemov")
18566 (set (attr "mode")
18567 (cond [(eq_attr "alternative" "0,1")
18568 (if_then_else
18569 (ne (symbol_ref "optimize_size")
18570 (const_int 0))
18571 (const_string "V4SF")
18572 (const_string "TI"))
18573 (eq_attr "alternative" "2")
18574 (if_then_else
18575 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18576 (const_int 0))
18577 (ne (symbol_ref "optimize_size")
18578 (const_int 0)))
18579 (const_string "V4SF")
18580 (const_string "TI"))]
18581 (const_string "TI")))])
18582
18583(define_insn "*movv2di_internal"
18584 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18585 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18586 "TARGET_SSE
18587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18588{
18589 switch (which_alternative)
18590 {
18591 case 0:
18592 if (get_attr_mode (insn) == MODE_V4SF)
18593 return "xorps\t%0, %0";
18594 else
18595 return "pxor\t%0, %0";
18596 case 1:
18597 case 2:
18598 if (get_attr_mode (insn) == MODE_V4SF)
18599 return "movaps\t{%1, %0|%0, %1}";
18600 else
18601 return "movdqa\t{%1, %0|%0, %1}";
18602 default:
18603 abort ();
18604 }
18605}
18606 [(set_attr "type" "ssemov")
18607 (set (attr "mode")
18608 (cond [(eq_attr "alternative" "0,1")
18609 (if_then_else
18610 (ne (symbol_ref "optimize_size")
18611 (const_int 0))
18612 (const_string "V4SF")
18613 (const_string "TI"))
18614 (eq_attr "alternative" "2")
18615 (if_then_else
18616 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18617 (const_int 0))
18618 (ne (symbol_ref "optimize_size")
18619 (const_int 0)))
18620 (const_string "V4SF")
18621 (const_string "TI"))]
18622 (const_string "TI")))])
18623
18624(define_split
18625 [(set (match_operand:V2DF 0 "register_operand" "")
18626 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18627 "TARGET_SSE2 && reload_completed"
18628 [(set (match_dup 0)
18629 (vec_merge:V2DF
18630 (vec_duplicate:V2DF (match_dup 1))
18631 (match_dup 2)
18632 (const_int 1)))]
18633{
18634 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18635 operands[2] = CONST0_RTX (V2DFmode);
18636})
18637
18638(define_insn "*movv2si_internal"
18639 [(set (match_operand:V2SI 0 "nonimmediate_operand"
18640 "=y,y ,m,!y,!*Y,*x,?*x,?m")
18641 (match_operand:V2SI 1 "vector_move_operand"
18642 "C ,ym,y,*Y,y ,C ,*xm,*x"))]
18643 "TARGET_MMX
18644 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18645 "@
18646 pxor\t%0, %0
18647 movq\t{%1, %0|%0, %1}
18648 movq\t{%1, %0|%0, %1}
18649 movdq2q\t{%1, %0|%0, %1}
18650 movq2dq\t{%1, %0|%0, %1}
18651 pxor\t%0, %0
18652 movq\t{%1, %0|%0, %1}
18653 movq\t{%1, %0|%0, %1}"
18654 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18655 (set_attr "mode" "DI")])
18656
18657(define_insn "*movv4hi_internal"
18658 [(set (match_operand:V4HI 0 "nonimmediate_operand"
18659 "=y,y ,m,!y,!*Y,*x,?*x,?m")
18660 (match_operand:V4HI 1 "vector_move_operand"
18661 "C ,ym,y,*Y,y ,C ,*xm,*x"))]
18662 "TARGET_MMX
18663 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18664 "@
18665 pxor\t%0, %0
18666 movq\t{%1, %0|%0, %1}
18667 movq\t{%1, %0|%0, %1}
18668 movdq2q\t{%1, %0|%0, %1}
18669 movq2dq\t{%1, %0|%0, %1}
18670 pxor\t%0, %0
18671 movq\t{%1, %0|%0, %1}
18672 movq\t{%1, %0|%0, %1}"
18673 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18674 (set_attr "mode" "DI")])
18675
18676(define_insn "*movv8qi_internal"
18677 [(set (match_operand:V8QI 0 "nonimmediate_operand"
18678 "=y,y ,m,!y,!*Y,*x,?*x,?m")
18679 (match_operand:V8QI 1 "vector_move_operand"
18680 "C ,ym,y,*Y,y ,C ,*xm,*x"))]
18681 "TARGET_MMX
18682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18683 "@
18684 pxor\t%0, %0
18685 movq\t{%1, %0|%0, %1}
18686 movq\t{%1, %0|%0, %1}
18687 movdq2q\t{%1, %0|%0, %1}
18688 movq2dq\t{%1, %0|%0, %1}
18689 pxor\t%0, %0
18690 movq\t{%1, %0|%0, %1}
18691 movq\t{%1, %0|%0, %1}"
18692 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18693 (set_attr "mode" "DI")])
18694
18695(define_insn "*movv2sf_internal"
18696 [(set (match_operand:V2SF 0 "nonimmediate_operand"
18697 "=y,y ,m,!y,!*Y,*x,?*x,?m")
18698 (match_operand:V2SF 1 "vector_move_operand"
18699 "C ,ym,y,*Y,y ,C ,*xm,*x"))]
18700 "TARGET_MMX
18701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18702 "@
18703 pxor\t%0, %0
18704 movq\t{%1, %0|%0, %1}
18705 movq\t{%1, %0|%0, %1}
18706 movdq2q\t{%1, %0|%0, %1}
18707 movq2dq\t{%1, %0|%0, %1}
18708 xorps\t%0, %0
18709 movq\t{%1, %0|%0, %1}
18710 movq\t{%1, %0|%0, %1}"
18711 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
18712 (set_attr "mode" "DI")])
18713
18714(define_expand "movti"
18715 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18716 (match_operand:TI 1 "nonimmediate_operand" ""))]
18717 "TARGET_SSE || TARGET_64BIT"
18718{
18719 if (TARGET_64BIT)
18720 ix86_expand_move (TImode, operands);
18721 else
18722 ix86_expand_vector_move (TImode, operands);
18723 DONE;
18724})
18725
18726(define_expand "movtf"
18727 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18728 (match_operand:TF 1 "nonimmediate_operand" ""))]
18729 "TARGET_64BIT"
18730{
18731 ix86_expand_move (TFmode, operands);
18732 DONE;
18733})
18734
18735(define_insn "*movv2df_internal"
18736 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18737 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18738 "TARGET_SSE
18739 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18740{
18741 switch (which_alternative)
18742 {
18743 case 0:
18744 if (get_attr_mode (insn) == MODE_V4SF)
18745 return "xorps\t%0, %0";
18746 else
18747 return "xorpd\t%0, %0";
18748 case 1:
18749 case 2:
18750 if (get_attr_mode (insn) == MODE_V4SF)
18751 return "movaps\t{%1, %0|%0, %1}";
18752 else
18753 return "movapd\t{%1, %0|%0, %1}";
18754 default:
18755 abort ();
18756 }
18757}
18758 [(set_attr "type" "ssemov")
18759 (set (attr "mode")
18760 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
18761 (const_string "V4SF")
18762 (eq_attr "alternative" "0,1")
18763 (if_then_else
18764 (ne (symbol_ref "optimize_size")
18765 (const_int 0))
18766 (const_string "V4SF")
18767 (const_string "V2DF"))
18768 (eq_attr "alternative" "2")
18769 (if_then_else
18770 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18771 (const_int 0))
18772 (ne (symbol_ref "optimize_size")
18773 (const_int 0)))
18774 (const_string "V4SF")
18775 (const_string "V2DF"))]
18776 (const_string "V2DF")))])
18777
18778(define_insn "*movv8hi_internal"
18779 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18780 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18781 "TARGET_SSE
18782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18783{
18784 switch (which_alternative)
18785 {
18786 case 0:
18787 if (get_attr_mode (insn) == MODE_V4SF)
18788 return "xorps\t%0, %0";
18789 else
18790 return "pxor\t%0, %0";
18791 case 1:
18792 case 2:
18793 if (get_attr_mode (insn) == MODE_V4SF)
18794 return "movaps\t{%1, %0|%0, %1}";
18795 else
18796 return "movdqa\t{%1, %0|%0, %1}";
18797 default:
18798 abort ();
18799 }
18800}
18801 [(set_attr "type" "ssemov")
18802 (set (attr "mode")
18803 (cond [(eq_attr "alternative" "0,1")
18804 (if_then_else
18805 (ne (symbol_ref "optimize_size")
18806 (const_int 0))
18807 (const_string "V4SF")
18808 (const_string "TI"))
18809 (eq_attr "alternative" "2")
18810 (if_then_else
18811 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18812 (const_int 0))
18813 (ne (symbol_ref "optimize_size")
18814 (const_int 0)))
18815 (const_string "V4SF")
18816 (const_string "TI"))]
18817 (const_string "TI")))])
18818
18819(define_insn "*movv16qi_internal"
18820 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18821 (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
18822 "TARGET_SSE
18823 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18824{
18825 switch (which_alternative)
18826 {
18827 case 0:
18828 if (get_attr_mode (insn) == MODE_V4SF)
18829 return "xorps\t%0, %0";
18830 else
18831 return "pxor\t%0, %0";
18832 case 1:
18833 case 2:
18834 if (get_attr_mode (insn) == MODE_V4SF)
18835 return "movaps\t{%1, %0|%0, %1}";
18836 else
18837 return "movdqa\t{%1, %0|%0, %1}";
18838 default:
18839 abort ();
18840 }
18841}
18842 [(set_attr "type" "ssemov")
18843 (set (attr "mode")
18844 (cond [(eq_attr "alternative" "0,1")
18845 (if_then_else
18846 (ne (symbol_ref "optimize_size")
18847 (const_int 0))
18848 (const_string "V4SF")
18849 (const_string "TI"))
18850 (eq_attr "alternative" "2")
18851 (if_then_else
18852 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18853 (const_int 0))
18854 (ne (symbol_ref "optimize_size")
18855 (const_int 0)))
18856 (const_string "V4SF")
18857 (const_string "TI"))]
18858 (const_string "TI")))])
18859
18860(define_expand "movv2df"
18861 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18862 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18863 "TARGET_SSE"
18864{
18865 ix86_expand_vector_move (V2DFmode, operands);
18866 DONE;
18867})
18868
18869(define_expand "movv8hi"
18870 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18871 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18872 "TARGET_SSE"
18873{
18874 ix86_expand_vector_move (V8HImode, operands);
18875 DONE;
18876})
18877
18878(define_expand "movv16qi"
18879 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18880 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18881 "TARGET_SSE"
18882{
18883 ix86_expand_vector_move (V16QImode, operands);
18884 DONE;
18885})
18886
18887(define_expand "movv4sf"
18888 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18889 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18890 "TARGET_SSE"
18891{
18892 ix86_expand_vector_move (V4SFmode, operands);
18893 DONE;
18894})
18895
18896(define_expand "movv4si"
18897 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18898 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18899 "TARGET_SSE"
18900{
18901 ix86_expand_vector_move (V4SImode, operands);
18902 DONE;
18903})
18904
18905(define_expand "movv2di"
18906 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18907 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18908 "TARGET_SSE"
18909{
18910 ix86_expand_vector_move (V2DImode, operands);
18911 DONE;
18912})
18913
18914(define_expand "movv2si"
18915 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18916 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18917 "TARGET_MMX"
18918{
18919 ix86_expand_vector_move (V2SImode, operands);
18920 DONE;
18921})
18922
18923(define_expand "movv4hi"
18924 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18925 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18926 "TARGET_MMX"
18927{
18928 ix86_expand_vector_move (V4HImode, operands);
18929 DONE;
18930})
18931
18932(define_expand "movv8qi"
18933 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18934 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18935 "TARGET_MMX"
18936{
18937 ix86_expand_vector_move (V8QImode, operands);
18938 DONE;
18939})
18940
18941(define_expand "movv2sf"
18942 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18943 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18944 "TARGET_MMX"
18945{
18946 ix86_expand_vector_move (V2SFmode, operands);
18947 DONE;
18948})
18949
18950(define_insn "*pushti"
18951 [(set (match_operand:TI 0 "push_operand" "=<")
18952 (match_operand:TI 1 "register_operand" "x"))]
18953 "TARGET_SSE"
18954 "#")
18955
18956(define_insn "*pushv2df"
18957 [(set (match_operand:V2DF 0 "push_operand" "=<")
18958 (match_operand:V2DF 1 "register_operand" "x"))]
18959 "TARGET_SSE"
18960 "#")
18961
18962(define_insn "*pushv2di"
18963 [(set (match_operand:V2DI 0 "push_operand" "=<")
18964 (match_operand:V2DI 1 "register_operand" "x"))]
18965 "TARGET_SSE"
18966 "#")
18967
18968(define_insn "*pushv8hi"
18969 [(set (match_operand:V8HI 0 "push_operand" "=<")
18970 (match_operand:V8HI 1 "register_operand" "x"))]
18971 "TARGET_SSE"
18972 "#")
18973
18974(define_insn "*pushv16qi"
18975 [(set (match_operand:V16QI 0 "push_operand" "=<")
18976 (match_operand:V16QI 1 "register_operand" "x"))]
18977 "TARGET_SSE"
18978 "#")
18979
18980(define_insn "*pushv4sf"
18981 [(set (match_operand:V4SF 0 "push_operand" "=<")
18982 (match_operand:V4SF 1 "register_operand" "x"))]
18983 "TARGET_SSE"
18984 "#")
18985
18986(define_insn "*pushv4si"
18987 [(set (match_operand:V4SI 0 "push_operand" "=<")
18988 (match_operand:V4SI 1 "register_operand" "x"))]
18989 "TARGET_SSE"
18990 "#")
18991
18992(define_insn "*pushv2si"
18993 [(set (match_operand:V2SI 0 "push_operand" "=<")
18994 (match_operand:V2SI 1 "register_operand" "y"))]
18995 "TARGET_MMX"
18996 "#")
18997
18998(define_insn "*pushv4hi"
18999 [(set (match_operand:V4HI 0 "push_operand" "=<")
19000 (match_operand:V4HI 1 "register_operand" "y"))]
19001 "TARGET_MMX"
19002 "#")
19003
19004(define_insn "*pushv8qi"
19005 [(set (match_operand:V8QI 0 "push_operand" "=<")
19006 (match_operand:V8QI 1 "register_operand" "y"))]
19007 "TARGET_MMX"
19008 "#")
19009
19010(define_insn "*pushv2sf"
19011 [(set (match_operand:V2SF 0 "push_operand" "=<")
19012 (match_operand:V2SF 1 "register_operand" "y"))]
19013 "TARGET_MMX"
19014 "#")
19015
19016(define_split
19017 [(set (match_operand 0 "push_operand" "")
19018 (match_operand 1 "register_operand" ""))]
19019 "!TARGET_64BIT && reload_completed
19020 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19021 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19022 (set (match_dup 2) (match_dup 1))]
19023 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19024 stack_pointer_rtx);
19025 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19026
19027(define_split
19028 [(set (match_operand 0 "push_operand" "")
19029 (match_operand 1 "register_operand" ""))]
19030 "TARGET_64BIT && reload_completed
19031 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19032 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19033 (set (match_dup 2) (match_dup 1))]
19034 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19035 stack_pointer_rtx);
19036 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19037
19038
19039(define_insn "*movti_internal"
19040 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19041 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19042 "TARGET_SSE && !TARGET_64BIT
19043 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19044{
19045 switch (which_alternative)
19046 {
19047 case 0:
19048 if (get_attr_mode (insn) == MODE_V4SF)
19049 return "xorps\t%0, %0";
19050 else
19051 return "pxor\t%0, %0";
19052 case 1:
19053 case 2:
19054 if (get_attr_mode (insn) == MODE_V4SF)
19055 return "movaps\t{%1, %0|%0, %1}";
19056 else
19057 return "movdqa\t{%1, %0|%0, %1}";
19058 default:
19059 abort ();
19060 }
19061}
19062 [(set_attr "type" "ssemov,ssemov,ssemov")
19063 (set (attr "mode")
19064 (cond [(eq_attr "alternative" "0,1")
19065 (if_then_else
19066 (ne (symbol_ref "optimize_size")
19067 (const_int 0))
19068 (const_string "V4SF")
19069 (const_string "TI"))
19070 (eq_attr "alternative" "2")
19071 (if_then_else
19072 (ne (symbol_ref "optimize_size")
19073 (const_int 0))
19074 (const_string "V4SF")
19075 (const_string "TI"))]
19076 (const_string "TI")))])
19077
19078(define_insn "*movti_rex64"
19079 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19080 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19081 "TARGET_64BIT
19082 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19083{
19084 switch (which_alternative)
19085 {
19086 case 0:
19087 case 1:
19088 return "#";
19089 case 2:
19090 if (get_attr_mode (insn) == MODE_V4SF)
19091 return "xorps\t%0, %0";
19092 else
19093 return "pxor\t%0, %0";
19094 case 3:
19095 case 4:
19096 if (get_attr_mode (insn) == MODE_V4SF)
19097 return "movaps\t{%1, %0|%0, %1}";
19098 else
19099 return "movdqa\t{%1, %0|%0, %1}";
19100 default:
19101 abort ();
19102 }
19103}
19104 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19105 (set (attr "mode")
19106 (cond [(eq_attr "alternative" "2,3")
19107 (if_then_else
19108 (ne (symbol_ref "optimize_size")
19109 (const_int 0))
19110 (const_string "V4SF")
19111 (const_string "TI"))
19112 (eq_attr "alternative" "4")
19113 (if_then_else
19114 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19115 (const_int 0))
19116 (ne (symbol_ref "optimize_size")
19117 (const_int 0)))
19118 (const_string "V4SF")
19119 (const_string "TI"))]
19120 (const_string "DI")))])
19121
19122(define_insn "*movtf_rex64"
19123 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19124 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19125 "TARGET_64BIT
19126 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19127{
19128 switch (which_alternative)
19129 {
19130 case 0:
19131 case 1:
19132 return "#";
19133 case 2:
19134 if (get_attr_mode (insn) == MODE_V4SF)
19135 return "xorps\t%0, %0";
19136 else
19137 return "pxor\t%0, %0";
19138 case 3:
19139 case 4:
19140 if (get_attr_mode (insn) == MODE_V4SF)
19141 return "movaps\t{%1, %0|%0, %1}";
19142 else
19143 return "movdqa\t{%1, %0|%0, %1}";
19144 default:
19145 abort ();
19146 }
19147}
19148 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19149 (set (attr "mode")
19150 (cond [(eq_attr "alternative" "2,3")
19151 (if_then_else
19152 (ne (symbol_ref "optimize_size")
19153 (const_int 0))
19154 (const_string "V4SF")
19155 (const_string "TI"))
19156 (eq_attr "alternative" "4")
19157 (if_then_else
19158 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19159 (const_int 0))
19160 (ne (symbol_ref "optimize_size")
19161 (const_int 0)))
19162 (const_string "V4SF")
19163 (const_string "TI"))]
19164 (const_string "DI")))])
19165
19166(define_split
19167 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19168 (match_operand:TI 1 "general_operand" ""))]
19169 "reload_completed && !SSE_REG_P (operands[0])
19170 && !SSE_REG_P (operands[1])"
19171 [(const_int 0)]
19172 "ix86_split_long_move (operands); DONE;")
19173
19174(define_split
19175 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19176 (match_operand:TF 1 "general_operand" ""))]
19177 "reload_completed && !SSE_REG_P (operands[0])
19178 && !SSE_REG_P (operands[1])"
19179 [(const_int 0)]
19180 "ix86_split_long_move (operands); DONE;")
19181
19182;; These two patterns are useful for specifying exactly whether to use
19183;; movaps or movups
19184(define_expand "sse_movaps"
19185 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19186 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19187 UNSPEC_MOVA))]
19188 "TARGET_SSE"
19189{
19190 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19191 {
19192 rtx tmp = gen_reg_rtx (V4SFmode);
19193 emit_insn (gen_sse_movaps (tmp, operands[1]));
19194 emit_move_insn (operands[0], tmp);
19195 DONE;
19196 }
19197})
19198
19199(define_insn "*sse_movaps_1"
19200 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19201 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19202 UNSPEC_MOVA))]
19203 "TARGET_SSE
19204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19205 "movaps\t{%1, %0|%0, %1}"
19206 [(set_attr "type" "ssemov,ssemov")
19207 (set_attr "mode" "V4SF")])
19208
19209(define_expand "sse_movups"
19210 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19211 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19212 UNSPEC_MOVU))]
19213 "TARGET_SSE"
19214{
19215 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19216 {
19217 rtx tmp = gen_reg_rtx (V4SFmode);
19218 emit_insn (gen_sse_movups (tmp, operands[1]));
19219 emit_move_insn (operands[0], tmp);
19220 DONE;
19221 }
19222})
19223
19224(define_insn "*sse_movups_1"
19225 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19226 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19227 UNSPEC_MOVU))]
19228 "TARGET_SSE
19229 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19230 "movups\t{%1, %0|%0, %1}"
19231 [(set_attr "type" "ssecvt,ssecvt")
19232 (set_attr "mode" "V4SF")])
19233
19234;; SSE Strange Moves.
19235
19236(define_insn "sse_movmskps"
19237 [(set (match_operand:SI 0 "register_operand" "=r")
19238 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19239 UNSPEC_MOVMSK))]
19240 "TARGET_SSE"
19241 "movmskps\t{%1, %0|%0, %1}"
19242 [(set_attr "type" "ssecvt")
19243 (set_attr "mode" "V4SF")])
19244
19245(define_insn "mmx_pmovmskb"
19246 [(set (match_operand:SI 0 "register_operand" "=r")
19247 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19248 UNSPEC_MOVMSK))]
19249 "TARGET_SSE || TARGET_3DNOW_A"
19250 "pmovmskb\t{%1, %0|%0, %1}"
19251 [(set_attr "type" "ssecvt")
19252 (set_attr "mode" "V4SF")])
19253
19254
19255(define_insn "mmx_maskmovq"
19256 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19257 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19258 (match_operand:V8QI 2 "register_operand" "y")]
19259 UNSPEC_MASKMOV))]
19260 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19261 ;; @@@ check ordering of operands in intel/nonintel syntax
19262 "maskmovq\t{%2, %1|%1, %2}"
19263 [(set_attr "type" "mmxcvt")
19264 (set_attr "mode" "DI")])
19265
19266(define_insn "mmx_maskmovq_rex"
19267 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19268 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19269 (match_operand:V8QI 2 "register_operand" "y")]
19270 UNSPEC_MASKMOV))]
19271 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19272 ;; @@@ check ordering of operands in intel/nonintel syntax
19273 "maskmovq\t{%2, %1|%1, %2}"
19274 [(set_attr "type" "mmxcvt")
19275 (set_attr "mode" "DI")])
19276
19277(define_insn "sse_movntv4sf"
19278 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19279 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19280 UNSPEC_MOVNT))]
19281 "TARGET_SSE"
19282 "movntps\t{%1, %0|%0, %1}"
19283 [(set_attr "type" "ssemov")
19284 (set_attr "mode" "V4SF")])
19285
19286(define_insn "sse_movntdi"
19287 [(set (match_operand:DI 0 "memory_operand" "=m")
19288 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19289 UNSPEC_MOVNT))]
19290 "TARGET_SSE || TARGET_3DNOW_A"
19291 "movntq\t{%1, %0|%0, %1}"
19292 [(set_attr "type" "mmxmov")
19293 (set_attr "mode" "DI")])
19294
19295(define_insn "sse_movhlps"
19296 [(set (match_operand:V4SF 0 "register_operand" "=x")
19297 (vec_merge:V4SF
19298 (match_operand:V4SF 1 "register_operand" "0")
19299 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19300 (parallel [(const_int 2)
19301 (const_int 3)
19302 (const_int 0)
19303 (const_int 1)]))
19304 (const_int 3)))]
19305 "TARGET_SSE"
19306 "movhlps\t{%2, %0|%0, %2}"
19307 [(set_attr "type" "ssecvt")
19308 (set_attr "mode" "V4SF")])
19309
19310(define_insn "sse_movlhps"
19311 [(set (match_operand:V4SF 0 "register_operand" "=x")
19312 (vec_merge:V4SF
19313 (match_operand:V4SF 1 "register_operand" "0")
19314 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19315 (parallel [(const_int 2)
19316 (const_int 3)
19317 (const_int 0)
19318 (const_int 1)]))
19319 (const_int 12)))]
19320 "TARGET_SSE"
19321 "movlhps\t{%2, %0|%0, %2}"
19322 [(set_attr "type" "ssecvt")
19323 (set_attr "mode" "V4SF")])
19324
19325(define_insn "sse_movhps"
19326 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19327 (vec_merge:V4SF
19328 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19329 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19330 (const_int 12)))]
19331 "TARGET_SSE
19332 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19333 "movhps\t{%2, %0|%0, %2}"
19334 [(set_attr "type" "ssecvt")
19335 (set_attr "mode" "V4SF")])
19336
19337(define_insn "sse_movlps"
19338 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19339 (vec_merge:V4SF
19340 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19341 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19342 (const_int 3)))]
19343 "TARGET_SSE
19344 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19345 "movlps\t{%2, %0|%0, %2}"
19346 [(set_attr "type" "ssecvt")
19347 (set_attr "mode" "V4SF")])
19348
19349(define_expand "sse_loadss"
19350 [(match_operand:V4SF 0 "register_operand" "")
19351 (match_operand:SF 1 "memory_operand" "")]
19352 "TARGET_SSE"
19353{
19354 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19355 CONST0_RTX (V4SFmode)));
19356 DONE;
19357})
19358
19359(define_insn "sse_loadss_1"
19360 [(set (match_operand:V4SF 0 "register_operand" "=x")
19361 (vec_merge:V4SF
19362 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19363 (match_operand:V4SF 2 "const0_operand" "X")
19364 (const_int 1)))]
19365 "TARGET_SSE"
19366 "movss\t{%1, %0|%0, %1}"
19367 [(set_attr "type" "ssemov")
19368 (set_attr "mode" "SF")])
19369
19370(define_insn "sse_movss"
19371 [(set (match_operand:V4SF 0 "register_operand" "=x")
19372 (vec_merge:V4SF
19373 (match_operand:V4SF 1 "register_operand" "0")
19374 (match_operand:V4SF 2 "register_operand" "x")
19375 (const_int 1)))]
19376 "TARGET_SSE"
19377 "movss\t{%2, %0|%0, %2}"
19378 [(set_attr "type" "ssemov")
19379 (set_attr "mode" "SF")])
19380
19381(define_insn "sse_storess"
19382 [(set (match_operand:SF 0 "memory_operand" "=m")
19383 (vec_select:SF
19384 (match_operand:V4SF 1 "register_operand" "x")
19385 (parallel [(const_int 0)])))]
19386 "TARGET_SSE"
19387 "movss\t{%1, %0|%0, %1}"
19388 [(set_attr "type" "ssemov")
19389 (set_attr "mode" "SF")])
19390
19391(define_insn "sse_shufps"
19392 [(set (match_operand:V4SF 0 "register_operand" "=x")
19393 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19394 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19395 (match_operand:SI 3 "immediate_operand" "i")]
19396 UNSPEC_SHUFFLE))]
19397 "TARGET_SSE"
19398 ;; @@@ check operand order for intel/nonintel syntax
19399 "shufps\t{%3, %2, %0|%0, %2, %3}"
19400 [(set_attr "type" "ssecvt")
19401 (set_attr "mode" "V4SF")])
19402
19403
19404;; SSE arithmetic
19405
19406(define_insn "addv4sf3"
19407 [(set (match_operand:V4SF 0 "register_operand" "=x")
19408 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19409 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19410 "TARGET_SSE"
19411 "addps\t{%2, %0|%0, %2}"
19412 [(set_attr "type" "sseadd")
19413 (set_attr "mode" "V4SF")])
19414
19415(define_insn "vmaddv4sf3"
19416 [(set (match_operand:V4SF 0 "register_operand" "=x")
19417 (vec_merge:V4SF
19418 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19419 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19420 (match_dup 1)
19421 (const_int 1)))]
19422 "TARGET_SSE"
19423 "addss\t{%2, %0|%0, %2}"
19424 [(set_attr "type" "sseadd")
19425 (set_attr "mode" "SF")])
19426
19427(define_insn "subv4sf3"
19428 [(set (match_operand:V4SF 0 "register_operand" "=x")
19429 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19430 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19431 "TARGET_SSE"
19432 "subps\t{%2, %0|%0, %2}"
19433 [(set_attr "type" "sseadd")
19434 (set_attr "mode" "V4SF")])
19435
19436(define_insn "vmsubv4sf3"
19437 [(set (match_operand:V4SF 0 "register_operand" "=x")
19438 (vec_merge:V4SF
19439 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19440 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19441 (match_dup 1)
19442 (const_int 1)))]
19443 "TARGET_SSE"
19444 "subss\t{%2, %0|%0, %2}"
19445 [(set_attr "type" "sseadd")
19446 (set_attr "mode" "SF")])
19447
19448(define_insn "mulv4sf3"
19449 [(set (match_operand:V4SF 0 "register_operand" "=x")
19450 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19451 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19452 "TARGET_SSE"
19453 "mulps\t{%2, %0|%0, %2}"
19454 [(set_attr "type" "ssemul")
19455 (set_attr "mode" "V4SF")])
19456
19457(define_insn "vmmulv4sf3"
19458 [(set (match_operand:V4SF 0 "register_operand" "=x")
19459 (vec_merge:V4SF
19460 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19461 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19462 (match_dup 1)
19463 (const_int 1)))]
19464 "TARGET_SSE"
19465 "mulss\t{%2, %0|%0, %2}"
19466 [(set_attr "type" "ssemul")
19467 (set_attr "mode" "SF")])
19468
19469(define_insn "divv4sf3"
19470 [(set (match_operand:V4SF 0 "register_operand" "=x")
19471 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19472 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19473 "TARGET_SSE"
19474 "divps\t{%2, %0|%0, %2}"
19475 [(set_attr "type" "ssediv")
19476 (set_attr "mode" "V4SF")])
19477
19478(define_insn "vmdivv4sf3"
19479 [(set (match_operand:V4SF 0 "register_operand" "=x")
19480 (vec_merge:V4SF
19481 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19482 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19483 (match_dup 1)
19484 (const_int 1)))]
19485 "TARGET_SSE"
19486 "divss\t{%2, %0|%0, %2}"
19487 [(set_attr "type" "ssediv")
19488 (set_attr "mode" "SF")])
19489
19490
19491;; SSE square root/reciprocal
19492
19493(define_insn "rcpv4sf2"
19494 [(set (match_operand:V4SF 0 "register_operand" "=x")
19495 (unspec:V4SF
19496 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19497 "TARGET_SSE"
19498 "rcpps\t{%1, %0|%0, %1}"
19499 [(set_attr "type" "sse")
19500 (set_attr "mode" "V4SF")])
19501
19502(define_insn "vmrcpv4sf2"
19503 [(set (match_operand:V4SF 0 "register_operand" "=x")
19504 (vec_merge:V4SF
19505 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19506 UNSPEC_RCP)
19507 (match_operand:V4SF 2 "register_operand" "0")
19508 (const_int 1)))]
19509 "TARGET_SSE"
19510 "rcpss\t{%1, %0|%0, %1}"
19511 [(set_attr "type" "sse")
19512 (set_attr "mode" "SF")])
19513
19514(define_insn "rsqrtv4sf2"
19515 [(set (match_operand:V4SF 0 "register_operand" "=x")
19516 (unspec:V4SF
19517 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19518 "TARGET_SSE"
19519 "rsqrtps\t{%1, %0|%0, %1}"
19520 [(set_attr "type" "sse")
19521 (set_attr "mode" "V4SF")])
19522
19523(define_insn "vmrsqrtv4sf2"
19524 [(set (match_operand:V4SF 0 "register_operand" "=x")
19525 (vec_merge:V4SF
19526 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19527 UNSPEC_RSQRT)
19528 (match_operand:V4SF 2 "register_operand" "0")
19529 (const_int 1)))]
19530 "TARGET_SSE"
19531 "rsqrtss\t{%1, %0|%0, %1}"
19532 [(set_attr "type" "sse")
19533 (set_attr "mode" "SF")])
19534
19535(define_insn "sqrtv4sf2"
19536 [(set (match_operand:V4SF 0 "register_operand" "=x")
19537 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19538 "TARGET_SSE"
19539 "sqrtps\t{%1, %0|%0, %1}"
19540 [(set_attr "type" "sse")
19541 (set_attr "mode" "V4SF")])
19542
19543(define_insn "vmsqrtv4sf2"
19544 [(set (match_operand:V4SF 0 "register_operand" "=x")
19545 (vec_merge:V4SF
19546 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19547 (match_operand:V4SF 2 "register_operand" "0")
19548 (const_int 1)))]
19549 "TARGET_SSE"
19550 "sqrtss\t{%1, %0|%0, %1}"
19551 [(set_attr "type" "sse")
19552 (set_attr "mode" "SF")])
19553
19554;; SSE logical operations.
19555
19556;; SSE defines logical operations on floating point values. This brings
19557;; interesting challenge to RTL representation where logicals are only valid
19558;; on integral types. We deal with this by representing the floating point
19559;; logical as logical on arguments casted to TImode as this is what hardware
19560;; really does. Unfortunately hardware requires the type information to be
19561;; present and thus we must avoid subregs from being simplified and eliminated
19562;; in later compilation phases.
19563;;
19564;; We have following variants from each instruction:
19565;; sse_andsf3 - the operation taking V4SF vector operands
19566;; and doing TImode cast on them
19567;; *sse_andsf3_memory - the operation taking one memory operand casted to
19568;; TImode, since backend insist on eliminating casts
19569;; on memory operands
19570;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19571;; We can not accept memory operand here as instruction reads
19572;; whole scalar. This is generated only post reload by GCC
19573;; scalar float operations that expands to logicals (fabs)
19574;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19575;; memory operand. Eventually combine can be able
19576;; to synthesize these using splitter.
19577;; sse2_anddf3, *sse2_anddf3_memory
19578;;
19579;;
19580;; These are not called andti3 etc. because we really really don't want
19581;; the compiler to widen DImode ands to TImode ands and then try to move
19582;; into DImode subregs of SSE registers, and them together, and move out
19583;; of DImode subregs again!
19584;; SSE1 single precision floating point logical operation
19585(define_expand "sse_andv4sf3"
19586 [(set (match_operand:V4SF 0 "register_operand" "")
19587 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
19588 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19589 "TARGET_SSE"
19590 "")
19591
19592(define_insn "*sse_andv4sf3"
19593 [(set (match_operand:V4SF 0 "register_operand" "=x")
19594 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19595 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19596 "TARGET_SSE
19597 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19598 "andps\t{%2, %0|%0, %2}"
19599 [(set_attr "type" "sselog")
19600 (set_attr "mode" "V4SF")])
19601
19602(define_expand "sse_nandv4sf3"
19603 [(set (match_operand:V4SF 0 "register_operand" "")
19604 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
19605 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19606 "TARGET_SSE"
19607 "")
19608
19609(define_insn "*sse_nandv4sf3"
19610 [(set (match_operand:V4SF 0 "register_operand" "=x")
19611 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
19612 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19613 "TARGET_SSE"
19614 "andnps\t{%2, %0|%0, %2}"
19615 [(set_attr "type" "sselog")
19616 (set_attr "mode" "V4SF")])
19617
19618(define_expand "sse_iorv4sf3"
19619 [(set (match_operand:V4SF 0 "register_operand" "")
19620 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
19621 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19622 "TARGET_SSE"
19623 "")
19624
19625(define_insn "*sse_iorv4sf3"
19626 [(set (match_operand:V4SF 0 "register_operand" "=x")
19627 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19628 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19629 "TARGET_SSE
19630 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19631 "orps\t{%2, %0|%0, %2}"
19632 [(set_attr "type" "sselog")
19633 (set_attr "mode" "V4SF")])
19634
19635(define_expand "sse_xorv4sf3"
19636 [(set (match_operand:V4SF 0 "register_operand" "")
19637 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
19638 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19639 "TARGET_SSE"
19640 "")
19641
19642(define_insn "*sse_xorv4sf3"
19643 [(set (match_operand:V4SF 0 "register_operand" "=x")
19644 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19645 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19646 "TARGET_SSE
19647 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19648 "xorps\t{%2, %0|%0, %2}"
19649 [(set_attr "type" "sselog")
19650 (set_attr "mode" "V4SF")])
19651
19652;; SSE2 double precision floating point logical operation
19653
19654(define_expand "sse2_andv2df3"
19655 [(set (match_operand:V2DF 0 "register_operand" "")
19656 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
19657 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19658 "TARGET_SSE2"
19659 "")
19660
19661(define_insn "*sse2_andv2df3"
19662 [(set (match_operand:V2DF 0 "register_operand" "=x")
19663 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19664 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19665 "TARGET_SSE2
19666 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19667 "andpd\t{%2, %0|%0, %2}"
19668 [(set_attr "type" "sselog")
19669 (set_attr "mode" "V2DF")])
19670
19671(define_expand "sse2_nandv2df3"
19672 [(set (match_operand:V2DF 0 "register_operand" "")
19673 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
19674 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19675 "TARGET_SSE2"
19676 "")
19677
19678(define_insn "*sse2_nandv2df3"
19679 [(set (match_operand:V2DF 0 "register_operand" "=x")
19680 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
19681 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19682 "TARGET_SSE2"
19683 "andnpd\t{%2, %0|%0, %2}"
19684 [(set_attr "type" "sselog")
19685 (set_attr "mode" "V2DF")])
19686
19687(define_expand "sse2_iorv2df3"
19688 [(set (match_operand:V2DF 0 "register_operand" "")
19689 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
19690 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19691 "TARGET_SSE2"
19692 "")
19693
19694(define_insn "*sse2_iorv2df3"
19695 [(set (match_operand:V2DF 0 "register_operand" "=x")
19696 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19697 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19698 "TARGET_SSE2
19699 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19700 "orpd\t{%2, %0|%0, %2}"
19701 [(set_attr "type" "sselog")
19702 (set_attr "mode" "V2DF")])
19703
19704(define_expand "sse2_xorv2df3"
19705 [(set (match_operand:V2DF 0 "register_operand" "")
19706 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
19707 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19708 "TARGET_SSE2"
19709 "")
19710
19711(define_insn "*sse2_xorv2df3"
19712 [(set (match_operand:V2DF 0 "register_operand" "=x")
19713 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19714 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19715 "TARGET_SSE2
19716 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19717 "xorpd\t{%2, %0|%0, %2}"
19718 [(set_attr "type" "sselog")
19719 (set_attr "mode" "V2DF")])
19720
19721;; SSE2 integral logicals. These patterns must always come after floating
19722;; point ones since we don't want compiler to use integer opcodes on floating
19723;; point SSE values to avoid matching of subregs in the match_operand.
19724(define_insn "*sse2_andti3"
19725 [(set (match_operand:TI 0 "register_operand" "=x")
19726 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19727 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19728 "TARGET_SSE2
19729 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19730 "pand\t{%2, %0|%0, %2}"
19731 [(set_attr "type" "sselog")
19732 (set_attr "mode" "TI")])
19733
19734(define_insn "sse2_andv2di3"
19735 [(set (match_operand:V2DI 0 "register_operand" "=x")
19736 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19737 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19738 "TARGET_SSE2
19739 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19740 "pand\t{%2, %0|%0, %2}"
19741 [(set_attr "type" "sselog")
19742 (set_attr "mode" "TI")])
19743
19744(define_insn "*sse2_nandti3"
19745 [(set (match_operand:TI 0 "register_operand" "=x")
19746 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19747 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19748 "TARGET_SSE2"
19749 "pandn\t{%2, %0|%0, %2}"
19750 [(set_attr "type" "sselog")
19751 (set_attr "mode" "TI")])
19752
19753(define_insn "sse2_nandv2di3"
19754 [(set (match_operand:V2DI 0 "register_operand" "=x")
19755 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19756 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19757 "TARGET_SSE2
19758 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19759 "pandn\t{%2, %0|%0, %2}"
19760 [(set_attr "type" "sselog")
19761 (set_attr "mode" "TI")])
19762
19763(define_insn "*sse2_iorti3"
19764 [(set (match_operand:TI 0 "register_operand" "=x")
19765 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19766 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19767 "TARGET_SSE2
19768 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19769 "por\t{%2, %0|%0, %2}"
19770 [(set_attr "type" "sselog")
19771 (set_attr "mode" "TI")])
19772
19773(define_insn "sse2_iorv2di3"
19774 [(set (match_operand:V2DI 0 "register_operand" "=x")
19775 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19776 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19777 "TARGET_SSE2
19778 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19779 "por\t{%2, %0|%0, %2}"
19780 [(set_attr "type" "sselog")
19781 (set_attr "mode" "TI")])
19782
19783(define_insn "*sse2_xorti3"
19784 [(set (match_operand:TI 0 "register_operand" "=x")
19785 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19786 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19787 "TARGET_SSE2
19788 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19789 "pxor\t{%2, %0|%0, %2}"
19790 [(set_attr "type" "sselog")
19791 (set_attr "mode" "TI")])
19792
19793(define_insn "sse2_xorv2di3"
19794 [(set (match_operand:V2DI 0 "register_operand" "=x")
19795 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19796 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19797 "TARGET_SSE2
19798 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19799 "pxor\t{%2, %0|%0, %2}"
19800 [(set_attr "type" "sselog")
19801 (set_attr "mode" "TI")])
19802
19803;; Use xor, but don't show input operands so they aren't live before
19804;; this insn.
19805(define_insn "sse_clrv4sf"
19806 [(set (match_operand:V4SF 0 "register_operand" "=x")
19807 (match_operand:V4SF 1 "const0_operand" "X"))]
19808 "TARGET_SSE"
19809{
19810 if (get_attr_mode (insn) == MODE_TI)
19811 return "pxor\t{%0, %0|%0, %0}";
19812 else
19813 return "xorps\t{%0, %0|%0, %0}";
19814}
19815 [(set_attr "type" "sselog")
19816 (set_attr "memory" "none")
19817 (set (attr "mode")
19818 (if_then_else
19819 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19820 (const_int 0))
19821 (ne (symbol_ref "TARGET_SSE2")
19822 (const_int 0)))
19823 (eq (symbol_ref "optimize_size")
19824 (const_int 0)))
19825 (const_string "TI")
19826 (const_string "V4SF")))])
19827
19828;; Use xor, but don't show input operands so they aren't live before
19829;; this insn.
19830(define_insn "sse_clrv2df"
19831 [(set (match_operand:V2DF 0 "register_operand" "=x")
19832 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19833 "TARGET_SSE2"
19834 "xorpd\t{%0, %0|%0, %0}"
19835 [(set_attr "type" "sselog")
19836 (set_attr "memory" "none")
19837 (set_attr "mode" "V4SF")])
19838
19839;; SSE mask-generating compares
19840
19841(define_insn "maskcmpv4sf3"
19842 [(set (match_operand:V4SI 0 "register_operand" "=x")
19843 (match_operator:V4SI 3 "sse_comparison_operator"
19844 [(match_operand:V4SF 1 "register_operand" "0")
19845 (match_operand:V4SF 2 "register_operand" "x")]))]
19846 "TARGET_SSE"
19847 "cmp%D3ps\t{%2, %0|%0, %2}"
19848 [(set_attr "type" "ssecmp")
19849 (set_attr "mode" "V4SF")])
19850
19851(define_insn "maskncmpv4sf3"
19852 [(set (match_operand:V4SI 0 "register_operand" "=x")
19853 (not:V4SI
19854 (match_operator:V4SI 3 "sse_comparison_operator"
19855 [(match_operand:V4SF 1 "register_operand" "0")
19856 (match_operand:V4SF 2 "register_operand" "x")])))]
19857 "TARGET_SSE"
19858{
19859 if (GET_CODE (operands[3]) == UNORDERED)
19860 return "cmpordps\t{%2, %0|%0, %2}";
19861 else
19862 return "cmpn%D3ps\t{%2, %0|%0, %2}";
19863}
19864 [(set_attr "type" "ssecmp")
19865 (set_attr "mode" "V4SF")])
19866
19867(define_insn "vmmaskcmpv4sf3"
19868 [(set (match_operand:V4SI 0 "register_operand" "=x")
19869 (vec_merge:V4SI
19870 (match_operator:V4SI 3 "sse_comparison_operator"
19871 [(match_operand:V4SF 1 "register_operand" "0")
19872 (match_operand:V4SF 2 "register_operand" "x")])
19873 (subreg:V4SI (match_dup 1) 0)
19874 (const_int 1)))]
19875 "TARGET_SSE"
19876 "cmp%D3ss\t{%2, %0|%0, %2}"
19877 [(set_attr "type" "ssecmp")
19878 (set_attr "mode" "SF")])
19879
19880(define_insn "vmmaskncmpv4sf3"
19881 [(set (match_operand:V4SI 0 "register_operand" "=x")
19882 (vec_merge:V4SI
19883 (not:V4SI
19884 (match_operator:V4SI 3 "sse_comparison_operator"
19885 [(match_operand:V4SF 1 "register_operand" "0")
19886 (match_operand:V4SF 2 "register_operand" "x")]))
19887 (subreg:V4SI (match_dup 1) 0)
19888 (const_int 1)))]
19889 "TARGET_SSE"
19890{
19891 if (GET_CODE (operands[3]) == UNORDERED)
19892 return "cmpordss\t{%2, %0|%0, %2}";
19893 else
19894 return "cmpn%D3ss\t{%2, %0|%0, %2}";
19895}
19896 [(set_attr "type" "ssecmp")
19897 (set_attr "mode" "SF")])
19898
19899(define_insn "sse_comi"
19900 [(set (reg:CCFP 17)
19901 (compare:CCFP (vec_select:SF
19902 (match_operand:V4SF 0 "register_operand" "x")
19903 (parallel [(const_int 0)]))
19904 (vec_select:SF
19905 (match_operand:V4SF 1 "register_operand" "x")
19906 (parallel [(const_int 0)]))))]
19907 "TARGET_SSE"
19908 "comiss\t{%1, %0|%0, %1}"
19909 [(set_attr "type" "ssecomi")
19910 (set_attr "mode" "SF")])
19911
19912(define_insn "sse_ucomi"
19913 [(set (reg:CCFPU 17)
19914 (compare:CCFPU (vec_select:SF
19915 (match_operand:V4SF 0 "register_operand" "x")
19916 (parallel [(const_int 0)]))
19917 (vec_select:SF
19918 (match_operand:V4SF 1 "register_operand" "x")
19919 (parallel [(const_int 0)]))))]
19920 "TARGET_SSE"
19921 "ucomiss\t{%1, %0|%0, %1}"
19922 [(set_attr "type" "ssecomi")
19923 (set_attr "mode" "SF")])
19924
19925
19926;; SSE unpack
19927
19928(define_insn "sse_unpckhps"
19929 [(set (match_operand:V4SF 0 "register_operand" "=x")
19930 (vec_merge:V4SF
19931 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19932 (parallel [(const_int 2)
19933 (const_int 0)
19934 (const_int 3)
19935 (const_int 1)]))
19936 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19937 (parallel [(const_int 0)
19938 (const_int 2)
19939 (const_int 1)
19940 (const_int 3)]))
19941 (const_int 5)))]
19942 "TARGET_SSE"
19943 "unpckhps\t{%2, %0|%0, %2}"
19944 [(set_attr "type" "ssecvt")
19945 (set_attr "mode" "V4SF")])
19946
19947(define_insn "sse_unpcklps"
19948 [(set (match_operand:V4SF 0 "register_operand" "=x")
19949 (vec_merge:V4SF
19950 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19951 (parallel [(const_int 0)
19952 (const_int 2)
19953 (const_int 1)
19954 (const_int 3)]))
19955 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19956 (parallel [(const_int 2)
19957 (const_int 0)
19958 (const_int 3)
19959 (const_int 1)]))
19960 (const_int 5)))]
19961 "TARGET_SSE"
19962 "unpcklps\t{%2, %0|%0, %2}"
19963 [(set_attr "type" "ssecvt")
19964 (set_attr "mode" "V4SF")])
19965
19966
19967;; SSE min/max
19968
19969(define_insn "smaxv4sf3"
19970 [(set (match_operand:V4SF 0 "register_operand" "=x")
19971 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19972 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19973 "TARGET_SSE"
19974 "maxps\t{%2, %0|%0, %2}"
19975 [(set_attr "type" "sse")
19976 (set_attr "mode" "V4SF")])
19977
19978(define_insn "vmsmaxv4sf3"
19979 [(set (match_operand:V4SF 0 "register_operand" "=x")
19980 (vec_merge:V4SF
19981 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19982 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19983 (match_dup 1)
19984 (const_int 1)))]
19985 "TARGET_SSE"
19986 "maxss\t{%2, %0|%0, %2}"
19987 [(set_attr "type" "sse")
19988 (set_attr "mode" "SF")])
19989
19990(define_insn "sminv4sf3"
19991 [(set (match_operand:V4SF 0 "register_operand" "=x")
19992 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19993 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19994 "TARGET_SSE"
19995 "minps\t{%2, %0|%0, %2}"
19996 [(set_attr "type" "sse")
19997 (set_attr "mode" "V4SF")])
19998
19999(define_insn "vmsminv4sf3"
20000 [(set (match_operand:V4SF 0 "register_operand" "=x")
20001 (vec_merge:V4SF
20002 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20003 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20004 (match_dup 1)
20005 (const_int 1)))]
20006 "TARGET_SSE"
20007 "minss\t{%2, %0|%0, %2}"
20008 [(set_attr "type" "sse")
20009 (set_attr "mode" "SF")])
20010
20011;; SSE <-> integer/MMX conversions
20012
20013(define_insn "cvtpi2ps"
20014 [(set (match_operand:V4SF 0 "register_operand" "=x")
20015 (vec_merge:V4SF
20016 (match_operand:V4SF 1 "register_operand" "0")
20017 (vec_duplicate:V4SF
20018 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20019 (const_int 12)))]
20020 "TARGET_SSE"
20021 "cvtpi2ps\t{%2, %0|%0, %2}"
20022 [(set_attr "type" "ssecvt")
20023 (set_attr "mode" "V4SF")])
20024
20025(define_insn "cvtps2pi"
20026 [(set (match_operand:V2SI 0 "register_operand" "=y")
20027 (vec_select:V2SI
20028 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20029 (parallel [(const_int 0) (const_int 1)])))]
20030 "TARGET_SSE"
20031 "cvtps2pi\t{%1, %0|%0, %1}"
20032 [(set_attr "type" "ssecvt")
20033 (set_attr "mode" "V4SF")])
20034
20035(define_insn "cvttps2pi"
20036 [(set (match_operand:V2SI 0 "register_operand" "=y")
20037 (vec_select:V2SI
20038 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20039 UNSPEC_FIX)
20040 (parallel [(const_int 0) (const_int 1)])))]
20041 "TARGET_SSE"
20042 "cvttps2pi\t{%1, %0|%0, %1}"
20043 [(set_attr "type" "ssecvt")
20044 (set_attr "mode" "SF")])
20045
20046(define_insn "cvtsi2ss"
20047 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20048 (vec_merge:V4SF
20049 (match_operand:V4SF 1 "register_operand" "0,0")
20050 (vec_duplicate:V4SF
20051 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20052 (const_int 14)))]
20053 "TARGET_SSE"
20054 "cvtsi2ss\t{%2, %0|%0, %2}"
20055 [(set_attr "type" "sseicvt")
20056 (set_attr "athlon_decode" "vector,double")
20057 (set_attr "mode" "SF")])
20058
20059(define_insn "cvtsi2ssq"
20060 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20061 (vec_merge:V4SF
20062 (match_operand:V4SF 1 "register_operand" "0,0")
20063 (vec_duplicate:V4SF
20064 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20065 (const_int 14)))]
20066 "TARGET_SSE && TARGET_64BIT"
20067 "cvtsi2ssq\t{%2, %0|%0, %2}"
20068 [(set_attr "type" "sseicvt")
20069 (set_attr "athlon_decode" "vector,double")
20070 (set_attr "mode" "SF")])
20071
20072(define_insn "cvtss2si"
20073 [(set (match_operand:SI 0 "register_operand" "=r,r")
20074 (vec_select:SI
20075 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20076 (parallel [(const_int 0)])))]
20077 "TARGET_SSE"
20078 "cvtss2si\t{%1, %0|%0, %1}"
20079 [(set_attr "type" "sseicvt")
20080 (set_attr "athlon_decode" "double,vector")
20081 (set_attr "mode" "SI")])
20082
20083(define_insn "cvtss2siq"
20084 [(set (match_operand:DI 0 "register_operand" "=r,r")
20085 (vec_select:DI
20086 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20087 (parallel [(const_int 0)])))]
20088 "TARGET_SSE"
20089 "cvtss2siq\t{%1, %0|%0, %1}"
20090 [(set_attr "type" "sseicvt")
20091 (set_attr "athlon_decode" "double,vector")
20092 (set_attr "mode" "DI")])
20093
20094(define_insn "cvttss2si"
20095 [(set (match_operand:SI 0 "register_operand" "=r,r")
20096 (vec_select:SI
20097 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20098 UNSPEC_FIX)
20099 (parallel [(const_int 0)])))]
20100 "TARGET_SSE"
20101 "cvttss2si\t{%1, %0|%0, %1}"
20102 [(set_attr "type" "sseicvt")
20103 (set_attr "mode" "SF")
20104 (set_attr "athlon_decode" "double,vector")])
20105
20106(define_insn "cvttss2siq"
20107 [(set (match_operand:DI 0 "register_operand" "=r,r")
20108 (vec_select:DI
20109 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20110 UNSPEC_FIX)
20111 (parallel [(const_int 0)])))]
20112 "TARGET_SSE && TARGET_64BIT"
20113 "cvttss2siq\t{%1, %0|%0, %1}"
20114 [(set_attr "type" "sseicvt")
20115 (set_attr "mode" "SF")
20116 (set_attr "athlon_decode" "double,vector")])
20117
20118
20119;; MMX insns
20120
20121;; MMX arithmetic
20122
20123(define_insn "addv8qi3"
20124 [(set (match_operand:V8QI 0 "register_operand" "=y")
20125 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20126 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20127 "TARGET_MMX"
20128 "paddb\t{%2, %0|%0, %2}"
20129 [(set_attr "type" "mmxadd")
20130 (set_attr "mode" "DI")])
20131
20132(define_insn "addv4hi3"
20133 [(set (match_operand:V4HI 0 "register_operand" "=y")
20134 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20135 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20136 "TARGET_MMX"
20137 "paddw\t{%2, %0|%0, %2}"
20138 [(set_attr "type" "mmxadd")
20139 (set_attr "mode" "DI")])
20140
20141(define_insn "addv2si3"
20142 [(set (match_operand:V2SI 0 "register_operand" "=y")
20143 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20144 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20145 "TARGET_MMX"
20146 "paddd\t{%2, %0|%0, %2}"
20147 [(set_attr "type" "mmxadd")
20148 (set_attr "mode" "DI")])
20149
20150(define_insn "mmx_adddi3"
20151 [(set (match_operand:DI 0 "register_operand" "=y")
20152 (unspec:DI
20153 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20154 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20155 UNSPEC_NOP))]
20156 "TARGET_MMX"
20157 "paddq\t{%2, %0|%0, %2}"
20158 [(set_attr "type" "mmxadd")
20159 (set_attr "mode" "DI")])
20160
20161(define_insn "ssaddv8qi3"
20162 [(set (match_operand:V8QI 0 "register_operand" "=y")
20163 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20164 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20165 "TARGET_MMX"
20166 "paddsb\t{%2, %0|%0, %2}"
20167 [(set_attr "type" "mmxadd")
20168 (set_attr "mode" "DI")])
20169
20170(define_insn "ssaddv4hi3"
20171 [(set (match_operand:V4HI 0 "register_operand" "=y")
20172 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20173 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20174 "TARGET_MMX"
20175 "paddsw\t{%2, %0|%0, %2}"
20176 [(set_attr "type" "mmxadd")
20177 (set_attr "mode" "DI")])
20178
20179(define_insn "usaddv8qi3"
20180 [(set (match_operand:V8QI 0 "register_operand" "=y")
20181 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20182 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20183 "TARGET_MMX"
20184 "paddusb\t{%2, %0|%0, %2}"
20185 [(set_attr "type" "mmxadd")
20186 (set_attr "mode" "DI")])
20187
20188(define_insn "usaddv4hi3"
20189 [(set (match_operand:V4HI 0 "register_operand" "=y")
20190 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20191 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20192 "TARGET_MMX"
20193 "paddusw\t{%2, %0|%0, %2}"
20194 [(set_attr "type" "mmxadd")
20195 (set_attr "mode" "DI")])
20196
20197(define_insn "subv8qi3"
20198 [(set (match_operand:V8QI 0 "register_operand" "=y")
20199 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20200 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20201 "TARGET_MMX"
20202 "psubb\t{%2, %0|%0, %2}"
20203 [(set_attr "type" "mmxadd")
20204 (set_attr "mode" "DI")])
20205
20206(define_insn "subv4hi3"
20207 [(set (match_operand:V4HI 0 "register_operand" "=y")
20208 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20209 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20210 "TARGET_MMX"
20211 "psubw\t{%2, %0|%0, %2}"
20212 [(set_attr "type" "mmxadd")
20213 (set_attr "mode" "DI")])
20214
20215(define_insn "subv2si3"
20216 [(set (match_operand:V2SI 0 "register_operand" "=y")
20217 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20218 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20219 "TARGET_MMX"
20220 "psubd\t{%2, %0|%0, %2}"
20221 [(set_attr "type" "mmxadd")
20222 (set_attr "mode" "DI")])
20223
20224(define_insn "mmx_subdi3"
20225 [(set (match_operand:DI 0 "register_operand" "=y")
20226 (unspec:DI
20227 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20228 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20229 UNSPEC_NOP))]
20230 "TARGET_MMX"
20231 "psubq\t{%2, %0|%0, %2}"
20232 [(set_attr "type" "mmxadd")
20233 (set_attr "mode" "DI")])
20234
20235(define_insn "sssubv8qi3"
20236 [(set (match_operand:V8QI 0 "register_operand" "=y")
20237 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20238 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20239 "TARGET_MMX"
20240 "psubsb\t{%2, %0|%0, %2}"
20241 [(set_attr "type" "mmxadd")
20242 (set_attr "mode" "DI")])
20243
20244(define_insn "sssubv4hi3"
20245 [(set (match_operand:V4HI 0 "register_operand" "=y")
20246 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20247 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20248 "TARGET_MMX"
20249 "psubsw\t{%2, %0|%0, %2}"
20250 [(set_attr "type" "mmxadd")
20251 (set_attr "mode" "DI")])
20252
20253(define_insn "ussubv8qi3"
20254 [(set (match_operand:V8QI 0 "register_operand" "=y")
20255 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20256 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20257 "TARGET_MMX"
20258 "psubusb\t{%2, %0|%0, %2}"
20259 [(set_attr "type" "mmxadd")
20260 (set_attr "mode" "DI")])
20261
20262(define_insn "ussubv4hi3"
20263 [(set (match_operand:V4HI 0 "register_operand" "=y")
20264 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20265 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20266 "TARGET_MMX"
20267 "psubusw\t{%2, %0|%0, %2}"
20268 [(set_attr "type" "mmxadd")
20269 (set_attr "mode" "DI")])
20270
20271(define_insn "mulv4hi3"
20272 [(set (match_operand:V4HI 0 "register_operand" "=y")
20273 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20274 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20275 "TARGET_MMX"
20276 "pmullw\t{%2, %0|%0, %2}"
20277 [(set_attr "type" "mmxmul")
20278 (set_attr "mode" "DI")])
20279
20280(define_insn "smulv4hi3_highpart"
20281 [(set (match_operand:V4HI 0 "register_operand" "=y")
20282 (truncate:V4HI
20283 (lshiftrt:V4SI
20284 (mult:V4SI (sign_extend:V4SI
20285 (match_operand:V4HI 1 "register_operand" "0"))
20286 (sign_extend:V4SI
20287 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20288 (const_int 16))))]
20289 "TARGET_MMX"
20290 "pmulhw\t{%2, %0|%0, %2}"
20291 [(set_attr "type" "mmxmul")
20292 (set_attr "mode" "DI")])
20293
20294(define_insn "umulv4hi3_highpart"
20295 [(set (match_operand:V4HI 0 "register_operand" "=y")
20296 (truncate:V4HI
20297 (lshiftrt:V4SI
20298 (mult:V4SI (zero_extend:V4SI
20299 (match_operand:V4HI 1 "register_operand" "0"))
20300 (zero_extend:V4SI
20301 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20302 (const_int 16))))]
20303 "TARGET_SSE || TARGET_3DNOW_A"
20304 "pmulhuw\t{%2, %0|%0, %2}"
20305 [(set_attr "type" "mmxmul")
20306 (set_attr "mode" "DI")])
20307
20308(define_insn "mmx_pmaddwd"
20309 [(set (match_operand:V2SI 0 "register_operand" "=y")
20310 (plus:V2SI
20311 (mult:V2SI
20312 (sign_extend:V2SI
20313 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20314 (parallel [(const_int 0) (const_int 2)])))
20315 (sign_extend:V2SI
20316 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20317 (parallel [(const_int 0) (const_int 2)]))))
20318 (mult:V2SI
20319 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20320 (parallel [(const_int 1)
20321 (const_int 3)])))
20322 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20323 (parallel [(const_int 1)
20324 (const_int 3)]))))))]
20325 "TARGET_MMX"
20326 "pmaddwd\t{%2, %0|%0, %2}"
20327 [(set_attr "type" "mmxmul")
20328 (set_attr "mode" "DI")])
20329
20330
20331;; MMX logical operations
20332;; Note we don't want to declare these as regular iordi3 insns to prevent
20333;; normal code that also wants to use the FPU from getting broken.
20334;; The UNSPECs are there to prevent the combiner from getting overly clever.
20335(define_insn "mmx_iordi3"
20336 [(set (match_operand:DI 0 "register_operand" "=y")
20337 (unspec:DI
20338 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20339 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20340 UNSPEC_NOP))]
20341 "TARGET_MMX"
20342 "por\t{%2, %0|%0, %2}"
20343 [(set_attr "type" "mmxadd")
20344 (set_attr "mode" "DI")])
20345
20346(define_insn "mmx_xordi3"
20347 [(set (match_operand:DI 0 "register_operand" "=y")
20348 (unspec:DI
20349 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20350 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20351 UNSPEC_NOP))]
20352 "TARGET_MMX"
20353 "pxor\t{%2, %0|%0, %2}"
20354 [(set_attr "type" "mmxadd")
20355 (set_attr "mode" "DI")
20356 (set_attr "memory" "none")])
20357
20358;; Same as pxor, but don't show input operands so that we don't think
20359;; they are live.
20360(define_insn "mmx_clrdi"
20361 [(set (match_operand:DI 0 "register_operand" "=y")
20362 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20363 "TARGET_MMX"
20364 "pxor\t{%0, %0|%0, %0}"
20365 [(set_attr "type" "mmxadd")
20366 (set_attr "mode" "DI")
20367 (set_attr "memory" "none")])
20368
20369(define_insn "mmx_anddi3"
20370 [(set (match_operand:DI 0 "register_operand" "=y")
20371 (unspec:DI
20372 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20373 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20374 UNSPEC_NOP))]
20375 "TARGET_MMX"
20376 "pand\t{%2, %0|%0, %2}"
20377 [(set_attr "type" "mmxadd")
20378 (set_attr "mode" "DI")])
20379
20380(define_insn "mmx_nanddi3"
20381 [(set (match_operand:DI 0 "register_operand" "=y")
20382 (unspec:DI
20383 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20384 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20385 UNSPEC_NOP))]
20386 "TARGET_MMX"
20387 "pandn\t{%2, %0|%0, %2}"
20388 [(set_attr "type" "mmxadd")
20389 (set_attr "mode" "DI")])
20390
20391
20392;; MMX unsigned averages/sum of absolute differences
20393
20394(define_insn "mmx_uavgv8qi3"
20395 [(set (match_operand:V8QI 0 "register_operand" "=y")
20396 (ashiftrt:V8QI
20397 (plus:V8QI (plus:V8QI
20398 (match_operand:V8QI 1 "register_operand" "0")
20399 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20400 (const_vector:V8QI [(const_int 1)
20401 (const_int 1)
20402 (const_int 1)
20403 (const_int 1)
20404 (const_int 1)
20405 (const_int 1)
20406 (const_int 1)
20407 (const_int 1)]))
20408 (const_int 1)))]
20409 "TARGET_SSE || TARGET_3DNOW_A"
20410 "pavgb\t{%2, %0|%0, %2}"
20411 [(set_attr "type" "mmxshft")
20412 (set_attr "mode" "DI")])
20413
20414(define_insn "mmx_uavgv4hi3"
20415 [(set (match_operand:V4HI 0 "register_operand" "=y")
20416 (ashiftrt:V4HI
20417 (plus:V4HI (plus:V4HI
20418 (match_operand:V4HI 1 "register_operand" "0")
20419 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20420 (const_vector:V4HI [(const_int 1)
20421 (const_int 1)
20422 (const_int 1)
20423 (const_int 1)]))
20424 (const_int 1)))]
20425 "TARGET_SSE || TARGET_3DNOW_A"
20426 "pavgw\t{%2, %0|%0, %2}"
20427 [(set_attr "type" "mmxshft")
20428 (set_attr "mode" "DI")])
20429
20430(define_insn "mmx_psadbw"
20431 [(set (match_operand:DI 0 "register_operand" "=y")
20432 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20433 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20434 UNSPEC_PSADBW))]
20435 "TARGET_SSE || TARGET_3DNOW_A"
20436 "psadbw\t{%2, %0|%0, %2}"
20437 [(set_attr "type" "mmxshft")
20438 (set_attr "mode" "DI")])
20439
20440
20441;; MMX insert/extract/shuffle
20442
20443(define_insn "mmx_pinsrw"
20444 [(set (match_operand:V4HI 0 "register_operand" "=y")
20445 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20446 (vec_duplicate:V4HI
20447 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20448 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20449 "TARGET_SSE || TARGET_3DNOW_A"
20450 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20451 [(set_attr "type" "mmxcvt")
20452 (set_attr "mode" "DI")])
20453
20454(define_insn "mmx_pextrw"
20455 [(set (match_operand:SI 0 "register_operand" "=r")
20456 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20457 (parallel
20458 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20459 "TARGET_SSE || TARGET_3DNOW_A"
20460 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20461 [(set_attr "type" "mmxcvt")
20462 (set_attr "mode" "DI")])
20463
20464(define_insn "mmx_pshufw"
20465 [(set (match_operand:V4HI 0 "register_operand" "=y")
20466 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20467 (match_operand:SI 2 "immediate_operand" "i")]
20468 UNSPEC_SHUFFLE))]
20469 "TARGET_SSE || TARGET_3DNOW_A"
20470 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20471 [(set_attr "type" "mmxcvt")
20472 (set_attr "mode" "DI")])
20473
20474
20475;; MMX mask-generating comparisons
20476
20477(define_insn "eqv8qi3"
20478 [(set (match_operand:V8QI 0 "register_operand" "=y")
20479 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20480 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20481 "TARGET_MMX"
20482 "pcmpeqb\t{%2, %0|%0, %2}"
20483 [(set_attr "type" "mmxcmp")
20484 (set_attr "mode" "DI")])
20485
20486(define_insn "eqv4hi3"
20487 [(set (match_operand:V4HI 0 "register_operand" "=y")
20488 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20489 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20490 "TARGET_MMX"
20491 "pcmpeqw\t{%2, %0|%0, %2}"
20492 [(set_attr "type" "mmxcmp")
20493 (set_attr "mode" "DI")])
20494
20495(define_insn "eqv2si3"
20496 [(set (match_operand:V2SI 0 "register_operand" "=y")
20497 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20498 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20499 "TARGET_MMX"
20500 "pcmpeqd\t{%2, %0|%0, %2}"
20501 [(set_attr "type" "mmxcmp")
20502 (set_attr "mode" "DI")])
20503
20504(define_insn "gtv8qi3"
20505 [(set (match_operand:V8QI 0 "register_operand" "=y")
20506 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20507 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20508 "TARGET_MMX"
20509 "pcmpgtb\t{%2, %0|%0, %2}"
20510 [(set_attr "type" "mmxcmp")
20511 (set_attr "mode" "DI")])
20512
20513(define_insn "gtv4hi3"
20514 [(set (match_operand:V4HI 0 "register_operand" "=y")
20515 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20516 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20517 "TARGET_MMX"
20518 "pcmpgtw\t{%2, %0|%0, %2}"
20519 [(set_attr "type" "mmxcmp")
20520 (set_attr "mode" "DI")])
20521
20522(define_insn "gtv2si3"
20523 [(set (match_operand:V2SI 0 "register_operand" "=y")
20524 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20525 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20526 "TARGET_MMX"
20527 "pcmpgtd\t{%2, %0|%0, %2}"
20528 [(set_attr "type" "mmxcmp")
20529 (set_attr "mode" "DI")])
20530
20531
20532;; MMX max/min insns
20533
20534(define_insn "umaxv8qi3"
20535 [(set (match_operand:V8QI 0 "register_operand" "=y")
20536 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20537 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20538 "TARGET_SSE || TARGET_3DNOW_A"
20539 "pmaxub\t{%2, %0|%0, %2}"
20540 [(set_attr "type" "mmxadd")
20541 (set_attr "mode" "DI")])
20542
20543(define_insn "smaxv4hi3"
20544 [(set (match_operand:V4HI 0 "register_operand" "=y")
20545 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20546 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20547 "TARGET_SSE || TARGET_3DNOW_A"
20548 "pmaxsw\t{%2, %0|%0, %2}"
20549 [(set_attr "type" "mmxadd")
20550 (set_attr "mode" "DI")])
20551
20552(define_insn "uminv8qi3"
20553 [(set (match_operand:V8QI 0 "register_operand" "=y")
20554 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20555 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20556 "TARGET_SSE || TARGET_3DNOW_A"
20557 "pminub\t{%2, %0|%0, %2}"
20558 [(set_attr "type" "mmxadd")
20559 (set_attr "mode" "DI")])
20560
20561(define_insn "sminv4hi3"
20562 [(set (match_operand:V4HI 0 "register_operand" "=y")
20563 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20564 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20565 "TARGET_SSE || TARGET_3DNOW_A"
20566 "pminsw\t{%2, %0|%0, %2}"
20567 [(set_attr "type" "mmxadd")
20568 (set_attr "mode" "DI")])
20569
20570
20571;; MMX shifts
20572
20573(define_insn "ashrv4hi3"
20574 [(set (match_operand:V4HI 0 "register_operand" "=y")
20575 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20576 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20577 "TARGET_MMX"
20578 "psraw\t{%2, %0|%0, %2}"
20579 [(set_attr "type" "mmxshft")
20580 (set_attr "mode" "DI")])
20581
20582(define_insn "ashrv2si3"
20583 [(set (match_operand:V2SI 0 "register_operand" "=y")
20584 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20585 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20586 "TARGET_MMX"
20587 "psrad\t{%2, %0|%0, %2}"
20588 [(set_attr "type" "mmxshft")
20589 (set_attr "mode" "DI")])
20590
20591(define_insn "lshrv4hi3"
20592 [(set (match_operand:V4HI 0 "register_operand" "=y")
20593 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20594 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20595 "TARGET_MMX"
20596 "psrlw\t{%2, %0|%0, %2}"
20597 [(set_attr "type" "mmxshft")
20598 (set_attr "mode" "DI")])
20599
20600(define_insn "lshrv2si3"
20601 [(set (match_operand:V2SI 0 "register_operand" "=y")
20602 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20603 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20604 "TARGET_MMX"
20605 "psrld\t{%2, %0|%0, %2}"
20606 [(set_attr "type" "mmxshft")
20607 (set_attr "mode" "DI")])
20608
20609;; See logical MMX insns.
20610(define_insn "mmx_lshrdi3"
20611 [(set (match_operand:DI 0 "register_operand" "=y")
20612 (unspec:DI
20613 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20614 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20615 UNSPEC_NOP))]
20616 "TARGET_MMX"
20617 "psrlq\t{%2, %0|%0, %2}"
20618 [(set_attr "type" "mmxshft")
20619 (set_attr "mode" "DI")])
20620
20621(define_insn "ashlv4hi3"
20622 [(set (match_operand:V4HI 0 "register_operand" "=y")
20623 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20624 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20625 "TARGET_MMX"
20626 "psllw\t{%2, %0|%0, %2}"
20627 [(set_attr "type" "mmxshft")
20628 (set_attr "mode" "DI")])
20629
20630(define_insn "ashlv2si3"
20631 [(set (match_operand:V2SI 0 "register_operand" "=y")
20632 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20633 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20634 "TARGET_MMX"
20635 "pslld\t{%2, %0|%0, %2}"
20636 [(set_attr "type" "mmxshft")
20637 (set_attr "mode" "DI")])
20638
20639;; See logical MMX insns.
20640(define_insn "mmx_ashldi3"
20641 [(set (match_operand:DI 0 "register_operand" "=y")
20642 (unspec:DI
20643 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20644 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20645 UNSPEC_NOP))]
20646 "TARGET_MMX"
20647 "psllq\t{%2, %0|%0, %2}"
20648 [(set_attr "type" "mmxshft")
20649 (set_attr "mode" "DI")])
20650
20651
20652;; MMX pack/unpack insns.
20653
20654(define_insn "mmx_packsswb"
20655 [(set (match_operand:V8QI 0 "register_operand" "=y")
20656 (vec_concat:V8QI
20657 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20658 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20659 "TARGET_MMX"
20660 "packsswb\t{%2, %0|%0, %2}"
20661 [(set_attr "type" "mmxshft")
20662 (set_attr "mode" "DI")])
20663
20664(define_insn "mmx_packssdw"
20665 [(set (match_operand:V4HI 0 "register_operand" "=y")
20666 (vec_concat:V4HI
20667 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20668 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20669 "TARGET_MMX"
20670 "packssdw\t{%2, %0|%0, %2}"
20671 [(set_attr "type" "mmxshft")
20672 (set_attr "mode" "DI")])
20673
20674(define_insn "mmx_packuswb"
20675 [(set (match_operand:V8QI 0 "register_operand" "=y")
20676 (vec_concat:V8QI
20677 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20678 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20679 "TARGET_MMX"
20680 "packuswb\t{%2, %0|%0, %2}"
20681 [(set_attr "type" "mmxshft")
20682 (set_attr "mode" "DI")])
20683
20684(define_insn "mmx_punpckhbw"
20685 [(set (match_operand:V8QI 0 "register_operand" "=y")
20686 (vec_merge:V8QI
20687 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20688 (parallel [(const_int 4)
20689 (const_int 0)
20690 (const_int 5)
20691 (const_int 1)
20692 (const_int 6)
20693 (const_int 2)
20694 (const_int 7)
20695 (const_int 3)]))
20696 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20697 (parallel [(const_int 0)
20698 (const_int 4)
20699 (const_int 1)
20700 (const_int 5)
20701 (const_int 2)
20702 (const_int 6)
20703 (const_int 3)
20704 (const_int 7)]))
20705 (const_int 85)))]
20706 "TARGET_MMX"
20707 "punpckhbw\t{%2, %0|%0, %2}"
20708 [(set_attr "type" "mmxcvt")
20709 (set_attr "mode" "DI")])
20710
20711(define_insn "mmx_punpckhwd"
20712 [(set (match_operand:V4HI 0 "register_operand" "=y")
20713 (vec_merge:V4HI
20714 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20715 (parallel [(const_int 0)
20716 (const_int 2)
20717 (const_int 1)
20718 (const_int 3)]))
20719 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20720 (parallel [(const_int 2)
20721 (const_int 0)
20722 (const_int 3)
20723 (const_int 1)]))
20724 (const_int 5)))]
20725 "TARGET_MMX"
20726 "punpckhwd\t{%2, %0|%0, %2}"
20727 [(set_attr "type" "mmxcvt")
20728 (set_attr "mode" "DI")])
20729
20730(define_insn "mmx_punpckhdq"
20731 [(set (match_operand:V2SI 0 "register_operand" "=y")
20732 (vec_merge:V2SI
20733 (match_operand:V2SI 1 "register_operand" "0")
20734 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20735 (parallel [(const_int 1)
20736 (const_int 0)]))
20737 (const_int 1)))]
20738 "TARGET_MMX"
20739 "punpckhdq\t{%2, %0|%0, %2}"
20740 [(set_attr "type" "mmxcvt")
20741 (set_attr "mode" "DI")])
20742
20743(define_insn "mmx_punpcklbw"
20744 [(set (match_operand:V8QI 0 "register_operand" "=y")
20745 (vec_merge:V8QI
20746 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20747 (parallel [(const_int 0)
20748 (const_int 4)
20749 (const_int 1)
20750 (const_int 5)
20751 (const_int 2)
20752 (const_int 6)
20753 (const_int 3)
20754 (const_int 7)]))
20755 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20756 (parallel [(const_int 4)
20757 (const_int 0)
20758 (const_int 5)
20759 (const_int 1)
20760 (const_int 6)
20761 (const_int 2)
20762 (const_int 7)
20763 (const_int 3)]))
20764 (const_int 85)))]
20765 "TARGET_MMX"
20766 "punpcklbw\t{%2, %0|%0, %2}"
20767 [(set_attr "type" "mmxcvt")
20768 (set_attr "mode" "DI")])
20769
20770(define_insn "mmx_punpcklwd"
20771 [(set (match_operand:V4HI 0 "register_operand" "=y")
20772 (vec_merge:V4HI
20773 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20774 (parallel [(const_int 2)
20775 (const_int 0)
20776 (const_int 3)
20777 (const_int 1)]))
20778 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20779 (parallel [(const_int 0)
20780 (const_int 2)
20781 (const_int 1)
20782 (const_int 3)]))
20783 (const_int 5)))]
20784 "TARGET_MMX"
20785 "punpcklwd\t{%2, %0|%0, %2}"
20786 [(set_attr "type" "mmxcvt")
20787 (set_attr "mode" "DI")])
20788
20789(define_insn "mmx_punpckldq"
20790 [(set (match_operand:V2SI 0 "register_operand" "=y")
20791 (vec_merge:V2SI
20792 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20793 (parallel [(const_int 1)
20794 (const_int 0)]))
20795 (match_operand:V2SI 2 "register_operand" "y")
20796 (const_int 1)))]
20797 "TARGET_MMX"
20798 "punpckldq\t{%2, %0|%0, %2}"
20799 [(set_attr "type" "mmxcvt")
20800 (set_attr "mode" "DI")])
20801
20802
20803;; Miscellaneous stuff
20804
20805(define_insn "emms"
20806 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20807 (clobber (reg:XF 8))
20808 (clobber (reg:XF 9))
20809 (clobber (reg:XF 10))
20810 (clobber (reg:XF 11))
20811 (clobber (reg:XF 12))
20812 (clobber (reg:XF 13))
20813 (clobber (reg:XF 14))
20814 (clobber (reg:XF 15))
20815 (clobber (reg:DI 29))
20816 (clobber (reg:DI 30))
20817 (clobber (reg:DI 31))
20818 (clobber (reg:DI 32))
20819 (clobber (reg:DI 33))
20820 (clobber (reg:DI 34))
20821 (clobber (reg:DI 35))
20822 (clobber (reg:DI 36))]
20823 "TARGET_MMX"
20824 "emms"
20825 [(set_attr "type" "mmx")
20826 (set_attr "memory" "unknown")])
20827
20828(define_insn "ldmxcsr"
20829 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20830 UNSPECV_LDMXCSR)]
20831 "TARGET_SSE"
20832 "ldmxcsr\t%0"
20833 [(set_attr "type" "sse")
20834 (set_attr "memory" "load")])
20835
20836(define_insn "stmxcsr"
20837 [(set (match_operand:SI 0 "memory_operand" "=m")
20838 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20839 "TARGET_SSE"
20840 "stmxcsr\t%0"
20841 [(set_attr "type" "sse")
20842 (set_attr "memory" "store")])
20843
20844(define_expand "sfence"
20845 [(set (match_dup 0)
20846 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20847 "TARGET_SSE || TARGET_3DNOW_A"
20848{
20849 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20850 MEM_VOLATILE_P (operands[0]) = 1;
20851})
20852
20853(define_insn "*sfence_insn"
20854 [(set (match_operand:BLK 0 "" "")
20855 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20856 "TARGET_SSE || TARGET_3DNOW_A"
20857 "sfence"
20858 [(set_attr "type" "sse")
20859 (set_attr "memory" "unknown")])
20860
20861(define_expand "sse_prologue_save"
20862 [(parallel [(set (match_operand:BLK 0 "" "")
20863 (unspec:BLK [(reg:DI 21)
20864 (reg:DI 22)
20865 (reg:DI 23)
20866 (reg:DI 24)
20867 (reg:DI 25)
20868 (reg:DI 26)
20869 (reg:DI 27)
20870 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20871 (use (match_operand:DI 1 "register_operand" ""))
20872 (use (match_operand:DI 2 "immediate_operand" ""))
20873 (use (label_ref:DI (match_operand 3 "" "")))])]
20874 "TARGET_64BIT"
20875 "")
20876
20877(define_insn "*sse_prologue_save_insn"
20878 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20879 (match_operand:DI 4 "const_int_operand" "n")))
20880 (unspec:BLK [(reg:DI 21)
20881 (reg:DI 22)
20882 (reg:DI 23)
20883 (reg:DI 24)
20884 (reg:DI 25)
20885 (reg:DI 26)
20886 (reg:DI 27)
20887 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20888 (use (match_operand:DI 1 "register_operand" "r"))
20889 (use (match_operand:DI 2 "const_int_operand" "i"))
20890 (use (label_ref:DI (match_operand 3 "" "X")))]
20891 "TARGET_64BIT
20892 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20893 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20894 "*
20895{
20896 int i;
20897 operands[0] = gen_rtx_MEM (Pmode,
20898 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20899 output_asm_insn (\"jmp\\t%A1\", operands);
20900 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20901 {
20902 operands[4] = adjust_address (operands[0], DImode, i*16);
20903 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20904 PUT_MODE (operands[4], TImode);
20905 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20906 output_asm_insn (\"rex\", operands);
20907 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20908 }
20909 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20910 CODE_LABEL_NUMBER (operands[3]));
20911 RET;
20912}
20913 "
20914 [(set_attr "type" "other")
20915 (set_attr "length_immediate" "0")
20916 (set_attr "length_address" "0")
20917 (set_attr "length" "135")
20918 (set_attr "memory" "store")
20919 (set_attr "modrm" "0")
20920 (set_attr "mode" "DI")])
20921
20922;; 3Dnow! instructions
20923
20924(define_insn "addv2sf3"
20925 [(set (match_operand:V2SF 0 "register_operand" "=y")
20926 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20927 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20928 "TARGET_3DNOW"
20929 "pfadd\\t{%2, %0|%0, %2}"
20930 [(set_attr "type" "mmxadd")
20931 (set_attr "mode" "V2SF")])
20932
20933(define_insn "subv2sf3"
20934 [(set (match_operand:V2SF 0 "register_operand" "=y")
20935 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20936 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20937 "TARGET_3DNOW"
20938 "pfsub\\t{%2, %0|%0, %2}"
20939 [(set_attr "type" "mmxadd")
20940 (set_attr "mode" "V2SF")])
20941
20942(define_insn "subrv2sf3"
20943 [(set (match_operand:V2SF 0 "register_operand" "=y")
20944 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20945 (match_operand:V2SF 1 "register_operand" "0")))]
20946 "TARGET_3DNOW"
20947 "pfsubr\\t{%2, %0|%0, %2}"
20948 [(set_attr "type" "mmxadd")
20949 (set_attr "mode" "V2SF")])
20950
20951(define_insn "gtv2sf3"
20952 [(set (match_operand:V2SI 0 "register_operand" "=y")
20953 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20954 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20955 "TARGET_3DNOW"
20956 "pfcmpgt\\t{%2, %0|%0, %2}"
20957 [(set_attr "type" "mmxcmp")
20958 (set_attr "mode" "V2SF")])
20959
20960(define_insn "gev2sf3"
20961 [(set (match_operand:V2SI 0 "register_operand" "=y")
20962 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20963 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20964 "TARGET_3DNOW"
20965 "pfcmpge\\t{%2, %0|%0, %2}"
20966 [(set_attr "type" "mmxcmp")
20967 (set_attr "mode" "V2SF")])
20968
20969(define_insn "eqv2sf3"
20970 [(set (match_operand:V2SI 0 "register_operand" "=y")
20971 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20972 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20973 "TARGET_3DNOW"
20974 "pfcmpeq\\t{%2, %0|%0, %2}"
20975 [(set_attr "type" "mmxcmp")
20976 (set_attr "mode" "V2SF")])
20977
20978(define_insn "pfmaxv2sf3"
20979 [(set (match_operand:V2SF 0 "register_operand" "=y")
20980 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20981 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20982 "TARGET_3DNOW"
20983 "pfmax\\t{%2, %0|%0, %2}"
20984 [(set_attr "type" "mmxadd")
20985 (set_attr "mode" "V2SF")])
20986
20987(define_insn "pfminv2sf3"
20988 [(set (match_operand:V2SF 0 "register_operand" "=y")
20989 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20990 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20991 "TARGET_3DNOW"
20992 "pfmin\\t{%2, %0|%0, %2}"
20993 [(set_attr "type" "mmxadd")
20994 (set_attr "mode" "V2SF")])
20995
20996(define_insn "mulv2sf3"
20997 [(set (match_operand:V2SF 0 "register_operand" "=y")
20998 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20999 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21000 "TARGET_3DNOW"
21001 "pfmul\\t{%2, %0|%0, %2}"
21002 [(set_attr "type" "mmxmul")
21003 (set_attr "mode" "V2SF")])
21004
21005(define_insn "femms"
21006 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21007 (clobber (reg:XF 8))
21008 (clobber (reg:XF 9))
21009 (clobber (reg:XF 10))
21010 (clobber (reg:XF 11))
21011 (clobber (reg:XF 12))
21012 (clobber (reg:XF 13))
21013 (clobber (reg:XF 14))
21014 (clobber (reg:XF 15))
21015 (clobber (reg:DI 29))
21016 (clobber (reg:DI 30))
21017 (clobber (reg:DI 31))
21018 (clobber (reg:DI 32))
21019 (clobber (reg:DI 33))
21020 (clobber (reg:DI 34))
21021 (clobber (reg:DI 35))
21022 (clobber (reg:DI 36))]
21023 "TARGET_3DNOW"
21024 "femms"
21025 [(set_attr "type" "mmx")
21026 (set_attr "memory" "none")])
21027
21028(define_insn "pf2id"
21029 [(set (match_operand:V2SI 0 "register_operand" "=y")
21030 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21031 "TARGET_3DNOW"
21032 "pf2id\\t{%1, %0|%0, %1}"
21033 [(set_attr "type" "mmxcvt")
21034 (set_attr "mode" "V2SF")])
21035
21036(define_insn "pf2iw"
21037 [(set (match_operand:V2SI 0 "register_operand" "=y")
21038 (sign_extend:V2SI
21039 (ss_truncate:V2HI
21040 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21041 "TARGET_3DNOW_A"
21042 "pf2iw\\t{%1, %0|%0, %1}"
21043 [(set_attr "type" "mmxcvt")
21044 (set_attr "mode" "V2SF")])
21045
21046(define_insn "pfacc"
21047 [(set (match_operand:V2SF 0 "register_operand" "=y")
21048 (vec_concat:V2SF
21049 (plus:SF
21050 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21051 (parallel [(const_int 0)]))
21052 (vec_select:SF (match_dup 1)
21053 (parallel [(const_int 1)])))
21054 (plus:SF
21055 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21056 (parallel [(const_int 0)]))
21057 (vec_select:SF (match_dup 2)
21058 (parallel [(const_int 1)])))))]
21059 "TARGET_3DNOW"
21060 "pfacc\\t{%2, %0|%0, %2}"
21061 [(set_attr "type" "mmxadd")
21062 (set_attr "mode" "V2SF")])
21063
21064(define_insn "pfnacc"
21065 [(set (match_operand:V2SF 0 "register_operand" "=y")
21066 (vec_concat:V2SF
21067 (minus:SF
21068 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21069 (parallel [(const_int 0)]))
21070 (vec_select:SF (match_dup 1)
21071 (parallel [(const_int 1)])))
21072 (minus:SF
21073 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21074 (parallel [(const_int 0)]))
21075 (vec_select:SF (match_dup 2)
21076 (parallel [(const_int 1)])))))]
21077 "TARGET_3DNOW_A"
21078 "pfnacc\\t{%2, %0|%0, %2}"
21079 [(set_attr "type" "mmxadd")
21080 (set_attr "mode" "V2SF")])
21081
21082(define_insn "pfpnacc"
21083 [(set (match_operand:V2SF 0 "register_operand" "=y")
21084 (vec_concat:V2SF
21085 (minus:SF
21086 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21087 (parallel [(const_int 0)]))
21088 (vec_select:SF (match_dup 1)
21089 (parallel [(const_int 1)])))
21090 (plus:SF
21091 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21092 (parallel [(const_int 0)]))
21093 (vec_select:SF (match_dup 2)
21094 (parallel [(const_int 1)])))))]
21095 "TARGET_3DNOW_A"
21096 "pfpnacc\\t{%2, %0|%0, %2}"
21097 [(set_attr "type" "mmxadd")
21098 (set_attr "mode" "V2SF")])
21099
21100(define_insn "pi2fw"
21101 [(set (match_operand:V2SF 0 "register_operand" "=y")
21102 (float:V2SF
21103 (vec_concat:V2SI
21104 (sign_extend:SI
21105 (truncate:HI
21106 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21107 (parallel [(const_int 0)]))))
21108 (sign_extend:SI
21109 (truncate:HI
21110 (vec_select:SI (match_dup 1)
21111 (parallel [(const_int 1)])))))))]
21112 "TARGET_3DNOW_A"
21113 "pi2fw\\t{%1, %0|%0, %1}"
21114 [(set_attr "type" "mmxcvt")
21115 (set_attr "mode" "V2SF")])
21116
21117(define_insn "floatv2si2"
21118 [(set (match_operand:V2SF 0 "register_operand" "=y")
21119 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21120 "TARGET_3DNOW"
21121 "pi2fd\\t{%1, %0|%0, %1}"
21122 [(set_attr "type" "mmxcvt")
21123 (set_attr "mode" "V2SF")])
21124
21125;; This insn is identical to pavgb in operation, but the opcode is
21126;; different. To avoid accidentally matching pavgb, use an unspec.
21127
21128(define_insn "pavgusb"
21129 [(set (match_operand:V8QI 0 "register_operand" "=y")
21130 (unspec:V8QI
21131 [(match_operand:V8QI 1 "register_operand" "0")
21132 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21133 UNSPEC_PAVGUSB))]
21134 "TARGET_3DNOW"
21135 "pavgusb\\t{%2, %0|%0, %2}"
21136 [(set_attr "type" "mmxshft")
21137 (set_attr "mode" "TI")])
21138
21139;; 3DNow reciprocal and sqrt
21140
21141(define_insn "pfrcpv2sf2"
21142 [(set (match_operand:V2SF 0 "register_operand" "=y")
21143 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21144 UNSPEC_PFRCP))]
21145 "TARGET_3DNOW"
21146 "pfrcp\\t{%1, %0|%0, %1}"
21147 [(set_attr "type" "mmx")
21148 (set_attr "mode" "TI")])
21149
21150(define_insn "pfrcpit1v2sf3"
21151 [(set (match_operand:V2SF 0 "register_operand" "=y")
21152 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21153 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21154 UNSPEC_PFRCPIT1))]
21155 "TARGET_3DNOW"
21156 "pfrcpit1\\t{%2, %0|%0, %2}"
21157 [(set_attr "type" "mmx")
21158 (set_attr "mode" "TI")])
21159
21160(define_insn "pfrcpit2v2sf3"
21161 [(set (match_operand:V2SF 0 "register_operand" "=y")
21162 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21163 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21164 UNSPEC_PFRCPIT2))]
21165 "TARGET_3DNOW"
21166 "pfrcpit2\\t{%2, %0|%0, %2}"
21167 [(set_attr "type" "mmx")
21168 (set_attr "mode" "TI")])
21169
21170(define_insn "pfrsqrtv2sf2"
21171 [(set (match_operand:V2SF 0 "register_operand" "=y")
21172 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21173 UNSPEC_PFRSQRT))]
21174 "TARGET_3DNOW"
21175 "pfrsqrt\\t{%1, %0|%0, %1}"
21176 [(set_attr "type" "mmx")
21177 (set_attr "mode" "TI")])
21178
21179(define_insn "pfrsqit1v2sf3"
21180 [(set (match_operand:V2SF 0 "register_operand" "=y")
21181 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21182 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21183 UNSPEC_PFRSQIT1))]
21184 "TARGET_3DNOW"
21185 "pfrsqit1\\t{%2, %0|%0, %2}"
21186 [(set_attr "type" "mmx")
21187 (set_attr "mode" "TI")])
21188
21189(define_insn "pmulhrwv4hi3"
21190 [(set (match_operand:V4HI 0 "register_operand" "=y")
21191 (truncate:V4HI
21192 (lshiftrt:V4SI
21193 (plus:V4SI
21194 (mult:V4SI
21195 (sign_extend:V4SI
21196 (match_operand:V4HI 1 "register_operand" "0"))
21197 (sign_extend:V4SI
21198 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21199 (const_vector:V4SI [(const_int 32768)
21200 (const_int 32768)
21201 (const_int 32768)
21202 (const_int 32768)]))
21203 (const_int 16))))]
21204 "TARGET_3DNOW"
21205 "pmulhrw\\t{%2, %0|%0, %2}"
21206 [(set_attr "type" "mmxmul")
21207 (set_attr "mode" "TI")])
21208
21209(define_insn "pswapdv2si2"
21210 [(set (match_operand:V2SI 0 "register_operand" "=y")
21211 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21212 (parallel [(const_int 1) (const_int 0)])))]
21213 "TARGET_3DNOW_A"
21214 "pswapd\\t{%1, %0|%0, %1}"
21215 [(set_attr "type" "mmxcvt")
21216 (set_attr "mode" "TI")])
21217
21218(define_insn "pswapdv2sf2"
21219 [(set (match_operand:V2SF 0 "register_operand" "=y")
21220 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21221 (parallel [(const_int 1) (const_int 0)])))]
21222 "TARGET_3DNOW_A"
21223 "pswapd\\t{%1, %0|%0, %1}"
21224 [(set_attr "type" "mmxcvt")
21225 (set_attr "mode" "TI")])
21226
21227(define_expand "prefetch"
21228 [(prefetch (match_operand 0 "address_operand" "")
21229 (match_operand:SI 1 "const_int_operand" "")
21230 (match_operand:SI 2 "const_int_operand" ""))]
21231 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21232{
21233 int rw = INTVAL (operands[1]);
21234 int locality = INTVAL (operands[2]);
21235
21236 if (rw != 0 && rw != 1)
21237 abort ();
21238 if (locality < 0 || locality > 3)
21239 abort ();
21240 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21241 abort ();
21242
21243 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21244 suported by SSE counterpart or the SSE prefetch is not available
21245 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21246 of locality. */
21247 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21248 operands[2] = GEN_INT (3);
21249 else
21250 operands[1] = const0_rtx;
21251})
21252
21253(define_insn "*prefetch_sse"
21254 [(prefetch (match_operand:SI 0 "address_operand" "p")
21255 (const_int 0)
21256 (match_operand:SI 1 "const_int_operand" ""))]
21257 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21258{
21259 static const char * const patterns[4] = {
21260 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21261 };
21262
21263 int locality = INTVAL (operands[1]);
21264 if (locality < 0 || locality > 3)
21265 abort ();
21266
21267 return patterns[locality];
21268}
21269 [(set_attr "type" "sse")
21270 (set_attr "memory" "none")])
21271
21272(define_insn "*prefetch_sse_rex"
21273 [(prefetch (match_operand:DI 0 "address_operand" "p")
21274 (const_int 0)
21275 (match_operand:SI 1 "const_int_operand" ""))]
21276 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21277{
21278 static const char * const patterns[4] = {
21279 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21280 };
21281
21282 int locality = INTVAL (operands[1]);
21283 if (locality < 0 || locality > 3)
21284 abort ();
21285
21286 return patterns[locality];
21287}
21288 [(set_attr "type" "sse")
21289 (set_attr "memory" "none")])
21290
21291(define_insn "*prefetch_3dnow"
21292 [(prefetch (match_operand:SI 0 "address_operand" "p")
21293 (match_operand:SI 1 "const_int_operand" "n")
21294 (const_int 3))]
21295 "TARGET_3DNOW && !TARGET_64BIT"
21296{
21297 if (INTVAL (operands[1]) == 0)
21298 return "prefetch\t%a0";
21299 else
21300 return "prefetchw\t%a0";
21301}
21302 [(set_attr "type" "mmx")
21303 (set_attr "memory" "none")])
21304
21305(define_insn "*prefetch_3dnow_rex"
21306 [(prefetch (match_operand:DI 0 "address_operand" "p")
21307 (match_operand:SI 1 "const_int_operand" "n")
21308 (const_int 3))]
21309 "TARGET_3DNOW && TARGET_64BIT"
21310{
21311 if (INTVAL (operands[1]) == 0)
21312 return "prefetch\t%a0";
21313 else
21314 return "prefetchw\t%a0";
21315}
21316 [(set_attr "type" "mmx")
21317 (set_attr "memory" "none")])
21318
21319;; SSE2 support
21320
21321(define_insn "addv2df3"
21322 [(set (match_operand:V2DF 0 "register_operand" "=x")
21323 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21324 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21325 "TARGET_SSE2"
21326 "addpd\t{%2, %0|%0, %2}"
21327 [(set_attr "type" "sseadd")
21328 (set_attr "mode" "V2DF")])
21329
21330(define_insn "vmaddv2df3"
21331 [(set (match_operand:V2DF 0 "register_operand" "=x")
21332 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21333 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21334 (match_dup 1)
21335 (const_int 1)))]
21336 "TARGET_SSE2"
21337 "addsd\t{%2, %0|%0, %2}"
21338 [(set_attr "type" "sseadd")
21339 (set_attr "mode" "DF")])
21340
21341(define_insn "subv2df3"
21342 [(set (match_operand:V2DF 0 "register_operand" "=x")
21343 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21344 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21345 "TARGET_SSE2"
21346 "subpd\t{%2, %0|%0, %2}"
21347 [(set_attr "type" "sseadd")
21348 (set_attr "mode" "V2DF")])
21349
21350(define_insn "vmsubv2df3"
21351 [(set (match_operand:V2DF 0 "register_operand" "=x")
21352 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21353 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21354 (match_dup 1)
21355 (const_int 1)))]
21356 "TARGET_SSE2"
21357 "subsd\t{%2, %0|%0, %2}"
21358 [(set_attr "type" "sseadd")
21359 (set_attr "mode" "DF")])
21360
21361(define_insn "mulv2df3"
21362 [(set (match_operand:V2DF 0 "register_operand" "=x")
21363 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21364 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21365 "TARGET_SSE2"
21366 "mulpd\t{%2, %0|%0, %2}"
21367 [(set_attr "type" "ssemul")
21368 (set_attr "mode" "V2DF")])
21369
21370(define_insn "vmmulv2df3"
21371 [(set (match_operand:V2DF 0 "register_operand" "=x")
21372 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21373 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21374 (match_dup 1)
21375 (const_int 1)))]
21376 "TARGET_SSE2"
21377 "mulsd\t{%2, %0|%0, %2}"
21378 [(set_attr "type" "ssemul")
21379 (set_attr "mode" "DF")])
21380
21381(define_insn "divv2df3"
21382 [(set (match_operand:V2DF 0 "register_operand" "=x")
21383 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21384 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21385 "TARGET_SSE2"
21386 "divpd\t{%2, %0|%0, %2}"
21387 [(set_attr "type" "ssediv")
21388 (set_attr "mode" "V2DF")])
21389
21390(define_insn "vmdivv2df3"
21391 [(set (match_operand:V2DF 0 "register_operand" "=x")
21392 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21393 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21394 (match_dup 1)
21395 (const_int 1)))]
21396 "TARGET_SSE2"
21397 "divsd\t{%2, %0|%0, %2}"
21398 [(set_attr "type" "ssediv")
21399 (set_attr "mode" "DF")])
21400
21401;; SSE min/max
21402
21403(define_insn "smaxv2df3"
21404 [(set (match_operand:V2DF 0 "register_operand" "=x")
21405 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21406 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21407 "TARGET_SSE2"
21408 "maxpd\t{%2, %0|%0, %2}"
21409 [(set_attr "type" "sseadd")
21410 (set_attr "mode" "V2DF")])
21411
21412(define_insn "vmsmaxv2df3"
21413 [(set (match_operand:V2DF 0 "register_operand" "=x")
21414 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21415 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21416 (match_dup 1)
21417 (const_int 1)))]
21418 "TARGET_SSE2"
21419 "maxsd\t{%2, %0|%0, %2}"
21420 [(set_attr "type" "sseadd")
21421 (set_attr "mode" "DF")])
21422
21423(define_insn "sminv2df3"
21424 [(set (match_operand:V2DF 0 "register_operand" "=x")
21425 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21426 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21427 "TARGET_SSE2"
21428 "minpd\t{%2, %0|%0, %2}"
21429 [(set_attr "type" "sseadd")
21430 (set_attr "mode" "V2DF")])
21431
21432(define_insn "vmsminv2df3"
21433 [(set (match_operand:V2DF 0 "register_operand" "=x")
21434 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21435 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21436 (match_dup 1)
21437 (const_int 1)))]
21438 "TARGET_SSE2"
21439 "minsd\t{%2, %0|%0, %2}"
21440 [(set_attr "type" "sseadd")
21441 (set_attr "mode" "DF")])
21442;; SSE2 square root. There doesn't appear to be an extension for the
21443;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21444
21445(define_insn "sqrtv2df2"
21446 [(set (match_operand:V2DF 0 "register_operand" "=x")
21447 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21448 "TARGET_SSE2"
21449 "sqrtpd\t{%1, %0|%0, %1}"
21450 [(set_attr "type" "sse")
21451 (set_attr "mode" "V2DF")])
21452
21453(define_insn "vmsqrtv2df2"
21454 [(set (match_operand:V2DF 0 "register_operand" "=x")
21455 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21456 (match_operand:V2DF 2 "register_operand" "0")
21457 (const_int 1)))]
21458 "TARGET_SSE2"
21459 "sqrtsd\t{%1, %0|%0, %1}"
21460 [(set_attr "type" "sse")
21461 (set_attr "mode" "SF")])
21462
21463;; SSE mask-generating compares
21464
21465(define_insn "maskcmpv2df3"
21466 [(set (match_operand:V2DI 0 "register_operand" "=x")
21467 (match_operator:V2DI 3 "sse_comparison_operator"
21468 [(match_operand:V2DF 1 "register_operand" "0")
21469 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21470 "TARGET_SSE2"
21471 "cmp%D3pd\t{%2, %0|%0, %2}"
21472 [(set_attr "type" "ssecmp")
21473 (set_attr "mode" "V2DF")])
21474
21475(define_insn "maskncmpv2df3"
21476 [(set (match_operand:V2DI 0 "register_operand" "=x")
21477 (not:V2DI
21478 (match_operator:V2DI 3 "sse_comparison_operator"
21479 [(match_operand:V2DF 1 "register_operand" "0")
21480 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21481 "TARGET_SSE2"
21482{
21483 if (GET_CODE (operands[3]) == UNORDERED)
21484 return "cmpordps\t{%2, %0|%0, %2}";
21485 else
21486 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21487}
21488 [(set_attr "type" "ssecmp")
21489 (set_attr "mode" "V2DF")])
21490
21491(define_insn "vmmaskcmpv2df3"
21492 [(set (match_operand:V2DI 0 "register_operand" "=x")
21493 (vec_merge:V2DI
21494 (match_operator:V2DI 3 "sse_comparison_operator"
21495 [(match_operand:V2DF 1 "register_operand" "0")
21496 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21497 (subreg:V2DI (match_dup 1) 0)
21498 (const_int 1)))]
21499 "TARGET_SSE2"
21500 "cmp%D3sd\t{%2, %0|%0, %2}"
21501 [(set_attr "type" "ssecmp")
21502 (set_attr "mode" "DF")])
21503
21504(define_insn "vmmaskncmpv2df3"
21505 [(set (match_operand:V2DI 0 "register_operand" "=x")
21506 (vec_merge:V2DI
21507 (not:V2DI
21508 (match_operator:V2DI 3 "sse_comparison_operator"
21509 [(match_operand:V2DF 1 "register_operand" "0")
21510 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21511 (subreg:V2DI (match_dup 1) 0)
21512 (const_int 1)))]
21513 "TARGET_SSE2"
21514{
21515 if (GET_CODE (operands[3]) == UNORDERED)
21516 return "cmpordsd\t{%2, %0|%0, %2}";
21517 else
21518 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21519}
21520 [(set_attr "type" "ssecmp")
21521 (set_attr "mode" "DF")])
21522
21523(define_insn "sse2_comi"
21524 [(set (reg:CCFP 17)
21525 (compare:CCFP (vec_select:DF
21526 (match_operand:V2DF 0 "register_operand" "x")
21527 (parallel [(const_int 0)]))
21528 (vec_select:DF
21529 (match_operand:V2DF 1 "register_operand" "x")
21530 (parallel [(const_int 0)]))))]
21531 "TARGET_SSE2"
21532 "comisd\t{%1, %0|%0, %1}"
21533 [(set_attr "type" "ssecomi")
21534 (set_attr "mode" "DF")])
21535
21536(define_insn "sse2_ucomi"
21537 [(set (reg:CCFPU 17)
21538 (compare:CCFPU (vec_select:DF
21539 (match_operand:V2DF 0 "register_operand" "x")
21540 (parallel [(const_int 0)]))
21541 (vec_select:DF
21542 (match_operand:V2DF 1 "register_operand" "x")
21543 (parallel [(const_int 0)]))))]
21544 "TARGET_SSE2"
21545 "ucomisd\t{%1, %0|%0, %1}"
21546 [(set_attr "type" "ssecomi")
21547 (set_attr "mode" "DF")])
21548
21549;; SSE Strange Moves.
21550
21551(define_insn "sse2_movmskpd"
21552 [(set (match_operand:SI 0 "register_operand" "=r")
21553 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21554 UNSPEC_MOVMSK))]
21555 "TARGET_SSE2"
21556 "movmskpd\t{%1, %0|%0, %1}"
21557 [(set_attr "type" "ssecvt")
21558 (set_attr "mode" "V2DF")])
21559
21560(define_insn "sse2_pmovmskb"
21561 [(set (match_operand:SI 0 "register_operand" "=r")
21562 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21563 UNSPEC_MOVMSK))]
21564 "TARGET_SSE2"
21565 "pmovmskb\t{%1, %0|%0, %1}"
21566 [(set_attr "type" "ssecvt")
21567 (set_attr "mode" "V2DF")])
21568
21569(define_insn "sse2_maskmovdqu"
21570 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21571 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21572 (match_operand:V16QI 2 "register_operand" "x")]
21573 UNSPEC_MASKMOV))]
21574 "TARGET_SSE2"
21575 ;; @@@ check ordering of operands in intel/nonintel syntax
21576 "maskmovdqu\t{%2, %1|%1, %2}"
21577 [(set_attr "type" "ssecvt")
21578 (set_attr "mode" "TI")])
21579
21580(define_insn "sse2_maskmovdqu_rex64"
21581 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21582 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21583 (match_operand:V16QI 2 "register_operand" "x")]
21584 UNSPEC_MASKMOV))]
21585 "TARGET_SSE2"
21586 ;; @@@ check ordering of operands in intel/nonintel syntax
21587 "maskmovdqu\t{%2, %1|%1, %2}"
21588 [(set_attr "type" "ssecvt")
21589 (set_attr "mode" "TI")])
21590
21591(define_insn "sse2_movntv2df"
21592 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21593 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21594 UNSPEC_MOVNT))]
21595 "TARGET_SSE2"
21596 "movntpd\t{%1, %0|%0, %1}"
21597 [(set_attr "type" "ssecvt")
21598 (set_attr "mode" "V2DF")])
21599
21600(define_insn "sse2_movntv2di"
21601 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21602 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21603 UNSPEC_MOVNT))]
21604 "TARGET_SSE2"
21605 "movntdq\t{%1, %0|%0, %1}"
21606 [(set_attr "type" "ssecvt")
21607 (set_attr "mode" "TI")])
21608
21609(define_insn "sse2_movntsi"
21610 [(set (match_operand:SI 0 "memory_operand" "=m")
21611 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21612 UNSPEC_MOVNT))]
21613 "TARGET_SSE2"
21614 "movnti\t{%1, %0|%0, %1}"
21615 [(set_attr "type" "ssecvt")
21616 (set_attr "mode" "V2DF")])
21617
21618;; SSE <-> integer/MMX conversions
21619
21620;; Conversions between SI and SF
21621
21622(define_insn "cvtdq2ps"
21623 [(set (match_operand:V4SF 0 "register_operand" "=x")
21624 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21625 "TARGET_SSE2"
21626 "cvtdq2ps\t{%1, %0|%0, %1}"
21627 [(set_attr "type" "ssecvt")
21628 (set_attr "mode" "V2DF")])
21629
21630(define_insn "cvtps2dq"
21631 [(set (match_operand:V4SI 0 "register_operand" "=x")
21632 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21633 "TARGET_SSE2"
21634 "cvtps2dq\t{%1, %0|%0, %1}"
21635 [(set_attr "type" "ssecvt")
21636 (set_attr "mode" "TI")])
21637
21638(define_insn "cvttps2dq"
21639 [(set (match_operand:V4SI 0 "register_operand" "=x")
21640 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21641 UNSPEC_FIX))]
21642 "TARGET_SSE2"
21643 "cvttps2dq\t{%1, %0|%0, %1}"
21644 [(set_attr "type" "ssecvt")
21645 (set_attr "mode" "TI")])
21646
21647;; Conversions between SI and DF
21648
21649(define_insn "cvtdq2pd"
21650 [(set (match_operand:V2DF 0 "register_operand" "=x")
21651 (float:V2DF (vec_select:V2SI
21652 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21653 (parallel
21654 [(const_int 0)
21655 (const_int 1)]))))]
21656 "TARGET_SSE2"
21657 "cvtdq2pd\t{%1, %0|%0, %1}"
21658 [(set_attr "type" "ssecvt")
21659 (set_attr "mode" "V2DF")])
21660
21661(define_insn "cvtpd2dq"
21662 [(set (match_operand:V4SI 0 "register_operand" "=x")
21663 (vec_concat:V4SI
21664 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21665 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21666 "TARGET_SSE2"
21667 "cvtpd2dq\t{%1, %0|%0, %1}"
21668 [(set_attr "type" "ssecvt")
21669 (set_attr "mode" "TI")])
21670
21671(define_insn "cvttpd2dq"
21672 [(set (match_operand:V4SI 0 "register_operand" "=x")
21673 (vec_concat:V4SI
21674 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21675 UNSPEC_FIX)
21676 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21677 "TARGET_SSE2"
21678 "cvttpd2dq\t{%1, %0|%0, %1}"
21679 [(set_attr "type" "ssecvt")
21680 (set_attr "mode" "TI")])
21681
21682(define_insn "cvtpd2pi"
21683 [(set (match_operand:V2SI 0 "register_operand" "=y")
21684 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21685 "TARGET_SSE2"
21686 "cvtpd2pi\t{%1, %0|%0, %1}"
21687 [(set_attr "type" "ssecvt")
21688 (set_attr "mode" "TI")])
21689
21690(define_insn "cvttpd2pi"
21691 [(set (match_operand:V2SI 0 "register_operand" "=y")
21692 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21693 UNSPEC_FIX))]
21694 "TARGET_SSE2"
21695 "cvttpd2pi\t{%1, %0|%0, %1}"
21696 [(set_attr "type" "ssecvt")
21697 (set_attr "mode" "TI")])
21698
21699(define_insn "cvtpi2pd"
21700 [(set (match_operand:V2DF 0 "register_operand" "=x")
21701 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21702 "TARGET_SSE2"
21703 "cvtpi2pd\t{%1, %0|%0, %1}"
21704 [(set_attr "type" "ssecvt")
21705 (set_attr "mode" "TI")])
21706
21707;; Conversions between SI and DF
21708
21709(define_insn "cvtsd2si"
21710 [(set (match_operand:SI 0 "register_operand" "=r,r")
21711 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21712 (parallel [(const_int 0)]))))]
21713 "TARGET_SSE2"
21714 "cvtsd2si\t{%1, %0|%0, %1}"
21715 [(set_attr "type" "sseicvt")
21716 (set_attr "athlon_decode" "double,vector")
21717 (set_attr "mode" "SI")])
21718
21719(define_insn "cvtsd2siq"
21720 [(set (match_operand:DI 0 "register_operand" "=r,r")
21721 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21722 (parallel [(const_int 0)]))))]
21723 "TARGET_SSE2 && TARGET_64BIT"
21724 "cvtsd2siq\t{%1, %0|%0, %1}"
21725 [(set_attr "type" "sseicvt")
21726 (set_attr "athlon_decode" "double,vector")
21727 (set_attr "mode" "DI")])
21728
21729(define_insn "cvttsd2si"
21730 [(set (match_operand:SI 0 "register_operand" "=r,r")
21731 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21732 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21733 "TARGET_SSE2"
21734 "cvttsd2si\t{%1, %0|%0, %1}"
21735 [(set_attr "type" "sseicvt")
21736 (set_attr "mode" "SI")
21737 (set_attr "athlon_decode" "double,vector")])
21738
21739(define_insn "cvttsd2siq"
21740 [(set (match_operand:DI 0 "register_operand" "=r,r")
21741 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21742 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21743 "TARGET_SSE2 && TARGET_64BIT"
21744 "cvttsd2siq\t{%1, %0|%0, %1}"
21745 [(set_attr "type" "sseicvt")
21746 (set_attr "mode" "DI")
21747 (set_attr "athlon_decode" "double,vector")])
21748
21749(define_insn "cvtsi2sd"
21750 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21751 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21752 (vec_duplicate:V2DF
21753 (float:DF
21754 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21755 (const_int 2)))]
21756 "TARGET_SSE2"
21757 "cvtsi2sd\t{%2, %0|%0, %2}"
21758 [(set_attr "type" "sseicvt")
21759 (set_attr "mode" "DF")
21760 (set_attr "athlon_decode" "double,direct")])
21761
21762(define_insn "cvtsi2sdq"
21763 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21764 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21765 (vec_duplicate:V2DF
21766 (float:DF
21767 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21768 (const_int 2)))]
21769 "TARGET_SSE2 && TARGET_64BIT"
21770 "cvtsi2sdq\t{%2, %0|%0, %2}"
21771 [(set_attr "type" "sseicvt")
21772 (set_attr "mode" "DF")
21773 (set_attr "athlon_decode" "double,direct")])
21774
21775;; Conversions between SF and DF
21776
21777(define_insn "cvtsd2ss"
21778 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21779 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21780 (vec_duplicate:V4SF
21781 (float_truncate:V2SF
21782 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21783 (const_int 14)))]
21784 "TARGET_SSE2"
21785 "cvtsd2ss\t{%2, %0|%0, %2}"
21786 [(set_attr "type" "ssecvt")
21787 (set_attr "athlon_decode" "vector,double")
21788 (set_attr "mode" "SF")])
21789
21790(define_insn "cvtss2sd"
21791 [(set (match_operand:V2DF 0 "register_operand" "=x")
21792 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21793 (float_extend:V2DF
21794 (vec_select:V2SF
21795 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21796 (parallel [(const_int 0)
21797 (const_int 1)])))
21798 (const_int 2)))]
21799 "TARGET_SSE2"
21800 "cvtss2sd\t{%2, %0|%0, %2}"
21801 [(set_attr "type" "ssecvt")
21802 (set_attr "mode" "DF")])
21803
21804(define_insn "cvtpd2ps"
21805 [(set (match_operand:V4SF 0 "register_operand" "=x")
21806 (subreg:V4SF
21807 (vec_concat:V4SI
21808 (subreg:V2SI (float_truncate:V2SF
21809 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21810 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21811 "TARGET_SSE2"
21812 "cvtpd2ps\t{%1, %0|%0, %1}"
21813 [(set_attr "type" "ssecvt")
21814 (set_attr "mode" "V4SF")])
21815
21816(define_insn "cvtps2pd"
21817 [(set (match_operand:V2DF 0 "register_operand" "=x")
21818 (float_extend:V2DF
21819 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21820 (parallel [(const_int 0)
21821 (const_int 1)]))))]
21822 "TARGET_SSE2"
21823 "cvtps2pd\t{%1, %0|%0, %1}"
21824 [(set_attr "type" "ssecvt")
21825 (set_attr "mode" "V2DF")])
21826
21827;; SSE2 variants of MMX insns
21828
21829;; MMX arithmetic
21830
21831(define_insn "addv16qi3"
21832 [(set (match_operand:V16QI 0 "register_operand" "=x")
21833 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21834 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21835 "TARGET_SSE2"
21836 "paddb\t{%2, %0|%0, %2}"
21837 [(set_attr "type" "sseiadd")
21838 (set_attr "mode" "TI")])
21839
21840(define_insn "addv8hi3"
21841 [(set (match_operand:V8HI 0 "register_operand" "=x")
21842 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21843 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21844 "TARGET_SSE2"
21845 "paddw\t{%2, %0|%0, %2}"
21846 [(set_attr "type" "sseiadd")
21847 (set_attr "mode" "TI")])
21848
21849(define_insn "addv4si3"
21850 [(set (match_operand:V4SI 0 "register_operand" "=x")
21851 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21852 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21853 "TARGET_SSE2"
21854 "paddd\t{%2, %0|%0, %2}"
21855 [(set_attr "type" "sseiadd")
21856 (set_attr "mode" "TI")])
21857
21858(define_insn "addv2di3"
21859 [(set (match_operand:V2DI 0 "register_operand" "=x")
21860 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21861 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21862 "TARGET_SSE2"
21863 "paddq\t{%2, %0|%0, %2}"
21864 [(set_attr "type" "sseiadd")
21865 (set_attr "mode" "TI")])
21866
21867(define_insn "ssaddv16qi3"
21868 [(set (match_operand:V16QI 0 "register_operand" "=x")
21869 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21870 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21871 "TARGET_SSE2"
21872 "paddsb\t{%2, %0|%0, %2}"
21873 [(set_attr "type" "sseiadd")
21874 (set_attr "mode" "TI")])
21875
21876(define_insn "ssaddv8hi3"
21877 [(set (match_operand:V8HI 0 "register_operand" "=x")
21878 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21879 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21880 "TARGET_SSE2"
21881 "paddsw\t{%2, %0|%0, %2}"
21882 [(set_attr "type" "sseiadd")
21883 (set_attr "mode" "TI")])
21884
21885(define_insn "usaddv16qi3"
21886 [(set (match_operand:V16QI 0 "register_operand" "=x")
21887 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21888 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21889 "TARGET_SSE2"
21890 "paddusb\t{%2, %0|%0, %2}"
21891 [(set_attr "type" "sseiadd")
21892 (set_attr "mode" "TI")])
21893
21894(define_insn "usaddv8hi3"
21895 [(set (match_operand:V8HI 0 "register_operand" "=x")
21896 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21897 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21898 "TARGET_SSE2"
21899 "paddusw\t{%2, %0|%0, %2}"
21900 [(set_attr "type" "sseiadd")
21901 (set_attr "mode" "TI")])
21902
21903(define_insn "subv16qi3"
21904 [(set (match_operand:V16QI 0 "register_operand" "=x")
21905 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21906 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21907 "TARGET_SSE2"
21908 "psubb\t{%2, %0|%0, %2}"
21909 [(set_attr "type" "sseiadd")
21910 (set_attr "mode" "TI")])
21911
21912(define_insn "subv8hi3"
21913 [(set (match_operand:V8HI 0 "register_operand" "=x")
21914 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21915 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21916 "TARGET_SSE2"
21917 "psubw\t{%2, %0|%0, %2}"
21918 [(set_attr "type" "sseiadd")
21919 (set_attr "mode" "TI")])
21920
21921(define_insn "subv4si3"
21922 [(set (match_operand:V4SI 0 "register_operand" "=x")
21923 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21924 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21925 "TARGET_SSE2"
21926 "psubd\t{%2, %0|%0, %2}"
21927 [(set_attr "type" "sseiadd")
21928 (set_attr "mode" "TI")])
21929
21930(define_insn "subv2di3"
21931 [(set (match_operand:V2DI 0 "register_operand" "=x")
21932 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21933 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21934 "TARGET_SSE2"
21935 "psubq\t{%2, %0|%0, %2}"
21936 [(set_attr "type" "sseiadd")
21937 (set_attr "mode" "TI")])
21938
21939(define_insn "sssubv16qi3"
21940 [(set (match_operand:V16QI 0 "register_operand" "=x")
21941 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21942 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21943 "TARGET_SSE2"
21944 "psubsb\t{%2, %0|%0, %2}"
21945 [(set_attr "type" "sseiadd")
21946 (set_attr "mode" "TI")])
21947
21948(define_insn "sssubv8hi3"
21949 [(set (match_operand:V8HI 0 "register_operand" "=x")
21950 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21951 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21952 "TARGET_SSE2"
21953 "psubsw\t{%2, %0|%0, %2}"
21954 [(set_attr "type" "sseiadd")
21955 (set_attr "mode" "TI")])
21956
21957(define_insn "ussubv16qi3"
21958 [(set (match_operand:V16QI 0 "register_operand" "=x")
21959 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21960 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21961 "TARGET_SSE2"
21962 "psubusb\t{%2, %0|%0, %2}"
21963 [(set_attr "type" "sseiadd")
21964 (set_attr "mode" "TI")])
21965
21966(define_insn "ussubv8hi3"
21967 [(set (match_operand:V8HI 0 "register_operand" "=x")
21968 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21969 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21970 "TARGET_SSE2"
21971 "psubusw\t{%2, %0|%0, %2}"
21972 [(set_attr "type" "sseiadd")
21973 (set_attr "mode" "TI")])
21974
21975(define_insn "mulv8hi3"
21976 [(set (match_operand:V8HI 0 "register_operand" "=x")
21977 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21978 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21979 "TARGET_SSE2"
21980 "pmullw\t{%2, %0|%0, %2}"
21981 [(set_attr "type" "sseimul")
21982 (set_attr "mode" "TI")])
21983
21984(define_insn "smulv8hi3_highpart"
21985 [(set (match_operand:V8HI 0 "register_operand" "=x")
21986 (truncate:V8HI
21987 (lshiftrt:V8SI
21988 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21989 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21990 (const_int 16))))]
21991 "TARGET_SSE2"
21992 "pmulhw\t{%2, %0|%0, %2}"
21993 [(set_attr "type" "sseimul")
21994 (set_attr "mode" "TI")])
21995
21996(define_insn "umulv8hi3_highpart"
21997 [(set (match_operand:V8HI 0 "register_operand" "=x")
21998 (truncate:V8HI
21999 (lshiftrt:V8SI
22000 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22001 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22002 (const_int 16))))]
22003 "TARGET_SSE2"
22004 "pmulhuw\t{%2, %0|%0, %2}"
22005 [(set_attr "type" "sseimul")
22006 (set_attr "mode" "TI")])
22007
22008(define_insn "sse2_umulsidi3"
22009 [(set (match_operand:DI 0 "register_operand" "=y")
22010 (mult:DI (zero_extend:DI (vec_select:SI
22011 (match_operand:V2SI 1 "register_operand" "0")
22012 (parallel [(const_int 0)])))
22013 (zero_extend:DI (vec_select:SI
22014 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22015 (parallel [(const_int 0)])))))]
22016 "TARGET_SSE2"
22017 "pmuludq\t{%2, %0|%0, %2}"
22018 [(set_attr "type" "sseimul")
22019 (set_attr "mode" "TI")])
22020
22021(define_insn "sse2_umulv2siv2di3"
22022 [(set (match_operand:V2DI 0 "register_operand" "=x")
22023 (mult:V2DI (zero_extend:V2DI
22024 (vec_select:V2SI
22025 (match_operand:V4SI 1 "register_operand" "0")
22026 (parallel [(const_int 0) (const_int 2)])))
22027 (zero_extend:V2DI
22028 (vec_select:V2SI
22029 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22030 (parallel [(const_int 0) (const_int 2)])))))]
22031 "TARGET_SSE2"
22032 "pmuludq\t{%2, %0|%0, %2}"
22033 [(set_attr "type" "sseimul")
22034 (set_attr "mode" "TI")])
22035
22036(define_insn "sse2_pmaddwd"
22037 [(set (match_operand:V4SI 0 "register_operand" "=x")
22038 (plus:V4SI
22039 (mult:V4SI
22040 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22041 (parallel [(const_int 0)
22042 (const_int 2)
22043 (const_int 4)
22044 (const_int 6)])))
22045 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22046 (parallel [(const_int 0)
22047 (const_int 2)
22048 (const_int 4)
22049 (const_int 6)]))))
22050 (mult:V4SI
22051 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22052 (parallel [(const_int 1)
22053 (const_int 3)
22054 (const_int 5)
22055 (const_int 7)])))
22056 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22057 (parallel [(const_int 1)
22058 (const_int 3)
22059 (const_int 5)
22060 (const_int 7)]))))))]
22061 "TARGET_SSE2"
22062 "pmaddwd\t{%2, %0|%0, %2}"
22063 [(set_attr "type" "sseiadd")
22064 (set_attr "mode" "TI")])
22065
22066;; Same as pxor, but don't show input operands so that we don't think
22067;; they are live.
22068(define_insn "sse2_clrti"
22069 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22070 "TARGET_SSE2"
22071{
22072 if (get_attr_mode (insn) == MODE_TI)
22073 return "pxor\t%0, %0";
22074 else
22075 return "xorps\t%0, %0";
22076}
22077 [(set_attr "type" "ssemov")
22078 (set_attr "memory" "none")
22079 (set (attr "mode")
22080 (if_then_else
22081 (ne (symbol_ref "optimize_size")
22082 (const_int 0))
22083 (const_string "V4SF")
22084 (const_string "TI")))])
22085
22086;; MMX unsigned averages/sum of absolute differences
22087
22088(define_insn "sse2_uavgv16qi3"
22089 [(set (match_operand:V16QI 0 "register_operand" "=x")
22090 (ashiftrt:V16QI
22091 (plus:V16QI (plus:V16QI
22092 (match_operand:V16QI 1 "register_operand" "0")
22093 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22094 (const_vector:V16QI [(const_int 1) (const_int 1)
22095 (const_int 1) (const_int 1)
22096 (const_int 1) (const_int 1)
22097 (const_int 1) (const_int 1)
22098 (const_int 1) (const_int 1)
22099 (const_int 1) (const_int 1)
22100 (const_int 1) (const_int 1)
22101 (const_int 1) (const_int 1)]))
22102 (const_int 1)))]
22103 "TARGET_SSE2"
22104 "pavgb\t{%2, %0|%0, %2}"
22105 [(set_attr "type" "sseiadd")
22106 (set_attr "mode" "TI")])
22107
22108(define_insn "sse2_uavgv8hi3"
22109 [(set (match_operand:V8HI 0 "register_operand" "=x")
22110 (ashiftrt:V8HI
22111 (plus:V8HI (plus:V8HI
22112 (match_operand:V8HI 1 "register_operand" "0")
22113 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22114 (const_vector:V8HI [(const_int 1) (const_int 1)
22115 (const_int 1) (const_int 1)
22116 (const_int 1) (const_int 1)
22117 (const_int 1) (const_int 1)]))
22118 (const_int 1)))]
22119 "TARGET_SSE2"
22120 "pavgw\t{%2, %0|%0, %2}"
22121 [(set_attr "type" "sseiadd")
22122 (set_attr "mode" "TI")])
22123
22124;; @@@ this isn't the right representation.
22125(define_insn "sse2_psadbw"
22126 [(set (match_operand:V2DI 0 "register_operand" "=x")
22127 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22128 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22129 UNSPEC_PSADBW))]
22130 "TARGET_SSE2"
22131 "psadbw\t{%2, %0|%0, %2}"
22132 [(set_attr "type" "sseiadd")
22133 (set_attr "mode" "TI")])
22134
22135
22136;; MMX insert/extract/shuffle
22137
22138(define_insn "sse2_pinsrw"
22139 [(set (match_operand:V8HI 0 "register_operand" "=x")
22140 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22141 (vec_duplicate:V8HI
22142 (truncate:HI
22143 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22144 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22145 "TARGET_SSE2"
22146 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22147 [(set_attr "type" "ssecvt")
22148 (set_attr "mode" "TI")])
22149
22150(define_insn "sse2_pextrw"
22151 [(set (match_operand:SI 0 "register_operand" "=r")
22152 (zero_extend:SI
22153 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22154 (parallel
22155 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22156 "TARGET_SSE2"
22157 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22158 [(set_attr "type" "ssecvt")
22159 (set_attr "mode" "TI")])
22160
22161(define_insn "sse2_pshufd"
22162 [(set (match_operand:V4SI 0 "register_operand" "=x")
22163 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22164 (match_operand:SI 2 "immediate_operand" "i")]
22165 UNSPEC_SHUFFLE))]
22166 "TARGET_SSE2"
22167 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22168 [(set_attr "type" "ssecvt")
22169 (set_attr "mode" "TI")])
22170
22171(define_insn "sse2_pshuflw"
22172 [(set (match_operand:V8HI 0 "register_operand" "=x")
22173 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22174 (match_operand:SI 2 "immediate_operand" "i")]
22175 UNSPEC_PSHUFLW))]
22176 "TARGET_SSE2"
22177 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22178 [(set_attr "type" "ssecvt")
22179 (set_attr "mode" "TI")])
22180
22181(define_insn "sse2_pshufhw"
22182 [(set (match_operand:V8HI 0 "register_operand" "=x")
22183 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22184 (match_operand:SI 2 "immediate_operand" "i")]
22185 UNSPEC_PSHUFHW))]
22186 "TARGET_SSE2"
22187 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22188 [(set_attr "type" "ssecvt")
22189 (set_attr "mode" "TI")])
22190
22191;; MMX mask-generating comparisons
22192
22193(define_insn "eqv16qi3"
22194 [(set (match_operand:V16QI 0 "register_operand" "=x")
22195 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22196 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22197 "TARGET_SSE2"
22198 "pcmpeqb\t{%2, %0|%0, %2}"
22199 [(set_attr "type" "ssecmp")
22200 (set_attr "mode" "TI")])
22201
22202(define_insn "eqv8hi3"
22203 [(set (match_operand:V8HI 0 "register_operand" "=x")
22204 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22205 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22206 "TARGET_SSE2"
22207 "pcmpeqw\t{%2, %0|%0, %2}"
22208 [(set_attr "type" "ssecmp")
22209 (set_attr "mode" "TI")])
22210
22211(define_insn "eqv4si3"
22212 [(set (match_operand:V4SI 0 "register_operand" "=x")
22213 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22214 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22215 "TARGET_SSE2"
22216 "pcmpeqd\t{%2, %0|%0, %2}"
22217 [(set_attr "type" "ssecmp")
22218 (set_attr "mode" "TI")])
22219
22220(define_insn "gtv16qi3"
22221 [(set (match_operand:V16QI 0 "register_operand" "=x")
22222 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22223 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22224 "TARGET_SSE2"
22225 "pcmpgtb\t{%2, %0|%0, %2}"
22226 [(set_attr "type" "ssecmp")
22227 (set_attr "mode" "TI")])
22228
22229(define_insn "gtv8hi3"
22230 [(set (match_operand:V8HI 0 "register_operand" "=x")
22231 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22232 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22233 "TARGET_SSE2"
22234 "pcmpgtw\t{%2, %0|%0, %2}"
22235 [(set_attr "type" "ssecmp")
22236 (set_attr "mode" "TI")])
22237
22238(define_insn "gtv4si3"
22239 [(set (match_operand:V4SI 0 "register_operand" "=x")
22240 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22241 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22242 "TARGET_SSE2"
22243 "pcmpgtd\t{%2, %0|%0, %2}"
22244 [(set_attr "type" "ssecmp")
22245 (set_attr "mode" "TI")])
22246
22247
22248;; MMX max/min insns
22249
22250(define_insn "umaxv16qi3"
22251 [(set (match_operand:V16QI 0 "register_operand" "=x")
22252 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22253 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22254 "TARGET_SSE2"
22255 "pmaxub\t{%2, %0|%0, %2}"
22256 [(set_attr "type" "sseiadd")
22257 (set_attr "mode" "TI")])
22258
22259(define_insn "smaxv8hi3"
22260 [(set (match_operand:V8HI 0 "register_operand" "=x")
22261 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22262 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22263 "TARGET_SSE2"
22264 "pmaxsw\t{%2, %0|%0, %2}"
22265 [(set_attr "type" "sseiadd")
22266 (set_attr "mode" "TI")])
22267
22268(define_insn "uminv16qi3"
22269 [(set (match_operand:V16QI 0 "register_operand" "=x")
22270 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22271 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22272 "TARGET_SSE2"
22273 "pminub\t{%2, %0|%0, %2}"
22274 [(set_attr "type" "sseiadd")
22275 (set_attr "mode" "TI")])
22276
22277(define_insn "sminv8hi3"
22278 [(set (match_operand:V8HI 0 "register_operand" "=x")
22279 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22280 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22281 "TARGET_SSE2"
22282 "pminsw\t{%2, %0|%0, %2}"
22283 [(set_attr "type" "sseiadd")
22284 (set_attr "mode" "TI")])
22285
22286
22287;; MMX shifts
22288
22289(define_insn "ashrv8hi3"
22290 [(set (match_operand:V8HI 0 "register_operand" "=x")
22291 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22292 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22293 "TARGET_SSE2"
22294 "psraw\t{%2, %0|%0, %2}"
22295 [(set_attr "type" "sseishft")
22296 (set_attr "mode" "TI")])
22297
22298(define_insn "ashrv4si3"
22299 [(set (match_operand:V4SI 0 "register_operand" "=x")
22300 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22301 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22302 "TARGET_SSE2"
22303 "psrad\t{%2, %0|%0, %2}"
22304 [(set_attr "type" "sseishft")
22305 (set_attr "mode" "TI")])
22306
22307(define_insn "lshrv8hi3"
22308 [(set (match_operand:V8HI 0 "register_operand" "=x")
22309 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22310 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22311 "TARGET_SSE2"
22312 "psrlw\t{%2, %0|%0, %2}"
22313 [(set_attr "type" "sseishft")
22314 (set_attr "mode" "TI")])
22315
22316(define_insn "lshrv4si3"
22317 [(set (match_operand:V4SI 0 "register_operand" "=x")
22318 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22319 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22320 "TARGET_SSE2"
22321 "psrld\t{%2, %0|%0, %2}"
22322 [(set_attr "type" "sseishft")
22323 (set_attr "mode" "TI")])
22324
22325(define_insn "lshrv2di3"
22326 [(set (match_operand:V2DI 0 "register_operand" "=x")
22327 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22328 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22329 "TARGET_SSE2"
22330 "psrlq\t{%2, %0|%0, %2}"
22331 [(set_attr "type" "sseishft")
22332 (set_attr "mode" "TI")])
22333
22334(define_insn "ashlv8hi3"
22335 [(set (match_operand:V8HI 0 "register_operand" "=x")
22336 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22337 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22338 "TARGET_SSE2"
22339 "psllw\t{%2, %0|%0, %2}"
22340 [(set_attr "type" "sseishft")
22341 (set_attr "mode" "TI")])
22342
22343(define_insn "ashlv4si3"
22344 [(set (match_operand:V4SI 0 "register_operand" "=x")
22345 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22346 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22347 "TARGET_SSE2"
22348 "pslld\t{%2, %0|%0, %2}"
22349 [(set_attr "type" "sseishft")
22350 (set_attr "mode" "TI")])
22351
22352(define_insn "ashlv2di3"
22353 [(set (match_operand:V2DI 0 "register_operand" "=x")
22354 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22355 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22356 "TARGET_SSE2"
22357 "psllq\t{%2, %0|%0, %2}"
22358 [(set_attr "type" "sseishft")
22359 (set_attr "mode" "TI")])
22360
22361(define_insn "ashrv8hi3_ti"
22362 [(set (match_operand:V8HI 0 "register_operand" "=x")
22363 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22364 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22365 "TARGET_SSE2"
22366 "psraw\t{%2, %0|%0, %2}"
22367 [(set_attr "type" "sseishft")
22368 (set_attr "mode" "TI")])
22369
22370(define_insn "ashrv4si3_ti"
22371 [(set (match_operand:V4SI 0 "register_operand" "=x")
22372 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22373 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22374 "TARGET_SSE2"
22375 "psrad\t{%2, %0|%0, %2}"
22376 [(set_attr "type" "sseishft")
22377 (set_attr "mode" "TI")])
22378
22379(define_insn "lshrv8hi3_ti"
22380 [(set (match_operand:V8HI 0 "register_operand" "=x")
22381 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22382 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22383 "TARGET_SSE2"
22384 "psrlw\t{%2, %0|%0, %2}"
22385 [(set_attr "type" "sseishft")
22386 (set_attr "mode" "TI")])
22387
22388(define_insn "lshrv4si3_ti"
22389 [(set (match_operand:V4SI 0 "register_operand" "=x")
22390 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22391 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22392 "TARGET_SSE2"
22393 "psrld\t{%2, %0|%0, %2}"
22394 [(set_attr "type" "sseishft")
22395 (set_attr "mode" "TI")])
22396
22397(define_insn "lshrv2di3_ti"
22398 [(set (match_operand:V2DI 0 "register_operand" "=x")
22399 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22400 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22401 "TARGET_SSE2"
22402 "psrlq\t{%2, %0|%0, %2}"
22403 [(set_attr "type" "sseishft")
22404 (set_attr "mode" "TI")])
22405
22406(define_insn "ashlv8hi3_ti"
22407 [(set (match_operand:V8HI 0 "register_operand" "=x")
22408 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22409 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22410 "TARGET_SSE2"
22411 "psllw\t{%2, %0|%0, %2}"
22412 [(set_attr "type" "sseishft")
22413 (set_attr "mode" "TI")])
22414
22415(define_insn "ashlv4si3_ti"
22416 [(set (match_operand:V4SI 0 "register_operand" "=x")
22417 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22418 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22419 "TARGET_SSE2"
22420 "pslld\t{%2, %0|%0, %2}"
22421 [(set_attr "type" "sseishft")
22422 (set_attr "mode" "TI")])
22423
22424(define_insn "ashlv2di3_ti"
22425 [(set (match_operand:V2DI 0 "register_operand" "=x")
22426 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22427 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22428 "TARGET_SSE2"
22429 "psllq\t{%2, %0|%0, %2}"
22430 [(set_attr "type" "sseishft")
22431 (set_attr "mode" "TI")])
22432
22433;; See logical MMX insns for the reason for the unspec. Strictly speaking
22434;; we wouldn't need here it since we never generate TImode arithmetic.
22435
22436;; There has to be some kind of prize for the weirdest new instruction...
22437(define_insn "sse2_ashlti3"
22438 [(set (match_operand:TI 0 "register_operand" "=x")
22439 (unspec:TI
22440 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22441 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22442 (const_int 8)))] UNSPEC_NOP))]
22443 "TARGET_SSE2"
22444 "pslldq\t{%2, %0|%0, %2}"
22445 [(set_attr "type" "sseishft")
22446 (set_attr "mode" "TI")])
22447
22448(define_insn "sse2_lshrti3"
22449 [(set (match_operand:TI 0 "register_operand" "=x")
22450 (unspec:TI
22451 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22452 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22453 (const_int 8)))] UNSPEC_NOP))]
22454 "TARGET_SSE2"
22455 "psrldq\t{%2, %0|%0, %2}"
22456 [(set_attr "type" "sseishft")
22457 (set_attr "mode" "TI")])
22458
22459;; SSE unpack
22460
22461(define_insn "sse2_unpckhpd"
22462 [(set (match_operand:V2DF 0 "register_operand" "=x")
22463 (vec_concat:V2DF
22464 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22465 (parallel [(const_int 1)]))
22466 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22467 (parallel [(const_int 1)]))))]
22468 "TARGET_SSE2"
22469 "unpckhpd\t{%2, %0|%0, %2}"
22470 [(set_attr "type" "ssecvt")
22471 (set_attr "mode" "V2DF")])
22472
22473(define_insn "sse2_unpcklpd"
22474 [(set (match_operand:V2DF 0 "register_operand" "=x")
22475 (vec_concat:V2DF
22476 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22477 (parallel [(const_int 0)]))
22478 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22479 (parallel [(const_int 0)]))))]
22480 "TARGET_SSE2"
22481 "unpcklpd\t{%2, %0|%0, %2}"
22482 [(set_attr "type" "ssecvt")
22483 (set_attr "mode" "V2DF")])
22484
22485;; MMX pack/unpack insns.
22486
22487(define_insn "sse2_packsswb"
22488 [(set (match_operand:V16QI 0 "register_operand" "=x")
22489 (vec_concat:V16QI
22490 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22491 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22492 "TARGET_SSE2"
22493 "packsswb\t{%2, %0|%0, %2}"
22494 [(set_attr "type" "ssecvt")
22495 (set_attr "mode" "TI")])
22496
22497(define_insn "sse2_packssdw"
22498 [(set (match_operand:V8HI 0 "register_operand" "=x")
22499 (vec_concat:V8HI
22500 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22501 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22502 "TARGET_SSE2"
22503 "packssdw\t{%2, %0|%0, %2}"
22504 [(set_attr "type" "ssecvt")
22505 (set_attr "mode" "TI")])
22506
22507(define_insn "sse2_packuswb"
22508 [(set (match_operand:V16QI 0 "register_operand" "=x")
22509 (vec_concat:V16QI
22510 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22511 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22512 "TARGET_SSE2"
22513 "packuswb\t{%2, %0|%0, %2}"
22514 [(set_attr "type" "ssecvt")
22515 (set_attr "mode" "TI")])
22516
22517(define_insn "sse2_punpckhbw"
22518 [(set (match_operand:V16QI 0 "register_operand" "=x")
22519 (vec_merge:V16QI
22520 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22521 (parallel [(const_int 8) (const_int 0)
22522 (const_int 9) (const_int 1)
22523 (const_int 10) (const_int 2)
22524 (const_int 11) (const_int 3)
22525 (const_int 12) (const_int 4)
22526 (const_int 13) (const_int 5)
22527 (const_int 14) (const_int 6)
22528 (const_int 15) (const_int 7)]))
22529 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22530 (parallel [(const_int 0) (const_int 8)
22531 (const_int 1) (const_int 9)
22532 (const_int 2) (const_int 10)
22533 (const_int 3) (const_int 11)
22534 (const_int 4) (const_int 12)
22535 (const_int 5) (const_int 13)
22536 (const_int 6) (const_int 14)
22537 (const_int 7) (const_int 15)]))
22538 (const_int 21845)))]
22539 "TARGET_SSE2"
22540 "punpckhbw\t{%2, %0|%0, %2}"
22541 [(set_attr "type" "ssecvt")
22542 (set_attr "mode" "TI")])
22543
22544(define_insn "sse2_punpckhwd"
22545 [(set (match_operand:V8HI 0 "register_operand" "=x")
22546 (vec_merge:V8HI
22547 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22548 (parallel [(const_int 4) (const_int 0)
22549 (const_int 5) (const_int 1)
22550 (const_int 6) (const_int 2)
22551 (const_int 7) (const_int 3)]))
22552 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22553 (parallel [(const_int 0) (const_int 4)
22554 (const_int 1) (const_int 5)
22555 (const_int 2) (const_int 6)
22556 (const_int 3) (const_int 7)]))
22557 (const_int 85)))]
22558 "TARGET_SSE2"
22559 "punpckhwd\t{%2, %0|%0, %2}"
22560 [(set_attr "type" "ssecvt")
22561 (set_attr "mode" "TI")])
22562
22563(define_insn "sse2_punpckhdq"
22564 [(set (match_operand:V4SI 0 "register_operand" "=x")
22565 (vec_merge:V4SI
22566 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22567 (parallel [(const_int 2) (const_int 0)
22568 (const_int 3) (const_int 1)]))
22569 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22570 (parallel [(const_int 0) (const_int 2)
22571 (const_int 1) (const_int 3)]))
22572 (const_int 5)))]
22573 "TARGET_SSE2"
22574 "punpckhdq\t{%2, %0|%0, %2}"
22575 [(set_attr "type" "ssecvt")
22576 (set_attr "mode" "TI")])
22577
22578(define_insn "sse2_punpcklbw"
22579 [(set (match_operand:V16QI 0 "register_operand" "=x")
22580 (vec_merge:V16QI
22581 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22582 (parallel [(const_int 0) (const_int 8)
22583 (const_int 1) (const_int 9)
22584 (const_int 2) (const_int 10)
22585 (const_int 3) (const_int 11)
22586 (const_int 4) (const_int 12)
22587 (const_int 5) (const_int 13)
22588 (const_int 6) (const_int 14)
22589 (const_int 7) (const_int 15)]))
22590 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22591 (parallel [(const_int 8) (const_int 0)
22592 (const_int 9) (const_int 1)
22593 (const_int 10) (const_int 2)
22594 (const_int 11) (const_int 3)
22595 (const_int 12) (const_int 4)
22596 (const_int 13) (const_int 5)
22597 (const_int 14) (const_int 6)
22598 (const_int 15) (const_int 7)]))
22599 (const_int 21845)))]
22600 "TARGET_SSE2"
22601 "punpcklbw\t{%2, %0|%0, %2}"
22602 [(set_attr "type" "ssecvt")
22603 (set_attr "mode" "TI")])
22604
22605(define_insn "sse2_punpcklwd"
22606 [(set (match_operand:V8HI 0 "register_operand" "=x")
22607 (vec_merge:V8HI
22608 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22609 (parallel [(const_int 0) (const_int 4)
22610 (const_int 1) (const_int 5)
22611 (const_int 2) (const_int 6)
22612 (const_int 3) (const_int 7)]))
22613 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22614 (parallel [(const_int 4) (const_int 0)
22615 (const_int 5) (const_int 1)
22616 (const_int 6) (const_int 2)
22617 (const_int 7) (const_int 3)]))
22618 (const_int 85)))]
22619 "TARGET_SSE2"
22620 "punpcklwd\t{%2, %0|%0, %2}"
22621 [(set_attr "type" "ssecvt")
22622 (set_attr "mode" "TI")])
22623
22624(define_insn "sse2_punpckldq"
22625 [(set (match_operand:V4SI 0 "register_operand" "=x")
22626 (vec_merge:V4SI
22627 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22628 (parallel [(const_int 0) (const_int 2)
22629 (const_int 1) (const_int 3)]))
22630 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22631 (parallel [(const_int 2) (const_int 0)
22632 (const_int 3) (const_int 1)]))
22633 (const_int 5)))]
22634 "TARGET_SSE2"
22635 "punpckldq\t{%2, %0|%0, %2}"
22636 [(set_attr "type" "ssecvt")
22637 (set_attr "mode" "TI")])
22638
22639(define_insn "sse2_punpcklqdq"
22640 [(set (match_operand:V2DI 0 "register_operand" "=x")
22641 (vec_merge:V2DI
22642 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22643 (parallel [(const_int 1)
22644 (const_int 0)]))
22645 (match_operand:V2DI 1 "register_operand" "0")
22646 (const_int 1)))]
22647 "TARGET_SSE2"
22648 "punpcklqdq\t{%2, %0|%0, %2}"
22649 [(set_attr "type" "ssecvt")
22650 (set_attr "mode" "TI")])
22651
22652(define_insn "sse2_punpckhqdq"
22653 [(set (match_operand:V2DI 0 "register_operand" "=x")
22654 (vec_merge:V2DI
22655 (match_operand:V2DI 1 "register_operand" "0")
22656 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22657 (parallel [(const_int 1)
22658 (const_int 0)]))
22659 (const_int 1)))]
22660 "TARGET_SSE2"
22661 "punpckhqdq\t{%2, %0|%0, %2}"
22662 [(set_attr "type" "ssecvt")
22663 (set_attr "mode" "TI")])
22664
22665;; SSE2 moves
22666
22667(define_insn "sse2_movapd"
22668 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22669 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22670 UNSPEC_MOVA))]
22671 "TARGET_SSE2
22672 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22673 "movapd\t{%1, %0|%0, %1}"
22674 [(set_attr "type" "ssemov")
22675 (set_attr "mode" "V2DF")])
22676
22677(define_insn "sse2_movupd"
22678 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22679 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22680 UNSPEC_MOVU))]
22681 "TARGET_SSE2
22682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22683 "movupd\t{%1, %0|%0, %1}"
22684 [(set_attr "type" "ssecvt")
22685 (set_attr "mode" "V2DF")])
22686
22687(define_insn "sse2_movdqa"
22688 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22689 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22690 UNSPEC_MOVA))]
22691 "TARGET_SSE2
22692 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22693 "movdqa\t{%1, %0|%0, %1}"
22694 [(set_attr "type" "ssemov")
22695 (set_attr "mode" "TI")])
22696
22697(define_insn "sse2_movdqu"
22698 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22699 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22700 UNSPEC_MOVU))]
22701 "TARGET_SSE2
22702 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22703 "movdqu\t{%1, %0|%0, %1}"
22704 [(set_attr "type" "ssecvt")
22705 (set_attr "mode" "TI")])
22706
22707(define_insn "sse2_movdq2q"
22708 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22709 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22710 (parallel [(const_int 0)])))]
22711 "TARGET_SSE2 && !TARGET_64BIT"
22712 "@
22713 movq\t{%1, %0|%0, %1}
22714 movdq2q\t{%1, %0|%0, %1}"
22715 [(set_attr "type" "ssecvt")
22716 (set_attr "mode" "TI")])
22717
22718(define_insn "sse2_movdq2q_rex64"
22719 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22720 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22721 (parallel [(const_int 0)])))]
22722 "TARGET_SSE2 && TARGET_64BIT"
22723 "@
22724 movq\t{%1, %0|%0, %1}
22725 movdq2q\t{%1, %0|%0, %1}
22726 movd\t{%1, %0|%0, %1}"
22727 [(set_attr "type" "ssecvt")
22728 (set_attr "mode" "TI")])
22729
22730(define_insn "sse2_movq2dq"
22731 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22732 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22733 (const_int 0)))]
22734 "TARGET_SSE2 && !TARGET_64BIT"
22735 "@
22736 movq\t{%1, %0|%0, %1}
22737 movq2dq\t{%1, %0|%0, %1}"
22738 [(set_attr "type" "ssecvt,ssemov")
22739 (set_attr "mode" "TI")])
22740
22741(define_insn "sse2_movq2dq_rex64"
22742 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22743 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22744 (const_int 0)))]
22745 "TARGET_SSE2 && TARGET_64BIT"
22746 "@
22747 movq\t{%1, %0|%0, %1}
22748 movq2dq\t{%1, %0|%0, %1}
22749 movd\t{%1, %0|%0, %1}"
22750 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22751 (set_attr "mode" "TI")])
22752
22753(define_insn "sse2_movq"
22754 [(set (match_operand:V2DI 0 "register_operand" "=x")
22755 (vec_concat:V2DI (vec_select:DI
22756 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22757 (parallel [(const_int 0)]))
22758 (const_int 0)))]
22759 "TARGET_SSE2"
22760 "movq\t{%1, %0|%0, %1}"
22761 [(set_attr "type" "ssemov")
22762 (set_attr "mode" "TI")])
22763
22764(define_insn "sse2_loadd"
22765 [(set (match_operand:V4SI 0 "register_operand" "=x")
22766 (vec_merge:V4SI
22767 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22768 (const_vector:V4SI [(const_int 0)
22769 (const_int 0)
22770 (const_int 0)
22771 (const_int 0)])
22772 (const_int 1)))]
22773 "TARGET_SSE2"
22774 "movd\t{%1, %0|%0, %1}"
22775 [(set_attr "type" "ssemov")
22776 (set_attr "mode" "TI")])
22777
22778(define_insn "sse2_stored"
22779 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22780 (vec_select:SI
22781 (match_operand:V4SI 1 "register_operand" "x")
22782 (parallel [(const_int 0)])))]
22783 "TARGET_SSE2"
22784 "movd\t{%1, %0|%0, %1}"
22785 [(set_attr "type" "ssemov")
22786 (set_attr "mode" "TI")])
22787
22788(define_insn "sse2_movhpd"
22789 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22790 (vec_merge:V2DF
22791 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22792 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22793 (const_int 2)))]
22794 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22795 "movhpd\t{%2, %0|%0, %2}"
22796 [(set_attr "type" "ssecvt")
22797 (set_attr "mode" "V2DF")])
22798
22799(define_expand "sse2_loadsd"
22800 [(match_operand:V2DF 0 "register_operand" "")
22801 (match_operand:DF 1 "memory_operand" "")]
22802 "TARGET_SSE2"
22803{
22804 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22805 CONST0_RTX (V2DFmode)));
22806 DONE;
22807})
22808
22809(define_insn "sse2_loadsd_1"
22810 [(set (match_operand:V2DF 0 "register_operand" "=x")
22811 (vec_merge:V2DF
22812 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22813 (match_operand:V2DF 2 "const0_operand" "X")
22814 (const_int 1)))]
22815 "TARGET_SSE2"
22816 "movsd\t{%1, %0|%0, %1}"
22817 [(set_attr "type" "ssecvt")
22818 (set_attr "mode" "DF")])
22819
22820(define_insn "sse2_movsd"
22821 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22822 (vec_merge:V2DF
22823 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22824 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22825 (const_int 1)))]
22826 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22827 "@movsd\t{%2, %0|%0, %2}
22828 movlpd\t{%2, %0|%0, %2}
22829 movlpd\t{%2, %0|%0, %2}"
22830 [(set_attr "type" "ssecvt")
22831 (set_attr "mode" "DF,V2DF,V2DF")])
22832
22833(define_insn "sse2_storesd"
22834 [(set (match_operand:DF 0 "memory_operand" "=m")
22835 (vec_select:DF
22836 (match_operand:V2DF 1 "register_operand" "x")
22837 (parallel [(const_int 0)])))]
22838 "TARGET_SSE2"
22839 "movsd\t{%1, %0|%0, %1}"
22840 [(set_attr "type" "ssecvt")
22841 (set_attr "mode" "DF")])
22842
22843(define_insn "sse2_shufpd"
22844 [(set (match_operand:V2DF 0 "register_operand" "=x")
22845 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22846 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22847 (match_operand:SI 3 "immediate_operand" "i")]
22848 UNSPEC_SHUFFLE))]
22849 "TARGET_SSE2"
22850 ;; @@@ check operand order for intel/nonintel syntax
22851 "shufpd\t{%3, %2, %0|%0, %2, %3}"
22852 [(set_attr "type" "ssecvt")
22853 (set_attr "mode" "V2DF")])
22854
22855(define_insn "sse2_clflush"
22856 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22857 UNSPECV_CLFLUSH)]
22858 "TARGET_SSE2"
22859 "clflush %0"
22860 [(set_attr "type" "sse")
22861 (set_attr "memory" "unknown")])
22862
22863(define_expand "sse2_mfence"
22864 [(set (match_dup 0)
22865 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22866 "TARGET_SSE2"
22867{
22868 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22869 MEM_VOLATILE_P (operands[0]) = 1;
22870})
22871
22872(define_insn "*mfence_insn"
22873 [(set (match_operand:BLK 0 "" "")
22874 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22875 "TARGET_SSE2"
22876 "mfence"
22877 [(set_attr "type" "sse")
22878 (set_attr "memory" "unknown")])
22879
22880(define_expand "sse2_lfence"
22881 [(set (match_dup 0)
22882 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22883 "TARGET_SSE2"
22884{
22885 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22886 MEM_VOLATILE_P (operands[0]) = 1;
22887})
22888
22889(define_insn "*lfence_insn"
22890 [(set (match_operand:BLK 0 "" "")
22891 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22892 "TARGET_SSE2"
22893 "lfence"
22894 [(set_attr "type" "sse")
22895 (set_attr "memory" "unknown")])
22896
22897;; SSE3
22898
22899(define_insn "mwait"
22900 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22901 (match_operand:SI 1 "register_operand" "c")]
22902 UNSPECV_MWAIT)]
22903 "TARGET_SSE3"
22904 "mwait\t%0, %1"
22905 [(set_attr "length" "3")])
22906
22907(define_insn "monitor"
22908 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22909 (match_operand:SI 1 "register_operand" "c")
22910 (match_operand:SI 2 "register_operand" "d")]
22911 UNSPECV_MONITOR)]
22912 "TARGET_SSE3"
22913 "monitor\t%0, %1, %2"
22914 [(set_attr "length" "3")])
22915
22916;; SSE3 arithmetic
22917
22918(define_insn "addsubv4sf3"
22919 [(set (match_operand:V4SF 0 "register_operand" "=x")
22920 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22921 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22922 UNSPEC_ADDSUB))]
22923 "TARGET_SSE3"
22924 "addsubps\t{%2, %0|%0, %2}"
22925 [(set_attr "type" "sseadd")
22926 (set_attr "mode" "V4SF")])
22927
22928(define_insn "addsubv2df3"
22929 [(set (match_operand:V2DF 0 "register_operand" "=x")
22930 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22931 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22932 UNSPEC_ADDSUB))]
22933 "TARGET_SSE3"
22934 "addsubpd\t{%2, %0|%0, %2}"
22935 [(set_attr "type" "sseadd")
22936 (set_attr "mode" "V2DF")])
22937
22938(define_insn "haddv4sf3"
22939 [(set (match_operand:V4SF 0 "register_operand" "=x")
22940 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22941 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22942 UNSPEC_HADD))]
22943 "TARGET_SSE3"
22944 "haddps\t{%2, %0|%0, %2}"
22945 [(set_attr "type" "sseadd")
22946 (set_attr "mode" "V4SF")])
22947
22948(define_insn "haddv2df3"
22949 [(set (match_operand:V2DF 0 "register_operand" "=x")
22950 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22951 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22952 UNSPEC_HADD))]
22953 "TARGET_SSE3"
22954 "haddpd\t{%2, %0|%0, %2}"
22955 [(set_attr "type" "sseadd")
22956 (set_attr "mode" "V2DF")])
22957
22958(define_insn "hsubv4sf3"
22959 [(set (match_operand:V4SF 0 "register_operand" "=x")
22960 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22961 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22962 UNSPEC_HSUB))]
22963 "TARGET_SSE3"
22964 "hsubps\t{%2, %0|%0, %2}"
22965 [(set_attr "type" "sseadd")
22966 (set_attr "mode" "V4SF")])
22967
22968(define_insn "hsubv2df3"
22969 [(set (match_operand:V2DF 0 "register_operand" "=x")
22970 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22971 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22972 UNSPEC_HSUB))]
22973 "TARGET_SSE3"
22974 "hsubpd\t{%2, %0|%0, %2}"
22975 [(set_attr "type" "sseadd")
22976 (set_attr "mode" "V2DF")])
22977
22978(define_insn "movshdup"
22979 [(set (match_operand:V4SF 0 "register_operand" "=x")
22980 (unspec:V4SF
22981 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22982 "TARGET_SSE3"
22983 "movshdup\t{%1, %0|%0, %1}"
22984 [(set_attr "type" "sse")
22985 (set_attr "mode" "V4SF")])
22986
22987(define_insn "movsldup"
22988 [(set (match_operand:V4SF 0 "register_operand" "=x")
22989 (unspec:V4SF
22990 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22991 "TARGET_SSE3"
22992 "movsldup\t{%1, %0|%0, %1}"
22993 [(set_attr "type" "sse")
22994 (set_attr "mode" "V4SF")])
22995
22996(define_insn "lddqu"
22997 [(set (match_operand:V16QI 0 "register_operand" "=x")
22998 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22999 UNSPEC_LDQQU))]
23000 "TARGET_SSE3"
23001 "lddqu\t{%1, %0|%0, %1}"
23002 [(set_attr "type" "ssecvt")
23003 (set_attr "mode" "TI")])
23004
23005(define_insn "loadddup"
23006 [(set (match_operand:V2DF 0 "register_operand" "=x")
23007 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23008 "TARGET_SSE3"
23009 "movddup\t{%1, %0|%0, %1}"
23010 [(set_attr "type" "ssecvt")
23011 (set_attr "mode" "DF")])
23012
23013(define_insn "movddup"
23014 [(set (match_operand:V2DF 0 "register_operand" "=x")
23015 (vec_duplicate:V2DF
23016 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23017 (parallel [(const_int 0)]))))]
23018 "TARGET_SSE3"
23019 "movddup\t{%1, %0|%0, %1}"
23020 [(set_attr "type" "ssecvt")
23021 (set_attr "mode" "DF")])