i386.md (testdi_1_rex64): Discourage reload from using the %eax alternative.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003
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 GNU CC.
9 ;;
10 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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 #define NOTICE_UPDATE_CC in file i386.h handles condition code
31 ;; updates for most instructions.
32 ;;
33 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
34 ;; constraint letters.
35 ;;
36 ;; The special asm out single letter directives following a '%' are:
37 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
38 ;; operands[1].
39 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
40 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
41 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
42 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
43 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
44 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
45 ;; 'J' Print the appropriate jump operand.
46 ;;
47 ;; 'b' Print the QImode name of the register for the indicated operand.
48 ;; %b0 would print %al if operands[0] is reg 0.
49 ;; 'w' Likewise, print the HImode name of the register.
50 ;; 'k' Likewise, print the SImode name of the register.
51 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; 'y' Print "st(0)" instead of "st" as a register.
53
54 ;; UNSPEC usage:
55
56 (define_constants
57 [; Relocation specifiers
58 (UNSPEC_GOT 0)
59 (UNSPEC_GOTOFF 1)
60 (UNSPEC_GOTPCREL 2)
61 (UNSPEC_GOTTPOFF 3)
62 (UNSPEC_TPOFF 4)
63 (UNSPEC_NTPOFF 5)
64 (UNSPEC_DTPOFF 6)
65 (UNSPEC_GOTNTPOFF 7)
66 (UNSPEC_INDNTPOFF 8)
67
68 ; Prologue support
69 (UNSPEC_STACK_PROBE 10)
70 (UNSPEC_STACK_ALLOC 11)
71 (UNSPEC_SET_GOT 12)
72 (UNSPEC_SSE_PROLOGUE_SAVE 13)
73
74 ; TLS support
75 (UNSPEC_TP 15)
76 (UNSPEC_TLS_GD 16)
77 (UNSPEC_TLS_LD_BASE 17)
78
79 ; Other random patterns
80 (UNSPEC_SCAS 20)
81 (UNSPEC_SIN 21)
82 (UNSPEC_COS 22)
83 (UNSPEC_FNSTSW 24)
84 (UNSPEC_SAHF 25)
85 (UNSPEC_FSTCW 26)
86 (UNSPEC_ADD_CARRY 27)
87 (UNSPEC_FLDCW 28)
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX 30)
91 (UNSPEC_MASKMOV 32)
92 (UNSPEC_MOVMSK 33)
93 (UNSPEC_MOVNT 34)
94 (UNSPEC_MOVA 38)
95 (UNSPEC_MOVU 39)
96 (UNSPEC_SHUFFLE 41)
97 (UNSPEC_RCP 42)
98 (UNSPEC_RSQRT 43)
99 (UNSPEC_SFENCE 44)
100 (UNSPEC_NOP 45) ; prevents combiner cleverness
101 (UNSPEC_PAVGUSB 49)
102 (UNSPEC_PFRCP 50)
103 (UNSPEC_PFRCPIT1 51)
104 (UNSPEC_PFRCPIT2 52)
105 (UNSPEC_PFRSQRT 53)
106 (UNSPEC_PFRSQIT1 54)
107 (UNSPEC_PSHUFLW 55)
108 (UNSPEC_PSHUFHW 56)
109 (UNSPEC_MFENCE 59)
110 (UNSPEC_LFENCE 60)
111 (UNSPEC_PSADBW 61)
112
113 ; x87 Floating point
114 (UNSPEC_FPATAN 65)
115 ])
116
117 (define_constants
118 [(UNSPECV_BLOCKAGE 0)
119 (UNSPECV_EH_RETURN 13)
120 (UNSPECV_EMMS 31)
121 (UNSPECV_LDMXCSR 37)
122 (UNSPECV_STMXCSR 40)
123 (UNSPECV_FEMMS 46)
124 (UNSPECV_CLFLUSH 57)
125 ])
126
127 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
128 ;; from i386.c.
129
130 ;; In C guard expressions, put expressions which may be compile-time
131 ;; constants first. This allows for better optimization. For
132 ;; example, write "TARGET_64BIT && reload_completed", not
133 ;; "reload_completed && TARGET_64BIT".
134
135 \f
136 ;; Processor type. This attribute must exactly match the processor_type
137 ;; enumeration in i386.h.
138 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
139 (const (symbol_ref "ix86_tune")))
140
141 ;; A basic instruction type. Refinements due to arguments to be
142 ;; provided in other attributes.
143 (define_attr "type"
144 "other,multi,
145 alu,alu1,negnot,imov,imovx,lea,
146 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
147 icmp,test,ibr,setcc,icmov,
148 push,pop,call,callv,leave,
149 str,cld,
150 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
151 sselog,sseiadd,sseishft,sseimul,
152 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
153 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
154 (const_string "other"))
155
156 ;; Main data type used by the insn
157 (define_attr "mode"
158 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
159 (const_string "unknown"))
160
161 ;; The CPU unit operations uses.
162 (define_attr "unit" "integer,i387,sse,mmx,unknown"
163 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
164 (const_string "i387")
165 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
166 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
167 (const_string "sse")
168 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
169 (const_string "mmx")
170 (eq_attr "type" "other")
171 (const_string "unknown")]
172 (const_string "integer")))
173
174 ;; The (bounding maximum) length of an instruction immediate.
175 (define_attr "length_immediate" ""
176 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
177 (const_int 0)
178 (eq_attr "unit" "i387,sse,mmx")
179 (const_int 0)
180 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
181 imul,icmp,push,pop")
182 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
183 (eq_attr "type" "imov,test")
184 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
185 (eq_attr "type" "call")
186 (if_then_else (match_operand 0 "constant_call_address_operand" "")
187 (const_int 4)
188 (const_int 0))
189 (eq_attr "type" "callv")
190 (if_then_else (match_operand 1 "constant_call_address_operand" "")
191 (const_int 4)
192 (const_int 0))
193 ;; We don't know the size before shorten_branches. Expect
194 ;; the instruction to fit for better scheduling.
195 (eq_attr "type" "ibr")
196 (const_int 1)
197 ]
198 (symbol_ref "/* Update immediate_length and other attributes! */
199 abort(),1")))
200
201 ;; The (bounding maximum) length of an instruction address.
202 (define_attr "length_address" ""
203 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
204 (const_int 0)
205 (and (eq_attr "type" "call")
206 (match_operand 0 "constant_call_address_operand" ""))
207 (const_int 0)
208 (and (eq_attr "type" "callv")
209 (match_operand 1 "constant_call_address_operand" ""))
210 (const_int 0)
211 ]
212 (symbol_ref "ix86_attr_length_address_default (insn)")))
213
214 ;; Set when length prefix is used.
215 (define_attr "prefix_data16" ""
216 (if_then_else (ior (eq_attr "mode" "HI")
217 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
218 (const_int 1)
219 (const_int 0)))
220
221 ;; Set when string REP prefix is used.
222 (define_attr "prefix_rep" ""
223 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
224 (const_int 1)
225 (const_int 0)))
226
227 ;; Set when 0f opcode prefix is used.
228 (define_attr "prefix_0f" ""
229 (if_then_else
230 (ior (eq_attr "type" "imovx,setcc,icmov")
231 (eq_attr "unit" "sse,mmx"))
232 (const_int 1)
233 (const_int 0)))
234
235 ;; Set when 0f opcode prefix is used.
236 (define_attr "prefix_rex" ""
237 (cond [(and (eq_attr "mode" "DI")
238 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
239 (const_int 1)
240 (and (eq_attr "mode" "QI")
241 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
242 (const_int 0)))
243 (const_int 1)
244 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
245 (const_int 0))
246 (const_int 1)
247 ]
248 (const_int 0)))
249
250 ;; Set when modrm byte is used.
251 (define_attr "modrm" ""
252 (cond [(eq_attr "type" "str,cld,leave")
253 (const_int 0)
254 (eq_attr "unit" "i387")
255 (const_int 0)
256 (and (eq_attr "type" "incdec")
257 (ior (match_operand:SI 1 "register_operand" "")
258 (match_operand:HI 1 "register_operand" "")))
259 (const_int 0)
260 (and (eq_attr "type" "push")
261 (not (match_operand 1 "memory_operand" "")))
262 (const_int 0)
263 (and (eq_attr "type" "pop")
264 (not (match_operand 0 "memory_operand" "")))
265 (const_int 0)
266 (and (eq_attr "type" "imov")
267 (and (match_operand 0 "register_operand" "")
268 (match_operand 1 "immediate_operand" "")))
269 (const_int 0)
270 (and (eq_attr "type" "call")
271 (match_operand 0 "constant_call_address_operand" ""))
272 (const_int 0)
273 (and (eq_attr "type" "callv")
274 (match_operand 1 "constant_call_address_operand" ""))
275 (const_int 0)
276 ]
277 (const_int 1)))
278
279 ;; The (bounding maximum) length of an instruction in bytes.
280 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
281 ;; to split it and compute proper length as for other insns.
282 (define_attr "length" ""
283 (cond [(eq_attr "type" "other,multi,fistp")
284 (const_int 16)
285 (eq_attr "unit" "i387")
286 (plus (const_int 2)
287 (plus (attr "prefix_data16")
288 (attr "length_address")))]
289 (plus (plus (attr "modrm")
290 (plus (attr "prefix_0f")
291 (plus (attr "prefix_rex")
292 (const_int 1))))
293 (plus (attr "prefix_rep")
294 (plus (attr "prefix_data16")
295 (plus (attr "length_immediate")
296 (attr "length_address")))))))
297
298 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
299 ;; `store' if there is a simple memory reference therein, or `unknown'
300 ;; if the instruction is complex.
301
302 (define_attr "memory" "none,load,store,both,unknown"
303 (cond [(eq_attr "type" "other,multi,str")
304 (const_string "unknown")
305 (eq_attr "type" "lea,fcmov,fpspc,cld")
306 (const_string "none")
307 (eq_attr "type" "fistp,leave")
308 (const_string "both")
309 (eq_attr "type" "push")
310 (if_then_else (match_operand 1 "memory_operand" "")
311 (const_string "both")
312 (const_string "store"))
313 (eq_attr "type" "pop")
314 (if_then_else (match_operand 0 "memory_operand" "")
315 (const_string "both")
316 (const_string "load"))
317 (eq_attr "type" "setcc")
318 (if_then_else (match_operand 0 "memory_operand" "")
319 (const_string "store")
320 (const_string "none"))
321 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
322 (if_then_else (ior (match_operand 0 "memory_operand" "")
323 (match_operand 1 "memory_operand" ""))
324 (const_string "load")
325 (const_string "none"))
326 (eq_attr "type" "ibr")
327 (if_then_else (match_operand 0 "memory_operand" "")
328 (const_string "load")
329 (const_string "none"))
330 (eq_attr "type" "call")
331 (if_then_else (match_operand 0 "constant_call_address_operand" "")
332 (const_string "none")
333 (const_string "load"))
334 (eq_attr "type" "callv")
335 (if_then_else (match_operand 1 "constant_call_address_operand" "")
336 (const_string "none")
337 (const_string "load"))
338 (and (eq_attr "type" "alu1,negnot")
339 (match_operand 1 "memory_operand" ""))
340 (const_string "both")
341 (and (match_operand 0 "memory_operand" "")
342 (match_operand 1 "memory_operand" ""))
343 (const_string "both")
344 (match_operand 0 "memory_operand" "")
345 (const_string "store")
346 (match_operand 1 "memory_operand" "")
347 (const_string "load")
348 (and (eq_attr "type"
349 "!alu1,negnot,
350 imov,imovx,icmp,test,
351 fmov,fcmp,fsgn,
352 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
353 mmx,mmxmov,mmxcmp,mmxcvt")
354 (match_operand 2 "memory_operand" ""))
355 (const_string "load")
356 (and (eq_attr "type" "icmov")
357 (match_operand 3 "memory_operand" ""))
358 (const_string "load")
359 ]
360 (const_string "none")))
361
362 ;; Indicates if an instruction has both an immediate and a displacement.
363
364 (define_attr "imm_disp" "false,true,unknown"
365 (cond [(eq_attr "type" "other,multi")
366 (const_string "unknown")
367 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
368 (and (match_operand 0 "memory_displacement_operand" "")
369 (match_operand 1 "immediate_operand" "")))
370 (const_string "true")
371 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
372 (and (match_operand 0 "memory_displacement_operand" "")
373 (match_operand 2 "immediate_operand" "")))
374 (const_string "true")
375 ]
376 (const_string "false")))
377
378 ;; Indicates if an FP operation has an integer source.
379
380 (define_attr "fp_int_src" "false,true"
381 (const_string "false"))
382
383 ;; Describe a user's asm statement.
384 (define_asm_attributes
385 [(set_attr "length" "128")
386 (set_attr "type" "multi")])
387 \f
388 (include "pentium.md")
389 (include "ppro.md")
390 (include "k6.md")
391 (include "athlon.md")
392 \f
393 ;; Compare instructions.
394
395 ;; All compare insns have expanders that save the operands away without
396 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
397 ;; after the cmp) will actually emit the cmpM.
398
399 (define_expand "cmpdi"
400 [(set (reg:CC 17)
401 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
402 (match_operand:DI 1 "x86_64_general_operand" "")))]
403 ""
404 {
405 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
406 operands[0] = force_reg (DImode, operands[0]);
407 ix86_compare_op0 = operands[0];
408 ix86_compare_op1 = operands[1];
409 DONE;
410 })
411
412 (define_expand "cmpsi"
413 [(set (reg:CC 17)
414 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
415 (match_operand:SI 1 "general_operand" "")))]
416 ""
417 {
418 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
419 operands[0] = force_reg (SImode, operands[0]);
420 ix86_compare_op0 = operands[0];
421 ix86_compare_op1 = operands[1];
422 DONE;
423 })
424
425 (define_expand "cmphi"
426 [(set (reg:CC 17)
427 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
428 (match_operand:HI 1 "general_operand" "")))]
429 ""
430 {
431 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
432 operands[0] = force_reg (HImode, operands[0]);
433 ix86_compare_op0 = operands[0];
434 ix86_compare_op1 = operands[1];
435 DONE;
436 })
437
438 (define_expand "cmpqi"
439 [(set (reg:CC 17)
440 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
441 (match_operand:QI 1 "general_operand" "")))]
442 "TARGET_QIMODE_MATH"
443 {
444 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
445 operands[0] = force_reg (QImode, operands[0]);
446 ix86_compare_op0 = operands[0];
447 ix86_compare_op1 = operands[1];
448 DONE;
449 })
450
451 (define_insn "cmpdi_ccno_1_rex64"
452 [(set (reg 17)
453 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
454 (match_operand:DI 1 "const0_operand" "n,n")))]
455 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
456 "@
457 test{q}\t{%0, %0|%0, %0}
458 cmp{q}\t{%1, %0|%0, %1}"
459 [(set_attr "type" "test,icmp")
460 (set_attr "length_immediate" "0,1")
461 (set_attr "mode" "DI")])
462
463 (define_insn "*cmpdi_minus_1_rex64"
464 [(set (reg 17)
465 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
466 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
467 (const_int 0)))]
468 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
469 "cmp{q}\t{%1, %0|%0, %1}"
470 [(set_attr "type" "icmp")
471 (set_attr "mode" "DI")])
472
473 (define_expand "cmpdi_1_rex64"
474 [(set (reg:CC 17)
475 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
476 (match_operand:DI 1 "general_operand" "")))]
477 "TARGET_64BIT"
478 "")
479
480 (define_insn "cmpdi_1_insn_rex64"
481 [(set (reg 17)
482 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
483 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
484 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
485 "cmp{q}\t{%1, %0|%0, %1}"
486 [(set_attr "type" "icmp")
487 (set_attr "mode" "DI")])
488
489
490 (define_insn "*cmpsi_ccno_1"
491 [(set (reg 17)
492 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
493 (match_operand:SI 1 "const0_operand" "n,n")))]
494 "ix86_match_ccmode (insn, CCNOmode)"
495 "@
496 test{l}\t{%0, %0|%0, %0}
497 cmp{l}\t{%1, %0|%0, %1}"
498 [(set_attr "type" "test,icmp")
499 (set_attr "length_immediate" "0,1")
500 (set_attr "mode" "SI")])
501
502 (define_insn "*cmpsi_minus_1"
503 [(set (reg 17)
504 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
505 (match_operand:SI 1 "general_operand" "ri,mr"))
506 (const_int 0)))]
507 "ix86_match_ccmode (insn, CCGOCmode)"
508 "cmp{l}\t{%1, %0|%0, %1}"
509 [(set_attr "type" "icmp")
510 (set_attr "mode" "SI")])
511
512 (define_expand "cmpsi_1"
513 [(set (reg:CC 17)
514 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
515 (match_operand:SI 1 "general_operand" "ri,mr")))]
516 ""
517 "")
518
519 (define_insn "*cmpsi_1_insn"
520 [(set (reg 17)
521 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
522 (match_operand:SI 1 "general_operand" "ri,mr")))]
523 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
524 && ix86_match_ccmode (insn, CCmode)"
525 "cmp{l}\t{%1, %0|%0, %1}"
526 [(set_attr "type" "icmp")
527 (set_attr "mode" "SI")])
528
529 (define_insn "*cmphi_ccno_1"
530 [(set (reg 17)
531 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
532 (match_operand:HI 1 "const0_operand" "n,n")))]
533 "ix86_match_ccmode (insn, CCNOmode)"
534 "@
535 test{w}\t{%0, %0|%0, %0}
536 cmp{w}\t{%1, %0|%0, %1}"
537 [(set_attr "type" "test,icmp")
538 (set_attr "length_immediate" "0,1")
539 (set_attr "mode" "HI")])
540
541 (define_insn "*cmphi_minus_1"
542 [(set (reg 17)
543 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
544 (match_operand:HI 1 "general_operand" "ri,mr"))
545 (const_int 0)))]
546 "ix86_match_ccmode (insn, CCGOCmode)"
547 "cmp{w}\t{%1, %0|%0, %1}"
548 [(set_attr "type" "icmp")
549 (set_attr "mode" "HI")])
550
551 (define_insn "*cmphi_1"
552 [(set (reg 17)
553 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
554 (match_operand:HI 1 "general_operand" "ri,mr")))]
555 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
556 && ix86_match_ccmode (insn, CCmode)"
557 "cmp{w}\t{%1, %0|%0, %1}"
558 [(set_attr "type" "icmp")
559 (set_attr "mode" "HI")])
560
561 (define_insn "*cmpqi_ccno_1"
562 [(set (reg 17)
563 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
564 (match_operand:QI 1 "const0_operand" "n,n")))]
565 "ix86_match_ccmode (insn, CCNOmode)"
566 "@
567 test{b}\t{%0, %0|%0, %0}
568 cmp{b}\t{$0, %0|%0, 0}"
569 [(set_attr "type" "test,icmp")
570 (set_attr "length_immediate" "0,1")
571 (set_attr "mode" "QI")])
572
573 (define_insn "*cmpqi_1"
574 [(set (reg 17)
575 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
576 (match_operand:QI 1 "general_operand" "qi,mq")))]
577 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
578 && ix86_match_ccmode (insn, CCmode)"
579 "cmp{b}\t{%1, %0|%0, %1}"
580 [(set_attr "type" "icmp")
581 (set_attr "mode" "QI")])
582
583 (define_insn "*cmpqi_minus_1"
584 [(set (reg 17)
585 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
586 (match_operand:QI 1 "general_operand" "qi,mq"))
587 (const_int 0)))]
588 "ix86_match_ccmode (insn, CCGOCmode)"
589 "cmp{b}\t{%1, %0|%0, %1}"
590 [(set_attr "type" "icmp")
591 (set_attr "mode" "QI")])
592
593 (define_insn "*cmpqi_ext_1"
594 [(set (reg 17)
595 (compare
596 (match_operand:QI 0 "general_operand" "Qm")
597 (subreg:QI
598 (zero_extract:SI
599 (match_operand 1 "ext_register_operand" "Q")
600 (const_int 8)
601 (const_int 8)) 0)))]
602 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603 "cmp{b}\t{%h1, %0|%0, %h1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "QI")])
606
607 (define_insn "*cmpqi_ext_1_rex64"
608 [(set (reg 17)
609 (compare
610 (match_operand:QI 0 "register_operand" "Q")
611 (subreg:QI
612 (zero_extract:SI
613 (match_operand 1 "ext_register_operand" "Q")
614 (const_int 8)
615 (const_int 8)) 0)))]
616 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
617 "cmp{b}\t{%h1, %0|%0, %h1}"
618 [(set_attr "type" "icmp")
619 (set_attr "mode" "QI")])
620
621 (define_insn "*cmpqi_ext_2"
622 [(set (reg 17)
623 (compare
624 (subreg:QI
625 (zero_extract:SI
626 (match_operand 0 "ext_register_operand" "Q")
627 (const_int 8)
628 (const_int 8)) 0)
629 (match_operand:QI 1 "const0_operand" "n")))]
630 "ix86_match_ccmode (insn, CCNOmode)"
631 "test{b}\t%h0, %h0"
632 [(set_attr "type" "test")
633 (set_attr "length_immediate" "0")
634 (set_attr "mode" "QI")])
635
636 (define_expand "cmpqi_ext_3"
637 [(set (reg:CC 17)
638 (compare:CC
639 (subreg:QI
640 (zero_extract:SI
641 (match_operand 0 "ext_register_operand" "")
642 (const_int 8)
643 (const_int 8)) 0)
644 (match_operand:QI 1 "general_operand" "")))]
645 ""
646 "")
647
648 (define_insn "cmpqi_ext_3_insn"
649 [(set (reg 17)
650 (compare
651 (subreg:QI
652 (zero_extract:SI
653 (match_operand 0 "ext_register_operand" "Q")
654 (const_int 8)
655 (const_int 8)) 0)
656 (match_operand:QI 1 "general_operand" "Qmn")))]
657 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
658 "cmp{b}\t{%1, %h0|%h0, %1}"
659 [(set_attr "type" "icmp")
660 (set_attr "mode" "QI")])
661
662 (define_insn "cmpqi_ext_3_insn_rex64"
663 [(set (reg 17)
664 (compare
665 (subreg:QI
666 (zero_extract:SI
667 (match_operand 0 "ext_register_operand" "Q")
668 (const_int 8)
669 (const_int 8)) 0)
670 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
671 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
672 "cmp{b}\t{%1, %h0|%h0, %1}"
673 [(set_attr "type" "icmp")
674 (set_attr "mode" "QI")])
675
676 (define_insn "*cmpqi_ext_4"
677 [(set (reg 17)
678 (compare
679 (subreg:QI
680 (zero_extract:SI
681 (match_operand 0 "ext_register_operand" "Q")
682 (const_int 8)
683 (const_int 8)) 0)
684 (subreg:QI
685 (zero_extract:SI
686 (match_operand 1 "ext_register_operand" "Q")
687 (const_int 8)
688 (const_int 8)) 0)))]
689 "ix86_match_ccmode (insn, CCmode)"
690 "cmp{b}\t{%h1, %h0|%h0, %h1}"
691 [(set_attr "type" "icmp")
692 (set_attr "mode" "QI")])
693
694 ;; These implement float point compares.
695 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
696 ;; which would allow mix and match FP modes on the compares. Which is what
697 ;; the old patterns did, but with many more of them.
698
699 (define_expand "cmpxf"
700 [(set (reg:CC 17)
701 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
702 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
703 "!TARGET_64BIT && TARGET_80387"
704 {
705 ix86_compare_op0 = operands[0];
706 ix86_compare_op1 = operands[1];
707 DONE;
708 })
709
710 (define_expand "cmptf"
711 [(set (reg:CC 17)
712 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
713 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
714 "TARGET_80387"
715 {
716 ix86_compare_op0 = operands[0];
717 ix86_compare_op1 = operands[1];
718 DONE;
719 })
720
721 (define_expand "cmpdf"
722 [(set (reg:CC 17)
723 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
724 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
725 "TARGET_80387 || TARGET_SSE2"
726 {
727 ix86_compare_op0 = operands[0];
728 ix86_compare_op1 = operands[1];
729 DONE;
730 })
731
732 (define_expand "cmpsf"
733 [(set (reg:CC 17)
734 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
735 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
736 "TARGET_80387 || TARGET_SSE"
737 {
738 ix86_compare_op0 = operands[0];
739 ix86_compare_op1 = operands[1];
740 DONE;
741 })
742
743 ;; FP compares, step 1:
744 ;; Set the FP condition codes.
745 ;;
746 ;; CCFPmode compare with exceptions
747 ;; CCFPUmode compare with no exceptions
748
749 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
750 ;; and that fp moves clobber the condition codes, and that there is
751 ;; currently no way to describe this fact to reg-stack. So there are
752 ;; no splitters yet for this.
753
754 ;; %%% YIKES! This scheme does not retain a strong connection between
755 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
756 ;; work! Only allow tos/mem with tos in op 0.
757 ;;
758 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
759 ;; things aren't as bad as they sound...
760
761 (define_insn "*cmpfp_0"
762 [(set (match_operand:HI 0 "register_operand" "=a")
763 (unspec:HI
764 [(compare:CCFP (match_operand 1 "register_operand" "f")
765 (match_operand 2 "const0_operand" "X"))]
766 UNSPEC_FNSTSW))]
767 "TARGET_80387
768 && FLOAT_MODE_P (GET_MODE (operands[1]))
769 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
770 {
771 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
772 return "ftst\;fnstsw\t%0\;fstp\t%y0";
773 else
774 return "ftst\;fnstsw\t%0";
775 }
776 [(set_attr "type" "multi")
777 (set (attr "mode")
778 (cond [(match_operand:SF 1 "" "")
779 (const_string "SF")
780 (match_operand:DF 1 "" "")
781 (const_string "DF")
782 ]
783 (const_string "XF")))])
784
785 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
786 ;; used to manage the reg stack popping would not be preserved.
787
788 (define_insn "*cmpfp_2_sf"
789 [(set (reg:CCFP 18)
790 (compare:CCFP
791 (match_operand:SF 0 "register_operand" "f")
792 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
793 "TARGET_80387"
794 "* return output_fp_compare (insn, operands, 0, 0);"
795 [(set_attr "type" "fcmp")
796 (set_attr "mode" "SF")])
797
798 (define_insn "*cmpfp_2_sf_1"
799 [(set (match_operand:HI 0 "register_operand" "=a")
800 (unspec:HI
801 [(compare:CCFP
802 (match_operand:SF 1 "register_operand" "f")
803 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
804 UNSPEC_FNSTSW))]
805 "TARGET_80387"
806 "* return output_fp_compare (insn, operands, 2, 0);"
807 [(set_attr "type" "fcmp")
808 (set_attr "mode" "SF")])
809
810 (define_insn "*cmpfp_2_df"
811 [(set (reg:CCFP 18)
812 (compare:CCFP
813 (match_operand:DF 0 "register_operand" "f")
814 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
815 "TARGET_80387"
816 "* return output_fp_compare (insn, operands, 0, 0);"
817 [(set_attr "type" "fcmp")
818 (set_attr "mode" "DF")])
819
820 (define_insn "*cmpfp_2_df_1"
821 [(set (match_operand:HI 0 "register_operand" "=a")
822 (unspec:HI
823 [(compare:CCFP
824 (match_operand:DF 1 "register_operand" "f")
825 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
826 UNSPEC_FNSTSW))]
827 "TARGET_80387"
828 "* return output_fp_compare (insn, operands, 2, 0);"
829 [(set_attr "type" "multi")
830 (set_attr "mode" "DF")])
831
832 (define_insn "*cmpfp_2_xf"
833 [(set (reg:CCFP 18)
834 (compare:CCFP
835 (match_operand:XF 0 "register_operand" "f")
836 (match_operand:XF 1 "register_operand" "f")))]
837 "!TARGET_64BIT && TARGET_80387"
838 "* return output_fp_compare (insn, operands, 0, 0);"
839 [(set_attr "type" "fcmp")
840 (set_attr "mode" "XF")])
841
842 (define_insn "*cmpfp_2_tf"
843 [(set (reg:CCFP 18)
844 (compare:CCFP
845 (match_operand:TF 0 "register_operand" "f")
846 (match_operand:TF 1 "register_operand" "f")))]
847 "TARGET_80387"
848 "* return output_fp_compare (insn, operands, 0, 0);"
849 [(set_attr "type" "fcmp")
850 (set_attr "mode" "XF")])
851
852 (define_insn "*cmpfp_2_xf_1"
853 [(set (match_operand:HI 0 "register_operand" "=a")
854 (unspec:HI
855 [(compare:CCFP
856 (match_operand:XF 1 "register_operand" "f")
857 (match_operand:XF 2 "register_operand" "f"))]
858 UNSPEC_FNSTSW))]
859 "!TARGET_64BIT && TARGET_80387"
860 "* return output_fp_compare (insn, operands, 2, 0);"
861 [(set_attr "type" "multi")
862 (set_attr "mode" "XF")])
863
864 (define_insn "*cmpfp_2_tf_1"
865 [(set (match_operand:HI 0 "register_operand" "=a")
866 (unspec:HI
867 [(compare:CCFP
868 (match_operand:TF 1 "register_operand" "f")
869 (match_operand:TF 2 "register_operand" "f"))]
870 UNSPEC_FNSTSW))]
871 "TARGET_80387"
872 "* return output_fp_compare (insn, operands, 2, 0);"
873 [(set_attr "type" "multi")
874 (set_attr "mode" "XF")])
875
876 (define_insn "*cmpfp_2u"
877 [(set (reg:CCFPU 18)
878 (compare:CCFPU
879 (match_operand 0 "register_operand" "f")
880 (match_operand 1 "register_operand" "f")))]
881 "TARGET_80387
882 && FLOAT_MODE_P (GET_MODE (operands[0]))
883 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
884 "* return output_fp_compare (insn, operands, 0, 1);"
885 [(set_attr "type" "fcmp")
886 (set (attr "mode")
887 (cond [(match_operand:SF 1 "" "")
888 (const_string "SF")
889 (match_operand:DF 1 "" "")
890 (const_string "DF")
891 ]
892 (const_string "XF")))])
893
894 (define_insn "*cmpfp_2u_1"
895 [(set (match_operand:HI 0 "register_operand" "=a")
896 (unspec:HI
897 [(compare:CCFPU
898 (match_operand 1 "register_operand" "f")
899 (match_operand 2 "register_operand" "f"))]
900 UNSPEC_FNSTSW))]
901 "TARGET_80387
902 && FLOAT_MODE_P (GET_MODE (operands[1]))
903 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
904 "* return output_fp_compare (insn, operands, 2, 1);"
905 [(set_attr "type" "multi")
906 (set (attr "mode")
907 (cond [(match_operand:SF 1 "" "")
908 (const_string "SF")
909 (match_operand:DF 1 "" "")
910 (const_string "DF")
911 ]
912 (const_string "XF")))])
913
914 ;; Patterns to match the SImode-in-memory ficom instructions.
915 ;;
916 ;; %%% Play games with accepting gp registers, as otherwise we have to
917 ;; force them to memory during rtl generation, which is no good. We
918 ;; can get rid of this once we teach reload to do memory input reloads
919 ;; via pushes.
920
921 (define_insn "*ficom_1"
922 [(set (reg:CCFP 18)
923 (compare:CCFP
924 (match_operand 0 "register_operand" "f,f")
925 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
926 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
927 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
928 "#")
929
930 ;; Split the not-really-implemented gp register case into a
931 ;; push-op-pop sequence.
932 ;;
933 ;; %%% This is most efficient, but am I gonna get in trouble
934 ;; for separating cc0_setter and cc0_user?
935
936 (define_split
937 [(set (reg:CCFP 18)
938 (compare:CCFP
939 (match_operand:SF 0 "register_operand" "")
940 (float (match_operand:SI 1 "register_operand" ""))))]
941 "0 && TARGET_80387 && reload_completed"
942 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
943 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
944 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
945 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
946 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
947 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
948
949 ;; FP compares, step 2
950 ;; Move the fpsw to ax.
951
952 (define_insn "*x86_fnstsw_1"
953 [(set (match_operand:HI 0 "register_operand" "=a")
954 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
955 "TARGET_80387"
956 "fnstsw\t%0"
957 [(set_attr "length" "2")
958 (set_attr "mode" "SI")
959 (set_attr "unit" "i387")
960 (set_attr "ppro_uops" "few")])
961
962 ;; FP compares, step 3
963 ;; Get ax into flags, general case.
964
965 (define_insn "x86_sahf_1"
966 [(set (reg:CC 17)
967 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
968 "!TARGET_64BIT"
969 "sahf"
970 [(set_attr "length" "1")
971 (set_attr "athlon_decode" "vector")
972 (set_attr "mode" "SI")
973 (set_attr "ppro_uops" "one")])
974
975 ;; Pentium Pro can do steps 1 through 3 in one go.
976
977 (define_insn "*cmpfp_i"
978 [(set (reg:CCFP 17)
979 (compare:CCFP (match_operand 0 "register_operand" "f")
980 (match_operand 1 "register_operand" "f")))]
981 "TARGET_80387 && TARGET_CMOVE
982 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983 && FLOAT_MODE_P (GET_MODE (operands[0]))
984 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
985 "* return output_fp_compare (insn, operands, 1, 0);"
986 [(set_attr "type" "fcmp")
987 (set (attr "mode")
988 (cond [(match_operand:SF 1 "" "")
989 (const_string "SF")
990 (match_operand:DF 1 "" "")
991 (const_string "DF")
992 ]
993 (const_string "XF")))
994 (set_attr "athlon_decode" "vector")])
995
996 (define_insn "*cmpfp_i_sse"
997 [(set (reg:CCFP 17)
998 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
999 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1000 "TARGET_80387
1001 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1003 "* return output_fp_compare (insn, operands, 1, 0);"
1004 [(set_attr "type" "fcmp,ssecomi")
1005 (set (attr "mode")
1006 (if_then_else (match_operand:SF 1 "" "")
1007 (const_string "SF")
1008 (const_string "DF")))
1009 (set_attr "athlon_decode" "vector")])
1010
1011 (define_insn "*cmpfp_i_sse_only"
1012 [(set (reg:CCFP 17)
1013 (compare:CCFP (match_operand 0 "register_operand" "x")
1014 (match_operand 1 "nonimmediate_operand" "xm")))]
1015 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1016 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1017 "* return output_fp_compare (insn, operands, 1, 0);"
1018 [(set_attr "type" "ssecomi")
1019 (set (attr "mode")
1020 (if_then_else (match_operand:SF 1 "" "")
1021 (const_string "SF")
1022 (const_string "DF")))
1023 (set_attr "athlon_decode" "vector")])
1024
1025 (define_insn "*cmpfp_iu"
1026 [(set (reg:CCFPU 17)
1027 (compare:CCFPU (match_operand 0 "register_operand" "f")
1028 (match_operand 1 "register_operand" "f")))]
1029 "TARGET_80387 && TARGET_CMOVE
1030 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1031 && FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 1);"
1034 [(set_attr "type" "fcmp")
1035 (set (attr "mode")
1036 (cond [(match_operand:SF 1 "" "")
1037 (const_string "SF")
1038 (match_operand:DF 1 "" "")
1039 (const_string "DF")
1040 ]
1041 (const_string "XF")))
1042 (set_attr "athlon_decode" "vector")])
1043
1044 (define_insn "*cmpfp_iu_sse"
1045 [(set (reg:CCFPU 17)
1046 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1047 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1048 "TARGET_80387
1049 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1050 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1051 "* return output_fp_compare (insn, operands, 1, 1);"
1052 [(set_attr "type" "fcmp,ssecomi")
1053 (set (attr "mode")
1054 (if_then_else (match_operand:SF 1 "" "")
1055 (const_string "SF")
1056 (const_string "DF")))
1057 (set_attr "athlon_decode" "vector")])
1058
1059 (define_insn "*cmpfp_iu_sse_only"
1060 [(set (reg:CCFPU 17)
1061 (compare:CCFPU (match_operand 0 "register_operand" "x")
1062 (match_operand 1 "nonimmediate_operand" "xm")))]
1063 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1064 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1065 "* return output_fp_compare (insn, operands, 1, 1);"
1066 [(set_attr "type" "ssecomi")
1067 (set (attr "mode")
1068 (if_then_else (match_operand:SF 1 "" "")
1069 (const_string "SF")
1070 (const_string "DF")))
1071 (set_attr "athlon_decode" "vector")])
1072 \f
1073 ;; Move instructions.
1074
1075 ;; General case of fullword move.
1076
1077 (define_expand "movsi"
1078 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1079 (match_operand:SI 1 "general_operand" ""))]
1080 ""
1081 "ix86_expand_move (SImode, operands); DONE;")
1082
1083 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1084 ;; general_operand.
1085 ;;
1086 ;; %%% We don't use a post-inc memory reference because x86 is not a
1087 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1088 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1089 ;; targets without our curiosities, and it is just as easy to represent
1090 ;; this differently.
1091
1092 (define_insn "*pushsi2"
1093 [(set (match_operand:SI 0 "push_operand" "=<")
1094 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1095 "!TARGET_64BIT"
1096 "push{l}\t%1"
1097 [(set_attr "type" "push")
1098 (set_attr "mode" "SI")])
1099
1100 ;; For 64BIT abi we always round up to 8 bytes.
1101 (define_insn "*pushsi2_rex64"
1102 [(set (match_operand:SI 0 "push_operand" "=X")
1103 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1104 "TARGET_64BIT"
1105 "push{q}\t%q1"
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1108
1109 (define_insn "*pushsi2_prologue"
1110 [(set (match_operand:SI 0 "push_operand" "=<")
1111 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1112 (clobber (mem:BLK (scratch)))]
1113 "!TARGET_64BIT"
1114 "push{l}\t%1"
1115 [(set_attr "type" "push")
1116 (set_attr "mode" "SI")])
1117
1118 (define_insn "*popsi1_epilogue"
1119 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1120 (mem:SI (reg:SI 7)))
1121 (set (reg:SI 7)
1122 (plus:SI (reg:SI 7) (const_int 4)))
1123 (clobber (mem:BLK (scratch)))]
1124 "!TARGET_64BIT"
1125 "pop{l}\t%0"
1126 [(set_attr "type" "pop")
1127 (set_attr "mode" "SI")])
1128
1129 (define_insn "popsi1"
1130 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1131 (mem:SI (reg:SI 7)))
1132 (set (reg:SI 7)
1133 (plus:SI (reg:SI 7) (const_int 4)))]
1134 "!TARGET_64BIT"
1135 "pop{l}\t%0"
1136 [(set_attr "type" "pop")
1137 (set_attr "mode" "SI")])
1138
1139 (define_insn "*movsi_xor"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (match_operand:SI 1 "const0_operand" "i"))
1142 (clobber (reg:CC 17))]
1143 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1144 "xor{l}\t{%0, %0|%0, %0}"
1145 [(set_attr "type" "alu1")
1146 (set_attr "mode" "SI")
1147 (set_attr "length_immediate" "0")])
1148
1149 (define_insn "*movsi_or"
1150 [(set (match_operand:SI 0 "register_operand" "=r")
1151 (match_operand:SI 1 "immediate_operand" "i"))
1152 (clobber (reg:CC 17))]
1153 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1154 && INTVAL (operands[1]) == -1
1155 && (TARGET_PENTIUM || optimize_size)"
1156 {
1157 operands[1] = constm1_rtx;
1158 return "or{l}\t{%1, %0|%0, %1}";
1159 }
1160 [(set_attr "type" "alu1")
1161 (set_attr "mode" "SI")
1162 (set_attr "length_immediate" "1")])
1163
1164 ; The first alternative is used only to compute proper length of instruction.
1165 ; Reload's algorithm does not take into account the cost of spill instructions
1166 ; needed to free register in given class, so avoid it from choosing the first
1167 ; alternative when eax is not available.
1168
1169 (define_insn "*movsi_1"
1170 [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1171 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1172 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1173 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1174 {
1175 switch (get_attr_type (insn))
1176 {
1177 case TYPE_SSEMOV:
1178 if (get_attr_mode (insn) == TImode)
1179 return "movdqa\t{%1, %0|%0, %1}";
1180 return "movd\t{%1, %0|%0, %1}";
1181
1182 case TYPE_MMXMOV:
1183 if (get_attr_mode (insn) == DImode)
1184 return "movq\t{%1, %0|%0, %1}";
1185 return "movd\t{%1, %0|%0, %1}";
1186
1187 case TYPE_LEA:
1188 return "lea{l}\t{%1, %0|%0, %1}";
1189
1190 default:
1191 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1192 abort();
1193 return "mov{l}\t{%1, %0|%0, %1}";
1194 }
1195 }
1196 [(set (attr "type")
1197 (cond [(eq_attr "alternative" "4,5,6")
1198 (const_string "mmxmov")
1199 (eq_attr "alternative" "7,8,9")
1200 (const_string "ssemov")
1201 (and (ne (symbol_ref "flag_pic") (const_int 0))
1202 (match_operand:SI 1 "symbolic_operand" ""))
1203 (const_string "lea")
1204 ]
1205 (const_string "imov")))
1206 (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
1207 (set_attr "mode" "SI,SI,SI,SI,DI,SI,SI,TI,SI,SI")])
1208
1209 (define_insn "*movsi_1_nointernunit"
1210 [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!m,!*y,!*Y,!m,!*Y")
1211 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,*y,*y,m,*Y,*Y,m"))]
1212 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1213 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1214 {
1215 switch (get_attr_type (insn))
1216 {
1217 case TYPE_SSEMOV:
1218 if (get_attr_mode (insn) == TImode || which_alternative == 9)
1219 return "movdqa\t{%1, %0|%0, %1}";
1220 return "movd\t{%1, %0|%0, %1}";
1221
1222 case TYPE_MMXMOV:
1223 if (get_attr_mode (insn) == DImode)
1224 return "movq\t{%1, %0|%0, %1}";
1225 return "movd\t{%1, %0|%0, %1}";
1226
1227 case TYPE_LEA:
1228 return "lea{l}\t{%1, %0|%0, %1}";
1229
1230 default:
1231 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1232 abort();
1233 return "mov{l}\t{%1, %0|%0, %1}";
1234 }
1235 }
1236 [(set (attr "type")
1237 (cond [(eq_attr "alternative" "4,5,6")
1238 (const_string "mmxmov")
1239 (eq_attr "alternative" "7,8,9")
1240 (const_string "ssemov")
1241 (and (ne (symbol_ref "flag_pic") (const_int 0))
1242 (match_operand:SI 1 "symbolic_operand" ""))
1243 (const_string "lea")
1244 ]
1245 (const_string "imov")))
1246 (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
1247 (set_attr "mode" "SI,SI,SI,SI,DI,SI,SI,TI,SI,SI")])
1248
1249 ;; Stores and loads of ax to arbitrary constant address.
1250 ;; We fake an second form of instruction to force reload to load address
1251 ;; into register when rax is not available
1252 (define_insn "*movabssi_1_rex64"
1253 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1254 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1255 "TARGET_64BIT"
1256 "@
1257 movabs{l}\t{%1, %P0|%P0, %1}
1258 mov{l}\t{%1, %a0|%a0, %1}
1259 movabs{l}\t{%1, %a0|%a0, %1}"
1260 [(set_attr "type" "imov")
1261 (set_attr "modrm" "0,*,*")
1262 (set_attr "length_address" "8,0,0")
1263 (set_attr "length_immediate" "0,*,*")
1264 (set_attr "memory" "store")
1265 (set_attr "mode" "SI")])
1266
1267 (define_insn "*movabssi_2_rex64"
1268 [(set (match_operand:SI 0 "register_operand" "=a,r")
1269 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1270 "TARGET_64BIT"
1271 "@
1272 movabs{l}\t{%P1, %0|%0, %P1}
1273 mov{l}\t{%a1, %0|%0, %a1}"
1274 [(set_attr "type" "imov")
1275 (set_attr "modrm" "0,*")
1276 (set_attr "length_address" "8,0")
1277 (set_attr "length_immediate" "0")
1278 (set_attr "memory" "load")
1279 (set_attr "mode" "SI")])
1280
1281 (define_insn "*swapsi"
1282 [(set (match_operand:SI 0 "register_operand" "+r")
1283 (match_operand:SI 1 "register_operand" "+r"))
1284 (set (match_dup 1)
1285 (match_dup 0))]
1286 ""
1287 "xchg{l}\t%1, %0"
1288 [(set_attr "type" "imov")
1289 (set_attr "pent_pair" "np")
1290 (set_attr "athlon_decode" "vector")
1291 (set_attr "mode" "SI")
1292 (set_attr "modrm" "0")
1293 (set_attr "ppro_uops" "few")])
1294
1295 (define_expand "movhi"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297 (match_operand:HI 1 "general_operand" ""))]
1298 ""
1299 "ix86_expand_move (HImode, operands); DONE;")
1300
1301 (define_insn "*pushhi2"
1302 [(set (match_operand:HI 0 "push_operand" "=<,<")
1303 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1304 "!TARGET_64BIT"
1305 "@
1306 push{w}\t{|WORD PTR }%1
1307 push{w}\t%1"
1308 [(set_attr "type" "push")
1309 (set_attr "mode" "HI")])
1310
1311 ;; For 64BIT abi we always round up to 8 bytes.
1312 (define_insn "*pushhi2_rex64"
1313 [(set (match_operand:HI 0 "push_operand" "=X")
1314 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1315 "TARGET_64BIT"
1316 "push{q}\t%q1"
1317 [(set_attr "type" "push")
1318 (set_attr "mode" "QI")])
1319
1320 ; The first alternative is used only to compute proper length of instruction.
1321 ; Reload's algorithm does not take into account the cost of spill instructions
1322 ; needed to free register in given class, so avoid it from choosing the first
1323 ; alternative when eax is not available.
1324
1325 (define_insn "*movhi_1"
1326 [(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
1327 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1328 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1329 {
1330 switch (get_attr_type (insn))
1331 {
1332 case TYPE_IMOVX:
1333 /* movzwl is faster than movw on p2 due to partial word stalls,
1334 though not as fast as an aligned movl. */
1335 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1336 default:
1337 if (get_attr_mode (insn) == MODE_SI)
1338 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1339 else
1340 return "mov{w}\t{%1, %0|%0, %1}";
1341 }
1342 }
1343 [(set (attr "type")
1344 (cond [(and (eq_attr "alternative" "0,1")
1345 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1346 (const_int 0))
1347 (eq (symbol_ref "TARGET_HIMODE_MATH")
1348 (const_int 0))))
1349 (const_string "imov")
1350 (and (eq_attr "alternative" "2,3,4")
1351 (match_operand:HI 1 "aligned_operand" ""))
1352 (const_string "imov")
1353 (and (ne (symbol_ref "TARGET_MOVX")
1354 (const_int 0))
1355 (eq_attr "alternative" "0,1,3,4"))
1356 (const_string "imovx")
1357 ]
1358 (const_string "imov")))
1359 (set (attr "mode")
1360 (cond [(eq_attr "type" "imovx")
1361 (const_string "SI")
1362 (and (eq_attr "alternative" "2,3,4")
1363 (match_operand:HI 1 "aligned_operand" ""))
1364 (const_string "SI")
1365 (and (eq_attr "alternative" "0,1")
1366 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1367 (const_int 0))
1368 (eq (symbol_ref "TARGET_HIMODE_MATH")
1369 (const_int 0))))
1370 (const_string "SI")
1371 ]
1372 (const_string "HI")))
1373 (set_attr "modrm" "0,*,*,0,*,*")])
1374
1375 ;; Stores and loads of ax to arbitrary constant address.
1376 ;; We fake an second form of instruction to force reload to load address
1377 ;; into register when rax is not available
1378 (define_insn "*movabshi_1_rex64"
1379 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1380 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1381 "TARGET_64BIT"
1382 "@
1383 movabs{w}\t{%1, %P0|%P0, %1}
1384 mov{w}\t{%1, %a0|%a0, %1}
1385 movabs{w}\t{%1, %a0|%a0, %1}"
1386 [(set_attr "type" "imov")
1387 (set_attr "modrm" "0,*,*")
1388 (set_attr "length_address" "8,0,0")
1389 (set_attr "length_immediate" "0,*,*")
1390 (set_attr "memory" "store")
1391 (set_attr "mode" "HI")])
1392
1393 (define_insn "*movabshi_2_rex64"
1394 [(set (match_operand:HI 0 "register_operand" "=a,r")
1395 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1396 "TARGET_64BIT"
1397 "@
1398 movabs{w}\t{%P1, %0|%0, %P1}
1399 mov{w}\t{%a1, %0|%0, %a1}"
1400 [(set_attr "type" "imov")
1401 (set_attr "modrm" "0,*")
1402 (set_attr "length_address" "8,0")
1403 (set_attr "length_immediate" "0")
1404 (set_attr "memory" "load")
1405 (set_attr "mode" "HI")])
1406
1407 (define_insn "*swaphi_1"
1408 [(set (match_operand:HI 0 "register_operand" "+r")
1409 (match_operand:HI 1 "register_operand" "+r"))
1410 (set (match_dup 1)
1411 (match_dup 0))]
1412 "TARGET_PARTIAL_REG_STALL"
1413 "xchg{w}\t%1, %0"
1414 [(set_attr "type" "imov")
1415 (set_attr "pent_pair" "np")
1416 (set_attr "mode" "HI")
1417 (set_attr "modrm" "0")
1418 (set_attr "ppro_uops" "few")])
1419
1420 (define_insn "*swaphi_2"
1421 [(set (match_operand:HI 0 "register_operand" "+r")
1422 (match_operand:HI 1 "register_operand" "+r"))
1423 (set (match_dup 1)
1424 (match_dup 0))]
1425 "! TARGET_PARTIAL_REG_STALL"
1426 "xchg{l}\t%k1, %k0"
1427 [(set_attr "type" "imov")
1428 (set_attr "pent_pair" "np")
1429 (set_attr "mode" "SI")
1430 (set_attr "modrm" "0")
1431 (set_attr "ppro_uops" "few")])
1432
1433 (define_expand "movstricthi"
1434 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1435 (match_operand:HI 1 "general_operand" ""))]
1436 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1437 {
1438 /* Don't generate memory->memory moves, go through a register */
1439 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1440 operands[1] = force_reg (HImode, operands[1]);
1441 })
1442
1443 (define_insn "*movstricthi_1"
1444 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1445 (match_operand:HI 1 "general_operand" "rn,m"))]
1446 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1447 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1448 "mov{w}\t{%1, %0|%0, %1}"
1449 [(set_attr "type" "imov")
1450 (set_attr "mode" "HI")])
1451
1452 (define_insn "*movstricthi_xor"
1453 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1454 (match_operand:HI 1 "const0_operand" "i"))
1455 (clobber (reg:CC 17))]
1456 "reload_completed
1457 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1458 "xor{w}\t{%0, %0|%0, %0}"
1459 [(set_attr "type" "alu1")
1460 (set_attr "mode" "HI")
1461 (set_attr "length_immediate" "0")])
1462
1463 (define_expand "movqi"
1464 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1465 (match_operand:QI 1 "general_operand" ""))]
1466 ""
1467 "ix86_expand_move (QImode, operands); DONE;")
1468
1469 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1470 ;; "push a byte". But actually we use pushw, which has the effect
1471 ;; of rounding the amount pushed up to a halfword.
1472
1473 (define_insn "*pushqi2"
1474 [(set (match_operand:QI 0 "push_operand" "=X,X")
1475 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1476 "!TARGET_64BIT"
1477 "@
1478 push{w}\t{|word ptr }%1
1479 push{w}\t%w1"
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "HI")])
1482
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485 [(set (match_operand:QI 0 "push_operand" "=X")
1486 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1487 "TARGET_64BIT"
1488 "push{q}\t%q1"
1489 [(set_attr "type" "push")
1490 (set_attr "mode" "QI")])
1491
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1497 ;; instruction).
1498 ;;
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there. Then we use movzx.
1502 (define_insn "*movqi_1"
1503 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1505 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1506 {
1507 switch (get_attr_type (insn))
1508 {
1509 case TYPE_IMOVX:
1510 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1511 abort ();
1512 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1513 default:
1514 if (get_attr_mode (insn) == MODE_SI)
1515 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1516 else
1517 return "mov{b}\t{%1, %0|%0, %1}";
1518 }
1519 }
1520 [(set (attr "type")
1521 (cond [(and (eq_attr "alternative" "3")
1522 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1523 (const_int 0))
1524 (eq (symbol_ref "TARGET_QIMODE_MATH")
1525 (const_int 0))))
1526 (const_string "imov")
1527 (eq_attr "alternative" "3,5")
1528 (const_string "imovx")
1529 (and (ne (symbol_ref "TARGET_MOVX")
1530 (const_int 0))
1531 (eq_attr "alternative" "2"))
1532 (const_string "imovx")
1533 ]
1534 (const_string "imov")))
1535 (set (attr "mode")
1536 (cond [(eq_attr "alternative" "3,4,5")
1537 (const_string "SI")
1538 (eq_attr "alternative" "6")
1539 (const_string "QI")
1540 (eq_attr "type" "imovx")
1541 (const_string "SI")
1542 (and (eq_attr "type" "imov")
1543 (and (eq_attr "alternative" "0,1,2")
1544 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1545 (const_int 0))))
1546 (const_string "SI")
1547 ;; Avoid partial register stalls when not using QImode arithmetic
1548 (and (eq_attr "type" "imov")
1549 (and (eq_attr "alternative" "0,1,2")
1550 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1551 (const_int 0))
1552 (eq (symbol_ref "TARGET_QIMODE_MATH")
1553 (const_int 0)))))
1554 (const_string "SI")
1555 ]
1556 (const_string "QI")))])
1557
1558 (define_expand "reload_outqi"
1559 [(parallel [(match_operand:QI 0 "" "=m")
1560 (match_operand:QI 1 "register_operand" "r")
1561 (match_operand:QI 2 "register_operand" "=&q")])]
1562 ""
1563 {
1564 rtx op0, op1, op2;
1565 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1566
1567 if (reg_overlap_mentioned_p (op2, op0))
1568 abort ();
1569 if (! q_regs_operand (op1, QImode))
1570 {
1571 emit_insn (gen_movqi (op2, op1));
1572 op1 = op2;
1573 }
1574 emit_insn (gen_movqi (op0, op1));
1575 DONE;
1576 })
1577
1578 (define_insn "*swapqi"
1579 [(set (match_operand:QI 0 "register_operand" "+r")
1580 (match_operand:QI 1 "register_operand" "+r"))
1581 (set (match_dup 1)
1582 (match_dup 0))]
1583 ""
1584 "xchg{b}\t%1, %0"
1585 [(set_attr "type" "imov")
1586 (set_attr "pent_pair" "np")
1587 (set_attr "mode" "QI")
1588 (set_attr "modrm" "0")
1589 (set_attr "ppro_uops" "few")])
1590
1591 (define_expand "movstrictqi"
1592 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1593 (match_operand:QI 1 "general_operand" ""))]
1594 "! TARGET_PARTIAL_REG_STALL"
1595 {
1596 /* Don't generate memory->memory moves, go through a register. */
1597 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1598 operands[1] = force_reg (QImode, operands[1]);
1599 })
1600
1601 (define_insn "*movstrictqi_1"
1602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1603 (match_operand:QI 1 "general_operand" "*qn,m"))]
1604 "! TARGET_PARTIAL_REG_STALL
1605 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1606 "mov{b}\t{%1, %0|%0, %1}"
1607 [(set_attr "type" "imov")
1608 (set_attr "mode" "QI")])
1609
1610 (define_insn "*movstrictqi_xor"
1611 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1612 (match_operand:QI 1 "const0_operand" "i"))
1613 (clobber (reg:CC 17))]
1614 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1615 "xor{b}\t{%0, %0|%0, %0}"
1616 [(set_attr "type" "alu1")
1617 (set_attr "mode" "QI")
1618 (set_attr "length_immediate" "0")])
1619
1620 (define_insn "*movsi_extv_1"
1621 [(set (match_operand:SI 0 "register_operand" "=R")
1622 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1623 (const_int 8)
1624 (const_int 8)))]
1625 ""
1626 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1627 [(set_attr "type" "imovx")
1628 (set_attr "mode" "SI")])
1629
1630 (define_insn "*movhi_extv_1"
1631 [(set (match_operand:HI 0 "register_operand" "=R")
1632 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1633 (const_int 8)
1634 (const_int 8)))]
1635 ""
1636 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1637 [(set_attr "type" "imovx")
1638 (set_attr "mode" "SI")])
1639
1640 (define_insn "*movqi_extv_1"
1641 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1642 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1643 (const_int 8)
1644 (const_int 8)))]
1645 "!TARGET_64BIT"
1646 {
1647 switch (get_attr_type (insn))
1648 {
1649 case TYPE_IMOVX:
1650 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1651 default:
1652 return "mov{b}\t{%h1, %0|%0, %h1}";
1653 }
1654 }
1655 [(set (attr "type")
1656 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1657 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1658 (ne (symbol_ref "TARGET_MOVX")
1659 (const_int 0))))
1660 (const_string "imovx")
1661 (const_string "imov")))
1662 (set (attr "mode")
1663 (if_then_else (eq_attr "type" "imovx")
1664 (const_string "SI")
1665 (const_string "QI")))])
1666
1667 (define_insn "*movqi_extv_1_rex64"
1668 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1669 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1670 (const_int 8)
1671 (const_int 8)))]
1672 "TARGET_64BIT"
1673 {
1674 switch (get_attr_type (insn))
1675 {
1676 case TYPE_IMOVX:
1677 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1678 default:
1679 return "mov{b}\t{%h1, %0|%0, %h1}";
1680 }
1681 }
1682 [(set (attr "type")
1683 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1684 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1685 (ne (symbol_ref "TARGET_MOVX")
1686 (const_int 0))))
1687 (const_string "imovx")
1688 (const_string "imov")))
1689 (set (attr "mode")
1690 (if_then_else (eq_attr "type" "imovx")
1691 (const_string "SI")
1692 (const_string "QI")))])
1693
1694 ;; Stores and loads of ax to arbitrary constant address.
1695 ;; We fake an second form of instruction to force reload to load address
1696 ;; into register when rax is not available
1697 (define_insn "*movabsqi_1_rex64"
1698 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1699 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1700 "TARGET_64BIT"
1701 "@
1702 movabs{b}\t{%1, %P0|%P0, %1}
1703 mov{b}\t{%1, %a0|%a0, %1}
1704 movabs{b}\t{%1, %a0|%a0, %1}"
1705 [(set_attr "type" "imov")
1706 (set_attr "modrm" "0,*,*")
1707 (set_attr "length_address" "8,0,0")
1708 (set_attr "length_immediate" "0,*,*")
1709 (set_attr "memory" "store")
1710 (set_attr "mode" "QI")])
1711
1712 (define_insn "*movabsqi_2_rex64"
1713 [(set (match_operand:QI 0 "register_operand" "=a,r")
1714 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1715 "TARGET_64BIT"
1716 "@
1717 movabs{b}\t{%P1, %0|%0, %P1}
1718 mov{b}\t{%a1, %0|%0, %a1}"
1719 [(set_attr "type" "imov")
1720 (set_attr "modrm" "0,*")
1721 (set_attr "length_address" "8,0")
1722 (set_attr "length_immediate" "0")
1723 (set_attr "memory" "load")
1724 (set_attr "mode" "QI")])
1725
1726 (define_insn "*movsi_extzv_1"
1727 [(set (match_operand:SI 0 "register_operand" "=R")
1728 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1729 (const_int 8)
1730 (const_int 8)))]
1731 ""
1732 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1733 [(set_attr "type" "imovx")
1734 (set_attr "mode" "SI")])
1735
1736 (define_insn "*movqi_extzv_2"
1737 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1738 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1739 (const_int 8)
1740 (const_int 8)) 0))]
1741 "!TARGET_64BIT"
1742 {
1743 switch (get_attr_type (insn))
1744 {
1745 case TYPE_IMOVX:
1746 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1747 default:
1748 return "mov{b}\t{%h1, %0|%0, %h1}";
1749 }
1750 }
1751 [(set (attr "type")
1752 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1753 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1754 (ne (symbol_ref "TARGET_MOVX")
1755 (const_int 0))))
1756 (const_string "imovx")
1757 (const_string "imov")))
1758 (set (attr "mode")
1759 (if_then_else (eq_attr "type" "imovx")
1760 (const_string "SI")
1761 (const_string "QI")))])
1762
1763 (define_insn "*movqi_extzv_2_rex64"
1764 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1765 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1766 (const_int 8)
1767 (const_int 8)) 0))]
1768 "TARGET_64BIT"
1769 {
1770 switch (get_attr_type (insn))
1771 {
1772 case TYPE_IMOVX:
1773 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1774 default:
1775 return "mov{b}\t{%h1, %0|%0, %h1}";
1776 }
1777 }
1778 [(set (attr "type")
1779 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1780 (ne (symbol_ref "TARGET_MOVX")
1781 (const_int 0)))
1782 (const_string "imovx")
1783 (const_string "imov")))
1784 (set (attr "mode")
1785 (if_then_else (eq_attr "type" "imovx")
1786 (const_string "SI")
1787 (const_string "QI")))])
1788
1789 (define_insn "movsi_insv_1"
1790 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1791 (const_int 8)
1792 (const_int 8))
1793 (match_operand:SI 1 "general_operand" "Qmn"))]
1794 "!TARGET_64BIT"
1795 "mov{b}\t{%b1, %h0|%h0, %b1}"
1796 [(set_attr "type" "imov")
1797 (set_attr "mode" "QI")])
1798
1799 (define_insn "*movsi_insv_1_rex64"
1800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1801 (const_int 8)
1802 (const_int 8))
1803 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1804 "TARGET_64BIT"
1805 "mov{b}\t{%b1, %h0|%h0, %b1}"
1806 [(set_attr "type" "imov")
1807 (set_attr "mode" "QI")])
1808
1809 (define_insn "*movqi_insv_2"
1810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811 (const_int 8)
1812 (const_int 8))
1813 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1814 (const_int 8))
1815 (const_int 255)))]
1816 ""
1817 "mov{b}\t{%h1, %h0|%h0, %h1}"
1818 [(set_attr "type" "imov")
1819 (set_attr "mode" "QI")])
1820
1821 (define_expand "movdi"
1822 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1823 (match_operand:DI 1 "general_operand" ""))]
1824 ""
1825 "ix86_expand_move (DImode, operands); DONE;")
1826
1827 (define_insn "*pushdi"
1828 [(set (match_operand:DI 0 "push_operand" "=<")
1829 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1830 "!TARGET_64BIT"
1831 "#")
1832
1833 (define_insn "pushdi2_rex64"
1834 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1835 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1836 "TARGET_64BIT"
1837 "@
1838 push{q}\t%1
1839 #"
1840 [(set_attr "type" "push,multi")
1841 (set_attr "mode" "DI")])
1842
1843 ;; Convert impossible pushes of immediate to existing instructions.
1844 ;; First try to get scratch register and go through it. In case this
1845 ;; fails, push sign extended lower part first and then overwrite
1846 ;; upper part by 32bit move.
1847 (define_peephole2
1848 [(match_scratch:DI 2 "r")
1849 (set (match_operand:DI 0 "push_operand" "")
1850 (match_operand:DI 1 "immediate_operand" ""))]
1851 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1852 && !x86_64_immediate_operand (operands[1], DImode)"
1853 [(set (match_dup 2) (match_dup 1))
1854 (set (match_dup 0) (match_dup 2))]
1855 "")
1856
1857 ;; We need to define this as both peepholer and splitter for case
1858 ;; peephole2 pass is not run.
1859 (define_peephole2
1860 [(set (match_operand:DI 0 "push_operand" "")
1861 (match_operand:DI 1 "immediate_operand" ""))]
1862 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1863 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1864 [(set (match_dup 0) (match_dup 1))
1865 (set (match_dup 2) (match_dup 3))]
1866 "split_di (operands + 1, 1, operands + 2, operands + 3);
1867 operands[1] = gen_lowpart (DImode, operands[2]);
1868 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1869 GEN_INT (4)));
1870 ")
1871
1872 (define_split
1873 [(set (match_operand:DI 0 "push_operand" "")
1874 (match_operand:DI 1 "immediate_operand" ""))]
1875 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1876 && !symbolic_operand (operands[1], DImode)
1877 && !x86_64_immediate_operand (operands[1], DImode)"
1878 [(set (match_dup 0) (match_dup 1))
1879 (set (match_dup 2) (match_dup 3))]
1880 "split_di (operands + 1, 1, operands + 2, operands + 3);
1881 operands[1] = gen_lowpart (DImode, operands[2]);
1882 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1883 GEN_INT (4)));
1884 ")
1885
1886 (define_insn "*pushdi2_prologue_rex64"
1887 [(set (match_operand:DI 0 "push_operand" "=<")
1888 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1889 (clobber (mem:BLK (scratch)))]
1890 "TARGET_64BIT"
1891 "push{q}\t%1"
1892 [(set_attr "type" "push")
1893 (set_attr "mode" "DI")])
1894
1895 (define_insn "*popdi1_epilogue_rex64"
1896 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1897 (mem:DI (reg:DI 7)))
1898 (set (reg:DI 7)
1899 (plus:DI (reg:DI 7) (const_int 8)))
1900 (clobber (mem:BLK (scratch)))]
1901 "TARGET_64BIT"
1902 "pop{q}\t%0"
1903 [(set_attr "type" "pop")
1904 (set_attr "mode" "DI")])
1905
1906 (define_insn "popdi1"
1907 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1908 (mem:DI (reg:DI 7)))
1909 (set (reg:DI 7)
1910 (plus:DI (reg:DI 7) (const_int 8)))]
1911 "TARGET_64BIT"
1912 "pop{q}\t%0"
1913 [(set_attr "type" "pop")
1914 (set_attr "mode" "DI")])
1915
1916 (define_insn "*movdi_xor_rex64"
1917 [(set (match_operand:DI 0 "register_operand" "=r")
1918 (match_operand:DI 1 "const0_operand" "i"))
1919 (clobber (reg:CC 17))]
1920 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1921 && reload_completed"
1922 "xor{l}\t{%k0, %k0|%k0, %k0}"
1923 [(set_attr "type" "alu1")
1924 (set_attr "mode" "SI")
1925 (set_attr "length_immediate" "0")])
1926
1927 (define_insn "*movdi_or_rex64"
1928 [(set (match_operand:DI 0 "register_operand" "=r")
1929 (match_operand:DI 1 "const_int_operand" "i"))
1930 (clobber (reg:CC 17))]
1931 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1932 && reload_completed
1933 && GET_CODE (operands[1]) == CONST_INT
1934 && INTVAL (operands[1]) == -1"
1935 {
1936 operands[1] = constm1_rtx;
1937 return "or{q}\t{%1, %0|%0, %1}";
1938 }
1939 [(set_attr "type" "alu1")
1940 (set_attr "mode" "DI")
1941 (set_attr "length_immediate" "1")])
1942
1943 (define_insn "*movdi_2"
1944 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1945 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1946 "!TARGET_64BIT
1947 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1948 "@
1949 #
1950 #
1951 movq\t{%1, %0|%0, %1}
1952 movq\t{%1, %0|%0, %1}
1953 movq\t{%1, %0|%0, %1}
1954 movdqa\t{%1, %0|%0, %1}
1955 movq\t{%1, %0|%0, %1}"
1956 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1957 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1958
1959 (define_split
1960 [(set (match_operand:DI 0 "push_operand" "")
1961 (match_operand:DI 1 "general_operand" ""))]
1962 "!TARGET_64BIT && reload_completed
1963 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1964 [(const_int 0)]
1965 "ix86_split_long_move (operands); DONE;")
1966
1967 ;; %%% This multiword shite has got to go.
1968 (define_split
1969 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1970 (match_operand:DI 1 "general_operand" ""))]
1971 "!TARGET_64BIT && reload_completed
1972 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1973 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1974 [(const_int 0)]
1975 "ix86_split_long_move (operands); DONE;")
1976
1977 (define_insn "*movdi_1_rex64"
1978 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1979 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1980 "TARGET_64BIT
1981 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1982 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1983 {
1984 switch (get_attr_type (insn))
1985 {
1986 case TYPE_SSEMOV:
1987 if (get_attr_mode (insn) == MODE_TI)
1988 return "movdqa\t{%1, %0|%0, %1}";
1989 /* FALLTHRU */
1990 case TYPE_MMXMOV:
1991 /* Moves from and into integer register is done using movd opcode with
1992 REX prefix. */
1993 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1994 return "movd\t{%1, %0|%0, %1}";
1995 return "movq\t{%1, %0|%0, %1}";
1996 case TYPE_MULTI:
1997 return "#";
1998 case TYPE_LEA:
1999 return "lea{q}\t{%a1, %0|%0, %a1}";
2000 default:
2001 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2002 abort ();
2003 if (get_attr_mode (insn) == MODE_SI)
2004 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2005 else if (which_alternative == 2)
2006 return "movabs{q}\t{%1, %0|%0, %1}";
2007 else
2008 return "mov{q}\t{%1, %0|%0, %1}";
2009 }
2010 }
2011 [(set (attr "type")
2012 (cond [(eq_attr "alternative" "5,6,7")
2013 (const_string "mmxmov")
2014 (eq_attr "alternative" "8,9,10")
2015 (const_string "ssemov")
2016 (eq_attr "alternative" "4")
2017 (const_string "multi")
2018 (and (ne (symbol_ref "flag_pic") (const_int 0))
2019 (match_operand:DI 1 "symbolic_operand" ""))
2020 (const_string "lea")
2021 ]
2022 (const_string "imov")))
2023 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2024 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2025 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2026
2027 (define_insn "*movdi_1_rex64_nointerunit"
2028 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2029 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2030 "TARGET_64BIT
2031 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2032 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2033 {
2034 switch (get_attr_type (insn))
2035 {
2036 case TYPE_SSEMOV:
2037 if (get_attr_mode (insn) == MODE_TI)
2038 return "movdqa\t{%1, %0|%0, %1}";
2039 /* FALLTHRU */
2040 case TYPE_MMXMOV:
2041 return "movq\t{%1, %0|%0, %1}";
2042 case TYPE_MULTI:
2043 return "#";
2044 case TYPE_LEA:
2045 return "lea{q}\t{%a1, %0|%0, %a1}";
2046 default:
2047 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2048 abort ();
2049 if (get_attr_mode (insn) == MODE_SI)
2050 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2051 else if (which_alternative == 2)
2052 return "movabs{q}\t{%1, %0|%0, %1}";
2053 else
2054 return "mov{q}\t{%1, %0|%0, %1}";
2055 }
2056 }
2057 [(set (attr "type")
2058 (cond [(eq_attr "alternative" "5,6,7")
2059 (const_string "mmxmov")
2060 (eq_attr "alternative" "8,9,10")
2061 (const_string "ssemov")
2062 (eq_attr "alternative" "4")
2063 (const_string "multi")
2064 (and (ne (symbol_ref "flag_pic") (const_int 0))
2065 (match_operand:DI 1 "symbolic_operand" ""))
2066 (const_string "lea")
2067 ]
2068 (const_string "imov")))
2069 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2070 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2071 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2072
2073 ;; Stores and loads of ax to arbitrary constant address.
2074 ;; We fake an second form of instruction to force reload to load address
2075 ;; into register when rax is not available
2076 (define_insn "*movabsdi_1_rex64"
2077 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2078 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2079 "TARGET_64BIT"
2080 "@
2081 movabs{q}\t{%1, %P0|%P0, %1}
2082 mov{q}\t{%1, %a0|%a0, %1}
2083 movabs{q}\t{%1, %a0|%a0, %1}"
2084 [(set_attr "type" "imov")
2085 (set_attr "modrm" "0,*,*")
2086 (set_attr "length_address" "8,0,0")
2087 (set_attr "length_immediate" "0,*,*")
2088 (set_attr "memory" "store")
2089 (set_attr "mode" "DI")])
2090
2091 (define_insn "*movabsdi_2_rex64"
2092 [(set (match_operand:DI 0 "register_operand" "=a,r")
2093 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2094 "TARGET_64BIT"
2095 "@
2096 movabs{q}\t{%P1, %0|%0, %P1}
2097 mov{q}\t{%a1, %0|%0, %a1}"
2098 [(set_attr "type" "imov")
2099 (set_attr "modrm" "0,*")
2100 (set_attr "length_address" "8,0")
2101 (set_attr "length_immediate" "0")
2102 (set_attr "memory" "load")
2103 (set_attr "mode" "DI")])
2104
2105 ;; Convert impossible stores of immediate to existing instructions.
2106 ;; First try to get scratch register and go through it. In case this
2107 ;; fails, move by 32bit parts.
2108 (define_peephole2
2109 [(match_scratch:DI 2 "r")
2110 (set (match_operand:DI 0 "memory_operand" "")
2111 (match_operand:DI 1 "immediate_operand" ""))]
2112 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2113 && !x86_64_immediate_operand (operands[1], DImode)"
2114 [(set (match_dup 2) (match_dup 1))
2115 (set (match_dup 0) (match_dup 2))]
2116 "")
2117
2118 ;; We need to define this as both peepholer and splitter for case
2119 ;; peephole2 pass is not run.
2120 (define_peephole2
2121 [(set (match_operand:DI 0 "memory_operand" "")
2122 (match_operand:DI 1 "immediate_operand" ""))]
2123 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2124 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2125 [(set (match_dup 2) (match_dup 3))
2126 (set (match_dup 4) (match_dup 5))]
2127 "split_di (operands, 2, operands + 2, operands + 4);")
2128
2129 (define_split
2130 [(set (match_operand:DI 0 "memory_operand" "")
2131 (match_operand:DI 1 "immediate_operand" ""))]
2132 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2133 && !symbolic_operand (operands[1], DImode)
2134 && !x86_64_immediate_operand (operands[1], DImode)"
2135 [(set (match_dup 2) (match_dup 3))
2136 (set (match_dup 4) (match_dup 5))]
2137 "split_di (operands, 2, operands + 2, operands + 4);")
2138
2139 (define_insn "*swapdi_rex64"
2140 [(set (match_operand:DI 0 "register_operand" "+r")
2141 (match_operand:DI 1 "register_operand" "+r"))
2142 (set (match_dup 1)
2143 (match_dup 0))]
2144 "TARGET_64BIT"
2145 "xchg{q}\t%1, %0"
2146 [(set_attr "type" "imov")
2147 (set_attr "pent_pair" "np")
2148 (set_attr "athlon_decode" "vector")
2149 (set_attr "mode" "DI")
2150 (set_attr "modrm" "0")
2151 (set_attr "ppro_uops" "few")])
2152
2153
2154 (define_expand "movsf"
2155 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2156 (match_operand:SF 1 "general_operand" ""))]
2157 ""
2158 "ix86_expand_move (SFmode, operands); DONE;")
2159
2160 (define_insn "*pushsf"
2161 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2162 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2163 "!TARGET_64BIT"
2164 {
2165 switch (which_alternative)
2166 {
2167 case 1:
2168 return "push{l}\t%1";
2169
2170 default:
2171 /* This insn should be already splitted before reg-stack. */
2172 abort ();
2173 }
2174 }
2175 [(set_attr "type" "multi,push,multi")
2176 (set_attr "mode" "SF,SI,SF")])
2177
2178 (define_insn "*pushsf_rex64"
2179 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2180 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2181 "TARGET_64BIT"
2182 {
2183 switch (which_alternative)
2184 {
2185 case 1:
2186 return "push{q}\t%q1";
2187
2188 default:
2189 /* This insn should be already splitted before reg-stack. */
2190 abort ();
2191 }
2192 }
2193 [(set_attr "type" "multi,push,multi")
2194 (set_attr "mode" "SF,DI,SF")])
2195
2196 (define_split
2197 [(set (match_operand:SF 0 "push_operand" "")
2198 (match_operand:SF 1 "memory_operand" ""))]
2199 "reload_completed
2200 && GET_CODE (operands[1]) == MEM
2201 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2202 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2203 [(set (match_dup 0)
2204 (match_dup 1))]
2205 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2206
2207
2208 ;; %%% Kill this when call knows how to work this out.
2209 (define_split
2210 [(set (match_operand:SF 0 "push_operand" "")
2211 (match_operand:SF 1 "any_fp_register_operand" ""))]
2212 "!TARGET_64BIT"
2213 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2214 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2215
2216 (define_split
2217 [(set (match_operand:SF 0 "push_operand" "")
2218 (match_operand:SF 1 "any_fp_register_operand" ""))]
2219 "TARGET_64BIT"
2220 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2221 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2222
2223 (define_insn "*movsf_1"
2224 [(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")
2225 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2226 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2227 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2228 && (reload_in_progress || reload_completed
2229 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2230 || GET_CODE (operands[1]) != CONST_DOUBLE
2231 || memory_operand (operands[0], SFmode))"
2232 {
2233 switch (which_alternative)
2234 {
2235 case 0:
2236 if (REG_P (operands[1])
2237 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2238 return "fstp\t%y0";
2239 else if (STACK_TOP_P (operands[0]))
2240 return "fld%z1\t%y1";
2241 else
2242 return "fst\t%y0";
2243
2244 case 1:
2245 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2246 return "fstp%z0\t%y0";
2247 else
2248 return "fst%z0\t%y0";
2249
2250 case 2:
2251 return standard_80387_constant_opcode (operands[1]);
2252
2253 case 3:
2254 case 4:
2255 return "mov{l}\t{%1, %0|%0, %1}";
2256 case 5:
2257 if (get_attr_mode (insn) == MODE_TI)
2258 return "pxor\t%0, %0";
2259 else
2260 return "xorps\t%0, %0";
2261 case 6:
2262 if (get_attr_mode (insn) == MODE_V4SF)
2263 return "movaps\t{%1, %0|%0, %1}";
2264 else
2265 return "movss\t{%1, %0|%0, %1}";
2266 case 7:
2267 case 8:
2268 return "movss\t{%1, %0|%0, %1}";
2269
2270 case 9:
2271 case 10:
2272 return "movd\t{%1, %0|%0, %1}";
2273
2274 case 11:
2275 return "movq\t{%1, %0|%0, %1}";
2276
2277 default:
2278 abort();
2279 }
2280 }
2281 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2282 (set (attr "mode")
2283 (cond [(eq_attr "alternative" "3,4,9,10")
2284 (const_string "SI")
2285 (eq_attr "alternative" "5")
2286 (if_then_else
2287 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2288 (const_int 0))
2289 (ne (symbol_ref "TARGET_SSE2")
2290 (const_int 0)))
2291 (eq (symbol_ref "optimize_size")
2292 (const_int 0)))
2293 (const_string "TI")
2294 (const_string "V4SF"))
2295 /* For architectures resolving dependencies on
2296 whole SSE registers use APS move to break dependency
2297 chains, otherwise use short move to avoid extra work.
2298
2299 Do the same for architectures resolving dependencies on
2300 the parts. While in DF mode it is better to always handle
2301 just register parts, the SF mode is different due to lack
2302 of instructions to load just part of the register. It is
2303 better to maintain the whole registers in single format
2304 to avoid problems on using packed logical operations. */
2305 (eq_attr "alternative" "6")
2306 (if_then_else
2307 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2308 (const_int 0))
2309 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2310 (const_int 0)))
2311 (const_string "V4SF")
2312 (const_string "SF"))
2313 (eq_attr "alternative" "11")
2314 (const_string "DI")]
2315 (const_string "SF")))])
2316
2317 (define_insn "*movsf_1_nointerunit"
2318 [(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")
2319 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2320 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2321 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2322 && (reload_in_progress || reload_completed
2323 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2324 || GET_CODE (operands[1]) != CONST_DOUBLE
2325 || memory_operand (operands[0], SFmode))"
2326 {
2327 switch (which_alternative)
2328 {
2329 case 0:
2330 if (REG_P (operands[1])
2331 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2332 {
2333 if (REGNO (operands[0]) == FIRST_STACK_REG
2334 && TARGET_USE_FFREEP)
2335 return "ffreep\t%y0";
2336 return "fstp\t%y0";
2337 }
2338 else if (STACK_TOP_P (operands[0]))
2339 return "fld%z1\t%y1";
2340 else
2341 return "fst\t%y0";
2342
2343 case 1:
2344 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2345 return "fstp%z0\t%y0";
2346 else
2347 return "fst%z0\t%y0";
2348
2349 case 2:
2350 return standard_80387_constant_opcode (operands[1]);
2351
2352 case 3:
2353 case 4:
2354 return "mov{l}\t{%1, %0|%0, %1}";
2355 case 5:
2356 if (get_attr_mode (insn) == MODE_TI)
2357 return "pxor\t%0, %0";
2358 else
2359 return "xorps\t%0, %0";
2360 case 6:
2361 if (get_attr_mode (insn) == MODE_V4SF)
2362 return "movaps\t{%1, %0|%0, %1}";
2363 else
2364 return "movss\t{%1, %0|%0, %1}";
2365 case 7:
2366 case 8:
2367 return "movss\t{%1, %0|%0, %1}";
2368
2369 case 9:
2370 case 10:
2371 return "movd\t{%1, %0|%0, %1}";
2372
2373 case 11:
2374 return "movq\t{%1, %0|%0, %1}";
2375
2376 default:
2377 abort();
2378 }
2379 }
2380 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2381 (set (attr "mode")
2382 (cond [(eq_attr "alternative" "3,4,9,10")
2383 (const_string "SI")
2384 (eq_attr "alternative" "5")
2385 (if_then_else
2386 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2387 (const_int 0))
2388 (ne (symbol_ref "TARGET_SSE2")
2389 (const_int 0)))
2390 (eq (symbol_ref "optimize_size")
2391 (const_int 0)))
2392 (const_string "TI")
2393 (const_string "V4SF"))
2394 /* For architectures resolving dependencies on
2395 whole SSE registers use APS move to break dependency
2396 chains, otherwise use short move to avoid extra work.
2397
2398 Do the same for architectures resolving dependencies on
2399 the parts. While in DF mode it is better to always handle
2400 just register parts, the SF mode is different due to lack
2401 of instructions to load just part of the register. It is
2402 better to maintain the whole registers in single format
2403 to avoid problems on using packed logical operations. */
2404 (eq_attr "alternative" "6")
2405 (if_then_else
2406 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2407 (const_int 0))
2408 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2409 (const_int 0)))
2410 (const_string "V4SF")
2411 (const_string "SF"))
2412 (eq_attr "alternative" "11")
2413 (const_string "DI")]
2414 (const_string "SF")))])
2415
2416 (define_insn "*swapsf"
2417 [(set (match_operand:SF 0 "register_operand" "+f")
2418 (match_operand:SF 1 "register_operand" "+f"))
2419 (set (match_dup 1)
2420 (match_dup 0))]
2421 "reload_completed || !TARGET_SSE"
2422 {
2423 if (STACK_TOP_P (operands[0]))
2424 return "fxch\t%1";
2425 else
2426 return "fxch\t%0";
2427 }
2428 [(set_attr "type" "fxch")
2429 (set_attr "mode" "SF")])
2430
2431 (define_expand "movdf"
2432 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2433 (match_operand:DF 1 "general_operand" ""))]
2434 ""
2435 "ix86_expand_move (DFmode, operands); DONE;")
2436
2437 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2438 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2439 ;; On the average, pushdf using integers can be still shorter. Allow this
2440 ;; pattern for optimize_size too.
2441
2442 (define_insn "*pushdf_nointeger"
2443 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2444 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2445 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2446 {
2447 /* This insn should be already splitted before reg-stack. */
2448 abort ();
2449 }
2450 [(set_attr "type" "multi")
2451 (set_attr "mode" "DF,SI,SI,DF")])
2452
2453 (define_insn "*pushdf_integer"
2454 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2455 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2456 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2457 {
2458 /* This insn should be already splitted before reg-stack. */
2459 abort ();
2460 }
2461 [(set_attr "type" "multi")
2462 (set_attr "mode" "DF,SI,DF")])
2463
2464 ;; %%% Kill this when call knows how to work this out.
2465 (define_split
2466 [(set (match_operand:DF 0 "push_operand" "")
2467 (match_operand:DF 1 "any_fp_register_operand" ""))]
2468 "!TARGET_64BIT && reload_completed"
2469 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2470 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2471 "")
2472
2473 (define_split
2474 [(set (match_operand:DF 0 "push_operand" "")
2475 (match_operand:DF 1 "any_fp_register_operand" ""))]
2476 "TARGET_64BIT && reload_completed"
2477 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2478 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2479 "")
2480
2481 (define_split
2482 [(set (match_operand:DF 0 "push_operand" "")
2483 (match_operand:DF 1 "general_operand" ""))]
2484 "reload_completed"
2485 [(const_int 0)]
2486 "ix86_split_long_move (operands); DONE;")
2487
2488 ;; Moving is usually shorter when only FP registers are used. This separate
2489 ;; movdf pattern avoids the use of integer registers for FP operations
2490 ;; when optimizing for size.
2491
2492 (define_insn "*movdf_nointeger"
2493 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2494 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2495 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2496 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2497 && (reload_in_progress || reload_completed
2498 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2499 || GET_CODE (operands[1]) != CONST_DOUBLE
2500 || memory_operand (operands[0], DFmode))"
2501 {
2502 switch (which_alternative)
2503 {
2504 case 0:
2505 if (REG_P (operands[1])
2506 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2507 {
2508 if (REGNO (operands[0]) == FIRST_STACK_REG
2509 && TARGET_USE_FFREEP)
2510 return "ffreep\t%y0";
2511 return "fstp\t%y0";
2512 }
2513 else if (STACK_TOP_P (operands[0]))
2514 return "fld%z1\t%y1";
2515 else
2516 return "fst\t%y0";
2517
2518 case 1:
2519 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2520 return "fstp%z0\t%y0";
2521 else
2522 return "fst%z0\t%y0";
2523
2524 case 2:
2525 return standard_80387_constant_opcode (operands[1]);
2526
2527 case 3:
2528 case 4:
2529 return "#";
2530 case 5:
2531 switch (get_attr_mode (insn))
2532 {
2533 case MODE_V4SF:
2534 return "xorps\t%0, %0";
2535 case MODE_V2DF:
2536 return "xorpd\t%0, %0";
2537 case MODE_TI:
2538 return "pxor\t%0, %0";
2539 default:
2540 abort ();
2541 }
2542 case 6:
2543 switch (get_attr_mode (insn))
2544 {
2545 case MODE_V4SF:
2546 return "movaps\t{%1, %0|%0, %1}";
2547 case MODE_V2DF:
2548 return "movapd\t{%1, %0|%0, %1}";
2549 case MODE_DF:
2550 return "movsd\t{%1, %0|%0, %1}";
2551 default:
2552 abort ();
2553 }
2554 case 7:
2555 if (get_attr_mode (insn) == MODE_V2DF)
2556 return "movlpd\t{%1, %0|%0, %1}";
2557 else
2558 return "movsd\t{%1, %0|%0, %1}";
2559 case 8:
2560 return "movsd\t{%1, %0|%0, %1}";
2561
2562 default:
2563 abort();
2564 }
2565 }
2566 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2567 (set (attr "mode")
2568 (cond [(eq_attr "alternative" "3,4")
2569 (const_string "SI")
2570 /* xorps is one byte shorter. */
2571 (eq_attr "alternative" "5")
2572 (cond [(ne (symbol_ref "optimize_size")
2573 (const_int 0))
2574 (const_string "V4SF")
2575 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2576 (const_int 0))
2577 (const_string "TI")]
2578 (const_string "V2DF"))
2579 /* For architectures resolving dependencies on
2580 whole SSE registers use APD move to break dependency
2581 chains, otherwise use short move to avoid extra work.
2582
2583 movaps encodes one byte shorter. */
2584 (eq_attr "alternative" "6")
2585 (cond
2586 [(ne (symbol_ref "optimize_size")
2587 (const_int 0))
2588 (const_string "V4SF")
2589 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2590 (const_int 0))
2591 (const_string "V2DF")]
2592 (const_string "DF"))
2593 /* For architectures resolving dependencies on register
2594 parts we may avoid extra work to zero out upper part
2595 of register. */
2596 (eq_attr "alternative" "7")
2597 (if_then_else
2598 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2599 (const_int 0))
2600 (const_string "V2DF")
2601 (const_string "DF"))]
2602 (const_string "DF")))])
2603
2604 (define_insn "*movdf_integer"
2605 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2606 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2607 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2608 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2609 && (reload_in_progress || reload_completed
2610 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2611 || GET_CODE (operands[1]) != CONST_DOUBLE
2612 || memory_operand (operands[0], DFmode))"
2613 {
2614 switch (which_alternative)
2615 {
2616 case 0:
2617 if (REG_P (operands[1])
2618 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2619 {
2620 if (REGNO (operands[0]) == FIRST_STACK_REG
2621 && TARGET_USE_FFREEP)
2622 return "ffreep\t%y0";
2623 return "fstp\t%y0";
2624 }
2625 else if (STACK_TOP_P (operands[0]))
2626 return "fld%z1\t%y1";
2627 else
2628 return "fst\t%y0";
2629
2630 case 1:
2631 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2632 return "fstp%z0\t%y0";
2633 else
2634 return "fst%z0\t%y0";
2635
2636 case 2:
2637 return standard_80387_constant_opcode (operands[1]);
2638
2639 case 3:
2640 case 4:
2641 return "#";
2642
2643 case 5:
2644 switch (get_attr_mode (insn))
2645 {
2646 case MODE_V4SF:
2647 return "xorps\t%0, %0";
2648 case MODE_V2DF:
2649 return "xorpd\t%0, %0";
2650 case MODE_TI:
2651 return "pxor\t%0, %0";
2652 default:
2653 abort ();
2654 }
2655 case 6:
2656 switch (get_attr_mode (insn))
2657 {
2658 case MODE_V4SF:
2659 return "movaps\t{%1, %0|%0, %1}";
2660 case MODE_V2DF:
2661 return "movapd\t{%1, %0|%0, %1}";
2662 case MODE_DF:
2663 return "movsd\t{%1, %0|%0, %1}";
2664 default:
2665 abort ();
2666 }
2667 case 7:
2668 if (get_attr_mode (insn) == MODE_V2DF)
2669 return "movlpd\t{%1, %0|%0, %1}";
2670 else
2671 return "movsd\t{%1, %0|%0, %1}";
2672 case 8:
2673 return "movsd\t{%1, %0|%0, %1}";
2674
2675 default:
2676 abort();
2677 }
2678 }
2679 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2680 (set (attr "mode")
2681 (cond [(eq_attr "alternative" "3,4")
2682 (const_string "SI")
2683 /* xorps is one byte shorter. */
2684 (eq_attr "alternative" "5")
2685 (cond [(ne (symbol_ref "optimize_size")
2686 (const_int 0))
2687 (const_string "V4SF")
2688 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2689 (const_int 0))
2690 (const_string "TI")]
2691 (const_string "V2DF"))
2692 /* For architectures resolving dependencies on
2693 whole SSE registers use APD move to break dependency
2694 chains, otherwise use short move to avoid extra work.
2695
2696 movaps encodes one byte shorter. */
2697 (eq_attr "alternative" "6")
2698 (cond
2699 [(ne (symbol_ref "optimize_size")
2700 (const_int 0))
2701 (const_string "V4SF")
2702 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2703 (const_int 0))
2704 (const_string "V2DF")]
2705 (const_string "DF"))
2706 /* For architectures resolving dependencies on register
2707 parts we may avoid extra work to zero out upper part
2708 of register. */
2709 (eq_attr "alternative" "7")
2710 (if_then_else
2711 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2712 (const_int 0))
2713 (const_string "V2DF")
2714 (const_string "DF"))]
2715 (const_string "DF")))])
2716
2717 (define_split
2718 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2719 (match_operand:DF 1 "general_operand" ""))]
2720 "reload_completed
2721 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2722 && ! (ANY_FP_REG_P (operands[0]) ||
2723 (GET_CODE (operands[0]) == SUBREG
2724 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2725 && ! (ANY_FP_REG_P (operands[1]) ||
2726 (GET_CODE (operands[1]) == SUBREG
2727 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2728 [(const_int 0)]
2729 "ix86_split_long_move (operands); DONE;")
2730
2731 (define_insn "*swapdf"
2732 [(set (match_operand:DF 0 "register_operand" "+f")
2733 (match_operand:DF 1 "register_operand" "+f"))
2734 (set (match_dup 1)
2735 (match_dup 0))]
2736 "reload_completed || !TARGET_SSE2"
2737 {
2738 if (STACK_TOP_P (operands[0]))
2739 return "fxch\t%1";
2740 else
2741 return "fxch\t%0";
2742 }
2743 [(set_attr "type" "fxch")
2744 (set_attr "mode" "DF")])
2745
2746 (define_expand "movxf"
2747 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2748 (match_operand:XF 1 "general_operand" ""))]
2749 "!TARGET_64BIT"
2750 "ix86_expand_move (XFmode, operands); DONE;")
2751
2752 (define_expand "movtf"
2753 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2754 (match_operand:TF 1 "general_operand" ""))]
2755 ""
2756 "ix86_expand_move (TFmode, operands); DONE;")
2757
2758 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2759 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2760 ;; Pushing using integer instructions is longer except for constants
2761 ;; and direct memory references.
2762 ;; (assuming that any given constant is pushed only once, but this ought to be
2763 ;; handled elsewhere).
2764
2765 (define_insn "*pushxf_nointeger"
2766 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2767 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2768 "!TARGET_64BIT && optimize_size"
2769 {
2770 /* This insn should be already splitted before reg-stack. */
2771 abort ();
2772 }
2773 [(set_attr "type" "multi")
2774 (set_attr "mode" "XF,SI,SI")])
2775
2776 (define_insn "*pushtf_nointeger"
2777 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2778 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2779 "optimize_size"
2780 {
2781 /* This insn should be already splitted before reg-stack. */
2782 abort ();
2783 }
2784 [(set_attr "type" "multi")
2785 (set_attr "mode" "XF,SI,SI")])
2786
2787 (define_insn "*pushxf_integer"
2788 [(set (match_operand:XF 0 "push_operand" "=<,<")
2789 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2790 "!TARGET_64BIT && !optimize_size"
2791 {
2792 /* This insn should be already splitted before reg-stack. */
2793 abort ();
2794 }
2795 [(set_attr "type" "multi")
2796 (set_attr "mode" "XF,SI")])
2797
2798 (define_insn "*pushtf_integer"
2799 [(set (match_operand:TF 0 "push_operand" "=<,<")
2800 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2801 "!optimize_size"
2802 {
2803 /* This insn should be already splitted before reg-stack. */
2804 abort ();
2805 }
2806 [(set_attr "type" "multi")
2807 (set_attr "mode" "XF,SI")])
2808
2809 (define_split
2810 [(set (match_operand 0 "push_operand" "")
2811 (match_operand 1 "general_operand" ""))]
2812 "reload_completed
2813 && (GET_MODE (operands[0]) == XFmode
2814 || GET_MODE (operands[0]) == TFmode
2815 || GET_MODE (operands[0]) == DFmode)
2816 && !ANY_FP_REG_P (operands[1])"
2817 [(const_int 0)]
2818 "ix86_split_long_move (operands); DONE;")
2819
2820 (define_split
2821 [(set (match_operand:XF 0 "push_operand" "")
2822 (match_operand:XF 1 "any_fp_register_operand" ""))]
2823 "!TARGET_64BIT"
2824 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2825 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2826
2827 (define_split
2828 [(set (match_operand:TF 0 "push_operand" "")
2829 (match_operand:TF 1 "any_fp_register_operand" ""))]
2830 "!TARGET_64BIT"
2831 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2832 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2833
2834 (define_split
2835 [(set (match_operand:TF 0 "push_operand" "")
2836 (match_operand:TF 1 "any_fp_register_operand" ""))]
2837 "TARGET_64BIT"
2838 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2839 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2840
2841 ;; Do not use integer registers when optimizing for size
2842 (define_insn "*movxf_nointeger"
2843 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2844 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2845 "!TARGET_64BIT
2846 && optimize_size
2847 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2848 && (reload_in_progress || reload_completed
2849 || GET_CODE (operands[1]) != CONST_DOUBLE
2850 || memory_operand (operands[0], XFmode))"
2851 {
2852 switch (which_alternative)
2853 {
2854 case 0:
2855 if (REG_P (operands[1])
2856 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2857 {
2858 if (REGNO (operands[0]) == FIRST_STACK_REG
2859 && TARGET_USE_FFREEP)
2860 return "ffreep\t%y0";
2861 return "fstp\t%y0";
2862 }
2863 else if (STACK_TOP_P (operands[0]))
2864 return "fld%z1\t%y1";
2865 else
2866 return "fst\t%y0";
2867
2868 case 1:
2869 /* There is no non-popping store to memory for XFmode. So if
2870 we need one, follow the store with a load. */
2871 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2872 return "fstp%z0\t%y0\;fld%z0\t%y0";
2873 else
2874 return "fstp%z0\t%y0";
2875
2876 case 2:
2877 return standard_80387_constant_opcode (operands[1]);
2878
2879 case 3: case 4:
2880 return "#";
2881 }
2882 abort();
2883 }
2884 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2885 (set_attr "mode" "XF,XF,XF,SI,SI")])
2886
2887 (define_insn "*movtf_nointeger"
2888 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2889 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2890 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2891 && optimize_size
2892 && (reload_in_progress || reload_completed
2893 || GET_CODE (operands[1]) != CONST_DOUBLE
2894 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2895 || memory_operand (operands[0], TFmode))"
2896 {
2897 switch (which_alternative)
2898 {
2899 case 0:
2900 if (REG_P (operands[1])
2901 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2902 {
2903 if (REGNO (operands[0]) == FIRST_STACK_REG
2904 && TARGET_USE_FFREEP)
2905 return "ffreep\t%y0";
2906 return "fstp\t%y0";
2907 }
2908 else if (STACK_TOP_P (operands[0]))
2909 return "fld%z1\t%y1";
2910 else
2911 return "fst\t%y0";
2912
2913 case 1:
2914 /* There is no non-popping store to memory for XFmode. So if
2915 we need one, follow the store with a load. */
2916 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2917 return "fstp%z0\t%y0\;fld%z0\t%y0";
2918 else
2919 return "fstp%z0\t%y0";
2920
2921 case 2:
2922 return standard_80387_constant_opcode (operands[1]);
2923
2924 case 3: case 4:
2925 return "#";
2926 }
2927 abort();
2928 }
2929 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2930 (set_attr "mode" "XF,XF,XF,SI,SI")])
2931
2932 (define_insn "*movxf_integer"
2933 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2934 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2935 "!TARGET_64BIT
2936 && !optimize_size
2937 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2938 && (reload_in_progress || reload_completed
2939 || GET_CODE (operands[1]) != CONST_DOUBLE
2940 || memory_operand (operands[0], XFmode))"
2941 {
2942 switch (which_alternative)
2943 {
2944 case 0:
2945 if (REG_P (operands[1])
2946 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2947 {
2948 if (REGNO (operands[0]) == FIRST_STACK_REG
2949 && TARGET_USE_FFREEP)
2950 return "ffreep\t%y0";
2951 return "fstp\t%y0";
2952 }
2953 else if (STACK_TOP_P (operands[0]))
2954 return "fld%z1\t%y1";
2955 else
2956 return "fst\t%y0";
2957
2958 case 1:
2959 /* There is no non-popping store to memory for XFmode. So if
2960 we need one, follow the store with a load. */
2961 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2962 return "fstp%z0\t%y0\;fld%z0\t%y0";
2963 else
2964 return "fstp%z0\t%y0";
2965
2966 case 2:
2967 return standard_80387_constant_opcode (operands[1]);
2968
2969 case 3: case 4:
2970 return "#";
2971 }
2972 abort();
2973 }
2974 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2975 (set_attr "mode" "XF,XF,XF,SI,SI")])
2976
2977 (define_insn "*movtf_integer"
2978 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2979 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2980 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2981 && !optimize_size
2982 && (reload_in_progress || reload_completed
2983 || GET_CODE (operands[1]) != CONST_DOUBLE
2984 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2985 || memory_operand (operands[0], TFmode))"
2986 {
2987 switch (which_alternative)
2988 {
2989 case 0:
2990 if (REG_P (operands[1])
2991 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2992 {
2993 if (REGNO (operands[0]) == FIRST_STACK_REG
2994 && TARGET_USE_FFREEP)
2995 return "ffreep\t%y0";
2996 return "fstp\t%y0";
2997 }
2998 else if (STACK_TOP_P (operands[0]))
2999 return "fld%z1\t%y1";
3000 else
3001 return "fst\t%y0";
3002
3003 case 1:
3004 /* There is no non-popping store to memory for XFmode. So if
3005 we need one, follow the store with a load. */
3006 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3007 return "fstp%z0\t%y0\;fld%z0\t%y0";
3008 else
3009 return "fstp%z0\t%y0";
3010
3011 case 2:
3012 return standard_80387_constant_opcode (operands[1]);
3013
3014 case 3: case 4:
3015 return "#";
3016 }
3017 abort();
3018 }
3019 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3020 (set_attr "mode" "XF,XF,XF,SI,SI")])
3021
3022 (define_split
3023 [(set (match_operand 0 "nonimmediate_operand" "")
3024 (match_operand 1 "general_operand" ""))]
3025 "reload_completed
3026 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3027 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3028 && ! (ANY_FP_REG_P (operands[0]) ||
3029 (GET_CODE (operands[0]) == SUBREG
3030 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3031 && ! (ANY_FP_REG_P (operands[1]) ||
3032 (GET_CODE (operands[1]) == SUBREG
3033 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3034 [(const_int 0)]
3035 "ix86_split_long_move (operands); DONE;")
3036
3037 (define_split
3038 [(set (match_operand 0 "register_operand" "")
3039 (match_operand 1 "memory_operand" ""))]
3040 "reload_completed
3041 && GET_CODE (operands[1]) == MEM
3042 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3043 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3044 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3045 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3046 && (!(SSE_REG_P (operands[0]) ||
3047 (GET_CODE (operands[0]) == SUBREG
3048 && SSE_REG_P (SUBREG_REG (operands[0]))))
3049 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3050 && (!(FP_REG_P (operands[0]) ||
3051 (GET_CODE (operands[0]) == SUBREG
3052 && FP_REG_P (SUBREG_REG (operands[0]))))
3053 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3054 [(set (match_dup 0)
3055 (match_dup 1))]
3056 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3057
3058 (define_insn "swapxf"
3059 [(set (match_operand:XF 0 "register_operand" "+f")
3060 (match_operand:XF 1 "register_operand" "+f"))
3061 (set (match_dup 1)
3062 (match_dup 0))]
3063 ""
3064 {
3065 if (STACK_TOP_P (operands[0]))
3066 return "fxch\t%1";
3067 else
3068 return "fxch\t%0";
3069 }
3070 [(set_attr "type" "fxch")
3071 (set_attr "mode" "XF")])
3072
3073 (define_insn "swaptf"
3074 [(set (match_operand:TF 0 "register_operand" "+f")
3075 (match_operand:TF 1 "register_operand" "+f"))
3076 (set (match_dup 1)
3077 (match_dup 0))]
3078 ""
3079 {
3080 if (STACK_TOP_P (operands[0]))
3081 return "fxch\t%1";
3082 else
3083 return "fxch\t%0";
3084 }
3085 [(set_attr "type" "fxch")
3086 (set_attr "mode" "XF")])
3087 \f
3088 ;; Zero extension instructions
3089
3090 (define_expand "zero_extendhisi2"
3091 [(set (match_operand:SI 0 "register_operand" "")
3092 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3093 ""
3094 {
3095 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3096 {
3097 operands[1] = force_reg (HImode, operands[1]);
3098 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3099 DONE;
3100 }
3101 })
3102
3103 (define_insn "zero_extendhisi2_and"
3104 [(set (match_operand:SI 0 "register_operand" "=r")
3105 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3106 (clobber (reg:CC 17))]
3107 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3108 "#"
3109 [(set_attr "type" "alu1")
3110 (set_attr "mode" "SI")])
3111
3112 (define_split
3113 [(set (match_operand:SI 0 "register_operand" "")
3114 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3115 (clobber (reg:CC 17))]
3116 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3117 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3118 (clobber (reg:CC 17))])]
3119 "")
3120
3121 (define_insn "*zero_extendhisi2_movzwl"
3122 [(set (match_operand:SI 0 "register_operand" "=r")
3123 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3124 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3125 "movz{wl|x}\t{%1, %0|%0, %1}"
3126 [(set_attr "type" "imovx")
3127 (set_attr "mode" "SI")])
3128
3129 (define_expand "zero_extendqihi2"
3130 [(parallel
3131 [(set (match_operand:HI 0 "register_operand" "")
3132 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3133 (clobber (reg:CC 17))])]
3134 ""
3135 "")
3136
3137 (define_insn "*zero_extendqihi2_and"
3138 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3139 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3140 (clobber (reg:CC 17))]
3141 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3142 "#"
3143 [(set_attr "type" "alu1")
3144 (set_attr "mode" "HI")])
3145
3146 (define_insn "*zero_extendqihi2_movzbw_and"
3147 [(set (match_operand:HI 0 "register_operand" "=r,r")
3148 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3149 (clobber (reg:CC 17))]
3150 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3151 "#"
3152 [(set_attr "type" "imovx,alu1")
3153 (set_attr "mode" "HI")])
3154
3155 (define_insn "*zero_extendqihi2_movzbw"
3156 [(set (match_operand:HI 0 "register_operand" "=r")
3157 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3158 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3159 "movz{bw|x}\t{%1, %0|%0, %1}"
3160 [(set_attr "type" "imovx")
3161 (set_attr "mode" "HI")])
3162
3163 ;; For the movzbw case strip only the clobber
3164 (define_split
3165 [(set (match_operand:HI 0 "register_operand" "")
3166 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3167 (clobber (reg:CC 17))]
3168 "reload_completed
3169 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3170 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3171 [(set (match_operand:HI 0 "register_operand" "")
3172 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3173
3174 ;; When source and destination does not overlap, clear destination
3175 ;; first and then do the movb
3176 (define_split
3177 [(set (match_operand:HI 0 "register_operand" "")
3178 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3179 (clobber (reg:CC 17))]
3180 "reload_completed
3181 && ANY_QI_REG_P (operands[0])
3182 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3183 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3184 [(set (match_dup 0) (const_int 0))
3185 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3186 "operands[2] = gen_lowpart (QImode, operands[0]);")
3187
3188 ;; Rest is handled by single and.
3189 (define_split
3190 [(set (match_operand:HI 0 "register_operand" "")
3191 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3192 (clobber (reg:CC 17))]
3193 "reload_completed
3194 && true_regnum (operands[0]) == true_regnum (operands[1])"
3195 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3196 (clobber (reg:CC 17))])]
3197 "")
3198
3199 (define_expand "zero_extendqisi2"
3200 [(parallel
3201 [(set (match_operand:SI 0 "register_operand" "")
3202 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3203 (clobber (reg:CC 17))])]
3204 ""
3205 "")
3206
3207 (define_insn "*zero_extendqisi2_and"
3208 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3209 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3210 (clobber (reg:CC 17))]
3211 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3212 "#"
3213 [(set_attr "type" "alu1")
3214 (set_attr "mode" "SI")])
3215
3216 (define_insn "*zero_extendqisi2_movzbw_and"
3217 [(set (match_operand:SI 0 "register_operand" "=r,r")
3218 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3219 (clobber (reg:CC 17))]
3220 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3221 "#"
3222 [(set_attr "type" "imovx,alu1")
3223 (set_attr "mode" "SI")])
3224
3225 (define_insn "*zero_extendqisi2_movzbw"
3226 [(set (match_operand:SI 0 "register_operand" "=r")
3227 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3228 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3229 "movz{bl|x}\t{%1, %0|%0, %1}"
3230 [(set_attr "type" "imovx")
3231 (set_attr "mode" "SI")])
3232
3233 ;; For the movzbl case strip only the clobber
3234 (define_split
3235 [(set (match_operand:SI 0 "register_operand" "")
3236 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3237 (clobber (reg:CC 17))]
3238 "reload_completed
3239 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3240 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3241 [(set (match_dup 0)
3242 (zero_extend:SI (match_dup 1)))])
3243
3244 ;; When source and destination does not overlap, clear destination
3245 ;; first and then do the movb
3246 (define_split
3247 [(set (match_operand:SI 0 "register_operand" "")
3248 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3249 (clobber (reg:CC 17))]
3250 "reload_completed
3251 && ANY_QI_REG_P (operands[0])
3252 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3253 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3254 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3255 [(set (match_dup 0) (const_int 0))
3256 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3257 "operands[2] = gen_lowpart (QImode, operands[0]);")
3258
3259 ;; Rest is handled by single and.
3260 (define_split
3261 [(set (match_operand:SI 0 "register_operand" "")
3262 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3263 (clobber (reg:CC 17))]
3264 "reload_completed
3265 && true_regnum (operands[0]) == true_regnum (operands[1])"
3266 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3267 (clobber (reg:CC 17))])]
3268 "")
3269
3270 ;; %%% Kill me once multi-word ops are sane.
3271 (define_expand "zero_extendsidi2"
3272 [(set (match_operand:DI 0 "register_operand" "=r")
3273 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3274 ""
3275 "if (!TARGET_64BIT)
3276 {
3277 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3278 DONE;
3279 }
3280 ")
3281
3282 (define_insn "zero_extendsidi2_32"
3283 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3284 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3285 (clobber (reg:CC 17))]
3286 "!TARGET_64BIT"
3287 "#"
3288 [(set_attr "mode" "SI")])
3289
3290 (define_insn "zero_extendsidi2_rex64"
3291 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3292 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3293 "TARGET_64BIT"
3294 "@
3295 mov\t{%k1, %k0|%k0, %k1}
3296 #"
3297 [(set_attr "type" "imovx,imov")
3298 (set_attr "mode" "SI,DI")])
3299
3300 (define_split
3301 [(set (match_operand:DI 0 "memory_operand" "")
3302 (zero_extend:DI (match_dup 0)))]
3303 "TARGET_64BIT"
3304 [(set (match_dup 4) (const_int 0))]
3305 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3306
3307 (define_split
3308 [(set (match_operand:DI 0 "register_operand" "")
3309 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3310 (clobber (reg:CC 17))]
3311 "!TARGET_64BIT && reload_completed
3312 && true_regnum (operands[0]) == true_regnum (operands[1])"
3313 [(set (match_dup 4) (const_int 0))]
3314 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3315
3316 (define_split
3317 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3318 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3319 (clobber (reg:CC 17))]
3320 "!TARGET_64BIT && reload_completed"
3321 [(set (match_dup 3) (match_dup 1))
3322 (set (match_dup 4) (const_int 0))]
3323 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3324
3325 (define_insn "zero_extendhidi2"
3326 [(set (match_operand:DI 0 "register_operand" "=r,r")
3327 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3328 "TARGET_64BIT"
3329 "@
3330 movz{wl|x}\t{%1, %k0|%k0, %1}
3331 movz{wq|x}\t{%1, %0|%0, %1}"
3332 [(set_attr "type" "imovx")
3333 (set_attr "mode" "SI,DI")])
3334
3335 (define_insn "zero_extendqidi2"
3336 [(set (match_operand:DI 0 "register_operand" "=r,r")
3337 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3338 "TARGET_64BIT"
3339 "@
3340 movz{bl|x}\t{%1, %k0|%k0, %1}
3341 movz{bq|x}\t{%1, %0|%0, %1}"
3342 [(set_attr "type" "imovx")
3343 (set_attr "mode" "SI,DI")])
3344 \f
3345 ;; Sign extension instructions
3346
3347 (define_expand "extendsidi2"
3348 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3349 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3350 (clobber (reg:CC 17))
3351 (clobber (match_scratch:SI 2 ""))])]
3352 ""
3353 {
3354 if (TARGET_64BIT)
3355 {
3356 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3357 DONE;
3358 }
3359 })
3360
3361 (define_insn "*extendsidi2_1"
3362 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3363 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3364 (clobber (reg:CC 17))
3365 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3366 "!TARGET_64BIT"
3367 "#")
3368
3369 (define_insn "extendsidi2_rex64"
3370 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3371 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3372 "TARGET_64BIT"
3373 "@
3374 {cltq|cdqe}
3375 movs{lq|x}\t{%1,%0|%0, %1}"
3376 [(set_attr "type" "imovx")
3377 (set_attr "mode" "DI")
3378 (set_attr "prefix_0f" "0")
3379 (set_attr "modrm" "0,1")])
3380
3381 (define_insn "extendhidi2"
3382 [(set (match_operand:DI 0 "register_operand" "=r")
3383 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3384 "TARGET_64BIT"
3385 "movs{wq|x}\t{%1,%0|%0, %1}"
3386 [(set_attr "type" "imovx")
3387 (set_attr "mode" "DI")])
3388
3389 (define_insn "extendqidi2"
3390 [(set (match_operand:DI 0 "register_operand" "=r")
3391 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3392 "TARGET_64BIT"
3393 "movs{bq|x}\t{%1,%0|%0, %1}"
3394 [(set_attr "type" "imovx")
3395 (set_attr "mode" "DI")])
3396
3397 ;; Extend to memory case when source register does die.
3398 (define_split
3399 [(set (match_operand:DI 0 "memory_operand" "")
3400 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3401 (clobber (reg:CC 17))
3402 (clobber (match_operand:SI 2 "register_operand" ""))]
3403 "(reload_completed
3404 && dead_or_set_p (insn, operands[1])
3405 && !reg_mentioned_p (operands[1], operands[0]))"
3406 [(set (match_dup 3) (match_dup 1))
3407 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3408 (clobber (reg:CC 17))])
3409 (set (match_dup 4) (match_dup 1))]
3410 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3411
3412 ;; Extend to memory case when source register does not die.
3413 (define_split
3414 [(set (match_operand:DI 0 "memory_operand" "")
3415 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3416 (clobber (reg:CC 17))
3417 (clobber (match_operand:SI 2 "register_operand" ""))]
3418 "reload_completed"
3419 [(const_int 0)]
3420 {
3421 split_di (&operands[0], 1, &operands[3], &operands[4]);
3422
3423 emit_move_insn (operands[3], operands[1]);
3424
3425 /* Generate a cltd if possible and doing so it profitable. */
3426 if (true_regnum (operands[1]) == 0
3427 && true_regnum (operands[2]) == 1
3428 && (optimize_size || TARGET_USE_CLTD))
3429 {
3430 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3431 }
3432 else
3433 {
3434 emit_move_insn (operands[2], operands[1]);
3435 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3436 }
3437 emit_move_insn (operands[4], operands[2]);
3438 DONE;
3439 })
3440
3441 ;; Extend to register case. Optimize case where source and destination
3442 ;; registers match and cases where we can use cltd.
3443 (define_split
3444 [(set (match_operand:DI 0 "register_operand" "")
3445 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3446 (clobber (reg:CC 17))
3447 (clobber (match_scratch:SI 2 ""))]
3448 "reload_completed"
3449 [(const_int 0)]
3450 {
3451 split_di (&operands[0], 1, &operands[3], &operands[4]);
3452
3453 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3454 emit_move_insn (operands[3], operands[1]);
3455
3456 /* Generate a cltd if possible and doing so it profitable. */
3457 if (true_regnum (operands[3]) == 0
3458 && (optimize_size || TARGET_USE_CLTD))
3459 {
3460 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3461 DONE;
3462 }
3463
3464 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3465 emit_move_insn (operands[4], operands[1]);
3466
3467 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3468 DONE;
3469 })
3470
3471 (define_insn "extendhisi2"
3472 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3473 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3474 ""
3475 {
3476 switch (get_attr_prefix_0f (insn))
3477 {
3478 case 0:
3479 return "{cwtl|cwde}";
3480 default:
3481 return "movs{wl|x}\t{%1,%0|%0, %1}";
3482 }
3483 }
3484 [(set_attr "type" "imovx")
3485 (set_attr "mode" "SI")
3486 (set (attr "prefix_0f")
3487 ;; movsx is short decodable while cwtl is vector decoded.
3488 (if_then_else (and (eq_attr "cpu" "!k6")
3489 (eq_attr "alternative" "0"))
3490 (const_string "0")
3491 (const_string "1")))
3492 (set (attr "modrm")
3493 (if_then_else (eq_attr "prefix_0f" "0")
3494 (const_string "0")
3495 (const_string "1")))])
3496
3497 (define_insn "*extendhisi2_zext"
3498 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3499 (zero_extend:DI
3500 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3501 "TARGET_64BIT"
3502 {
3503 switch (get_attr_prefix_0f (insn))
3504 {
3505 case 0:
3506 return "{cwtl|cwde}";
3507 default:
3508 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3509 }
3510 }
3511 [(set_attr "type" "imovx")
3512 (set_attr "mode" "SI")
3513 (set (attr "prefix_0f")
3514 ;; movsx is short decodable while cwtl is vector decoded.
3515 (if_then_else (and (eq_attr "cpu" "!k6")
3516 (eq_attr "alternative" "0"))
3517 (const_string "0")
3518 (const_string "1")))
3519 (set (attr "modrm")
3520 (if_then_else (eq_attr "prefix_0f" "0")
3521 (const_string "0")
3522 (const_string "1")))])
3523
3524 (define_insn "extendqihi2"
3525 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3526 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3527 ""
3528 {
3529 switch (get_attr_prefix_0f (insn))
3530 {
3531 case 0:
3532 return "{cbtw|cbw}";
3533 default:
3534 return "movs{bw|x}\t{%1,%0|%0, %1}";
3535 }
3536 }
3537 [(set_attr "type" "imovx")
3538 (set_attr "mode" "HI")
3539 (set (attr "prefix_0f")
3540 ;; movsx is short decodable while cwtl is vector decoded.
3541 (if_then_else (and (eq_attr "cpu" "!k6")
3542 (eq_attr "alternative" "0"))
3543 (const_string "0")
3544 (const_string "1")))
3545 (set (attr "modrm")
3546 (if_then_else (eq_attr "prefix_0f" "0")
3547 (const_string "0")
3548 (const_string "1")))])
3549
3550 (define_insn "extendqisi2"
3551 [(set (match_operand:SI 0 "register_operand" "=r")
3552 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3553 ""
3554 "movs{bl|x}\t{%1,%0|%0, %1}"
3555 [(set_attr "type" "imovx")
3556 (set_attr "mode" "SI")])
3557
3558 (define_insn "*extendqisi2_zext"
3559 [(set (match_operand:DI 0 "register_operand" "=r")
3560 (zero_extend:DI
3561 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3562 "TARGET_64BIT"
3563 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3564 [(set_attr "type" "imovx")
3565 (set_attr "mode" "SI")])
3566 \f
3567 ;; Conversions between float and double.
3568
3569 ;; These are all no-ops in the model used for the 80387. So just
3570 ;; emit moves.
3571
3572 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3573 (define_insn "*dummy_extendsfdf2"
3574 [(set (match_operand:DF 0 "push_operand" "=<")
3575 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3576 "0"
3577 "#")
3578
3579 (define_split
3580 [(set (match_operand:DF 0 "push_operand" "")
3581 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3582 "!TARGET_64BIT"
3583 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3584 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3585
3586 (define_split
3587 [(set (match_operand:DF 0 "push_operand" "")
3588 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3589 "TARGET_64BIT"
3590 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3591 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3592
3593 (define_insn "*dummy_extendsfxf2"
3594 [(set (match_operand:XF 0 "push_operand" "=<")
3595 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3596 "0"
3597 "#")
3598
3599 (define_split
3600 [(set (match_operand:XF 0 "push_operand" "")
3601 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3602 "!TARGET_64BIT"
3603 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3604 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3605
3606 (define_insn "*dummy_extendsftf2"
3607 [(set (match_operand:TF 0 "push_operand" "=<")
3608 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3609 "0"
3610 "#")
3611
3612 (define_split
3613 [(set (match_operand:TF 0 "push_operand" "")
3614 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3615 "!TARGET_64BIT"
3616 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3617 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3618
3619 (define_split
3620 [(set (match_operand:TF 0 "push_operand" "")
3621 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3622 "TARGET_64BIT"
3623 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3624 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3625
3626 (define_insn "*dummy_extenddfxf2"
3627 [(set (match_operand:XF 0 "push_operand" "=<")
3628 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3629 "0"
3630 "#")
3631
3632 (define_split
3633 [(set (match_operand:XF 0 "push_operand" "")
3634 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3635 "!TARGET_64BIT"
3636 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3637 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3638
3639 (define_insn "*dummy_extenddftf2"
3640 [(set (match_operand:TF 0 "push_operand" "=<")
3641 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3642 "0"
3643 "#")
3644
3645 (define_split
3646 [(set (match_operand:TF 0 "push_operand" "")
3647 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3648 "!TARGET_64BIT"
3649 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3650 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3651
3652 (define_split
3653 [(set (match_operand:TF 0 "push_operand" "")
3654 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3655 "TARGET_64BIT"
3656 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3657 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3658
3659 (define_expand "extendsfdf2"
3660 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3661 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3662 "TARGET_80387 || TARGET_SSE2"
3663 {
3664 /* ??? Needed for compress_float_constant since all fp constants
3665 are LEGITIMATE_CONSTANT_P. */
3666 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3667 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3668 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3669 operands[1] = force_reg (SFmode, operands[1]);
3670 })
3671
3672 (define_insn "*extendsfdf2_1"
3673 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3674 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3675 "(TARGET_80387 || TARGET_SSE2)
3676 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3677 {
3678 switch (which_alternative)
3679 {
3680 case 0:
3681 if (REG_P (operands[1])
3682 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3683 return "fstp\t%y0";
3684 else if (STACK_TOP_P (operands[0]))
3685 return "fld%z1\t%y1";
3686 else
3687 return "fst\t%y0";
3688
3689 case 1:
3690 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691 return "fstp%z0\t%y0";
3692
3693 else
3694 return "fst%z0\t%y0";
3695 case 2:
3696 return "cvtss2sd\t{%1, %0|%0, %1}";
3697
3698 default:
3699 abort ();
3700 }
3701 }
3702 [(set_attr "type" "fmov,fmov,ssecvt")
3703 (set_attr "mode" "SF,XF,DF")])
3704
3705 (define_insn "*extendsfdf2_1_sse_only"
3706 [(set (match_operand:DF 0 "register_operand" "=Y")
3707 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3708 "!TARGET_80387 && TARGET_SSE2
3709 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3710 "cvtss2sd\t{%1, %0|%0, %1}"
3711 [(set_attr "type" "ssecvt")
3712 (set_attr "mode" "DF")])
3713
3714 (define_expand "extendsfxf2"
3715 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3716 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3717 "!TARGET_64BIT && TARGET_80387"
3718 {
3719 /* ??? Needed for compress_float_constant since all fp constants
3720 are LEGITIMATE_CONSTANT_P. */
3721 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3722 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3723 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3724 operands[1] = force_reg (SFmode, operands[1]);
3725 })
3726
3727 (define_insn "*extendsfxf2_1"
3728 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3729 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3730 "!TARGET_64BIT && TARGET_80387
3731 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3732 {
3733 switch (which_alternative)
3734 {
3735 case 0:
3736 if (REG_P (operands[1])
3737 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3738 return "fstp\t%y0";
3739 else if (STACK_TOP_P (operands[0]))
3740 return "fld%z1\t%y1";
3741 else
3742 return "fst\t%y0";
3743
3744 case 1:
3745 /* There is no non-popping store to memory for XFmode. So if
3746 we need one, follow the store with a load. */
3747 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3748 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3749 else
3750 return "fstp%z0\t%y0";
3751
3752 default:
3753 abort ();
3754 }
3755 }
3756 [(set_attr "type" "fmov")
3757 (set_attr "mode" "SF,XF")])
3758
3759 (define_expand "extendsftf2"
3760 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3761 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3762 "TARGET_80387"
3763 {
3764 /* ??? Needed for compress_float_constant since all fp constants
3765 are LEGITIMATE_CONSTANT_P. */
3766 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3767 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3768 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3769 operands[1] = force_reg (SFmode, operands[1]);
3770 })
3771
3772 (define_insn "*extendsftf2_1"
3773 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3774 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3775 "TARGET_80387
3776 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3777 {
3778 switch (which_alternative)
3779 {
3780 case 0:
3781 if (REG_P (operands[1])
3782 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783 return "fstp\t%y0";
3784 else if (STACK_TOP_P (operands[0]))
3785 return "fld%z1\t%y1";
3786 else
3787 return "fst\t%y0";
3788
3789 case 1:
3790 /* There is no non-popping store to memory for XFmode. So if
3791 we need one, follow the store with a load. */
3792 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3793 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3794 else
3795 return "fstp%z0\t%y0";
3796
3797 default:
3798 abort ();
3799 }
3800 }
3801 [(set_attr "type" "fmov")
3802 (set_attr "mode" "SF,XF")])
3803
3804 (define_expand "extenddfxf2"
3805 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3806 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3807 "!TARGET_64BIT && TARGET_80387"
3808 {
3809 /* ??? Needed for compress_float_constant since all fp constants
3810 are LEGITIMATE_CONSTANT_P. */
3811 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3812 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3813 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3814 operands[1] = force_reg (DFmode, operands[1]);
3815 })
3816
3817 (define_insn "*extenddfxf2_1"
3818 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3819 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3820 "!TARGET_64BIT && TARGET_80387
3821 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3822 {
3823 switch (which_alternative)
3824 {
3825 case 0:
3826 if (REG_P (operands[1])
3827 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3828 return "fstp\t%y0";
3829 else if (STACK_TOP_P (operands[0]))
3830 return "fld%z1\t%y1";
3831 else
3832 return "fst\t%y0";
3833
3834 case 1:
3835 /* There is no non-popping store to memory for XFmode. So if
3836 we need one, follow the store with a load. */
3837 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3838 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3839 else
3840 return "fstp%z0\t%y0";
3841
3842 default:
3843 abort ();
3844 }
3845 }
3846 [(set_attr "type" "fmov")
3847 (set_attr "mode" "DF,XF")])
3848
3849 (define_expand "extenddftf2"
3850 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3851 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3852 "TARGET_80387"
3853 {
3854 /* ??? Needed for compress_float_constant since all fp constants
3855 are LEGITIMATE_CONSTANT_P. */
3856 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3857 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3858 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3859 operands[1] = force_reg (DFmode, operands[1]);
3860 })
3861
3862 (define_insn "*extenddftf2_1"
3863 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3864 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3865 "TARGET_80387
3866 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3867 {
3868 switch (which_alternative)
3869 {
3870 case 0:
3871 if (REG_P (operands[1])
3872 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3873 return "fstp\t%y0";
3874 else if (STACK_TOP_P (operands[0]))
3875 return "fld%z1\t%y1";
3876 else
3877 return "fst\t%y0";
3878
3879 case 1:
3880 /* There is no non-popping store to memory for XFmode. So if
3881 we need one, follow the store with a load. */
3882 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3884 else
3885 return "fstp%z0\t%y0";
3886
3887 default:
3888 abort ();
3889 }
3890 }
3891 [(set_attr "type" "fmov")
3892 (set_attr "mode" "DF,XF")])
3893
3894 ;; %%% This seems bad bad news.
3895 ;; This cannot output into an f-reg because there is no way to be sure
3896 ;; of truncating in that case. Otherwise this is just like a simple move
3897 ;; insn. So we pretend we can output to a reg in order to get better
3898 ;; register preferencing, but we really use a stack slot.
3899
3900 (define_expand "truncdfsf2"
3901 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3902 (float_truncate:SF
3903 (match_operand:DF 1 "register_operand" "")))
3904 (clobber (match_dup 2))])]
3905 "TARGET_80387 || TARGET_SSE2"
3906 "
3907 if (TARGET_80387)
3908 operands[2] = assign_386_stack_local (SFmode, 0);
3909 else
3910 {
3911 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3912 DONE;
3913 }
3914 ")
3915
3916 (define_insn "*truncdfsf2_1"
3917 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3918 (float_truncate:SF
3919 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3920 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3921 "TARGET_80387 && !TARGET_SSE2"
3922 {
3923 switch (which_alternative)
3924 {
3925 case 0:
3926 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3927 return "fstp%z0\t%y0";
3928 else
3929 return "fst%z0\t%y0";
3930 default:
3931 abort ();
3932 }
3933 }
3934 [(set_attr "type" "fmov,multi,multi,multi")
3935 (set_attr "mode" "SF,SF,SF,SF")])
3936
3937 (define_insn "*truncdfsf2_1_sse"
3938 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3939 (float_truncate:SF
3940 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3941 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3942 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3943 {
3944 switch (which_alternative)
3945 {
3946 case 0:
3947 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3948 return "fstp%z0\t%y0";
3949 else
3950 return "fst%z0\t%y0";
3951 case 4:
3952 return "#";
3953 default:
3954 abort ();
3955 }
3956 }
3957 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3958 (set_attr "mode" "SF,SF,SF,SF,DF")])
3959
3960 (define_insn "*truncdfsf2_1_sse_nooverlap"
3961 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3962 (float_truncate:SF
3963 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3964 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3965 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3966 {
3967 switch (which_alternative)
3968 {
3969 case 0:
3970 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3971 return "fstp%z0\t%y0";
3972 else
3973 return "fst%z0\t%y0";
3974 case 4:
3975 return "#";
3976 default:
3977 abort ();
3978 }
3979 }
3980 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3981 (set_attr "mode" "SF,SF,SF,SF,DF")])
3982
3983 (define_insn "*truncdfsf2_2"
3984 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3985 (float_truncate:SF
3986 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3987 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3988 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3989 {
3990 switch (which_alternative)
3991 {
3992 case 0:
3993 case 1:
3994 return "cvtsd2ss\t{%1, %0|%0, %1}";
3995 case 2:
3996 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3997 return "fstp%z0\t%y0";
3998 else
3999 return "fst%z0\t%y0";
4000 default:
4001 abort ();
4002 }
4003 }
4004 [(set_attr "type" "ssecvt,ssecvt,fmov")
4005 (set_attr "athlon_decode" "vector,double,*")
4006 (set_attr "mode" "DF,DF,SF")])
4007
4008 (define_insn "*truncdfsf2_2_nooverlap"
4009 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
4010 (float_truncate:SF
4011 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4012 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4013 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4014 {
4015 switch (which_alternative)
4016 {
4017 case 0:
4018 return "#";
4019 case 1:
4020 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4021 return "fstp%z0\t%y0";
4022 else
4023 return "fst%z0\t%y0";
4024 default:
4025 abort ();
4026 }
4027 }
4028 [(set_attr "type" "ssecvt,fmov")
4029 (set_attr "mode" "DF,SF")])
4030
4031 (define_insn "*truncdfsf2_3"
4032 [(set (match_operand:SF 0 "memory_operand" "=m")
4033 (float_truncate:SF
4034 (match_operand:DF 1 "register_operand" "f")))]
4035 "TARGET_80387"
4036 {
4037 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4038 return "fstp%z0\t%y0";
4039 else
4040 return "fst%z0\t%y0";
4041 }
4042 [(set_attr "type" "fmov")
4043 (set_attr "mode" "SF")])
4044
4045 (define_insn "truncdfsf2_sse_only"
4046 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4047 (float_truncate:SF
4048 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4049 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4050 "cvtsd2ss\t{%1, %0|%0, %1}"
4051 [(set_attr "type" "ssecvt")
4052 (set_attr "athlon_decode" "vector,double")
4053 (set_attr "mode" "DF")])
4054
4055 (define_insn "*truncdfsf2_sse_only_nooverlap"
4056 [(set (match_operand:SF 0 "register_operand" "=&Y")
4057 (float_truncate:SF
4058 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4059 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4060 "#"
4061 [(set_attr "type" "ssecvt")
4062 (set_attr "mode" "DF")])
4063
4064 (define_split
4065 [(set (match_operand:SF 0 "memory_operand" "")
4066 (float_truncate:SF
4067 (match_operand:DF 1 "register_operand" "")))
4068 (clobber (match_operand:SF 2 "memory_operand" ""))]
4069 "TARGET_80387"
4070 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4071 "")
4072
4073 ; Avoid possible reformatting penalty on the destination by first
4074 ; zeroing it out
4075 (define_split
4076 [(set (match_operand:SF 0 "register_operand" "")
4077 (float_truncate:SF
4078 (match_operand:DF 1 "nonimmediate_operand" "")))
4079 (clobber (match_operand 2 "" ""))]
4080 "TARGET_80387 && reload_completed
4081 && SSE_REG_P (operands[0])
4082 && !STACK_REG_P (operands[1])"
4083 [(const_int 0)]
4084 {
4085 rtx src, dest;
4086 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4087 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4088 else
4089 {
4090 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4091 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4092 /* simplify_gen_subreg refuses to widen memory references. */
4093 if (GET_CODE (src) == SUBREG)
4094 alter_subreg (&src);
4095 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4096 abort ();
4097 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4098 emit_insn (gen_cvtsd2ss (dest, dest, src));
4099 }
4100 DONE;
4101 })
4102
4103 (define_split
4104 [(set (match_operand:SF 0 "register_operand" "")
4105 (float_truncate:SF
4106 (match_operand:DF 1 "nonimmediate_operand" "")))]
4107 "TARGET_80387 && reload_completed
4108 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4109 [(const_int 0)]
4110 {
4111 rtx src, dest;
4112 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4113 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4114 /* simplify_gen_subreg refuses to widen memory references. */
4115 if (GET_CODE (src) == SUBREG)
4116 alter_subreg (&src);
4117 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4118 abort ();
4119 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4120 emit_insn (gen_cvtsd2ss (dest, dest, src));
4121 DONE;
4122 })
4123
4124 (define_split
4125 [(set (match_operand:SF 0 "register_operand" "")
4126 (float_truncate:SF
4127 (match_operand:DF 1 "fp_register_operand" "")))
4128 (clobber (match_operand:SF 2 "memory_operand" ""))]
4129 "TARGET_80387 && reload_completed"
4130 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4131 (set (match_dup 0) (match_dup 2))]
4132 "")
4133
4134 (define_expand "truncxfsf2"
4135 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4136 (float_truncate:SF
4137 (match_operand:XF 1 "register_operand" "")))
4138 (clobber (match_dup 2))])]
4139 "!TARGET_64BIT && TARGET_80387"
4140 "operands[2] = assign_386_stack_local (SFmode, 0);")
4141
4142 (define_insn "*truncxfsf2_1"
4143 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4144 (float_truncate:SF
4145 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4146 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4147 "!TARGET_64BIT && TARGET_80387"
4148 {
4149 switch (which_alternative)
4150 {
4151 case 0:
4152 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4153 return "fstp%z0\t%y0";
4154 else
4155 return "fst%z0\t%y0";
4156 default:
4157 abort();
4158 }
4159 }
4160 [(set_attr "type" "fmov,multi,multi,multi")
4161 (set_attr "mode" "SF")])
4162
4163 (define_insn "*truncxfsf2_2"
4164 [(set (match_operand:SF 0 "memory_operand" "=m")
4165 (float_truncate:SF
4166 (match_operand:XF 1 "register_operand" "f")))]
4167 "!TARGET_64BIT && TARGET_80387"
4168 {
4169 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4170 return "fstp%z0\t%y0";
4171 else
4172 return "fst%z0\t%y0";
4173 }
4174 [(set_attr "type" "fmov")
4175 (set_attr "mode" "SF")])
4176
4177 (define_split
4178 [(set (match_operand:SF 0 "memory_operand" "")
4179 (float_truncate:SF
4180 (match_operand:XF 1 "register_operand" "")))
4181 (clobber (match_operand:SF 2 "memory_operand" ""))]
4182 "TARGET_80387"
4183 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4184 "")
4185
4186 (define_split
4187 [(set (match_operand:SF 0 "register_operand" "")
4188 (float_truncate:SF
4189 (match_operand:XF 1 "register_operand" "")))
4190 (clobber (match_operand:SF 2 "memory_operand" ""))]
4191 "TARGET_80387 && reload_completed"
4192 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4193 (set (match_dup 0) (match_dup 2))]
4194 "")
4195
4196 (define_expand "trunctfsf2"
4197 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4198 (float_truncate:SF
4199 (match_operand:TF 1 "register_operand" "")))
4200 (clobber (match_dup 2))])]
4201 "TARGET_80387"
4202 "operands[2] = assign_386_stack_local (SFmode, 0);")
4203
4204 (define_insn "*trunctfsf2_1"
4205 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4206 (float_truncate:SF
4207 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4208 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4209 "TARGET_80387"
4210 {
4211 switch (which_alternative)
4212 {
4213 case 0:
4214 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4215 return "fstp%z0\t%y0";
4216 else
4217 return "fst%z0\t%y0";
4218 default:
4219 abort();
4220 }
4221 }
4222 [(set_attr "type" "fmov,multi,multi,multi")
4223 (set_attr "mode" "SF")])
4224
4225 (define_insn "*trunctfsf2_2"
4226 [(set (match_operand:SF 0 "memory_operand" "=m")
4227 (float_truncate:SF
4228 (match_operand:TF 1 "register_operand" "f")))]
4229 "TARGET_80387"
4230 {
4231 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4232 return "fstp%z0\t%y0";
4233 else
4234 return "fst%z0\t%y0";
4235 }
4236 [(set_attr "type" "fmov")
4237 (set_attr "mode" "SF")])
4238
4239 (define_split
4240 [(set (match_operand:SF 0 "memory_operand" "")
4241 (float_truncate:SF
4242 (match_operand:TF 1 "register_operand" "")))
4243 (clobber (match_operand:SF 2 "memory_operand" ""))]
4244 "TARGET_80387"
4245 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4246 "")
4247
4248 (define_split
4249 [(set (match_operand:SF 0 "register_operand" "")
4250 (float_truncate:SF
4251 (match_operand:TF 1 "register_operand" "")))
4252 (clobber (match_operand:SF 2 "memory_operand" ""))]
4253 "TARGET_80387 && reload_completed"
4254 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4255 (set (match_dup 0) (match_dup 2))]
4256 "")
4257
4258
4259 (define_expand "truncxfdf2"
4260 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4261 (float_truncate:DF
4262 (match_operand:XF 1 "register_operand" "")))
4263 (clobber (match_dup 2))])]
4264 "!TARGET_64BIT && TARGET_80387"
4265 "operands[2] = assign_386_stack_local (DFmode, 0);")
4266
4267 (define_insn "*truncxfdf2_1"
4268 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4269 (float_truncate:DF
4270 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4271 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4272 "!TARGET_64BIT && TARGET_80387"
4273 {
4274 switch (which_alternative)
4275 {
4276 case 0:
4277 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4278 return "fstp%z0\t%y0";
4279 else
4280 return "fst%z0\t%y0";
4281 default:
4282 abort();
4283 }
4284 abort ();
4285 }
4286 [(set_attr "type" "fmov,multi,multi,multi")
4287 (set_attr "mode" "DF")])
4288
4289 (define_insn "*truncxfdf2_2"
4290 [(set (match_operand:DF 0 "memory_operand" "=m")
4291 (float_truncate:DF
4292 (match_operand:XF 1 "register_operand" "f")))]
4293 "!TARGET_64BIT && TARGET_80387"
4294 {
4295 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4296 return "fstp%z0\t%y0";
4297 else
4298 return "fst%z0\t%y0";
4299 }
4300 [(set_attr "type" "fmov")
4301 (set_attr "mode" "DF")])
4302
4303 (define_split
4304 [(set (match_operand:DF 0 "memory_operand" "")
4305 (float_truncate:DF
4306 (match_operand:XF 1 "register_operand" "")))
4307 (clobber (match_operand:DF 2 "memory_operand" ""))]
4308 "TARGET_80387"
4309 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4310 "")
4311
4312 (define_split
4313 [(set (match_operand:DF 0 "register_operand" "")
4314 (float_truncate:DF
4315 (match_operand:XF 1 "register_operand" "")))
4316 (clobber (match_operand:DF 2 "memory_operand" ""))]
4317 "TARGET_80387 && reload_completed"
4318 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4319 (set (match_dup 0) (match_dup 2))]
4320 "")
4321
4322 (define_expand "trunctfdf2"
4323 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4324 (float_truncate:DF
4325 (match_operand:TF 1 "register_operand" "")))
4326 (clobber (match_dup 2))])]
4327 "TARGET_80387"
4328 "operands[2] = assign_386_stack_local (DFmode, 0);")
4329
4330 (define_insn "*trunctfdf2_1"
4331 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4332 (float_truncate:DF
4333 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4334 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4335 "TARGET_80387"
4336 {
4337 switch (which_alternative)
4338 {
4339 case 0:
4340 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4341 return "fstp%z0\t%y0";
4342 else
4343 return "fst%z0\t%y0";
4344 default:
4345 abort();
4346 }
4347 abort ();
4348 }
4349 [(set_attr "type" "fmov,multi,multi,multi")
4350 (set_attr "mode" "DF")])
4351
4352 (define_insn "*trunctfdf2_2"
4353 [(set (match_operand:DF 0 "memory_operand" "=m")
4354 (float_truncate:DF
4355 (match_operand:TF 1 "register_operand" "f")))]
4356 "TARGET_80387"
4357 {
4358 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4359 return "fstp%z0\t%y0";
4360 else
4361 return "fst%z0\t%y0";
4362 }
4363 [(set_attr "type" "fmov")
4364 (set_attr "mode" "DF")])
4365
4366 (define_split
4367 [(set (match_operand:DF 0 "memory_operand" "")
4368 (float_truncate:DF
4369 (match_operand:TF 1 "register_operand" "")))
4370 (clobber (match_operand:DF 2 "memory_operand" ""))]
4371 "TARGET_80387"
4372 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4373 "")
4374
4375 (define_split
4376 [(set (match_operand:DF 0 "register_operand" "")
4377 (float_truncate:DF
4378 (match_operand:TF 1 "register_operand" "")))
4379 (clobber (match_operand:DF 2 "memory_operand" ""))]
4380 "TARGET_80387 && reload_completed"
4381 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4382 (set (match_dup 0) (match_dup 2))]
4383 "")
4384
4385 \f
4386 ;; %%% Break up all these bad boys.
4387
4388 ;; Signed conversion to DImode.
4389
4390 (define_expand "fix_truncxfdi2"
4391 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4392 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4393 "!TARGET_64BIT && TARGET_80387"
4394 "")
4395
4396 (define_expand "fix_trunctfdi2"
4397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4398 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4399 "TARGET_80387"
4400 "")
4401
4402 (define_expand "fix_truncdfdi2"
4403 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4404 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4405 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4406 {
4407 if (TARGET_64BIT && TARGET_SSE2)
4408 {
4409 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4410 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4411 if (out != operands[0])
4412 emit_move_insn (operands[0], out);
4413 DONE;
4414 }
4415 })
4416
4417 (define_expand "fix_truncsfdi2"
4418 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4419 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4420 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4421 {
4422 if (TARGET_SSE && TARGET_64BIT)
4423 {
4424 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4425 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4426 if (out != operands[0])
4427 emit_move_insn (operands[0], out);
4428 DONE;
4429 }
4430 })
4431
4432 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4433 ;; of the machinery.
4434 (define_insn_and_split "*fix_truncdi_1"
4435 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4436 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4437 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4438 && !reload_completed && !reload_in_progress
4439 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4440 "#"
4441 "&& 1"
4442 [(const_int 0)]
4443 {
4444 operands[2] = assign_386_stack_local (HImode, 1);
4445 operands[3] = assign_386_stack_local (HImode, 2);
4446 if (memory_operand (operands[0], VOIDmode))
4447 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4448 operands[2], operands[3]));
4449 else
4450 {
4451 operands[4] = assign_386_stack_local (DImode, 0);
4452 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4453 operands[2], operands[3],
4454 operands[4]));
4455 }
4456 DONE;
4457 }
4458 [(set_attr "type" "fistp")])
4459
4460 (define_insn "fix_truncdi_nomemory"
4461 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4462 (fix:DI (match_operand 1 "register_operand" "f,f")))
4463 (use (match_operand:HI 2 "memory_operand" "m,m"))
4464 (use (match_operand:HI 3 "memory_operand" "m,m"))
4465 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4466 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4467 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4468 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4469 "#"
4470 [(set_attr "type" "fistp")])
4471
4472 (define_insn "fix_truncdi_memory"
4473 [(set (match_operand:DI 0 "memory_operand" "=m")
4474 (fix:DI (match_operand 1 "register_operand" "f")))
4475 (use (match_operand:HI 2 "memory_operand" "m"))
4476 (use (match_operand:HI 3 "memory_operand" "m"))
4477 (clobber (match_scratch:DF 4 "=&1f"))]
4478 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4479 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4480 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4481 [(set_attr "type" "fistp")])
4482
4483 (define_split
4484 [(set (match_operand:DI 0 "register_operand" "")
4485 (fix:DI (match_operand 1 "register_operand" "")))
4486 (use (match_operand:HI 2 "memory_operand" ""))
4487 (use (match_operand:HI 3 "memory_operand" ""))
4488 (clobber (match_operand:DI 4 "memory_operand" ""))
4489 (clobber (match_scratch 5 ""))]
4490 "reload_completed"
4491 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4492 (use (match_dup 2))
4493 (use (match_dup 3))
4494 (clobber (match_dup 5))])
4495 (set (match_dup 0) (match_dup 4))]
4496 "")
4497
4498 (define_split
4499 [(set (match_operand:DI 0 "memory_operand" "")
4500 (fix:DI (match_operand 1 "register_operand" "")))
4501 (use (match_operand:HI 2 "memory_operand" ""))
4502 (use (match_operand:HI 3 "memory_operand" ""))
4503 (clobber (match_operand:DI 4 "memory_operand" ""))
4504 (clobber (match_scratch 5 ""))]
4505 "reload_completed"
4506 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4507 (use (match_dup 2))
4508 (use (match_dup 3))
4509 (clobber (match_dup 5))])]
4510 "")
4511
4512 ;; When SSE available, it is always faster to use it!
4513 (define_insn "fix_truncsfdi_sse"
4514 [(set (match_operand:DI 0 "register_operand" "=r,r")
4515 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4516 "TARGET_64BIT && TARGET_SSE"
4517 "cvttss2si{q}\t{%1, %0|%0, %1}"
4518 [(set_attr "type" "sseicvt")
4519 (set_attr "athlon_decode" "double,vector")])
4520
4521 (define_insn "fix_truncdfdi_sse"
4522 [(set (match_operand:DI 0 "register_operand" "=r,r")
4523 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4524 "TARGET_64BIT && TARGET_SSE2"
4525 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4526 [(set_attr "type" "sseicvt,sseicvt")
4527 (set_attr "athlon_decode" "double,vector")])
4528
4529 ;; Signed conversion to SImode.
4530
4531 (define_expand "fix_truncxfsi2"
4532 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4533 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4534 "!TARGET_64BIT && TARGET_80387"
4535 "")
4536
4537 (define_expand "fix_trunctfsi2"
4538 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4539 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4540 "TARGET_80387"
4541 "")
4542
4543 (define_expand "fix_truncdfsi2"
4544 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4545 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4546 "TARGET_80387 || TARGET_SSE2"
4547 {
4548 if (TARGET_SSE2)
4549 {
4550 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4551 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4552 if (out != operands[0])
4553 emit_move_insn (operands[0], out);
4554 DONE;
4555 }
4556 })
4557
4558 (define_expand "fix_truncsfsi2"
4559 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4560 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4561 "TARGET_80387 || TARGET_SSE"
4562 {
4563 if (TARGET_SSE)
4564 {
4565 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4566 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4567 if (out != operands[0])
4568 emit_move_insn (operands[0], out);
4569 DONE;
4570 }
4571 })
4572
4573 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4574 ;; of the machinery.
4575 (define_insn_and_split "*fix_truncsi_1"
4576 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4577 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4578 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4579 && !reload_completed && !reload_in_progress
4580 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4581 "#"
4582 "&& 1"
4583 [(const_int 0)]
4584 {
4585 operands[2] = assign_386_stack_local (HImode, 1);
4586 operands[3] = assign_386_stack_local (HImode, 2);
4587 if (memory_operand (operands[0], VOIDmode))
4588 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4589 operands[2], operands[3]));
4590 else
4591 {
4592 operands[4] = assign_386_stack_local (SImode, 0);
4593 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4594 operands[2], operands[3],
4595 operands[4]));
4596 }
4597 DONE;
4598 }
4599 [(set_attr "type" "fistp")])
4600
4601 (define_insn "fix_truncsi_nomemory"
4602 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4603 (fix:SI (match_operand 1 "register_operand" "f,f")))
4604 (use (match_operand:HI 2 "memory_operand" "m,m"))
4605 (use (match_operand:HI 3 "memory_operand" "m,m"))
4606 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4607 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4608 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4609 "#"
4610 [(set_attr "type" "fistp")])
4611
4612 (define_insn "fix_truncsi_memory"
4613 [(set (match_operand:SI 0 "memory_operand" "=m")
4614 (fix:SI (match_operand 1 "register_operand" "f")))
4615 (use (match_operand:HI 2 "memory_operand" "m"))
4616 (use (match_operand:HI 3 "memory_operand" "m"))]
4617 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4618 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4619 "* return output_fix_trunc (insn, operands);"
4620 [(set_attr "type" "fistp")])
4621
4622 ;; When SSE available, it is always faster to use it!
4623 (define_insn "fix_truncsfsi_sse"
4624 [(set (match_operand:SI 0 "register_operand" "=r,r")
4625 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4626 "TARGET_SSE"
4627 "cvttss2si\t{%1, %0|%0, %1}"
4628 [(set_attr "type" "sseicvt")
4629 (set_attr "athlon_decode" "double,vector")])
4630
4631 (define_insn "fix_truncdfsi_sse"
4632 [(set (match_operand:SI 0 "register_operand" "=r,r")
4633 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4634 "TARGET_SSE2"
4635 "cvttsd2si\t{%1, %0|%0, %1}"
4636 [(set_attr "type" "sseicvt")
4637 (set_attr "athlon_decode" "double,vector")])
4638
4639 (define_split
4640 [(set (match_operand:SI 0 "register_operand" "")
4641 (fix:SI (match_operand 1 "register_operand" "")))
4642 (use (match_operand:HI 2 "memory_operand" ""))
4643 (use (match_operand:HI 3 "memory_operand" ""))
4644 (clobber (match_operand:SI 4 "memory_operand" ""))]
4645 "reload_completed"
4646 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4647 (use (match_dup 2))
4648 (use (match_dup 3))])
4649 (set (match_dup 0) (match_dup 4))]
4650 "")
4651
4652 (define_split
4653 [(set (match_operand:SI 0 "memory_operand" "")
4654 (fix:SI (match_operand 1 "register_operand" "")))
4655 (use (match_operand:HI 2 "memory_operand" ""))
4656 (use (match_operand:HI 3 "memory_operand" ""))
4657 (clobber (match_operand:SI 4 "memory_operand" ""))]
4658 "reload_completed"
4659 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4660 (use (match_dup 2))
4661 (use (match_dup 3))])]
4662 "")
4663
4664 ;; Signed conversion to HImode.
4665
4666 (define_expand "fix_truncxfhi2"
4667 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4668 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4669 "!TARGET_64BIT && TARGET_80387"
4670 "")
4671
4672 (define_expand "fix_trunctfhi2"
4673 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4674 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4675 "TARGET_80387"
4676 "")
4677
4678 (define_expand "fix_truncdfhi2"
4679 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4680 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4681 "TARGET_80387 && !TARGET_SSE2"
4682 "")
4683
4684 (define_expand "fix_truncsfhi2"
4685 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4686 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4687 "TARGET_80387 && !TARGET_SSE"
4688 "")
4689
4690 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4691 ;; of the machinery.
4692 (define_insn_and_split "*fix_trunchi_1"
4693 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4694 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4695 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4696 && !reload_completed && !reload_in_progress
4697 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4698 "#"
4699 ""
4700 [(const_int 0)]
4701 {
4702 operands[2] = assign_386_stack_local (HImode, 1);
4703 operands[3] = assign_386_stack_local (HImode, 2);
4704 if (memory_operand (operands[0], VOIDmode))
4705 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4706 operands[2], operands[3]));
4707 else
4708 {
4709 operands[4] = assign_386_stack_local (HImode, 0);
4710 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4711 operands[2], operands[3],
4712 operands[4]));
4713 }
4714 DONE;
4715 }
4716 [(set_attr "type" "fistp")])
4717
4718 (define_insn "fix_trunchi_nomemory"
4719 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4720 (fix:HI (match_operand 1 "register_operand" "f,f")))
4721 (use (match_operand:HI 2 "memory_operand" "m,m"))
4722 (use (match_operand:HI 3 "memory_operand" "m,m"))
4723 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4724 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4725 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4726 "#"
4727 [(set_attr "type" "fistp")])
4728
4729 (define_insn "fix_trunchi_memory"
4730 [(set (match_operand:HI 0 "memory_operand" "=m")
4731 (fix:HI (match_operand 1 "register_operand" "f")))
4732 (use (match_operand:HI 2 "memory_operand" "m"))
4733 (use (match_operand:HI 3 "memory_operand" "m"))]
4734 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4736 "* return output_fix_trunc (insn, operands);"
4737 [(set_attr "type" "fistp")])
4738
4739 (define_split
4740 [(set (match_operand:HI 0 "memory_operand" "")
4741 (fix:HI (match_operand 1 "register_operand" "")))
4742 (use (match_operand:HI 2 "memory_operand" ""))
4743 (use (match_operand:HI 3 "memory_operand" ""))
4744 (clobber (match_operand:HI 4 "memory_operand" ""))]
4745 "reload_completed"
4746 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4747 (use (match_dup 2))
4748 (use (match_dup 3))])]
4749 "")
4750
4751 (define_split
4752 [(set (match_operand:HI 0 "register_operand" "")
4753 (fix:HI (match_operand 1 "register_operand" "")))
4754 (use (match_operand:HI 2 "memory_operand" ""))
4755 (use (match_operand:HI 3 "memory_operand" ""))
4756 (clobber (match_operand:HI 4 "memory_operand" ""))]
4757 "reload_completed"
4758 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4759 (use (match_dup 2))
4760 (use (match_dup 3))
4761 (clobber (match_dup 4))])
4762 (set (match_dup 0) (match_dup 4))]
4763 "")
4764
4765 ;; %% Not used yet.
4766 (define_insn "x86_fnstcw_1"
4767 [(set (match_operand:HI 0 "memory_operand" "=m")
4768 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4769 "TARGET_80387"
4770 "fnstcw\t%0"
4771 [(set_attr "length" "2")
4772 (set_attr "mode" "HI")
4773 (set_attr "unit" "i387")
4774 (set_attr "ppro_uops" "few")])
4775
4776 (define_insn "x86_fldcw_1"
4777 [(set (reg:HI 18)
4778 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4779 "TARGET_80387"
4780 "fldcw\t%0"
4781 [(set_attr "length" "2")
4782 (set_attr "mode" "HI")
4783 (set_attr "unit" "i387")
4784 (set_attr "athlon_decode" "vector")
4785 (set_attr "ppro_uops" "few")])
4786 \f
4787 ;; Conversion between fixed point and floating point.
4788
4789 ;; Even though we only accept memory inputs, the backend _really_
4790 ;; wants to be able to do this between registers.
4791
4792 (define_expand "floathisf2"
4793 [(set (match_operand:SF 0 "register_operand" "")
4794 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4795 "TARGET_SSE || TARGET_80387"
4796 {
4797 if (TARGET_SSE && TARGET_SSE_MATH)
4798 {
4799 emit_insn (gen_floatsisf2 (operands[0],
4800 convert_to_mode (SImode, operands[1], 0)));
4801 DONE;
4802 }
4803 })
4804
4805 (define_insn "*floathisf2_1"
4806 [(set (match_operand:SF 0 "register_operand" "=f,f")
4807 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4808 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4809 "@
4810 fild%z1\t%1
4811 #"
4812 [(set_attr "type" "fmov,multi")
4813 (set_attr "mode" "SF")
4814 (set_attr "fp_int_src" "true")])
4815
4816 (define_expand "floatsisf2"
4817 [(set (match_operand:SF 0 "register_operand" "")
4818 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4819 "TARGET_SSE || TARGET_80387"
4820 "")
4821
4822 (define_insn "*floatsisf2_i387"
4823 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4824 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4825 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4826 "@
4827 fild%z1\t%1
4828 #
4829 cvtsi2ss\t{%1, %0|%0, %1}
4830 cvtsi2ss\t{%1, %0|%0, %1}"
4831 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832 (set_attr "mode" "SF")
4833 (set_attr "athlon_decode" "*,*,vector,double")
4834 (set_attr "fp_int_src" "true")])
4835
4836 (define_insn "*floatsisf2_sse"
4837 [(set (match_operand:SF 0 "register_operand" "=x,x")
4838 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4839 "TARGET_SSE"
4840 "cvtsi2ss\t{%1, %0|%0, %1}"
4841 [(set_attr "type" "sseicvt")
4842 (set_attr "mode" "SF")
4843 (set_attr "athlon_decode" "vector,double")
4844 (set_attr "fp_int_src" "true")])
4845
4846 ; Avoid possible reformatting penalty on the destination by first
4847 ; zeroing it out
4848 (define_split
4849 [(set (match_operand:SF 0 "register_operand" "")
4850 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4851 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4852 && SSE_REG_P (operands[0])"
4853 [(const_int 0)]
4854 {
4855 rtx dest;
4856 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4857 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4858 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4859 DONE;
4860 })
4861
4862 (define_expand "floatdisf2"
4863 [(set (match_operand:SF 0 "register_operand" "")
4864 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4865 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4866 "")
4867
4868 (define_insn "*floatdisf2_i387_only"
4869 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4870 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4871 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4872 "@
4873 fild%z1\t%1
4874 #"
4875 [(set_attr "type" "fmov,multi")
4876 (set_attr "mode" "SF")
4877 (set_attr "fp_int_src" "true")])
4878
4879 (define_insn "*floatdisf2_i387"
4880 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4881 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4882 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4883 "@
4884 fild%z1\t%1
4885 #
4886 cvtsi2ss{q}\t{%1, %0|%0, %1}
4887 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4888 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4889 (set_attr "mode" "SF")
4890 (set_attr "athlon_decode" "*,*,vector,double")
4891 (set_attr "fp_int_src" "true")])
4892
4893 (define_insn "*floatdisf2_sse"
4894 [(set (match_operand:SF 0 "register_operand" "=x,x")
4895 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4896 "TARGET_64BIT && TARGET_SSE"
4897 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4898 [(set_attr "type" "sseicvt")
4899 (set_attr "mode" "SF")
4900 (set_attr "athlon_decode" "vector,double")
4901 (set_attr "fp_int_src" "true")])
4902
4903 ; Avoid possible reformatting penalty on the destination by first
4904 ; zeroing it out
4905 (define_split
4906 [(set (match_operand:SF 0 "register_operand" "")
4907 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4908 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4909 && SSE_REG_P (operands[0])"
4910 [(const_int 0)]
4911 {
4912 rtx dest;
4913 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4914 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4915 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4916 DONE;
4917 })
4918
4919 (define_expand "floathidf2"
4920 [(set (match_operand:DF 0 "register_operand" "")
4921 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4922 "TARGET_SSE2 || TARGET_80387"
4923 {
4924 if (TARGET_SSE && TARGET_SSE_MATH)
4925 {
4926 emit_insn (gen_floatsidf2 (operands[0],
4927 convert_to_mode (SImode, operands[1], 0)));
4928 DONE;
4929 }
4930 })
4931
4932 (define_insn "*floathidf2_1"
4933 [(set (match_operand:DF 0 "register_operand" "=f,f")
4934 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4935 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4936 "@
4937 fild%z1\t%1
4938 #"
4939 [(set_attr "type" "fmov,multi")
4940 (set_attr "mode" "DF")
4941 (set_attr "fp_int_src" "true")])
4942
4943 (define_expand "floatsidf2"
4944 [(set (match_operand:DF 0 "register_operand" "")
4945 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4946 "TARGET_80387 || TARGET_SSE2"
4947 "")
4948
4949 (define_insn "*floatsidf2_i387"
4950 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4951 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4952 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4953 "@
4954 fild%z1\t%1
4955 #
4956 cvtsi2sd\t{%1, %0|%0, %1}
4957 cvtsi2sd\t{%1, %0|%0, %1}"
4958 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4959 (set_attr "mode" "DF")
4960 (set_attr "athlon_decode" "*,*,double,direct")
4961 (set_attr "fp_int_src" "true")])
4962
4963 (define_insn "*floatsidf2_sse"
4964 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4965 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4966 "TARGET_SSE2"
4967 "cvtsi2sd\t{%1, %0|%0, %1}"
4968 [(set_attr "type" "sseicvt")
4969 (set_attr "mode" "DF")
4970 (set_attr "athlon_decode" "double,direct")
4971 (set_attr "fp_int_src" "true")])
4972
4973 (define_expand "floatdidf2"
4974 [(set (match_operand:DF 0 "register_operand" "")
4975 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4976 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4977 "")
4978
4979 (define_insn "*floatdidf2_i387_only"
4980 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4981 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4982 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4983 "@
4984 fild%z1\t%1
4985 #"
4986 [(set_attr "type" "fmov,multi")
4987 (set_attr "mode" "DF")
4988 (set_attr "fp_int_src" "true")])
4989
4990 (define_insn "*floatdidf2_i387"
4991 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4992 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4993 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4994 "@
4995 fild%z1\t%1
4996 #
4997 cvtsi2sd{q}\t{%1, %0|%0, %1}
4998 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4999 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5000 (set_attr "mode" "DF")
5001 (set_attr "athlon_decode" "*,*,double,direct")
5002 (set_attr "fp_int_src" "true")])
5003
5004 (define_insn "*floatdidf2_sse"
5005 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5006 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5007 "TARGET_SSE2"
5008 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5009 [(set_attr "type" "sseicvt")
5010 (set_attr "mode" "DF")
5011 (set_attr "athlon_decode" "double,direct")
5012 (set_attr "fp_int_src" "true")])
5013
5014 (define_insn "floathixf2"
5015 [(set (match_operand:XF 0 "register_operand" "=f,f")
5016 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5017 "!TARGET_64BIT && TARGET_80387"
5018 "@
5019 fild%z1\t%1
5020 #"
5021 [(set_attr "type" "fmov,multi")
5022 (set_attr "mode" "XF")
5023 (set_attr "fp_int_src" "true")])
5024
5025 (define_insn "floathitf2"
5026 [(set (match_operand:TF 0 "register_operand" "=f,f")
5027 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5028 "TARGET_80387"
5029 "@
5030 fild%z1\t%1
5031 #"
5032 [(set_attr "type" "fmov,multi")
5033 (set_attr "mode" "XF")
5034 (set_attr "fp_int_src" "true")])
5035
5036 (define_insn "floatsixf2"
5037 [(set (match_operand:XF 0 "register_operand" "=f,f")
5038 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5039 "!TARGET_64BIT && TARGET_80387"
5040 "@
5041 fild%z1\t%1
5042 #"
5043 [(set_attr "type" "fmov,multi")
5044 (set_attr "mode" "XF")
5045 (set_attr "fp_int_src" "true")])
5046
5047 (define_insn "floatsitf2"
5048 [(set (match_operand:TF 0 "register_operand" "=f,f")
5049 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5050 "TARGET_80387"
5051 "@
5052 fild%z1\t%1
5053 #"
5054 [(set_attr "type" "fmov,multi")
5055 (set_attr "mode" "XF")
5056 (set_attr "fp_int_src" "true")])
5057
5058 (define_insn "floatdixf2"
5059 [(set (match_operand:XF 0 "register_operand" "=f,f")
5060 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5061 "!TARGET_64BIT && TARGET_80387"
5062 "@
5063 fild%z1\t%1
5064 #"
5065 [(set_attr "type" "fmov,multi")
5066 (set_attr "mode" "XF")
5067 (set_attr "fp_int_src" "true")])
5068
5069 (define_insn "floatditf2"
5070 [(set (match_operand:TF 0 "register_operand" "=f,f")
5071 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5072 "TARGET_80387"
5073 "@
5074 fild%z1\t%1
5075 #"
5076 [(set_attr "type" "fmov,multi")
5077 (set_attr "mode" "XF")
5078 (set_attr "fp_int_src" "true")])
5079
5080 ;; %%% Kill these when reload knows how to do it.
5081 (define_split
5082 [(set (match_operand 0 "fp_register_operand" "")
5083 (float (match_operand 1 "register_operand" "")))]
5084 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5085 [(const_int 0)]
5086 {
5087 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5088 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5089 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5090 ix86_free_from_memory (GET_MODE (operands[1]));
5091 DONE;
5092 })
5093
5094 (define_expand "floatunssisf2"
5095 [(use (match_operand:SF 0 "register_operand" ""))
5096 (use (match_operand:SI 1 "register_operand" ""))]
5097 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5098 "x86_emit_floatuns (operands); DONE;")
5099
5100 (define_expand "floatunsdisf2"
5101 [(use (match_operand:SF 0 "register_operand" ""))
5102 (use (match_operand:DI 1 "register_operand" ""))]
5103 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5104 "x86_emit_floatuns (operands); DONE;")
5105
5106 (define_expand "floatunsdidf2"
5107 [(use (match_operand:DF 0 "register_operand" ""))
5108 (use (match_operand:DI 1 "register_operand" ""))]
5109 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5110 "x86_emit_floatuns (operands); DONE;")
5111 \f
5112 ;; Add instructions
5113
5114 ;; %%% splits for addsidi3
5115 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5116 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5117 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5118
5119 (define_expand "adddi3"
5120 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5121 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5122 (match_operand:DI 2 "x86_64_general_operand" "")))
5123 (clobber (reg:CC 17))]
5124 ""
5125 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5126
5127 (define_insn "*adddi3_1"
5128 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5129 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5130 (match_operand:DI 2 "general_operand" "roiF,riF")))
5131 (clobber (reg:CC 17))]
5132 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5133 "#")
5134
5135 (define_split
5136 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5137 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5138 (match_operand:DI 2 "general_operand" "")))
5139 (clobber (reg:CC 17))]
5140 "!TARGET_64BIT && reload_completed"
5141 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5142 UNSPEC_ADD_CARRY))
5143 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5144 (parallel [(set (match_dup 3)
5145 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5146 (match_dup 4))
5147 (match_dup 5)))
5148 (clobber (reg:CC 17))])]
5149 "split_di (operands+0, 1, operands+0, operands+3);
5150 split_di (operands+1, 1, operands+1, operands+4);
5151 split_di (operands+2, 1, operands+2, operands+5);")
5152
5153 (define_insn "adddi3_carry_rex64"
5154 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5155 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5156 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5157 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5158 (clobber (reg:CC 17))]
5159 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5160 "adc{q}\t{%2, %0|%0, %2}"
5161 [(set_attr "type" "alu")
5162 (set_attr "pent_pair" "pu")
5163 (set_attr "mode" "DI")
5164 (set_attr "ppro_uops" "few")])
5165
5166 (define_insn "*adddi3_cc_rex64"
5167 [(set (reg:CC 17)
5168 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5169 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5170 UNSPEC_ADD_CARRY))
5171 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5172 (plus:DI (match_dup 1) (match_dup 2)))]
5173 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5174 "add{q}\t{%2, %0|%0, %2}"
5175 [(set_attr "type" "alu")
5176 (set_attr "mode" "DI")])
5177
5178 (define_insn "addqi3_carry"
5179 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5180 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5181 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5182 (match_operand:QI 2 "general_operand" "ri,rm")))
5183 (clobber (reg:CC 17))]
5184 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5185 "adc{b}\t{%2, %0|%0, %2}"
5186 [(set_attr "type" "alu")
5187 (set_attr "pent_pair" "pu")
5188 (set_attr "mode" "QI")
5189 (set_attr "ppro_uops" "few")])
5190
5191 (define_insn "addhi3_carry"
5192 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5193 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5194 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5195 (match_operand:HI 2 "general_operand" "ri,rm")))
5196 (clobber (reg:CC 17))]
5197 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5198 "adc{w}\t{%2, %0|%0, %2}"
5199 [(set_attr "type" "alu")
5200 (set_attr "pent_pair" "pu")
5201 (set_attr "mode" "HI")
5202 (set_attr "ppro_uops" "few")])
5203
5204 (define_insn "addsi3_carry"
5205 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5206 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5207 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5208 (match_operand:SI 2 "general_operand" "ri,rm")))
5209 (clobber (reg:CC 17))]
5210 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5211 "adc{l}\t{%2, %0|%0, %2}"
5212 [(set_attr "type" "alu")
5213 (set_attr "pent_pair" "pu")
5214 (set_attr "mode" "SI")
5215 (set_attr "ppro_uops" "few")])
5216
5217 (define_insn "*addsi3_carry_zext"
5218 [(set (match_operand:DI 0 "register_operand" "=r")
5219 (zero_extend:DI
5220 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5221 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5222 (match_operand:SI 2 "general_operand" "rim"))))
5223 (clobber (reg:CC 17))]
5224 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5225 "adc{l}\t{%2, %k0|%k0, %2}"
5226 [(set_attr "type" "alu")
5227 (set_attr "pent_pair" "pu")
5228 (set_attr "mode" "SI")
5229 (set_attr "ppro_uops" "few")])
5230
5231 (define_insn "*addsi3_cc"
5232 [(set (reg:CC 17)
5233 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5234 (match_operand:SI 2 "general_operand" "ri,rm")]
5235 UNSPEC_ADD_CARRY))
5236 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5237 (plus:SI (match_dup 1) (match_dup 2)))]
5238 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5239 "add{l}\t{%2, %0|%0, %2}"
5240 [(set_attr "type" "alu")
5241 (set_attr "mode" "SI")])
5242
5243 (define_insn "addqi3_cc"
5244 [(set (reg:CC 17)
5245 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5246 (match_operand:QI 2 "general_operand" "qi,qm")]
5247 UNSPEC_ADD_CARRY))
5248 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5249 (plus:QI (match_dup 1) (match_dup 2)))]
5250 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5251 "add{b}\t{%2, %0|%0, %2}"
5252 [(set_attr "type" "alu")
5253 (set_attr "mode" "QI")])
5254
5255 (define_expand "addsi3"
5256 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5257 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5258 (match_operand:SI 2 "general_operand" "")))
5259 (clobber (reg:CC 17))])]
5260 ""
5261 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5262
5263 (define_insn "*lea_1"
5264 [(set (match_operand:SI 0 "register_operand" "=r")
5265 (match_operand:SI 1 "address_operand" "p"))]
5266 "!TARGET_64BIT"
5267 "lea{l}\t{%a1, %0|%0, %a1}"
5268 [(set_attr "type" "lea")
5269 (set_attr "mode" "SI")])
5270
5271 (define_insn "*lea_1_rex64"
5272 [(set (match_operand:SI 0 "register_operand" "=r")
5273 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5274 "TARGET_64BIT"
5275 "lea{l}\t{%a1, %0|%0, %a1}"
5276 [(set_attr "type" "lea")
5277 (set_attr "mode" "SI")])
5278
5279 (define_insn "*lea_1_zext"
5280 [(set (match_operand:DI 0 "register_operand" "=r")
5281 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5282 "TARGET_64BIT"
5283 "lea{l}\t{%a1, %k0|%k0, %a1}"
5284 [(set_attr "type" "lea")
5285 (set_attr "mode" "SI")])
5286
5287 (define_insn "*lea_2_rex64"
5288 [(set (match_operand:DI 0 "register_operand" "=r")
5289 (match_operand:DI 1 "address_operand" "p"))]
5290 "TARGET_64BIT"
5291 "lea{q}\t{%a1, %0|%0, %a1}"
5292 [(set_attr "type" "lea")
5293 (set_attr "mode" "DI")])
5294
5295 ;; The lea patterns for non-Pmodes needs to be matched by several
5296 ;; insns converted to real lea by splitters.
5297
5298 (define_insn_and_split "*lea_general_1"
5299 [(set (match_operand 0 "register_operand" "=r")
5300 (plus (plus (match_operand 1 "index_register_operand" "r")
5301 (match_operand 2 "register_operand" "r"))
5302 (match_operand 3 "immediate_operand" "i")))]
5303 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5304 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5305 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5306 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5307 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5308 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5309 || GET_MODE (operands[3]) == VOIDmode)"
5310 "#"
5311 "&& reload_completed"
5312 [(const_int 0)]
5313 {
5314 rtx pat;
5315 operands[0] = gen_lowpart (SImode, operands[0]);
5316 operands[1] = gen_lowpart (Pmode, operands[1]);
5317 operands[2] = gen_lowpart (Pmode, operands[2]);
5318 operands[3] = gen_lowpart (Pmode, operands[3]);
5319 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5320 operands[3]);
5321 if (Pmode != SImode)
5322 pat = gen_rtx_SUBREG (SImode, pat, 0);
5323 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5324 DONE;
5325 }
5326 [(set_attr "type" "lea")
5327 (set_attr "mode" "SI")])
5328
5329 (define_insn_and_split "*lea_general_1_zext"
5330 [(set (match_operand:DI 0 "register_operand" "=r")
5331 (zero_extend:DI
5332 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5333 (match_operand:SI 2 "register_operand" "r"))
5334 (match_operand:SI 3 "immediate_operand" "i"))))]
5335 "TARGET_64BIT"
5336 "#"
5337 "&& reload_completed"
5338 [(set (match_dup 0)
5339 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5340 (match_dup 2))
5341 (match_dup 3)) 0)))]
5342 {
5343 operands[1] = gen_lowpart (Pmode, operands[1]);
5344 operands[2] = gen_lowpart (Pmode, operands[2]);
5345 operands[3] = gen_lowpart (Pmode, operands[3]);
5346 }
5347 [(set_attr "type" "lea")
5348 (set_attr "mode" "SI")])
5349
5350 (define_insn_and_split "*lea_general_2"
5351 [(set (match_operand 0 "register_operand" "=r")
5352 (plus (mult (match_operand 1 "index_register_operand" "r")
5353 (match_operand 2 "const248_operand" "i"))
5354 (match_operand 3 "nonmemory_operand" "ri")))]
5355 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5356 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5357 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5358 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5359 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5360 || GET_MODE (operands[3]) == VOIDmode)"
5361 "#"
5362 "&& reload_completed"
5363 [(const_int 0)]
5364 {
5365 rtx pat;
5366 operands[0] = gen_lowpart (SImode, operands[0]);
5367 operands[1] = gen_lowpart (Pmode, operands[1]);
5368 operands[3] = gen_lowpart (Pmode, operands[3]);
5369 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5370 operands[3]);
5371 if (Pmode != SImode)
5372 pat = gen_rtx_SUBREG (SImode, pat, 0);
5373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5374 DONE;
5375 }
5376 [(set_attr "type" "lea")
5377 (set_attr "mode" "SI")])
5378
5379 (define_insn_and_split "*lea_general_2_zext"
5380 [(set (match_operand:DI 0 "register_operand" "=r")
5381 (zero_extend:DI
5382 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5383 (match_operand:SI 2 "const248_operand" "n"))
5384 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5385 "TARGET_64BIT"
5386 "#"
5387 "&& reload_completed"
5388 [(set (match_dup 0)
5389 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5390 (match_dup 2))
5391 (match_dup 3)) 0)))]
5392 {
5393 operands[1] = gen_lowpart (Pmode, operands[1]);
5394 operands[3] = gen_lowpart (Pmode, operands[3]);
5395 }
5396 [(set_attr "type" "lea")
5397 (set_attr "mode" "SI")])
5398
5399 (define_insn_and_split "*lea_general_3"
5400 [(set (match_operand 0 "register_operand" "=r")
5401 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5402 (match_operand 2 "const248_operand" "i"))
5403 (match_operand 3 "register_operand" "r"))
5404 (match_operand 4 "immediate_operand" "i")))]
5405 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5406 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5407 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5408 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5409 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5410 "#"
5411 "&& reload_completed"
5412 [(const_int 0)]
5413 {
5414 rtx pat;
5415 operands[0] = gen_lowpart (SImode, operands[0]);
5416 operands[1] = gen_lowpart (Pmode, operands[1]);
5417 operands[3] = gen_lowpart (Pmode, operands[3]);
5418 operands[4] = gen_lowpart (Pmode, operands[4]);
5419 pat = gen_rtx_PLUS (Pmode,
5420 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5421 operands[2]),
5422 operands[3]),
5423 operands[4]);
5424 if (Pmode != SImode)
5425 pat = gen_rtx_SUBREG (SImode, pat, 0);
5426 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5427 DONE;
5428 }
5429 [(set_attr "type" "lea")
5430 (set_attr "mode" "SI")])
5431
5432 (define_insn_and_split "*lea_general_3_zext"
5433 [(set (match_operand:DI 0 "register_operand" "=r")
5434 (zero_extend:DI
5435 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5436 (match_operand:SI 2 "const248_operand" "n"))
5437 (match_operand:SI 3 "register_operand" "r"))
5438 (match_operand:SI 4 "immediate_operand" "i"))))]
5439 "TARGET_64BIT"
5440 "#"
5441 "&& reload_completed"
5442 [(set (match_dup 0)
5443 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5444 (match_dup 2))
5445 (match_dup 3))
5446 (match_dup 4)) 0)))]
5447 {
5448 operands[1] = gen_lowpart (Pmode, operands[1]);
5449 operands[3] = gen_lowpart (Pmode, operands[3]);
5450 operands[4] = gen_lowpart (Pmode, operands[4]);
5451 }
5452 [(set_attr "type" "lea")
5453 (set_attr "mode" "SI")])
5454
5455 (define_insn "*adddi_1_rex64"
5456 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5457 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5458 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5459 (clobber (reg:CC 17))]
5460 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5461 {
5462 switch (get_attr_type (insn))
5463 {
5464 case TYPE_LEA:
5465 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5466 return "lea{q}\t{%a2, %0|%0, %a2}";
5467
5468 case TYPE_INCDEC:
5469 if (! rtx_equal_p (operands[0], operands[1]))
5470 abort ();
5471 if (operands[2] == const1_rtx)
5472 return "inc{q}\t%0";
5473 else if (operands[2] == constm1_rtx)
5474 return "dec{q}\t%0";
5475 else
5476 abort ();
5477
5478 default:
5479 if (! rtx_equal_p (operands[0], operands[1]))
5480 abort ();
5481
5482 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5483 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5484 if (GET_CODE (operands[2]) == CONST_INT
5485 /* Avoid overflows. */
5486 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5487 && (INTVAL (operands[2]) == 128
5488 || (INTVAL (operands[2]) < 0
5489 && INTVAL (operands[2]) != -128)))
5490 {
5491 operands[2] = GEN_INT (-INTVAL (operands[2]));
5492 return "sub{q}\t{%2, %0|%0, %2}";
5493 }
5494 return "add{q}\t{%2, %0|%0, %2}";
5495 }
5496 }
5497 [(set (attr "type")
5498 (cond [(eq_attr "alternative" "2")
5499 (const_string "lea")
5500 ; Current assemblers are broken and do not allow @GOTOFF in
5501 ; ought but a memory context.
5502 (match_operand:DI 2 "pic_symbolic_operand" "")
5503 (const_string "lea")
5504 (match_operand:DI 2 "incdec_operand" "")
5505 (const_string "incdec")
5506 ]
5507 (const_string "alu")))
5508 (set_attr "mode" "DI")])
5509
5510 ;; Convert lea to the lea pattern to avoid flags dependency.
5511 (define_split
5512 [(set (match_operand:DI 0 "register_operand" "")
5513 (plus:DI (match_operand:DI 1 "register_operand" "")
5514 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5515 (clobber (reg:CC 17))]
5516 "TARGET_64BIT && reload_completed
5517 && true_regnum (operands[0]) != true_regnum (operands[1])"
5518 [(set (match_dup 0)
5519 (plus:DI (match_dup 1)
5520 (match_dup 2)))]
5521 "")
5522
5523 (define_insn "*adddi_2_rex64"
5524 [(set (reg 17)
5525 (compare
5526 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5527 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5528 (const_int 0)))
5529 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5530 (plus:DI (match_dup 1) (match_dup 2)))]
5531 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5532 && ix86_binary_operator_ok (PLUS, DImode, operands)
5533 /* Current assemblers are broken and do not allow @GOTOFF in
5534 ought but a memory context. */
5535 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5536 {
5537 switch (get_attr_type (insn))
5538 {
5539 case TYPE_INCDEC:
5540 if (! rtx_equal_p (operands[0], operands[1]))
5541 abort ();
5542 if (operands[2] == const1_rtx)
5543 return "inc{q}\t%0";
5544 else if (operands[2] == constm1_rtx)
5545 return "dec{q}\t%0";
5546 else
5547 abort ();
5548
5549 default:
5550 if (! rtx_equal_p (operands[0], operands[1]))
5551 abort ();
5552 /* ???? We ought to handle there the 32bit case too
5553 - do we need new constraint? */
5554 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5556 if (GET_CODE (operands[2]) == CONST_INT
5557 /* Avoid overflows. */
5558 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5559 && (INTVAL (operands[2]) == 128
5560 || (INTVAL (operands[2]) < 0
5561 && INTVAL (operands[2]) != -128)))
5562 {
5563 operands[2] = GEN_INT (-INTVAL (operands[2]));
5564 return "sub{q}\t{%2, %0|%0, %2}";
5565 }
5566 return "add{q}\t{%2, %0|%0, %2}";
5567 }
5568 }
5569 [(set (attr "type")
5570 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5571 (const_string "incdec")
5572 (const_string "alu")))
5573 (set_attr "mode" "DI")])
5574
5575 (define_insn "*adddi_3_rex64"
5576 [(set (reg 17)
5577 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5578 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5579 (clobber (match_scratch:DI 0 "=r"))]
5580 "TARGET_64BIT
5581 && ix86_match_ccmode (insn, CCZmode)
5582 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5583 /* Current assemblers are broken and do not allow @GOTOFF in
5584 ought but a memory context. */
5585 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5586 {
5587 switch (get_attr_type (insn))
5588 {
5589 case TYPE_INCDEC:
5590 if (! rtx_equal_p (operands[0], operands[1]))
5591 abort ();
5592 if (operands[2] == const1_rtx)
5593 return "inc{q}\t%0";
5594 else if (operands[2] == constm1_rtx)
5595 return "dec{q}\t%0";
5596 else
5597 abort ();
5598
5599 default:
5600 if (! rtx_equal_p (operands[0], operands[1]))
5601 abort ();
5602 /* ???? We ought to handle there the 32bit case too
5603 - do we need new constraint? */
5604 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5605 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5606 if (GET_CODE (operands[2]) == CONST_INT
5607 /* Avoid overflows. */
5608 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5609 && (INTVAL (operands[2]) == 128
5610 || (INTVAL (operands[2]) < 0
5611 && INTVAL (operands[2]) != -128)))
5612 {
5613 operands[2] = GEN_INT (-INTVAL (operands[2]));
5614 return "sub{q}\t{%2, %0|%0, %2}";
5615 }
5616 return "add{q}\t{%2, %0|%0, %2}";
5617 }
5618 }
5619 [(set (attr "type")
5620 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5621 (const_string "incdec")
5622 (const_string "alu")))
5623 (set_attr "mode" "DI")])
5624
5625 ; For comparisons against 1, -1 and 128, we may generate better code
5626 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5627 ; is matched then. We can't accept general immediate, because for
5628 ; case of overflows, the result is messed up.
5629 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5630 ; when negated.
5631 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5632 ; only for comparisons not depending on it.
5633 (define_insn "*adddi_4_rex64"
5634 [(set (reg 17)
5635 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5636 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5637 (clobber (match_scratch:DI 0 "=rm"))]
5638 "TARGET_64BIT
5639 && ix86_match_ccmode (insn, CCGCmode)"
5640 {
5641 switch (get_attr_type (insn))
5642 {
5643 case TYPE_INCDEC:
5644 if (operands[2] == constm1_rtx)
5645 return "inc{q}\t%0";
5646 else if (operands[2] == const1_rtx)
5647 return "dec{q}\t%0";
5648 else
5649 abort();
5650
5651 default:
5652 if (! rtx_equal_p (operands[0], operands[1]))
5653 abort ();
5654 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5655 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5656 if ((INTVAL (operands[2]) == -128
5657 || (INTVAL (operands[2]) > 0
5658 && INTVAL (operands[2]) != 128))
5659 /* Avoid overflows. */
5660 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5661 return "sub{q}\t{%2, %0|%0, %2}";
5662 operands[2] = GEN_INT (-INTVAL (operands[2]));
5663 return "add{q}\t{%2, %0|%0, %2}";
5664 }
5665 }
5666 [(set (attr "type")
5667 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5668 (const_string "incdec")
5669 (const_string "alu")))
5670 (set_attr "mode" "DI")])
5671
5672 (define_insn "*adddi_5_rex64"
5673 [(set (reg 17)
5674 (compare
5675 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5676 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5677 (const_int 0)))
5678 (clobber (match_scratch:DI 0 "=r"))]
5679 "TARGET_64BIT
5680 && ix86_match_ccmode (insn, CCGOCmode)
5681 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5682 /* Current assemblers are broken and do not allow @GOTOFF in
5683 ought but a memory context. */
5684 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5685 {
5686 switch (get_attr_type (insn))
5687 {
5688 case TYPE_INCDEC:
5689 if (! rtx_equal_p (operands[0], operands[1]))
5690 abort ();
5691 if (operands[2] == const1_rtx)
5692 return "inc{q}\t%0";
5693 else if (operands[2] == constm1_rtx)
5694 return "dec{q}\t%0";
5695 else
5696 abort();
5697
5698 default:
5699 if (! rtx_equal_p (operands[0], operands[1]))
5700 abort ();
5701 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5702 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5703 if (GET_CODE (operands[2]) == CONST_INT
5704 /* Avoid overflows. */
5705 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5706 && (INTVAL (operands[2]) == 128
5707 || (INTVAL (operands[2]) < 0
5708 && INTVAL (operands[2]) != -128)))
5709 {
5710 operands[2] = GEN_INT (-INTVAL (operands[2]));
5711 return "sub{q}\t{%2, %0|%0, %2}";
5712 }
5713 return "add{q}\t{%2, %0|%0, %2}";
5714 }
5715 }
5716 [(set (attr "type")
5717 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5718 (const_string "incdec")
5719 (const_string "alu")))
5720 (set_attr "mode" "DI")])
5721
5722
5723 (define_insn "*addsi_1"
5724 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5725 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5726 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5727 (clobber (reg:CC 17))]
5728 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5729 {
5730 switch (get_attr_type (insn))
5731 {
5732 case TYPE_LEA:
5733 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5734 return "lea{l}\t{%a2, %0|%0, %a2}";
5735
5736 case TYPE_INCDEC:
5737 if (! rtx_equal_p (operands[0], operands[1]))
5738 abort ();
5739 if (operands[2] == const1_rtx)
5740 return "inc{l}\t%0";
5741 else if (operands[2] == constm1_rtx)
5742 return "dec{l}\t%0";
5743 else
5744 abort();
5745
5746 default:
5747 if (! rtx_equal_p (operands[0], operands[1]))
5748 abort ();
5749
5750 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5752 if (GET_CODE (operands[2]) == CONST_INT
5753 && (INTVAL (operands[2]) == 128
5754 || (INTVAL (operands[2]) < 0
5755 && INTVAL (operands[2]) != -128)))
5756 {
5757 operands[2] = GEN_INT (-INTVAL (operands[2]));
5758 return "sub{l}\t{%2, %0|%0, %2}";
5759 }
5760 return "add{l}\t{%2, %0|%0, %2}";
5761 }
5762 }
5763 [(set (attr "type")
5764 (cond [(eq_attr "alternative" "2")
5765 (const_string "lea")
5766 ; Current assemblers are broken and do not allow @GOTOFF in
5767 ; ought but a memory context.
5768 (match_operand:SI 2 "pic_symbolic_operand" "")
5769 (const_string "lea")
5770 (match_operand:SI 2 "incdec_operand" "")
5771 (const_string "incdec")
5772 ]
5773 (const_string "alu")))
5774 (set_attr "mode" "SI")])
5775
5776 ;; Convert lea to the lea pattern to avoid flags dependency.
5777 (define_split
5778 [(set (match_operand 0 "register_operand" "")
5779 (plus (match_operand 1 "register_operand" "")
5780 (match_operand 2 "nonmemory_operand" "")))
5781 (clobber (reg:CC 17))]
5782 "reload_completed
5783 && true_regnum (operands[0]) != true_regnum (operands[1])"
5784 [(const_int 0)]
5785 {
5786 rtx pat;
5787 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5788 may confuse gen_lowpart. */
5789 if (GET_MODE (operands[0]) != Pmode)
5790 {
5791 operands[1] = gen_lowpart (Pmode, operands[1]);
5792 operands[2] = gen_lowpart (Pmode, operands[2]);
5793 }
5794 operands[0] = gen_lowpart (SImode, operands[0]);
5795 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5796 if (Pmode != SImode)
5797 pat = gen_rtx_SUBREG (SImode, pat, 0);
5798 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5799 DONE;
5800 })
5801
5802 ;; It may seem that nonimmediate operand is proper one for operand 1.
5803 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5804 ;; we take care in ix86_binary_operator_ok to not allow two memory
5805 ;; operands so proper swapping will be done in reload. This allow
5806 ;; patterns constructed from addsi_1 to match.
5807 (define_insn "addsi_1_zext"
5808 [(set (match_operand:DI 0 "register_operand" "=r,r")
5809 (zero_extend:DI
5810 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5811 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5812 (clobber (reg:CC 17))]
5813 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5814 {
5815 switch (get_attr_type (insn))
5816 {
5817 case TYPE_LEA:
5818 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5819 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5820
5821 case TYPE_INCDEC:
5822 if (operands[2] == const1_rtx)
5823 return "inc{l}\t%k0";
5824 else if (operands[2] == constm1_rtx)
5825 return "dec{l}\t%k0";
5826 else
5827 abort();
5828
5829 default:
5830 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5831 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5832 if (GET_CODE (operands[2]) == CONST_INT
5833 && (INTVAL (operands[2]) == 128
5834 || (INTVAL (operands[2]) < 0
5835 && INTVAL (operands[2]) != -128)))
5836 {
5837 operands[2] = GEN_INT (-INTVAL (operands[2]));
5838 return "sub{l}\t{%2, %k0|%k0, %2}";
5839 }
5840 return "add{l}\t{%2, %k0|%k0, %2}";
5841 }
5842 }
5843 [(set (attr "type")
5844 (cond [(eq_attr "alternative" "1")
5845 (const_string "lea")
5846 ; Current assemblers are broken and do not allow @GOTOFF in
5847 ; ought but a memory context.
5848 (match_operand:SI 2 "pic_symbolic_operand" "")
5849 (const_string "lea")
5850 (match_operand:SI 2 "incdec_operand" "")
5851 (const_string "incdec")
5852 ]
5853 (const_string "alu")))
5854 (set_attr "mode" "SI")])
5855
5856 ;; Convert lea to the lea pattern to avoid flags dependency.
5857 (define_split
5858 [(set (match_operand:DI 0 "register_operand" "")
5859 (zero_extend:DI
5860 (plus:SI (match_operand:SI 1 "register_operand" "")
5861 (match_operand:SI 2 "nonmemory_operand" ""))))
5862 (clobber (reg:CC 17))]
5863 "TARGET_64BIT && reload_completed
5864 && true_regnum (operands[0]) != true_regnum (operands[1])"
5865 [(set (match_dup 0)
5866 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5867 {
5868 operands[1] = gen_lowpart (Pmode, operands[1]);
5869 operands[2] = gen_lowpart (Pmode, operands[2]);
5870 })
5871
5872 (define_insn "*addsi_2"
5873 [(set (reg 17)
5874 (compare
5875 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5876 (match_operand:SI 2 "general_operand" "rmni,rni"))
5877 (const_int 0)))
5878 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5879 (plus:SI (match_dup 1) (match_dup 2)))]
5880 "ix86_match_ccmode (insn, CCGOCmode)
5881 && ix86_binary_operator_ok (PLUS, SImode, operands)
5882 /* Current assemblers are broken and do not allow @GOTOFF in
5883 ought but a memory context. */
5884 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5885 {
5886 switch (get_attr_type (insn))
5887 {
5888 case TYPE_INCDEC:
5889 if (! rtx_equal_p (operands[0], operands[1]))
5890 abort ();
5891 if (operands[2] == const1_rtx)
5892 return "inc{l}\t%0";
5893 else if (operands[2] == constm1_rtx)
5894 return "dec{l}\t%0";
5895 else
5896 abort();
5897
5898 default:
5899 if (! rtx_equal_p (operands[0], operands[1]))
5900 abort ();
5901 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5902 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5903 if (GET_CODE (operands[2]) == CONST_INT
5904 && (INTVAL (operands[2]) == 128
5905 || (INTVAL (operands[2]) < 0
5906 && INTVAL (operands[2]) != -128)))
5907 {
5908 operands[2] = GEN_INT (-INTVAL (operands[2]));
5909 return "sub{l}\t{%2, %0|%0, %2}";
5910 }
5911 return "add{l}\t{%2, %0|%0, %2}";
5912 }
5913 }
5914 [(set (attr "type")
5915 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5916 (const_string "incdec")
5917 (const_string "alu")))
5918 (set_attr "mode" "SI")])
5919
5920 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5921 (define_insn "*addsi_2_zext"
5922 [(set (reg 17)
5923 (compare
5924 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5925 (match_operand:SI 2 "general_operand" "rmni"))
5926 (const_int 0)))
5927 (set (match_operand:DI 0 "register_operand" "=r")
5928 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5929 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5930 && ix86_binary_operator_ok (PLUS, SImode, operands)
5931 /* Current assemblers are broken and do not allow @GOTOFF in
5932 ought but a memory context. */
5933 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5934 {
5935 switch (get_attr_type (insn))
5936 {
5937 case TYPE_INCDEC:
5938 if (operands[2] == const1_rtx)
5939 return "inc{l}\t%k0";
5940 else if (operands[2] == constm1_rtx)
5941 return "dec{l}\t%k0";
5942 else
5943 abort();
5944
5945 default:
5946 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5947 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5948 if (GET_CODE (operands[2]) == CONST_INT
5949 && (INTVAL (operands[2]) == 128
5950 || (INTVAL (operands[2]) < 0
5951 && INTVAL (operands[2]) != -128)))
5952 {
5953 operands[2] = GEN_INT (-INTVAL (operands[2]));
5954 return "sub{l}\t{%2, %k0|%k0, %2}";
5955 }
5956 return "add{l}\t{%2, %k0|%k0, %2}";
5957 }
5958 }
5959 [(set (attr "type")
5960 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5961 (const_string "incdec")
5962 (const_string "alu")))
5963 (set_attr "mode" "SI")])
5964
5965 (define_insn "*addsi_3"
5966 [(set (reg 17)
5967 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5968 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5969 (clobber (match_scratch:SI 0 "=r"))]
5970 "ix86_match_ccmode (insn, CCZmode)
5971 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5972 /* Current assemblers are broken and do not allow @GOTOFF in
5973 ought but a memory context. */
5974 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5975 {
5976 switch (get_attr_type (insn))
5977 {
5978 case TYPE_INCDEC:
5979 if (! rtx_equal_p (operands[0], operands[1]))
5980 abort ();
5981 if (operands[2] == const1_rtx)
5982 return "inc{l}\t%0";
5983 else if (operands[2] == constm1_rtx)
5984 return "dec{l}\t%0";
5985 else
5986 abort();
5987
5988 default:
5989 if (! rtx_equal_p (operands[0], operands[1]))
5990 abort ();
5991 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5992 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5993 if (GET_CODE (operands[2]) == CONST_INT
5994 && (INTVAL (operands[2]) == 128
5995 || (INTVAL (operands[2]) < 0
5996 && INTVAL (operands[2]) != -128)))
5997 {
5998 operands[2] = GEN_INT (-INTVAL (operands[2]));
5999 return "sub{l}\t{%2, %0|%0, %2}";
6000 }
6001 return "add{l}\t{%2, %0|%0, %2}";
6002 }
6003 }
6004 [(set (attr "type")
6005 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6006 (const_string "incdec")
6007 (const_string "alu")))
6008 (set_attr "mode" "SI")])
6009
6010 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6011 (define_insn "*addsi_3_zext"
6012 [(set (reg 17)
6013 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6014 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6015 (set (match_operand:DI 0 "register_operand" "=r")
6016 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6017 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6018 && ix86_binary_operator_ok (PLUS, SImode, operands)
6019 /* Current assemblers are broken and do not allow @GOTOFF in
6020 ought but a memory context. */
6021 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6022 {
6023 switch (get_attr_type (insn))
6024 {
6025 case TYPE_INCDEC:
6026 if (operands[2] == const1_rtx)
6027 return "inc{l}\t%k0";
6028 else if (operands[2] == constm1_rtx)
6029 return "dec{l}\t%k0";
6030 else
6031 abort();
6032
6033 default:
6034 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6036 if (GET_CODE (operands[2]) == CONST_INT
6037 && (INTVAL (operands[2]) == 128
6038 || (INTVAL (operands[2]) < 0
6039 && INTVAL (operands[2]) != -128)))
6040 {
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "sub{l}\t{%2, %k0|%k0, %2}";
6043 }
6044 return "add{l}\t{%2, %k0|%k0, %2}";
6045 }
6046 }
6047 [(set (attr "type")
6048 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6049 (const_string "incdec")
6050 (const_string "alu")))
6051 (set_attr "mode" "SI")])
6052
6053 ; For comparisons against 1, -1 and 128, we may generate better code
6054 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6055 ; is matched then. We can't accept general immediate, because for
6056 ; case of overflows, the result is messed up.
6057 ; This pattern also don't hold of 0x80000000, since the value overflows
6058 ; when negated.
6059 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6060 ; only for comparisons not depending on it.
6061 (define_insn "*addsi_4"
6062 [(set (reg 17)
6063 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6064 (match_operand:SI 2 "const_int_operand" "n")))
6065 (clobber (match_scratch:SI 0 "=rm"))]
6066 "ix86_match_ccmode (insn, CCGCmode)
6067 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6068 {
6069 switch (get_attr_type (insn))
6070 {
6071 case TYPE_INCDEC:
6072 if (operands[2] == constm1_rtx)
6073 return "inc{l}\t%0";
6074 else if (operands[2] == const1_rtx)
6075 return "dec{l}\t%0";
6076 else
6077 abort();
6078
6079 default:
6080 if (! rtx_equal_p (operands[0], operands[1]))
6081 abort ();
6082 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6083 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6084 if ((INTVAL (operands[2]) == -128
6085 || (INTVAL (operands[2]) > 0
6086 && INTVAL (operands[2]) != 128)))
6087 return "sub{l}\t{%2, %0|%0, %2}";
6088 operands[2] = GEN_INT (-INTVAL (operands[2]));
6089 return "add{l}\t{%2, %0|%0, %2}";
6090 }
6091 }
6092 [(set (attr "type")
6093 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6094 (const_string "incdec")
6095 (const_string "alu")))
6096 (set_attr "mode" "SI")])
6097
6098 (define_insn "*addsi_5"
6099 [(set (reg 17)
6100 (compare
6101 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6102 (match_operand:SI 2 "general_operand" "rmni"))
6103 (const_int 0)))
6104 (clobber (match_scratch:SI 0 "=r"))]
6105 "ix86_match_ccmode (insn, CCGOCmode)
6106 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6107 /* Current assemblers are broken and do not allow @GOTOFF in
6108 ought but a memory context. */
6109 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6110 {
6111 switch (get_attr_type (insn))
6112 {
6113 case TYPE_INCDEC:
6114 if (! rtx_equal_p (operands[0], operands[1]))
6115 abort ();
6116 if (operands[2] == const1_rtx)
6117 return "inc{l}\t%0";
6118 else if (operands[2] == constm1_rtx)
6119 return "dec{l}\t%0";
6120 else
6121 abort();
6122
6123 default:
6124 if (! rtx_equal_p (operands[0], operands[1]))
6125 abort ();
6126 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6127 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6128 if (GET_CODE (operands[2]) == CONST_INT
6129 && (INTVAL (operands[2]) == 128
6130 || (INTVAL (operands[2]) < 0
6131 && INTVAL (operands[2]) != -128)))
6132 {
6133 operands[2] = GEN_INT (-INTVAL (operands[2]));
6134 return "sub{l}\t{%2, %0|%0, %2}";
6135 }
6136 return "add{l}\t{%2, %0|%0, %2}";
6137 }
6138 }
6139 [(set (attr "type")
6140 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6141 (const_string "incdec")
6142 (const_string "alu")))
6143 (set_attr "mode" "SI")])
6144
6145 (define_expand "addhi3"
6146 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6147 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6148 (match_operand:HI 2 "general_operand" "")))
6149 (clobber (reg:CC 17))])]
6150 "TARGET_HIMODE_MATH"
6151 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6152
6153 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6154 ;; type optimizations enabled by define-splits. This is not important
6155 ;; for PII, and in fact harmful because of partial register stalls.
6156
6157 (define_insn "*addhi_1_lea"
6158 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6159 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6160 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6161 (clobber (reg:CC 17))]
6162 "!TARGET_PARTIAL_REG_STALL
6163 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6164 {
6165 switch (get_attr_type (insn))
6166 {
6167 case TYPE_LEA:
6168 return "#";
6169 case TYPE_INCDEC:
6170 if (operands[2] == const1_rtx)
6171 return "inc{w}\t%0";
6172 else if (operands[2] == constm1_rtx)
6173 return "dec{w}\t%0";
6174 abort();
6175
6176 default:
6177 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6178 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6179 if (GET_CODE (operands[2]) == CONST_INT
6180 && (INTVAL (operands[2]) == 128
6181 || (INTVAL (operands[2]) < 0
6182 && INTVAL (operands[2]) != -128)))
6183 {
6184 operands[2] = GEN_INT (-INTVAL (operands[2]));
6185 return "sub{w}\t{%2, %0|%0, %2}";
6186 }
6187 return "add{w}\t{%2, %0|%0, %2}";
6188 }
6189 }
6190 [(set (attr "type")
6191 (if_then_else (eq_attr "alternative" "2")
6192 (const_string "lea")
6193 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6194 (const_string "incdec")
6195 (const_string "alu"))))
6196 (set_attr "mode" "HI,HI,SI")])
6197
6198 (define_insn "*addhi_1"
6199 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6200 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6201 (match_operand:HI 2 "general_operand" "ri,rm")))
6202 (clobber (reg:CC 17))]
6203 "TARGET_PARTIAL_REG_STALL
6204 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6205 {
6206 switch (get_attr_type (insn))
6207 {
6208 case TYPE_INCDEC:
6209 if (operands[2] == const1_rtx)
6210 return "inc{w}\t%0";
6211 else if (operands[2] == constm1_rtx)
6212 return "dec{w}\t%0";
6213 abort();
6214
6215 default:
6216 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6217 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6218 if (GET_CODE (operands[2]) == CONST_INT
6219 && (INTVAL (operands[2]) == 128
6220 || (INTVAL (operands[2]) < 0
6221 && INTVAL (operands[2]) != -128)))
6222 {
6223 operands[2] = GEN_INT (-INTVAL (operands[2]));
6224 return "sub{w}\t{%2, %0|%0, %2}";
6225 }
6226 return "add{w}\t{%2, %0|%0, %2}";
6227 }
6228 }
6229 [(set (attr "type")
6230 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6231 (const_string "incdec")
6232 (const_string "alu")))
6233 (set_attr "mode" "HI")])
6234
6235 (define_insn "*addhi_2"
6236 [(set (reg 17)
6237 (compare
6238 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6239 (match_operand:HI 2 "general_operand" "rmni,rni"))
6240 (const_int 0)))
6241 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6242 (plus:HI (match_dup 1) (match_dup 2)))]
6243 "ix86_match_ccmode (insn, CCGOCmode)
6244 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6245 {
6246 switch (get_attr_type (insn))
6247 {
6248 case TYPE_INCDEC:
6249 if (operands[2] == const1_rtx)
6250 return "inc{w}\t%0";
6251 else if (operands[2] == constm1_rtx)
6252 return "dec{w}\t%0";
6253 abort();
6254
6255 default:
6256 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6257 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6258 if (GET_CODE (operands[2]) == CONST_INT
6259 && (INTVAL (operands[2]) == 128
6260 || (INTVAL (operands[2]) < 0
6261 && INTVAL (operands[2]) != -128)))
6262 {
6263 operands[2] = GEN_INT (-INTVAL (operands[2]));
6264 return "sub{w}\t{%2, %0|%0, %2}";
6265 }
6266 return "add{w}\t{%2, %0|%0, %2}";
6267 }
6268 }
6269 [(set (attr "type")
6270 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set_attr "mode" "HI")])
6274
6275 (define_insn "*addhi_3"
6276 [(set (reg 17)
6277 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6278 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6279 (clobber (match_scratch:HI 0 "=r"))]
6280 "ix86_match_ccmode (insn, CCZmode)
6281 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6282 {
6283 switch (get_attr_type (insn))
6284 {
6285 case TYPE_INCDEC:
6286 if (operands[2] == const1_rtx)
6287 return "inc{w}\t%0";
6288 else if (operands[2] == constm1_rtx)
6289 return "dec{w}\t%0";
6290 abort();
6291
6292 default:
6293 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6294 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6295 if (GET_CODE (operands[2]) == CONST_INT
6296 && (INTVAL (operands[2]) == 128
6297 || (INTVAL (operands[2]) < 0
6298 && INTVAL (operands[2]) != -128)))
6299 {
6300 operands[2] = GEN_INT (-INTVAL (operands[2]));
6301 return "sub{w}\t{%2, %0|%0, %2}";
6302 }
6303 return "add{w}\t{%2, %0|%0, %2}";
6304 }
6305 }
6306 [(set (attr "type")
6307 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6308 (const_string "incdec")
6309 (const_string "alu")))
6310 (set_attr "mode" "HI")])
6311
6312 ; See comments above addsi_3_imm for details.
6313 (define_insn "*addhi_4"
6314 [(set (reg 17)
6315 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6316 (match_operand:HI 2 "const_int_operand" "n")))
6317 (clobber (match_scratch:HI 0 "=rm"))]
6318 "ix86_match_ccmode (insn, CCGCmode)
6319 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6320 {
6321 switch (get_attr_type (insn))
6322 {
6323 case TYPE_INCDEC:
6324 if (operands[2] == constm1_rtx)
6325 return "inc{w}\t%0";
6326 else if (operands[2] == const1_rtx)
6327 return "dec{w}\t%0";
6328 else
6329 abort();
6330
6331 default:
6332 if (! rtx_equal_p (operands[0], operands[1]))
6333 abort ();
6334 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6335 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6336 if ((INTVAL (operands[2]) == -128
6337 || (INTVAL (operands[2]) > 0
6338 && INTVAL (operands[2]) != 128)))
6339 return "sub{w}\t{%2, %0|%0, %2}";
6340 operands[2] = GEN_INT (-INTVAL (operands[2]));
6341 return "add{w}\t{%2, %0|%0, %2}";
6342 }
6343 }
6344 [(set (attr "type")
6345 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6346 (const_string "incdec")
6347 (const_string "alu")))
6348 (set_attr "mode" "SI")])
6349
6350
6351 (define_insn "*addhi_5"
6352 [(set (reg 17)
6353 (compare
6354 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6355 (match_operand:HI 2 "general_operand" "rmni"))
6356 (const_int 0)))
6357 (clobber (match_scratch:HI 0 "=r"))]
6358 "ix86_match_ccmode (insn, CCGOCmode)
6359 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6360 {
6361 switch (get_attr_type (insn))
6362 {
6363 case TYPE_INCDEC:
6364 if (operands[2] == const1_rtx)
6365 return "inc{w}\t%0";
6366 else if (operands[2] == constm1_rtx)
6367 return "dec{w}\t%0";
6368 abort();
6369
6370 default:
6371 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6372 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6373 if (GET_CODE (operands[2]) == CONST_INT
6374 && (INTVAL (operands[2]) == 128
6375 || (INTVAL (operands[2]) < 0
6376 && INTVAL (operands[2]) != -128)))
6377 {
6378 operands[2] = GEN_INT (-INTVAL (operands[2]));
6379 return "sub{w}\t{%2, %0|%0, %2}";
6380 }
6381 return "add{w}\t{%2, %0|%0, %2}";
6382 }
6383 }
6384 [(set (attr "type")
6385 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6386 (const_string "incdec")
6387 (const_string "alu")))
6388 (set_attr "mode" "HI")])
6389
6390 (define_expand "addqi3"
6391 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6392 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6393 (match_operand:QI 2 "general_operand" "")))
6394 (clobber (reg:CC 17))])]
6395 "TARGET_QIMODE_MATH"
6396 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6397
6398 ;; %%% Potential partial reg stall on alternative 2. What to do?
6399 (define_insn "*addqi_1_lea"
6400 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6401 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6402 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6403 (clobber (reg:CC 17))]
6404 "!TARGET_PARTIAL_REG_STALL
6405 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6406 {
6407 int widen = (which_alternative == 2);
6408 switch (get_attr_type (insn))
6409 {
6410 case TYPE_LEA:
6411 return "#";
6412 case TYPE_INCDEC:
6413 if (operands[2] == const1_rtx)
6414 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6415 else if (operands[2] == constm1_rtx)
6416 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6417 abort();
6418
6419 default:
6420 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6421 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6422 if (GET_CODE (operands[2]) == CONST_INT
6423 && (INTVAL (operands[2]) == 128
6424 || (INTVAL (operands[2]) < 0
6425 && INTVAL (operands[2]) != -128)))
6426 {
6427 operands[2] = GEN_INT (-INTVAL (operands[2]));
6428 if (widen)
6429 return "sub{l}\t{%2, %k0|%k0, %2}";
6430 else
6431 return "sub{b}\t{%2, %0|%0, %2}";
6432 }
6433 if (widen)
6434 return "add{l}\t{%k2, %k0|%k0, %k2}";
6435 else
6436 return "add{b}\t{%2, %0|%0, %2}";
6437 }
6438 }
6439 [(set (attr "type")
6440 (if_then_else (eq_attr "alternative" "3")
6441 (const_string "lea")
6442 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6443 (const_string "incdec")
6444 (const_string "alu"))))
6445 (set_attr "mode" "QI,QI,SI,SI")])
6446
6447 (define_insn "*addqi_1"
6448 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6449 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6450 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6451 (clobber (reg:CC 17))]
6452 "TARGET_PARTIAL_REG_STALL
6453 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6454 {
6455 int widen = (which_alternative == 2);
6456 switch (get_attr_type (insn))
6457 {
6458 case TYPE_INCDEC:
6459 if (operands[2] == const1_rtx)
6460 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6461 else if (operands[2] == constm1_rtx)
6462 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6463 abort();
6464
6465 default:
6466 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6467 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6468 if (GET_CODE (operands[2]) == CONST_INT
6469 && (INTVAL (operands[2]) == 128
6470 || (INTVAL (operands[2]) < 0
6471 && INTVAL (operands[2]) != -128)))
6472 {
6473 operands[2] = GEN_INT (-INTVAL (operands[2]));
6474 if (widen)
6475 return "sub{l}\t{%2, %k0|%k0, %2}";
6476 else
6477 return "sub{b}\t{%2, %0|%0, %2}";
6478 }
6479 if (widen)
6480 return "add{l}\t{%k2, %k0|%k0, %k2}";
6481 else
6482 return "add{b}\t{%2, %0|%0, %2}";
6483 }
6484 }
6485 [(set (attr "type")
6486 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6487 (const_string "incdec")
6488 (const_string "alu")))
6489 (set_attr "mode" "QI,QI,SI")])
6490
6491 (define_insn "*addqi_1_slp"
6492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6493 (plus:QI (match_dup 0)
6494 (match_operand:QI 1 "general_operand" "qn,qnm")))
6495 (clobber (reg:CC 17))]
6496 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6497 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6498 {
6499 switch (get_attr_type (insn))
6500 {
6501 case TYPE_INCDEC:
6502 if (operands[1] == const1_rtx)
6503 return "inc{b}\t%0";
6504 else if (operands[1] == constm1_rtx)
6505 return "dec{b}\t%0";
6506 abort();
6507
6508 default:
6509 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6510 if (GET_CODE (operands[1]) == CONST_INT
6511 && INTVAL (operands[1]) < 0)
6512 {
6513 operands[2] = GEN_INT (-INTVAL (operands[2]));
6514 return "sub{b}\t{%1, %0|%0, %1}";
6515 }
6516 return "add{b}\t{%1, %0|%0, %1}";
6517 }
6518 }
6519 [(set (attr "type")
6520 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521 (const_string "incdec")
6522 (const_string "alu1")))
6523 (set_attr "mode" "QI")])
6524
6525 (define_insn "*addqi_2"
6526 [(set (reg 17)
6527 (compare
6528 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6529 (match_operand:QI 2 "general_operand" "qmni,qni"))
6530 (const_int 0)))
6531 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6532 (plus:QI (match_dup 1) (match_dup 2)))]
6533 "ix86_match_ccmode (insn, CCGOCmode)
6534 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6535 {
6536 switch (get_attr_type (insn))
6537 {
6538 case TYPE_INCDEC:
6539 if (operands[2] == const1_rtx)
6540 return "inc{b}\t%0";
6541 else if (operands[2] == constm1_rtx
6542 || (GET_CODE (operands[2]) == CONST_INT
6543 && INTVAL (operands[2]) == 255))
6544 return "dec{b}\t%0";
6545 abort();
6546
6547 default:
6548 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6549 if (GET_CODE (operands[2]) == CONST_INT
6550 && INTVAL (operands[2]) < 0)
6551 {
6552 operands[2] = GEN_INT (-INTVAL (operands[2]));
6553 return "sub{b}\t{%2, %0|%0, %2}";
6554 }
6555 return "add{b}\t{%2, %0|%0, %2}";
6556 }
6557 }
6558 [(set (attr "type")
6559 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6560 (const_string "incdec")
6561 (const_string "alu")))
6562 (set_attr "mode" "QI")])
6563
6564 (define_insn "*addqi_3"
6565 [(set (reg 17)
6566 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6567 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6568 (clobber (match_scratch:QI 0 "=q"))]
6569 "ix86_match_ccmode (insn, CCZmode)
6570 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6571 {
6572 switch (get_attr_type (insn))
6573 {
6574 case TYPE_INCDEC:
6575 if (operands[2] == const1_rtx)
6576 return "inc{b}\t%0";
6577 else if (operands[2] == constm1_rtx
6578 || (GET_CODE (operands[2]) == CONST_INT
6579 && INTVAL (operands[2]) == 255))
6580 return "dec{b}\t%0";
6581 abort();
6582
6583 default:
6584 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6585 if (GET_CODE (operands[2]) == CONST_INT
6586 && INTVAL (operands[2]) < 0)
6587 {
6588 operands[2] = GEN_INT (-INTVAL (operands[2]));
6589 return "sub{b}\t{%2, %0|%0, %2}";
6590 }
6591 return "add{b}\t{%2, %0|%0, %2}";
6592 }
6593 }
6594 [(set (attr "type")
6595 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6596 (const_string "incdec")
6597 (const_string "alu")))
6598 (set_attr "mode" "QI")])
6599
6600 ; See comments above addsi_3_imm for details.
6601 (define_insn "*addqi_4"
6602 [(set (reg 17)
6603 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6604 (match_operand:QI 2 "const_int_operand" "n")))
6605 (clobber (match_scratch:QI 0 "=qm"))]
6606 "ix86_match_ccmode (insn, CCGCmode)
6607 && (INTVAL (operands[2]) & 0xff) != 0x80"
6608 {
6609 switch (get_attr_type (insn))
6610 {
6611 case TYPE_INCDEC:
6612 if (operands[2] == constm1_rtx
6613 || (GET_CODE (operands[2]) == CONST_INT
6614 && INTVAL (operands[2]) == 255))
6615 return "inc{b}\t%0";
6616 else if (operands[2] == const1_rtx)
6617 return "dec{b}\t%0";
6618 else
6619 abort();
6620
6621 default:
6622 if (! rtx_equal_p (operands[0], operands[1]))
6623 abort ();
6624 if (INTVAL (operands[2]) < 0)
6625 {
6626 operands[2] = GEN_INT (-INTVAL (operands[2]));
6627 return "add{b}\t{%2, %0|%0, %2}";
6628 }
6629 return "sub{b}\t{%2, %0|%0, %2}";
6630 }
6631 }
6632 [(set (attr "type")
6633 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6634 (const_string "incdec")
6635 (const_string "alu")))
6636 (set_attr "mode" "QI")])
6637
6638
6639 (define_insn "*addqi_5"
6640 [(set (reg 17)
6641 (compare
6642 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6643 (match_operand:QI 2 "general_operand" "qmni"))
6644 (const_int 0)))
6645 (clobber (match_scratch:QI 0 "=q"))]
6646 "ix86_match_ccmode (insn, CCGOCmode)
6647 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6648 {
6649 switch (get_attr_type (insn))
6650 {
6651 case TYPE_INCDEC:
6652 if (operands[2] == const1_rtx)
6653 return "inc{b}\t%0";
6654 else if (operands[2] == constm1_rtx
6655 || (GET_CODE (operands[2]) == CONST_INT
6656 && INTVAL (operands[2]) == 255))
6657 return "dec{b}\t%0";
6658 abort();
6659
6660 default:
6661 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6662 if (GET_CODE (operands[2]) == CONST_INT
6663 && INTVAL (operands[2]) < 0)
6664 {
6665 operands[2] = GEN_INT (-INTVAL (operands[2]));
6666 return "sub{b}\t{%2, %0|%0, %2}";
6667 }
6668 return "add{b}\t{%2, %0|%0, %2}";
6669 }
6670 }
6671 [(set (attr "type")
6672 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6673 (const_string "incdec")
6674 (const_string "alu")))
6675 (set_attr "mode" "QI")])
6676
6677
6678 (define_insn "addqi_ext_1"
6679 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6680 (const_int 8)
6681 (const_int 8))
6682 (plus:SI
6683 (zero_extract:SI
6684 (match_operand 1 "ext_register_operand" "0")
6685 (const_int 8)
6686 (const_int 8))
6687 (match_operand:QI 2 "general_operand" "Qmn")))
6688 (clobber (reg:CC 17))]
6689 "!TARGET_64BIT"
6690 {
6691 switch (get_attr_type (insn))
6692 {
6693 case TYPE_INCDEC:
6694 if (operands[2] == const1_rtx)
6695 return "inc{b}\t%h0";
6696 else if (operands[2] == constm1_rtx
6697 || (GET_CODE (operands[2]) == CONST_INT
6698 && INTVAL (operands[2]) == 255))
6699 return "dec{b}\t%h0";
6700 abort();
6701
6702 default:
6703 return "add{b}\t{%2, %h0|%h0, %2}";
6704 }
6705 }
6706 [(set (attr "type")
6707 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6708 (const_string "incdec")
6709 (const_string "alu")))
6710 (set_attr "mode" "QI")])
6711
6712 (define_insn "*addqi_ext_1_rex64"
6713 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6714 (const_int 8)
6715 (const_int 8))
6716 (plus:SI
6717 (zero_extract:SI
6718 (match_operand 1 "ext_register_operand" "0")
6719 (const_int 8)
6720 (const_int 8))
6721 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6722 (clobber (reg:CC 17))]
6723 "TARGET_64BIT"
6724 {
6725 switch (get_attr_type (insn))
6726 {
6727 case TYPE_INCDEC:
6728 if (operands[2] == const1_rtx)
6729 return "inc{b}\t%h0";
6730 else if (operands[2] == constm1_rtx
6731 || (GET_CODE (operands[2]) == CONST_INT
6732 && INTVAL (operands[2]) == 255))
6733 return "dec{b}\t%h0";
6734 abort();
6735
6736 default:
6737 return "add{b}\t{%2, %h0|%h0, %2}";
6738 }
6739 }
6740 [(set (attr "type")
6741 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6742 (const_string "incdec")
6743 (const_string "alu")))
6744 (set_attr "mode" "QI")])
6745
6746 (define_insn "*addqi_ext_2"
6747 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6748 (const_int 8)
6749 (const_int 8))
6750 (plus:SI
6751 (zero_extract:SI
6752 (match_operand 1 "ext_register_operand" "%0")
6753 (const_int 8)
6754 (const_int 8))
6755 (zero_extract:SI
6756 (match_operand 2 "ext_register_operand" "Q")
6757 (const_int 8)
6758 (const_int 8))))
6759 (clobber (reg:CC 17))]
6760 ""
6761 "add{b}\t{%h2, %h0|%h0, %h2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "mode" "QI")])
6764
6765 ;; The patterns that match these are at the end of this file.
6766
6767 (define_expand "addxf3"
6768 [(set (match_operand:XF 0 "register_operand" "")
6769 (plus:XF (match_operand:XF 1 "register_operand" "")
6770 (match_operand:XF 2 "register_operand" "")))]
6771 "!TARGET_64BIT && TARGET_80387"
6772 "")
6773
6774 (define_expand "addtf3"
6775 [(set (match_operand:TF 0 "register_operand" "")
6776 (plus:TF (match_operand:TF 1 "register_operand" "")
6777 (match_operand:TF 2 "register_operand" "")))]
6778 "TARGET_80387"
6779 "")
6780
6781 (define_expand "adddf3"
6782 [(set (match_operand:DF 0 "register_operand" "")
6783 (plus:DF (match_operand:DF 1 "register_operand" "")
6784 (match_operand:DF 2 "nonimmediate_operand" "")))]
6785 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6786 "")
6787
6788 (define_expand "addsf3"
6789 [(set (match_operand:SF 0 "register_operand" "")
6790 (plus:SF (match_operand:SF 1 "register_operand" "")
6791 (match_operand:SF 2 "nonimmediate_operand" "")))]
6792 "TARGET_80387 || TARGET_SSE_MATH"
6793 "")
6794 \f
6795 ;; Subtract instructions
6796
6797 ;; %%% splits for subsidi3
6798
6799 (define_expand "subdi3"
6800 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6801 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6802 (match_operand:DI 2 "x86_64_general_operand" "")))
6803 (clobber (reg:CC 17))])]
6804 ""
6805 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6806
6807 (define_insn "*subdi3_1"
6808 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6809 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6810 (match_operand:DI 2 "general_operand" "roiF,riF")))
6811 (clobber (reg:CC 17))]
6812 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6813 "#")
6814
6815 (define_split
6816 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6817 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6818 (match_operand:DI 2 "general_operand" "")))
6819 (clobber (reg:CC 17))]
6820 "!TARGET_64BIT && reload_completed"
6821 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6822 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6823 (parallel [(set (match_dup 3)
6824 (minus:SI (match_dup 4)
6825 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6826 (match_dup 5))))
6827 (clobber (reg:CC 17))])]
6828 "split_di (operands+0, 1, operands+0, operands+3);
6829 split_di (operands+1, 1, operands+1, operands+4);
6830 split_di (operands+2, 1, operands+2, operands+5);")
6831
6832 (define_insn "subdi3_carry_rex64"
6833 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6834 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6835 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6836 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6837 (clobber (reg:CC 17))]
6838 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6839 "sbb{q}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "pent_pair" "pu")
6842 (set_attr "ppro_uops" "few")
6843 (set_attr "mode" "DI")])
6844
6845 (define_insn "*subdi_1_rex64"
6846 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6847 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6848 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6849 (clobber (reg:CC 17))]
6850 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6851 "sub{q}\t{%2, %0|%0, %2}"
6852 [(set_attr "type" "alu")
6853 (set_attr "mode" "DI")])
6854
6855 (define_insn "*subdi_2_rex64"
6856 [(set (reg 17)
6857 (compare
6858 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6859 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6860 (const_int 0)))
6861 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6862 (minus:DI (match_dup 1) (match_dup 2)))]
6863 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6864 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6865 "sub{q}\t{%2, %0|%0, %2}"
6866 [(set_attr "type" "alu")
6867 (set_attr "mode" "DI")])
6868
6869 (define_insn "*subdi_3_rex63"
6870 [(set (reg 17)
6871 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6872 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6873 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6874 (minus:DI (match_dup 1) (match_dup 2)))]
6875 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6876 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6877 "sub{q}\t{%2, %0|%0, %2}"
6878 [(set_attr "type" "alu")
6879 (set_attr "mode" "DI")])
6880
6881 (define_insn "subqi3_carry"
6882 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6883 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6884 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6885 (match_operand:QI 2 "general_operand" "ri,rm"))))
6886 (clobber (reg:CC 17))]
6887 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6888 "sbb{b}\t{%2, %0|%0, %2}"
6889 [(set_attr "type" "alu")
6890 (set_attr "pent_pair" "pu")
6891 (set_attr "ppro_uops" "few")
6892 (set_attr "mode" "QI")])
6893
6894 (define_insn "subhi3_carry"
6895 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6896 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6897 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6898 (match_operand:HI 2 "general_operand" "ri,rm"))))
6899 (clobber (reg:CC 17))]
6900 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6901 "sbb{w}\t{%2, %0|%0, %2}"
6902 [(set_attr "type" "alu")
6903 (set_attr "pent_pair" "pu")
6904 (set_attr "ppro_uops" "few")
6905 (set_attr "mode" "HI")])
6906
6907 (define_insn "subsi3_carry"
6908 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6909 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6910 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6911 (match_operand:SI 2 "general_operand" "ri,rm"))))
6912 (clobber (reg:CC 17))]
6913 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6914 "sbb{l}\t{%2, %0|%0, %2}"
6915 [(set_attr "type" "alu")
6916 (set_attr "pent_pair" "pu")
6917 (set_attr "ppro_uops" "few")
6918 (set_attr "mode" "SI")])
6919
6920 (define_insn "subsi3_carry_zext"
6921 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6922 (zero_extend:DI
6923 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6924 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6925 (match_operand:SI 2 "general_operand" "ri,rm")))))
6926 (clobber (reg:CC 17))]
6927 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6928 "sbb{l}\t{%2, %k0|%k0, %2}"
6929 [(set_attr "type" "alu")
6930 (set_attr "pent_pair" "pu")
6931 (set_attr "ppro_uops" "few")
6932 (set_attr "mode" "SI")])
6933
6934 (define_expand "subsi3"
6935 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6936 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6937 (match_operand:SI 2 "general_operand" "")))
6938 (clobber (reg:CC 17))])]
6939 ""
6940 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6941
6942 (define_insn "*subsi_1"
6943 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6944 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6945 (match_operand:SI 2 "general_operand" "ri,rm")))
6946 (clobber (reg:CC 17))]
6947 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6948 "sub{l}\t{%2, %0|%0, %2}"
6949 [(set_attr "type" "alu")
6950 (set_attr "mode" "SI")])
6951
6952 (define_insn "*subsi_1_zext"
6953 [(set (match_operand:DI 0 "register_operand" "=r")
6954 (zero_extend:DI
6955 (minus:SI (match_operand:SI 1 "register_operand" "0")
6956 (match_operand:SI 2 "general_operand" "rim"))))
6957 (clobber (reg:CC 17))]
6958 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6959 "sub{l}\t{%2, %k0|%k0, %2}"
6960 [(set_attr "type" "alu")
6961 (set_attr "mode" "SI")])
6962
6963 (define_insn "*subsi_2"
6964 [(set (reg 17)
6965 (compare
6966 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6967 (match_operand:SI 2 "general_operand" "ri,rm"))
6968 (const_int 0)))
6969 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6970 (minus:SI (match_dup 1) (match_dup 2)))]
6971 "ix86_match_ccmode (insn, CCGOCmode)
6972 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6973 "sub{l}\t{%2, %0|%0, %2}"
6974 [(set_attr "type" "alu")
6975 (set_attr "mode" "SI")])
6976
6977 (define_insn "*subsi_2_zext"
6978 [(set (reg 17)
6979 (compare
6980 (minus:SI (match_operand:SI 1 "register_operand" "0")
6981 (match_operand:SI 2 "general_operand" "rim"))
6982 (const_int 0)))
6983 (set (match_operand:DI 0 "register_operand" "=r")
6984 (zero_extend:DI
6985 (minus:SI (match_dup 1)
6986 (match_dup 2))))]
6987 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6988 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6989 "sub{l}\t{%2, %k0|%k0, %2}"
6990 [(set_attr "type" "alu")
6991 (set_attr "mode" "SI")])
6992
6993 (define_insn "*subsi_3"
6994 [(set (reg 17)
6995 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6996 (match_operand:SI 2 "general_operand" "ri,rm")))
6997 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6998 (minus:SI (match_dup 1) (match_dup 2)))]
6999 "ix86_match_ccmode (insn, CCmode)
7000 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7001 "sub{l}\t{%2, %0|%0, %2}"
7002 [(set_attr "type" "alu")
7003 (set_attr "mode" "SI")])
7004
7005 (define_insn "*subsi_3_zext"
7006 [(set (reg 17)
7007 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7008 (match_operand:SI 2 "general_operand" "rim")))
7009 (set (match_operand:DI 0 "register_operand" "=r")
7010 (zero_extend:DI
7011 (minus:SI (match_dup 1)
7012 (match_dup 2))))]
7013 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7014 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7015 "sub{q}\t{%2, %0|%0, %2}"
7016 [(set_attr "type" "alu")
7017 (set_attr "mode" "DI")])
7018
7019 (define_expand "subhi3"
7020 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7021 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7022 (match_operand:HI 2 "general_operand" "")))
7023 (clobber (reg:CC 17))])]
7024 "TARGET_HIMODE_MATH"
7025 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7026
7027 (define_insn "*subhi_1"
7028 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7029 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7030 (match_operand:HI 2 "general_operand" "ri,rm")))
7031 (clobber (reg:CC 17))]
7032 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7033 "sub{w}\t{%2, %0|%0, %2}"
7034 [(set_attr "type" "alu")
7035 (set_attr "mode" "HI")])
7036
7037 (define_insn "*subhi_2"
7038 [(set (reg 17)
7039 (compare
7040 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7041 (match_operand:HI 2 "general_operand" "ri,rm"))
7042 (const_int 0)))
7043 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7044 (minus:HI (match_dup 1) (match_dup 2)))]
7045 "ix86_match_ccmode (insn, CCGOCmode)
7046 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7047 "sub{w}\t{%2, %0|%0, %2}"
7048 [(set_attr "type" "alu")
7049 (set_attr "mode" "HI")])
7050
7051 (define_insn "*subhi_3"
7052 [(set (reg 17)
7053 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7054 (match_operand:HI 2 "general_operand" "ri,rm")))
7055 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7056 (minus:HI (match_dup 1) (match_dup 2)))]
7057 "ix86_match_ccmode (insn, CCmode)
7058 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7059 "sub{w}\t{%2, %0|%0, %2}"
7060 [(set_attr "type" "alu")
7061 (set_attr "mode" "HI")])
7062
7063 (define_expand "subqi3"
7064 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7065 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7066 (match_operand:QI 2 "general_operand" "")))
7067 (clobber (reg:CC 17))])]
7068 "TARGET_QIMODE_MATH"
7069 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7070
7071 (define_insn "*subqi_1"
7072 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7073 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7074 (match_operand:QI 2 "general_operand" "qn,qmn")))
7075 (clobber (reg:CC 17))]
7076 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7077 "sub{b}\t{%2, %0|%0, %2}"
7078 [(set_attr "type" "alu")
7079 (set_attr "mode" "QI")])
7080
7081 (define_insn "*subqi_1_slp"
7082 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7083 (minus:QI (match_dup 0)
7084 (match_operand:QI 1 "general_operand" "qn,qmn")))
7085 (clobber (reg:CC 17))]
7086 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7087 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7088 "sub{b}\t{%1, %0|%0, %1}"
7089 [(set_attr "type" "alu1")
7090 (set_attr "mode" "QI")])
7091
7092 (define_insn "*subqi_2"
7093 [(set (reg 17)
7094 (compare
7095 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7096 (match_operand:QI 2 "general_operand" "qi,qm"))
7097 (const_int 0)))
7098 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7099 (minus:HI (match_dup 1) (match_dup 2)))]
7100 "ix86_match_ccmode (insn, CCGOCmode)
7101 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7102 "sub{b}\t{%2, %0|%0, %2}"
7103 [(set_attr "type" "alu")
7104 (set_attr "mode" "QI")])
7105
7106 (define_insn "*subqi_3"
7107 [(set (reg 17)
7108 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7109 (match_operand:QI 2 "general_operand" "qi,qm")))
7110 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7111 (minus:HI (match_dup 1) (match_dup 2)))]
7112 "ix86_match_ccmode (insn, CCmode)
7113 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7114 "sub{b}\t{%2, %0|%0, %2}"
7115 [(set_attr "type" "alu")
7116 (set_attr "mode" "QI")])
7117
7118 ;; The patterns that match these are at the end of this file.
7119
7120 (define_expand "subxf3"
7121 [(set (match_operand:XF 0 "register_operand" "")
7122 (minus:XF (match_operand:XF 1 "register_operand" "")
7123 (match_operand:XF 2 "register_operand" "")))]
7124 "!TARGET_64BIT && TARGET_80387"
7125 "")
7126
7127 (define_expand "subtf3"
7128 [(set (match_operand:TF 0 "register_operand" "")
7129 (minus:TF (match_operand:TF 1 "register_operand" "")
7130 (match_operand:TF 2 "register_operand" "")))]
7131 "TARGET_80387"
7132 "")
7133
7134 (define_expand "subdf3"
7135 [(set (match_operand:DF 0 "register_operand" "")
7136 (minus:DF (match_operand:DF 1 "register_operand" "")
7137 (match_operand:DF 2 "nonimmediate_operand" "")))]
7138 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7139 "")
7140
7141 (define_expand "subsf3"
7142 [(set (match_operand:SF 0 "register_operand" "")
7143 (minus:SF (match_operand:SF 1 "register_operand" "")
7144 (match_operand:SF 2 "nonimmediate_operand" "")))]
7145 "TARGET_80387 || TARGET_SSE_MATH"
7146 "")
7147 \f
7148 ;; Multiply instructions
7149
7150 (define_expand "muldi3"
7151 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7152 (mult:DI (match_operand:DI 1 "register_operand" "")
7153 (match_operand:DI 2 "x86_64_general_operand" "")))
7154 (clobber (reg:CC 17))])]
7155 "TARGET_64BIT"
7156 "")
7157
7158 (define_insn "*muldi3_1_rex64"
7159 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7160 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7161 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7162 (clobber (reg:CC 17))]
7163 "TARGET_64BIT
7164 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7165 "@
7166 imul{q}\t{%2, %1, %0|%0, %1, %2}
7167 imul{q}\t{%2, %1, %0|%0, %1, %2}
7168 imul{q}\t{%2, %0|%0, %2}"
7169 [(set_attr "type" "imul")
7170 (set_attr "prefix_0f" "0,0,1")
7171 (set (attr "athlon_decode")
7172 (cond [(eq_attr "cpu" "athlon")
7173 (const_string "vector")
7174 (eq_attr "alternative" "1")
7175 (const_string "vector")
7176 (and (eq_attr "alternative" "2")
7177 (match_operand 1 "memory_operand" ""))
7178 (const_string "vector")]
7179 (const_string "direct")))
7180 (set_attr "mode" "DI")])
7181
7182 (define_expand "mulsi3"
7183 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7184 (mult:SI (match_operand:SI 1 "register_operand" "")
7185 (match_operand:SI 2 "general_operand" "")))
7186 (clobber (reg:CC 17))])]
7187 ""
7188 "")
7189
7190 (define_insn "*mulsi3_1"
7191 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7192 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7193 (match_operand:SI 2 "general_operand" "K,i,mr")))
7194 (clobber (reg:CC 17))]
7195 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7196 "@
7197 imul{l}\t{%2, %1, %0|%0, %1, %2}
7198 imul{l}\t{%2, %1, %0|%0, %1, %2}
7199 imul{l}\t{%2, %0|%0, %2}"
7200 [(set_attr "type" "imul")
7201 (set_attr "prefix_0f" "0,0,1")
7202 (set (attr "athlon_decode")
7203 (cond [(eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (eq_attr "alternative" "1")
7206 (const_string "vector")
7207 (and (eq_attr "alternative" "2")
7208 (match_operand 1 "memory_operand" ""))
7209 (const_string "vector")]
7210 (const_string "direct")))
7211 (set_attr "mode" "SI")])
7212
7213 (define_insn "*mulsi3_1_zext"
7214 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7215 (zero_extend:DI
7216 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7217 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7218 (clobber (reg:CC 17))]
7219 "TARGET_64BIT
7220 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7221 "@
7222 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7223 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7224 imul{l}\t{%2, %k0|%k0, %2}"
7225 [(set_attr "type" "imul")
7226 (set_attr "prefix_0f" "0,0,1")
7227 (set (attr "athlon_decode")
7228 (cond [(eq_attr "cpu" "athlon")
7229 (const_string "vector")
7230 (eq_attr "alternative" "1")
7231 (const_string "vector")
7232 (and (eq_attr "alternative" "2")
7233 (match_operand 1 "memory_operand" ""))
7234 (const_string "vector")]
7235 (const_string "direct")))
7236 (set_attr "mode" "SI")])
7237
7238 (define_expand "mulhi3"
7239 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7240 (mult:HI (match_operand:HI 1 "register_operand" "")
7241 (match_operand:HI 2 "general_operand" "")))
7242 (clobber (reg:CC 17))])]
7243 "TARGET_HIMODE_MATH"
7244 "")
7245
7246 (define_insn "*mulhi3_1"
7247 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7248 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7249 (match_operand:HI 2 "general_operand" "K,i,mr")))
7250 (clobber (reg:CC 17))]
7251 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7252 "@
7253 imul{w}\t{%2, %1, %0|%0, %1, %2}
7254 imul{w}\t{%2, %1, %0|%0, %1, %2}
7255 imul{w}\t{%2, %0|%0, %2}"
7256 [(set_attr "type" "imul")
7257 (set_attr "prefix_0f" "0,0,1")
7258 (set (attr "athlon_decode")
7259 (cond [(eq_attr "cpu" "athlon")
7260 (const_string "vector")
7261 (eq_attr "alternative" "1,2")
7262 (const_string "vector")]
7263 (const_string "direct")))
7264 (set_attr "mode" "HI")])
7265
7266 (define_expand "mulqi3"
7267 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7268 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7269 (match_operand:QI 2 "register_operand" "")))
7270 (clobber (reg:CC 17))])]
7271 "TARGET_QIMODE_MATH"
7272 "")
7273
7274 (define_insn "*mulqi3_1"
7275 [(set (match_operand:QI 0 "register_operand" "=a")
7276 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7277 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7278 (clobber (reg:CC 17))]
7279 "TARGET_QIMODE_MATH
7280 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7281 "mul{b}\t%2"
7282 [(set_attr "type" "imul")
7283 (set_attr "length_immediate" "0")
7284 (set (attr "athlon_decode")
7285 (if_then_else (eq_attr "cpu" "athlon")
7286 (const_string "vector")
7287 (const_string "direct")))
7288 (set_attr "mode" "QI")])
7289
7290 (define_expand "umulqihi3"
7291 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7292 (mult:HI (zero_extend:HI
7293 (match_operand:QI 1 "nonimmediate_operand" ""))
7294 (zero_extend:HI
7295 (match_operand:QI 2 "register_operand" ""))))
7296 (clobber (reg:CC 17))])]
7297 "TARGET_QIMODE_MATH"
7298 "")
7299
7300 (define_insn "*umulqihi3_1"
7301 [(set (match_operand:HI 0 "register_operand" "=a")
7302 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7303 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7304 (clobber (reg:CC 17))]
7305 "TARGET_QIMODE_MATH
7306 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7307 "mul{b}\t%2"
7308 [(set_attr "type" "imul")
7309 (set_attr "length_immediate" "0")
7310 (set (attr "athlon_decode")
7311 (if_then_else (eq_attr "cpu" "athlon")
7312 (const_string "vector")
7313 (const_string "direct")))
7314 (set_attr "mode" "QI")])
7315
7316 (define_expand "mulqihi3"
7317 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7318 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7319 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7320 (clobber (reg:CC 17))])]
7321 "TARGET_QIMODE_MATH"
7322 "")
7323
7324 (define_insn "*mulqihi3_insn"
7325 [(set (match_operand:HI 0 "register_operand" "=a")
7326 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7327 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7328 (clobber (reg:CC 17))]
7329 "TARGET_QIMODE_MATH
7330 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7331 "imul{b}\t%2"
7332 [(set_attr "type" "imul")
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 "direct")))
7338 (set_attr "mode" "QI")])
7339
7340 (define_expand "umulditi3"
7341 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7342 (mult:TI (zero_extend:TI
7343 (match_operand:DI 1 "nonimmediate_operand" ""))
7344 (zero_extend:TI
7345 (match_operand:DI 2 "register_operand" ""))))
7346 (clobber (reg:CC 17))])]
7347 "TARGET_64BIT"
7348 "")
7349
7350 (define_insn "*umulditi3_insn"
7351 [(set (match_operand:TI 0 "register_operand" "=A")
7352 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7353 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7354 (clobber (reg:CC 17))]
7355 "TARGET_64BIT
7356 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7357 "mul{q}\t%2"
7358 [(set_attr "type" "imul")
7359 (set_attr "ppro_uops" "few")
7360 (set_attr "length_immediate" "0")
7361 (set (attr "athlon_decode")
7362 (if_then_else (eq_attr "cpu" "athlon")
7363 (const_string "vector")
7364 (const_string "double")))
7365 (set_attr "mode" "DI")])
7366
7367 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7368 (define_expand "umulsidi3"
7369 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7370 (mult:DI (zero_extend:DI
7371 (match_operand:SI 1 "nonimmediate_operand" ""))
7372 (zero_extend:DI
7373 (match_operand:SI 2 "register_operand" ""))))
7374 (clobber (reg:CC 17))])]
7375 "!TARGET_64BIT"
7376 "")
7377
7378 (define_insn "*umulsidi3_insn"
7379 [(set (match_operand:DI 0 "register_operand" "=A")
7380 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7381 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7382 (clobber (reg:CC 17))]
7383 "!TARGET_64BIT
7384 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7385 "mul{l}\t%2"
7386 [(set_attr "type" "imul")
7387 (set_attr "ppro_uops" "few")
7388 (set_attr "length_immediate" "0")
7389 (set (attr "athlon_decode")
7390 (if_then_else (eq_attr "cpu" "athlon")
7391 (const_string "vector")
7392 (const_string "double")))
7393 (set_attr "mode" "SI")])
7394
7395 (define_expand "mulditi3"
7396 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7397 (mult:TI (sign_extend:TI
7398 (match_operand:DI 1 "nonimmediate_operand" ""))
7399 (sign_extend:TI
7400 (match_operand:DI 2 "register_operand" ""))))
7401 (clobber (reg:CC 17))])]
7402 "TARGET_64BIT"
7403 "")
7404
7405 (define_insn "*mulditi3_insn"
7406 [(set (match_operand:TI 0 "register_operand" "=A")
7407 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7408 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7409 (clobber (reg:CC 17))]
7410 "TARGET_64BIT
7411 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7412 "imul{q}\t%2"
7413 [(set_attr "type" "imul")
7414 (set_attr "length_immediate" "0")
7415 (set (attr "athlon_decode")
7416 (if_then_else (eq_attr "cpu" "athlon")
7417 (const_string "vector")
7418 (const_string "double")))
7419 (set_attr "mode" "DI")])
7420
7421 (define_expand "mulsidi3"
7422 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7423 (mult:DI (sign_extend:DI
7424 (match_operand:SI 1 "nonimmediate_operand" ""))
7425 (sign_extend:DI
7426 (match_operand:SI 2 "register_operand" ""))))
7427 (clobber (reg:CC 17))])]
7428 "!TARGET_64BIT"
7429 "")
7430
7431 (define_insn "*mulsidi3_insn"
7432 [(set (match_operand:DI 0 "register_operand" "=A")
7433 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7434 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7435 (clobber (reg:CC 17))]
7436 "!TARGET_64BIT
7437 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7438 "imul{l}\t%2"
7439 [(set_attr "type" "imul")
7440 (set_attr "length_immediate" "0")
7441 (set (attr "athlon_decode")
7442 (if_then_else (eq_attr "cpu" "athlon")
7443 (const_string "vector")
7444 (const_string "double")))
7445 (set_attr "mode" "SI")])
7446
7447 (define_expand "umuldi3_highpart"
7448 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7449 (truncate:DI
7450 (lshiftrt:TI
7451 (mult:TI (zero_extend:TI
7452 (match_operand:DI 1 "nonimmediate_operand" ""))
7453 (zero_extend:TI
7454 (match_operand:DI 2 "register_operand" "")))
7455 (const_int 64))))
7456 (clobber (match_scratch:DI 3 ""))
7457 (clobber (reg:CC 17))])]
7458 "TARGET_64BIT"
7459 "")
7460
7461 (define_insn "*umuldi3_highpart_rex64"
7462 [(set (match_operand:DI 0 "register_operand" "=d")
7463 (truncate:DI
7464 (lshiftrt:TI
7465 (mult:TI (zero_extend:TI
7466 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7467 (zero_extend:TI
7468 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7469 (const_int 64))))
7470 (clobber (match_scratch:DI 3 "=1"))
7471 (clobber (reg:CC 17))]
7472 "TARGET_64BIT
7473 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7474 "mul{q}\t%2"
7475 [(set_attr "type" "imul")
7476 (set_attr "ppro_uops" "few")
7477 (set_attr "length_immediate" "0")
7478 (set (attr "athlon_decode")
7479 (if_then_else (eq_attr "cpu" "athlon")
7480 (const_string "vector")
7481 (const_string "double")))
7482 (set_attr "mode" "DI")])
7483
7484 (define_expand "umulsi3_highpart"
7485 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7486 (truncate:SI
7487 (lshiftrt:DI
7488 (mult:DI (zero_extend:DI
7489 (match_operand:SI 1 "nonimmediate_operand" ""))
7490 (zero_extend:DI
7491 (match_operand:SI 2 "register_operand" "")))
7492 (const_int 32))))
7493 (clobber (match_scratch:SI 3 ""))
7494 (clobber (reg:CC 17))])]
7495 ""
7496 "")
7497
7498 (define_insn "*umulsi3_highpart_insn"
7499 [(set (match_operand:SI 0 "register_operand" "=d")
7500 (truncate:SI
7501 (lshiftrt:DI
7502 (mult:DI (zero_extend:DI
7503 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7504 (zero_extend:DI
7505 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7506 (const_int 32))))
7507 (clobber (match_scratch:SI 3 "=1"))
7508 (clobber (reg:CC 17))]
7509 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7510 "mul{l}\t%2"
7511 [(set_attr "type" "imul")
7512 (set_attr "ppro_uops" "few")
7513 (set_attr "length_immediate" "0")
7514 (set (attr "athlon_decode")
7515 (if_then_else (eq_attr "cpu" "athlon")
7516 (const_string "vector")
7517 (const_string "double")))
7518 (set_attr "mode" "SI")])
7519
7520 (define_insn "*umulsi3_highpart_zext"
7521 [(set (match_operand:DI 0 "register_operand" "=d")
7522 (zero_extend:DI (truncate:SI
7523 (lshiftrt:DI
7524 (mult:DI (zero_extend:DI
7525 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7526 (zero_extend:DI
7527 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7528 (const_int 32)))))
7529 (clobber (match_scratch:SI 3 "=1"))
7530 (clobber (reg:CC 17))]
7531 "TARGET_64BIT
7532 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7533 "mul{l}\t%2"
7534 [(set_attr "type" "imul")
7535 (set_attr "ppro_uops" "few")
7536 (set_attr "length_immediate" "0")
7537 (set (attr "athlon_decode")
7538 (if_then_else (eq_attr "cpu" "athlon")
7539 (const_string "vector")
7540 (const_string "double")))
7541 (set_attr "mode" "SI")])
7542
7543 (define_expand "smuldi3_highpart"
7544 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7545 (truncate:DI
7546 (lshiftrt:TI
7547 (mult:TI (sign_extend:TI
7548 (match_operand:DI 1 "nonimmediate_operand" ""))
7549 (sign_extend:TI
7550 (match_operand:DI 2 "register_operand" "")))
7551 (const_int 64))))
7552 (clobber (match_scratch:DI 3 ""))
7553 (clobber (reg:CC 17))])]
7554 "TARGET_64BIT"
7555 "")
7556
7557 (define_insn "*smuldi3_highpart_rex64"
7558 [(set (match_operand:DI 0 "register_operand" "=d")
7559 (truncate:DI
7560 (lshiftrt:TI
7561 (mult:TI (sign_extend:TI
7562 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7563 (sign_extend:TI
7564 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7565 (const_int 64))))
7566 (clobber (match_scratch:DI 3 "=1"))
7567 (clobber (reg:CC 17))]
7568 "TARGET_64BIT
7569 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7570 "imul{q}\t%2"
7571 [(set_attr "type" "imul")
7572 (set_attr "ppro_uops" "few")
7573 (set (attr "athlon_decode")
7574 (if_then_else (eq_attr "cpu" "athlon")
7575 (const_string "vector")
7576 (const_string "double")))
7577 (set_attr "mode" "DI")])
7578
7579 (define_expand "smulsi3_highpart"
7580 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581 (truncate:SI
7582 (lshiftrt:DI
7583 (mult:DI (sign_extend:DI
7584 (match_operand:SI 1 "nonimmediate_operand" ""))
7585 (sign_extend:DI
7586 (match_operand:SI 2 "register_operand" "")))
7587 (const_int 32))))
7588 (clobber (match_scratch:SI 3 ""))
7589 (clobber (reg:CC 17))])]
7590 ""
7591 "")
7592
7593 (define_insn "*smulsi3_highpart_insn"
7594 [(set (match_operand:SI 0 "register_operand" "=d")
7595 (truncate:SI
7596 (lshiftrt:DI
7597 (mult:DI (sign_extend:DI
7598 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7599 (sign_extend:DI
7600 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7601 (const_int 32))))
7602 (clobber (match_scratch:SI 3 "=1"))
7603 (clobber (reg:CC 17))]
7604 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7605 "imul{l}\t%2"
7606 [(set_attr "type" "imul")
7607 (set_attr "ppro_uops" "few")
7608 (set (attr "athlon_decode")
7609 (if_then_else (eq_attr "cpu" "athlon")
7610 (const_string "vector")
7611 (const_string "double")))
7612 (set_attr "mode" "SI")])
7613
7614 (define_insn "*smulsi3_highpart_zext"
7615 [(set (match_operand:DI 0 "register_operand" "=d")
7616 (zero_extend:DI (truncate:SI
7617 (lshiftrt:DI
7618 (mult:DI (sign_extend:DI
7619 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7620 (sign_extend:DI
7621 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7622 (const_int 32)))))
7623 (clobber (match_scratch:SI 3 "=1"))
7624 (clobber (reg:CC 17))]
7625 "TARGET_64BIT
7626 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7627 "imul{l}\t%2"
7628 [(set_attr "type" "imul")
7629 (set_attr "ppro_uops" "few")
7630 (set (attr "athlon_decode")
7631 (if_then_else (eq_attr "cpu" "athlon")
7632 (const_string "vector")
7633 (const_string "double")))
7634 (set_attr "mode" "SI")])
7635
7636 ;; The patterns that match these are at the end of this file.
7637
7638 (define_expand "mulxf3"
7639 [(set (match_operand:XF 0 "register_operand" "")
7640 (mult:XF (match_operand:XF 1 "register_operand" "")
7641 (match_operand:XF 2 "register_operand" "")))]
7642 "!TARGET_64BIT && TARGET_80387"
7643 "")
7644
7645 (define_expand "multf3"
7646 [(set (match_operand:TF 0 "register_operand" "")
7647 (mult:TF (match_operand:TF 1 "register_operand" "")
7648 (match_operand:TF 2 "register_operand" "")))]
7649 "TARGET_80387"
7650 "")
7651
7652 (define_expand "muldf3"
7653 [(set (match_operand:DF 0 "register_operand" "")
7654 (mult:DF (match_operand:DF 1 "register_operand" "")
7655 (match_operand:DF 2 "nonimmediate_operand" "")))]
7656 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7657 "")
7658
7659 (define_expand "mulsf3"
7660 [(set (match_operand:SF 0 "register_operand" "")
7661 (mult:SF (match_operand:SF 1 "register_operand" "")
7662 (match_operand:SF 2 "nonimmediate_operand" "")))]
7663 "TARGET_80387 || TARGET_SSE_MATH"
7664 "")
7665 \f
7666 ;; Divide instructions
7667
7668 (define_insn "divqi3"
7669 [(set (match_operand:QI 0 "register_operand" "=a")
7670 (div:QI (match_operand:HI 1 "register_operand" "0")
7671 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7672 (clobber (reg:CC 17))]
7673 "TARGET_QIMODE_MATH"
7674 "idiv{b}\t%2"
7675 [(set_attr "type" "idiv")
7676 (set_attr "mode" "QI")
7677 (set_attr "ppro_uops" "few")])
7678
7679 (define_insn "udivqi3"
7680 [(set (match_operand:QI 0 "register_operand" "=a")
7681 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7682 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7683 (clobber (reg:CC 17))]
7684 "TARGET_QIMODE_MATH"
7685 "div{b}\t%2"
7686 [(set_attr "type" "idiv")
7687 (set_attr "mode" "QI")
7688 (set_attr "ppro_uops" "few")])
7689
7690 ;; The patterns that match these are at the end of this file.
7691
7692 (define_expand "divxf3"
7693 [(set (match_operand:XF 0 "register_operand" "")
7694 (div:XF (match_operand:XF 1 "register_operand" "")
7695 (match_operand:XF 2 "register_operand" "")))]
7696 "!TARGET_64BIT && TARGET_80387"
7697 "")
7698
7699 (define_expand "divtf3"
7700 [(set (match_operand:TF 0 "register_operand" "")
7701 (div:TF (match_operand:TF 1 "register_operand" "")
7702 (match_operand:TF 2 "register_operand" "")))]
7703 "TARGET_80387"
7704 "")
7705
7706 (define_expand "divdf3"
7707 [(set (match_operand:DF 0 "register_operand" "")
7708 (div:DF (match_operand:DF 1 "register_operand" "")
7709 (match_operand:DF 2 "nonimmediate_operand" "")))]
7710 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7711 "")
7712
7713 (define_expand "divsf3"
7714 [(set (match_operand:SF 0 "register_operand" "")
7715 (div:SF (match_operand:SF 1 "register_operand" "")
7716 (match_operand:SF 2 "nonimmediate_operand" "")))]
7717 "TARGET_80387 || TARGET_SSE_MATH"
7718 "")
7719 \f
7720 ;; Remainder instructions.
7721
7722 (define_expand "divmoddi4"
7723 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7724 (div:DI (match_operand:DI 1 "register_operand" "")
7725 (match_operand:DI 2 "nonimmediate_operand" "")))
7726 (set (match_operand:DI 3 "register_operand" "")
7727 (mod:DI (match_dup 1) (match_dup 2)))
7728 (clobber (reg:CC 17))])]
7729 "TARGET_64BIT"
7730 "")
7731
7732 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7733 ;; Penalize eax case slightly because it results in worse scheduling
7734 ;; of code.
7735 (define_insn "*divmoddi4_nocltd_rex64"
7736 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7737 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7738 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7739 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7740 (mod:DI (match_dup 2) (match_dup 3)))
7741 (clobber (reg:CC 17))]
7742 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7743 "#"
7744 [(set_attr "type" "multi")])
7745
7746 (define_insn "*divmoddi4_cltd_rex64"
7747 [(set (match_operand:DI 0 "register_operand" "=a")
7748 (div:DI (match_operand:DI 2 "register_operand" "a")
7749 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7750 (set (match_operand:DI 1 "register_operand" "=&d")
7751 (mod:DI (match_dup 2) (match_dup 3)))
7752 (clobber (reg:CC 17))]
7753 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7754 "#"
7755 [(set_attr "type" "multi")])
7756
7757 (define_insn "*divmoddi_noext_rex64"
7758 [(set (match_operand:DI 0 "register_operand" "=a")
7759 (div:DI (match_operand:DI 1 "register_operand" "0")
7760 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7761 (set (match_operand:DI 3 "register_operand" "=d")
7762 (mod:DI (match_dup 1) (match_dup 2)))
7763 (use (match_operand:DI 4 "register_operand" "3"))
7764 (clobber (reg:CC 17))]
7765 "TARGET_64BIT"
7766 "idiv{q}\t%2"
7767 [(set_attr "type" "idiv")
7768 (set_attr "mode" "DI")
7769 (set_attr "ppro_uops" "few")])
7770
7771 (define_split
7772 [(set (match_operand:DI 0 "register_operand" "")
7773 (div:DI (match_operand:DI 1 "register_operand" "")
7774 (match_operand:DI 2 "nonimmediate_operand" "")))
7775 (set (match_operand:DI 3 "register_operand" "")
7776 (mod:DI (match_dup 1) (match_dup 2)))
7777 (clobber (reg:CC 17))]
7778 "TARGET_64BIT && reload_completed"
7779 [(parallel [(set (match_dup 3)
7780 (ashiftrt:DI (match_dup 4) (const_int 63)))
7781 (clobber (reg:CC 17))])
7782 (parallel [(set (match_dup 0)
7783 (div:DI (reg:DI 0) (match_dup 2)))
7784 (set (match_dup 3)
7785 (mod:DI (reg:DI 0) (match_dup 2)))
7786 (use (match_dup 3))
7787 (clobber (reg:CC 17))])]
7788 {
7789 /* Avoid use of cltd in favor of a mov+shift. */
7790 if (!TARGET_USE_CLTD && !optimize_size)
7791 {
7792 if (true_regnum (operands[1]))
7793 emit_move_insn (operands[0], operands[1]);
7794 else
7795 emit_move_insn (operands[3], operands[1]);
7796 operands[4] = operands[3];
7797 }
7798 else
7799 {
7800 if (true_regnum (operands[1]))
7801 abort();
7802 operands[4] = operands[1];
7803 }
7804 })
7805
7806
7807 (define_expand "divmodsi4"
7808 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7809 (div:SI (match_operand:SI 1 "register_operand" "")
7810 (match_operand:SI 2 "nonimmediate_operand" "")))
7811 (set (match_operand:SI 3 "register_operand" "")
7812 (mod:SI (match_dup 1) (match_dup 2)))
7813 (clobber (reg:CC 17))])]
7814 ""
7815 "")
7816
7817 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7818 ;; Penalize eax case slightly because it results in worse scheduling
7819 ;; of code.
7820 (define_insn "*divmodsi4_nocltd"
7821 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7822 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7823 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7824 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7825 (mod:SI (match_dup 2) (match_dup 3)))
7826 (clobber (reg:CC 17))]
7827 "!optimize_size && !TARGET_USE_CLTD"
7828 "#"
7829 [(set_attr "type" "multi")])
7830
7831 (define_insn "*divmodsi4_cltd"
7832 [(set (match_operand:SI 0 "register_operand" "=a")
7833 (div:SI (match_operand:SI 2 "register_operand" "a")
7834 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7835 (set (match_operand:SI 1 "register_operand" "=&d")
7836 (mod:SI (match_dup 2) (match_dup 3)))
7837 (clobber (reg:CC 17))]
7838 "optimize_size || TARGET_USE_CLTD"
7839 "#"
7840 [(set_attr "type" "multi")])
7841
7842 (define_insn "*divmodsi_noext"
7843 [(set (match_operand:SI 0 "register_operand" "=a")
7844 (div:SI (match_operand:SI 1 "register_operand" "0")
7845 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7846 (set (match_operand:SI 3 "register_operand" "=d")
7847 (mod:SI (match_dup 1) (match_dup 2)))
7848 (use (match_operand:SI 4 "register_operand" "3"))
7849 (clobber (reg:CC 17))]
7850 ""
7851 "idiv{l}\t%2"
7852 [(set_attr "type" "idiv")
7853 (set_attr "mode" "SI")
7854 (set_attr "ppro_uops" "few")])
7855
7856 (define_split
7857 [(set (match_operand:SI 0 "register_operand" "")
7858 (div:SI (match_operand:SI 1 "register_operand" "")
7859 (match_operand:SI 2 "nonimmediate_operand" "")))
7860 (set (match_operand:SI 3 "register_operand" "")
7861 (mod:SI (match_dup 1) (match_dup 2)))
7862 (clobber (reg:CC 17))]
7863 "reload_completed"
7864 [(parallel [(set (match_dup 3)
7865 (ashiftrt:SI (match_dup 4) (const_int 31)))
7866 (clobber (reg:CC 17))])
7867 (parallel [(set (match_dup 0)
7868 (div:SI (reg:SI 0) (match_dup 2)))
7869 (set (match_dup 3)
7870 (mod:SI (reg:SI 0) (match_dup 2)))
7871 (use (match_dup 3))
7872 (clobber (reg:CC 17))])]
7873 {
7874 /* Avoid use of cltd in favor of a mov+shift. */
7875 if (!TARGET_USE_CLTD && !optimize_size)
7876 {
7877 if (true_regnum (operands[1]))
7878 emit_move_insn (operands[0], operands[1]);
7879 else
7880 emit_move_insn (operands[3], operands[1]);
7881 operands[4] = operands[3];
7882 }
7883 else
7884 {
7885 if (true_regnum (operands[1]))
7886 abort();
7887 operands[4] = operands[1];
7888 }
7889 })
7890 ;; %%% Split me.
7891 (define_insn "divmodhi4"
7892 [(set (match_operand:HI 0 "register_operand" "=a")
7893 (div:HI (match_operand:HI 1 "register_operand" "0")
7894 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7895 (set (match_operand:HI 3 "register_operand" "=&d")
7896 (mod:HI (match_dup 1) (match_dup 2)))
7897 (clobber (reg:CC 17))]
7898 "TARGET_HIMODE_MATH"
7899 "cwtd\;idiv{w}\t%2"
7900 [(set_attr "type" "multi")
7901 (set_attr "length_immediate" "0")
7902 (set_attr "mode" "SI")])
7903
7904 (define_insn "udivmoddi4"
7905 [(set (match_operand:DI 0 "register_operand" "=a")
7906 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7907 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7908 (set (match_operand:DI 3 "register_operand" "=&d")
7909 (umod:DI (match_dup 1) (match_dup 2)))
7910 (clobber (reg:CC 17))]
7911 "TARGET_64BIT"
7912 "xor{q}\t%3, %3\;div{q}\t%2"
7913 [(set_attr "type" "multi")
7914 (set_attr "length_immediate" "0")
7915 (set_attr "mode" "DI")])
7916
7917 (define_insn "*udivmoddi4_noext"
7918 [(set (match_operand:DI 0 "register_operand" "=a")
7919 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7920 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7921 (set (match_operand:DI 3 "register_operand" "=d")
7922 (umod:DI (match_dup 1) (match_dup 2)))
7923 (use (match_dup 3))
7924 (clobber (reg:CC 17))]
7925 "TARGET_64BIT"
7926 "div{q}\t%2"
7927 [(set_attr "type" "idiv")
7928 (set_attr "ppro_uops" "few")
7929 (set_attr "mode" "DI")])
7930
7931 (define_split
7932 [(set (match_operand:DI 0 "register_operand" "")
7933 (udiv:DI (match_operand:DI 1 "register_operand" "")
7934 (match_operand:DI 2 "nonimmediate_operand" "")))
7935 (set (match_operand:DI 3 "register_operand" "")
7936 (umod:DI (match_dup 1) (match_dup 2)))
7937 (clobber (reg:CC 17))]
7938 "TARGET_64BIT && reload_completed"
7939 [(set (match_dup 3) (const_int 0))
7940 (parallel [(set (match_dup 0)
7941 (udiv:DI (match_dup 1) (match_dup 2)))
7942 (set (match_dup 3)
7943 (umod:DI (match_dup 1) (match_dup 2)))
7944 (use (match_dup 3))
7945 (clobber (reg:CC 17))])]
7946 "")
7947
7948 (define_insn "udivmodsi4"
7949 [(set (match_operand:SI 0 "register_operand" "=a")
7950 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7951 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7952 (set (match_operand:SI 3 "register_operand" "=&d")
7953 (umod:SI (match_dup 1) (match_dup 2)))
7954 (clobber (reg:CC 17))]
7955 ""
7956 "xor{l}\t%3, %3\;div{l}\t%2"
7957 [(set_attr "type" "multi")
7958 (set_attr "length_immediate" "0")
7959 (set_attr "mode" "SI")])
7960
7961 (define_insn "*udivmodsi4_noext"
7962 [(set (match_operand:SI 0 "register_operand" "=a")
7963 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7964 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7965 (set (match_operand:SI 3 "register_operand" "=d")
7966 (umod:SI (match_dup 1) (match_dup 2)))
7967 (use (match_dup 3))
7968 (clobber (reg:CC 17))]
7969 ""
7970 "div{l}\t%2"
7971 [(set_attr "type" "idiv")
7972 (set_attr "ppro_uops" "few")
7973 (set_attr "mode" "SI")])
7974
7975 (define_split
7976 [(set (match_operand:SI 0 "register_operand" "")
7977 (udiv:SI (match_operand:SI 1 "register_operand" "")
7978 (match_operand:SI 2 "nonimmediate_operand" "")))
7979 (set (match_operand:SI 3 "register_operand" "")
7980 (umod:SI (match_dup 1) (match_dup 2)))
7981 (clobber (reg:CC 17))]
7982 "reload_completed"
7983 [(set (match_dup 3) (const_int 0))
7984 (parallel [(set (match_dup 0)
7985 (udiv:SI (match_dup 1) (match_dup 2)))
7986 (set (match_dup 3)
7987 (umod:SI (match_dup 1) (match_dup 2)))
7988 (use (match_dup 3))
7989 (clobber (reg:CC 17))])]
7990 "")
7991
7992 (define_expand "udivmodhi4"
7993 [(set (match_dup 4) (const_int 0))
7994 (parallel [(set (match_operand:HI 0 "register_operand" "")
7995 (udiv:HI (match_operand:HI 1 "register_operand" "")
7996 (match_operand:HI 2 "nonimmediate_operand" "")))
7997 (set (match_operand:HI 3 "register_operand" "")
7998 (umod:HI (match_dup 1) (match_dup 2)))
7999 (use (match_dup 4))
8000 (clobber (reg:CC 17))])]
8001 "TARGET_HIMODE_MATH"
8002 "operands[4] = gen_reg_rtx (HImode);")
8003
8004 (define_insn "*udivmodhi_noext"
8005 [(set (match_operand:HI 0 "register_operand" "=a")
8006 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8007 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8008 (set (match_operand:HI 3 "register_operand" "=d")
8009 (umod:HI (match_dup 1) (match_dup 2)))
8010 (use (match_operand:HI 4 "register_operand" "3"))
8011 (clobber (reg:CC 17))]
8012 ""
8013 "div{w}\t%2"
8014 [(set_attr "type" "idiv")
8015 (set_attr "mode" "HI")
8016 (set_attr "ppro_uops" "few")])
8017
8018 ;; We can not use div/idiv for double division, because it causes
8019 ;; "division by zero" on the overflow and that's not what we expect
8020 ;; from truncate. Because true (non truncating) double division is
8021 ;; never generated, we can't create this insn anyway.
8022 ;
8023 ;(define_insn ""
8024 ; [(set (match_operand:SI 0 "register_operand" "=a")
8025 ; (truncate:SI
8026 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8027 ; (zero_extend:DI
8028 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8029 ; (set (match_operand:SI 3 "register_operand" "=d")
8030 ; (truncate:SI
8031 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8032 ; (clobber (reg:CC 17))]
8033 ; ""
8034 ; "div{l}\t{%2, %0|%0, %2}"
8035 ; [(set_attr "type" "idiv")
8036 ; (set_attr "ppro_uops" "few")])
8037 \f
8038 ;;- Logical AND instructions
8039
8040 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8041 ;; Note that this excludes ah.
8042
8043 (define_insn "*testdi_1_rex64"
8044 [(set (reg 17)
8045 (compare
8046 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8047 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
8048 (const_int 0)))]
8049 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8050 "@
8051 test{l}\t{%k1, %k0|%k0, %k1}
8052 test{l}\t{%k1, %k0|%k0, %k1}
8053 test{q}\t{%1, %0|%0, %1}
8054 test{q}\t{%1, %0|%0, %1}
8055 test{q}\t{%1, %0|%0, %1}"
8056 [(set_attr "type" "test")
8057 (set_attr "modrm" "0,1,0,1,1")
8058 (set_attr "mode" "SI,SI,DI,DI,DI")
8059 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8060
8061 (define_insn "testsi_1"
8062 [(set (reg 17)
8063 (compare
8064 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8065 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
8066 (const_int 0)))]
8067 "ix86_match_ccmode (insn, CCNOmode)"
8068 "test{l}\t{%1, %0|%0, %1}"
8069 [(set_attr "type" "test")
8070 (set_attr "modrm" "0,1,1")
8071 (set_attr "mode" "SI")
8072 (set_attr "pent_pair" "uv,np,uv")])
8073
8074 (define_expand "testsi_ccno_1"
8075 [(set (reg:CCNO 17)
8076 (compare:CCNO
8077 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8078 (match_operand:SI 1 "nonmemory_operand" ""))
8079 (const_int 0)))]
8080 ""
8081 "")
8082
8083 (define_insn "*testhi_1"
8084 [(set (reg 17)
8085 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8086 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
8087 (const_int 0)))]
8088 "ix86_match_ccmode (insn, CCNOmode)"
8089 "test{w}\t{%1, %0|%0, %1}"
8090 [(set_attr "type" "test")
8091 (set_attr "modrm" "0,1,1")
8092 (set_attr "mode" "HI")
8093 (set_attr "pent_pair" "uv,np,uv")])
8094
8095 (define_expand "testqi_ccz_1"
8096 [(set (reg:CCZ 17)
8097 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8098 (match_operand:QI 1 "nonmemory_operand" ""))
8099 (const_int 0)))]
8100 ""
8101 "")
8102
8103 (define_insn "*testqi_1"
8104 [(set (reg 17)
8105 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8106 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
8107 (const_int 0)))]
8108 "ix86_match_ccmode (insn, CCNOmode)"
8109 {
8110 if (which_alternative == 3)
8111 {
8112 if (GET_CODE (operands[1]) == CONST_INT
8113 && (INTVAL (operands[1]) & 0xffffff00))
8114 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8115 return "test{l}\t{%1, %k0|%k0, %1}";
8116 }
8117 return "test{b}\t{%1, %0|%0, %1}";
8118 }
8119 [(set_attr "type" "test")
8120 (set_attr "modrm" "0,1,1,1")
8121 (set_attr "mode" "QI,QI,QI,SI")
8122 (set_attr "pent_pair" "uv,np,uv,np")])
8123
8124 (define_expand "testqi_ext_ccno_0"
8125 [(set (reg:CCNO 17)
8126 (compare:CCNO
8127 (and:SI
8128 (zero_extract:SI
8129 (match_operand 0 "ext_register_operand" "")
8130 (const_int 8)
8131 (const_int 8))
8132 (match_operand 1 "const_int_operand" ""))
8133 (const_int 0)))]
8134 ""
8135 "")
8136
8137 (define_insn "*testqi_ext_0"
8138 [(set (reg 17)
8139 (compare
8140 (and:SI
8141 (zero_extract:SI
8142 (match_operand 0 "ext_register_operand" "Q")
8143 (const_int 8)
8144 (const_int 8))
8145 (match_operand 1 "const_int_operand" "n"))
8146 (const_int 0)))]
8147 "ix86_match_ccmode (insn, CCNOmode)"
8148 "test{b}\t{%1, %h0|%h0, %1}"
8149 [(set_attr "type" "test")
8150 (set_attr "mode" "QI")
8151 (set_attr "length_immediate" "1")
8152 (set_attr "pent_pair" "np")])
8153
8154 (define_insn "*testqi_ext_1"
8155 [(set (reg 17)
8156 (compare
8157 (and:SI
8158 (zero_extract:SI
8159 (match_operand 0 "ext_register_operand" "Q")
8160 (const_int 8)
8161 (const_int 8))
8162 (zero_extend:SI
8163 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
8164 (const_int 0)))]
8165 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8166 "test{b}\t{%1, %h0|%h0, %1}"
8167 [(set_attr "type" "test")
8168 (set_attr "mode" "QI")])
8169
8170 (define_insn "*testqi_ext_1_rex64"
8171 [(set (reg 17)
8172 (compare
8173 (and:SI
8174 (zero_extract:SI
8175 (match_operand 0 "ext_register_operand" "Q")
8176 (const_int 8)
8177 (const_int 8))
8178 (zero_extend:SI
8179 (match_operand:QI 1 "register_operand" "Q")))
8180 (const_int 0)))]
8181 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8182 "test{b}\t{%1, %h0|%h0, %1}"
8183 [(set_attr "type" "test")
8184 (set_attr "mode" "QI")])
8185
8186 (define_insn "*testqi_ext_2"
8187 [(set (reg 17)
8188 (compare
8189 (and:SI
8190 (zero_extract:SI
8191 (match_operand 0 "ext_register_operand" "Q")
8192 (const_int 8)
8193 (const_int 8))
8194 (zero_extract:SI
8195 (match_operand 1 "ext_register_operand" "Q")
8196 (const_int 8)
8197 (const_int 8)))
8198 (const_int 0)))]
8199 "ix86_match_ccmode (insn, CCNOmode)"
8200 "test{b}\t{%h1, %h0|%h0, %h1}"
8201 [(set_attr "type" "test")
8202 (set_attr "mode" "QI")])
8203
8204 ;; Combine likes to form bit extractions for some tests. Humor it.
8205 (define_insn "*testqi_ext_3"
8206 [(set (reg 17)
8207 (compare (zero_extract:SI
8208 (match_operand 0 "nonimmediate_operand" "rm")
8209 (match_operand:SI 1 "const_int_operand" "")
8210 (match_operand:SI 2 "const_int_operand" ""))
8211 (const_int 0)))]
8212 "ix86_match_ccmode (insn, CCNOmode)
8213 && (GET_MODE (operands[0]) == SImode
8214 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8215 || GET_MODE (operands[0]) == HImode
8216 || GET_MODE (operands[0]) == QImode)"
8217 "#")
8218
8219 (define_insn "*testqi_ext_3_rex64"
8220 [(set (reg 17)
8221 (compare (zero_extract:DI
8222 (match_operand 0 "nonimmediate_operand" "rm")
8223 (match_operand:DI 1 "const_int_operand" "")
8224 (match_operand:DI 2 "const_int_operand" ""))
8225 (const_int 0)))]
8226 "TARGET_64BIT
8227 && ix86_match_ccmode (insn, CCNOmode)
8228 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8229 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8230 /* Ensure that resulting mask is zero or sign extended operand. */
8231 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8232 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8233 && INTVAL (operands[1]) > 32))
8234 && (GET_MODE (operands[0]) == SImode
8235 || GET_MODE (operands[0]) == DImode
8236 || GET_MODE (operands[0]) == HImode
8237 || GET_MODE (operands[0]) == QImode)"
8238 "#")
8239
8240 (define_split
8241 [(set (reg 17)
8242 (compare (zero_extract
8243 (match_operand 0 "nonimmediate_operand" "")
8244 (match_operand 1 "const_int_operand" "")
8245 (match_operand 2 "const_int_operand" ""))
8246 (const_int 0)))]
8247 "ix86_match_ccmode (insn, CCNOmode)"
8248 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8249 {
8250 HOST_WIDE_INT len = INTVAL (operands[1]);
8251 HOST_WIDE_INT pos = INTVAL (operands[2]);
8252 HOST_WIDE_INT mask;
8253 enum machine_mode mode, submode;
8254
8255 mode = GET_MODE (operands[0]);
8256 if (GET_CODE (operands[0]) == MEM)
8257 {
8258 /* ??? Combine likes to put non-volatile mem extractions in QImode
8259 no matter the size of the test. So find a mode that works. */
8260 if (! MEM_VOLATILE_P (operands[0]))
8261 {
8262 mode = smallest_mode_for_size (pos + len, MODE_INT);
8263 operands[0] = adjust_address (operands[0], mode, 0);
8264 }
8265 }
8266 else if (GET_CODE (operands[0]) == SUBREG
8267 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8268 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8269 && pos + len <= GET_MODE_BITSIZE (submode))
8270 {
8271 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8272 mode = submode;
8273 operands[0] = SUBREG_REG (operands[0]);
8274 }
8275 else if (mode == HImode && pos + len <= 8)
8276 {
8277 /* Small HImode tests can be converted to QImode. */
8278 mode = QImode;
8279 operands[0] = gen_lowpart (QImode, operands[0]);
8280 }
8281
8282 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8283 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8284
8285 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8286 })
8287
8288 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8289 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8290 ;; this is relatively important trick.
8291 ;; Do the conversion only post-reload to avoid limiting of the register class
8292 ;; to QI regs.
8293 (define_split
8294 [(set (reg 17)
8295 (compare
8296 (and (match_operand 0 "register_operand" "")
8297 (match_operand 1 "const_int_operand" ""))
8298 (const_int 0)))]
8299 "reload_completed
8300 && QI_REG_P (operands[0])
8301 && ((ix86_match_ccmode (insn, CCZmode)
8302 && !(INTVAL (operands[1]) & ~(255 << 8)))
8303 || (ix86_match_ccmode (insn, CCNOmode)
8304 && !(INTVAL (operands[1]) & ~(127 << 8))))
8305 && GET_MODE (operands[0]) != QImode"
8306 [(set (reg:CCNO 17)
8307 (compare:CCNO
8308 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8309 (match_dup 1))
8310 (const_int 0)))]
8311 "operands[0] = gen_lowpart (SImode, operands[0]);
8312 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8313
8314 (define_split
8315 [(set (reg 17)
8316 (compare
8317 (and (match_operand 0 "nonimmediate_operand" "")
8318 (match_operand 1 "const_int_operand" ""))
8319 (const_int 0)))]
8320 "reload_completed
8321 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8322 && ((ix86_match_ccmode (insn, CCZmode)
8323 && !(INTVAL (operands[1]) & ~255))
8324 || (ix86_match_ccmode (insn, CCNOmode)
8325 && !(INTVAL (operands[1]) & ~127)))
8326 && GET_MODE (operands[0]) != QImode"
8327 [(set (reg:CCNO 17)
8328 (compare:CCNO
8329 (and:QI (match_dup 0)
8330 (match_dup 1))
8331 (const_int 0)))]
8332 "operands[0] = gen_lowpart (QImode, operands[0]);
8333 operands[1] = gen_lowpart (QImode, operands[1]);")
8334
8335
8336 ;; %%% This used to optimize known byte-wide and operations to memory,
8337 ;; and sometimes to QImode registers. If this is considered useful,
8338 ;; it should be done with splitters.
8339
8340 (define_expand "anddi3"
8341 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8342 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8343 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8344 (clobber (reg:CC 17))]
8345 "TARGET_64BIT"
8346 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8347
8348 (define_insn "*anddi_1_rex64"
8349 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8350 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8351 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8352 (clobber (reg:CC 17))]
8353 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8354 {
8355 switch (get_attr_type (insn))
8356 {
8357 case TYPE_IMOVX:
8358 {
8359 enum machine_mode mode;
8360
8361 if (GET_CODE (operands[2]) != CONST_INT)
8362 abort ();
8363 if (INTVAL (operands[2]) == 0xff)
8364 mode = QImode;
8365 else if (INTVAL (operands[2]) == 0xffff)
8366 mode = HImode;
8367 else
8368 abort ();
8369
8370 operands[1] = gen_lowpart (mode, operands[1]);
8371 if (mode == QImode)
8372 return "movz{bq|x}\t{%1,%0|%0, %1}";
8373 else
8374 return "movz{wq|x}\t{%1,%0|%0, %1}";
8375 }
8376
8377 default:
8378 if (! rtx_equal_p (operands[0], operands[1]))
8379 abort ();
8380 if (get_attr_mode (insn) == MODE_SI)
8381 return "and{l}\t{%k2, %k0|%k0, %k2}";
8382 else
8383 return "and{q}\t{%2, %0|%0, %2}";
8384 }
8385 }
8386 [(set_attr "type" "alu,alu,alu,imovx")
8387 (set_attr "length_immediate" "*,*,*,0")
8388 (set_attr "mode" "SI,DI,DI,DI")])
8389
8390 (define_insn "*anddi_2"
8391 [(set (reg 17)
8392 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8393 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8394 (const_int 0)))
8395 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8396 (and:DI (match_dup 1) (match_dup 2)))]
8397 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8398 && ix86_binary_operator_ok (AND, DImode, operands)"
8399 "@
8400 and{l}\t{%k2, %k0|%k0, %k2}
8401 and{q}\t{%2, %0|%0, %2}
8402 and{q}\t{%2, %0|%0, %2}"
8403 [(set_attr "type" "alu")
8404 (set_attr "mode" "SI,DI,DI")])
8405
8406 (define_expand "andsi3"
8407 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8408 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8409 (match_operand:SI 2 "general_operand" "")))
8410 (clobber (reg:CC 17))]
8411 ""
8412 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8413
8414 (define_insn "*andsi_1"
8415 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8416 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8417 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8418 (clobber (reg:CC 17))]
8419 "ix86_binary_operator_ok (AND, SImode, operands)"
8420 {
8421 switch (get_attr_type (insn))
8422 {
8423 case TYPE_IMOVX:
8424 {
8425 enum machine_mode mode;
8426
8427 if (GET_CODE (operands[2]) != CONST_INT)
8428 abort ();
8429 if (INTVAL (operands[2]) == 0xff)
8430 mode = QImode;
8431 else if (INTVAL (operands[2]) == 0xffff)
8432 mode = HImode;
8433 else
8434 abort ();
8435
8436 operands[1] = gen_lowpart (mode, operands[1]);
8437 if (mode == QImode)
8438 return "movz{bl|x}\t{%1,%0|%0, %1}";
8439 else
8440 return "movz{wl|x}\t{%1,%0|%0, %1}";
8441 }
8442
8443 default:
8444 if (! rtx_equal_p (operands[0], operands[1]))
8445 abort ();
8446 return "and{l}\t{%2, %0|%0, %2}";
8447 }
8448 }
8449 [(set_attr "type" "alu,alu,imovx")
8450 (set_attr "length_immediate" "*,*,0")
8451 (set_attr "mode" "SI")])
8452
8453 (define_split
8454 [(set (match_operand 0 "register_operand" "")
8455 (and (match_dup 0)
8456 (const_int -65536)))
8457 (clobber (reg:CC 17))]
8458 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8459 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8460 "operands[1] = gen_lowpart (HImode, operands[0]);")
8461
8462 (define_split
8463 [(set (match_operand 0 "ext_register_operand" "")
8464 (and (match_dup 0)
8465 (const_int -256)))
8466 (clobber (reg:CC 17))]
8467 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8468 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8469 "operands[1] = gen_lowpart (QImode, operands[0]);")
8470
8471 (define_split
8472 [(set (match_operand 0 "ext_register_operand" "")
8473 (and (match_dup 0)
8474 (const_int -65281)))
8475 (clobber (reg:CC 17))]
8476 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8477 [(parallel [(set (zero_extract:SI (match_dup 0)
8478 (const_int 8)
8479 (const_int 8))
8480 (xor:SI
8481 (zero_extract:SI (match_dup 0)
8482 (const_int 8)
8483 (const_int 8))
8484 (zero_extract:SI (match_dup 0)
8485 (const_int 8)
8486 (const_int 8))))
8487 (clobber (reg:CC 17))])]
8488 "operands[0] = gen_lowpart (SImode, operands[0]);")
8489
8490 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8491 (define_insn "*andsi_1_zext"
8492 [(set (match_operand:DI 0 "register_operand" "=r")
8493 (zero_extend:DI
8494 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8495 (match_operand:SI 2 "general_operand" "rim"))))
8496 (clobber (reg:CC 17))]
8497 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8498 "and{l}\t{%2, %k0|%k0, %2}"
8499 [(set_attr "type" "alu")
8500 (set_attr "mode" "SI")])
8501
8502 (define_insn "*andsi_2"
8503 [(set (reg 17)
8504 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8505 (match_operand:SI 2 "general_operand" "rim,ri"))
8506 (const_int 0)))
8507 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8508 (and:SI (match_dup 1) (match_dup 2)))]
8509 "ix86_match_ccmode (insn, CCNOmode)
8510 && ix86_binary_operator_ok (AND, SImode, operands)"
8511 "and{l}\t{%2, %0|%0, %2}"
8512 [(set_attr "type" "alu")
8513 (set_attr "mode" "SI")])
8514
8515 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8516 (define_insn "*andsi_2_zext"
8517 [(set (reg 17)
8518 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8519 (match_operand:SI 2 "general_operand" "rim"))
8520 (const_int 0)))
8521 (set (match_operand:DI 0 "register_operand" "=r")
8522 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8523 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8524 && ix86_binary_operator_ok (AND, SImode, operands)"
8525 "and{l}\t{%2, %k0|%k0, %2}"
8526 [(set_attr "type" "alu")
8527 (set_attr "mode" "SI")])
8528
8529 (define_expand "andhi3"
8530 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8531 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8532 (match_operand:HI 2 "general_operand" "")))
8533 (clobber (reg:CC 17))]
8534 "TARGET_HIMODE_MATH"
8535 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8536
8537 (define_insn "*andhi_1"
8538 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8539 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8540 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8541 (clobber (reg:CC 17))]
8542 "ix86_binary_operator_ok (AND, HImode, operands)"
8543 {
8544 switch (get_attr_type (insn))
8545 {
8546 case TYPE_IMOVX:
8547 if (GET_CODE (operands[2]) != CONST_INT)
8548 abort ();
8549 if (INTVAL (operands[2]) == 0xff)
8550 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8551 abort ();
8552
8553 default:
8554 if (! rtx_equal_p (operands[0], operands[1]))
8555 abort ();
8556
8557 return "and{w}\t{%2, %0|%0, %2}";
8558 }
8559 }
8560 [(set_attr "type" "alu,alu,imovx")
8561 (set_attr "length_immediate" "*,*,0")
8562 (set_attr "mode" "HI,HI,SI")])
8563
8564 (define_insn "*andhi_2"
8565 [(set (reg 17)
8566 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8567 (match_operand:HI 2 "general_operand" "rim,ri"))
8568 (const_int 0)))
8569 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8570 (and:HI (match_dup 1) (match_dup 2)))]
8571 "ix86_match_ccmode (insn, CCNOmode)
8572 && ix86_binary_operator_ok (AND, HImode, operands)"
8573 "and{w}\t{%2, %0|%0, %2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "mode" "HI")])
8576
8577 (define_expand "andqi3"
8578 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8579 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8580 (match_operand:QI 2 "general_operand" "")))
8581 (clobber (reg:CC 17))]
8582 "TARGET_QIMODE_MATH"
8583 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8584
8585 ;; %%% Potential partial reg stall on alternative 2. What to do?
8586 (define_insn "*andqi_1"
8587 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8588 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8589 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8590 (clobber (reg:CC 17))]
8591 "ix86_binary_operator_ok (AND, QImode, operands)"
8592 "@
8593 and{b}\t{%2, %0|%0, %2}
8594 and{b}\t{%2, %0|%0, %2}
8595 and{l}\t{%k2, %k0|%k0, %k2}"
8596 [(set_attr "type" "alu")
8597 (set_attr "mode" "QI,QI,SI")])
8598
8599 (define_insn "*andqi_1_slp"
8600 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8601 (and:QI (match_dup 0)
8602 (match_operand:QI 1 "general_operand" "qi,qmi")))
8603 (clobber (reg:CC 17))]
8604 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8605 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8606 "and{b}\t{%1, %0|%0, %1}"
8607 [(set_attr "type" "alu1")
8608 (set_attr "mode" "QI")])
8609
8610 (define_insn "*andqi_2"
8611 [(set (reg 17)
8612 (compare (and:QI
8613 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8614 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8615 (const_int 0)))
8616 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8617 (and:QI (match_dup 1) (match_dup 2)))]
8618 "ix86_match_ccmode (insn, CCNOmode)
8619 && ix86_binary_operator_ok (AND, QImode, operands)"
8620 {
8621 if (which_alternative == 2)
8622 {
8623 if (GET_CODE (operands[2]) == CONST_INT
8624 && (INTVAL (operands[2]) & 0xffffff00))
8625 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8626 return "and{l}\t{%2, %k0|%k0, %2}";
8627 }
8628 return "and{b}\t{%2, %0|%0, %2}";
8629 }
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "QI,QI,SI")])
8632
8633 (define_insn "*andqi_2_slp"
8634 [(set (reg 17)
8635 (compare (and:QI
8636 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8637 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8638 (const_int 0)))
8639 (set (strict_low_part (match_dup 0))
8640 (and:QI (match_dup 0) (match_dup 1)))]
8641 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8642 && ix86_match_ccmode (insn, CCNOmode)
8643 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8644 "and{b}\t{%1, %0|%0, %1}"
8645 [(set_attr "type" "alu1")
8646 (set_attr "mode" "QI")])
8647
8648 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8649 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8650 ;; for a QImode operand, which of course failed.
8651
8652 (define_insn "andqi_ext_0"
8653 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8654 (const_int 8)
8655 (const_int 8))
8656 (and:SI
8657 (zero_extract:SI
8658 (match_operand 1 "ext_register_operand" "0")
8659 (const_int 8)
8660 (const_int 8))
8661 (match_operand 2 "const_int_operand" "n")))
8662 (clobber (reg:CC 17))]
8663 ""
8664 "and{b}\t{%2, %h0|%h0, %2}"
8665 [(set_attr "type" "alu")
8666 (set_attr "length_immediate" "1")
8667 (set_attr "mode" "QI")])
8668
8669 ;; Generated by peephole translating test to and. This shows up
8670 ;; often in fp comparisons.
8671
8672 (define_insn "*andqi_ext_0_cc"
8673 [(set (reg 17)
8674 (compare
8675 (and:SI
8676 (zero_extract:SI
8677 (match_operand 1 "ext_register_operand" "0")
8678 (const_int 8)
8679 (const_int 8))
8680 (match_operand 2 "const_int_operand" "n"))
8681 (const_int 0)))
8682 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8683 (const_int 8)
8684 (const_int 8))
8685 (and:SI
8686 (zero_extract:SI
8687 (match_dup 1)
8688 (const_int 8)
8689 (const_int 8))
8690 (match_dup 2)))]
8691 "ix86_match_ccmode (insn, CCNOmode)"
8692 "and{b}\t{%2, %h0|%h0, %2}"
8693 [(set_attr "type" "alu")
8694 (set_attr "length_immediate" "1")
8695 (set_attr "mode" "QI")])
8696
8697 (define_insn "*andqi_ext_1"
8698 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8699 (const_int 8)
8700 (const_int 8))
8701 (and:SI
8702 (zero_extract:SI
8703 (match_operand 1 "ext_register_operand" "0")
8704 (const_int 8)
8705 (const_int 8))
8706 (zero_extend:SI
8707 (match_operand:QI 2 "general_operand" "Qm"))))
8708 (clobber (reg:CC 17))]
8709 "!TARGET_64BIT"
8710 "and{b}\t{%2, %h0|%h0, %2}"
8711 [(set_attr "type" "alu")
8712 (set_attr "length_immediate" "0")
8713 (set_attr "mode" "QI")])
8714
8715 (define_insn "*andqi_ext_1_rex64"
8716 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8717 (const_int 8)
8718 (const_int 8))
8719 (and:SI
8720 (zero_extract:SI
8721 (match_operand 1 "ext_register_operand" "0")
8722 (const_int 8)
8723 (const_int 8))
8724 (zero_extend:SI
8725 (match_operand 2 "ext_register_operand" "Q"))))
8726 (clobber (reg:CC 17))]
8727 "TARGET_64BIT"
8728 "and{b}\t{%2, %h0|%h0, %2}"
8729 [(set_attr "type" "alu")
8730 (set_attr "length_immediate" "0")
8731 (set_attr "mode" "QI")])
8732
8733 (define_insn "*andqi_ext_2"
8734 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8735 (const_int 8)
8736 (const_int 8))
8737 (and:SI
8738 (zero_extract:SI
8739 (match_operand 1 "ext_register_operand" "%0")
8740 (const_int 8)
8741 (const_int 8))
8742 (zero_extract:SI
8743 (match_operand 2 "ext_register_operand" "Q")
8744 (const_int 8)
8745 (const_int 8))))
8746 (clobber (reg:CC 17))]
8747 ""
8748 "and{b}\t{%h2, %h0|%h0, %h2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "length_immediate" "0")
8751 (set_attr "mode" "QI")])
8752
8753 ;; Convert wide AND instructions with immediate operand to shorter QImode
8754 ;; equivalents when possible.
8755 ;; Don't do the splitting with memory operands, since it introduces risk
8756 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8757 ;; for size, but that can (should?) be handled by generic code instead.
8758 (define_split
8759 [(set (match_operand 0 "register_operand" "")
8760 (and (match_operand 1 "register_operand" "")
8761 (match_operand 2 "const_int_operand" "")))
8762 (clobber (reg:CC 17))]
8763 "reload_completed
8764 && QI_REG_P (operands[0])
8765 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8766 && !(~INTVAL (operands[2]) & ~(255 << 8))
8767 && GET_MODE (operands[0]) != QImode"
8768 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8769 (and:SI (zero_extract:SI (match_dup 1)
8770 (const_int 8) (const_int 8))
8771 (match_dup 2)))
8772 (clobber (reg:CC 17))])]
8773 "operands[0] = gen_lowpart (SImode, operands[0]);
8774 operands[1] = gen_lowpart (SImode, operands[1]);
8775 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8776
8777 ;; Since AND can be encoded with sign extended immediate, this is only
8778 ;; profitable when 7th bit is not set.
8779 (define_split
8780 [(set (match_operand 0 "register_operand" "")
8781 (and (match_operand 1 "general_operand" "")
8782 (match_operand 2 "const_int_operand" "")))
8783 (clobber (reg:CC 17))]
8784 "reload_completed
8785 && ANY_QI_REG_P (operands[0])
8786 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8787 && !(~INTVAL (operands[2]) & ~255)
8788 && !(INTVAL (operands[2]) & 128)
8789 && GET_MODE (operands[0]) != QImode"
8790 [(parallel [(set (strict_low_part (match_dup 0))
8791 (and:QI (match_dup 1)
8792 (match_dup 2)))
8793 (clobber (reg:CC 17))])]
8794 "operands[0] = gen_lowpart (QImode, operands[0]);
8795 operands[1] = gen_lowpart (QImode, operands[1]);
8796 operands[2] = gen_lowpart (QImode, operands[2]);")
8797 \f
8798 ;; Logical inclusive OR instructions
8799
8800 ;; %%% This used to optimize known byte-wide and operations to memory.
8801 ;; If this is considered useful, it should be done with splitters.
8802
8803 (define_expand "iordi3"
8804 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8805 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8806 (match_operand:DI 2 "x86_64_general_operand" "")))
8807 (clobber (reg:CC 17))]
8808 "TARGET_64BIT"
8809 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8810
8811 (define_insn "*iordi_1_rex64"
8812 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8813 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8814 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8815 (clobber (reg:CC 17))]
8816 "TARGET_64BIT
8817 && ix86_binary_operator_ok (IOR, DImode, operands)"
8818 "or{q}\t{%2, %0|%0, %2}"
8819 [(set_attr "type" "alu")
8820 (set_attr "mode" "DI")])
8821
8822 (define_insn "*iordi_2_rex64"
8823 [(set (reg 17)
8824 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8825 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8826 (const_int 0)))
8827 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8828 (ior:DI (match_dup 1) (match_dup 2)))]
8829 "TARGET_64BIT
8830 && ix86_match_ccmode (insn, CCNOmode)
8831 && ix86_binary_operator_ok (IOR, DImode, operands)"
8832 "or{q}\t{%2, %0|%0, %2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "mode" "DI")])
8835
8836 (define_insn "*iordi_3_rex64"
8837 [(set (reg 17)
8838 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8839 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8840 (const_int 0)))
8841 (clobber (match_scratch:DI 0 "=r"))]
8842 "TARGET_64BIT
8843 && ix86_match_ccmode (insn, CCNOmode)
8844 && ix86_binary_operator_ok (IOR, DImode, operands)"
8845 "or{q}\t{%2, %0|%0, %2}"
8846 [(set_attr "type" "alu")
8847 (set_attr "mode" "DI")])
8848
8849
8850 (define_expand "iorsi3"
8851 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8852 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8853 (match_operand:SI 2 "general_operand" "")))
8854 (clobber (reg:CC 17))]
8855 ""
8856 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8857
8858 (define_insn "*iorsi_1"
8859 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8860 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8861 (match_operand:SI 2 "general_operand" "ri,rmi")))
8862 (clobber (reg:CC 17))]
8863 "ix86_binary_operator_ok (IOR, SImode, operands)"
8864 "or{l}\t{%2, %0|%0, %2}"
8865 [(set_attr "type" "alu")
8866 (set_attr "mode" "SI")])
8867
8868 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8869 (define_insn "*iorsi_1_zext"
8870 [(set (match_operand:DI 0 "register_operand" "=rm")
8871 (zero_extend:DI
8872 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8873 (match_operand:SI 2 "general_operand" "rim"))))
8874 (clobber (reg:CC 17))]
8875 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8876 "or{l}\t{%2, %k0|%k0, %2}"
8877 [(set_attr "type" "alu")
8878 (set_attr "mode" "SI")])
8879
8880 (define_insn "*iorsi_1_zext_imm"
8881 [(set (match_operand:DI 0 "register_operand" "=rm")
8882 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8883 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8884 (clobber (reg:CC 17))]
8885 "TARGET_64BIT"
8886 "or{l}\t{%2, %k0|%k0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "mode" "SI")])
8889
8890 (define_insn "*iorsi_2"
8891 [(set (reg 17)
8892 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8893 (match_operand:SI 2 "general_operand" "rim,ri"))
8894 (const_int 0)))
8895 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8896 (ior:SI (match_dup 1) (match_dup 2)))]
8897 "ix86_match_ccmode (insn, CCNOmode)
8898 && ix86_binary_operator_ok (IOR, SImode, operands)"
8899 "or{l}\t{%2, %0|%0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "SI")])
8902
8903 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8904 ;; ??? Special case for immediate operand is missing - it is tricky.
8905 (define_insn "*iorsi_2_zext"
8906 [(set (reg 17)
8907 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8908 (match_operand:SI 2 "general_operand" "rim"))
8909 (const_int 0)))
8910 (set (match_operand:DI 0 "register_operand" "=r")
8911 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8912 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8913 && ix86_binary_operator_ok (IOR, SImode, operands)"
8914 "or{l}\t{%2, %k0|%k0, %2}"
8915 [(set_attr "type" "alu")
8916 (set_attr "mode" "SI")])
8917
8918 (define_insn "*iorsi_2_zext_imm"
8919 [(set (reg 17)
8920 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8922 (const_int 0)))
8923 (set (match_operand:DI 0 "register_operand" "=r")
8924 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8925 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8926 && ix86_binary_operator_ok (IOR, SImode, operands)"
8927 "or{l}\t{%2, %k0|%k0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "mode" "SI")])
8930
8931 (define_insn "*iorsi_3"
8932 [(set (reg 17)
8933 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8934 (match_operand:SI 2 "general_operand" "rim"))
8935 (const_int 0)))
8936 (clobber (match_scratch:SI 0 "=r"))]
8937 "ix86_match_ccmode (insn, CCNOmode)
8938 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8939 "or{l}\t{%2, %0|%0, %2}"
8940 [(set_attr "type" "alu")
8941 (set_attr "mode" "SI")])
8942
8943 (define_expand "iorhi3"
8944 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8945 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8946 (match_operand:HI 2 "general_operand" "")))
8947 (clobber (reg:CC 17))]
8948 "TARGET_HIMODE_MATH"
8949 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8950
8951 (define_insn "*iorhi_1"
8952 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8953 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8954 (match_operand:HI 2 "general_operand" "rmi,ri")))
8955 (clobber (reg:CC 17))]
8956 "ix86_binary_operator_ok (IOR, HImode, operands)"
8957 "or{w}\t{%2, %0|%0, %2}"
8958 [(set_attr "type" "alu")
8959 (set_attr "mode" "HI")])
8960
8961 (define_insn "*iorhi_2"
8962 [(set (reg 17)
8963 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8964 (match_operand:HI 2 "general_operand" "rim,ri"))
8965 (const_int 0)))
8966 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8967 (ior:HI (match_dup 1) (match_dup 2)))]
8968 "ix86_match_ccmode (insn, CCNOmode)
8969 && ix86_binary_operator_ok (IOR, HImode, operands)"
8970 "or{w}\t{%2, %0|%0, %2}"
8971 [(set_attr "type" "alu")
8972 (set_attr "mode" "HI")])
8973
8974 (define_insn "*iorhi_3"
8975 [(set (reg 17)
8976 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8977 (match_operand:HI 2 "general_operand" "rim"))
8978 (const_int 0)))
8979 (clobber (match_scratch:HI 0 "=r"))]
8980 "ix86_match_ccmode (insn, CCNOmode)
8981 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8982 "or{w}\t{%2, %0|%0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "HI")])
8985
8986 (define_expand "iorqi3"
8987 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8988 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8989 (match_operand:QI 2 "general_operand" "")))
8990 (clobber (reg:CC 17))]
8991 "TARGET_QIMODE_MATH"
8992 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8993
8994 ;; %%% Potential partial reg stall on alternative 2. What to do?
8995 (define_insn "*iorqi_1"
8996 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8997 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8998 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8999 (clobber (reg:CC 17))]
9000 "ix86_binary_operator_ok (IOR, QImode, operands)"
9001 "@
9002 or{b}\t{%2, %0|%0, %2}
9003 or{b}\t{%2, %0|%0, %2}
9004 or{l}\t{%k2, %k0|%k0, %k2}"
9005 [(set_attr "type" "alu")
9006 (set_attr "mode" "QI,QI,SI")])
9007
9008 (define_insn "*iorqi_1_slp"
9009 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9010 (ior:QI (match_dup 0)
9011 (match_operand:QI 1 "general_operand" "qmi,qi")))
9012 (clobber (reg:CC 17))]
9013 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9014 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9015 "or{b}\t{%1, %0|%0, %1}"
9016 [(set_attr "type" "alu1")
9017 (set_attr "mode" "QI")])
9018
9019 (define_insn "*iorqi_2"
9020 [(set (reg 17)
9021 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9022 (match_operand:QI 2 "general_operand" "qim,qi"))
9023 (const_int 0)))
9024 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9025 (ior:QI (match_dup 1) (match_dup 2)))]
9026 "ix86_match_ccmode (insn, CCNOmode)
9027 && ix86_binary_operator_ok (IOR, QImode, operands)"
9028 "or{b}\t{%2, %0|%0, %2}"
9029 [(set_attr "type" "alu")
9030 (set_attr "mode" "QI")])
9031
9032 (define_insn "*iorqi_2_slp"
9033 [(set (reg 17)
9034 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9035 (match_operand:QI 1 "general_operand" "qim,qi"))
9036 (const_int 0)))
9037 (set (strict_low_part (match_dup 0))
9038 (ior:QI (match_dup 0) (match_dup 1)))]
9039 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9040 && ix86_match_ccmode (insn, CCNOmode)
9041 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9042 "or{b}\t{%1, %0|%0, %1}"
9043 [(set_attr "type" "alu1")
9044 (set_attr "mode" "QI")])
9045
9046 (define_insn "*iorqi_3"
9047 [(set (reg 17)
9048 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9049 (match_operand:QI 2 "general_operand" "qim"))
9050 (const_int 0)))
9051 (clobber (match_scratch:QI 0 "=q"))]
9052 "ix86_match_ccmode (insn, CCNOmode)
9053 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9054 "or{b}\t{%2, %0|%0, %2}"
9055 [(set_attr "type" "alu")
9056 (set_attr "mode" "QI")])
9057
9058 (define_insn "iorqi_ext_0"
9059 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9060 (const_int 8)
9061 (const_int 8))
9062 (ior:SI
9063 (zero_extract:SI
9064 (match_operand 1 "ext_register_operand" "0")
9065 (const_int 8)
9066 (const_int 8))
9067 (match_operand 2 "const_int_operand" "n")))
9068 (clobber (reg:CC 17))]
9069 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9070 "or{b}\t{%2, %h0|%h0, %2}"
9071 [(set_attr "type" "alu")
9072 (set_attr "length_immediate" "1")
9073 (set_attr "mode" "QI")])
9074
9075 (define_insn "*iorqi_ext_1"
9076 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9077 (const_int 8)
9078 (const_int 8))
9079 (ior:SI
9080 (zero_extract:SI
9081 (match_operand 1 "ext_register_operand" "0")
9082 (const_int 8)
9083 (const_int 8))
9084 (zero_extend:SI
9085 (match_operand:QI 2 "general_operand" "Qm"))))
9086 (clobber (reg:CC 17))]
9087 "!TARGET_64BIT
9088 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9089 "or{b}\t{%2, %h0|%h0, %2}"
9090 [(set_attr "type" "alu")
9091 (set_attr "length_immediate" "0")
9092 (set_attr "mode" "QI")])
9093
9094 (define_insn "*iorqi_ext_1_rex64"
9095 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9096 (const_int 8)
9097 (const_int 8))
9098 (ior:SI
9099 (zero_extract:SI
9100 (match_operand 1 "ext_register_operand" "0")
9101 (const_int 8)
9102 (const_int 8))
9103 (zero_extend:SI
9104 (match_operand 2 "ext_register_operand" "Q"))))
9105 (clobber (reg:CC 17))]
9106 "TARGET_64BIT
9107 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9108 "or{b}\t{%2, %h0|%h0, %2}"
9109 [(set_attr "type" "alu")
9110 (set_attr "length_immediate" "0")
9111 (set_attr "mode" "QI")])
9112
9113 (define_insn "*iorqi_ext_2"
9114 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115 (const_int 8)
9116 (const_int 8))
9117 (ior:SI
9118 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9119 (const_int 8)
9120 (const_int 8))
9121 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9122 (const_int 8)
9123 (const_int 8))))
9124 (clobber (reg:CC 17))]
9125 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9126 "ior{b}\t{%h2, %h0|%h0, %h2}"
9127 [(set_attr "type" "alu")
9128 (set_attr "length_immediate" "0")
9129 (set_attr "mode" "QI")])
9130
9131 (define_split
9132 [(set (match_operand 0 "register_operand" "")
9133 (ior (match_operand 1 "register_operand" "")
9134 (match_operand 2 "const_int_operand" "")))
9135 (clobber (reg:CC 17))]
9136 "reload_completed
9137 && QI_REG_P (operands[0])
9138 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9139 && !(INTVAL (operands[2]) & ~(255 << 8))
9140 && GET_MODE (operands[0]) != QImode"
9141 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9142 (ior:SI (zero_extract:SI (match_dup 1)
9143 (const_int 8) (const_int 8))
9144 (match_dup 2)))
9145 (clobber (reg:CC 17))])]
9146 "operands[0] = gen_lowpart (SImode, operands[0]);
9147 operands[1] = gen_lowpart (SImode, operands[1]);
9148 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9149
9150 ;; Since OR can be encoded with sign extended immediate, this is only
9151 ;; profitable when 7th bit is set.
9152 (define_split
9153 [(set (match_operand 0 "register_operand" "")
9154 (ior (match_operand 1 "general_operand" "")
9155 (match_operand 2 "const_int_operand" "")))
9156 (clobber (reg:CC 17))]
9157 "reload_completed
9158 && ANY_QI_REG_P (operands[0])
9159 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9160 && !(INTVAL (operands[2]) & ~255)
9161 && (INTVAL (operands[2]) & 128)
9162 && GET_MODE (operands[0]) != QImode"
9163 [(parallel [(set (strict_low_part (match_dup 0))
9164 (ior:QI (match_dup 1)
9165 (match_dup 2)))
9166 (clobber (reg:CC 17))])]
9167 "operands[0] = gen_lowpart (QImode, operands[0]);
9168 operands[1] = gen_lowpart (QImode, operands[1]);
9169 operands[2] = gen_lowpart (QImode, operands[2]);")
9170 \f
9171 ;; Logical XOR instructions
9172
9173 ;; %%% This used to optimize known byte-wide and operations to memory.
9174 ;; If this is considered useful, it should be done with splitters.
9175
9176 (define_expand "xordi3"
9177 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9178 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9179 (match_operand:DI 2 "x86_64_general_operand" "")))
9180 (clobber (reg:CC 17))]
9181 "TARGET_64BIT"
9182 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9183
9184 (define_insn "*xordi_1_rex64"
9185 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9186 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9187 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9188 (clobber (reg:CC 17))]
9189 "TARGET_64BIT
9190 && ix86_binary_operator_ok (XOR, DImode, operands)"
9191 "@
9192 xor{q}\t{%2, %0|%0, %2}
9193 xor{q}\t{%2, %0|%0, %2}"
9194 [(set_attr "type" "alu")
9195 (set_attr "mode" "DI,DI")])
9196
9197 (define_insn "*xordi_2_rex64"
9198 [(set (reg 17)
9199 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9200 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9201 (const_int 0)))
9202 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9203 (xor:DI (match_dup 1) (match_dup 2)))]
9204 "TARGET_64BIT
9205 && ix86_match_ccmode (insn, CCNOmode)
9206 && ix86_binary_operator_ok (XOR, DImode, operands)"
9207 "@
9208 xor{q}\t{%2, %0|%0, %2}
9209 xor{q}\t{%2, %0|%0, %2}"
9210 [(set_attr "type" "alu")
9211 (set_attr "mode" "DI,DI")])
9212
9213 (define_insn "*xordi_3_rex64"
9214 [(set (reg 17)
9215 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9216 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9217 (const_int 0)))
9218 (clobber (match_scratch:DI 0 "=r"))]
9219 "TARGET_64BIT
9220 && ix86_match_ccmode (insn, CCNOmode)
9221 && ix86_binary_operator_ok (XOR, DImode, operands)"
9222 "xor{q}\t{%2, %0|%0, %2}"
9223 [(set_attr "type" "alu")
9224 (set_attr "mode" "DI")])
9225
9226 (define_expand "xorsi3"
9227 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9228 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9229 (match_operand:SI 2 "general_operand" "")))
9230 (clobber (reg:CC 17))]
9231 ""
9232 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9233
9234 (define_insn "*xorsi_1"
9235 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9236 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9237 (match_operand:SI 2 "general_operand" "ri,rm")))
9238 (clobber (reg:CC 17))]
9239 "ix86_binary_operator_ok (XOR, SImode, operands)"
9240 "xor{l}\t{%2, %0|%0, %2}"
9241 [(set_attr "type" "alu")
9242 (set_attr "mode" "SI")])
9243
9244 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9245 ;; Add speccase for immediates
9246 (define_insn "*xorsi_1_zext"
9247 [(set (match_operand:DI 0 "register_operand" "=r")
9248 (zero_extend:DI
9249 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9250 (match_operand:SI 2 "general_operand" "rim"))))
9251 (clobber (reg:CC 17))]
9252 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9253 "xor{l}\t{%2, %k0|%k0, %2}"
9254 [(set_attr "type" "alu")
9255 (set_attr "mode" "SI")])
9256
9257 (define_insn "*xorsi_1_zext_imm"
9258 [(set (match_operand:DI 0 "register_operand" "=r")
9259 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9260 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9261 (clobber (reg:CC 17))]
9262 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9263 "xor{l}\t{%2, %k0|%k0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "mode" "SI")])
9266
9267 (define_insn "*xorsi_2"
9268 [(set (reg 17)
9269 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9270 (match_operand:SI 2 "general_operand" "rim,ri"))
9271 (const_int 0)))
9272 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9273 (xor:SI (match_dup 1) (match_dup 2)))]
9274 "ix86_match_ccmode (insn, CCNOmode)
9275 && ix86_binary_operator_ok (XOR, SImode, operands)"
9276 "xor{l}\t{%2, %0|%0, %2}"
9277 [(set_attr "type" "alu")
9278 (set_attr "mode" "SI")])
9279
9280 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9281 ;; ??? Special case for immediate operand is missing - it is tricky.
9282 (define_insn "*xorsi_2_zext"
9283 [(set (reg 17)
9284 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9285 (match_operand:SI 2 "general_operand" "rim"))
9286 (const_int 0)))
9287 (set (match_operand:DI 0 "register_operand" "=r")
9288 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9289 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9290 && ix86_binary_operator_ok (XOR, SImode, operands)"
9291 "xor{l}\t{%2, %k0|%k0, %2}"
9292 [(set_attr "type" "alu")
9293 (set_attr "mode" "SI")])
9294
9295 (define_insn "*xorsi_2_zext_imm"
9296 [(set (reg 17)
9297 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9298 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9299 (const_int 0)))
9300 (set (match_operand:DI 0 "register_operand" "=r")
9301 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9302 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9303 && ix86_binary_operator_ok (XOR, SImode, operands)"
9304 "xor{l}\t{%2, %k0|%k0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "SI")])
9307
9308 (define_insn "*xorsi_3"
9309 [(set (reg 17)
9310 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9311 (match_operand:SI 2 "general_operand" "rim"))
9312 (const_int 0)))
9313 (clobber (match_scratch:SI 0 "=r"))]
9314 "ix86_match_ccmode (insn, CCNOmode)
9315 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9316 "xor{l}\t{%2, %0|%0, %2}"
9317 [(set_attr "type" "alu")
9318 (set_attr "mode" "SI")])
9319
9320 (define_expand "xorhi3"
9321 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9322 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9323 (match_operand:HI 2 "general_operand" "")))
9324 (clobber (reg:CC 17))]
9325 "TARGET_HIMODE_MATH"
9326 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9327
9328 (define_insn "*xorhi_1"
9329 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9330 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9331 (match_operand:HI 2 "general_operand" "rmi,ri")))
9332 (clobber (reg:CC 17))]
9333 "ix86_binary_operator_ok (XOR, HImode, operands)"
9334 "xor{w}\t{%2, %0|%0, %2}"
9335 [(set_attr "type" "alu")
9336 (set_attr "mode" "HI")])
9337
9338 (define_insn "*xorhi_2"
9339 [(set (reg 17)
9340 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9341 (match_operand:HI 2 "general_operand" "rim,ri"))
9342 (const_int 0)))
9343 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9344 (xor:HI (match_dup 1) (match_dup 2)))]
9345 "ix86_match_ccmode (insn, CCNOmode)
9346 && ix86_binary_operator_ok (XOR, HImode, operands)"
9347 "xor{w}\t{%2, %0|%0, %2}"
9348 [(set_attr "type" "alu")
9349 (set_attr "mode" "HI")])
9350
9351 (define_insn "*xorhi_3"
9352 [(set (reg 17)
9353 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9354 (match_operand:HI 2 "general_operand" "rim"))
9355 (const_int 0)))
9356 (clobber (match_scratch:HI 0 "=r"))]
9357 "ix86_match_ccmode (insn, CCNOmode)
9358 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9359 "xor{w}\t{%2, %0|%0, %2}"
9360 [(set_attr "type" "alu")
9361 (set_attr "mode" "HI")])
9362
9363 (define_expand "xorqi3"
9364 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9365 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9366 (match_operand:QI 2 "general_operand" "")))
9367 (clobber (reg:CC 17))]
9368 "TARGET_QIMODE_MATH"
9369 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9370
9371 ;; %%% Potential partial reg stall on alternative 2. What to do?
9372 (define_insn "*xorqi_1"
9373 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9374 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9375 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9376 (clobber (reg:CC 17))]
9377 "ix86_binary_operator_ok (XOR, QImode, operands)"
9378 "@
9379 xor{b}\t{%2, %0|%0, %2}
9380 xor{b}\t{%2, %0|%0, %2}
9381 xor{l}\t{%k2, %k0|%k0, %k2}"
9382 [(set_attr "type" "alu")
9383 (set_attr "mode" "QI,QI,SI")])
9384
9385 (define_insn "*xorqi_1_slp"
9386 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9387 (xor:QI (match_dup 0)
9388 (match_operand:QI 1 "general_operand" "qi,qmi")))
9389 (clobber (reg:CC 17))]
9390 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9391 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9392 "xor{b}\t{%1, %0|%0, %1}"
9393 [(set_attr "type" "alu1")
9394 (set_attr "mode" "QI")])
9395
9396 (define_insn "xorqi_ext_0"
9397 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9398 (const_int 8)
9399 (const_int 8))
9400 (xor:SI
9401 (zero_extract:SI
9402 (match_operand 1 "ext_register_operand" "0")
9403 (const_int 8)
9404 (const_int 8))
9405 (match_operand 2 "const_int_operand" "n")))
9406 (clobber (reg:CC 17))]
9407 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9408 "xor{b}\t{%2, %h0|%h0, %2}"
9409 [(set_attr "type" "alu")
9410 (set_attr "length_immediate" "1")
9411 (set_attr "mode" "QI")])
9412
9413 (define_insn "*xorqi_ext_1"
9414 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9415 (const_int 8)
9416 (const_int 8))
9417 (xor:SI
9418 (zero_extract:SI
9419 (match_operand 1 "ext_register_operand" "0")
9420 (const_int 8)
9421 (const_int 8))
9422 (zero_extend:SI
9423 (match_operand:QI 2 "general_operand" "Qm"))))
9424 (clobber (reg:CC 17))]
9425 "!TARGET_64BIT
9426 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9427 "xor{b}\t{%2, %h0|%h0, %2}"
9428 [(set_attr "type" "alu")
9429 (set_attr "length_immediate" "0")
9430 (set_attr "mode" "QI")])
9431
9432 (define_insn "*xorqi_ext_1_rex64"
9433 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9434 (const_int 8)
9435 (const_int 8))
9436 (xor:SI
9437 (zero_extract:SI
9438 (match_operand 1 "ext_register_operand" "0")
9439 (const_int 8)
9440 (const_int 8))
9441 (zero_extend:SI
9442 (match_operand 2 "ext_register_operand" "Q"))))
9443 (clobber (reg:CC 17))]
9444 "TARGET_64BIT
9445 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9446 "xor{b}\t{%2, %h0|%h0, %2}"
9447 [(set_attr "type" "alu")
9448 (set_attr "length_immediate" "0")
9449 (set_attr "mode" "QI")])
9450
9451 (define_insn "*xorqi_ext_2"
9452 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9453 (const_int 8)
9454 (const_int 8))
9455 (xor:SI
9456 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9457 (const_int 8)
9458 (const_int 8))
9459 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9460 (const_int 8)
9461 (const_int 8))))
9462 (clobber (reg:CC 17))]
9463 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9464 "xor{b}\t{%h2, %h0|%h0, %h2}"
9465 [(set_attr "type" "alu")
9466 (set_attr "length_immediate" "0")
9467 (set_attr "mode" "QI")])
9468
9469 (define_insn "*xorqi_cc_1"
9470 [(set (reg 17)
9471 (compare
9472 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9473 (match_operand:QI 2 "general_operand" "qim,qi"))
9474 (const_int 0)))
9475 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9476 (xor:QI (match_dup 1) (match_dup 2)))]
9477 "ix86_match_ccmode (insn, CCNOmode)
9478 && ix86_binary_operator_ok (XOR, QImode, operands)"
9479 "xor{b}\t{%2, %0|%0, %2}"
9480 [(set_attr "type" "alu")
9481 (set_attr "mode" "QI")])
9482
9483 (define_insn "*xorqi_2_slp"
9484 [(set (reg 17)
9485 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9486 (match_operand:QI 1 "general_operand" "qim,qi"))
9487 (const_int 0)))
9488 (set (strict_low_part (match_dup 0))
9489 (xor:QI (match_dup 0) (match_dup 1)))]
9490 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9491 && ix86_match_ccmode (insn, CCNOmode)
9492 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9493 "xor{b}\t{%1, %0|%0, %1}"
9494 [(set_attr "type" "alu1")
9495 (set_attr "mode" "QI")])
9496
9497 (define_insn "*xorqi_cc_2"
9498 [(set (reg 17)
9499 (compare
9500 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9501 (match_operand:QI 2 "general_operand" "qim"))
9502 (const_int 0)))
9503 (clobber (match_scratch:QI 0 "=q"))]
9504 "ix86_match_ccmode (insn, CCNOmode)
9505 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9506 "xor{b}\t{%2, %0|%0, %2}"
9507 [(set_attr "type" "alu")
9508 (set_attr "mode" "QI")])
9509
9510 (define_insn "*xorqi_cc_ext_1"
9511 [(set (reg 17)
9512 (compare
9513 (xor:SI
9514 (zero_extract:SI
9515 (match_operand 1 "ext_register_operand" "0")
9516 (const_int 8)
9517 (const_int 8))
9518 (match_operand:QI 2 "general_operand" "qmn"))
9519 (const_int 0)))
9520 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9521 (const_int 8)
9522 (const_int 8))
9523 (xor:SI
9524 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9525 (match_dup 2)))]
9526 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9527 "xor{b}\t{%2, %h0|%h0, %2}"
9528 [(set_attr "type" "alu")
9529 (set_attr "mode" "QI")])
9530
9531 (define_insn "*xorqi_cc_ext_1_rex64"
9532 [(set (reg 17)
9533 (compare
9534 (xor:SI
9535 (zero_extract:SI
9536 (match_operand 1 "ext_register_operand" "0")
9537 (const_int 8)
9538 (const_int 8))
9539 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9540 (const_int 0)))
9541 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9542 (const_int 8)
9543 (const_int 8))
9544 (xor:SI
9545 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9546 (match_dup 2)))]
9547 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9548 "xor{b}\t{%2, %h0|%h0, %2}"
9549 [(set_attr "type" "alu")
9550 (set_attr "mode" "QI")])
9551
9552 (define_expand "xorqi_cc_ext_1"
9553 [(parallel [
9554 (set (reg:CCNO 17)
9555 (compare:CCNO
9556 (xor:SI
9557 (zero_extract:SI
9558 (match_operand 1 "ext_register_operand" "")
9559 (const_int 8)
9560 (const_int 8))
9561 (match_operand:QI 2 "general_operand" ""))
9562 (const_int 0)))
9563 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9564 (const_int 8)
9565 (const_int 8))
9566 (xor:SI
9567 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9568 (match_dup 2)))])]
9569 ""
9570 "")
9571
9572 (define_split
9573 [(set (match_operand 0 "register_operand" "")
9574 (xor (match_operand 1 "register_operand" "")
9575 (match_operand 2 "const_int_operand" "")))
9576 (clobber (reg:CC 17))]
9577 "reload_completed
9578 && QI_REG_P (operands[0])
9579 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9580 && !(INTVAL (operands[2]) & ~(255 << 8))
9581 && GET_MODE (operands[0]) != QImode"
9582 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9583 (xor:SI (zero_extract:SI (match_dup 1)
9584 (const_int 8) (const_int 8))
9585 (match_dup 2)))
9586 (clobber (reg:CC 17))])]
9587 "operands[0] = gen_lowpart (SImode, operands[0]);
9588 operands[1] = gen_lowpart (SImode, operands[1]);
9589 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9590
9591 ;; Since XOR can be encoded with sign extended immediate, this is only
9592 ;; profitable when 7th bit is set.
9593 (define_split
9594 [(set (match_operand 0 "register_operand" "")
9595 (xor (match_operand 1 "general_operand" "")
9596 (match_operand 2 "const_int_operand" "")))
9597 (clobber (reg:CC 17))]
9598 "reload_completed
9599 && ANY_QI_REG_P (operands[0])
9600 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9601 && !(INTVAL (operands[2]) & ~255)
9602 && (INTVAL (operands[2]) & 128)
9603 && GET_MODE (operands[0]) != QImode"
9604 [(parallel [(set (strict_low_part (match_dup 0))
9605 (xor:QI (match_dup 1)
9606 (match_dup 2)))
9607 (clobber (reg:CC 17))])]
9608 "operands[0] = gen_lowpart (QImode, operands[0]);
9609 operands[1] = gen_lowpart (QImode, operands[1]);
9610 operands[2] = gen_lowpart (QImode, operands[2]);")
9611 \f
9612 ;; Negation instructions
9613
9614 (define_expand "negdi2"
9615 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9616 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9617 (clobber (reg:CC 17))])]
9618 ""
9619 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9620
9621 (define_insn "*negdi2_1"
9622 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9623 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9624 (clobber (reg:CC 17))]
9625 "!TARGET_64BIT
9626 && ix86_unary_operator_ok (NEG, DImode, operands)"
9627 "#")
9628
9629 (define_split
9630 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9631 (neg:DI (match_operand:DI 1 "general_operand" "")))
9632 (clobber (reg:CC 17))]
9633 "!TARGET_64BIT && reload_completed"
9634 [(parallel
9635 [(set (reg:CCZ 17)
9636 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9637 (set (match_dup 0) (neg:SI (match_dup 2)))])
9638 (parallel
9639 [(set (match_dup 1)
9640 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9641 (match_dup 3))
9642 (const_int 0)))
9643 (clobber (reg:CC 17))])
9644 (parallel
9645 [(set (match_dup 1)
9646 (neg:SI (match_dup 1)))
9647 (clobber (reg:CC 17))])]
9648 "split_di (operands+1, 1, operands+2, operands+3);
9649 split_di (operands+0, 1, operands+0, operands+1);")
9650
9651 (define_insn "*negdi2_1_rex64"
9652 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9653 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9654 (clobber (reg:CC 17))]
9655 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9656 "neg{q}\t%0"
9657 [(set_attr "type" "negnot")
9658 (set_attr "mode" "DI")])
9659
9660 ;; The problem with neg is that it does not perform (compare x 0),
9661 ;; it really performs (compare 0 x), which leaves us with the zero
9662 ;; flag being the only useful item.
9663
9664 (define_insn "*negdi2_cmpz_rex64"
9665 [(set (reg:CCZ 17)
9666 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9667 (const_int 0)))
9668 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9669 (neg:DI (match_dup 1)))]
9670 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9671 "neg{q}\t%0"
9672 [(set_attr "type" "negnot")
9673 (set_attr "mode" "DI")])
9674
9675
9676 (define_expand "negsi2"
9677 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9678 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9679 (clobber (reg:CC 17))])]
9680 ""
9681 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9682
9683 (define_insn "*negsi2_1"
9684 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9685 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9686 (clobber (reg:CC 17))]
9687 "ix86_unary_operator_ok (NEG, SImode, operands)"
9688 "neg{l}\t%0"
9689 [(set_attr "type" "negnot")
9690 (set_attr "mode" "SI")])
9691
9692 ;; Combine is quite creative about this pattern.
9693 (define_insn "*negsi2_1_zext"
9694 [(set (match_operand:DI 0 "register_operand" "=r")
9695 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9696 (const_int 32)))
9697 (const_int 32)))
9698 (clobber (reg:CC 17))]
9699 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9700 "neg{l}\t%k0"
9701 [(set_attr "type" "negnot")
9702 (set_attr "mode" "SI")])
9703
9704 ;; The problem with neg is that it does not perform (compare x 0),
9705 ;; it really performs (compare 0 x), which leaves us with the zero
9706 ;; flag being the only useful item.
9707
9708 (define_insn "*negsi2_cmpz"
9709 [(set (reg:CCZ 17)
9710 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9711 (const_int 0)))
9712 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9713 (neg:SI (match_dup 1)))]
9714 "ix86_unary_operator_ok (NEG, SImode, operands)"
9715 "neg{l}\t%0"
9716 [(set_attr "type" "negnot")
9717 (set_attr "mode" "SI")])
9718
9719 (define_insn "*negsi2_cmpz_zext"
9720 [(set (reg:CCZ 17)
9721 (compare:CCZ (lshiftrt:DI
9722 (neg:DI (ashift:DI
9723 (match_operand:DI 1 "register_operand" "0")
9724 (const_int 32)))
9725 (const_int 32))
9726 (const_int 0)))
9727 (set (match_operand:DI 0 "register_operand" "=r")
9728 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9729 (const_int 32)))
9730 (const_int 32)))]
9731 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9732 "neg{l}\t%k0"
9733 [(set_attr "type" "negnot")
9734 (set_attr "mode" "SI")])
9735
9736 (define_expand "neghi2"
9737 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9738 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9739 (clobber (reg:CC 17))])]
9740 "TARGET_HIMODE_MATH"
9741 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9742
9743 (define_insn "*neghi2_1"
9744 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9745 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9746 (clobber (reg:CC 17))]
9747 "ix86_unary_operator_ok (NEG, HImode, operands)"
9748 "neg{w}\t%0"
9749 [(set_attr "type" "negnot")
9750 (set_attr "mode" "HI")])
9751
9752 (define_insn "*neghi2_cmpz"
9753 [(set (reg:CCZ 17)
9754 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9755 (const_int 0)))
9756 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9757 (neg:HI (match_dup 1)))]
9758 "ix86_unary_operator_ok (NEG, HImode, operands)"
9759 "neg{w}\t%0"
9760 [(set_attr "type" "negnot")
9761 (set_attr "mode" "HI")])
9762
9763 (define_expand "negqi2"
9764 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9765 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9766 (clobber (reg:CC 17))])]
9767 "TARGET_QIMODE_MATH"
9768 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9769
9770 (define_insn "*negqi2_1"
9771 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9772 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9773 (clobber (reg:CC 17))]
9774 "ix86_unary_operator_ok (NEG, QImode, operands)"
9775 "neg{b}\t%0"
9776 [(set_attr "type" "negnot")
9777 (set_attr "mode" "QI")])
9778
9779 (define_insn "*negqi2_cmpz"
9780 [(set (reg:CCZ 17)
9781 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9782 (const_int 0)))
9783 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9784 (neg:QI (match_dup 1)))]
9785 "ix86_unary_operator_ok (NEG, QImode, operands)"
9786 "neg{b}\t%0"
9787 [(set_attr "type" "negnot")
9788 (set_attr "mode" "QI")])
9789
9790 ;; Changing of sign for FP values is doable using integer unit too.
9791
9792 (define_expand "negsf2"
9793 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9794 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9795 (clobber (reg:CC 17))])]
9796 "TARGET_80387"
9797 "if (TARGET_SSE)
9798 {
9799 /* In case operand is in memory, we will not use SSE. */
9800 if (memory_operand (operands[0], VOIDmode)
9801 && rtx_equal_p (operands[0], operands[1]))
9802 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9803 else
9804 {
9805 /* Using SSE is tricky, since we need bitwise negation of -0
9806 in register. */
9807 rtx reg = gen_reg_rtx (SFmode);
9808 rtx dest = operands[0];
9809 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9810
9811 operands[1] = force_reg (SFmode, operands[1]);
9812 operands[0] = force_reg (SFmode, operands[0]);
9813 reg = force_reg (V4SFmode,
9814 gen_rtx_CONST_VECTOR (V4SFmode,
9815 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9816 CONST0_RTX (SFmode),
9817 CONST0_RTX (SFmode))));
9818 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9819 if (dest != operands[0])
9820 emit_move_insn (dest, operands[0]);
9821 }
9822 DONE;
9823 }
9824 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9825
9826 (define_insn "negsf2_memory"
9827 [(set (match_operand:SF 0 "memory_operand" "=m")
9828 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9829 (clobber (reg:CC 17))]
9830 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9831 "#")
9832
9833 (define_insn "negsf2_ifs"
9834 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9835 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9836 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9837 (clobber (reg:CC 17))]
9838 "TARGET_SSE
9839 && (reload_in_progress || reload_completed
9840 || (register_operand (operands[0], VOIDmode)
9841 && register_operand (operands[1], VOIDmode)))"
9842 "#")
9843
9844 (define_split
9845 [(set (match_operand:SF 0 "memory_operand" "")
9846 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9847 (use (match_operand:SF 2 "" ""))
9848 (clobber (reg:CC 17))]
9849 ""
9850 [(parallel [(set (match_dup 0)
9851 (neg:SF (match_dup 1)))
9852 (clobber (reg:CC 17))])])
9853
9854 (define_split
9855 [(set (match_operand:SF 0 "register_operand" "")
9856 (neg:SF (match_operand:SF 1 "register_operand" "")))
9857 (use (match_operand:V4SF 2 "" ""))
9858 (clobber (reg:CC 17))]
9859 "reload_completed && !SSE_REG_P (operands[0])"
9860 [(parallel [(set (match_dup 0)
9861 (neg:SF (match_dup 1)))
9862 (clobber (reg:CC 17))])])
9863
9864 (define_split
9865 [(set (match_operand:SF 0 "register_operand" "")
9866 (neg:SF (match_operand:SF 1 "register_operand" "")))
9867 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9868 (clobber (reg:CC 17))]
9869 "reload_completed && SSE_REG_P (operands[0])"
9870 [(set (subreg:TI (match_dup 0) 0)
9871 (xor:TI (match_dup 1)
9872 (match_dup 2)))]
9873 {
9874 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9875 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9876 if (operands_match_p (operands[0], operands[2]))
9877 {
9878 rtx tmp;
9879 tmp = operands[1];
9880 operands[1] = operands[2];
9881 operands[2] = tmp;
9882 }
9883 })
9884
9885
9886 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9887 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9888 ;; to itself.
9889 (define_insn "*negsf2_if"
9890 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9891 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9892 (clobber (reg:CC 17))]
9893 "TARGET_80387 && !TARGET_SSE
9894 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9895 "#")
9896
9897 (define_split
9898 [(set (match_operand:SF 0 "fp_register_operand" "")
9899 (neg:SF (match_operand:SF 1 "register_operand" "")))
9900 (clobber (reg:CC 17))]
9901 "TARGET_80387 && reload_completed"
9902 [(set (match_dup 0)
9903 (neg:SF (match_dup 1)))]
9904 "")
9905
9906 (define_split
9907 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9908 (neg:SF (match_operand:SF 1 "register_operand" "")))
9909 (clobber (reg:CC 17))]
9910 "TARGET_80387 && reload_completed"
9911 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9912 (clobber (reg:CC 17))])]
9913 "operands[1] = gen_int_mode (0x80000000, SImode);
9914 operands[0] = gen_lowpart (SImode, operands[0]);")
9915
9916 (define_split
9917 [(set (match_operand 0 "memory_operand" "")
9918 (neg (match_operand 1 "memory_operand" "")))
9919 (clobber (reg:CC 17))]
9920 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9921 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9922 (clobber (reg:CC 17))])]
9923 {
9924 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9925
9926 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9927 if (size >= 12)
9928 size = 10;
9929 operands[0] = adjust_address (operands[0], QImode, size - 1);
9930 operands[1] = gen_int_mode (0x80, QImode);
9931 })
9932
9933 (define_expand "negdf2"
9934 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9935 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9936 (clobber (reg:CC 17))])]
9937 "TARGET_80387"
9938 "if (TARGET_SSE2)
9939 {
9940 /* In case operand is in memory, we will not use SSE. */
9941 if (memory_operand (operands[0], VOIDmode)
9942 && rtx_equal_p (operands[0], operands[1]))
9943 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9944 else
9945 {
9946 /* Using SSE is tricky, since we need bitwise negation of -0
9947 in register. */
9948 rtx reg;
9949 #if HOST_BITS_PER_WIDE_INT >= 64
9950 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9951 #else
9952 rtx imm = immed_double_const (0, 0x80000000, DImode);
9953 #endif
9954 rtx dest = operands[0];
9955
9956 operands[1] = force_reg (DFmode, operands[1]);
9957 operands[0] = force_reg (DFmode, operands[0]);
9958 imm = gen_lowpart (DFmode, imm);
9959 reg = force_reg (V2DFmode,
9960 gen_rtx_CONST_VECTOR (V2DFmode,
9961 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9962 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9963 if (dest != operands[0])
9964 emit_move_insn (dest, operands[0]);
9965 }
9966 DONE;
9967 }
9968 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9969
9970 (define_insn "negdf2_memory"
9971 [(set (match_operand:DF 0 "memory_operand" "=m")
9972 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9973 (clobber (reg:CC 17))]
9974 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9975 "#")
9976
9977 (define_insn "negdf2_ifs"
9978 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9979 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9980 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9981 (clobber (reg:CC 17))]
9982 "!TARGET_64BIT && TARGET_SSE2
9983 && (reload_in_progress || reload_completed
9984 || (register_operand (operands[0], VOIDmode)
9985 && register_operand (operands[1], VOIDmode)))"
9986 "#")
9987
9988 (define_insn "*negdf2_ifs_rex64"
9989 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9990 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9991 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9992 (clobber (reg:CC 17))]
9993 "TARGET_64BIT && TARGET_SSE2
9994 && (reload_in_progress || reload_completed
9995 || (register_operand (operands[0], VOIDmode)
9996 && register_operand (operands[1], VOIDmode)))"
9997 "#")
9998
9999 (define_split
10000 [(set (match_operand:DF 0 "memory_operand" "")
10001 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10002 (use (match_operand:V2DF 2 "" ""))
10003 (clobber (reg:CC 17))]
10004 ""
10005 [(parallel [(set (match_dup 0)
10006 (neg:DF (match_dup 1)))
10007 (clobber (reg:CC 17))])])
10008
10009 (define_split
10010 [(set (match_operand:DF 0 "register_operand" "")
10011 (neg:DF (match_operand:DF 1 "register_operand" "")))
10012 (use (match_operand:V2DF 2 "" ""))
10013 (clobber (reg:CC 17))]
10014 "reload_completed && !SSE_REG_P (operands[0])
10015 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10016 [(parallel [(set (match_dup 0)
10017 (neg:DF (match_dup 1)))
10018 (clobber (reg:CC 17))])])
10019
10020 (define_split
10021 [(set (match_operand:DF 0 "register_operand" "")
10022 (neg:DF (match_operand:DF 1 "register_operand" "")))
10023 (use (match_operand:V2DF 2 "" ""))
10024 (clobber (reg:CC 17))]
10025 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10026 [(parallel [(set (match_dup 0)
10027 (xor:DI (match_dup 1) (match_dup 2)))
10028 (clobber (reg:CC 17))])]
10029 "operands[0] = gen_lowpart (DImode, operands[0]);
10030 operands[1] = gen_lowpart (DImode, operands[1]);
10031 operands[2] = gen_lowpart (DImode, operands[2]);")
10032
10033 (define_split
10034 [(set (match_operand:DF 0 "register_operand" "")
10035 (neg:DF (match_operand:DF 1 "register_operand" "")))
10036 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10037 (clobber (reg:CC 17))]
10038 "reload_completed && SSE_REG_P (operands[0])"
10039 [(set (subreg:TI (match_dup 0) 0)
10040 (xor:TI (match_dup 1)
10041 (match_dup 2)))]
10042 {
10043 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10044 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10045 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10046 /* Avoid possible reformatting on the operands. */
10047 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10048 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10049 if (operands_match_p (operands[0], operands[2]))
10050 {
10051 rtx tmp;
10052 tmp = operands[1];
10053 operands[1] = operands[2];
10054 operands[2] = tmp;
10055 }
10056 })
10057
10058 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10059 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10060 ;; to itself.
10061 (define_insn "*negdf2_if"
10062 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10063 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10064 (clobber (reg:CC 17))]
10065 "!TARGET_64BIT && TARGET_80387
10066 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10067 "#")
10068
10069 ;; FIXME: We should to allow integer registers here. Problem is that
10070 ;; we need another scratch register to get constant from.
10071 ;; Forcing constant to mem if no register available in peep2 should be
10072 ;; safe even for PIC mode, because of RIP relative addressing.
10073 (define_insn "*negdf2_if_rex64"
10074 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10075 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10076 (clobber (reg:CC 17))]
10077 "TARGET_64BIT && TARGET_80387
10078 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10079 "#")
10080
10081 (define_split
10082 [(set (match_operand:DF 0 "fp_register_operand" "")
10083 (neg:DF (match_operand:DF 1 "register_operand" "")))
10084 (clobber (reg:CC 17))]
10085 "TARGET_80387 && reload_completed"
10086 [(set (match_dup 0)
10087 (neg:DF (match_dup 1)))]
10088 "")
10089
10090 (define_split
10091 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10092 (neg:DF (match_operand:DF 1 "register_operand" "")))
10093 (clobber (reg:CC 17))]
10094 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10095 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10096 (clobber (reg:CC 17))])]
10097 "operands[4] = gen_int_mode (0x80000000, SImode);
10098 split_di (operands+0, 1, operands+2, operands+3);")
10099
10100 (define_expand "negxf2"
10101 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10102 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10103 (clobber (reg:CC 17))])]
10104 "!TARGET_64BIT && TARGET_80387"
10105 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10106
10107 (define_expand "negtf2"
10108 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10109 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10110 (clobber (reg:CC 17))])]
10111 "TARGET_80387"
10112 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10113
10114 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10115 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10116 ;; to itself.
10117 (define_insn "*negxf2_if"
10118 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10119 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10120 (clobber (reg:CC 17))]
10121 "!TARGET_64BIT && TARGET_80387
10122 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10123 "#")
10124
10125 (define_split
10126 [(set (match_operand:XF 0 "fp_register_operand" "")
10127 (neg:XF (match_operand:XF 1 "register_operand" "")))
10128 (clobber (reg:CC 17))]
10129 "TARGET_80387 && reload_completed"
10130 [(set (match_dup 0)
10131 (neg:XF (match_dup 1)))]
10132 "")
10133
10134 (define_split
10135 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10136 (neg:XF (match_operand:XF 1 "register_operand" "")))
10137 (clobber (reg:CC 17))]
10138 "TARGET_80387 && reload_completed"
10139 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10140 (clobber (reg:CC 17))])]
10141 "operands[1] = GEN_INT (0x8000);
10142 operands[0] = gen_rtx_REG (SImode,
10143 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10144
10145 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10146 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10147 ;; to itself.
10148 (define_insn "*negtf2_if"
10149 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10150 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10151 (clobber (reg:CC 17))]
10152 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10153 "#")
10154
10155 (define_split
10156 [(set (match_operand:TF 0 "fp_register_operand" "")
10157 (neg:TF (match_operand:TF 1 "register_operand" "")))
10158 (clobber (reg:CC 17))]
10159 "TARGET_80387 && reload_completed"
10160 [(set (match_dup 0)
10161 (neg:TF (match_dup 1)))]
10162 "")
10163
10164 (define_split
10165 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10166 (neg:TF (match_operand:TF 1 "register_operand" "")))
10167 (clobber (reg:CC 17))]
10168 "TARGET_80387 && reload_completed"
10169 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10170 (clobber (reg:CC 17))])]
10171 "operands[1] = GEN_INT (0x8000);
10172 operands[0] = gen_rtx_REG (SImode,
10173 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10174
10175 ;; Conditionalize these after reload. If they matches before reload, we
10176 ;; lose the clobber and ability to use integer instructions.
10177
10178 (define_insn "*negsf2_1"
10179 [(set (match_operand:SF 0 "register_operand" "=f")
10180 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10181 "TARGET_80387 && reload_completed"
10182 "fchs"
10183 [(set_attr "type" "fsgn")
10184 (set_attr "mode" "SF")
10185 (set_attr "ppro_uops" "few")])
10186
10187 (define_insn "*negdf2_1"
10188 [(set (match_operand:DF 0 "register_operand" "=f")
10189 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10190 "TARGET_80387 && reload_completed"
10191 "fchs"
10192 [(set_attr "type" "fsgn")
10193 (set_attr "mode" "DF")
10194 (set_attr "ppro_uops" "few")])
10195
10196 (define_insn "*negextendsfdf2"
10197 [(set (match_operand:DF 0 "register_operand" "=f")
10198 (neg:DF (float_extend:DF
10199 (match_operand:SF 1 "register_operand" "0"))))]
10200 "TARGET_80387"
10201 "fchs"
10202 [(set_attr "type" "fsgn")
10203 (set_attr "mode" "DF")
10204 (set_attr "ppro_uops" "few")])
10205
10206 (define_insn "*negxf2_1"
10207 [(set (match_operand:XF 0 "register_operand" "=f")
10208 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10209 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10210 "fchs"
10211 [(set_attr "type" "fsgn")
10212 (set_attr "mode" "XF")
10213 (set_attr "ppro_uops" "few")])
10214
10215 (define_insn "*negextenddfxf2"
10216 [(set (match_operand:XF 0 "register_operand" "=f")
10217 (neg:XF (float_extend:XF
10218 (match_operand:DF 1 "register_operand" "0"))))]
10219 "!TARGET_64BIT && TARGET_80387"
10220 "fchs"
10221 [(set_attr "type" "fsgn")
10222 (set_attr "mode" "XF")
10223 (set_attr "ppro_uops" "few")])
10224
10225 (define_insn "*negextendsfxf2"
10226 [(set (match_operand:XF 0 "register_operand" "=f")
10227 (neg:XF (float_extend:XF
10228 (match_operand:SF 1 "register_operand" "0"))))]
10229 "!TARGET_64BIT && TARGET_80387"
10230 "fchs"
10231 [(set_attr "type" "fsgn")
10232 (set_attr "mode" "XF")
10233 (set_attr "ppro_uops" "few")])
10234
10235 (define_insn "*negtf2_1"
10236 [(set (match_operand:TF 0 "register_operand" "=f")
10237 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10238 "TARGET_80387 && reload_completed"
10239 "fchs"
10240 [(set_attr "type" "fsgn")
10241 (set_attr "mode" "XF")
10242 (set_attr "ppro_uops" "few")])
10243
10244 (define_insn "*negextenddftf2"
10245 [(set (match_operand:TF 0 "register_operand" "=f")
10246 (neg:TF (float_extend:TF
10247 (match_operand:DF 1 "register_operand" "0"))))]
10248 "TARGET_80387"
10249 "fchs"
10250 [(set_attr "type" "fsgn")
10251 (set_attr "mode" "XF")
10252 (set_attr "ppro_uops" "few")])
10253
10254 (define_insn "*negextendsftf2"
10255 [(set (match_operand:TF 0 "register_operand" "=f")
10256 (neg:TF (float_extend:TF
10257 (match_operand:SF 1 "register_operand" "0"))))]
10258 "TARGET_80387"
10259 "fchs"
10260 [(set_attr "type" "fsgn")
10261 (set_attr "mode" "XF")
10262 (set_attr "ppro_uops" "few")])
10263 \f
10264 ;; Absolute value instructions
10265
10266 (define_expand "abssf2"
10267 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10268 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10269 (clobber (reg:CC 17))])]
10270 "TARGET_80387"
10271 "if (TARGET_SSE)
10272 {
10273 /* In case operand is in memory, we will not use SSE. */
10274 if (memory_operand (operands[0], VOIDmode)
10275 && rtx_equal_p (operands[0], operands[1]))
10276 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10277 else
10278 {
10279 /* Using SSE is tricky, since we need bitwise negation of -0
10280 in register. */
10281 rtx reg = gen_reg_rtx (V4SFmode);
10282 rtx dest = operands[0];
10283 rtx imm;
10284
10285 operands[1] = force_reg (SFmode, operands[1]);
10286 operands[0] = force_reg (SFmode, operands[0]);
10287 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10288 reg = force_reg (V4SFmode,
10289 gen_rtx_CONST_VECTOR (V4SFmode,
10290 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10291 CONST0_RTX (SFmode),
10292 CONST0_RTX (SFmode))));
10293 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10294 if (dest != operands[0])
10295 emit_move_insn (dest, operands[0]);
10296 }
10297 DONE;
10298 }
10299 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10300
10301 (define_insn "abssf2_memory"
10302 [(set (match_operand:SF 0 "memory_operand" "=m")
10303 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10304 (clobber (reg:CC 17))]
10305 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10306 "#")
10307
10308 (define_insn "abssf2_ifs"
10309 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10310 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10311 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10312 (clobber (reg:CC 17))]
10313 "TARGET_SSE
10314 && (reload_in_progress || reload_completed
10315 || (register_operand (operands[0], VOIDmode)
10316 && register_operand (operands[1], VOIDmode)))"
10317 "#")
10318
10319 (define_split
10320 [(set (match_operand:SF 0 "memory_operand" "")
10321 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10322 (use (match_operand:V4SF 2 "" ""))
10323 (clobber (reg:CC 17))]
10324 ""
10325 [(parallel [(set (match_dup 0)
10326 (abs:SF (match_dup 1)))
10327 (clobber (reg:CC 17))])])
10328
10329 (define_split
10330 [(set (match_operand:SF 0 "register_operand" "")
10331 (abs:SF (match_operand:SF 1 "register_operand" "")))
10332 (use (match_operand:V4SF 2 "" ""))
10333 (clobber (reg:CC 17))]
10334 "reload_completed && !SSE_REG_P (operands[0])"
10335 [(parallel [(set (match_dup 0)
10336 (abs:SF (match_dup 1)))
10337 (clobber (reg:CC 17))])])
10338
10339 (define_split
10340 [(set (match_operand:SF 0 "register_operand" "")
10341 (abs:SF (match_operand:SF 1 "register_operand" "")))
10342 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10343 (clobber (reg:CC 17))]
10344 "reload_completed && SSE_REG_P (operands[0])"
10345 [(set (subreg:TI (match_dup 0) 0)
10346 (and:TI (match_dup 1)
10347 (match_dup 2)))]
10348 {
10349 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10350 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10351 if (operands_match_p (operands[0], operands[2]))
10352 {
10353 rtx tmp;
10354 tmp = operands[1];
10355 operands[1] = operands[2];
10356 operands[2] = tmp;
10357 }
10358 })
10359
10360 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10361 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10362 ;; to itself.
10363 (define_insn "*abssf2_if"
10364 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10365 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10366 (clobber (reg:CC 17))]
10367 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10368 "#")
10369
10370 (define_split
10371 [(set (match_operand:SF 0 "fp_register_operand" "")
10372 (abs:SF (match_operand:SF 1 "register_operand" "")))
10373 (clobber (reg:CC 17))]
10374 "TARGET_80387"
10375 [(set (match_dup 0)
10376 (abs:SF (match_dup 1)))]
10377 "")
10378
10379 (define_split
10380 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10381 (abs:SF (match_operand:SF 1 "register_operand" "")))
10382 (clobber (reg:CC 17))]
10383 "TARGET_80387 && reload_completed"
10384 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10385 (clobber (reg:CC 17))])]
10386 "operands[1] = gen_int_mode (~0x80000000, SImode);
10387 operands[0] = gen_lowpart (SImode, operands[0]);")
10388
10389 (define_split
10390 [(set (match_operand 0 "memory_operand" "")
10391 (abs (match_operand 1 "memory_operand" "")))
10392 (clobber (reg:CC 17))]
10393 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10394 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10395 (clobber (reg:CC 17))])]
10396 {
10397 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10398
10399 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10400 if (size >= 12)
10401 size = 10;
10402 operands[0] = adjust_address (operands[0], QImode, size - 1);
10403 operands[1] = gen_int_mode (~0x80, QImode);
10404 })
10405
10406 (define_expand "absdf2"
10407 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10408 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10409 (clobber (reg:CC 17))])]
10410 "TARGET_80387"
10411 "if (TARGET_SSE2)
10412 {
10413 /* In case operand is in memory, we will not use SSE. */
10414 if (memory_operand (operands[0], VOIDmode)
10415 && rtx_equal_p (operands[0], operands[1]))
10416 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10417 else
10418 {
10419 /* Using SSE is tricky, since we need bitwise negation of -0
10420 in register. */
10421 rtx reg = gen_reg_rtx (V2DFmode);
10422 #if HOST_BITS_PER_WIDE_INT >= 64
10423 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10424 #else
10425 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10426 #endif
10427 rtx dest = operands[0];
10428
10429 operands[1] = force_reg (DFmode, operands[1]);
10430 operands[0] = force_reg (DFmode, operands[0]);
10431
10432 /* Produce LONG_DOUBLE with the proper immediate argument. */
10433 imm = gen_lowpart (DFmode, imm);
10434 reg = force_reg (V2DFmode,
10435 gen_rtx_CONST_VECTOR (V2DFmode,
10436 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10437 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10438 if (dest != operands[0])
10439 emit_move_insn (dest, operands[0]);
10440 }
10441 DONE;
10442 }
10443 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10444
10445 (define_insn "absdf2_memory"
10446 [(set (match_operand:DF 0 "memory_operand" "=m")
10447 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10448 (clobber (reg:CC 17))]
10449 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10450 "#")
10451
10452 (define_insn "absdf2_ifs"
10453 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10454 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10455 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10456 (clobber (reg:CC 17))]
10457 "!TARGET_64BIT && TARGET_SSE2
10458 && (reload_in_progress || reload_completed
10459 || (register_operand (operands[0], VOIDmode)
10460 && register_operand (operands[1], VOIDmode)))"
10461 "#")
10462
10463 (define_insn "*absdf2_ifs_rex64"
10464 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10465 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10466 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10467 (clobber (reg:CC 17))]
10468 "TARGET_64BIT && TARGET_SSE2
10469 && (reload_in_progress || reload_completed
10470 || (register_operand (operands[0], VOIDmode)
10471 && register_operand (operands[1], VOIDmode)))"
10472 "#")
10473
10474 (define_split
10475 [(set (match_operand:DF 0 "memory_operand" "")
10476 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10477 (use (match_operand:V2DF 2 "" ""))
10478 (clobber (reg:CC 17))]
10479 ""
10480 [(parallel [(set (match_dup 0)
10481 (abs:DF (match_dup 1)))
10482 (clobber (reg:CC 17))])])
10483
10484 (define_split
10485 [(set (match_operand:DF 0 "register_operand" "")
10486 (abs:DF (match_operand:DF 1 "register_operand" "")))
10487 (use (match_operand:V2DF 2 "" ""))
10488 (clobber (reg:CC 17))]
10489 "reload_completed && !SSE_REG_P (operands[0])"
10490 [(parallel [(set (match_dup 0)
10491 (abs:DF (match_dup 1)))
10492 (clobber (reg:CC 17))])])
10493
10494 (define_split
10495 [(set (match_operand:DF 0 "register_operand" "")
10496 (abs:DF (match_operand:DF 1 "register_operand" "")))
10497 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10498 (clobber (reg:CC 17))]
10499 "reload_completed && SSE_REG_P (operands[0])"
10500 [(set (subreg:TI (match_dup 0) 0)
10501 (and:TI (match_dup 1)
10502 (match_dup 2)))]
10503 {
10504 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10505 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10506 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10507 /* Avoid possible reformatting on the operands. */
10508 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10509 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10510 if (operands_match_p (operands[0], operands[2]))
10511 {
10512 rtx tmp;
10513 tmp = operands[1];
10514 operands[1] = operands[2];
10515 operands[2] = tmp;
10516 }
10517 })
10518
10519
10520 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10521 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10522 ;; to itself.
10523 (define_insn "*absdf2_if"
10524 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10525 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10526 (clobber (reg:CC 17))]
10527 "!TARGET_64BIT && TARGET_80387
10528 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10529 "#")
10530
10531 ;; FIXME: We should to allow integer registers here. Problem is that
10532 ;; we need another scratch register to get constant from.
10533 ;; Forcing constant to mem if no register available in peep2 should be
10534 ;; safe even for PIC mode, because of RIP relative addressing.
10535 (define_insn "*absdf2_if_rex64"
10536 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10537 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10538 (clobber (reg:CC 17))]
10539 "TARGET_64BIT && TARGET_80387
10540 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10541 "#")
10542
10543 (define_split
10544 [(set (match_operand:DF 0 "fp_register_operand" "")
10545 (abs:DF (match_operand:DF 1 "register_operand" "")))
10546 (clobber (reg:CC 17))]
10547 "TARGET_80387 && reload_completed"
10548 [(set (match_dup 0)
10549 (abs:DF (match_dup 1)))]
10550 "")
10551
10552 (define_split
10553 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10554 (abs:DF (match_operand:DF 1 "register_operand" "")))
10555 (clobber (reg:CC 17))]
10556 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10557 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10558 (clobber (reg:CC 17))])]
10559 "operands[4] = gen_int_mode (~0x80000000, SImode);
10560 split_di (operands+0, 1, operands+2, operands+3);")
10561
10562 (define_expand "absxf2"
10563 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10564 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10565 (clobber (reg:CC 17))])]
10566 "!TARGET_64BIT && TARGET_80387"
10567 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10568
10569 (define_expand "abstf2"
10570 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10571 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10572 (clobber (reg:CC 17))])]
10573 "TARGET_80387"
10574 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10575
10576 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10577 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10578 ;; to itself.
10579 (define_insn "*absxf2_if"
10580 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10581 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10582 (clobber (reg:CC 17))]
10583 "!TARGET_64BIT && TARGET_80387
10584 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10585 "#")
10586
10587 (define_split
10588 [(set (match_operand:XF 0 "fp_register_operand" "")
10589 (abs:XF (match_operand:XF 1 "register_operand" "")))
10590 (clobber (reg:CC 17))]
10591 "TARGET_80387 && reload_completed"
10592 [(set (match_dup 0)
10593 (abs:XF (match_dup 1)))]
10594 "")
10595
10596 (define_split
10597 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10598 (abs:XF (match_operand:XF 1 "register_operand" "")))
10599 (clobber (reg:CC 17))]
10600 "TARGET_80387 && reload_completed"
10601 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10602 (clobber (reg:CC 17))])]
10603 "operands[1] = GEN_INT (~0x8000);
10604 operands[0] = gen_rtx_REG (SImode,
10605 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10606
10607 (define_insn "*abstf2_if"
10608 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10609 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10610 (clobber (reg:CC 17))]
10611 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10612 "#")
10613
10614 (define_split
10615 [(set (match_operand:TF 0 "fp_register_operand" "")
10616 (abs:TF (match_operand:TF 1 "register_operand" "")))
10617 (clobber (reg:CC 17))]
10618 "TARGET_80387 && reload_completed"
10619 [(set (match_dup 0)
10620 (abs:TF (match_dup 1)))]
10621 "")
10622
10623 (define_split
10624 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10625 (abs:TF (match_operand:TF 1 "register_operand" "")))
10626 (clobber (reg:CC 17))]
10627 "TARGET_80387 && reload_completed"
10628 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10629 (clobber (reg:CC 17))])]
10630 "operands[1] = GEN_INT (~0x8000);
10631 operands[0] = gen_rtx_REG (SImode,
10632 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10633
10634 (define_insn "*abssf2_1"
10635 [(set (match_operand:SF 0 "register_operand" "=f")
10636 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10637 "TARGET_80387 && reload_completed"
10638 "fabs"
10639 [(set_attr "type" "fsgn")
10640 (set_attr "mode" "SF")])
10641
10642 (define_insn "*absdf2_1"
10643 [(set (match_operand:DF 0 "register_operand" "=f")
10644 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10645 "TARGET_80387 && reload_completed"
10646 "fabs"
10647 [(set_attr "type" "fsgn")
10648 (set_attr "mode" "DF")])
10649
10650 (define_insn "*absextendsfdf2"
10651 [(set (match_operand:DF 0 "register_operand" "=f")
10652 (abs:DF (float_extend:DF
10653 (match_operand:SF 1 "register_operand" "0"))))]
10654 "TARGET_80387"
10655 "fabs"
10656 [(set_attr "type" "fsgn")
10657 (set_attr "mode" "DF")])
10658
10659 (define_insn "*absxf2_1"
10660 [(set (match_operand:XF 0 "register_operand" "=f")
10661 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10662 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10663 "fabs"
10664 [(set_attr "type" "fsgn")
10665 (set_attr "mode" "DF")])
10666
10667 (define_insn "*absextenddfxf2"
10668 [(set (match_operand:XF 0 "register_operand" "=f")
10669 (abs:XF (float_extend:XF
10670 (match_operand:DF 1 "register_operand" "0"))))]
10671 "!TARGET_64BIT && TARGET_80387"
10672 "fabs"
10673 [(set_attr "type" "fsgn")
10674 (set_attr "mode" "XF")])
10675
10676 (define_insn "*absextendsfxf2"
10677 [(set (match_operand:XF 0 "register_operand" "=f")
10678 (abs:XF (float_extend:XF
10679 (match_operand:SF 1 "register_operand" "0"))))]
10680 "!TARGET_64BIT && TARGET_80387"
10681 "fabs"
10682 [(set_attr "type" "fsgn")
10683 (set_attr "mode" "XF")])
10684
10685 (define_insn "*abstf2_1"
10686 [(set (match_operand:TF 0 "register_operand" "=f")
10687 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10688 "TARGET_80387 && reload_completed"
10689 "fabs"
10690 [(set_attr "type" "fsgn")
10691 (set_attr "mode" "DF")])
10692
10693 (define_insn "*absextenddftf2"
10694 [(set (match_operand:TF 0 "register_operand" "=f")
10695 (abs:TF (float_extend:TF
10696 (match_operand:DF 1 "register_operand" "0"))))]
10697 "TARGET_80387"
10698 "fabs"
10699 [(set_attr "type" "fsgn")
10700 (set_attr "mode" "XF")])
10701
10702 (define_insn "*absextendsftf2"
10703 [(set (match_operand:TF 0 "register_operand" "=f")
10704 (abs:TF (float_extend:TF
10705 (match_operand:SF 1 "register_operand" "0"))))]
10706 "TARGET_80387"
10707 "fabs"
10708 [(set_attr "type" "fsgn")
10709 (set_attr "mode" "XF")])
10710 \f
10711 ;; One complement instructions
10712
10713 (define_expand "one_cmpldi2"
10714 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10715 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10716 "TARGET_64BIT"
10717 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10718
10719 (define_insn "*one_cmpldi2_1_rex64"
10720 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10721 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10722 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10723 "not{q}\t%0"
10724 [(set_attr "type" "negnot")
10725 (set_attr "mode" "DI")])
10726
10727 (define_insn "*one_cmpldi2_2_rex64"
10728 [(set (reg 17)
10729 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10730 (const_int 0)))
10731 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10732 (not:DI (match_dup 1)))]
10733 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10734 && ix86_unary_operator_ok (NOT, DImode, operands)"
10735 "#"
10736 [(set_attr "type" "alu1")
10737 (set_attr "mode" "DI")])
10738
10739 (define_split
10740 [(set (reg 17)
10741 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10742 (const_int 0)))
10743 (set (match_operand:DI 0 "nonimmediate_operand" "")
10744 (not:DI (match_dup 1)))]
10745 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10746 [(parallel [(set (reg:CCNO 17)
10747 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10748 (const_int 0)))
10749 (set (match_dup 0)
10750 (xor:DI (match_dup 1) (const_int -1)))])]
10751 "")
10752
10753 (define_expand "one_cmplsi2"
10754 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10755 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10756 ""
10757 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10758
10759 (define_insn "*one_cmplsi2_1"
10760 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10761 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10762 "ix86_unary_operator_ok (NOT, SImode, operands)"
10763 "not{l}\t%0"
10764 [(set_attr "type" "negnot")
10765 (set_attr "mode" "SI")])
10766
10767 ;; ??? Currently never generated - xor is used instead.
10768 (define_insn "*one_cmplsi2_1_zext"
10769 [(set (match_operand:DI 0 "register_operand" "=r")
10770 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10771 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10772 "not{l}\t%k0"
10773 [(set_attr "type" "negnot")
10774 (set_attr "mode" "SI")])
10775
10776 (define_insn "*one_cmplsi2_2"
10777 [(set (reg 17)
10778 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10779 (const_int 0)))
10780 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10781 (not:SI (match_dup 1)))]
10782 "ix86_match_ccmode (insn, CCNOmode)
10783 && ix86_unary_operator_ok (NOT, SImode, operands)"
10784 "#"
10785 [(set_attr "type" "alu1")
10786 (set_attr "mode" "SI")])
10787
10788 (define_split
10789 [(set (reg 17)
10790 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10791 (const_int 0)))
10792 (set (match_operand:SI 0 "nonimmediate_operand" "")
10793 (not:SI (match_dup 1)))]
10794 "ix86_match_ccmode (insn, CCNOmode)"
10795 [(parallel [(set (reg:CCNO 17)
10796 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10797 (const_int 0)))
10798 (set (match_dup 0)
10799 (xor:SI (match_dup 1) (const_int -1)))])]
10800 "")
10801
10802 ;; ??? Currently never generated - xor is used instead.
10803 (define_insn "*one_cmplsi2_2_zext"
10804 [(set (reg 17)
10805 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10806 (const_int 0)))
10807 (set (match_operand:DI 0 "register_operand" "=r")
10808 (zero_extend:DI (not:SI (match_dup 1))))]
10809 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10810 && ix86_unary_operator_ok (NOT, SImode, operands)"
10811 "#"
10812 [(set_attr "type" "alu1")
10813 (set_attr "mode" "SI")])
10814
10815 (define_split
10816 [(set (reg 17)
10817 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10818 (const_int 0)))
10819 (set (match_operand:DI 0 "register_operand" "")
10820 (zero_extend:DI (not:SI (match_dup 1))))]
10821 "ix86_match_ccmode (insn, CCNOmode)"
10822 [(parallel [(set (reg:CCNO 17)
10823 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10824 (const_int 0)))
10825 (set (match_dup 0)
10826 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10827 "")
10828
10829 (define_expand "one_cmplhi2"
10830 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10831 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10832 "TARGET_HIMODE_MATH"
10833 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10834
10835 (define_insn "*one_cmplhi2_1"
10836 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10837 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10838 "ix86_unary_operator_ok (NOT, HImode, operands)"
10839 "not{w}\t%0"
10840 [(set_attr "type" "negnot")
10841 (set_attr "mode" "HI")])
10842
10843 (define_insn "*one_cmplhi2_2"
10844 [(set (reg 17)
10845 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10846 (const_int 0)))
10847 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10848 (not:HI (match_dup 1)))]
10849 "ix86_match_ccmode (insn, CCNOmode)
10850 && ix86_unary_operator_ok (NEG, HImode, operands)"
10851 "#"
10852 [(set_attr "type" "alu1")
10853 (set_attr "mode" "HI")])
10854
10855 (define_split
10856 [(set (reg 17)
10857 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10858 (const_int 0)))
10859 (set (match_operand:HI 0 "nonimmediate_operand" "")
10860 (not:HI (match_dup 1)))]
10861 "ix86_match_ccmode (insn, CCNOmode)"
10862 [(parallel [(set (reg:CCNO 17)
10863 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10864 (const_int 0)))
10865 (set (match_dup 0)
10866 (xor:HI (match_dup 1) (const_int -1)))])]
10867 "")
10868
10869 ;; %%% Potential partial reg stall on alternative 1. What to do?
10870 (define_expand "one_cmplqi2"
10871 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10872 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10873 "TARGET_QIMODE_MATH"
10874 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10875
10876 (define_insn "*one_cmplqi2_1"
10877 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10878 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10879 "ix86_unary_operator_ok (NOT, QImode, operands)"
10880 "@
10881 not{b}\t%0
10882 not{l}\t%k0"
10883 [(set_attr "type" "negnot")
10884 (set_attr "mode" "QI,SI")])
10885
10886 (define_insn "*one_cmplqi2_2"
10887 [(set (reg 17)
10888 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10889 (const_int 0)))
10890 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10891 (not:QI (match_dup 1)))]
10892 "ix86_match_ccmode (insn, CCNOmode)
10893 && ix86_unary_operator_ok (NOT, QImode, operands)"
10894 "#"
10895 [(set_attr "type" "alu1")
10896 (set_attr "mode" "QI")])
10897
10898 (define_split
10899 [(set (reg 17)
10900 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10901 (const_int 0)))
10902 (set (match_operand:QI 0 "nonimmediate_operand" "")
10903 (not:QI (match_dup 1)))]
10904 "ix86_match_ccmode (insn, CCNOmode)"
10905 [(parallel [(set (reg:CCNO 17)
10906 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10907 (const_int 0)))
10908 (set (match_dup 0)
10909 (xor:QI (match_dup 1) (const_int -1)))])]
10910 "")
10911 \f
10912 ;; Arithmetic shift instructions
10913
10914 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10915 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10916 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10917 ;; from the assembler input.
10918 ;;
10919 ;; This instruction shifts the target reg/mem as usual, but instead of
10920 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10921 ;; is a left shift double, bits are taken from the high order bits of
10922 ;; reg, else if the insn is a shift right double, bits are taken from the
10923 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10924 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10925 ;;
10926 ;; Since sh[lr]d does not change the `reg' operand, that is done
10927 ;; separately, making all shifts emit pairs of shift double and normal
10928 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10929 ;; support a 63 bit shift, each shift where the count is in a reg expands
10930 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10931 ;;
10932 ;; If the shift count is a constant, we need never emit more than one
10933 ;; shift pair, instead using moves and sign extension for counts greater
10934 ;; than 31.
10935
10936 (define_expand "ashldi3"
10937 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10938 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10939 (match_operand:QI 2 "nonmemory_operand" "")))
10940 (clobber (reg:CC 17))])]
10941 ""
10942 {
10943 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10944 {
10945 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10946 DONE;
10947 }
10948 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10949 DONE;
10950 })
10951
10952 (define_insn "*ashldi3_1_rex64"
10953 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10954 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10955 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10956 (clobber (reg:CC 17))]
10957 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10958 {
10959 switch (get_attr_type (insn))
10960 {
10961 case TYPE_ALU:
10962 if (operands[2] != const1_rtx)
10963 abort ();
10964 if (!rtx_equal_p (operands[0], operands[1]))
10965 abort ();
10966 return "add{q}\t{%0, %0|%0, %0}";
10967
10968 case TYPE_LEA:
10969 if (GET_CODE (operands[2]) != CONST_INT
10970 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10971 abort ();
10972 operands[1] = gen_rtx_MULT (DImode, operands[1],
10973 GEN_INT (1 << INTVAL (operands[2])));
10974 return "lea{q}\t{%a1, %0|%0, %a1}";
10975
10976 default:
10977 if (REG_P (operands[2]))
10978 return "sal{q}\t{%b2, %0|%0, %b2}";
10979 else if (GET_CODE (operands[2]) == CONST_INT
10980 && INTVAL (operands[2]) == 1
10981 && (TARGET_SHIFT1 || optimize_size))
10982 return "sal{q}\t%0";
10983 else
10984 return "sal{q}\t{%2, %0|%0, %2}";
10985 }
10986 }
10987 [(set (attr "type")
10988 (cond [(eq_attr "alternative" "1")
10989 (const_string "lea")
10990 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10991 (const_int 0))
10992 (match_operand 0 "register_operand" ""))
10993 (match_operand 2 "const1_operand" ""))
10994 (const_string "alu")
10995 ]
10996 (const_string "ishift")))
10997 (set_attr "mode" "DI")])
10998
10999 ;; Convert lea to the lea pattern to avoid flags dependency.
11000 (define_split
11001 [(set (match_operand:DI 0 "register_operand" "")
11002 (ashift:DI (match_operand:DI 1 "register_operand" "")
11003 (match_operand:QI 2 "immediate_operand" "")))
11004 (clobber (reg:CC 17))]
11005 "TARGET_64BIT && reload_completed
11006 && true_regnum (operands[0]) != true_regnum (operands[1])"
11007 [(set (match_dup 0)
11008 (mult:DI (match_dup 1)
11009 (match_dup 2)))]
11010 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11011
11012 ;; This pattern can't accept a variable shift count, since shifts by
11013 ;; zero don't affect the flags. We assume that shifts by constant
11014 ;; zero are optimized away.
11015 (define_insn "*ashldi3_cmp_rex64"
11016 [(set (reg 17)
11017 (compare
11018 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11019 (match_operand:QI 2 "immediate_operand" "e"))
11020 (const_int 0)))
11021 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11022 (ashift:DI (match_dup 1) (match_dup 2)))]
11023 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11024 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11025 {
11026 switch (get_attr_type (insn))
11027 {
11028 case TYPE_ALU:
11029 if (operands[2] != const1_rtx)
11030 abort ();
11031 return "add{q}\t{%0, %0|%0, %0}";
11032
11033 default:
11034 if (REG_P (operands[2]))
11035 return "sal{q}\t{%b2, %0|%0, %b2}";
11036 else if (GET_CODE (operands[2]) == CONST_INT
11037 && INTVAL (operands[2]) == 1
11038 && (TARGET_SHIFT1 || optimize_size))
11039 return "sal{q}\t%0";
11040 else
11041 return "sal{q}\t{%2, %0|%0, %2}";
11042 }
11043 }
11044 [(set (attr "type")
11045 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11046 (const_int 0))
11047 (match_operand 0 "register_operand" ""))
11048 (match_operand 2 "const1_operand" ""))
11049 (const_string "alu")
11050 ]
11051 (const_string "ishift")))
11052 (set_attr "mode" "DI")])
11053
11054 (define_insn "ashldi3_1"
11055 [(set (match_operand:DI 0 "register_operand" "=r")
11056 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11057 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11058 (clobber (match_scratch:SI 3 "=&r"))
11059 (clobber (reg:CC 17))]
11060 "!TARGET_64BIT && TARGET_CMOVE"
11061 "#"
11062 [(set_attr "type" "multi")])
11063
11064 (define_insn "*ashldi3_2"
11065 [(set (match_operand:DI 0 "register_operand" "=r")
11066 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11067 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11068 (clobber (reg:CC 17))]
11069 "!TARGET_64BIT"
11070 "#"
11071 [(set_attr "type" "multi")])
11072
11073 (define_split
11074 [(set (match_operand:DI 0 "register_operand" "")
11075 (ashift:DI (match_operand:DI 1 "register_operand" "")
11076 (match_operand:QI 2 "nonmemory_operand" "")))
11077 (clobber (match_scratch:SI 3 ""))
11078 (clobber (reg:CC 17))]
11079 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11080 [(const_int 0)]
11081 "ix86_split_ashldi (operands, operands[3]); DONE;")
11082
11083 (define_split
11084 [(set (match_operand:DI 0 "register_operand" "")
11085 (ashift:DI (match_operand:DI 1 "register_operand" "")
11086 (match_operand:QI 2 "nonmemory_operand" "")))
11087 (clobber (reg:CC 17))]
11088 "!TARGET_64BIT && reload_completed"
11089 [(const_int 0)]
11090 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11091
11092 (define_insn "x86_shld_1"
11093 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11094 (ior:SI (ashift:SI (match_dup 0)
11095 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11096 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11097 (minus:QI (const_int 32) (match_dup 2)))))
11098 (clobber (reg:CC 17))]
11099 ""
11100 "@
11101 shld{l}\t{%2, %1, %0|%0, %1, %2}
11102 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11103 [(set_attr "type" "ishift")
11104 (set_attr "prefix_0f" "1")
11105 (set_attr "mode" "SI")
11106 (set_attr "pent_pair" "np")
11107 (set_attr "athlon_decode" "vector")
11108 (set_attr "ppro_uops" "few")])
11109
11110 (define_expand "x86_shift_adj_1"
11111 [(set (reg:CCZ 17)
11112 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11113 (const_int 32))
11114 (const_int 0)))
11115 (set (match_operand:SI 0 "register_operand" "")
11116 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11117 (match_operand:SI 1 "register_operand" "")
11118 (match_dup 0)))
11119 (set (match_dup 1)
11120 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11121 (match_operand:SI 3 "register_operand" "r")
11122 (match_dup 1)))]
11123 "TARGET_CMOVE"
11124 "")
11125
11126 (define_expand "x86_shift_adj_2"
11127 [(use (match_operand:SI 0 "register_operand" ""))
11128 (use (match_operand:SI 1 "register_operand" ""))
11129 (use (match_operand:QI 2 "register_operand" ""))]
11130 ""
11131 {
11132 rtx label = gen_label_rtx ();
11133 rtx tmp;
11134
11135 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11136
11137 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11138 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11139 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11140 gen_rtx_LABEL_REF (VOIDmode, label),
11141 pc_rtx);
11142 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11143 JUMP_LABEL (tmp) = label;
11144
11145 emit_move_insn (operands[0], operands[1]);
11146 emit_move_insn (operands[1], const0_rtx);
11147
11148 emit_label (label);
11149 LABEL_NUSES (label) = 1;
11150
11151 DONE;
11152 })
11153
11154 (define_expand "ashlsi3"
11155 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11156 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11157 (match_operand:QI 2 "nonmemory_operand" "")))
11158 (clobber (reg:CC 17))]
11159 ""
11160 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11161
11162 (define_insn "*ashlsi3_1"
11163 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11164 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11165 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11166 (clobber (reg:CC 17))]
11167 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11168 {
11169 switch (get_attr_type (insn))
11170 {
11171 case TYPE_ALU:
11172 if (operands[2] != const1_rtx)
11173 abort ();
11174 if (!rtx_equal_p (operands[0], operands[1]))
11175 abort ();
11176 return "add{l}\t{%0, %0|%0, %0}";
11177
11178 case TYPE_LEA:
11179 return "#";
11180
11181 default:
11182 if (REG_P (operands[2]))
11183 return "sal{l}\t{%b2, %0|%0, %b2}";
11184 else if (GET_CODE (operands[2]) == CONST_INT
11185 && INTVAL (operands[2]) == 1
11186 && (TARGET_SHIFT1 || optimize_size))
11187 return "sal{l}\t%0";
11188 else
11189 return "sal{l}\t{%2, %0|%0, %2}";
11190 }
11191 }
11192 [(set (attr "type")
11193 (cond [(eq_attr "alternative" "1")
11194 (const_string "lea")
11195 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11196 (const_int 0))
11197 (match_operand 0 "register_operand" ""))
11198 (match_operand 2 "const1_operand" ""))
11199 (const_string "alu")
11200 ]
11201 (const_string "ishift")))
11202 (set_attr "mode" "SI")])
11203
11204 ;; Convert lea to the lea pattern to avoid flags dependency.
11205 (define_split
11206 [(set (match_operand 0 "register_operand" "")
11207 (ashift (match_operand 1 "index_register_operand" "")
11208 (match_operand:QI 2 "const_int_operand" "")))
11209 (clobber (reg:CC 17))]
11210 "reload_completed
11211 && true_regnum (operands[0]) != true_regnum (operands[1])"
11212 [(const_int 0)]
11213 {
11214 rtx pat;
11215 operands[0] = gen_lowpart (SImode, operands[0]);
11216 operands[1] = gen_lowpart (Pmode, operands[1]);
11217 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11218 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11219 if (Pmode != SImode)
11220 pat = gen_rtx_SUBREG (SImode, pat, 0);
11221 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11222 DONE;
11223 })
11224
11225 ;; Rare case of shifting RSP is handled by generating move and shift
11226 (define_split
11227 [(set (match_operand 0 "register_operand" "")
11228 (ashift (match_operand 1 "register_operand" "")
11229 (match_operand:QI 2 "const_int_operand" "")))
11230 (clobber (reg:CC 17))]
11231 "reload_completed
11232 && true_regnum (operands[0]) != true_regnum (operands[1])"
11233 [(const_int 0)]
11234 {
11235 rtx pat, clob;
11236 emit_move_insn (operands[1], operands[0]);
11237 pat = gen_rtx_SET (VOIDmode, operands[0],
11238 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11239 operands[0], operands[2]));
11240 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11241 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11242 DONE;
11243 })
11244
11245 (define_insn "*ashlsi3_1_zext"
11246 [(set (match_operand:DI 0 "register_operand" "=r,r")
11247 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11248 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11249 (clobber (reg:CC 17))]
11250 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11251 {
11252 switch (get_attr_type (insn))
11253 {
11254 case TYPE_ALU:
11255 if (operands[2] != const1_rtx)
11256 abort ();
11257 return "add{l}\t{%k0, %k0|%k0, %k0}";
11258
11259 case TYPE_LEA:
11260 return "#";
11261
11262 default:
11263 if (REG_P (operands[2]))
11264 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11265 else if (GET_CODE (operands[2]) == CONST_INT
11266 && INTVAL (operands[2]) == 1
11267 && (TARGET_SHIFT1 || optimize_size))
11268 return "sal{l}\t%k0";
11269 else
11270 return "sal{l}\t{%2, %k0|%k0, %2}";
11271 }
11272 }
11273 [(set (attr "type")
11274 (cond [(eq_attr "alternative" "1")
11275 (const_string "lea")
11276 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11277 (const_int 0))
11278 (match_operand 2 "const1_operand" ""))
11279 (const_string "alu")
11280 ]
11281 (const_string "ishift")))
11282 (set_attr "mode" "SI")])
11283
11284 ;; Convert lea to the lea pattern to avoid flags dependency.
11285 (define_split
11286 [(set (match_operand:DI 0 "register_operand" "")
11287 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11288 (match_operand:QI 2 "const_int_operand" ""))))
11289 (clobber (reg:CC 17))]
11290 "TARGET_64BIT && reload_completed
11291 && true_regnum (operands[0]) != true_regnum (operands[1])"
11292 [(set (match_dup 0) (zero_extend:DI
11293 (subreg:SI (mult:SI (match_dup 1)
11294 (match_dup 2)) 0)))]
11295 {
11296 operands[1] = gen_lowpart (Pmode, operands[1]);
11297 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11298 })
11299
11300 ;; This pattern can't accept a variable shift count, since shifts by
11301 ;; zero don't affect the flags. We assume that shifts by constant
11302 ;; zero are optimized away.
11303 (define_insn "*ashlsi3_cmp"
11304 [(set (reg 17)
11305 (compare
11306 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11307 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11308 (const_int 0)))
11309 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11310 (ashift:SI (match_dup 1) (match_dup 2)))]
11311 "ix86_match_ccmode (insn, CCGOCmode)
11312 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11313 {
11314 switch (get_attr_type (insn))
11315 {
11316 case TYPE_ALU:
11317 if (operands[2] != const1_rtx)
11318 abort ();
11319 return "add{l}\t{%0, %0|%0, %0}";
11320
11321 default:
11322 if (REG_P (operands[2]))
11323 return "sal{l}\t{%b2, %0|%0, %b2}";
11324 else if (GET_CODE (operands[2]) == CONST_INT
11325 && INTVAL (operands[2]) == 1
11326 && (TARGET_SHIFT1 || optimize_size))
11327 return "sal{l}\t%0";
11328 else
11329 return "sal{l}\t{%2, %0|%0, %2}";
11330 }
11331 }
11332 [(set (attr "type")
11333 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11334 (const_int 0))
11335 (match_operand 0 "register_operand" ""))
11336 (match_operand 2 "const1_operand" ""))
11337 (const_string "alu")
11338 ]
11339 (const_string "ishift")))
11340 (set_attr "mode" "SI")])
11341
11342 (define_insn "*ashlsi3_cmp_zext"
11343 [(set (reg 17)
11344 (compare
11345 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11346 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11347 (const_int 0)))
11348 (set (match_operand:DI 0 "register_operand" "=r")
11349 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11350 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11351 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11352 {
11353 switch (get_attr_type (insn))
11354 {
11355 case TYPE_ALU:
11356 if (operands[2] != const1_rtx)
11357 abort ();
11358 return "add{l}\t{%k0, %k0|%k0, %k0}";
11359
11360 default:
11361 if (REG_P (operands[2]))
11362 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11363 else if (GET_CODE (operands[2]) == CONST_INT
11364 && INTVAL (operands[2]) == 1
11365 && (TARGET_SHIFT1 || optimize_size))
11366 return "sal{l}\t%k0";
11367 else
11368 return "sal{l}\t{%2, %k0|%k0, %2}";
11369 }
11370 }
11371 [(set (attr "type")
11372 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11373 (const_int 0))
11374 (match_operand 2 "const1_operand" ""))
11375 (const_string "alu")
11376 ]
11377 (const_string "ishift")))
11378 (set_attr "mode" "SI")])
11379
11380 (define_expand "ashlhi3"
11381 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11382 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11383 (match_operand:QI 2 "nonmemory_operand" "")))
11384 (clobber (reg:CC 17))]
11385 "TARGET_HIMODE_MATH"
11386 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11387
11388 (define_insn "*ashlhi3_1_lea"
11389 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11390 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11391 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11392 (clobber (reg:CC 17))]
11393 "!TARGET_PARTIAL_REG_STALL
11394 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11395 {
11396 switch (get_attr_type (insn))
11397 {
11398 case TYPE_LEA:
11399 return "#";
11400 case TYPE_ALU:
11401 if (operands[2] != const1_rtx)
11402 abort ();
11403 return "add{w}\t{%0, %0|%0, %0}";
11404
11405 default:
11406 if (REG_P (operands[2]))
11407 return "sal{w}\t{%b2, %0|%0, %b2}";
11408 else if (GET_CODE (operands[2]) == CONST_INT
11409 && INTVAL (operands[2]) == 1
11410 && (TARGET_SHIFT1 || optimize_size))
11411 return "sal{w}\t%0";
11412 else
11413 return "sal{w}\t{%2, %0|%0, %2}";
11414 }
11415 }
11416 [(set (attr "type")
11417 (cond [(eq_attr "alternative" "1")
11418 (const_string "lea")
11419 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11420 (const_int 0))
11421 (match_operand 0 "register_operand" ""))
11422 (match_operand 2 "const1_operand" ""))
11423 (const_string "alu")
11424 ]
11425 (const_string "ishift")))
11426 (set_attr "mode" "HI,SI")])
11427
11428 (define_insn "*ashlhi3_1"
11429 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11430 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11431 (match_operand:QI 2 "nonmemory_operand" "cI")))
11432 (clobber (reg:CC 17))]
11433 "TARGET_PARTIAL_REG_STALL
11434 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11435 {
11436 switch (get_attr_type (insn))
11437 {
11438 case TYPE_ALU:
11439 if (operands[2] != const1_rtx)
11440 abort ();
11441 return "add{w}\t{%0, %0|%0, %0}";
11442
11443 default:
11444 if (REG_P (operands[2]))
11445 return "sal{w}\t{%b2, %0|%0, %b2}";
11446 else if (GET_CODE (operands[2]) == CONST_INT
11447 && INTVAL (operands[2]) == 1
11448 && (TARGET_SHIFT1 || optimize_size))
11449 return "sal{w}\t%0";
11450 else
11451 return "sal{w}\t{%2, %0|%0, %2}";
11452 }
11453 }
11454 [(set (attr "type")
11455 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11456 (const_int 0))
11457 (match_operand 0 "register_operand" ""))
11458 (match_operand 2 "const1_operand" ""))
11459 (const_string "alu")
11460 ]
11461 (const_string "ishift")))
11462 (set_attr "mode" "HI")])
11463
11464 ;; This pattern can't accept a variable shift count, since shifts by
11465 ;; zero don't affect the flags. We assume that shifts by constant
11466 ;; zero are optimized away.
11467 (define_insn "*ashlhi3_cmp"
11468 [(set (reg 17)
11469 (compare
11470 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11471 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11472 (const_int 0)))
11473 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11474 (ashift:HI (match_dup 1) (match_dup 2)))]
11475 "ix86_match_ccmode (insn, CCGOCmode)
11476 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11477 {
11478 switch (get_attr_type (insn))
11479 {
11480 case TYPE_ALU:
11481 if (operands[2] != const1_rtx)
11482 abort ();
11483 return "add{w}\t{%0, %0|%0, %0}";
11484
11485 default:
11486 if (REG_P (operands[2]))
11487 return "sal{w}\t{%b2, %0|%0, %b2}";
11488 else if (GET_CODE (operands[2]) == CONST_INT
11489 && INTVAL (operands[2]) == 1
11490 && (TARGET_SHIFT1 || optimize_size))
11491 return "sal{w}\t%0";
11492 else
11493 return "sal{w}\t{%2, %0|%0, %2}";
11494 }
11495 }
11496 [(set (attr "type")
11497 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11498 (const_int 0))
11499 (match_operand 0 "register_operand" ""))
11500 (match_operand 2 "const1_operand" ""))
11501 (const_string "alu")
11502 ]
11503 (const_string "ishift")))
11504 (set_attr "mode" "HI")])
11505
11506 (define_expand "ashlqi3"
11507 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11508 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11509 (match_operand:QI 2 "nonmemory_operand" "")))
11510 (clobber (reg:CC 17))]
11511 "TARGET_QIMODE_MATH"
11512 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11513
11514 ;; %%% Potential partial reg stall on alternative 2. What to do?
11515
11516 (define_insn "*ashlqi3_1_lea"
11517 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11518 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11519 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11520 (clobber (reg:CC 17))]
11521 "!TARGET_PARTIAL_REG_STALL
11522 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11523 {
11524 switch (get_attr_type (insn))
11525 {
11526 case TYPE_LEA:
11527 return "#";
11528 case TYPE_ALU:
11529 if (operands[2] != const1_rtx)
11530 abort ();
11531 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11532 return "add{l}\t{%k0, %k0|%k0, %k0}";
11533 else
11534 return "add{b}\t{%0, %0|%0, %0}";
11535
11536 default:
11537 if (REG_P (operands[2]))
11538 {
11539 if (get_attr_mode (insn) == MODE_SI)
11540 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11541 else
11542 return "sal{b}\t{%b2, %0|%0, %b2}";
11543 }
11544 else if (GET_CODE (operands[2]) == CONST_INT
11545 && INTVAL (operands[2]) == 1
11546 && (TARGET_SHIFT1 || optimize_size))
11547 {
11548 if (get_attr_mode (insn) == MODE_SI)
11549 return "sal{l}\t%0";
11550 else
11551 return "sal{b}\t%0";
11552 }
11553 else
11554 {
11555 if (get_attr_mode (insn) == MODE_SI)
11556 return "sal{l}\t{%2, %k0|%k0, %2}";
11557 else
11558 return "sal{b}\t{%2, %0|%0, %2}";
11559 }
11560 }
11561 }
11562 [(set (attr "type")
11563 (cond [(eq_attr "alternative" "2")
11564 (const_string "lea")
11565 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11566 (const_int 0))
11567 (match_operand 0 "register_operand" ""))
11568 (match_operand 2 "const1_operand" ""))
11569 (const_string "alu")
11570 ]
11571 (const_string "ishift")))
11572 (set_attr "mode" "QI,SI,SI")])
11573
11574 (define_insn "*ashlqi3_1"
11575 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11576 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11577 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11578 (clobber (reg:CC 17))]
11579 "TARGET_PARTIAL_REG_STALL
11580 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11581 {
11582 switch (get_attr_type (insn))
11583 {
11584 case TYPE_ALU:
11585 if (operands[2] != const1_rtx)
11586 abort ();
11587 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11588 return "add{l}\t{%k0, %k0|%k0, %k0}";
11589 else
11590 return "add{b}\t{%0, %0|%0, %0}";
11591
11592 default:
11593 if (REG_P (operands[2]))
11594 {
11595 if (get_attr_mode (insn) == MODE_SI)
11596 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11597 else
11598 return "sal{b}\t{%b2, %0|%0, %b2}";
11599 }
11600 else if (GET_CODE (operands[2]) == CONST_INT
11601 && INTVAL (operands[2]) == 1
11602 && (TARGET_SHIFT1 || optimize_size))
11603 {
11604 if (get_attr_mode (insn) == MODE_SI)
11605 return "sal{l}\t%0";
11606 else
11607 return "sal{b}\t%0";
11608 }
11609 else
11610 {
11611 if (get_attr_mode (insn) == MODE_SI)
11612 return "sal{l}\t{%2, %k0|%k0, %2}";
11613 else
11614 return "sal{b}\t{%2, %0|%0, %2}";
11615 }
11616 }
11617 }
11618 [(set (attr "type")
11619 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11620 (const_int 0))
11621 (match_operand 0 "register_operand" ""))
11622 (match_operand 2 "const1_operand" ""))
11623 (const_string "alu")
11624 ]
11625 (const_string "ishift")))
11626 (set_attr "mode" "QI,SI")])
11627
11628 ;; This pattern can't accept a variable shift count, since shifts by
11629 ;; zero don't affect the flags. We assume that shifts by constant
11630 ;; zero are optimized away.
11631 (define_insn "*ashlqi3_cmp"
11632 [(set (reg 17)
11633 (compare
11634 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11635 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11636 (const_int 0)))
11637 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11638 (ashift:QI (match_dup 1) (match_dup 2)))]
11639 "ix86_match_ccmode (insn, CCGOCmode)
11640 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11641 {
11642 switch (get_attr_type (insn))
11643 {
11644 case TYPE_ALU:
11645 if (operands[2] != const1_rtx)
11646 abort ();
11647 return "add{b}\t{%0, %0|%0, %0}";
11648
11649 default:
11650 if (REG_P (operands[2]))
11651 return "sal{b}\t{%b2, %0|%0, %b2}";
11652 else if (GET_CODE (operands[2]) == CONST_INT
11653 && INTVAL (operands[2]) == 1
11654 && (TARGET_SHIFT1 || optimize_size))
11655 return "sal{b}\t%0";
11656 else
11657 return "sal{b}\t{%2, %0|%0, %2}";
11658 }
11659 }
11660 [(set (attr "type")
11661 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11662 (const_int 0))
11663 (match_operand 0 "register_operand" ""))
11664 (match_operand 2 "const1_operand" ""))
11665 (const_string "alu")
11666 ]
11667 (const_string "ishift")))
11668 (set_attr "mode" "QI")])
11669
11670 ;; See comment above `ashldi3' about how this works.
11671
11672 (define_expand "ashrdi3"
11673 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11674 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11675 (match_operand:QI 2 "nonmemory_operand" "")))
11676 (clobber (reg:CC 17))])]
11677 ""
11678 {
11679 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11680 {
11681 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11682 DONE;
11683 }
11684 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11685 DONE;
11686 })
11687
11688 (define_insn "ashrdi3_63_rex64"
11689 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11690 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11691 (match_operand:DI 2 "const_int_operand" "i,i")))
11692 (clobber (reg:CC 17))]
11693 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11694 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11695 "@
11696 {cqto|cqo}
11697 sar{q}\t{%2, %0|%0, %2}"
11698 [(set_attr "type" "imovx,ishift")
11699 (set_attr "prefix_0f" "0,*")
11700 (set_attr "length_immediate" "0,*")
11701 (set_attr "modrm" "0,1")
11702 (set_attr "mode" "DI")])
11703
11704 (define_insn "*ashrdi3_1_one_bit_rex64"
11705 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11706 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11707 (match_operand:QI 2 "const_int_1_operand" "")))
11708 (clobber (reg:CC 17))]
11709 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11710 && (TARGET_SHIFT1 || optimize_size)"
11711 "sar{q}\t%0"
11712 [(set_attr "type" "ishift")
11713 (set (attr "length")
11714 (if_then_else (match_operand:DI 0 "register_operand" "")
11715 (const_string "2")
11716 (const_string "*")))])
11717
11718 (define_insn "*ashrdi3_1_rex64"
11719 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11720 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11721 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11722 (clobber (reg:CC 17))]
11723 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11724 "@
11725 sar{q}\t{%2, %0|%0, %2}
11726 sar{q}\t{%b2, %0|%0, %b2}"
11727 [(set_attr "type" "ishift")
11728 (set_attr "mode" "DI")])
11729
11730 ;; This pattern can't accept a variable shift count, since shifts by
11731 ;; zero don't affect the flags. We assume that shifts by constant
11732 ;; zero are optimized away.
11733 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11734 [(set (reg 17)
11735 (compare
11736 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11737 (match_operand:QI 2 "const_int_1_operand" ""))
11738 (const_int 0)))
11739 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11740 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11741 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11742 && (TARGET_SHIFT1 || optimize_size)
11743 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11744 "sar{q}\t%0"
11745 [(set_attr "type" "ishift")
11746 (set (attr "length")
11747 (if_then_else (match_operand:DI 0 "register_operand" "")
11748 (const_string "2")
11749 (const_string "*")))])
11750
11751 ;; This pattern can't accept a variable shift count, since shifts by
11752 ;; zero don't affect the flags. We assume that shifts by constant
11753 ;; zero are optimized away.
11754 (define_insn "*ashrdi3_cmp_rex64"
11755 [(set (reg 17)
11756 (compare
11757 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11758 (match_operand:QI 2 "const_int_operand" "n"))
11759 (const_int 0)))
11760 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11761 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11762 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11763 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11764 "sar{q}\t{%2, %0|%0, %2}"
11765 [(set_attr "type" "ishift")
11766 (set_attr "mode" "DI")])
11767
11768
11769 (define_insn "ashrdi3_1"
11770 [(set (match_operand:DI 0 "register_operand" "=r")
11771 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11772 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11773 (clobber (match_scratch:SI 3 "=&r"))
11774 (clobber (reg:CC 17))]
11775 "!TARGET_64BIT && TARGET_CMOVE"
11776 "#"
11777 [(set_attr "type" "multi")])
11778
11779 (define_insn "*ashrdi3_2"
11780 [(set (match_operand:DI 0 "register_operand" "=r")
11781 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11782 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11783 (clobber (reg:CC 17))]
11784 "!TARGET_64BIT"
11785 "#"
11786 [(set_attr "type" "multi")])
11787
11788 (define_split
11789 [(set (match_operand:DI 0 "register_operand" "")
11790 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11791 (match_operand:QI 2 "nonmemory_operand" "")))
11792 (clobber (match_scratch:SI 3 ""))
11793 (clobber (reg:CC 17))]
11794 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11795 [(const_int 0)]
11796 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11797
11798 (define_split
11799 [(set (match_operand:DI 0 "register_operand" "")
11800 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11801 (match_operand:QI 2 "nonmemory_operand" "")))
11802 (clobber (reg:CC 17))]
11803 "!TARGET_64BIT && reload_completed"
11804 [(const_int 0)]
11805 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11806
11807 (define_insn "x86_shrd_1"
11808 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11809 (ior:SI (ashiftrt:SI (match_dup 0)
11810 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11811 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11812 (minus:QI (const_int 32) (match_dup 2)))))
11813 (clobber (reg:CC 17))]
11814 ""
11815 "@
11816 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11817 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11818 [(set_attr "type" "ishift")
11819 (set_attr "prefix_0f" "1")
11820 (set_attr "pent_pair" "np")
11821 (set_attr "ppro_uops" "few")
11822 (set_attr "mode" "SI")])
11823
11824 (define_expand "x86_shift_adj_3"
11825 [(use (match_operand:SI 0 "register_operand" ""))
11826 (use (match_operand:SI 1 "register_operand" ""))
11827 (use (match_operand:QI 2 "register_operand" ""))]
11828 ""
11829 {
11830 rtx label = gen_label_rtx ();
11831 rtx tmp;
11832
11833 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11834
11835 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11836 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11837 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11838 gen_rtx_LABEL_REF (VOIDmode, label),
11839 pc_rtx);
11840 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11841 JUMP_LABEL (tmp) = label;
11842
11843 emit_move_insn (operands[0], operands[1]);
11844 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11845
11846 emit_label (label);
11847 LABEL_NUSES (label) = 1;
11848
11849 DONE;
11850 })
11851
11852 (define_insn "ashrsi3_31"
11853 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11854 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11855 (match_operand:SI 2 "const_int_operand" "i,i")))
11856 (clobber (reg:CC 17))]
11857 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11858 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11859 "@
11860 {cltd|cdq}
11861 sar{l}\t{%2, %0|%0, %2}"
11862 [(set_attr "type" "imovx,ishift")
11863 (set_attr "prefix_0f" "0,*")
11864 (set_attr "length_immediate" "0,*")
11865 (set_attr "modrm" "0,1")
11866 (set_attr "mode" "SI")])
11867
11868 (define_insn "*ashrsi3_31_zext"
11869 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11870 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11871 (match_operand:SI 2 "const_int_operand" "i,i"))))
11872 (clobber (reg:CC 17))]
11873 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11874 && INTVAL (operands[2]) == 31
11875 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11876 "@
11877 {cltd|cdq}
11878 sar{l}\t{%2, %k0|%k0, %2}"
11879 [(set_attr "type" "imovx,ishift")
11880 (set_attr "prefix_0f" "0,*")
11881 (set_attr "length_immediate" "0,*")
11882 (set_attr "modrm" "0,1")
11883 (set_attr "mode" "SI")])
11884
11885 (define_expand "ashrsi3"
11886 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11887 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11888 (match_operand:QI 2 "nonmemory_operand" "")))
11889 (clobber (reg:CC 17))]
11890 ""
11891 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11892
11893 (define_insn "*ashrsi3_1_one_bit"
11894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11895 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11896 (match_operand:QI 2 "const_int_1_operand" "")))
11897 (clobber (reg:CC 17))]
11898 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11899 && (TARGET_SHIFT1 || optimize_size)"
11900 "sar{l}\t%0"
11901 [(set_attr "type" "ishift")
11902 (set (attr "length")
11903 (if_then_else (match_operand:SI 0 "register_operand" "")
11904 (const_string "2")
11905 (const_string "*")))])
11906
11907 (define_insn "*ashrsi3_1_one_bit_zext"
11908 [(set (match_operand:DI 0 "register_operand" "=r")
11909 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11910 (match_operand:QI 2 "const_int_1_operand" ""))))
11911 (clobber (reg:CC 17))]
11912 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11913 && (TARGET_SHIFT1 || optimize_size)"
11914 "sar{l}\t%k0"
11915 [(set_attr "type" "ishift")
11916 (set_attr "length" "2")])
11917
11918 (define_insn "*ashrsi3_1"
11919 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11920 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11921 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11922 (clobber (reg:CC 17))]
11923 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11924 "@
11925 sar{l}\t{%2, %0|%0, %2}
11926 sar{l}\t{%b2, %0|%0, %b2}"
11927 [(set_attr "type" "ishift")
11928 (set_attr "mode" "SI")])
11929
11930 (define_insn "*ashrsi3_1_zext"
11931 [(set (match_operand:DI 0 "register_operand" "=r,r")
11932 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11933 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11934 (clobber (reg:CC 17))]
11935 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11936 "@
11937 sar{l}\t{%2, %k0|%k0, %2}
11938 sar{l}\t{%b2, %k0|%k0, %b2}"
11939 [(set_attr "type" "ishift")
11940 (set_attr "mode" "SI")])
11941
11942 ;; This pattern can't accept a variable shift count, since shifts by
11943 ;; zero don't affect the flags. We assume that shifts by constant
11944 ;; zero are optimized away.
11945 (define_insn "*ashrsi3_one_bit_cmp"
11946 [(set (reg 17)
11947 (compare
11948 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11949 (match_operand:QI 2 "const_int_1_operand" ""))
11950 (const_int 0)))
11951 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11952 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11953 "ix86_match_ccmode (insn, CCGOCmode)
11954 && (TARGET_SHIFT1 || optimize_size)
11955 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11956 "sar{l}\t%0"
11957 [(set_attr "type" "ishift")
11958 (set (attr "length")
11959 (if_then_else (match_operand:SI 0 "register_operand" "")
11960 (const_string "2")
11961 (const_string "*")))])
11962
11963 (define_insn "*ashrsi3_one_bit_cmp_zext"
11964 [(set (reg 17)
11965 (compare
11966 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11967 (match_operand:QI 2 "const_int_1_operand" ""))
11968 (const_int 0)))
11969 (set (match_operand:DI 0 "register_operand" "=r")
11970 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11971 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11972 && (TARGET_SHIFT1 || optimize_size)
11973 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11974 "sar{l}\t%k0"
11975 [(set_attr "type" "ishift")
11976 (set_attr "length" "2")])
11977
11978 ;; This pattern can't accept a variable shift count, since shifts by
11979 ;; zero don't affect the flags. We assume that shifts by constant
11980 ;; zero are optimized away.
11981 (define_insn "*ashrsi3_cmp"
11982 [(set (reg 17)
11983 (compare
11984 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11985 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11986 (const_int 0)))
11987 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11988 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11989 "ix86_match_ccmode (insn, CCGOCmode)
11990 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11991 "sar{l}\t{%2, %0|%0, %2}"
11992 [(set_attr "type" "ishift")
11993 (set_attr "mode" "SI")])
11994
11995 (define_insn "*ashrsi3_cmp_zext"
11996 [(set (reg 17)
11997 (compare
11998 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11999 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12000 (const_int 0)))
12001 (set (match_operand:DI 0 "register_operand" "=r")
12002 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12003 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12004 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12005 "sar{l}\t{%2, %k0|%k0, %2}"
12006 [(set_attr "type" "ishift")
12007 (set_attr "mode" "SI")])
12008
12009 (define_expand "ashrhi3"
12010 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12011 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12012 (match_operand:QI 2 "nonmemory_operand" "")))
12013 (clobber (reg:CC 17))]
12014 "TARGET_HIMODE_MATH"
12015 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12016
12017 (define_insn "*ashrhi3_1_one_bit"
12018 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12019 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12020 (match_operand:QI 2 "const_int_1_operand" "")))
12021 (clobber (reg:CC 17))]
12022 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12023 && (TARGET_SHIFT1 || optimize_size)"
12024 "sar{w}\t%0"
12025 [(set_attr "type" "ishift")
12026 (set (attr "length")
12027 (if_then_else (match_operand 0 "register_operand" "")
12028 (const_string "2")
12029 (const_string "*")))])
12030
12031 (define_insn "*ashrhi3_1"
12032 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12033 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12034 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12035 (clobber (reg:CC 17))]
12036 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12037 "@
12038 sar{w}\t{%2, %0|%0, %2}
12039 sar{w}\t{%b2, %0|%0, %b2}"
12040 [(set_attr "type" "ishift")
12041 (set_attr "mode" "HI")])
12042
12043 ;; This pattern can't accept a variable shift count, since shifts by
12044 ;; zero don't affect the flags. We assume that shifts by constant
12045 ;; zero are optimized away.
12046 (define_insn "*ashrhi3_one_bit_cmp"
12047 [(set (reg 17)
12048 (compare
12049 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12050 (match_operand:QI 2 "const_int_1_operand" ""))
12051 (const_int 0)))
12052 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12053 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12054 "ix86_match_ccmode (insn, CCGOCmode)
12055 && (TARGET_SHIFT1 || optimize_size)
12056 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12057 "sar{w}\t%0"
12058 [(set_attr "type" "ishift")
12059 (set (attr "length")
12060 (if_then_else (match_operand 0 "register_operand" "")
12061 (const_string "2")
12062 (const_string "*")))])
12063
12064 ;; This pattern can't accept a variable shift count, since shifts by
12065 ;; zero don't affect the flags. We assume that shifts by constant
12066 ;; zero are optimized away.
12067 (define_insn "*ashrhi3_cmp"
12068 [(set (reg 17)
12069 (compare
12070 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12071 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12072 (const_int 0)))
12073 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12074 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12075 "ix86_match_ccmode (insn, CCGOCmode)
12076 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12077 "sar{w}\t{%2, %0|%0, %2}"
12078 [(set_attr "type" "ishift")
12079 (set_attr "mode" "HI")])
12080
12081 (define_expand "ashrqi3"
12082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12083 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12084 (match_operand:QI 2 "nonmemory_operand" "")))
12085 (clobber (reg:CC 17))]
12086 "TARGET_QIMODE_MATH"
12087 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12088
12089 (define_insn "*ashrqi3_1_one_bit"
12090 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12091 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12092 (match_operand:QI 2 "const_int_1_operand" "")))
12093 (clobber (reg:CC 17))]
12094 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12095 && (TARGET_SHIFT1 || optimize_size)"
12096 "sar{b}\t%0"
12097 [(set_attr "type" "ishift")
12098 (set (attr "length")
12099 (if_then_else (match_operand 0 "register_operand" "")
12100 (const_string "2")
12101 (const_string "*")))])
12102
12103 (define_insn "*ashrqi3_1_one_bit_slp"
12104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12105 (ashiftrt:QI (match_dup 0)
12106 (match_operand:QI 1 "const_int_1_operand" "")))
12107 (clobber (reg:CC 17))]
12108 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12109 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12110 && (TARGET_SHIFT1 || optimize_size)"
12111 "sar{b}\t%0"
12112 [(set_attr "type" "ishift1")
12113 (set (attr "length")
12114 (if_then_else (match_operand 0 "register_operand" "")
12115 (const_string "2")
12116 (const_string "*")))])
12117
12118 (define_insn "*ashrqi3_1"
12119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12120 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12121 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12122 (clobber (reg:CC 17))]
12123 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12124 "@
12125 sar{b}\t{%2, %0|%0, %2}
12126 sar{b}\t{%b2, %0|%0, %b2}"
12127 [(set_attr "type" "ishift")
12128 (set_attr "mode" "QI")])
12129
12130 (define_insn "*ashrqi3_1_slp"
12131 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12132 (ashiftrt:QI (match_dup 0)
12133 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12134 (clobber (reg:CC 17))]
12135 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12136 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12137 "@
12138 sar{b}\t{%1, %0|%0, %1}
12139 sar{b}\t{%b1, %0|%0, %b1}"
12140 [(set_attr "type" "ishift1")
12141 (set_attr "mode" "QI")])
12142
12143 ;; This pattern can't accept a variable shift count, since shifts by
12144 ;; zero don't affect the flags. We assume that shifts by constant
12145 ;; zero are optimized away.
12146 (define_insn "*ashrqi3_one_bit_cmp"
12147 [(set (reg 17)
12148 (compare
12149 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12150 (match_operand:QI 2 "const_int_1_operand" "I"))
12151 (const_int 0)))
12152 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12153 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12154 "ix86_match_ccmode (insn, CCGOCmode)
12155 && (TARGET_SHIFT1 || optimize_size)
12156 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12157 "sar{b}\t%0"
12158 [(set_attr "type" "ishift")
12159 (set (attr "length")
12160 (if_then_else (match_operand 0 "register_operand" "")
12161 (const_string "2")
12162 (const_string "*")))])
12163
12164 ;; This pattern can't accept a variable shift count, since shifts by
12165 ;; zero don't affect the flags. We assume that shifts by constant
12166 ;; zero are optimized away.
12167 (define_insn "*ashrqi3_cmp"
12168 [(set (reg 17)
12169 (compare
12170 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12171 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12172 (const_int 0)))
12173 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12174 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12175 "ix86_match_ccmode (insn, CCGOCmode)
12176 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12177 "sar{b}\t{%2, %0|%0, %2}"
12178 [(set_attr "type" "ishift")
12179 (set_attr "mode" "QI")])
12180 \f
12181 ;; Logical shift instructions
12182
12183 ;; See comment above `ashldi3' about how this works.
12184
12185 (define_expand "lshrdi3"
12186 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12187 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12188 (match_operand:QI 2 "nonmemory_operand" "")))
12189 (clobber (reg:CC 17))])]
12190 ""
12191 {
12192 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12193 {
12194 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12195 DONE;
12196 }
12197 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12198 DONE;
12199 })
12200
12201 (define_insn "*lshrdi3_1_one_bit_rex64"
12202 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12203 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12204 (match_operand:QI 2 "const_int_1_operand" "")))
12205 (clobber (reg:CC 17))]
12206 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12207 && (TARGET_SHIFT1 || optimize_size)"
12208 "shr{q}\t%0"
12209 [(set_attr "type" "ishift")
12210 (set (attr "length")
12211 (if_then_else (match_operand:DI 0 "register_operand" "")
12212 (const_string "2")
12213 (const_string "*")))])
12214
12215 (define_insn "*lshrdi3_1_rex64"
12216 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12217 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12218 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12219 (clobber (reg:CC 17))]
12220 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12221 "@
12222 shr{q}\t{%2, %0|%0, %2}
12223 shr{q}\t{%b2, %0|%0, %b2}"
12224 [(set_attr "type" "ishift")
12225 (set_attr "mode" "DI")])
12226
12227 ;; This pattern can't accept a variable shift count, since shifts by
12228 ;; zero don't affect the flags. We assume that shifts by constant
12229 ;; zero are optimized away.
12230 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12231 [(set (reg 17)
12232 (compare
12233 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const_int_1_operand" ""))
12235 (const_int 0)))
12236 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12237 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12238 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12239 && (TARGET_SHIFT1 || optimize_size)
12240 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12241 "shr{q}\t%0"
12242 [(set_attr "type" "ishift")
12243 (set (attr "length")
12244 (if_then_else (match_operand:DI 0 "register_operand" "")
12245 (const_string "2")
12246 (const_string "*")))])
12247
12248 ;; This pattern can't accept a variable shift count, since shifts by
12249 ;; zero don't affect the flags. We assume that shifts by constant
12250 ;; zero are optimized away.
12251 (define_insn "*lshrdi3_cmp_rex64"
12252 [(set (reg 17)
12253 (compare
12254 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12255 (match_operand:QI 2 "const_int_operand" "e"))
12256 (const_int 0)))
12257 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12258 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12259 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12260 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12261 "shr{q}\t{%2, %0|%0, %2}"
12262 [(set_attr "type" "ishift")
12263 (set_attr "mode" "DI")])
12264
12265 (define_insn "lshrdi3_1"
12266 [(set (match_operand:DI 0 "register_operand" "=r")
12267 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12268 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12269 (clobber (match_scratch:SI 3 "=&r"))
12270 (clobber (reg:CC 17))]
12271 "!TARGET_64BIT && TARGET_CMOVE"
12272 "#"
12273 [(set_attr "type" "multi")])
12274
12275 (define_insn "*lshrdi3_2"
12276 [(set (match_operand:DI 0 "register_operand" "=r")
12277 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12278 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12279 (clobber (reg:CC 17))]
12280 "!TARGET_64BIT"
12281 "#"
12282 [(set_attr "type" "multi")])
12283
12284 (define_split
12285 [(set (match_operand:DI 0 "register_operand" "")
12286 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12287 (match_operand:QI 2 "nonmemory_operand" "")))
12288 (clobber (match_scratch:SI 3 ""))
12289 (clobber (reg:CC 17))]
12290 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12291 [(const_int 0)]
12292 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12293
12294 (define_split
12295 [(set (match_operand:DI 0 "register_operand" "")
12296 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12297 (match_operand:QI 2 "nonmemory_operand" "")))
12298 (clobber (reg:CC 17))]
12299 "!TARGET_64BIT && reload_completed"
12300 [(const_int 0)]
12301 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12302
12303 (define_expand "lshrsi3"
12304 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12305 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12306 (match_operand:QI 2 "nonmemory_operand" "")))
12307 (clobber (reg:CC 17))]
12308 ""
12309 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12310
12311 (define_insn "*lshrsi3_1_one_bit"
12312 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12313 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const_int_1_operand" "")))
12315 (clobber (reg:CC 17))]
12316 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12317 && (TARGET_SHIFT1 || optimize_size)"
12318 "shr{l}\t%0"
12319 [(set_attr "type" "ishift")
12320 (set (attr "length")
12321 (if_then_else (match_operand:SI 0 "register_operand" "")
12322 (const_string "2")
12323 (const_string "*")))])
12324
12325 (define_insn "*lshrsi3_1_one_bit_zext"
12326 [(set (match_operand:DI 0 "register_operand" "=r")
12327 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12328 (match_operand:QI 2 "const_int_1_operand" "")))
12329 (clobber (reg:CC 17))]
12330 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12331 && (TARGET_SHIFT1 || optimize_size)"
12332 "shr{l}\t%k0"
12333 [(set_attr "type" "ishift")
12334 (set_attr "length" "2")])
12335
12336 (define_insn "*lshrsi3_1"
12337 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12338 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12339 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12340 (clobber (reg:CC 17))]
12341 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12342 "@
12343 shr{l}\t{%2, %0|%0, %2}
12344 shr{l}\t{%b2, %0|%0, %b2}"
12345 [(set_attr "type" "ishift")
12346 (set_attr "mode" "SI")])
12347
12348 (define_insn "*lshrsi3_1_zext"
12349 [(set (match_operand:DI 0 "register_operand" "=r,r")
12350 (zero_extend:DI
12351 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12352 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12353 (clobber (reg:CC 17))]
12354 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12355 "@
12356 shr{l}\t{%2, %k0|%k0, %2}
12357 shr{l}\t{%b2, %k0|%k0, %b2}"
12358 [(set_attr "type" "ishift")
12359 (set_attr "mode" "SI")])
12360
12361 ;; This pattern can't accept a variable shift count, since shifts by
12362 ;; zero don't affect the flags. We assume that shifts by constant
12363 ;; zero are optimized away.
12364 (define_insn "*lshrsi3_one_bit_cmp"
12365 [(set (reg 17)
12366 (compare
12367 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const_int_1_operand" ""))
12369 (const_int 0)))
12370 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12371 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12372 "ix86_match_ccmode (insn, CCGOCmode)
12373 && (TARGET_SHIFT1 || optimize_size)
12374 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375 "shr{l}\t%0"
12376 [(set_attr "type" "ishift")
12377 (set (attr "length")
12378 (if_then_else (match_operand:SI 0 "register_operand" "")
12379 (const_string "2")
12380 (const_string "*")))])
12381
12382 (define_insn "*lshrsi3_cmp_one_bit_zext"
12383 [(set (reg 17)
12384 (compare
12385 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12386 (match_operand:QI 2 "const_int_1_operand" ""))
12387 (const_int 0)))
12388 (set (match_operand:DI 0 "register_operand" "=r")
12389 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12390 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12391 && (TARGET_SHIFT1 || optimize_size)
12392 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12393 "shr{l}\t%k0"
12394 [(set_attr "type" "ishift")
12395 (set_attr "length" "2")])
12396
12397 ;; This pattern can't accept a variable shift count, since shifts by
12398 ;; zero don't affect the flags. We assume that shifts by constant
12399 ;; zero are optimized away.
12400 (define_insn "*lshrsi3_cmp"
12401 [(set (reg 17)
12402 (compare
12403 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12404 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12405 (const_int 0)))
12406 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12407 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12408 "ix86_match_ccmode (insn, CCGOCmode)
12409 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12410 "shr{l}\t{%2, %0|%0, %2}"
12411 [(set_attr "type" "ishift")
12412 (set_attr "mode" "SI")])
12413
12414 (define_insn "*lshrsi3_cmp_zext"
12415 [(set (reg 17)
12416 (compare
12417 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12418 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12419 (const_int 0)))
12420 (set (match_operand:DI 0 "register_operand" "=r")
12421 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12422 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12423 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12424 "shr{l}\t{%2, %k0|%k0, %2}"
12425 [(set_attr "type" "ishift")
12426 (set_attr "mode" "SI")])
12427
12428 (define_expand "lshrhi3"
12429 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12430 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12431 (match_operand:QI 2 "nonmemory_operand" "")))
12432 (clobber (reg:CC 17))]
12433 "TARGET_HIMODE_MATH"
12434 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12435
12436 (define_insn "*lshrhi3_1_one_bit"
12437 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12438 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12439 (match_operand:QI 2 "const_int_1_operand" "")))
12440 (clobber (reg:CC 17))]
12441 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12442 && (TARGET_SHIFT1 || optimize_size)"
12443 "shr{w}\t%0"
12444 [(set_attr "type" "ishift")
12445 (set (attr "length")
12446 (if_then_else (match_operand 0 "register_operand" "")
12447 (const_string "2")
12448 (const_string "*")))])
12449
12450 (define_insn "*lshrhi3_1"
12451 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12452 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12453 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12454 (clobber (reg:CC 17))]
12455 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12456 "@
12457 shr{w}\t{%2, %0|%0, %2}
12458 shr{w}\t{%b2, %0|%0, %b2}"
12459 [(set_attr "type" "ishift")
12460 (set_attr "mode" "HI")])
12461
12462 ;; This pattern can't accept a variable shift count, since shifts by
12463 ;; zero don't affect the flags. We assume that shifts by constant
12464 ;; zero are optimized away.
12465 (define_insn "*lshrhi3_one_bit_cmp"
12466 [(set (reg 17)
12467 (compare
12468 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12469 (match_operand:QI 2 "const_int_1_operand" ""))
12470 (const_int 0)))
12471 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12472 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12473 "ix86_match_ccmode (insn, CCGOCmode)
12474 && (TARGET_SHIFT1 || optimize_size)
12475 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12476 "shr{w}\t%0"
12477 [(set_attr "type" "ishift")
12478 (set (attr "length")
12479 (if_then_else (match_operand:SI 0 "register_operand" "")
12480 (const_string "2")
12481 (const_string "*")))])
12482
12483 ;; This pattern can't accept a variable shift count, since shifts by
12484 ;; zero don't affect the flags. We assume that shifts by constant
12485 ;; zero are optimized away.
12486 (define_insn "*lshrhi3_cmp"
12487 [(set (reg 17)
12488 (compare
12489 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12490 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12491 (const_int 0)))
12492 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12493 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12494 "ix86_match_ccmode (insn, CCGOCmode)
12495 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12496 "shr{w}\t{%2, %0|%0, %2}"
12497 [(set_attr "type" "ishift")
12498 (set_attr "mode" "HI")])
12499
12500 (define_expand "lshrqi3"
12501 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12502 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12503 (match_operand:QI 2 "nonmemory_operand" "")))
12504 (clobber (reg:CC 17))]
12505 "TARGET_QIMODE_MATH"
12506 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12507
12508 (define_insn "*lshrqi3_1_one_bit"
12509 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12510 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12511 (match_operand:QI 2 "const_int_1_operand" "")))
12512 (clobber (reg:CC 17))]
12513 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12514 && (TARGET_SHIFT1 || optimize_size)"
12515 "shr{b}\t%0"
12516 [(set_attr "type" "ishift")
12517 (set (attr "length")
12518 (if_then_else (match_operand 0 "register_operand" "")
12519 (const_string "2")
12520 (const_string "*")))])
12521
12522 (define_insn "*lshrqi3_1_one_bit_slp"
12523 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12524 (lshiftrt:QI (match_dup 0)
12525 (match_operand:QI 1 "const_int_1_operand" "")))
12526 (clobber (reg:CC 17))]
12527 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12528 && (TARGET_SHIFT1 || optimize_size)"
12529 "shr{b}\t%0"
12530 [(set_attr "type" "ishift1")
12531 (set (attr "length")
12532 (if_then_else (match_operand 0 "register_operand" "")
12533 (const_string "2")
12534 (const_string "*")))])
12535
12536 (define_insn "*lshrqi3_1"
12537 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12538 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12539 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12540 (clobber (reg:CC 17))]
12541 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12542 "@
12543 shr{b}\t{%2, %0|%0, %2}
12544 shr{b}\t{%b2, %0|%0, %b2}"
12545 [(set_attr "type" "ishift")
12546 (set_attr "mode" "QI")])
12547
12548 (define_insn "*lshrqi3_1_slp"
12549 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12550 (lshiftrt:QI (match_dup 0)
12551 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12552 (clobber (reg:CC 17))]
12553 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12554 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12555 "@
12556 shr{b}\t{%1, %0|%0, %1}
12557 shr{b}\t{%b1, %0|%0, %b1}"
12558 [(set_attr "type" "ishift1")
12559 (set_attr "mode" "QI")])
12560
12561 ;; This pattern can't accept a variable shift count, since shifts by
12562 ;; zero don't affect the flags. We assume that shifts by constant
12563 ;; zero are optimized away.
12564 (define_insn "*lshrqi2_one_bit_cmp"
12565 [(set (reg 17)
12566 (compare
12567 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12568 (match_operand:QI 2 "const_int_1_operand" ""))
12569 (const_int 0)))
12570 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12571 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12572 "ix86_match_ccmode (insn, CCGOCmode)
12573 && (TARGET_SHIFT1 || optimize_size)
12574 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12575 "shr{b}\t%0"
12576 [(set_attr "type" "ishift")
12577 (set (attr "length")
12578 (if_then_else (match_operand:SI 0 "register_operand" "")
12579 (const_string "2")
12580 (const_string "*")))])
12581
12582 ;; This pattern can't accept a variable shift count, since shifts by
12583 ;; zero don't affect the flags. We assume that shifts by constant
12584 ;; zero are optimized away.
12585 (define_insn "*lshrqi2_cmp"
12586 [(set (reg 17)
12587 (compare
12588 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12589 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12590 (const_int 0)))
12591 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12592 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12593 "ix86_match_ccmode (insn, CCGOCmode)
12594 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12595 "shr{b}\t{%2, %0|%0, %2}"
12596 [(set_attr "type" "ishift")
12597 (set_attr "mode" "QI")])
12598 \f
12599 ;; Rotate instructions
12600
12601 (define_expand "rotldi3"
12602 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12603 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12604 (match_operand:QI 2 "nonmemory_operand" "")))
12605 (clobber (reg:CC 17))]
12606 "TARGET_64BIT"
12607 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12608
12609 (define_insn "*rotlsi3_1_one_bit_rex64"
12610 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12611 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12612 (match_operand:QI 2 "const_int_1_operand" "")))
12613 (clobber (reg:CC 17))]
12614 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12615 && (TARGET_SHIFT1 || optimize_size)"
12616 "rol{q}\t%0"
12617 [(set_attr "type" "rotate")
12618 (set (attr "length")
12619 (if_then_else (match_operand:DI 0 "register_operand" "")
12620 (const_string "2")
12621 (const_string "*")))])
12622
12623 (define_insn "*rotldi3_1_rex64"
12624 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12625 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12626 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12627 (clobber (reg:CC 17))]
12628 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12629 "@
12630 rol{q}\t{%2, %0|%0, %2}
12631 rol{q}\t{%b2, %0|%0, %b2}"
12632 [(set_attr "type" "rotate")
12633 (set_attr "mode" "DI")])
12634
12635 (define_expand "rotlsi3"
12636 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12637 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12638 (match_operand:QI 2 "nonmemory_operand" "")))
12639 (clobber (reg:CC 17))]
12640 ""
12641 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12642
12643 (define_insn "*rotlsi3_1_one_bit"
12644 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12645 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12646 (match_operand:QI 2 "const_int_1_operand" "")))
12647 (clobber (reg:CC 17))]
12648 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12649 && (TARGET_SHIFT1 || optimize_size)"
12650 "rol{l}\t%0"
12651 [(set_attr "type" "rotate")
12652 (set (attr "length")
12653 (if_then_else (match_operand:SI 0 "register_operand" "")
12654 (const_string "2")
12655 (const_string "*")))])
12656
12657 (define_insn "*rotlsi3_1_one_bit_zext"
12658 [(set (match_operand:DI 0 "register_operand" "=r")
12659 (zero_extend:DI
12660 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12661 (match_operand:QI 2 "const_int_1_operand" ""))))
12662 (clobber (reg:CC 17))]
12663 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12664 && (TARGET_SHIFT1 || optimize_size)"
12665 "rol{l}\t%k0"
12666 [(set_attr "type" "rotate")
12667 (set_attr "length" "2")])
12668
12669 (define_insn "*rotlsi3_1"
12670 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12671 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12672 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12673 (clobber (reg:CC 17))]
12674 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12675 "@
12676 rol{l}\t{%2, %0|%0, %2}
12677 rol{l}\t{%b2, %0|%0, %b2}"
12678 [(set_attr "type" "rotate")
12679 (set_attr "mode" "SI")])
12680
12681 (define_insn "*rotlsi3_1_zext"
12682 [(set (match_operand:DI 0 "register_operand" "=r,r")
12683 (zero_extend:DI
12684 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12685 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12686 (clobber (reg:CC 17))]
12687 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12688 "@
12689 rol{l}\t{%2, %k0|%k0, %2}
12690 rol{l}\t{%b2, %k0|%k0, %b2}"
12691 [(set_attr "type" "rotate")
12692 (set_attr "mode" "SI")])
12693
12694 (define_expand "rotlhi3"
12695 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12696 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12697 (match_operand:QI 2 "nonmemory_operand" "")))
12698 (clobber (reg:CC 17))]
12699 "TARGET_HIMODE_MATH"
12700 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12701
12702 (define_insn "*rotlhi3_1_one_bit"
12703 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12704 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12705 (match_operand:QI 2 "const_int_1_operand" "")))
12706 (clobber (reg:CC 17))]
12707 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12708 && (TARGET_SHIFT1 || optimize_size)"
12709 "rol{w}\t%0"
12710 [(set_attr "type" "rotate")
12711 (set (attr "length")
12712 (if_then_else (match_operand 0 "register_operand" "")
12713 (const_string "2")
12714 (const_string "*")))])
12715
12716 (define_insn "*rotlhi3_1"
12717 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12718 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12719 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12720 (clobber (reg:CC 17))]
12721 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12722 "@
12723 rol{w}\t{%2, %0|%0, %2}
12724 rol{w}\t{%b2, %0|%0, %b2}"
12725 [(set_attr "type" "rotate")
12726 (set_attr "mode" "HI")])
12727
12728 (define_expand "rotlqi3"
12729 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12730 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12731 (match_operand:QI 2 "nonmemory_operand" "")))
12732 (clobber (reg:CC 17))]
12733 "TARGET_QIMODE_MATH"
12734 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12735
12736 (define_insn "*rotlqi3_1_one_bit_slp"
12737 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12738 (rotate:QI (match_dup 0)
12739 (match_operand:QI 1 "const_int_1_operand" "")))
12740 (clobber (reg:CC 17))]
12741 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12742 && (TARGET_SHIFT1 || optimize_size)"
12743 "rol{b}\t%0"
12744 [(set_attr "type" "rotate1")
12745 (set (attr "length")
12746 (if_then_else (match_operand 0 "register_operand" "")
12747 (const_string "2")
12748 (const_string "*")))])
12749
12750 (define_insn "*rotlqi3_1_one_bit"
12751 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12752 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12753 (match_operand:QI 2 "const_int_1_operand" "")))
12754 (clobber (reg:CC 17))]
12755 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12756 && (TARGET_SHIFT1 || optimize_size)"
12757 "rol{b}\t%0"
12758 [(set_attr "type" "rotate")
12759 (set (attr "length")
12760 (if_then_else (match_operand 0 "register_operand" "")
12761 (const_string "2")
12762 (const_string "*")))])
12763
12764 (define_insn "*rotlqi3_1_slp"
12765 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12766 (rotate:QI (match_dup 0)
12767 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12768 (clobber (reg:CC 17))]
12769 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12770 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12771 "@
12772 rol{b}\t{%1, %0|%0, %1}
12773 rol{b}\t{%b1, %0|%0, %b1}"
12774 [(set_attr "type" "rotate1")
12775 (set_attr "mode" "QI")])
12776
12777 (define_insn "*rotlqi3_1"
12778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12779 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12780 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12781 (clobber (reg:CC 17))]
12782 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12783 "@
12784 rol{b}\t{%2, %0|%0, %2}
12785 rol{b}\t{%b2, %0|%0, %b2}"
12786 [(set_attr "type" "rotate")
12787 (set_attr "mode" "QI")])
12788
12789 (define_expand "rotrdi3"
12790 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12791 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12792 (match_operand:QI 2 "nonmemory_operand" "")))
12793 (clobber (reg:CC 17))]
12794 "TARGET_64BIT"
12795 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12796
12797 (define_insn "*rotrdi3_1_one_bit_rex64"
12798 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12799 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12800 (match_operand:QI 2 "const_int_1_operand" "")))
12801 (clobber (reg:CC 17))]
12802 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12803 && (TARGET_SHIFT1 || optimize_size)"
12804 "ror{q}\t%0"
12805 [(set_attr "type" "rotate")
12806 (set (attr "length")
12807 (if_then_else (match_operand:DI 0 "register_operand" "")
12808 (const_string "2")
12809 (const_string "*")))])
12810
12811 (define_insn "*rotrdi3_1_rex64"
12812 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12813 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12814 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12815 (clobber (reg:CC 17))]
12816 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12817 "@
12818 ror{q}\t{%2, %0|%0, %2}
12819 ror{q}\t{%b2, %0|%0, %b2}"
12820 [(set_attr "type" "rotate")
12821 (set_attr "mode" "DI")])
12822
12823 (define_expand "rotrsi3"
12824 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12825 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12826 (match_operand:QI 2 "nonmemory_operand" "")))
12827 (clobber (reg:CC 17))]
12828 ""
12829 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12830
12831 (define_insn "*rotrsi3_1_one_bit"
12832 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12833 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12834 (match_operand:QI 2 "const_int_1_operand" "")))
12835 (clobber (reg:CC 17))]
12836 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12837 && (TARGET_SHIFT1 || optimize_size)"
12838 "ror{l}\t%0"
12839 [(set_attr "type" "rotate")
12840 (set (attr "length")
12841 (if_then_else (match_operand:SI 0 "register_operand" "")
12842 (const_string "2")
12843 (const_string "*")))])
12844
12845 (define_insn "*rotrsi3_1_one_bit_zext"
12846 [(set (match_operand:DI 0 "register_operand" "=r")
12847 (zero_extend:DI
12848 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12849 (match_operand:QI 2 "const_int_1_operand" ""))))
12850 (clobber (reg:CC 17))]
12851 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12852 && (TARGET_SHIFT1 || optimize_size)"
12853 "ror{l}\t%k0"
12854 [(set_attr "type" "rotate")
12855 (set (attr "length")
12856 (if_then_else (match_operand:SI 0 "register_operand" "")
12857 (const_string "2")
12858 (const_string "*")))])
12859
12860 (define_insn "*rotrsi3_1"
12861 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12862 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12863 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12864 (clobber (reg:CC 17))]
12865 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12866 "@
12867 ror{l}\t{%2, %0|%0, %2}
12868 ror{l}\t{%b2, %0|%0, %b2}"
12869 [(set_attr "type" "rotate")
12870 (set_attr "mode" "SI")])
12871
12872 (define_insn "*rotrsi3_1_zext"
12873 [(set (match_operand:DI 0 "register_operand" "=r,r")
12874 (zero_extend:DI
12875 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12876 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12877 (clobber (reg:CC 17))]
12878 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12879 "@
12880 ror{l}\t{%2, %k0|%k0, %2}
12881 ror{l}\t{%b2, %k0|%k0, %b2}"
12882 [(set_attr "type" "rotate")
12883 (set_attr "mode" "SI")])
12884
12885 (define_expand "rotrhi3"
12886 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12887 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12888 (match_operand:QI 2 "nonmemory_operand" "")))
12889 (clobber (reg:CC 17))]
12890 "TARGET_HIMODE_MATH"
12891 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12892
12893 (define_insn "*rotrhi3_one_bit"
12894 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12895 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12896 (match_operand:QI 2 "const_int_1_operand" "")))
12897 (clobber (reg:CC 17))]
12898 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12899 && (TARGET_SHIFT1 || optimize_size)"
12900 "ror{w}\t%0"
12901 [(set_attr "type" "rotate")
12902 (set (attr "length")
12903 (if_then_else (match_operand 0 "register_operand" "")
12904 (const_string "2")
12905 (const_string "*")))])
12906
12907 (define_insn "*rotrhi3"
12908 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12909 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12910 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12911 (clobber (reg:CC 17))]
12912 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12913 "@
12914 ror{w}\t{%2, %0|%0, %2}
12915 ror{w}\t{%b2, %0|%0, %b2}"
12916 [(set_attr "type" "rotate")
12917 (set_attr "mode" "HI")])
12918
12919 (define_expand "rotrqi3"
12920 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12921 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12922 (match_operand:QI 2 "nonmemory_operand" "")))
12923 (clobber (reg:CC 17))]
12924 "TARGET_QIMODE_MATH"
12925 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12926
12927 (define_insn "*rotrqi3_1_one_bit"
12928 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12929 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12930 (match_operand:QI 2 "const_int_1_operand" "")))
12931 (clobber (reg:CC 17))]
12932 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12933 && (TARGET_SHIFT1 || optimize_size)"
12934 "ror{b}\t%0"
12935 [(set_attr "type" "rotate")
12936 (set (attr "length")
12937 (if_then_else (match_operand 0 "register_operand" "")
12938 (const_string "2")
12939 (const_string "*")))])
12940
12941 (define_insn "*rotrqi3_1_one_bit_slp"
12942 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12943 (rotatert:QI (match_dup 0)
12944 (match_operand:QI 1 "const_int_1_operand" "")))
12945 (clobber (reg:CC 17))]
12946 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12947 && (TARGET_SHIFT1 || optimize_size)"
12948 "ror{b}\t%0"
12949 [(set_attr "type" "rotate1")
12950 (set (attr "length")
12951 (if_then_else (match_operand 0 "register_operand" "")
12952 (const_string "2")
12953 (const_string "*")))])
12954
12955 (define_insn "*rotrqi3_1"
12956 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12957 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12958 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12959 (clobber (reg:CC 17))]
12960 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12961 "@
12962 ror{b}\t{%2, %0|%0, %2}
12963 ror{b}\t{%b2, %0|%0, %b2}"
12964 [(set_attr "type" "rotate")
12965 (set_attr "mode" "QI")])
12966
12967 (define_insn "*rotrqi3_1_slp"
12968 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12969 (rotatert:QI (match_dup 0)
12970 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12971 (clobber (reg:CC 17))]
12972 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12973 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12974 "@
12975 ror{b}\t{%1, %0|%0, %1}
12976 ror{b}\t{%b1, %0|%0, %b1}"
12977 [(set_attr "type" "rotate1")
12978 (set_attr "mode" "QI")])
12979 \f
12980 ;; Bit set / bit test instructions
12981
12982 (define_expand "extv"
12983 [(set (match_operand:SI 0 "register_operand" "")
12984 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12985 (match_operand:SI 2 "immediate_operand" "")
12986 (match_operand:SI 3 "immediate_operand" "")))]
12987 ""
12988 {
12989 /* Handle extractions from %ah et al. */
12990 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12991 FAIL;
12992
12993 /* From mips.md: extract_bit_field doesn't verify that our source
12994 matches the predicate, so check it again here. */
12995 if (! register_operand (operands[1], VOIDmode))
12996 FAIL;
12997 })
12998
12999 (define_expand "extzv"
13000 [(set (match_operand:SI 0 "register_operand" "")
13001 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13002 (match_operand:SI 2 "immediate_operand" "")
13003 (match_operand:SI 3 "immediate_operand" "")))]
13004 ""
13005 {
13006 /* Handle extractions from %ah et al. */
13007 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13008 FAIL;
13009
13010 /* From mips.md: extract_bit_field doesn't verify that our source
13011 matches the predicate, so check it again here. */
13012 if (! register_operand (operands[1], VOIDmode))
13013 FAIL;
13014 })
13015
13016 (define_expand "insv"
13017 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13018 (match_operand:SI 1 "immediate_operand" "")
13019 (match_operand:SI 2 "immediate_operand" ""))
13020 (match_operand:SI 3 "register_operand" ""))]
13021 ""
13022 {
13023 /* Handle extractions from %ah et al. */
13024 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13025 FAIL;
13026
13027 /* From mips.md: insert_bit_field doesn't verify that our source
13028 matches the predicate, so check it again here. */
13029 if (! register_operand (operands[0], VOIDmode))
13030 FAIL;
13031 })
13032
13033 ;; %%% bts, btr, btc, bt.
13034 \f
13035 ;; Store-flag instructions.
13036
13037 ;; For all sCOND expanders, also expand the compare or test insn that
13038 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13039
13040 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13041 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13042 ;; way, which can later delete the movzx if only QImode is needed.
13043
13044 (define_expand "seq"
13045 [(set (match_operand:QI 0 "register_operand" "")
13046 (eq:QI (reg:CC 17) (const_int 0)))]
13047 ""
13048 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13049
13050 (define_expand "sne"
13051 [(set (match_operand:QI 0 "register_operand" "")
13052 (ne:QI (reg:CC 17) (const_int 0)))]
13053 ""
13054 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13055
13056 (define_expand "sgt"
13057 [(set (match_operand:QI 0 "register_operand" "")
13058 (gt:QI (reg:CC 17) (const_int 0)))]
13059 ""
13060 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13061
13062 (define_expand "sgtu"
13063 [(set (match_operand:QI 0 "register_operand" "")
13064 (gtu:QI (reg:CC 17) (const_int 0)))]
13065 ""
13066 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13067
13068 (define_expand "slt"
13069 [(set (match_operand:QI 0 "register_operand" "")
13070 (lt:QI (reg:CC 17) (const_int 0)))]
13071 ""
13072 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13073
13074 (define_expand "sltu"
13075 [(set (match_operand:QI 0 "register_operand" "")
13076 (ltu:QI (reg:CC 17) (const_int 0)))]
13077 ""
13078 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13079
13080 (define_expand "sge"
13081 [(set (match_operand:QI 0 "register_operand" "")
13082 (ge:QI (reg:CC 17) (const_int 0)))]
13083 ""
13084 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13085
13086 (define_expand "sgeu"
13087 [(set (match_operand:QI 0 "register_operand" "")
13088 (geu:QI (reg:CC 17) (const_int 0)))]
13089 ""
13090 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13091
13092 (define_expand "sle"
13093 [(set (match_operand:QI 0 "register_operand" "")
13094 (le:QI (reg:CC 17) (const_int 0)))]
13095 ""
13096 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13097
13098 (define_expand "sleu"
13099 [(set (match_operand:QI 0 "register_operand" "")
13100 (leu:QI (reg:CC 17) (const_int 0)))]
13101 ""
13102 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13103
13104 (define_expand "sunordered"
13105 [(set (match_operand:QI 0 "register_operand" "")
13106 (unordered:QI (reg:CC 17) (const_int 0)))]
13107 "TARGET_80387 || TARGET_SSE"
13108 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13109
13110 (define_expand "sordered"
13111 [(set (match_operand:QI 0 "register_operand" "")
13112 (ordered:QI (reg:CC 17) (const_int 0)))]
13113 "TARGET_80387"
13114 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13115
13116 (define_expand "suneq"
13117 [(set (match_operand:QI 0 "register_operand" "")
13118 (uneq:QI (reg:CC 17) (const_int 0)))]
13119 "TARGET_80387 || TARGET_SSE"
13120 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13121
13122 (define_expand "sunge"
13123 [(set (match_operand:QI 0 "register_operand" "")
13124 (unge:QI (reg:CC 17) (const_int 0)))]
13125 "TARGET_80387 || TARGET_SSE"
13126 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13127
13128 (define_expand "sungt"
13129 [(set (match_operand:QI 0 "register_operand" "")
13130 (ungt:QI (reg:CC 17) (const_int 0)))]
13131 "TARGET_80387 || TARGET_SSE"
13132 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13133
13134 (define_expand "sunle"
13135 [(set (match_operand:QI 0 "register_operand" "")
13136 (unle:QI (reg:CC 17) (const_int 0)))]
13137 "TARGET_80387 || TARGET_SSE"
13138 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13139
13140 (define_expand "sunlt"
13141 [(set (match_operand:QI 0 "register_operand" "")
13142 (unlt:QI (reg:CC 17) (const_int 0)))]
13143 "TARGET_80387 || TARGET_SSE"
13144 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13145
13146 (define_expand "sltgt"
13147 [(set (match_operand:QI 0 "register_operand" "")
13148 (ltgt:QI (reg:CC 17) (const_int 0)))]
13149 "TARGET_80387 || TARGET_SSE"
13150 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13151
13152 (define_insn "*setcc_1"
13153 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13154 (match_operator:QI 1 "ix86_comparison_operator"
13155 [(reg 17) (const_int 0)]))]
13156 ""
13157 "set%C1\t%0"
13158 [(set_attr "type" "setcc")
13159 (set_attr "mode" "QI")])
13160
13161 (define_insn "setcc_2"
13162 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13163 (match_operator:QI 1 "ix86_comparison_operator"
13164 [(reg 17) (const_int 0)]))]
13165 ""
13166 "set%C1\t%0"
13167 [(set_attr "type" "setcc")
13168 (set_attr "mode" "QI")])
13169
13170 ;; In general it is not safe to assume too much about CCmode registers,
13171 ;; so simplify-rtx stops when it sees a second one. Under certain
13172 ;; conditions this is safe on x86, so help combine not create
13173 ;;
13174 ;; seta %al
13175 ;; testb %al, %al
13176 ;; sete %al
13177
13178 (define_split
13179 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13180 (ne:QI (match_operator 1 "ix86_comparison_operator"
13181 [(reg 17) (const_int 0)])
13182 (const_int 0)))]
13183 ""
13184 [(set (match_dup 0) (match_dup 1))]
13185 {
13186 PUT_MODE (operands[1], QImode);
13187 })
13188
13189 (define_split
13190 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13191 (ne:QI (match_operator 1 "ix86_comparison_operator"
13192 [(reg 17) (const_int 0)])
13193 (const_int 0)))]
13194 ""
13195 [(set (match_dup 0) (match_dup 1))]
13196 {
13197 PUT_MODE (operands[1], QImode);
13198 })
13199
13200 (define_split
13201 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13202 (eq:QI (match_operator 1 "ix86_comparison_operator"
13203 [(reg 17) (const_int 0)])
13204 (const_int 0)))]
13205 ""
13206 [(set (match_dup 0) (match_dup 1))]
13207 {
13208 rtx new_op1 = copy_rtx (operands[1]);
13209 operands[1] = new_op1;
13210 PUT_MODE (new_op1, QImode);
13211 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13212 GET_MODE (XEXP (new_op1, 0))));
13213
13214 /* Make sure that (a) the CCmode we have for the flags is strong
13215 enough for the reversed compare or (b) we have a valid FP compare. */
13216 if (! ix86_comparison_operator (new_op1, VOIDmode))
13217 FAIL;
13218 })
13219
13220 (define_split
13221 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13222 (eq:QI (match_operator 1 "ix86_comparison_operator"
13223 [(reg 17) (const_int 0)])
13224 (const_int 0)))]
13225 ""
13226 [(set (match_dup 0) (match_dup 1))]
13227 {
13228 rtx new_op1 = copy_rtx (operands[1]);
13229 operands[1] = new_op1;
13230 PUT_MODE (new_op1, QImode);
13231 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13232 GET_MODE (XEXP (new_op1, 0))));
13233
13234 /* Make sure that (a) the CCmode we have for the flags is strong
13235 enough for the reversed compare or (b) we have a valid FP compare. */
13236 if (! ix86_comparison_operator (new_op1, VOIDmode))
13237 FAIL;
13238 })
13239
13240 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13241 ;; subsequent logical operations are used to imitate conditional moves.
13242 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13243 ;; it directly. Further holding this value in pseudo register might bring
13244 ;; problem in implicit normalization in spill code.
13245 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13246 ;; instructions after reload by splitting the conditional move patterns.
13247
13248 (define_insn "*sse_setccsf"
13249 [(set (match_operand:SF 0 "register_operand" "=x")
13250 (match_operator:SF 1 "sse_comparison_operator"
13251 [(match_operand:SF 2 "register_operand" "0")
13252 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13253 "TARGET_SSE && reload_completed"
13254 "cmp%D1ss\t{%3, %0|%0, %3}"
13255 [(set_attr "type" "ssecmp")
13256 (set_attr "mode" "SF")])
13257
13258 (define_insn "*sse_setccdf"
13259 [(set (match_operand:DF 0 "register_operand" "=Y")
13260 (match_operator:DF 1 "sse_comparison_operator"
13261 [(match_operand:DF 2 "register_operand" "0")
13262 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13263 "TARGET_SSE2 && reload_completed"
13264 "cmp%D1sd\t{%3, %0|%0, %3}"
13265 [(set_attr "type" "ssecmp")
13266 (set_attr "mode" "DF")])
13267 \f
13268 ;; Basic conditional jump instructions.
13269 ;; We ignore the overflow flag for signed branch instructions.
13270
13271 ;; For all bCOND expanders, also expand the compare or test insn that
13272 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13273
13274 (define_expand "beq"
13275 [(set (pc)
13276 (if_then_else (match_dup 1)
13277 (label_ref (match_operand 0 "" ""))
13278 (pc)))]
13279 ""
13280 "ix86_expand_branch (EQ, operands[0]); DONE;")
13281
13282 (define_expand "bne"
13283 [(set (pc)
13284 (if_then_else (match_dup 1)
13285 (label_ref (match_operand 0 "" ""))
13286 (pc)))]
13287 ""
13288 "ix86_expand_branch (NE, operands[0]); DONE;")
13289
13290 (define_expand "bgt"
13291 [(set (pc)
13292 (if_then_else (match_dup 1)
13293 (label_ref (match_operand 0 "" ""))
13294 (pc)))]
13295 ""
13296 "ix86_expand_branch (GT, operands[0]); DONE;")
13297
13298 (define_expand "bgtu"
13299 [(set (pc)
13300 (if_then_else (match_dup 1)
13301 (label_ref (match_operand 0 "" ""))
13302 (pc)))]
13303 ""
13304 "ix86_expand_branch (GTU, operands[0]); DONE;")
13305
13306 (define_expand "blt"
13307 [(set (pc)
13308 (if_then_else (match_dup 1)
13309 (label_ref (match_operand 0 "" ""))
13310 (pc)))]
13311 ""
13312 "ix86_expand_branch (LT, operands[0]); DONE;")
13313
13314 (define_expand "bltu"
13315 [(set (pc)
13316 (if_then_else (match_dup 1)
13317 (label_ref (match_operand 0 "" ""))
13318 (pc)))]
13319 ""
13320 "ix86_expand_branch (LTU, operands[0]); DONE;")
13321
13322 (define_expand "bge"
13323 [(set (pc)
13324 (if_then_else (match_dup 1)
13325 (label_ref (match_operand 0 "" ""))
13326 (pc)))]
13327 ""
13328 "ix86_expand_branch (GE, operands[0]); DONE;")
13329
13330 (define_expand "bgeu"
13331 [(set (pc)
13332 (if_then_else (match_dup 1)
13333 (label_ref (match_operand 0 "" ""))
13334 (pc)))]
13335 ""
13336 "ix86_expand_branch (GEU, operands[0]); DONE;")
13337
13338 (define_expand "ble"
13339 [(set (pc)
13340 (if_then_else (match_dup 1)
13341 (label_ref (match_operand 0 "" ""))
13342 (pc)))]
13343 ""
13344 "ix86_expand_branch (LE, operands[0]); DONE;")
13345
13346 (define_expand "bleu"
13347 [(set (pc)
13348 (if_then_else (match_dup 1)
13349 (label_ref (match_operand 0 "" ""))
13350 (pc)))]
13351 ""
13352 "ix86_expand_branch (LEU, operands[0]); DONE;")
13353
13354 (define_expand "bunordered"
13355 [(set (pc)
13356 (if_then_else (match_dup 1)
13357 (label_ref (match_operand 0 "" ""))
13358 (pc)))]
13359 "TARGET_80387 || TARGET_SSE"
13360 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13361
13362 (define_expand "bordered"
13363 [(set (pc)
13364 (if_then_else (match_dup 1)
13365 (label_ref (match_operand 0 "" ""))
13366 (pc)))]
13367 "TARGET_80387 || TARGET_SSE"
13368 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13369
13370 (define_expand "buneq"
13371 [(set (pc)
13372 (if_then_else (match_dup 1)
13373 (label_ref (match_operand 0 "" ""))
13374 (pc)))]
13375 "TARGET_80387 || TARGET_SSE"
13376 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13377
13378 (define_expand "bunge"
13379 [(set (pc)
13380 (if_then_else (match_dup 1)
13381 (label_ref (match_operand 0 "" ""))
13382 (pc)))]
13383 "TARGET_80387 || TARGET_SSE"
13384 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13385
13386 (define_expand "bungt"
13387 [(set (pc)
13388 (if_then_else (match_dup 1)
13389 (label_ref (match_operand 0 "" ""))
13390 (pc)))]
13391 "TARGET_80387 || TARGET_SSE"
13392 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13393
13394 (define_expand "bunle"
13395 [(set (pc)
13396 (if_then_else (match_dup 1)
13397 (label_ref (match_operand 0 "" ""))
13398 (pc)))]
13399 "TARGET_80387 || TARGET_SSE"
13400 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13401
13402 (define_expand "bunlt"
13403 [(set (pc)
13404 (if_then_else (match_dup 1)
13405 (label_ref (match_operand 0 "" ""))
13406 (pc)))]
13407 "TARGET_80387 || TARGET_SSE"
13408 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13409
13410 (define_expand "bltgt"
13411 [(set (pc)
13412 (if_then_else (match_dup 1)
13413 (label_ref (match_operand 0 "" ""))
13414 (pc)))]
13415 "TARGET_80387 || TARGET_SSE"
13416 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13417
13418 (define_insn "*jcc_1"
13419 [(set (pc)
13420 (if_then_else (match_operator 1 "ix86_comparison_operator"
13421 [(reg 17) (const_int 0)])
13422 (label_ref (match_operand 0 "" ""))
13423 (pc)))]
13424 ""
13425 "%+j%C1\t%l0"
13426 [(set_attr "type" "ibr")
13427 (set_attr "modrm" "0")
13428 (set (attr "length")
13429 (if_then_else (and (ge (minus (match_dup 0) (pc))
13430 (const_int -128))
13431 (lt (minus (match_dup 0) (pc))
13432 (const_int 124)))
13433 (const_int 2)
13434 (const_int 6)))])
13435
13436 (define_insn "*jcc_2"
13437 [(set (pc)
13438 (if_then_else (match_operator 1 "ix86_comparison_operator"
13439 [(reg 17) (const_int 0)])
13440 (pc)
13441 (label_ref (match_operand 0 "" ""))))]
13442 ""
13443 "%+j%c1\t%l0"
13444 [(set_attr "type" "ibr")
13445 (set_attr "modrm" "0")
13446 (set (attr "length")
13447 (if_then_else (and (ge (minus (match_dup 0) (pc))
13448 (const_int -128))
13449 (lt (minus (match_dup 0) (pc))
13450 (const_int 124)))
13451 (const_int 2)
13452 (const_int 6)))])
13453
13454 ;; In general it is not safe to assume too much about CCmode registers,
13455 ;; so simplify-rtx stops when it sees a second one. Under certain
13456 ;; conditions this is safe on x86, so help combine not create
13457 ;;
13458 ;; seta %al
13459 ;; testb %al, %al
13460 ;; je Lfoo
13461
13462 (define_split
13463 [(set (pc)
13464 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13465 [(reg 17) (const_int 0)])
13466 (const_int 0))
13467 (label_ref (match_operand 1 "" ""))
13468 (pc)))]
13469 ""
13470 [(set (pc)
13471 (if_then_else (match_dup 0)
13472 (label_ref (match_dup 1))
13473 (pc)))]
13474 {
13475 PUT_MODE (operands[0], VOIDmode);
13476 })
13477
13478 (define_split
13479 [(set (pc)
13480 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13481 [(reg 17) (const_int 0)])
13482 (const_int 0))
13483 (label_ref (match_operand 1 "" ""))
13484 (pc)))]
13485 ""
13486 [(set (pc)
13487 (if_then_else (match_dup 0)
13488 (label_ref (match_dup 1))
13489 (pc)))]
13490 {
13491 rtx new_op0 = copy_rtx (operands[0]);
13492 operands[0] = new_op0;
13493 PUT_MODE (new_op0, VOIDmode);
13494 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13495 GET_MODE (XEXP (new_op0, 0))));
13496
13497 /* Make sure that (a) the CCmode we have for the flags is strong
13498 enough for the reversed compare or (b) we have a valid FP compare. */
13499 if (! ix86_comparison_operator (new_op0, VOIDmode))
13500 FAIL;
13501 })
13502
13503 ;; Define combination compare-and-branch fp compare instructions to use
13504 ;; during early optimization. Splitting the operation apart early makes
13505 ;; for bad code when we want to reverse the operation.
13506
13507 (define_insn "*fp_jcc_1"
13508 [(set (pc)
13509 (if_then_else (match_operator 0 "comparison_operator"
13510 [(match_operand 1 "register_operand" "f")
13511 (match_operand 2 "register_operand" "f")])
13512 (label_ref (match_operand 3 "" ""))
13513 (pc)))
13514 (clobber (reg:CCFP 18))
13515 (clobber (reg:CCFP 17))]
13516 "TARGET_CMOVE && TARGET_80387
13517 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13518 && FLOAT_MODE_P (GET_MODE (operands[1]))
13519 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13520 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13521 "#")
13522
13523 (define_insn "*fp_jcc_1_sse"
13524 [(set (pc)
13525 (if_then_else (match_operator 0 "comparison_operator"
13526 [(match_operand 1 "register_operand" "f#x,x#f")
13527 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13528 (label_ref (match_operand 3 "" ""))
13529 (pc)))
13530 (clobber (reg:CCFP 18))
13531 (clobber (reg:CCFP 17))]
13532 "TARGET_80387
13533 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13534 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13535 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13536 "#")
13537
13538 (define_insn "*fp_jcc_1_sse_only"
13539 [(set (pc)
13540 (if_then_else (match_operator 0 "comparison_operator"
13541 [(match_operand 1 "register_operand" "x")
13542 (match_operand 2 "nonimmediate_operand" "xm")])
13543 (label_ref (match_operand 3 "" ""))
13544 (pc)))
13545 (clobber (reg:CCFP 18))
13546 (clobber (reg:CCFP 17))]
13547 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13548 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13549 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13550 "#")
13551
13552 (define_insn "*fp_jcc_2"
13553 [(set (pc)
13554 (if_then_else (match_operator 0 "comparison_operator"
13555 [(match_operand 1 "register_operand" "f")
13556 (match_operand 2 "register_operand" "f")])
13557 (pc)
13558 (label_ref (match_operand 3 "" ""))))
13559 (clobber (reg:CCFP 18))
13560 (clobber (reg:CCFP 17))]
13561 "TARGET_CMOVE && TARGET_80387
13562 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13563 && FLOAT_MODE_P (GET_MODE (operands[1]))
13564 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13565 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13566 "#")
13567
13568 (define_insn "*fp_jcc_2_sse"
13569 [(set (pc)
13570 (if_then_else (match_operator 0 "comparison_operator"
13571 [(match_operand 1 "register_operand" "f#x,x#f")
13572 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13573 (pc)
13574 (label_ref (match_operand 3 "" ""))))
13575 (clobber (reg:CCFP 18))
13576 (clobber (reg:CCFP 17))]
13577 "TARGET_80387
13578 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13579 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13580 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13581 "#")
13582
13583 (define_insn "*fp_jcc_2_sse_only"
13584 [(set (pc)
13585 (if_then_else (match_operator 0 "comparison_operator"
13586 [(match_operand 1 "register_operand" "x")
13587 (match_operand 2 "nonimmediate_operand" "xm")])
13588 (pc)
13589 (label_ref (match_operand 3 "" ""))))
13590 (clobber (reg:CCFP 18))
13591 (clobber (reg:CCFP 17))]
13592 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13593 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13594 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13595 "#")
13596
13597 (define_insn "*fp_jcc_3"
13598 [(set (pc)
13599 (if_then_else (match_operator 0 "comparison_operator"
13600 [(match_operand 1 "register_operand" "f")
13601 (match_operand 2 "nonimmediate_operand" "fm")])
13602 (label_ref (match_operand 3 "" ""))
13603 (pc)))
13604 (clobber (reg:CCFP 18))
13605 (clobber (reg:CCFP 17))
13606 (clobber (match_scratch:HI 4 "=a"))]
13607 "TARGET_80387
13608 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13609 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13610 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13611 && SELECT_CC_MODE (GET_CODE (operands[0]),
13612 operands[1], operands[2]) == CCFPmode
13613 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13614 "#")
13615
13616 (define_insn "*fp_jcc_4"
13617 [(set (pc)
13618 (if_then_else (match_operator 0 "comparison_operator"
13619 [(match_operand 1 "register_operand" "f")
13620 (match_operand 2 "nonimmediate_operand" "fm")])
13621 (pc)
13622 (label_ref (match_operand 3 "" ""))))
13623 (clobber (reg:CCFP 18))
13624 (clobber (reg:CCFP 17))
13625 (clobber (match_scratch:HI 4 "=a"))]
13626 "TARGET_80387
13627 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13628 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13629 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13630 && SELECT_CC_MODE (GET_CODE (operands[0]),
13631 operands[1], operands[2]) == CCFPmode
13632 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13633 "#")
13634
13635 (define_insn "*fp_jcc_5"
13636 [(set (pc)
13637 (if_then_else (match_operator 0 "comparison_operator"
13638 [(match_operand 1 "register_operand" "f")
13639 (match_operand 2 "register_operand" "f")])
13640 (label_ref (match_operand 3 "" ""))
13641 (pc)))
13642 (clobber (reg:CCFP 18))
13643 (clobber (reg:CCFP 17))
13644 (clobber (match_scratch:HI 4 "=a"))]
13645 "TARGET_80387
13646 && FLOAT_MODE_P (GET_MODE (operands[1]))
13647 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13648 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13649 "#")
13650
13651 (define_insn "*fp_jcc_6"
13652 [(set (pc)
13653 (if_then_else (match_operator 0 "comparison_operator"
13654 [(match_operand 1 "register_operand" "f")
13655 (match_operand 2 "register_operand" "f")])
13656 (pc)
13657 (label_ref (match_operand 3 "" ""))))
13658 (clobber (reg:CCFP 18))
13659 (clobber (reg:CCFP 17))
13660 (clobber (match_scratch:HI 4 "=a"))]
13661 "TARGET_80387
13662 && FLOAT_MODE_P (GET_MODE (operands[1]))
13663 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13664 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13665 "#")
13666
13667 (define_split
13668 [(set (pc)
13669 (if_then_else (match_operator 0 "comparison_operator"
13670 [(match_operand 1 "register_operand" "")
13671 (match_operand 2 "nonimmediate_operand" "")])
13672 (match_operand 3 "" "")
13673 (match_operand 4 "" "")))
13674 (clobber (reg:CCFP 18))
13675 (clobber (reg:CCFP 17))]
13676 "reload_completed"
13677 [(const_int 0)]
13678 {
13679 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13680 operands[3], operands[4], NULL_RTX);
13681 DONE;
13682 })
13683
13684 (define_split
13685 [(set (pc)
13686 (if_then_else (match_operator 0 "comparison_operator"
13687 [(match_operand 1 "register_operand" "")
13688 (match_operand 2 "nonimmediate_operand" "")])
13689 (match_operand 3 "" "")
13690 (match_operand 4 "" "")))
13691 (clobber (reg:CCFP 18))
13692 (clobber (reg:CCFP 17))
13693 (clobber (match_scratch:HI 5 "=a"))]
13694 "reload_completed"
13695 [(set (pc)
13696 (if_then_else (match_dup 6)
13697 (match_dup 3)
13698 (match_dup 4)))]
13699 {
13700 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13701 operands[3], operands[4], operands[5]);
13702 DONE;
13703 })
13704 \f
13705 ;; Unconditional and other jump instructions
13706
13707 (define_insn "jump"
13708 [(set (pc)
13709 (label_ref (match_operand 0 "" "")))]
13710 ""
13711 "jmp\t%l0"
13712 [(set_attr "type" "ibr")
13713 (set (attr "length")
13714 (if_then_else (and (ge (minus (match_dup 0) (pc))
13715 (const_int -128))
13716 (lt (minus (match_dup 0) (pc))
13717 (const_int 124)))
13718 (const_int 2)
13719 (const_int 5)))
13720 (set_attr "modrm" "0")])
13721
13722 (define_expand "indirect_jump"
13723 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13724 ""
13725 "")
13726
13727 (define_insn "*indirect_jump"
13728 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13729 "!TARGET_64BIT"
13730 "jmp\t%A0"
13731 [(set_attr "type" "ibr")
13732 (set_attr "length_immediate" "0")])
13733
13734 (define_insn "*indirect_jump_rtx64"
13735 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13736 "TARGET_64BIT"
13737 "jmp\t%A0"
13738 [(set_attr "type" "ibr")
13739 (set_attr "length_immediate" "0")])
13740
13741 (define_expand "tablejump"
13742 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13743 (use (label_ref (match_operand 1 "" "")))])]
13744 ""
13745 {
13746 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13747 relative. Convert the relative address to an absolute address. */
13748 if (flag_pic)
13749 {
13750 rtx op0, op1;
13751 enum rtx_code code;
13752
13753 if (TARGET_64BIT)
13754 {
13755 code = PLUS;
13756 op0 = operands[0];
13757 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13758 }
13759 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13760 {
13761 code = PLUS;
13762 op0 = operands[0];
13763 op1 = pic_offset_table_rtx;
13764 }
13765 else
13766 {
13767 code = MINUS;
13768 op0 = pic_offset_table_rtx;
13769 op1 = operands[0];
13770 }
13771
13772 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13773 OPTAB_DIRECT);
13774 }
13775 })
13776
13777 (define_insn "*tablejump_1"
13778 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13779 (use (label_ref (match_operand 1 "" "")))]
13780 "!TARGET_64BIT"
13781 "jmp\t%A0"
13782 [(set_attr "type" "ibr")
13783 (set_attr "length_immediate" "0")])
13784
13785 (define_insn "*tablejump_1_rtx64"
13786 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13787 (use (label_ref (match_operand 1 "" "")))]
13788 "TARGET_64BIT"
13789 "jmp\t%A0"
13790 [(set_attr "type" "ibr")
13791 (set_attr "length_immediate" "0")])
13792 \f
13793 ;; Loop instruction
13794 ;;
13795 ;; This is all complicated by the fact that since this is a jump insn
13796 ;; we must handle our own reloads.
13797
13798 (define_expand "doloop_end"
13799 [(use (match_operand 0 "" "")) ; loop pseudo
13800 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13801 (use (match_operand 2 "" "")) ; max iterations
13802 (use (match_operand 3 "" "")) ; loop level
13803 (use (match_operand 4 "" ""))] ; label
13804 "!TARGET_64BIT && TARGET_USE_LOOP"
13805 "
13806 {
13807 /* Only use cloop on innermost loops. */
13808 if (INTVAL (operands[3]) > 1)
13809 FAIL;
13810 if (GET_MODE (operands[0]) != SImode)
13811 FAIL;
13812 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13813 operands[0]));
13814 DONE;
13815 }")
13816
13817 (define_insn "doloop_end_internal"
13818 [(set (pc)
13819 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13820 (const_int 1))
13821 (label_ref (match_operand 0 "" ""))
13822 (pc)))
13823 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13824 (plus:SI (match_dup 1)
13825 (const_int -1)))
13826 (clobber (match_scratch:SI 3 "=X,X,r"))
13827 (clobber (reg:CC 17))]
13828 "!TARGET_64BIT && TARGET_USE_LOOP"
13829 {
13830 if (which_alternative != 0)
13831 return "#";
13832 if (get_attr_length (insn) == 2)
13833 return "%+loop\t%l0";
13834 else
13835 return "dec{l}\t%1\;%+jne\t%l0";
13836 }
13837 [(set_attr "ppro_uops" "many")
13838 (set (attr "length")
13839 (if_then_else (and (eq_attr "alternative" "0")
13840 (and (ge (minus (match_dup 0) (pc))
13841 (const_int -128))
13842 (lt (minus (match_dup 0) (pc))
13843 (const_int 124))))
13844 (const_int 2)
13845 (const_int 16)))
13846 ;; We don't know the type before shorten branches. Optimistically expect
13847 ;; the loop instruction to match.
13848 (set (attr "type") (const_string "ibr"))])
13849
13850 (define_split
13851 [(set (pc)
13852 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13853 (const_int 1))
13854 (match_operand 0 "" "")
13855 (pc)))
13856 (set (match_dup 1)
13857 (plus:SI (match_dup 1)
13858 (const_int -1)))
13859 (clobber (match_scratch:SI 2 ""))
13860 (clobber (reg:CC 17))]
13861 "!TARGET_64BIT && TARGET_USE_LOOP
13862 && reload_completed
13863 && REGNO (operands[1]) != 2"
13864 [(parallel [(set (reg:CCZ 17)
13865 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13866 (const_int 0)))
13867 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13868 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13869 (match_dup 0)
13870 (pc)))]
13871 "")
13872
13873 (define_split
13874 [(set (pc)
13875 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13876 (const_int 1))
13877 (match_operand 0 "" "")
13878 (pc)))
13879 (set (match_operand:SI 2 "nonimmediate_operand" "")
13880 (plus:SI (match_dup 1)
13881 (const_int -1)))
13882 (clobber (match_scratch:SI 3 ""))
13883 (clobber (reg:CC 17))]
13884 "!TARGET_64BIT && TARGET_USE_LOOP
13885 && reload_completed
13886 && (! REG_P (operands[2])
13887 || ! rtx_equal_p (operands[1], operands[2]))"
13888 [(set (match_dup 3) (match_dup 1))
13889 (parallel [(set (reg:CCZ 17)
13890 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13891 (const_int 0)))
13892 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13893 (set (match_dup 2) (match_dup 3))
13894 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13895 (match_dup 0)
13896 (pc)))]
13897 "")
13898
13899 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13900
13901 (define_peephole2
13902 [(set (reg 17) (match_operand 0 "" ""))
13903 (set (match_operand:QI 1 "register_operand" "")
13904 (match_operator:QI 2 "ix86_comparison_operator"
13905 [(reg 17) (const_int 0)]))
13906 (set (match_operand 3 "q_regs_operand" "")
13907 (zero_extend (match_dup 1)))]
13908 "(peep2_reg_dead_p (3, operands[1])
13909 || operands_match_p (operands[1], operands[3]))
13910 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13911 [(set (match_dup 4) (match_dup 0))
13912 (set (strict_low_part (match_dup 5))
13913 (match_dup 2))]
13914 {
13915 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13916 operands[5] = gen_lowpart (QImode, operands[3]);
13917 ix86_expand_clear (operands[3]);
13918 })
13919
13920 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13921
13922 (define_peephole2
13923 [(set (reg 17) (match_operand 0 "" ""))
13924 (set (match_operand:QI 1 "register_operand" "")
13925 (match_operator:QI 2 "ix86_comparison_operator"
13926 [(reg 17) (const_int 0)]))
13927 (parallel [(set (match_operand 3 "q_regs_operand" "")
13928 (zero_extend (match_dup 1)))
13929 (clobber (reg:CC 17))])]
13930 "(peep2_reg_dead_p (3, operands[1])
13931 || operands_match_p (operands[1], operands[3]))
13932 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13933 [(set (match_dup 4) (match_dup 0))
13934 (set (strict_low_part (match_dup 5))
13935 (match_dup 2))]
13936 {
13937 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13938 operands[5] = gen_lowpart (QImode, operands[3]);
13939 ix86_expand_clear (operands[3]);
13940 })
13941 \f
13942 ;; Call instructions.
13943
13944 ;; The predicates normally associated with named expanders are not properly
13945 ;; checked for calls. This is a bug in the generic code, but it isn't that
13946 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13947
13948 ;; Call subroutine returning no value.
13949
13950 (define_expand "call_pop"
13951 [(parallel [(call (match_operand:QI 0 "" "")
13952 (match_operand:SI 1 "" ""))
13953 (set (reg:SI 7)
13954 (plus:SI (reg:SI 7)
13955 (match_operand:SI 3 "" "")))])]
13956 "!TARGET_64BIT"
13957 {
13958 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13959 DONE;
13960 })
13961
13962 (define_insn "*call_pop_0"
13963 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13964 (match_operand:SI 1 "" ""))
13965 (set (reg:SI 7) (plus:SI (reg:SI 7)
13966 (match_operand:SI 2 "immediate_operand" "")))]
13967 "!TARGET_64BIT"
13968 {
13969 if (SIBLING_CALL_P (insn))
13970 return "jmp\t%P0";
13971 else
13972 return "call\t%P0";
13973 }
13974 [(set_attr "type" "call")])
13975
13976 (define_insn "*call_pop_1"
13977 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13978 (match_operand:SI 1 "" ""))
13979 (set (reg:SI 7) (plus:SI (reg:SI 7)
13980 (match_operand:SI 2 "immediate_operand" "i")))]
13981 "!TARGET_64BIT"
13982 {
13983 if (constant_call_address_operand (operands[0], Pmode))
13984 {
13985 if (SIBLING_CALL_P (insn))
13986 return "jmp\t%P0";
13987 else
13988 return "call\t%P0";
13989 }
13990 if (SIBLING_CALL_P (insn))
13991 return "jmp\t%A0";
13992 else
13993 return "call\t%A0";
13994 }
13995 [(set_attr "type" "call")])
13996
13997 (define_expand "call"
13998 [(call (match_operand:QI 0 "" "")
13999 (match_operand 1 "" ""))
14000 (use (match_operand 2 "" ""))]
14001 ""
14002 {
14003 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14004 DONE;
14005 })
14006
14007 (define_expand "sibcall"
14008 [(call (match_operand:QI 0 "" "")
14009 (match_operand 1 "" ""))
14010 (use (match_operand 2 "" ""))]
14011 ""
14012 {
14013 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14014 DONE;
14015 })
14016
14017 (define_insn "*call_0"
14018 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14019 (match_operand 1 "" ""))]
14020 ""
14021 {
14022 if (SIBLING_CALL_P (insn))
14023 return "jmp\t%P0";
14024 else
14025 return "call\t%P0";
14026 }
14027 [(set_attr "type" "call")])
14028
14029 (define_insn "*call_1"
14030 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14031 (match_operand 1 "" ""))]
14032 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14033 {
14034 if (constant_call_address_operand (operands[0], QImode))
14035 return "call\t%P0";
14036 return "call\t%A0";
14037 }
14038 [(set_attr "type" "call")])
14039
14040 (define_insn "*sibcall_1"
14041 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14042 (match_operand 1 "" ""))]
14043 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14044 {
14045 if (constant_call_address_operand (operands[0], QImode))
14046 return "jmp\t%P0";
14047 return "jmp\t%A0";
14048 }
14049 [(set_attr "type" "call")])
14050
14051 (define_insn "*call_1_rex64"
14052 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14053 (match_operand 1 "" ""))]
14054 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14055 {
14056 if (constant_call_address_operand (operands[0], QImode))
14057 return "call\t%P0";
14058 return "call\t%A0";
14059 }
14060 [(set_attr "type" "call")])
14061
14062 (define_insn "*sibcall_1_rex64"
14063 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14064 (match_operand 1 "" ""))]
14065 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14066 "jmp\t%P0"
14067 [(set_attr "type" "call")])
14068
14069 (define_insn "*sibcall_1_rex64_v"
14070 [(call (mem:QI (reg:DI 40))
14071 (match_operand 0 "" ""))]
14072 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14073 "jmp\t*%%r11"
14074 [(set_attr "type" "call")])
14075
14076
14077 ;; Call subroutine, returning value in operand 0
14078
14079 (define_expand "call_value_pop"
14080 [(parallel [(set (match_operand 0 "" "")
14081 (call (match_operand:QI 1 "" "")
14082 (match_operand:SI 2 "" "")))
14083 (set (reg:SI 7)
14084 (plus:SI (reg:SI 7)
14085 (match_operand:SI 4 "" "")))])]
14086 "!TARGET_64BIT"
14087 {
14088 ix86_expand_call (operands[0], operands[1], operands[2],
14089 operands[3], operands[4], 0);
14090 DONE;
14091 })
14092
14093 (define_expand "call_value"
14094 [(set (match_operand 0 "" "")
14095 (call (match_operand:QI 1 "" "")
14096 (match_operand:SI 2 "" "")))
14097 (use (match_operand:SI 3 "" ""))]
14098 ;; Operand 2 not used on the i386.
14099 ""
14100 {
14101 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14102 DONE;
14103 })
14104
14105 (define_expand "sibcall_value"
14106 [(set (match_operand 0 "" "")
14107 (call (match_operand:QI 1 "" "")
14108 (match_operand:SI 2 "" "")))
14109 (use (match_operand:SI 3 "" ""))]
14110 ;; Operand 2 not used on the i386.
14111 ""
14112 {
14113 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14114 DONE;
14115 })
14116
14117 ;; Call subroutine returning any type.
14118
14119 (define_expand "untyped_call"
14120 [(parallel [(call (match_operand 0 "" "")
14121 (const_int 0))
14122 (match_operand 1 "" "")
14123 (match_operand 2 "" "")])]
14124 ""
14125 {
14126 int i;
14127
14128 /* In order to give reg-stack an easier job in validating two
14129 coprocessor registers as containing a possible return value,
14130 simply pretend the untyped call returns a complex long double
14131 value. */
14132
14133 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14134 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14135 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14136 NULL, 0);
14137
14138 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14139 {
14140 rtx set = XVECEXP (operands[2], 0, i);
14141 emit_move_insn (SET_DEST (set), SET_SRC (set));
14142 }
14143
14144 /* The optimizer does not know that the call sets the function value
14145 registers we stored in the result block. We avoid problems by
14146 claiming that all hard registers are used and clobbered at this
14147 point. */
14148 emit_insn (gen_blockage (const0_rtx));
14149
14150 DONE;
14151 })
14152 \f
14153 ;; Prologue and epilogue instructions
14154
14155 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14156 ;; all of memory. This blocks insns from being moved across this point.
14157
14158 (define_insn "blockage"
14159 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14160 ""
14161 ""
14162 [(set_attr "length" "0")])
14163
14164 ;; Insn emitted into the body of a function to return from a function.
14165 ;; This is only done if the function's epilogue is known to be simple.
14166 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14167
14168 (define_expand "return"
14169 [(return)]
14170 "ix86_can_use_return_insn_p ()"
14171 {
14172 if (current_function_pops_args)
14173 {
14174 rtx popc = GEN_INT (current_function_pops_args);
14175 emit_jump_insn (gen_return_pop_internal (popc));
14176 DONE;
14177 }
14178 })
14179
14180 (define_insn "return_internal"
14181 [(return)]
14182 "reload_completed"
14183 "ret"
14184 [(set_attr "length" "1")
14185 (set_attr "length_immediate" "0")
14186 (set_attr "modrm" "0")])
14187
14188 (define_insn "return_pop_internal"
14189 [(return)
14190 (use (match_operand:SI 0 "const_int_operand" ""))]
14191 "reload_completed"
14192 "ret\t%0"
14193 [(set_attr "length" "3")
14194 (set_attr "length_immediate" "2")
14195 (set_attr "modrm" "0")])
14196
14197 (define_insn "return_indirect_internal"
14198 [(return)
14199 (use (match_operand:SI 0 "register_operand" "r"))]
14200 "reload_completed"
14201 "jmp\t%A0"
14202 [(set_attr "type" "ibr")
14203 (set_attr "length_immediate" "0")])
14204
14205 (define_insn "nop"
14206 [(const_int 0)]
14207 ""
14208 "nop"
14209 [(set_attr "length" "1")
14210 (set_attr "length_immediate" "0")
14211 (set_attr "modrm" "0")
14212 (set_attr "ppro_uops" "one")])
14213
14214 (define_expand "prologue"
14215 [(const_int 1)]
14216 ""
14217 "ix86_expand_prologue (); DONE;")
14218
14219 (define_insn "set_got"
14220 [(set (match_operand:SI 0 "register_operand" "=r")
14221 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14222 (clobber (reg:CC 17))]
14223 "!TARGET_64BIT"
14224 { return output_set_got (operands[0]); }
14225 [(set_attr "type" "multi")
14226 (set_attr "length" "12")])
14227
14228 (define_expand "epilogue"
14229 [(const_int 1)]
14230 ""
14231 "ix86_expand_epilogue (1); DONE;")
14232
14233 (define_expand "sibcall_epilogue"
14234 [(const_int 1)]
14235 ""
14236 "ix86_expand_epilogue (0); DONE;")
14237
14238 (define_expand "eh_return"
14239 [(use (match_operand 0 "register_operand" ""))
14240 (use (match_operand 1 "register_operand" ""))]
14241 ""
14242 {
14243 rtx tmp, sa = operands[0], ra = operands[1];
14244
14245 /* Tricky bit: we write the address of the handler to which we will
14246 be returning into someone else's stack frame, one word below the
14247 stack address we wish to restore. */
14248 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14249 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14250 tmp = gen_rtx_MEM (Pmode, tmp);
14251 emit_move_insn (tmp, ra);
14252
14253 if (Pmode == SImode)
14254 emit_insn (gen_eh_return_si (sa));
14255 else
14256 emit_insn (gen_eh_return_di (sa));
14257 emit_barrier ();
14258 DONE;
14259 })
14260
14261 (define_insn_and_split "eh_return_si"
14262 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14263 UNSPECV_EH_RETURN)]
14264 "!TARGET_64BIT"
14265 "#"
14266 "reload_completed"
14267 [(const_int 1)]
14268 "ix86_expand_epilogue (2); DONE;")
14269
14270 (define_insn_and_split "eh_return_di"
14271 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14272 UNSPECV_EH_RETURN)]
14273 "TARGET_64BIT"
14274 "#"
14275 "reload_completed"
14276 [(const_int 1)]
14277 "ix86_expand_epilogue (2); DONE;")
14278
14279 (define_insn "leave"
14280 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14281 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14282 (clobber (mem:BLK (scratch)))]
14283 "!TARGET_64BIT"
14284 "leave"
14285 [(set_attr "type" "leave")])
14286
14287 (define_insn "leave_rex64"
14288 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14289 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14290 (clobber (mem:BLK (scratch)))]
14291 "TARGET_64BIT"
14292 "leave"
14293 [(set_attr "type" "leave")])
14294 \f
14295 (define_expand "ffssi2"
14296 [(parallel
14297 [(set (match_operand:SI 0 "register_operand" "")
14298 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14299 (clobber (match_scratch:SI 2 ""))
14300 (clobber (reg:CC 17))])]
14301 ""
14302 "")
14303
14304 (define_insn_and_split "*ffs_cmove"
14305 [(set (match_operand:SI 0 "register_operand" "=r")
14306 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14307 (clobber (match_scratch:SI 2 "=&r"))
14308 (clobber (reg:CC 17))]
14309 "TARGET_CMOVE"
14310 "#"
14311 "&& reload_completed"
14312 [(set (match_dup 2) (const_int -1))
14313 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14314 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14315 (set (match_dup 0) (if_then_else:SI
14316 (eq (reg:CCZ 17) (const_int 0))
14317 (match_dup 2)
14318 (match_dup 0)))
14319 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14320 (clobber (reg:CC 17))])]
14321 "")
14322
14323 (define_insn_and_split "*ffs_no_cmove"
14324 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14325 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14326 (clobber (match_scratch:SI 2 "=&r"))
14327 (clobber (reg:CC 17))]
14328 ""
14329 "#"
14330 "reload_completed"
14331 [(parallel [(set (match_dup 2) (const_int 0))
14332 (clobber (reg:CC 17))])
14333 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14334 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14335 (set (strict_low_part (match_dup 3))
14336 (eq:QI (reg:CCZ 17) (const_int 0)))
14337 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14338 (clobber (reg:CC 17))])
14339 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14340 (clobber (reg:CC 17))])
14341 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14342 (clobber (reg:CC 17))])]
14343 {
14344 operands[3] = gen_lowpart (QImode, operands[2]);
14345 })
14346
14347 (define_insn "*ffssi_1"
14348 [(set (reg:CCZ 17)
14349 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14350 (const_int 0)))
14351 (set (match_operand:SI 0 "register_operand" "=r")
14352 (ctz:SI (match_dup 1)))]
14353 ""
14354 "bsf{l}\t{%1, %0|%0, %1}"
14355 [(set_attr "prefix_0f" "1")
14356 (set_attr "ppro_uops" "few")])
14357
14358 (define_insn "ctzsi2"
14359 [(set (match_operand:SI 0 "register_operand" "=r")
14360 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14361 (clobber (reg:CC 17))]
14362 ""
14363 "bsf{l}\t{%1, %0|%0, %1}"
14364 [(set_attr "prefix_0f" "1")
14365 (set_attr "ppro_uops" "few")])
14366
14367 (define_expand "clzsi2"
14368 [(parallel
14369 [(set (match_operand:SI 0 "register_operand" "")
14370 (minus:SI (const_int 31)
14371 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14372 (clobber (reg:CC 17))])
14373 (parallel
14374 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14375 (clobber (reg:CC 17))])]
14376 ""
14377 "")
14378
14379 (define_insn "*bsr"
14380 [(set (match_operand:SI 0 "register_operand" "=r")
14381 (minus:SI (const_int 31)
14382 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14383 (clobber (reg:CC 17))]
14384 ""
14385 "bsr{l}\t{%1, %0|%0, %1}"
14386 [(set_attr "prefix_0f" "1")
14387 (set_attr "ppro_uops" "few")])
14388 \f
14389 ;; Thread-local storage patterns for ELF.
14390 ;;
14391 ;; Note that these code sequences must appear exactly as shown
14392 ;; in order to allow linker relaxation.
14393
14394 (define_insn "*tls_global_dynamic_32_gnu"
14395 [(set (match_operand:SI 0 "register_operand" "=a")
14396 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14397 (match_operand:SI 2 "tls_symbolic_operand" "")
14398 (match_operand:SI 3 "call_insn_operand" "")]
14399 UNSPEC_TLS_GD))
14400 (clobber (match_scratch:SI 4 "=d"))
14401 (clobber (match_scratch:SI 5 "=c"))
14402 (clobber (reg:CC 17))]
14403 "!TARGET_64BIT && TARGET_GNU_TLS"
14404 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14405 [(set_attr "type" "multi")
14406 (set_attr "length" "12")])
14407
14408 (define_insn "*tls_global_dynamic_32_sun"
14409 [(set (match_operand:SI 0 "register_operand" "=a")
14410 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14411 (match_operand:SI 2 "tls_symbolic_operand" "")
14412 (match_operand:SI 3 "call_insn_operand" "")]
14413 UNSPEC_TLS_GD))
14414 (clobber (match_scratch:SI 4 "=d"))
14415 (clobber (match_scratch:SI 5 "=c"))
14416 (clobber (reg:CC 17))]
14417 "!TARGET_64BIT && TARGET_SUN_TLS"
14418 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14419 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14420 [(set_attr "type" "multi")
14421 (set_attr "length" "14")])
14422
14423 (define_expand "tls_global_dynamic_32"
14424 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14425 (unspec:SI
14426 [(match_dup 2)
14427 (match_operand:SI 1 "tls_symbolic_operand" "")
14428 (match_dup 3)]
14429 UNSPEC_TLS_GD))
14430 (clobber (match_scratch:SI 4 ""))
14431 (clobber (match_scratch:SI 5 ""))
14432 (clobber (reg:CC 17))])]
14433 ""
14434 {
14435 if (flag_pic)
14436 operands[2] = pic_offset_table_rtx;
14437 else
14438 {
14439 operands[2] = gen_reg_rtx (Pmode);
14440 emit_insn (gen_set_got (operands[2]));
14441 }
14442 operands[3] = ix86_tls_get_addr ();
14443 })
14444
14445 (define_insn "*tls_global_dynamic_64"
14446 [(set (match_operand:DI 0 "register_operand" "=a")
14447 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14448 (match_operand:DI 3 "" "")))
14449 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14450 UNSPEC_TLS_GD)]
14451 "TARGET_64BIT"
14452 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14453 [(set_attr "type" "multi")
14454 (set_attr "length" "16")])
14455
14456 (define_expand "tls_global_dynamic_64"
14457 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14458 (call (mem:QI (match_dup 2)) (const_int 0)))
14459 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14460 UNSPEC_TLS_GD)])]
14461 ""
14462 {
14463 operands[2] = ix86_tls_get_addr ();
14464 })
14465
14466 (define_insn "*tls_local_dynamic_base_32_gnu"
14467 [(set (match_operand:SI 0 "register_operand" "=a")
14468 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14469 (match_operand:SI 2 "call_insn_operand" "")]
14470 UNSPEC_TLS_LD_BASE))
14471 (clobber (match_scratch:SI 3 "=d"))
14472 (clobber (match_scratch:SI 4 "=c"))
14473 (clobber (reg:CC 17))]
14474 "!TARGET_64BIT && TARGET_GNU_TLS"
14475 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14476 [(set_attr "type" "multi")
14477 (set_attr "length" "11")])
14478
14479 (define_insn "*tls_local_dynamic_base_32_sun"
14480 [(set (match_operand:SI 0 "register_operand" "=a")
14481 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14482 (match_operand:SI 2 "call_insn_operand" "")]
14483 UNSPEC_TLS_LD_BASE))
14484 (clobber (match_scratch:SI 3 "=d"))
14485 (clobber (match_scratch:SI 4 "=c"))
14486 (clobber (reg:CC 17))]
14487 "!TARGET_64BIT && TARGET_SUN_TLS"
14488 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14489 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14490 [(set_attr "type" "multi")
14491 (set_attr "length" "13")])
14492
14493 (define_expand "tls_local_dynamic_base_32"
14494 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14495 (unspec:SI [(match_dup 1) (match_dup 2)]
14496 UNSPEC_TLS_LD_BASE))
14497 (clobber (match_scratch:SI 3 ""))
14498 (clobber (match_scratch:SI 4 ""))
14499 (clobber (reg:CC 17))])]
14500 ""
14501 {
14502 if (flag_pic)
14503 operands[1] = pic_offset_table_rtx;
14504 else
14505 {
14506 operands[1] = gen_reg_rtx (Pmode);
14507 emit_insn (gen_set_got (operands[1]));
14508 }
14509 operands[2] = ix86_tls_get_addr ();
14510 })
14511
14512 (define_insn "*tls_local_dynamic_base_64"
14513 [(set (match_operand:DI 0 "register_operand" "=a")
14514 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14515 (match_operand:DI 2 "" "")))
14516 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14517 "TARGET_64BIT"
14518 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14519 [(set_attr "type" "multi")
14520 (set_attr "length" "12")])
14521
14522 (define_expand "tls_local_dynamic_base_64"
14523 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14524 (call (mem:QI (match_dup 1)) (const_int 0)))
14525 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14526 ""
14527 {
14528 operands[1] = ix86_tls_get_addr ();
14529 })
14530
14531 ;; Local dynamic of a single variable is a lose. Show combine how
14532 ;; to convert that back to global dynamic.
14533
14534 (define_insn_and_split "*tls_local_dynamic_32_once"
14535 [(set (match_operand:SI 0 "register_operand" "=a")
14536 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14537 (match_operand:SI 2 "call_insn_operand" "")]
14538 UNSPEC_TLS_LD_BASE)
14539 (const:SI (unspec:SI
14540 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14541 UNSPEC_DTPOFF))))
14542 (clobber (match_scratch:SI 4 "=d"))
14543 (clobber (match_scratch:SI 5 "=c"))
14544 (clobber (reg:CC 17))]
14545 ""
14546 "#"
14547 ""
14548 [(parallel [(set (match_dup 0)
14549 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14550 UNSPEC_TLS_GD))
14551 (clobber (match_dup 4))
14552 (clobber (match_dup 5))
14553 (clobber (reg:CC 17))])]
14554 "")
14555 \f
14556 ;; These patterns match the binary 387 instructions for addM3, subM3,
14557 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14558 ;; SFmode. The first is the normal insn, the second the same insn but
14559 ;; with one operand a conversion, and the third the same insn but with
14560 ;; the other operand a conversion. The conversion may be SFmode or
14561 ;; SImode if the target mode DFmode, but only SImode if the target mode
14562 ;; is SFmode.
14563
14564 ;; Gcc is slightly more smart about handling normal two address instructions
14565 ;; so use special patterns for add and mull.
14566 (define_insn "*fop_sf_comm_nosse"
14567 [(set (match_operand:SF 0 "register_operand" "=f")
14568 (match_operator:SF 3 "binary_fp_operator"
14569 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14570 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14571 "TARGET_80387 && !TARGET_SSE_MATH
14572 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14573 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14574 "* return output_387_binary_op (insn, operands);"
14575 [(set (attr "type")
14576 (if_then_else (match_operand:SF 3 "mult_operator" "")
14577 (const_string "fmul")
14578 (const_string "fop")))
14579 (set_attr "mode" "SF")])
14580
14581 (define_insn "*fop_sf_comm"
14582 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14583 (match_operator:SF 3 "binary_fp_operator"
14584 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14585 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14586 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14587 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14588 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14589 "* return output_387_binary_op (insn, operands);"
14590 [(set (attr "type")
14591 (if_then_else (eq_attr "alternative" "1")
14592 (if_then_else (match_operand:SF 3 "mult_operator" "")
14593 (const_string "ssemul")
14594 (const_string "sseadd"))
14595 (if_then_else (match_operand:SF 3 "mult_operator" "")
14596 (const_string "fmul")
14597 (const_string "fop"))))
14598 (set_attr "mode" "SF")])
14599
14600 (define_insn "*fop_sf_comm_sse"
14601 [(set (match_operand:SF 0 "register_operand" "=x")
14602 (match_operator:SF 3 "binary_fp_operator"
14603 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14604 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14605 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14606 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14607 "* return output_387_binary_op (insn, operands);"
14608 [(set (attr "type")
14609 (if_then_else (match_operand:SF 3 "mult_operator" "")
14610 (const_string "ssemul")
14611 (const_string "sseadd")))
14612 (set_attr "mode" "SF")])
14613
14614 (define_insn "*fop_df_comm_nosse"
14615 [(set (match_operand:DF 0 "register_operand" "=f")
14616 (match_operator:DF 3 "binary_fp_operator"
14617 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14618 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14619 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14620 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14621 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14622 "* return output_387_binary_op (insn, operands);"
14623 [(set (attr "type")
14624 (if_then_else (match_operand:SF 3 "mult_operator" "")
14625 (const_string "fmul")
14626 (const_string "fop")))
14627 (set_attr "mode" "DF")])
14628
14629 (define_insn "*fop_df_comm"
14630 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14631 (match_operator:DF 3 "binary_fp_operator"
14632 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14633 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14634 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14635 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14636 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14637 "* return output_387_binary_op (insn, operands);"
14638 [(set (attr "type")
14639 (if_then_else (eq_attr "alternative" "1")
14640 (if_then_else (match_operand:SF 3 "mult_operator" "")
14641 (const_string "ssemul")
14642 (const_string "sseadd"))
14643 (if_then_else (match_operand:SF 3 "mult_operator" "")
14644 (const_string "fmul")
14645 (const_string "fop"))))
14646 (set_attr "mode" "DF")])
14647
14648 (define_insn "*fop_df_comm_sse"
14649 [(set (match_operand:DF 0 "register_operand" "=Y")
14650 (match_operator:DF 3 "binary_fp_operator"
14651 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14652 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14653 "TARGET_SSE2 && TARGET_SSE_MATH
14654 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14655 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14656 "* return output_387_binary_op (insn, operands);"
14657 [(set (attr "type")
14658 (if_then_else (match_operand:SF 3 "mult_operator" "")
14659 (const_string "ssemul")
14660 (const_string "sseadd")))
14661 (set_attr "mode" "DF")])
14662
14663 (define_insn "*fop_xf_comm"
14664 [(set (match_operand:XF 0 "register_operand" "=f")
14665 (match_operator:XF 3 "binary_fp_operator"
14666 [(match_operand:XF 1 "register_operand" "%0")
14667 (match_operand:XF 2 "register_operand" "f")]))]
14668 "!TARGET_64BIT && TARGET_80387
14669 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14670 "* return output_387_binary_op (insn, operands);"
14671 [(set (attr "type")
14672 (if_then_else (match_operand:XF 3 "mult_operator" "")
14673 (const_string "fmul")
14674 (const_string "fop")))
14675 (set_attr "mode" "XF")])
14676
14677 (define_insn "*fop_tf_comm"
14678 [(set (match_operand:TF 0 "register_operand" "=f")
14679 (match_operator:TF 3 "binary_fp_operator"
14680 [(match_operand:TF 1 "register_operand" "%0")
14681 (match_operand:TF 2 "register_operand" "f")]))]
14682 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14683 "* return output_387_binary_op (insn, operands);"
14684 [(set (attr "type")
14685 (if_then_else (match_operand:TF 3 "mult_operator" "")
14686 (const_string "fmul")
14687 (const_string "fop")))
14688 (set_attr "mode" "XF")])
14689
14690 (define_insn "*fop_sf_1_nosse"
14691 [(set (match_operand:SF 0 "register_operand" "=f,f")
14692 (match_operator:SF 3 "binary_fp_operator"
14693 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14694 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14695 "TARGET_80387 && !TARGET_SSE_MATH
14696 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14697 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14698 "* return output_387_binary_op (insn, operands);"
14699 [(set (attr "type")
14700 (cond [(match_operand:SF 3 "mult_operator" "")
14701 (const_string "fmul")
14702 (match_operand:SF 3 "div_operator" "")
14703 (const_string "fdiv")
14704 ]
14705 (const_string "fop")))
14706 (set_attr "mode" "SF")])
14707
14708 (define_insn "*fop_sf_1"
14709 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14710 (match_operator:SF 3 "binary_fp_operator"
14711 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14712 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14713 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14714 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14715 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14716 "* return output_387_binary_op (insn, operands);"
14717 [(set (attr "type")
14718 (cond [(and (eq_attr "alternative" "2")
14719 (match_operand:SF 3 "mult_operator" ""))
14720 (const_string "ssemul")
14721 (and (eq_attr "alternative" "2")
14722 (match_operand:SF 3 "div_operator" ""))
14723 (const_string "ssediv")
14724 (eq_attr "alternative" "2")
14725 (const_string "sseadd")
14726 (match_operand:SF 3 "mult_operator" "")
14727 (const_string "fmul")
14728 (match_operand:SF 3 "div_operator" "")
14729 (const_string "fdiv")
14730 ]
14731 (const_string "fop")))
14732 (set_attr "mode" "SF")])
14733
14734 (define_insn "*fop_sf_1_sse"
14735 [(set (match_operand:SF 0 "register_operand" "=x")
14736 (match_operator:SF 3 "binary_fp_operator"
14737 [(match_operand:SF 1 "register_operand" "0")
14738 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14739 "TARGET_SSE_MATH
14740 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14741 "* return output_387_binary_op (insn, operands);"
14742 [(set (attr "type")
14743 (cond [(match_operand:SF 3 "mult_operator" "")
14744 (const_string "ssemul")
14745 (match_operand:SF 3 "div_operator" "")
14746 (const_string "ssediv")
14747 ]
14748 (const_string "sseadd")))
14749 (set_attr "mode" "SF")])
14750
14751 ;; ??? Add SSE splitters for these!
14752 (define_insn "*fop_sf_2"
14753 [(set (match_operand:SF 0 "register_operand" "=f,f")
14754 (match_operator:SF 3 "binary_fp_operator"
14755 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14756 (match_operand:SF 2 "register_operand" "0,0")]))]
14757 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14758 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14759 [(set (attr "type")
14760 (cond [(match_operand:SF 3 "mult_operator" "")
14761 (const_string "fmul")
14762 (match_operand:SF 3 "div_operator" "")
14763 (const_string "fdiv")
14764 ]
14765 (const_string "fop")))
14766 (set_attr "fp_int_src" "true")
14767 (set_attr "ppro_uops" "many")
14768 (set_attr "mode" "SI")])
14769
14770 (define_insn "*fop_sf_3"
14771 [(set (match_operand:SF 0 "register_operand" "=f,f")
14772 (match_operator:SF 3 "binary_fp_operator"
14773 [(match_operand:SF 1 "register_operand" "0,0")
14774 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14775 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14776 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14777 [(set (attr "type")
14778 (cond [(match_operand:SF 3 "mult_operator" "")
14779 (const_string "fmul")
14780 (match_operand:SF 3 "div_operator" "")
14781 (const_string "fdiv")
14782 ]
14783 (const_string "fop")))
14784 (set_attr "fp_int_src" "true")
14785 (set_attr "ppro_uops" "many")
14786 (set_attr "mode" "SI")])
14787
14788 (define_insn "*fop_df_1_nosse"
14789 [(set (match_operand:DF 0 "register_operand" "=f,f")
14790 (match_operator:DF 3 "binary_fp_operator"
14791 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14792 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14793 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14794 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14795 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14796 "* return output_387_binary_op (insn, operands);"
14797 [(set (attr "type")
14798 (cond [(match_operand:DF 3 "mult_operator" "")
14799 (const_string "fmul")
14800 (match_operand:DF 3 "div_operator" "")
14801 (const_string "fdiv")
14802 ]
14803 (const_string "fop")))
14804 (set_attr "mode" "DF")])
14805
14806
14807 (define_insn "*fop_df_1"
14808 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14809 (match_operator:DF 3 "binary_fp_operator"
14810 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14811 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14812 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14813 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14814 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14815 "* return output_387_binary_op (insn, operands);"
14816 [(set (attr "type")
14817 (cond [(and (eq_attr "alternative" "2")
14818 (match_operand:SF 3 "mult_operator" ""))
14819 (const_string "ssemul")
14820 (and (eq_attr "alternative" "2")
14821 (match_operand:SF 3 "div_operator" ""))
14822 (const_string "ssediv")
14823 (eq_attr "alternative" "2")
14824 (const_string "sseadd")
14825 (match_operand:DF 3 "mult_operator" "")
14826 (const_string "fmul")
14827 (match_operand:DF 3 "div_operator" "")
14828 (const_string "fdiv")
14829 ]
14830 (const_string "fop")))
14831 (set_attr "mode" "DF")])
14832
14833 (define_insn "*fop_df_1_sse"
14834 [(set (match_operand:DF 0 "register_operand" "=Y")
14835 (match_operator:DF 3 "binary_fp_operator"
14836 [(match_operand:DF 1 "register_operand" "0")
14837 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14838 "TARGET_SSE2 && TARGET_SSE_MATH
14839 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14840 "* return output_387_binary_op (insn, operands);"
14841 [(set_attr "mode" "DF")
14842 (set (attr "type")
14843 (cond [(match_operand:SF 3 "mult_operator" "")
14844 (const_string "ssemul")
14845 (match_operand:SF 3 "div_operator" "")
14846 (const_string "ssediv")
14847 ]
14848 (const_string "sseadd")))])
14849
14850 ;; ??? Add SSE splitters for these!
14851 (define_insn "*fop_df_2"
14852 [(set (match_operand:DF 0 "register_operand" "=f,f")
14853 (match_operator:DF 3 "binary_fp_operator"
14854 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14855 (match_operand:DF 2 "register_operand" "0,0")]))]
14856 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14857 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14858 [(set (attr "type")
14859 (cond [(match_operand:DF 3 "mult_operator" "")
14860 (const_string "fmul")
14861 (match_operand:DF 3 "div_operator" "")
14862 (const_string "fdiv")
14863 ]
14864 (const_string "fop")))
14865 (set_attr "fp_int_src" "true")
14866 (set_attr "ppro_uops" "many")
14867 (set_attr "mode" "SI")])
14868
14869 (define_insn "*fop_df_3"
14870 [(set (match_operand:DF 0 "register_operand" "=f,f")
14871 (match_operator:DF 3 "binary_fp_operator"
14872 [(match_operand:DF 1 "register_operand" "0,0")
14873 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14874 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14875 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14876 [(set (attr "type")
14877 (cond [(match_operand:DF 3 "mult_operator" "")
14878 (const_string "fmul")
14879 (match_operand:DF 3 "div_operator" "")
14880 (const_string "fdiv")
14881 ]
14882 (const_string "fop")))
14883 (set_attr "fp_int_src" "true")
14884 (set_attr "ppro_uops" "many")
14885 (set_attr "mode" "SI")])
14886
14887 (define_insn "*fop_df_4"
14888 [(set (match_operand:DF 0 "register_operand" "=f,f")
14889 (match_operator:DF 3 "binary_fp_operator"
14890 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14891 (match_operand:DF 2 "register_operand" "0,f")]))]
14892 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14893 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14894 "* return output_387_binary_op (insn, operands);"
14895 [(set (attr "type")
14896 (cond [(match_operand:DF 3 "mult_operator" "")
14897 (const_string "fmul")
14898 (match_operand:DF 3 "div_operator" "")
14899 (const_string "fdiv")
14900 ]
14901 (const_string "fop")))
14902 (set_attr "mode" "SF")])
14903
14904 (define_insn "*fop_df_5"
14905 [(set (match_operand:DF 0 "register_operand" "=f,f")
14906 (match_operator:DF 3 "binary_fp_operator"
14907 [(match_operand:DF 1 "register_operand" "0,f")
14908 (float_extend:DF
14909 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14910 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14911 "* return output_387_binary_op (insn, operands);"
14912 [(set (attr "type")
14913 (cond [(match_operand:DF 3 "mult_operator" "")
14914 (const_string "fmul")
14915 (match_operand:DF 3 "div_operator" "")
14916 (const_string "fdiv")
14917 ]
14918 (const_string "fop")))
14919 (set_attr "mode" "SF")])
14920
14921 (define_insn "*fop_df_6"
14922 [(set (match_operand:DF 0 "register_operand" "=f,f")
14923 (match_operator:DF 3 "binary_fp_operator"
14924 [(float_extend:DF
14925 (match_operand:SF 1 "register_operand" "0,f"))
14926 (float_extend:DF
14927 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14928 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14929 "* return output_387_binary_op (insn, operands);"
14930 [(set (attr "type")
14931 (cond [(match_operand:DF 3 "mult_operator" "")
14932 (const_string "fmul")
14933 (match_operand:DF 3 "div_operator" "")
14934 (const_string "fdiv")
14935 ]
14936 (const_string "fop")))
14937 (set_attr "mode" "SF")])
14938
14939 (define_insn "*fop_xf_1"
14940 [(set (match_operand:XF 0 "register_operand" "=f,f")
14941 (match_operator:XF 3 "binary_fp_operator"
14942 [(match_operand:XF 1 "register_operand" "0,f")
14943 (match_operand:XF 2 "register_operand" "f,0")]))]
14944 "!TARGET_64BIT && TARGET_80387
14945 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14946 "* return output_387_binary_op (insn, operands);"
14947 [(set (attr "type")
14948 (cond [(match_operand:XF 3 "mult_operator" "")
14949 (const_string "fmul")
14950 (match_operand:XF 3 "div_operator" "")
14951 (const_string "fdiv")
14952 ]
14953 (const_string "fop")))
14954 (set_attr "mode" "XF")])
14955
14956 (define_insn "*fop_tf_1"
14957 [(set (match_operand:TF 0 "register_operand" "=f,f")
14958 (match_operator:TF 3 "binary_fp_operator"
14959 [(match_operand:TF 1 "register_operand" "0,f")
14960 (match_operand:TF 2 "register_operand" "f,0")]))]
14961 "TARGET_80387
14962 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14963 "* return output_387_binary_op (insn, operands);"
14964 [(set (attr "type")
14965 (cond [(match_operand:TF 3 "mult_operator" "")
14966 (const_string "fmul")
14967 (match_operand:TF 3 "div_operator" "")
14968 (const_string "fdiv")
14969 ]
14970 (const_string "fop")))
14971 (set_attr "mode" "XF")])
14972
14973 (define_insn "*fop_xf_2"
14974 [(set (match_operand:XF 0 "register_operand" "=f,f")
14975 (match_operator:XF 3 "binary_fp_operator"
14976 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14977 (match_operand:XF 2 "register_operand" "0,0")]))]
14978 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14979 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14980 [(set (attr "type")
14981 (cond [(match_operand:XF 3 "mult_operator" "")
14982 (const_string "fmul")
14983 (match_operand:XF 3 "div_operator" "")
14984 (const_string "fdiv")
14985 ]
14986 (const_string "fop")))
14987 (set_attr "fp_int_src" "true")
14988 (set_attr "mode" "SI")
14989 (set_attr "ppro_uops" "many")])
14990
14991 (define_insn "*fop_tf_2"
14992 [(set (match_operand:TF 0 "register_operand" "=f,f")
14993 (match_operator:TF 3 "binary_fp_operator"
14994 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14995 (match_operand:TF 2 "register_operand" "0,0")]))]
14996 "TARGET_80387 && TARGET_USE_FIOP"
14997 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14998 [(set (attr "type")
14999 (cond [(match_operand:TF 3 "mult_operator" "")
15000 (const_string "fmul")
15001 (match_operand:TF 3 "div_operator" "")
15002 (const_string "fdiv")
15003 ]
15004 (const_string "fop")))
15005 (set_attr "fp_int_src" "true")
15006 (set_attr "mode" "SI")
15007 (set_attr "ppro_uops" "many")])
15008
15009 (define_insn "*fop_xf_3"
15010 [(set (match_operand:XF 0 "register_operand" "=f,f")
15011 (match_operator:XF 3 "binary_fp_operator"
15012 [(match_operand:XF 1 "register_operand" "0,0")
15013 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15014 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
15015 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15016 [(set (attr "type")
15017 (cond [(match_operand:XF 3 "mult_operator" "")
15018 (const_string "fmul")
15019 (match_operand:XF 3 "div_operator" "")
15020 (const_string "fdiv")
15021 ]
15022 (const_string "fop")))
15023 (set_attr "fp_int_src" "true")
15024 (set_attr "mode" "SI")
15025 (set_attr "ppro_uops" "many")])
15026
15027 (define_insn "*fop_tf_3"
15028 [(set (match_operand:TF 0 "register_operand" "=f,f")
15029 (match_operator:TF 3 "binary_fp_operator"
15030 [(match_operand:TF 1 "register_operand" "0,0")
15031 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15032 "TARGET_80387 && TARGET_USE_FIOP"
15033 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15034 [(set (attr "type")
15035 (cond [(match_operand:TF 3 "mult_operator" "")
15036 (const_string "fmul")
15037 (match_operand:TF 3 "div_operator" "")
15038 (const_string "fdiv")
15039 ]
15040 (const_string "fop")))
15041 (set_attr "fp_int_src" "true")
15042 (set_attr "mode" "SI")
15043 (set_attr "ppro_uops" "many")])
15044
15045 (define_insn "*fop_xf_4"
15046 [(set (match_operand:XF 0 "register_operand" "=f,f")
15047 (match_operator:XF 3 "binary_fp_operator"
15048 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15049 (match_operand:XF 2 "register_operand" "0,f")]))]
15050 "!TARGET_64BIT && TARGET_80387"
15051 "* return output_387_binary_op (insn, operands);"
15052 [(set (attr "type")
15053 (cond [(match_operand:XF 3 "mult_operator" "")
15054 (const_string "fmul")
15055 (match_operand:XF 3 "div_operator" "")
15056 (const_string "fdiv")
15057 ]
15058 (const_string "fop")))
15059 (set_attr "mode" "SF")])
15060
15061 (define_insn "*fop_tf_4"
15062 [(set (match_operand:TF 0 "register_operand" "=f,f")
15063 (match_operator:TF 3 "binary_fp_operator"
15064 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15065 (match_operand:TF 2 "register_operand" "0,f")]))]
15066 "TARGET_80387"
15067 "* return output_387_binary_op (insn, operands);"
15068 [(set (attr "type")
15069 (cond [(match_operand:TF 3 "mult_operator" "")
15070 (const_string "fmul")
15071 (match_operand:TF 3 "div_operator" "")
15072 (const_string "fdiv")
15073 ]
15074 (const_string "fop")))
15075 (set_attr "mode" "SF")])
15076
15077 (define_insn "*fop_xf_5"
15078 [(set (match_operand:XF 0 "register_operand" "=f,f")
15079 (match_operator:XF 3 "binary_fp_operator"
15080 [(match_operand:XF 1 "register_operand" "0,f")
15081 (float_extend:XF
15082 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15083 "!TARGET_64BIT && TARGET_80387"
15084 "* return output_387_binary_op (insn, operands);"
15085 [(set (attr "type")
15086 (cond [(match_operand:XF 3 "mult_operator" "")
15087 (const_string "fmul")
15088 (match_operand:XF 3 "div_operator" "")
15089 (const_string "fdiv")
15090 ]
15091 (const_string "fop")))
15092 (set_attr "mode" "SF")])
15093
15094 (define_insn "*fop_tf_5"
15095 [(set (match_operand:TF 0 "register_operand" "=f,f")
15096 (match_operator:TF 3 "binary_fp_operator"
15097 [(match_operand:TF 1 "register_operand" "0,f")
15098 (float_extend:TF
15099 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15100 "TARGET_80387"
15101 "* return output_387_binary_op (insn, operands);"
15102 [(set (attr "type")
15103 (cond [(match_operand:TF 3 "mult_operator" "")
15104 (const_string "fmul")
15105 (match_operand:TF 3 "div_operator" "")
15106 (const_string "fdiv")
15107 ]
15108 (const_string "fop")))
15109 (set_attr "mode" "SF")])
15110
15111 (define_insn "*fop_xf_6"
15112 [(set (match_operand:XF 0 "register_operand" "=f,f")
15113 (match_operator:XF 3 "binary_fp_operator"
15114 [(float_extend:XF
15115 (match_operand 1 "register_operand" "0,f"))
15116 (float_extend:XF
15117 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15118 "!TARGET_64BIT && TARGET_80387"
15119 "* return output_387_binary_op (insn, operands);"
15120 [(set (attr "type")
15121 (cond [(match_operand:XF 3 "mult_operator" "")
15122 (const_string "fmul")
15123 (match_operand:XF 3 "div_operator" "")
15124 (const_string "fdiv")
15125 ]
15126 (const_string "fop")))
15127 (set_attr "mode" "SF")])
15128
15129 (define_insn "*fop_tf_6"
15130 [(set (match_operand:TF 0 "register_operand" "=f,f")
15131 (match_operator:TF 3 "binary_fp_operator"
15132 [(float_extend:TF
15133 (match_operand 1 "register_operand" "0,f"))
15134 (float_extend:TF
15135 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15136 "TARGET_80387"
15137 "* return output_387_binary_op (insn, operands);"
15138 [(set (attr "type")
15139 (cond [(match_operand:TF 3 "mult_operator" "")
15140 (const_string "fmul")
15141 (match_operand:TF 3 "div_operator" "")
15142 (const_string "fdiv")
15143 ]
15144 (const_string "fop")))
15145 (set_attr "mode" "SF")])
15146
15147 (define_split
15148 [(set (match_operand 0 "register_operand" "")
15149 (match_operator 3 "binary_fp_operator"
15150 [(float (match_operand:SI 1 "register_operand" ""))
15151 (match_operand 2 "register_operand" "")]))]
15152 "TARGET_80387 && reload_completed
15153 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15154 [(const_int 0)]
15155 {
15156 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15157 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15158 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15159 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15160 GET_MODE (operands[3]),
15161 operands[4],
15162 operands[2])));
15163 ix86_free_from_memory (GET_MODE (operands[1]));
15164 DONE;
15165 })
15166
15167 (define_split
15168 [(set (match_operand 0 "register_operand" "")
15169 (match_operator 3 "binary_fp_operator"
15170 [(match_operand 1 "register_operand" "")
15171 (float (match_operand:SI 2 "register_operand" ""))]))]
15172 "TARGET_80387 && reload_completed
15173 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15174 [(const_int 0)]
15175 {
15176 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15177 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15178 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15179 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15180 GET_MODE (operands[3]),
15181 operands[1],
15182 operands[4])));
15183 ix86_free_from_memory (GET_MODE (operands[2]));
15184 DONE;
15185 })
15186 \f
15187 ;; FPU special functions.
15188
15189 (define_expand "sqrtsf2"
15190 [(set (match_operand:SF 0 "register_operand" "")
15191 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15192 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15193 {
15194 if (!TARGET_SSE_MATH)
15195 operands[1] = force_reg (SFmode, operands[1]);
15196 })
15197
15198 (define_insn "sqrtsf2_1"
15199 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15200 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15201 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15202 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15203 "@
15204 fsqrt
15205 sqrtss\t{%1, %0|%0, %1}"
15206 [(set_attr "type" "fpspc,sse")
15207 (set_attr "mode" "SF,SF")
15208 (set_attr "athlon_decode" "direct,*")])
15209
15210 (define_insn "sqrtsf2_1_sse_only"
15211 [(set (match_operand:SF 0 "register_operand" "=x")
15212 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15213 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15214 "sqrtss\t{%1, %0|%0, %1}"
15215 [(set_attr "type" "sse")
15216 (set_attr "mode" "SF")
15217 (set_attr "athlon_decode" "*")])
15218
15219 (define_insn "sqrtsf2_i387"
15220 [(set (match_operand:SF 0 "register_operand" "=f")
15221 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15222 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15223 && !TARGET_SSE_MATH"
15224 "fsqrt"
15225 [(set_attr "type" "fpspc")
15226 (set_attr "mode" "SF")
15227 (set_attr "athlon_decode" "direct")])
15228
15229 (define_expand "sqrtdf2"
15230 [(set (match_operand:DF 0 "register_operand" "")
15231 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15232 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15233 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15234 {
15235 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15236 operands[1] = force_reg (DFmode, operands[1]);
15237 })
15238
15239 (define_insn "sqrtdf2_1"
15240 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15241 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15242 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15243 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15244 "@
15245 fsqrt
15246 sqrtsd\t{%1, %0|%0, %1}"
15247 [(set_attr "type" "fpspc,sse")
15248 (set_attr "mode" "DF,DF")
15249 (set_attr "athlon_decode" "direct,*")])
15250
15251 (define_insn "sqrtdf2_1_sse_only"
15252 [(set (match_operand:DF 0 "register_operand" "=Y")
15253 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15254 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15255 "sqrtsd\t{%1, %0|%0, %1}"
15256 [(set_attr "type" "sse")
15257 (set_attr "mode" "DF")
15258 (set_attr "athlon_decode" "*")])
15259
15260 (define_insn "sqrtdf2_i387"
15261 [(set (match_operand:DF 0 "register_operand" "=f")
15262 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15263 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15264 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15265 "fsqrt"
15266 [(set_attr "type" "fpspc")
15267 (set_attr "mode" "DF")
15268 (set_attr "athlon_decode" "direct")])
15269
15270 (define_insn "*sqrtextendsfdf2"
15271 [(set (match_operand:DF 0 "register_operand" "=f")
15272 (sqrt:DF (float_extend:DF
15273 (match_operand:SF 1 "register_operand" "0"))))]
15274 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15275 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15276 "fsqrt"
15277 [(set_attr "type" "fpspc")
15278 (set_attr "mode" "DF")
15279 (set_attr "athlon_decode" "direct")])
15280
15281 (define_insn "sqrtxf2"
15282 [(set (match_operand:XF 0 "register_operand" "=f")
15283 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15284 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15285 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15286 "fsqrt"
15287 [(set_attr "type" "fpspc")
15288 (set_attr "mode" "XF")
15289 (set_attr "athlon_decode" "direct")])
15290
15291 (define_insn "sqrttf2"
15292 [(set (match_operand:TF 0 "register_operand" "=f")
15293 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15294 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15295 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15296 "fsqrt"
15297 [(set_attr "type" "fpspc")
15298 (set_attr "mode" "XF")
15299 (set_attr "athlon_decode" "direct")])
15300
15301 (define_insn "*sqrtextenddfxf2"
15302 [(set (match_operand:XF 0 "register_operand" "=f")
15303 (sqrt:XF (float_extend:XF
15304 (match_operand:DF 1 "register_operand" "0"))))]
15305 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15306 "fsqrt"
15307 [(set_attr "type" "fpspc")
15308 (set_attr "mode" "XF")
15309 (set_attr "athlon_decode" "direct")])
15310
15311 (define_insn "*sqrtextenddftf2"
15312 [(set (match_operand:TF 0 "register_operand" "=f")
15313 (sqrt:TF (float_extend:TF
15314 (match_operand:DF 1 "register_operand" "0"))))]
15315 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15316 "fsqrt"
15317 [(set_attr "type" "fpspc")
15318 (set_attr "mode" "XF")
15319 (set_attr "athlon_decode" "direct")])
15320
15321 (define_insn "*sqrtextendsfxf2"
15322 [(set (match_operand:XF 0 "register_operand" "=f")
15323 (sqrt:XF (float_extend:XF
15324 (match_operand:SF 1 "register_operand" "0"))))]
15325 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15326 "fsqrt"
15327 [(set_attr "type" "fpspc")
15328 (set_attr "mode" "XF")
15329 (set_attr "athlon_decode" "direct")])
15330
15331 (define_insn "*sqrtextendsftf2"
15332 [(set (match_operand:TF 0 "register_operand" "=f")
15333 (sqrt:TF (float_extend:TF
15334 (match_operand:SF 1 "register_operand" "0"))))]
15335 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15336 "fsqrt"
15337 [(set_attr "type" "fpspc")
15338 (set_attr "mode" "XF")
15339 (set_attr "athlon_decode" "direct")])
15340
15341 (define_insn "sindf2"
15342 [(set (match_operand:DF 0 "register_operand" "=f")
15343 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15344 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15345 && flag_unsafe_math_optimizations"
15346 "fsin"
15347 [(set_attr "type" "fpspc")
15348 (set_attr "mode" "DF")])
15349
15350 (define_insn "sinsf2"
15351 [(set (match_operand:SF 0 "register_operand" "=f")
15352 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15353 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15354 && flag_unsafe_math_optimizations"
15355 "fsin"
15356 [(set_attr "type" "fpspc")
15357 (set_attr "mode" "SF")])
15358
15359 (define_insn "*sinextendsfdf2"
15360 [(set (match_operand:DF 0 "register_operand" "=f")
15361 (unspec:DF [(float_extend:DF
15362 (match_operand:SF 1 "register_operand" "0"))]
15363 UNSPEC_SIN))]
15364 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15365 && flag_unsafe_math_optimizations"
15366 "fsin"
15367 [(set_attr "type" "fpspc")
15368 (set_attr "mode" "DF")])
15369
15370 (define_insn "sinxf2"
15371 [(set (match_operand:XF 0 "register_operand" "=f")
15372 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15373 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15374 && flag_unsafe_math_optimizations"
15375 "fsin"
15376 [(set_attr "type" "fpspc")
15377 (set_attr "mode" "XF")])
15378
15379 (define_insn "sintf2"
15380 [(set (match_operand:TF 0 "register_operand" "=f")
15381 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15382 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15383 && flag_unsafe_math_optimizations"
15384 "fsin"
15385 [(set_attr "type" "fpspc")
15386 (set_attr "mode" "XF")])
15387
15388 (define_insn "cosdf2"
15389 [(set (match_operand:DF 0 "register_operand" "=f")
15390 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15391 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15392 && flag_unsafe_math_optimizations"
15393 "fcos"
15394 [(set_attr "type" "fpspc")
15395 (set_attr "mode" "DF")])
15396
15397 (define_insn "cossf2"
15398 [(set (match_operand:SF 0 "register_operand" "=f")
15399 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15400 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15401 && flag_unsafe_math_optimizations"
15402 "fcos"
15403 [(set_attr "type" "fpspc")
15404 (set_attr "mode" "SF")])
15405
15406 (define_insn "*cosextendsfdf2"
15407 [(set (match_operand:DF 0 "register_operand" "=f")
15408 (unspec:DF [(float_extend:DF
15409 (match_operand:SF 1 "register_operand" "0"))]
15410 UNSPEC_COS))]
15411 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15412 && flag_unsafe_math_optimizations"
15413 "fcos"
15414 [(set_attr "type" "fpspc")
15415 (set_attr "mode" "DF")])
15416
15417 (define_insn "cosxf2"
15418 [(set (match_operand:XF 0 "register_operand" "=f")
15419 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15420 "!TARGET_64BIT && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15421 && flag_unsafe_math_optimizations"
15422 "fcos"
15423 [(set_attr "type" "fpspc")
15424 (set_attr "mode" "XF")])
15425
15426 (define_insn "costf2"
15427 [(set (match_operand:TF 0 "register_operand" "=f")
15428 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15429 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15430 && flag_unsafe_math_optimizations"
15431 "fcos"
15432 [(set_attr "type" "fpspc")
15433 (set_attr "mode" "XF")])
15434
15435 (define_insn "atan2df3"
15436 [(set (match_operand:DF 0 "register_operand" "=f")
15437 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15438 (match_operand:DF 1 "register_operand" "u")]
15439 UNSPEC_FPATAN))]
15440 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15441 && flag_unsafe_math_optimizations"
15442 "fpatan"
15443 [(set_attr "type" "fpspc")
15444 (set_attr "mode" "DF")])
15445
15446 (define_insn "atan2sf3"
15447 [(set (match_operand:SF 0 "register_operand" "=f")
15448 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15449 (match_operand:SF 1 "register_operand" "u")]
15450 UNSPEC_FPATAN))]
15451 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15452 && flag_unsafe_math_optimizations"
15453 "fpatan"
15454 [(set_attr "type" "fpspc")
15455 (set_attr "mode" "SF")])
15456
15457 (define_insn "atan2xf3"
15458 [(set (match_operand:XF 0 "register_operand" "=f")
15459 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15460 (match_operand:XF 1 "register_operand" "u")]
15461 UNSPEC_FPATAN))]
15462 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15463 && flag_unsafe_math_optimizations"
15464 "fpatan"
15465 [(set_attr "type" "fpspc")
15466 (set_attr "mode" "XF")])
15467
15468 (define_insn "atan2tf3"
15469 [(set (match_operand:TF 0 "register_operand" "=f")
15470 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15471 (match_operand:TF 1 "register_operand" "u")]
15472 UNSPEC_FPATAN))]
15473 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15474 && flag_unsafe_math_optimizations"
15475 "fpatan"
15476 [(set_attr "type" "fpspc")
15477 (set_attr "mode" "XF")])
15478 \f
15479 ;; Block operation instructions
15480
15481 (define_insn "cld"
15482 [(set (reg:SI 19) (const_int 0))]
15483 ""
15484 "cld"
15485 [(set_attr "type" "cld")])
15486
15487 (define_expand "movstrsi"
15488 [(use (match_operand:BLK 0 "memory_operand" ""))
15489 (use (match_operand:BLK 1 "memory_operand" ""))
15490 (use (match_operand:SI 2 "nonmemory_operand" ""))
15491 (use (match_operand:SI 3 "const_int_operand" ""))]
15492 ""
15493 {
15494 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15495 DONE;
15496 else
15497 FAIL;
15498 })
15499
15500 (define_expand "movstrdi"
15501 [(use (match_operand:BLK 0 "memory_operand" ""))
15502 (use (match_operand:BLK 1 "memory_operand" ""))
15503 (use (match_operand:DI 2 "nonmemory_operand" ""))
15504 (use (match_operand:DI 3 "const_int_operand" ""))]
15505 "TARGET_64BIT"
15506 {
15507 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15508 DONE;
15509 else
15510 FAIL;
15511 })
15512
15513 ;; Most CPUs don't like single string operations
15514 ;; Handle this case here to simplify previous expander.
15515
15516 (define_expand "strmovdi_rex64"
15517 [(set (match_dup 2)
15518 (mem:DI (match_operand:DI 1 "register_operand" "")))
15519 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15520 (match_dup 2))
15521 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15522 (clobber (reg:CC 17))])
15523 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15524 (clobber (reg:CC 17))])]
15525 "TARGET_64BIT"
15526 {
15527 if (TARGET_SINGLE_STRINGOP || optimize_size)
15528 {
15529 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15530 operands[1]));
15531 DONE;
15532 }
15533 else
15534 operands[2] = gen_reg_rtx (DImode);
15535 })
15536
15537
15538 (define_expand "strmovsi"
15539 [(set (match_dup 2)
15540 (mem:SI (match_operand:SI 1 "register_operand" "")))
15541 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15542 (match_dup 2))
15543 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15544 (clobber (reg:CC 17))])
15545 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15546 (clobber (reg:CC 17))])]
15547 ""
15548 {
15549 if (TARGET_64BIT)
15550 {
15551 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15552 DONE;
15553 }
15554 if (TARGET_SINGLE_STRINGOP || optimize_size)
15555 {
15556 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15557 operands[1]));
15558 DONE;
15559 }
15560 else
15561 operands[2] = gen_reg_rtx (SImode);
15562 })
15563
15564 (define_expand "strmovsi_rex64"
15565 [(set (match_dup 2)
15566 (mem:SI (match_operand:DI 1 "register_operand" "")))
15567 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15568 (match_dup 2))
15569 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15570 (clobber (reg:CC 17))])
15571 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15572 (clobber (reg:CC 17))])]
15573 "TARGET_64BIT"
15574 {
15575 if (TARGET_SINGLE_STRINGOP || optimize_size)
15576 {
15577 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15578 operands[1]));
15579 DONE;
15580 }
15581 else
15582 operands[2] = gen_reg_rtx (SImode);
15583 })
15584
15585 (define_expand "strmovhi"
15586 [(set (match_dup 2)
15587 (mem:HI (match_operand:SI 1 "register_operand" "")))
15588 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15589 (match_dup 2))
15590 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15591 (clobber (reg:CC 17))])
15592 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15593 (clobber (reg:CC 17))])]
15594 ""
15595 {
15596 if (TARGET_64BIT)
15597 {
15598 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15599 DONE;
15600 }
15601 if (TARGET_SINGLE_STRINGOP || optimize_size)
15602 {
15603 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15604 operands[1]));
15605 DONE;
15606 }
15607 else
15608 operands[2] = gen_reg_rtx (HImode);
15609 })
15610
15611 (define_expand "strmovhi_rex64"
15612 [(set (match_dup 2)
15613 (mem:HI (match_operand:DI 1 "register_operand" "")))
15614 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15615 (match_dup 2))
15616 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15617 (clobber (reg:CC 17))])
15618 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15619 (clobber (reg:CC 17))])]
15620 "TARGET_64BIT"
15621 {
15622 if (TARGET_SINGLE_STRINGOP || optimize_size)
15623 {
15624 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15625 operands[1]));
15626 DONE;
15627 }
15628 else
15629 operands[2] = gen_reg_rtx (HImode);
15630 })
15631
15632 (define_expand "strmovqi"
15633 [(set (match_dup 2)
15634 (mem:QI (match_operand:SI 1 "register_operand" "")))
15635 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15636 (match_dup 2))
15637 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15638 (clobber (reg:CC 17))])
15639 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15640 (clobber (reg:CC 17))])]
15641 ""
15642 {
15643 if (TARGET_64BIT)
15644 {
15645 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15646 DONE;
15647 }
15648 if (TARGET_SINGLE_STRINGOP || optimize_size)
15649 {
15650 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15651 operands[1]));
15652 DONE;
15653 }
15654 else
15655 operands[2] = gen_reg_rtx (QImode);
15656 })
15657
15658 (define_expand "strmovqi_rex64"
15659 [(set (match_dup 2)
15660 (mem:QI (match_operand:DI 1 "register_operand" "")))
15661 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15662 (match_dup 2))
15663 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15664 (clobber (reg:CC 17))])
15665 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15666 (clobber (reg:CC 17))])]
15667 "TARGET_64BIT"
15668 {
15669 if (TARGET_SINGLE_STRINGOP || optimize_size)
15670 {
15671 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15672 operands[1]));
15673 DONE;
15674 }
15675 else
15676 operands[2] = gen_reg_rtx (QImode);
15677 })
15678
15679 (define_insn "strmovdi_rex_1"
15680 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15681 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15682 (set (match_operand:DI 0 "register_operand" "=D")
15683 (plus:DI (match_dup 2)
15684 (const_int 8)))
15685 (set (match_operand:DI 1 "register_operand" "=S")
15686 (plus:DI (match_dup 3)
15687 (const_int 8)))
15688 (use (reg:SI 19))]
15689 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15690 "movsq"
15691 [(set_attr "type" "str")
15692 (set_attr "mode" "DI")
15693 (set_attr "memory" "both")])
15694
15695 (define_insn "strmovsi_1"
15696 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15697 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15698 (set (match_operand:SI 0 "register_operand" "=D")
15699 (plus:SI (match_dup 2)
15700 (const_int 4)))
15701 (set (match_operand:SI 1 "register_operand" "=S")
15702 (plus:SI (match_dup 3)
15703 (const_int 4)))
15704 (use (reg:SI 19))]
15705 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15706 "{movsl|movsd}"
15707 [(set_attr "type" "str")
15708 (set_attr "mode" "SI")
15709 (set_attr "memory" "both")])
15710
15711 (define_insn "strmovsi_rex_1"
15712 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15713 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15714 (set (match_operand:DI 0 "register_operand" "=D")
15715 (plus:DI (match_dup 2)
15716 (const_int 4)))
15717 (set (match_operand:DI 1 "register_operand" "=S")
15718 (plus:DI (match_dup 3)
15719 (const_int 4)))
15720 (use (reg:SI 19))]
15721 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15722 "{movsl|movsd}"
15723 [(set_attr "type" "str")
15724 (set_attr "mode" "SI")
15725 (set_attr "memory" "both")])
15726
15727 (define_insn "strmovhi_1"
15728 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15729 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15730 (set (match_operand:SI 0 "register_operand" "=D")
15731 (plus:SI (match_dup 2)
15732 (const_int 2)))
15733 (set (match_operand:SI 1 "register_operand" "=S")
15734 (plus:SI (match_dup 3)
15735 (const_int 2)))
15736 (use (reg:SI 19))]
15737 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15738 "movsw"
15739 [(set_attr "type" "str")
15740 (set_attr "memory" "both")
15741 (set_attr "mode" "HI")])
15742
15743 (define_insn "strmovhi_rex_1"
15744 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15745 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15746 (set (match_operand:DI 0 "register_operand" "=D")
15747 (plus:DI (match_dup 2)
15748 (const_int 2)))
15749 (set (match_operand:DI 1 "register_operand" "=S")
15750 (plus:DI (match_dup 3)
15751 (const_int 2)))
15752 (use (reg:SI 19))]
15753 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15754 "movsw"
15755 [(set_attr "type" "str")
15756 (set_attr "memory" "both")
15757 (set_attr "mode" "HI")])
15758
15759 (define_insn "strmovqi_1"
15760 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15761 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15762 (set (match_operand:SI 0 "register_operand" "=D")
15763 (plus:SI (match_dup 2)
15764 (const_int 1)))
15765 (set (match_operand:SI 1 "register_operand" "=S")
15766 (plus:SI (match_dup 3)
15767 (const_int 1)))
15768 (use (reg:SI 19))]
15769 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15770 "movsb"
15771 [(set_attr "type" "str")
15772 (set_attr "memory" "both")
15773 (set_attr "mode" "QI")])
15774
15775 (define_insn "strmovqi_rex_1"
15776 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15777 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15778 (set (match_operand:DI 0 "register_operand" "=D")
15779 (plus:DI (match_dup 2)
15780 (const_int 1)))
15781 (set (match_operand:DI 1 "register_operand" "=S")
15782 (plus:DI (match_dup 3)
15783 (const_int 1)))
15784 (use (reg:SI 19))]
15785 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15786 "movsb"
15787 [(set_attr "type" "str")
15788 (set_attr "memory" "both")
15789 (set_attr "mode" "QI")])
15790
15791 (define_insn "rep_movdi_rex64"
15792 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15793 (set (match_operand:DI 0 "register_operand" "=D")
15794 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15795 (const_int 3))
15796 (match_operand:DI 3 "register_operand" "0")))
15797 (set (match_operand:DI 1 "register_operand" "=S")
15798 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15799 (match_operand:DI 4 "register_operand" "1")))
15800 (set (mem:BLK (match_dup 3))
15801 (mem:BLK (match_dup 4)))
15802 (use (match_dup 5))
15803 (use (reg:SI 19))]
15804 "TARGET_64BIT"
15805 "{rep\;movsq|rep movsq}"
15806 [(set_attr "type" "str")
15807 (set_attr "prefix_rep" "1")
15808 (set_attr "memory" "both")
15809 (set_attr "mode" "DI")])
15810
15811 (define_insn "rep_movsi"
15812 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15813 (set (match_operand:SI 0 "register_operand" "=D")
15814 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15815 (const_int 2))
15816 (match_operand:SI 3 "register_operand" "0")))
15817 (set (match_operand:SI 1 "register_operand" "=S")
15818 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15819 (match_operand:SI 4 "register_operand" "1")))
15820 (set (mem:BLK (match_dup 3))
15821 (mem:BLK (match_dup 4)))
15822 (use (match_dup 5))
15823 (use (reg:SI 19))]
15824 "!TARGET_64BIT"
15825 "{rep\;movsl|rep movsd}"
15826 [(set_attr "type" "str")
15827 (set_attr "prefix_rep" "1")
15828 (set_attr "memory" "both")
15829 (set_attr "mode" "SI")])
15830
15831 (define_insn "rep_movsi_rex64"
15832 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15833 (set (match_operand:DI 0 "register_operand" "=D")
15834 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15835 (const_int 2))
15836 (match_operand:DI 3 "register_operand" "0")))
15837 (set (match_operand:DI 1 "register_operand" "=S")
15838 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15839 (match_operand:DI 4 "register_operand" "1")))
15840 (set (mem:BLK (match_dup 3))
15841 (mem:BLK (match_dup 4)))
15842 (use (match_dup 5))
15843 (use (reg:SI 19))]
15844 "TARGET_64BIT"
15845 "{rep\;movsl|rep movsd}"
15846 [(set_attr "type" "str")
15847 (set_attr "prefix_rep" "1")
15848 (set_attr "memory" "both")
15849 (set_attr "mode" "SI")])
15850
15851 (define_insn "rep_movqi"
15852 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15853 (set (match_operand:SI 0 "register_operand" "=D")
15854 (plus:SI (match_operand:SI 3 "register_operand" "0")
15855 (match_operand:SI 5 "register_operand" "2")))
15856 (set (match_operand:SI 1 "register_operand" "=S")
15857 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15858 (set (mem:BLK (match_dup 3))
15859 (mem:BLK (match_dup 4)))
15860 (use (match_dup 5))
15861 (use (reg:SI 19))]
15862 "!TARGET_64BIT"
15863 "{rep\;movsb|rep movsb}"
15864 [(set_attr "type" "str")
15865 (set_attr "prefix_rep" "1")
15866 (set_attr "memory" "both")
15867 (set_attr "mode" "SI")])
15868
15869 (define_insn "rep_movqi_rex64"
15870 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15871 (set (match_operand:DI 0 "register_operand" "=D")
15872 (plus:DI (match_operand:DI 3 "register_operand" "0")
15873 (match_operand:DI 5 "register_operand" "2")))
15874 (set (match_operand:DI 1 "register_operand" "=S")
15875 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15876 (set (mem:BLK (match_dup 3))
15877 (mem:BLK (match_dup 4)))
15878 (use (match_dup 5))
15879 (use (reg:SI 19))]
15880 "TARGET_64BIT"
15881 "{rep\;movsb|rep movsb}"
15882 [(set_attr "type" "str")
15883 (set_attr "prefix_rep" "1")
15884 (set_attr "memory" "both")
15885 (set_attr "mode" "SI")])
15886
15887 (define_expand "clrstrsi"
15888 [(use (match_operand:BLK 0 "memory_operand" ""))
15889 (use (match_operand:SI 1 "nonmemory_operand" ""))
15890 (use (match_operand 2 "const_int_operand" ""))]
15891 ""
15892 {
15893 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15894 DONE;
15895 else
15896 FAIL;
15897 })
15898
15899 (define_expand "clrstrdi"
15900 [(use (match_operand:BLK 0 "memory_operand" ""))
15901 (use (match_operand:DI 1 "nonmemory_operand" ""))
15902 (use (match_operand 2 "const_int_operand" ""))]
15903 "TARGET_64BIT"
15904 {
15905 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15906 DONE;
15907 else
15908 FAIL;
15909 })
15910
15911 ;; Most CPUs don't like single string operations
15912 ;; Handle this case here to simplify previous expander.
15913
15914 (define_expand "strsetdi_rex64"
15915 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15916 (match_operand:DI 1 "register_operand" ""))
15917 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15918 (clobber (reg:CC 17))])]
15919 "TARGET_64BIT"
15920 {
15921 if (TARGET_SINGLE_STRINGOP || optimize_size)
15922 {
15923 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15924 DONE;
15925 }
15926 })
15927
15928 (define_expand "strsetsi"
15929 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15930 (match_operand:SI 1 "register_operand" ""))
15931 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15932 (clobber (reg:CC 17))])]
15933 ""
15934 {
15935 if (TARGET_64BIT)
15936 {
15937 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15938 DONE;
15939 }
15940 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15941 {
15942 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15943 DONE;
15944 }
15945 })
15946
15947 (define_expand "strsetsi_rex64"
15948 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15949 (match_operand:SI 1 "register_operand" ""))
15950 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15951 (clobber (reg:CC 17))])]
15952 "TARGET_64BIT"
15953 {
15954 if (TARGET_SINGLE_STRINGOP || optimize_size)
15955 {
15956 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15957 DONE;
15958 }
15959 })
15960
15961 (define_expand "strsethi"
15962 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15963 (match_operand:HI 1 "register_operand" ""))
15964 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15965 (clobber (reg:CC 17))])]
15966 ""
15967 {
15968 if (TARGET_64BIT)
15969 {
15970 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15971 DONE;
15972 }
15973 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15974 {
15975 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15976 DONE;
15977 }
15978 })
15979
15980 (define_expand "strsethi_rex64"
15981 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15982 (match_operand:HI 1 "register_operand" ""))
15983 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15984 (clobber (reg:CC 17))])]
15985 "TARGET_64BIT"
15986 {
15987 if (TARGET_SINGLE_STRINGOP || optimize_size)
15988 {
15989 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15990 DONE;
15991 }
15992 })
15993
15994 (define_expand "strsetqi"
15995 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15996 (match_operand:QI 1 "register_operand" ""))
15997 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15998 (clobber (reg:CC 17))])]
15999 ""
16000 {
16001 if (TARGET_64BIT)
16002 {
16003 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16004 DONE;
16005 }
16006 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16007 {
16008 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16009 DONE;
16010 }
16011 })
16012
16013 (define_expand "strsetqi_rex64"
16014 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16015 (match_operand:QI 1 "register_operand" ""))
16016 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16017 (clobber (reg:CC 17))])]
16018 "TARGET_64BIT"
16019 {
16020 if (TARGET_SINGLE_STRINGOP || optimize_size)
16021 {
16022 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16023 DONE;
16024 }
16025 })
16026
16027 (define_insn "strsetdi_rex_1"
16028 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16029 (match_operand:SI 2 "register_operand" "a"))
16030 (set (match_operand:DI 0 "register_operand" "=D")
16031 (plus:DI (match_dup 1)
16032 (const_int 8)))
16033 (use (reg:SI 19))]
16034 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16035 "stosq"
16036 [(set_attr "type" "str")
16037 (set_attr "memory" "store")
16038 (set_attr "mode" "DI")])
16039
16040 (define_insn "strsetsi_1"
16041 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16042 (match_operand:SI 2 "register_operand" "a"))
16043 (set (match_operand:SI 0 "register_operand" "=D")
16044 (plus:SI (match_dup 1)
16045 (const_int 4)))
16046 (use (reg:SI 19))]
16047 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16048 "{stosl|stosd}"
16049 [(set_attr "type" "str")
16050 (set_attr "memory" "store")
16051 (set_attr "mode" "SI")])
16052
16053 (define_insn "strsetsi_rex_1"
16054 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16055 (match_operand:SI 2 "register_operand" "a"))
16056 (set (match_operand:DI 0 "register_operand" "=D")
16057 (plus:DI (match_dup 1)
16058 (const_int 4)))
16059 (use (reg:SI 19))]
16060 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16061 "{stosl|stosd}"
16062 [(set_attr "type" "str")
16063 (set_attr "memory" "store")
16064 (set_attr "mode" "SI")])
16065
16066 (define_insn "strsethi_1"
16067 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16068 (match_operand:HI 2 "register_operand" "a"))
16069 (set (match_operand:SI 0 "register_operand" "=D")
16070 (plus:SI (match_dup 1)
16071 (const_int 2)))
16072 (use (reg:SI 19))]
16073 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16074 "stosw"
16075 [(set_attr "type" "str")
16076 (set_attr "memory" "store")
16077 (set_attr "mode" "HI")])
16078
16079 (define_insn "strsethi_rex_1"
16080 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16081 (match_operand:HI 2 "register_operand" "a"))
16082 (set (match_operand:DI 0 "register_operand" "=D")
16083 (plus:DI (match_dup 1)
16084 (const_int 2)))
16085 (use (reg:SI 19))]
16086 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16087 "stosw"
16088 [(set_attr "type" "str")
16089 (set_attr "memory" "store")
16090 (set_attr "mode" "HI")])
16091
16092 (define_insn "strsetqi_1"
16093 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16094 (match_operand:QI 2 "register_operand" "a"))
16095 (set (match_operand:SI 0 "register_operand" "=D")
16096 (plus:SI (match_dup 1)
16097 (const_int 1)))
16098 (use (reg:SI 19))]
16099 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16100 "stosb"
16101 [(set_attr "type" "str")
16102 (set_attr "memory" "store")
16103 (set_attr "mode" "QI")])
16104
16105 (define_insn "strsetqi_rex_1"
16106 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16107 (match_operand:QI 2 "register_operand" "a"))
16108 (set (match_operand:DI 0 "register_operand" "=D")
16109 (plus:DI (match_dup 1)
16110 (const_int 1)))
16111 (use (reg:SI 19))]
16112 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16113 "stosb"
16114 [(set_attr "type" "str")
16115 (set_attr "memory" "store")
16116 (set_attr "mode" "QI")])
16117
16118 (define_insn "rep_stosdi_rex64"
16119 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16120 (set (match_operand:DI 0 "register_operand" "=D")
16121 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16122 (const_int 3))
16123 (match_operand:DI 3 "register_operand" "0")))
16124 (set (mem:BLK (match_dup 3))
16125 (const_int 0))
16126 (use (match_operand:DI 2 "register_operand" "a"))
16127 (use (match_dup 4))
16128 (use (reg:SI 19))]
16129 "TARGET_64BIT"
16130 "{rep\;stosq|rep stosq}"
16131 [(set_attr "type" "str")
16132 (set_attr "prefix_rep" "1")
16133 (set_attr "memory" "store")
16134 (set_attr "mode" "DI")])
16135
16136 (define_insn "rep_stossi"
16137 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16138 (set (match_operand:SI 0 "register_operand" "=D")
16139 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16140 (const_int 2))
16141 (match_operand:SI 3 "register_operand" "0")))
16142 (set (mem:BLK (match_dup 3))
16143 (const_int 0))
16144 (use (match_operand:SI 2 "register_operand" "a"))
16145 (use (match_dup 4))
16146 (use (reg:SI 19))]
16147 "!TARGET_64BIT"
16148 "{rep\;stosl|rep stosd}"
16149 [(set_attr "type" "str")
16150 (set_attr "prefix_rep" "1")
16151 (set_attr "memory" "store")
16152 (set_attr "mode" "SI")])
16153
16154 (define_insn "rep_stossi_rex64"
16155 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16156 (set (match_operand:DI 0 "register_operand" "=D")
16157 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16158 (const_int 2))
16159 (match_operand:DI 3 "register_operand" "0")))
16160 (set (mem:BLK (match_dup 3))
16161 (const_int 0))
16162 (use (match_operand:SI 2 "register_operand" "a"))
16163 (use (match_dup 4))
16164 (use (reg:SI 19))]
16165 "TARGET_64BIT"
16166 "{rep\;stosl|rep stosd}"
16167 [(set_attr "type" "str")
16168 (set_attr "prefix_rep" "1")
16169 (set_attr "memory" "store")
16170 (set_attr "mode" "SI")])
16171
16172 (define_insn "rep_stosqi"
16173 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16174 (set (match_operand:SI 0 "register_operand" "=D")
16175 (plus:SI (match_operand:SI 3 "register_operand" "0")
16176 (match_operand:SI 4 "register_operand" "1")))
16177 (set (mem:BLK (match_dup 3))
16178 (const_int 0))
16179 (use (match_operand:QI 2 "register_operand" "a"))
16180 (use (match_dup 4))
16181 (use (reg:SI 19))]
16182 "!TARGET_64BIT"
16183 "{rep\;stosb|rep stosb}"
16184 [(set_attr "type" "str")
16185 (set_attr "prefix_rep" "1")
16186 (set_attr "memory" "store")
16187 (set_attr "mode" "QI")])
16188
16189 (define_insn "rep_stosqi_rex64"
16190 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16191 (set (match_operand:DI 0 "register_operand" "=D")
16192 (plus:DI (match_operand:DI 3 "register_operand" "0")
16193 (match_operand:DI 4 "register_operand" "1")))
16194 (set (mem:BLK (match_dup 3))
16195 (const_int 0))
16196 (use (match_operand:QI 2 "register_operand" "a"))
16197 (use (match_dup 4))
16198 (use (reg:DI 19))]
16199 "TARGET_64BIT"
16200 "{rep\;stosb|rep stosb}"
16201 [(set_attr "type" "str")
16202 (set_attr "prefix_rep" "1")
16203 (set_attr "memory" "store")
16204 (set_attr "mode" "QI")])
16205
16206 (define_expand "cmpstrsi"
16207 [(set (match_operand:SI 0 "register_operand" "")
16208 (compare:SI (match_operand:BLK 1 "general_operand" "")
16209 (match_operand:BLK 2 "general_operand" "")))
16210 (use (match_operand 3 "general_operand" ""))
16211 (use (match_operand 4 "immediate_operand" ""))]
16212 ""
16213 {
16214 rtx addr1, addr2, out, outlow, count, countreg, align;
16215
16216 /* Can't use this if the user has appropriated esi or edi. */
16217 if (global_regs[4] || global_regs[5])
16218 FAIL;
16219
16220 out = operands[0];
16221 if (GET_CODE (out) != REG)
16222 out = gen_reg_rtx (SImode);
16223
16224 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16225 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16226
16227 count = operands[3];
16228 countreg = ix86_zero_extend_to_Pmode (count);
16229
16230 /* %%% Iff we are testing strict equality, we can use known alignment
16231 to good advantage. This may be possible with combine, particularly
16232 once cc0 is dead. */
16233 align = operands[4];
16234
16235 emit_insn (gen_cld ());
16236 if (GET_CODE (count) == CONST_INT)
16237 {
16238 if (INTVAL (count) == 0)
16239 {
16240 emit_move_insn (operands[0], const0_rtx);
16241 DONE;
16242 }
16243 if (TARGET_64BIT)
16244 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16245 addr1, addr2, countreg));
16246 else
16247 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16248 addr1, addr2, countreg));
16249 }
16250 else
16251 {
16252 if (TARGET_64BIT)
16253 {
16254 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16255 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16256 addr1, addr2, countreg));
16257 }
16258 else
16259 {
16260 emit_insn (gen_cmpsi_1 (countreg, countreg));
16261 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16262 addr1, addr2, countreg));
16263 }
16264 }
16265
16266 outlow = gen_lowpart (QImode, out);
16267 emit_insn (gen_cmpintqi (outlow));
16268 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16269
16270 if (operands[0] != out)
16271 emit_move_insn (operands[0], out);
16272
16273 DONE;
16274 })
16275
16276 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16277
16278 (define_expand "cmpintqi"
16279 [(set (match_dup 1)
16280 (gtu:QI (reg:CC 17) (const_int 0)))
16281 (set (match_dup 2)
16282 (ltu:QI (reg:CC 17) (const_int 0)))
16283 (parallel [(set (match_operand:QI 0 "register_operand" "")
16284 (minus:QI (match_dup 1)
16285 (match_dup 2)))
16286 (clobber (reg:CC 17))])]
16287 ""
16288 "operands[1] = gen_reg_rtx (QImode);
16289 operands[2] = gen_reg_rtx (QImode);")
16290
16291 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16292 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16293
16294 (define_insn "cmpstrqi_nz_1"
16295 [(set (reg:CC 17)
16296 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16297 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16298 (use (match_operand:SI 6 "register_operand" "2"))
16299 (use (match_operand:SI 3 "immediate_operand" "i"))
16300 (use (reg:SI 19))
16301 (clobber (match_operand:SI 0 "register_operand" "=S"))
16302 (clobber (match_operand:SI 1 "register_operand" "=D"))
16303 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16304 "!TARGET_64BIT"
16305 "repz{\;| }cmpsb"
16306 [(set_attr "type" "str")
16307 (set_attr "mode" "QI")
16308 (set_attr "prefix_rep" "1")])
16309
16310 (define_insn "cmpstrqi_nz_rex_1"
16311 [(set (reg:CC 17)
16312 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16313 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16314 (use (match_operand:DI 6 "register_operand" "2"))
16315 (use (match_operand:SI 3 "immediate_operand" "i"))
16316 (use (reg:SI 19))
16317 (clobber (match_operand:DI 0 "register_operand" "=S"))
16318 (clobber (match_operand:DI 1 "register_operand" "=D"))
16319 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16320 "TARGET_64BIT"
16321 "repz{\;| }cmpsb"
16322 [(set_attr "type" "str")
16323 (set_attr "mode" "QI")
16324 (set_attr "prefix_rep" "1")])
16325
16326 ;; The same, but the count is not known to not be zero.
16327
16328 (define_insn "cmpstrqi_1"
16329 [(set (reg:CC 17)
16330 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16331 (const_int 0))
16332 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16333 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16334 (const_int 0)))
16335 (use (match_operand:SI 3 "immediate_operand" "i"))
16336 (use (reg:CC 17))
16337 (use (reg:SI 19))
16338 (clobber (match_operand:SI 0 "register_operand" "=S"))
16339 (clobber (match_operand:SI 1 "register_operand" "=D"))
16340 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16341 "!TARGET_64BIT"
16342 "repz{\;| }cmpsb"
16343 [(set_attr "type" "str")
16344 (set_attr "mode" "QI")
16345 (set_attr "prefix_rep" "1")])
16346
16347 (define_insn "cmpstrqi_rex_1"
16348 [(set (reg:CC 17)
16349 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16350 (const_int 0))
16351 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16352 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16353 (const_int 0)))
16354 (use (match_operand:SI 3 "immediate_operand" "i"))
16355 (use (reg:CC 17))
16356 (use (reg:SI 19))
16357 (clobber (match_operand:DI 0 "register_operand" "=S"))
16358 (clobber (match_operand:DI 1 "register_operand" "=D"))
16359 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16360 "TARGET_64BIT"
16361 "repz{\;| }cmpsb"
16362 [(set_attr "type" "str")
16363 (set_attr "mode" "QI")
16364 (set_attr "prefix_rep" "1")])
16365
16366 (define_expand "strlensi"
16367 [(set (match_operand:SI 0 "register_operand" "")
16368 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16369 (match_operand:QI 2 "immediate_operand" "")
16370 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16371 ""
16372 {
16373 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16374 DONE;
16375 else
16376 FAIL;
16377 })
16378
16379 (define_expand "strlendi"
16380 [(set (match_operand:DI 0 "register_operand" "")
16381 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16382 (match_operand:QI 2 "immediate_operand" "")
16383 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16384 ""
16385 {
16386 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16387 DONE;
16388 else
16389 FAIL;
16390 })
16391
16392 (define_insn "strlenqi_1"
16393 [(set (match_operand:SI 0 "register_operand" "=&c")
16394 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16395 (match_operand:QI 2 "register_operand" "a")
16396 (match_operand:SI 3 "immediate_operand" "i")
16397 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16398 (use (reg:SI 19))
16399 (clobber (match_operand:SI 1 "register_operand" "=D"))
16400 (clobber (reg:CC 17))]
16401 "!TARGET_64BIT"
16402 "repnz{\;| }scasb"
16403 [(set_attr "type" "str")
16404 (set_attr "mode" "QI")
16405 (set_attr "prefix_rep" "1")])
16406
16407 (define_insn "strlenqi_rex_1"
16408 [(set (match_operand:DI 0 "register_operand" "=&c")
16409 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16410 (match_operand:QI 2 "register_operand" "a")
16411 (match_operand:DI 3 "immediate_operand" "i")
16412 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16413 (use (reg:SI 19))
16414 (clobber (match_operand:DI 1 "register_operand" "=D"))
16415 (clobber (reg:CC 17))]
16416 "TARGET_64BIT"
16417 "repnz{\;| }scasb"
16418 [(set_attr "type" "str")
16419 (set_attr "mode" "QI")
16420 (set_attr "prefix_rep" "1")])
16421
16422 ;; Peephole optimizations to clean up after cmpstr*. This should be
16423 ;; handled in combine, but it is not currently up to the task.
16424 ;; When used for their truth value, the cmpstr* expanders generate
16425 ;; code like this:
16426 ;;
16427 ;; repz cmpsb
16428 ;; seta %al
16429 ;; setb %dl
16430 ;; cmpb %al, %dl
16431 ;; jcc label
16432 ;;
16433 ;; The intermediate three instructions are unnecessary.
16434
16435 ;; This one handles cmpstr*_nz_1...
16436 (define_peephole2
16437 [(parallel[
16438 (set (reg:CC 17)
16439 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16440 (mem:BLK (match_operand 5 "register_operand" ""))))
16441 (use (match_operand 6 "register_operand" ""))
16442 (use (match_operand:SI 3 "immediate_operand" ""))
16443 (use (reg:SI 19))
16444 (clobber (match_operand 0 "register_operand" ""))
16445 (clobber (match_operand 1 "register_operand" ""))
16446 (clobber (match_operand 2 "register_operand" ""))])
16447 (set (match_operand:QI 7 "register_operand" "")
16448 (gtu:QI (reg:CC 17) (const_int 0)))
16449 (set (match_operand:QI 8 "register_operand" "")
16450 (ltu:QI (reg:CC 17) (const_int 0)))
16451 (set (reg 17)
16452 (compare (match_dup 7) (match_dup 8)))
16453 ]
16454 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16455 [(parallel[
16456 (set (reg:CC 17)
16457 (compare:CC (mem:BLK (match_dup 4))
16458 (mem:BLK (match_dup 5))))
16459 (use (match_dup 6))
16460 (use (match_dup 3))
16461 (use (reg:SI 19))
16462 (clobber (match_dup 0))
16463 (clobber (match_dup 1))
16464 (clobber (match_dup 2))])]
16465 "")
16466
16467 ;; ...and this one handles cmpstr*_1.
16468 (define_peephole2
16469 [(parallel[
16470 (set (reg:CC 17)
16471 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16472 (const_int 0))
16473 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16474 (mem:BLK (match_operand 5 "register_operand" "")))
16475 (const_int 0)))
16476 (use (match_operand:SI 3 "immediate_operand" ""))
16477 (use (reg:CC 17))
16478 (use (reg:SI 19))
16479 (clobber (match_operand 0 "register_operand" ""))
16480 (clobber (match_operand 1 "register_operand" ""))
16481 (clobber (match_operand 2 "register_operand" ""))])
16482 (set (match_operand:QI 7 "register_operand" "")
16483 (gtu:QI (reg:CC 17) (const_int 0)))
16484 (set (match_operand:QI 8 "register_operand" "")
16485 (ltu:QI (reg:CC 17) (const_int 0)))
16486 (set (reg 17)
16487 (compare (match_dup 7) (match_dup 8)))
16488 ]
16489 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16490 [(parallel[
16491 (set (reg:CC 17)
16492 (if_then_else:CC (ne (match_dup 6)
16493 (const_int 0))
16494 (compare:CC (mem:BLK (match_dup 4))
16495 (mem:BLK (match_dup 5)))
16496 (const_int 0)))
16497 (use (match_dup 3))
16498 (use (reg:CC 17))
16499 (use (reg:SI 19))
16500 (clobber (match_dup 0))
16501 (clobber (match_dup 1))
16502 (clobber (match_dup 2))])]
16503 "")
16504
16505
16506 \f
16507 ;; Conditional move instructions.
16508
16509 (define_expand "movdicc"
16510 [(set (match_operand:DI 0 "register_operand" "")
16511 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16512 (match_operand:DI 2 "general_operand" "")
16513 (match_operand:DI 3 "general_operand" "")))]
16514 "TARGET_64BIT"
16515 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16516
16517 (define_insn "x86_movdicc_0_m1_rex64"
16518 [(set (match_operand:DI 0 "register_operand" "=r")
16519 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16520 (const_int -1)
16521 (const_int 0)))
16522 (clobber (reg:CC 17))]
16523 "TARGET_64BIT"
16524 "sbb{q}\t%0, %0"
16525 ; Since we don't have the proper number of operands for an alu insn,
16526 ; fill in all the blanks.
16527 [(set_attr "type" "alu")
16528 (set_attr "pent_pair" "pu")
16529 (set_attr "memory" "none")
16530 (set_attr "imm_disp" "false")
16531 (set_attr "mode" "DI")
16532 (set_attr "length_immediate" "0")])
16533
16534 (define_insn "movdicc_c_rex64"
16535 [(set (match_operand:DI 0 "register_operand" "=r,r")
16536 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16537 [(reg 17) (const_int 0)])
16538 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16539 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16540 "TARGET_64BIT && TARGET_CMOVE
16541 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16542 "@
16543 cmov%O2%C1\t{%2, %0|%0, %2}
16544 cmov%O2%c1\t{%3, %0|%0, %3}"
16545 [(set_attr "type" "icmov")
16546 (set_attr "mode" "DI")])
16547
16548 (define_expand "movsicc"
16549 [(set (match_operand:SI 0 "register_operand" "")
16550 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16551 (match_operand:SI 2 "general_operand" "")
16552 (match_operand:SI 3 "general_operand" "")))]
16553 ""
16554 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16555
16556 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16557 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16558 ;; So just document what we're doing explicitly.
16559
16560 (define_insn "x86_movsicc_0_m1"
16561 [(set (match_operand:SI 0 "register_operand" "=r")
16562 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16563 (const_int -1)
16564 (const_int 0)))
16565 (clobber (reg:CC 17))]
16566 ""
16567 "sbb{l}\t%0, %0"
16568 ; Since we don't have the proper number of operands for an alu insn,
16569 ; fill in all the blanks.
16570 [(set_attr "type" "alu")
16571 (set_attr "pent_pair" "pu")
16572 (set_attr "memory" "none")
16573 (set_attr "imm_disp" "false")
16574 (set_attr "mode" "SI")
16575 (set_attr "length_immediate" "0")])
16576
16577 (define_insn "*movsicc_noc"
16578 [(set (match_operand:SI 0 "register_operand" "=r,r")
16579 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16580 [(reg 17) (const_int 0)])
16581 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16582 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16583 "TARGET_CMOVE
16584 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16585 "@
16586 cmov%O2%C1\t{%2, %0|%0, %2}
16587 cmov%O2%c1\t{%3, %0|%0, %3}"
16588 [(set_attr "type" "icmov")
16589 (set_attr "mode" "SI")])
16590
16591 (define_expand "movhicc"
16592 [(set (match_operand:HI 0 "register_operand" "")
16593 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16594 (match_operand:HI 2 "general_operand" "")
16595 (match_operand:HI 3 "general_operand" "")))]
16596 "TARGET_HIMODE_MATH"
16597 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16598
16599 (define_insn "*movhicc_noc"
16600 [(set (match_operand:HI 0 "register_operand" "=r,r")
16601 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16602 [(reg 17) (const_int 0)])
16603 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16604 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16605 "TARGET_CMOVE
16606 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16607 "@
16608 cmov%O2%C1\t{%2, %0|%0, %2}
16609 cmov%O2%c1\t{%3, %0|%0, %3}"
16610 [(set_attr "type" "icmov")
16611 (set_attr "mode" "HI")])
16612
16613 (define_expand "movqicc"
16614 [(set (match_operand:QI 0 "register_operand" "")
16615 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16616 (match_operand:QI 2 "general_operand" "")
16617 (match_operand:QI 3 "general_operand" "")))]
16618 "TARGET_QIMODE_MATH"
16619 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16620
16621 (define_insn_and_split "*movqicc_noc"
16622 [(set (match_operand:QI 0 "register_operand" "=r,r")
16623 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16624 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16625 (match_operand:QI 2 "register_operand" "r,0")
16626 (match_operand:QI 3 "register_operand" "0,r")))]
16627 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16628 "#"
16629 "&& reload_completed"
16630 [(set (match_dup 0)
16631 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16632 (match_dup 2)
16633 (match_dup 3)))]
16634 "operands[0] = gen_lowpart (SImode, operands[0]);
16635 operands[2] = gen_lowpart (SImode, operands[2]);
16636 operands[3] = gen_lowpart (SImode, operands[3]);"
16637 [(set_attr "type" "icmov")
16638 (set_attr "mode" "SI")])
16639
16640 (define_expand "movsfcc"
16641 [(set (match_operand:SF 0 "register_operand" "")
16642 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16643 (match_operand:SF 2 "register_operand" "")
16644 (match_operand:SF 3 "register_operand" "")))]
16645 "TARGET_CMOVE"
16646 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16647
16648 (define_insn "*movsfcc_1"
16649 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16650 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16651 [(reg 17) (const_int 0)])
16652 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16653 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16654 "TARGET_CMOVE
16655 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16656 "@
16657 fcmov%F1\t{%2, %0|%0, %2}
16658 fcmov%f1\t{%3, %0|%0, %3}
16659 cmov%O2%C1\t{%2, %0|%0, %2}
16660 cmov%O2%c1\t{%3, %0|%0, %3}"
16661 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16662 (set_attr "mode" "SF,SF,SI,SI")])
16663
16664 (define_expand "movdfcc"
16665 [(set (match_operand:DF 0 "register_operand" "")
16666 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16667 (match_operand:DF 2 "register_operand" "")
16668 (match_operand:DF 3 "register_operand" "")))]
16669 "TARGET_CMOVE"
16670 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16671
16672 (define_insn "*movdfcc_1"
16673 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16674 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16675 [(reg 17) (const_int 0)])
16676 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16677 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16678 "!TARGET_64BIT && TARGET_CMOVE
16679 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16680 "@
16681 fcmov%F1\t{%2, %0|%0, %2}
16682 fcmov%f1\t{%3, %0|%0, %3}
16683 #
16684 #"
16685 [(set_attr "type" "fcmov,fcmov,multi,multi")
16686 (set_attr "mode" "DF")])
16687
16688 (define_insn "*movdfcc_1_rex64"
16689 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16690 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16691 [(reg 17) (const_int 0)])
16692 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16693 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16694 "TARGET_64BIT && TARGET_CMOVE
16695 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16696 "@
16697 fcmov%F1\t{%2, %0|%0, %2}
16698 fcmov%f1\t{%3, %0|%0, %3}
16699 cmov%O2%C1\t{%2, %0|%0, %2}
16700 cmov%O2%c1\t{%3, %0|%0, %3}"
16701 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16702 (set_attr "mode" "DF")])
16703
16704 (define_split
16705 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16706 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16707 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16708 (match_operand:DF 2 "nonimmediate_operand" "")
16709 (match_operand:DF 3 "nonimmediate_operand" "")))]
16710 "!TARGET_64BIT && reload_completed"
16711 [(set (match_dup 2)
16712 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16713 (match_dup 5)
16714 (match_dup 7)))
16715 (set (match_dup 3)
16716 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16717 (match_dup 6)
16718 (match_dup 8)))]
16719 "split_di (operands+2, 1, operands+5, operands+6);
16720 split_di (operands+3, 1, operands+7, operands+8);
16721 split_di (operands, 1, operands+2, operands+3);")
16722
16723 (define_expand "movxfcc"
16724 [(set (match_operand:XF 0 "register_operand" "")
16725 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16726 (match_operand:XF 2 "register_operand" "")
16727 (match_operand:XF 3 "register_operand" "")))]
16728 "!TARGET_64BIT && TARGET_CMOVE"
16729 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16730
16731 (define_expand "movtfcc"
16732 [(set (match_operand:TF 0 "register_operand" "")
16733 (if_then_else:TF (match_operand 1 "comparison_operator" "")
16734 (match_operand:TF 2 "register_operand" "")
16735 (match_operand:TF 3 "register_operand" "")))]
16736 "TARGET_CMOVE"
16737 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16738
16739 (define_insn "*movxfcc_1"
16740 [(set (match_operand:XF 0 "register_operand" "=f,f")
16741 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16742 [(reg 17) (const_int 0)])
16743 (match_operand:XF 2 "register_operand" "f,0")
16744 (match_operand:XF 3 "register_operand" "0,f")))]
16745 "!TARGET_64BIT && TARGET_CMOVE"
16746 "@
16747 fcmov%F1\t{%2, %0|%0, %2}
16748 fcmov%f1\t{%3, %0|%0, %3}"
16749 [(set_attr "type" "fcmov")
16750 (set_attr "mode" "XF")])
16751
16752 (define_insn "*movtfcc_1"
16753 [(set (match_operand:TF 0 "register_operand" "=f,f")
16754 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
16755 [(reg 17) (const_int 0)])
16756 (match_operand:TF 2 "register_operand" "f,0")
16757 (match_operand:TF 3 "register_operand" "0,f")))]
16758 "TARGET_CMOVE"
16759 "@
16760 fcmov%F1\t{%2, %0|%0, %2}
16761 fcmov%f1\t{%3, %0|%0, %3}"
16762 [(set_attr "type" "fcmov")
16763 (set_attr "mode" "XF")])
16764
16765 (define_expand "minsf3"
16766 [(parallel [
16767 (set (match_operand:SF 0 "register_operand" "")
16768 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16769 (match_operand:SF 2 "nonimmediate_operand" ""))
16770 (match_dup 1)
16771 (match_dup 2)))
16772 (clobber (reg:CC 17))])]
16773 "TARGET_SSE"
16774 "")
16775
16776 (define_insn "*minsf"
16777 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16778 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16779 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16780 (match_dup 1)
16781 (match_dup 2)))
16782 (clobber (reg:CC 17))]
16783 "TARGET_SSE && TARGET_IEEE_FP"
16784 "#")
16785
16786 (define_insn "*minsf_nonieee"
16787 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16788 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16789 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16790 (match_dup 1)
16791 (match_dup 2)))
16792 (clobber (reg:CC 17))]
16793 "TARGET_SSE && !TARGET_IEEE_FP
16794 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16795 "#")
16796
16797 (define_split
16798 [(set (match_operand:SF 0 "register_operand" "")
16799 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16800 (match_operand:SF 2 "nonimmediate_operand" ""))
16801 (match_operand:SF 3 "register_operand" "")
16802 (match_operand:SF 4 "nonimmediate_operand" "")))
16803 (clobber (reg:CC 17))]
16804 "SSE_REG_P (operands[0]) && reload_completed
16805 && ((operands_match_p (operands[1], operands[3])
16806 && operands_match_p (operands[2], operands[4]))
16807 || (operands_match_p (operands[1], operands[4])
16808 && operands_match_p (operands[2], operands[3])))"
16809 [(set (match_dup 0)
16810 (if_then_else:SF (lt (match_dup 1)
16811 (match_dup 2))
16812 (match_dup 1)
16813 (match_dup 2)))])
16814
16815 ;; Conditional addition patterns
16816 (define_expand "addqicc"
16817 [(match_operand:QI 0 "register_operand" "")
16818 (match_operand 1 "comparison_operator" "")
16819 (match_operand:QI 2 "register_operand" "")
16820 (match_operand:QI 3 "const_int_operand" "")]
16821 ""
16822 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16823
16824 (define_expand "addhicc"
16825 [(match_operand:HI 0 "register_operand" "")
16826 (match_operand 1 "comparison_operator" "")
16827 (match_operand:HI 2 "register_operand" "")
16828 (match_operand:HI 3 "const_int_operand" "")]
16829 ""
16830 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16831
16832 (define_expand "addsicc"
16833 [(match_operand:SI 0 "register_operand" "")
16834 (match_operand 1 "comparison_operator" "")
16835 (match_operand:SI 2 "register_operand" "")
16836 (match_operand:SI 3 "const_int_operand" "")]
16837 ""
16838 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16839
16840 (define_expand "adddicc"
16841 [(match_operand:DI 0 "register_operand" "")
16842 (match_operand 1 "comparison_operator" "")
16843 (match_operand:DI 2 "register_operand" "")
16844 (match_operand:DI 3 "const_int_operand" "")]
16845 "TARGET_64BIT"
16846 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16847
16848 ;; We can't represent the LT test directly. Do this by swapping the operands.
16849
16850 (define_split
16851 [(set (match_operand:SF 0 "fp_register_operand" "")
16852 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16853 (match_operand:SF 2 "register_operand" ""))
16854 (match_operand:SF 3 "register_operand" "")
16855 (match_operand:SF 4 "register_operand" "")))
16856 (clobber (reg:CC 17))]
16857 "reload_completed
16858 && ((operands_match_p (operands[1], operands[3])
16859 && operands_match_p (operands[2], operands[4]))
16860 || (operands_match_p (operands[1], operands[4])
16861 && operands_match_p (operands[2], operands[3])))"
16862 [(set (reg:CCFP 17)
16863 (compare:CCFP (match_dup 2)
16864 (match_dup 1)))
16865 (set (match_dup 0)
16866 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16867 (match_dup 1)
16868 (match_dup 2)))])
16869
16870 (define_insn "*minsf_sse"
16871 [(set (match_operand:SF 0 "register_operand" "=x")
16872 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16873 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16874 (match_dup 1)
16875 (match_dup 2)))]
16876 "TARGET_SSE && reload_completed"
16877 "minss\t{%2, %0|%0, %2}"
16878 [(set_attr "type" "sse")
16879 (set_attr "mode" "SF")])
16880
16881 (define_expand "mindf3"
16882 [(parallel [
16883 (set (match_operand:DF 0 "register_operand" "")
16884 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16885 (match_operand:DF 2 "nonimmediate_operand" ""))
16886 (match_dup 1)
16887 (match_dup 2)))
16888 (clobber (reg:CC 17))])]
16889 "TARGET_SSE2 && TARGET_SSE_MATH"
16890 "#")
16891
16892 (define_insn "*mindf"
16893 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16894 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16895 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16896 (match_dup 1)
16897 (match_dup 2)))
16898 (clobber (reg:CC 17))]
16899 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16900 "#")
16901
16902 (define_insn "*mindf_nonieee"
16903 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16904 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16905 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16906 (match_dup 1)
16907 (match_dup 2)))
16908 (clobber (reg:CC 17))]
16909 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16910 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16911 "#")
16912
16913 (define_split
16914 [(set (match_operand:DF 0 "register_operand" "")
16915 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16916 (match_operand:DF 2 "nonimmediate_operand" ""))
16917 (match_operand:DF 3 "register_operand" "")
16918 (match_operand:DF 4 "nonimmediate_operand" "")))
16919 (clobber (reg:CC 17))]
16920 "SSE_REG_P (operands[0]) && reload_completed
16921 && ((operands_match_p (operands[1], operands[3])
16922 && operands_match_p (operands[2], operands[4]))
16923 || (operands_match_p (operands[1], operands[4])
16924 && operands_match_p (operands[2], operands[3])))"
16925 [(set (match_dup 0)
16926 (if_then_else:DF (lt (match_dup 1)
16927 (match_dup 2))
16928 (match_dup 1)
16929 (match_dup 2)))])
16930
16931 ;; We can't represent the LT test directly. Do this by swapping the operands.
16932 (define_split
16933 [(set (match_operand:DF 0 "fp_register_operand" "")
16934 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16935 (match_operand:DF 2 "register_operand" ""))
16936 (match_operand:DF 3 "register_operand" "")
16937 (match_operand:DF 4 "register_operand" "")))
16938 (clobber (reg:CC 17))]
16939 "reload_completed
16940 && ((operands_match_p (operands[1], operands[3])
16941 && operands_match_p (operands[2], operands[4]))
16942 || (operands_match_p (operands[1], operands[4])
16943 && operands_match_p (operands[2], operands[3])))"
16944 [(set (reg:CCFP 17)
16945 (compare:CCFP (match_dup 2)
16946 (match_dup 2)))
16947 (set (match_dup 0)
16948 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16949 (match_dup 1)
16950 (match_dup 2)))])
16951
16952 (define_insn "*mindf_sse"
16953 [(set (match_operand:DF 0 "register_operand" "=Y")
16954 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16955 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16956 (match_dup 1)
16957 (match_dup 2)))]
16958 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16959 "minsd\t{%2, %0|%0, %2}"
16960 [(set_attr "type" "sse")
16961 (set_attr "mode" "DF")])
16962
16963 (define_expand "maxsf3"
16964 [(parallel [
16965 (set (match_operand:SF 0 "register_operand" "")
16966 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16967 (match_operand:SF 2 "nonimmediate_operand" ""))
16968 (match_dup 1)
16969 (match_dup 2)))
16970 (clobber (reg:CC 17))])]
16971 "TARGET_SSE"
16972 "#")
16973
16974 (define_insn "*maxsf"
16975 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16976 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16977 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16978 (match_dup 1)
16979 (match_dup 2)))
16980 (clobber (reg:CC 17))]
16981 "TARGET_SSE && TARGET_IEEE_FP"
16982 "#")
16983
16984 (define_insn "*maxsf_nonieee"
16985 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16986 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16987 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16988 (match_dup 1)
16989 (match_dup 2)))
16990 (clobber (reg:CC 17))]
16991 "TARGET_SSE && !TARGET_IEEE_FP
16992 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16993 "#")
16994
16995 (define_split
16996 [(set (match_operand:SF 0 "register_operand" "")
16997 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16998 (match_operand:SF 2 "nonimmediate_operand" ""))
16999 (match_operand:SF 3 "register_operand" "")
17000 (match_operand:SF 4 "nonimmediate_operand" "")))
17001 (clobber (reg:CC 17))]
17002 "SSE_REG_P (operands[0]) && reload_completed
17003 && ((operands_match_p (operands[1], operands[3])
17004 && operands_match_p (operands[2], operands[4]))
17005 || (operands_match_p (operands[1], operands[4])
17006 && operands_match_p (operands[2], operands[3])))"
17007 [(set (match_dup 0)
17008 (if_then_else:SF (gt (match_dup 1)
17009 (match_dup 2))
17010 (match_dup 1)
17011 (match_dup 2)))])
17012
17013 (define_split
17014 [(set (match_operand:SF 0 "fp_register_operand" "")
17015 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17016 (match_operand:SF 2 "register_operand" ""))
17017 (match_operand:SF 3 "register_operand" "")
17018 (match_operand:SF 4 "register_operand" "")))
17019 (clobber (reg:CC 17))]
17020 "reload_completed
17021 && ((operands_match_p (operands[1], operands[3])
17022 && operands_match_p (operands[2], operands[4]))
17023 || (operands_match_p (operands[1], operands[4])
17024 && operands_match_p (operands[2], operands[3])))"
17025 [(set (reg:CCFP 17)
17026 (compare:CCFP (match_dup 1)
17027 (match_dup 2)))
17028 (set (match_dup 0)
17029 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17030 (match_dup 1)
17031 (match_dup 2)))])
17032
17033 (define_insn "*maxsf_sse"
17034 [(set (match_operand:SF 0 "register_operand" "=x")
17035 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17036 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17037 (match_dup 1)
17038 (match_dup 2)))]
17039 "TARGET_SSE && reload_completed"
17040 "maxss\t{%2, %0|%0, %2}"
17041 [(set_attr "type" "sse")
17042 (set_attr "mode" "SF")])
17043
17044 (define_expand "maxdf3"
17045 [(parallel [
17046 (set (match_operand:DF 0 "register_operand" "")
17047 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17048 (match_operand:DF 2 "nonimmediate_operand" ""))
17049 (match_dup 1)
17050 (match_dup 2)))
17051 (clobber (reg:CC 17))])]
17052 "TARGET_SSE2 && TARGET_SSE_MATH"
17053 "#")
17054
17055 (define_insn "*maxdf"
17056 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17057 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17058 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17059 (match_dup 1)
17060 (match_dup 2)))
17061 (clobber (reg:CC 17))]
17062 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17063 "#")
17064
17065 (define_insn "*maxdf_nonieee"
17066 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17067 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17068 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17069 (match_dup 1)
17070 (match_dup 2)))
17071 (clobber (reg:CC 17))]
17072 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17073 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17074 "#")
17075
17076 (define_split
17077 [(set (match_operand:DF 0 "register_operand" "")
17078 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17079 (match_operand:DF 2 "nonimmediate_operand" ""))
17080 (match_operand:DF 3 "register_operand" "")
17081 (match_operand:DF 4 "nonimmediate_operand" "")))
17082 (clobber (reg:CC 17))]
17083 "SSE_REG_P (operands[0]) && reload_completed
17084 && ((operands_match_p (operands[1], operands[3])
17085 && operands_match_p (operands[2], operands[4]))
17086 || (operands_match_p (operands[1], operands[4])
17087 && operands_match_p (operands[2], operands[3])))"
17088 [(set (match_dup 0)
17089 (if_then_else:DF (gt (match_dup 1)
17090 (match_dup 2))
17091 (match_dup 1)
17092 (match_dup 2)))])
17093
17094 (define_split
17095 [(set (match_operand:DF 0 "fp_register_operand" "")
17096 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17097 (match_operand:DF 2 "register_operand" ""))
17098 (match_operand:DF 3 "register_operand" "")
17099 (match_operand:DF 4 "register_operand" "")))
17100 (clobber (reg:CC 17))]
17101 "reload_completed
17102 && ((operands_match_p (operands[1], operands[3])
17103 && operands_match_p (operands[2], operands[4]))
17104 || (operands_match_p (operands[1], operands[4])
17105 && operands_match_p (operands[2], operands[3])))"
17106 [(set (reg:CCFP 17)
17107 (compare:CCFP (match_dup 1)
17108 (match_dup 2)))
17109 (set (match_dup 0)
17110 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17111 (match_dup 1)
17112 (match_dup 2)))])
17113
17114 (define_insn "*maxdf_sse"
17115 [(set (match_operand:DF 0 "register_operand" "=Y")
17116 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17117 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17118 (match_dup 1)
17119 (match_dup 2)))]
17120 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17121 "maxsd\t{%2, %0|%0, %2}"
17122 [(set_attr "type" "sse")
17123 (set_attr "mode" "DF")])
17124 \f
17125 ;; Misc patterns (?)
17126
17127 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17128 ;; Otherwise there will be nothing to keep
17129 ;;
17130 ;; [(set (reg ebp) (reg esp))]
17131 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17132 ;; (clobber (eflags)]
17133 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17134 ;;
17135 ;; in proper program order.
17136 (define_expand "pro_epilogue_adjust_stack"
17137 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17138 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17139 (match_operand:SI 2 "immediate_operand" "i,i")))
17140 (clobber (reg:CC 17))
17141 (clobber (mem:BLK (scratch)))])]
17142 ""
17143 {
17144 if (TARGET_64BIT)
17145 {
17146 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17147 (operands[0], operands[1], operands[2]));
17148 DONE;
17149 }
17150 })
17151
17152 (define_insn "*pro_epilogue_adjust_stack_1"
17153 [(set (match_operand:SI 0 "register_operand" "=r,r")
17154 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17155 (match_operand:SI 2 "immediate_operand" "i,i")))
17156 (clobber (reg:CC 17))
17157 (clobber (mem:BLK (scratch)))]
17158 "!TARGET_64BIT"
17159 {
17160 switch (get_attr_type (insn))
17161 {
17162 case TYPE_IMOV:
17163 return "mov{l}\t{%1, %0|%0, %1}";
17164
17165 case TYPE_ALU:
17166 if (GET_CODE (operands[2]) == CONST_INT
17167 && (INTVAL (operands[2]) == 128
17168 || (INTVAL (operands[2]) < 0
17169 && INTVAL (operands[2]) != -128)))
17170 {
17171 operands[2] = GEN_INT (-INTVAL (operands[2]));
17172 return "sub{l}\t{%2, %0|%0, %2}";
17173 }
17174 return "add{l}\t{%2, %0|%0, %2}";
17175
17176 case TYPE_LEA:
17177 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17178 return "lea{l}\t{%a2, %0|%0, %a2}";
17179
17180 default:
17181 abort ();
17182 }
17183 }
17184 [(set (attr "type")
17185 (cond [(eq_attr "alternative" "0")
17186 (const_string "alu")
17187 (match_operand:SI 2 "const0_operand" "")
17188 (const_string "imov")
17189 ]
17190 (const_string "lea")))
17191 (set_attr "mode" "SI")])
17192
17193 (define_insn "pro_epilogue_adjust_stack_rex64"
17194 [(set (match_operand:DI 0 "register_operand" "=r,r")
17195 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17196 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17197 (clobber (reg:CC 17))
17198 (clobber (mem:BLK (scratch)))]
17199 "TARGET_64BIT"
17200 {
17201 switch (get_attr_type (insn))
17202 {
17203 case TYPE_IMOV:
17204 return "mov{q}\t{%1, %0|%0, %1}";
17205
17206 case TYPE_ALU:
17207 if (GET_CODE (operands[2]) == CONST_INT
17208 && (INTVAL (operands[2]) == 128
17209 || (INTVAL (operands[2]) < 0
17210 && INTVAL (operands[2]) != -128)))
17211 {
17212 operands[2] = GEN_INT (-INTVAL (operands[2]));
17213 return "sub{q}\t{%2, %0|%0, %2}";
17214 }
17215 return "add{q}\t{%2, %0|%0, %2}";
17216
17217 case TYPE_LEA:
17218 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17219 return "lea{q}\t{%a2, %0|%0, %a2}";
17220
17221 default:
17222 abort ();
17223 }
17224 }
17225 [(set (attr "type")
17226 (cond [(eq_attr "alternative" "0")
17227 (const_string "alu")
17228 (match_operand:DI 2 "const0_operand" "")
17229 (const_string "imov")
17230 ]
17231 (const_string "lea")))
17232 (set_attr "mode" "DI")])
17233
17234
17235 ;; Placeholder for the conditional moves. This one is split either to SSE
17236 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17237 ;; fact is that compares supported by the cmp??ss instructions are exactly
17238 ;; swapped of those supported by cmove sequence.
17239 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17240 ;; supported by i387 comparisons and we do need to emit two conditional moves
17241 ;; in tandem.
17242
17243 (define_insn "sse_movsfcc"
17244 [(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")
17245 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17246 [(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")
17247 (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")])
17248 (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")
17249 (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")))
17250 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17251 (clobber (reg:CC 17))]
17252 "TARGET_SSE
17253 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17254 /* Avoid combine from being smart and converting min/max
17255 instruction patterns into conditional moves. */
17256 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17257 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17258 || !rtx_equal_p (operands[4], operands[2])
17259 || !rtx_equal_p (operands[5], operands[3]))
17260 && (!TARGET_IEEE_FP
17261 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17262 "#")
17263
17264 (define_insn "sse_movsfcc_eq"
17265 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17266 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17267 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17268 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17269 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17270 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17271 (clobber (reg:CC 17))]
17272 "TARGET_SSE
17273 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17274 "#")
17275
17276 (define_insn "sse_movdfcc"
17277 [(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")
17278 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17279 [(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")
17280 (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")])
17281 (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")
17282 (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")))
17283 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17284 (clobber (reg:CC 17))]
17285 "TARGET_SSE2
17286 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17287 /* Avoid combine from being smart and converting min/max
17288 instruction patterns into conditional moves. */
17289 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17290 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17291 || !rtx_equal_p (operands[4], operands[2])
17292 || !rtx_equal_p (operands[5], operands[3]))
17293 && (!TARGET_IEEE_FP
17294 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17295 "#")
17296
17297 (define_insn "sse_movdfcc_eq"
17298 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17299 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17300 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17301 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17302 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17303 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17304 (clobber (reg:CC 17))]
17305 "TARGET_SSE
17306 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17307 "#")
17308
17309 ;; For non-sse moves just expand the usual cmove sequence.
17310 (define_split
17311 [(set (match_operand 0 "register_operand" "")
17312 (if_then_else (match_operator 1 "comparison_operator"
17313 [(match_operand 4 "nonimmediate_operand" "")
17314 (match_operand 5 "register_operand" "")])
17315 (match_operand 2 "nonimmediate_operand" "")
17316 (match_operand 3 "nonimmediate_operand" "")))
17317 (clobber (match_operand 6 "" ""))
17318 (clobber (reg:CC 17))]
17319 "!SSE_REG_P (operands[0]) && reload_completed
17320 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17321 [(const_int 0)]
17322 {
17323 ix86_compare_op0 = operands[5];
17324 ix86_compare_op1 = operands[4];
17325 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17326 VOIDmode, operands[5], operands[4]);
17327 ix86_expand_fp_movcc (operands);
17328 DONE;
17329 })
17330
17331 ;; Split SSE based conditional move into sequence:
17332 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17333 ;; and op2, op0 - zero op2 if comparison was false
17334 ;; nand op0, op3 - load op3 to op0 if comparison was false
17335 ;; or op2, op0 - get the nonzero one into the result.
17336 (define_split
17337 [(set (match_operand 0 "register_operand" "")
17338 (if_then_else (match_operator 1 "sse_comparison_operator"
17339 [(match_operand 4 "register_operand" "")
17340 (match_operand 5 "nonimmediate_operand" "")])
17341 (match_operand 2 "register_operand" "")
17342 (match_operand 3 "register_operand" "")))
17343 (clobber (match_operand 6 "" ""))
17344 (clobber (reg:CC 17))]
17345 "SSE_REG_P (operands[0]) && reload_completed"
17346 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17347 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17348 (subreg:TI (match_dup 4) 0)))
17349 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17350 (subreg:TI (match_dup 3) 0)))
17351 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17352 (subreg:TI (match_dup 7) 0)))]
17353 {
17354 if (GET_MODE (operands[2]) == DFmode
17355 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17356 {
17357 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17358 emit_insn (gen_sse2_unpcklpd (op, op, op));
17359 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17360 emit_insn (gen_sse2_unpcklpd (op, op, op));
17361 }
17362
17363 /* If op2 == op3, op3 would be clobbered before it is used. */
17364 if (operands_match_p (operands[2], operands[3]))
17365 {
17366 emit_move_insn (operands[0], operands[2]);
17367 DONE;
17368 }
17369
17370 PUT_MODE (operands[1], GET_MODE (operands[0]));
17371 if (operands_match_p (operands[0], operands[4]))
17372 operands[6] = operands[4], operands[7] = operands[2];
17373 else
17374 operands[6] = operands[2], operands[7] = operands[4];
17375 })
17376
17377 ;; Special case of conditional move we can handle effectively.
17378 ;; Do not brother with the integer/floating point case, since these are
17379 ;; bot considerably slower, unlike in the generic case.
17380 (define_insn "*sse_movsfcc_const0_1"
17381 [(set (match_operand:SF 0 "register_operand" "=&x")
17382 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17383 [(match_operand:SF 4 "register_operand" "0")
17384 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17385 (match_operand:SF 2 "register_operand" "x")
17386 (match_operand:SF 3 "const0_operand" "X")))]
17387 "TARGET_SSE"
17388 "#")
17389
17390 (define_insn "*sse_movsfcc_const0_2"
17391 [(set (match_operand:SF 0 "register_operand" "=&x")
17392 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17393 [(match_operand:SF 4 "register_operand" "0")
17394 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17395 (match_operand:SF 2 "const0_operand" "X")
17396 (match_operand:SF 3 "register_operand" "x")))]
17397 "TARGET_SSE"
17398 "#")
17399
17400 (define_insn "*sse_movsfcc_const0_3"
17401 [(set (match_operand:SF 0 "register_operand" "=&x")
17402 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17403 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17404 (match_operand:SF 5 "register_operand" "0")])
17405 (match_operand:SF 2 "register_operand" "x")
17406 (match_operand:SF 3 "const0_operand" "X")))]
17407 "TARGET_SSE"
17408 "#")
17409
17410 (define_insn "*sse_movsfcc_const0_4"
17411 [(set (match_operand:SF 0 "register_operand" "=&x")
17412 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17413 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17414 (match_operand:SF 5 "register_operand" "0")])
17415 (match_operand:SF 2 "const0_operand" "X")
17416 (match_operand:SF 3 "register_operand" "x")))]
17417 "TARGET_SSE"
17418 "#")
17419
17420 (define_insn "*sse_movdfcc_const0_1"
17421 [(set (match_operand:DF 0 "register_operand" "=&Y")
17422 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17423 [(match_operand:DF 4 "register_operand" "0")
17424 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17425 (match_operand:DF 2 "register_operand" "Y")
17426 (match_operand:DF 3 "const0_operand" "X")))]
17427 "TARGET_SSE2"
17428 "#")
17429
17430 (define_insn "*sse_movdfcc_const0_2"
17431 [(set (match_operand:DF 0 "register_operand" "=&Y")
17432 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17433 [(match_operand:DF 4 "register_operand" "0")
17434 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17435 (match_operand:DF 2 "const0_operand" "X")
17436 (match_operand:DF 3 "register_operand" "Y")))]
17437 "TARGET_SSE2"
17438 "#")
17439
17440 (define_insn "*sse_movdfcc_const0_3"
17441 [(set (match_operand:DF 0 "register_operand" "=&Y")
17442 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17443 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17444 (match_operand:DF 5 "register_operand" "0")])
17445 (match_operand:DF 2 "register_operand" "Y")
17446 (match_operand:DF 3 "const0_operand" "X")))]
17447 "TARGET_SSE2"
17448 "#")
17449
17450 (define_insn "*sse_movdfcc_const0_4"
17451 [(set (match_operand:DF 0 "register_operand" "=&Y")
17452 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17453 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17454 (match_operand:DF 5 "register_operand" "0")])
17455 (match_operand:DF 2 "const0_operand" "X")
17456 (match_operand:DF 3 "register_operand" "Y")))]
17457 "TARGET_SSE2"
17458 "#")
17459
17460 (define_split
17461 [(set (match_operand 0 "register_operand" "")
17462 (if_then_else (match_operator 1 "comparison_operator"
17463 [(match_operand 4 "nonimmediate_operand" "")
17464 (match_operand 5 "nonimmediate_operand" "")])
17465 (match_operand 2 "nonmemory_operand" "")
17466 (match_operand 3 "nonmemory_operand" "")))]
17467 "SSE_REG_P (operands[0]) && reload_completed
17468 && (const0_operand (operands[2], GET_MODE (operands[0]))
17469 || const0_operand (operands[3], GET_MODE (operands[0])))"
17470 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17471 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17472 (match_dup 7)))]
17473 {
17474 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17475 && GET_MODE (operands[2]) == DFmode)
17476 {
17477 if (REG_P (operands[2]))
17478 {
17479 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17480 emit_insn (gen_sse2_unpcklpd (op, op, op));
17481 }
17482 if (REG_P (operands[3]))
17483 {
17484 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17485 emit_insn (gen_sse2_unpcklpd (op, op, op));
17486 }
17487 }
17488 PUT_MODE (operands[1], GET_MODE (operands[0]));
17489 if (!sse_comparison_operator (operands[1], VOIDmode)
17490 || !rtx_equal_p (operands[0], operands[4]))
17491 {
17492 rtx tmp = operands[5];
17493 operands[5] = operands[4];
17494 operands[4] = tmp;
17495 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17496 }
17497 if (!rtx_equal_p (operands[0], operands[4]))
17498 abort ();
17499 if (const0_operand (operands[2], GET_MODE (operands[0])))
17500 {
17501 operands[7] = operands[3];
17502 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17503 0));
17504 }
17505 else
17506 {
17507 operands[7] = operands[2];
17508 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17509 }
17510 operands[7] = simplify_gen_subreg (TImode, operands[7],
17511 GET_MODE (operands[7]), 0);
17512 })
17513
17514 (define_expand "allocate_stack_worker"
17515 [(match_operand:SI 0 "register_operand" "")]
17516 "TARGET_STACK_PROBE"
17517 {
17518 if (TARGET_64BIT)
17519 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17520 else
17521 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17522 DONE;
17523 })
17524
17525 (define_insn "allocate_stack_worker_1"
17526 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17527 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17528 (clobber (match_dup 0))
17529 (clobber (reg:CC 17))]
17530 "!TARGET_64BIT && TARGET_STACK_PROBE"
17531 "call\t__alloca"
17532 [(set_attr "type" "multi")
17533 (set_attr "length" "5")])
17534
17535 (define_insn "allocate_stack_worker_rex64"
17536 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17537 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17538 (clobber (match_dup 0))
17539 (clobber (reg:CC 17))]
17540 "TARGET_64BIT && TARGET_STACK_PROBE"
17541 "call\t__alloca"
17542 [(set_attr "type" "multi")
17543 (set_attr "length" "5")])
17544
17545 (define_expand "allocate_stack"
17546 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17547 (minus:SI (reg:SI 7)
17548 (match_operand:SI 1 "general_operand" "")))
17549 (clobber (reg:CC 17))])
17550 (parallel [(set (reg:SI 7)
17551 (minus:SI (reg:SI 7) (match_dup 1)))
17552 (clobber (reg:CC 17))])]
17553 "TARGET_STACK_PROBE"
17554 {
17555 #ifdef CHECK_STACK_LIMIT
17556 if (GET_CODE (operands[1]) == CONST_INT
17557 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17558 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17559 operands[1]));
17560 else
17561 #endif
17562 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17563 operands[1])));
17564
17565 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17566 DONE;
17567 })
17568
17569 (define_expand "builtin_setjmp_receiver"
17570 [(label_ref (match_operand 0 "" ""))]
17571 "!TARGET_64BIT && flag_pic"
17572 {
17573 emit_insn (gen_set_got (pic_offset_table_rtx));
17574 DONE;
17575 })
17576 \f
17577 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17578
17579 (define_split
17580 [(set (match_operand 0 "register_operand" "")
17581 (match_operator 3 "promotable_binary_operator"
17582 [(match_operand 1 "register_operand" "")
17583 (match_operand 2 "aligned_operand" "")]))
17584 (clobber (reg:CC 17))]
17585 "! TARGET_PARTIAL_REG_STALL && reload_completed
17586 && ((GET_MODE (operands[0]) == HImode
17587 && ((!optimize_size && !TARGET_FAST_PREFIX)
17588 || GET_CODE (operands[2]) != CONST_INT
17589 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17590 || (GET_MODE (operands[0]) == QImode
17591 && (TARGET_PROMOTE_QImode || optimize_size)))"
17592 [(parallel [(set (match_dup 0)
17593 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17594 (clobber (reg:CC 17))])]
17595 "operands[0] = gen_lowpart (SImode, operands[0]);
17596 operands[1] = gen_lowpart (SImode, operands[1]);
17597 if (GET_CODE (operands[3]) != ASHIFT)
17598 operands[2] = gen_lowpart (SImode, operands[2]);
17599 PUT_MODE (operands[3], SImode);")
17600
17601 (define_split
17602 [(set (reg 17)
17603 (compare (and (match_operand 1 "aligned_operand" "")
17604 (match_operand 2 "const_int_operand" ""))
17605 (const_int 0)))
17606 (set (match_operand 0 "register_operand" "")
17607 (and (match_dup 1) (match_dup 2)))]
17608 "! TARGET_PARTIAL_REG_STALL && reload_completed
17609 && ix86_match_ccmode (insn, CCNOmode)
17610 && (GET_MODE (operands[0]) == HImode
17611 || (GET_MODE (operands[0]) == QImode
17612 /* Ensure that the operand will remain sign extended immediate. */
17613 && INTVAL (operands[2]) >= 0
17614 && (TARGET_PROMOTE_QImode || optimize_size)))"
17615 [(parallel [(set (reg:CCNO 17)
17616 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17617 (const_int 0)))
17618 (set (match_dup 0)
17619 (and:SI (match_dup 1) (match_dup 2)))])]
17620 "operands[2]
17621 = gen_int_mode (INTVAL (operands[2])
17622 & GET_MODE_MASK (GET_MODE (operands[0])),
17623 SImode);
17624 operands[0] = gen_lowpart (SImode, operands[0]);
17625 operands[1] = gen_lowpart (SImode, operands[1]);")
17626
17627 ; Don't promote the QImode tests, as i386 don't have encoding of
17628 ; the test instruction with 32bit sign extended immediate and thus
17629 ; the code grows.
17630 (define_split
17631 [(set (reg 17)
17632 (compare (and (match_operand:HI 0 "aligned_operand" "")
17633 (match_operand:HI 1 "const_int_operand" ""))
17634 (const_int 0)))]
17635 "! TARGET_PARTIAL_REG_STALL && reload_completed
17636 && ix86_match_ccmode (insn, CCNOmode)
17637 && GET_MODE (operands[0]) == HImode"
17638 [(set (reg:CCNO 17)
17639 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17640 (const_int 0)))]
17641 "operands[1]
17642 = gen_int_mode (INTVAL (operands[1])
17643 & GET_MODE_MASK (GET_MODE (operands[0])),
17644 SImode);
17645 operands[0] = gen_lowpart (SImode, operands[0]);")
17646
17647 (define_split
17648 [(set (match_operand 0 "register_operand" "")
17649 (neg (match_operand 1 "register_operand" "")))
17650 (clobber (reg:CC 17))]
17651 "! TARGET_PARTIAL_REG_STALL && reload_completed
17652 && (GET_MODE (operands[0]) == HImode
17653 || (GET_MODE (operands[0]) == QImode
17654 && (TARGET_PROMOTE_QImode || optimize_size)))"
17655 [(parallel [(set (match_dup 0)
17656 (neg:SI (match_dup 1)))
17657 (clobber (reg:CC 17))])]
17658 "operands[0] = gen_lowpart (SImode, operands[0]);
17659 operands[1] = gen_lowpart (SImode, operands[1]);")
17660
17661 (define_split
17662 [(set (match_operand 0 "register_operand" "")
17663 (not (match_operand 1 "register_operand" "")))]
17664 "! TARGET_PARTIAL_REG_STALL && reload_completed
17665 && (GET_MODE (operands[0]) == HImode
17666 || (GET_MODE (operands[0]) == QImode
17667 && (TARGET_PROMOTE_QImode || optimize_size)))"
17668 [(set (match_dup 0)
17669 (not:SI (match_dup 1)))]
17670 "operands[0] = gen_lowpart (SImode, operands[0]);
17671 operands[1] = gen_lowpart (SImode, operands[1]);")
17672
17673 (define_split
17674 [(set (match_operand 0 "register_operand" "")
17675 (if_then_else (match_operator 1 "comparison_operator"
17676 [(reg 17) (const_int 0)])
17677 (match_operand 2 "register_operand" "")
17678 (match_operand 3 "register_operand" "")))]
17679 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17680 && (GET_MODE (operands[0]) == HImode
17681 || (GET_MODE (operands[0]) == QImode
17682 && (TARGET_PROMOTE_QImode || optimize_size)))"
17683 [(set (match_dup 0)
17684 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17685 "operands[0] = gen_lowpart (SImode, operands[0]);
17686 operands[2] = gen_lowpart (SImode, operands[2]);
17687 operands[3] = gen_lowpart (SImode, operands[3]);")
17688
17689 \f
17690 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17691 ;; transform a complex memory operation into two memory to register operations.
17692
17693 ;; Don't push memory operands
17694 (define_peephole2
17695 [(set (match_operand:SI 0 "push_operand" "")
17696 (match_operand:SI 1 "memory_operand" ""))
17697 (match_scratch:SI 2 "r")]
17698 "! optimize_size && ! TARGET_PUSH_MEMORY"
17699 [(set (match_dup 2) (match_dup 1))
17700 (set (match_dup 0) (match_dup 2))]
17701 "")
17702
17703 (define_peephole2
17704 [(set (match_operand:DI 0 "push_operand" "")
17705 (match_operand:DI 1 "memory_operand" ""))
17706 (match_scratch:DI 2 "r")]
17707 "! optimize_size && ! TARGET_PUSH_MEMORY"
17708 [(set (match_dup 2) (match_dup 1))
17709 (set (match_dup 0) (match_dup 2))]
17710 "")
17711
17712 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17713 ;; SImode pushes.
17714 (define_peephole2
17715 [(set (match_operand:SF 0 "push_operand" "")
17716 (match_operand:SF 1 "memory_operand" ""))
17717 (match_scratch:SF 2 "r")]
17718 "! optimize_size && ! TARGET_PUSH_MEMORY"
17719 [(set (match_dup 2) (match_dup 1))
17720 (set (match_dup 0) (match_dup 2))]
17721 "")
17722
17723 (define_peephole2
17724 [(set (match_operand:HI 0 "push_operand" "")
17725 (match_operand:HI 1 "memory_operand" ""))
17726 (match_scratch:HI 2 "r")]
17727 "! optimize_size && ! TARGET_PUSH_MEMORY"
17728 [(set (match_dup 2) (match_dup 1))
17729 (set (match_dup 0) (match_dup 2))]
17730 "")
17731
17732 (define_peephole2
17733 [(set (match_operand:QI 0 "push_operand" "")
17734 (match_operand:QI 1 "memory_operand" ""))
17735 (match_scratch:QI 2 "q")]
17736 "! optimize_size && ! TARGET_PUSH_MEMORY"
17737 [(set (match_dup 2) (match_dup 1))
17738 (set (match_dup 0) (match_dup 2))]
17739 "")
17740
17741 ;; Don't move an immediate directly to memory when the instruction
17742 ;; gets too big.
17743 (define_peephole2
17744 [(match_scratch:SI 1 "r")
17745 (set (match_operand:SI 0 "memory_operand" "")
17746 (const_int 0))]
17747 "! optimize_size
17748 && ! TARGET_USE_MOV0
17749 && TARGET_SPLIT_LONG_MOVES
17750 && get_attr_length (insn) >= ix86_cost->large_insn
17751 && peep2_regno_dead_p (0, FLAGS_REG)"
17752 [(parallel [(set (match_dup 1) (const_int 0))
17753 (clobber (reg:CC 17))])
17754 (set (match_dup 0) (match_dup 1))]
17755 "")
17756
17757 (define_peephole2
17758 [(match_scratch:HI 1 "r")
17759 (set (match_operand:HI 0 "memory_operand" "")
17760 (const_int 0))]
17761 "! optimize_size
17762 && ! TARGET_USE_MOV0
17763 && TARGET_SPLIT_LONG_MOVES
17764 && get_attr_length (insn) >= ix86_cost->large_insn
17765 && peep2_regno_dead_p (0, FLAGS_REG)"
17766 [(parallel [(set (match_dup 2) (const_int 0))
17767 (clobber (reg:CC 17))])
17768 (set (match_dup 0) (match_dup 1))]
17769 "operands[2] = gen_lowpart (SImode, operands[1]);")
17770
17771 (define_peephole2
17772 [(match_scratch:QI 1 "q")
17773 (set (match_operand:QI 0 "memory_operand" "")
17774 (const_int 0))]
17775 "! optimize_size
17776 && ! TARGET_USE_MOV0
17777 && TARGET_SPLIT_LONG_MOVES
17778 && get_attr_length (insn) >= ix86_cost->large_insn
17779 && peep2_regno_dead_p (0, FLAGS_REG)"
17780 [(parallel [(set (match_dup 2) (const_int 0))
17781 (clobber (reg:CC 17))])
17782 (set (match_dup 0) (match_dup 1))]
17783 "operands[2] = gen_lowpart (SImode, operands[1]);")
17784
17785 (define_peephole2
17786 [(match_scratch:SI 2 "r")
17787 (set (match_operand:SI 0 "memory_operand" "")
17788 (match_operand:SI 1 "immediate_operand" ""))]
17789 "! optimize_size
17790 && get_attr_length (insn) >= ix86_cost->large_insn
17791 && TARGET_SPLIT_LONG_MOVES"
17792 [(set (match_dup 2) (match_dup 1))
17793 (set (match_dup 0) (match_dup 2))]
17794 "")
17795
17796 (define_peephole2
17797 [(match_scratch:HI 2 "r")
17798 (set (match_operand:HI 0 "memory_operand" "")
17799 (match_operand:HI 1 "immediate_operand" ""))]
17800 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17801 && TARGET_SPLIT_LONG_MOVES"
17802 [(set (match_dup 2) (match_dup 1))
17803 (set (match_dup 0) (match_dup 2))]
17804 "")
17805
17806 (define_peephole2
17807 [(match_scratch:QI 2 "q")
17808 (set (match_operand:QI 0 "memory_operand" "")
17809 (match_operand:QI 1 "immediate_operand" ""))]
17810 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17811 && TARGET_SPLIT_LONG_MOVES"
17812 [(set (match_dup 2) (match_dup 1))
17813 (set (match_dup 0) (match_dup 2))]
17814 "")
17815
17816 ;; Don't compare memory with zero, load and use a test instead.
17817 (define_peephole2
17818 [(set (reg 17)
17819 (compare (match_operand:SI 0 "memory_operand" "")
17820 (const_int 0)))
17821 (match_scratch:SI 3 "r")]
17822 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17823 [(set (match_dup 3) (match_dup 0))
17824 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17825 "")
17826
17827 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17828 ;; Don't split NOTs with a displacement operand, because resulting XOR
17829 ;; will not be pairable anyway.
17830 ;;
17831 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17832 ;; represented using a modRM byte. The XOR replacement is long decoded,
17833 ;; so this split helps here as well.
17834 ;;
17835 ;; Note: Can't do this as a regular split because we can't get proper
17836 ;; lifetime information then.
17837
17838 (define_peephole2
17839 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17840 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17841 "!optimize_size
17842 && peep2_regno_dead_p (0, FLAGS_REG)
17843 && ((TARGET_PENTIUM
17844 && (GET_CODE (operands[0]) != MEM
17845 || !memory_displacement_operand (operands[0], SImode)))
17846 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17847 [(parallel [(set (match_dup 0)
17848 (xor:SI (match_dup 1) (const_int -1)))
17849 (clobber (reg:CC 17))])]
17850 "")
17851
17852 (define_peephole2
17853 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17854 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17855 "!optimize_size
17856 && peep2_regno_dead_p (0, FLAGS_REG)
17857 && ((TARGET_PENTIUM
17858 && (GET_CODE (operands[0]) != MEM
17859 || !memory_displacement_operand (operands[0], HImode)))
17860 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17861 [(parallel [(set (match_dup 0)
17862 (xor:HI (match_dup 1) (const_int -1)))
17863 (clobber (reg:CC 17))])]
17864 "")
17865
17866 (define_peephole2
17867 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17868 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17869 "!optimize_size
17870 && peep2_regno_dead_p (0, FLAGS_REG)
17871 && ((TARGET_PENTIUM
17872 && (GET_CODE (operands[0]) != MEM
17873 || !memory_displacement_operand (operands[0], QImode)))
17874 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17875 [(parallel [(set (match_dup 0)
17876 (xor:QI (match_dup 1) (const_int -1)))
17877 (clobber (reg:CC 17))])]
17878 "")
17879
17880 ;; Non pairable "test imm, reg" instructions can be translated to
17881 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17882 ;; byte opcode instead of two, have a short form for byte operands),
17883 ;; so do it for other CPUs as well. Given that the value was dead,
17884 ;; this should not create any new dependencies. Pass on the sub-word
17885 ;; versions if we're concerned about partial register stalls.
17886
17887 (define_peephole2
17888 [(set (reg 17)
17889 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17890 (match_operand:SI 1 "immediate_operand" ""))
17891 (const_int 0)))]
17892 "ix86_match_ccmode (insn, CCNOmode)
17893 && (true_regnum (operands[0]) != 0
17894 || (GET_CODE (operands[1]) == CONST_INT
17895 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17896 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17897 [(parallel
17898 [(set (reg:CCNO 17)
17899 (compare:CCNO (and:SI (match_dup 0)
17900 (match_dup 1))
17901 (const_int 0)))
17902 (set (match_dup 0)
17903 (and:SI (match_dup 0) (match_dup 1)))])]
17904 "")
17905
17906 ;; We don't need to handle HImode case, because it will be promoted to SImode
17907 ;; on ! TARGET_PARTIAL_REG_STALL
17908
17909 (define_peephole2
17910 [(set (reg 17)
17911 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17912 (match_operand:QI 1 "immediate_operand" ""))
17913 (const_int 0)))]
17914 "! TARGET_PARTIAL_REG_STALL
17915 && ix86_match_ccmode (insn, CCNOmode)
17916 && true_regnum (operands[0]) != 0
17917 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17918 [(parallel
17919 [(set (reg:CCNO 17)
17920 (compare:CCNO (and:QI (match_dup 0)
17921 (match_dup 1))
17922 (const_int 0)))
17923 (set (match_dup 0)
17924 (and:QI (match_dup 0) (match_dup 1)))])]
17925 "")
17926
17927 (define_peephole2
17928 [(set (reg 17)
17929 (compare
17930 (and:SI
17931 (zero_extract:SI
17932 (match_operand 0 "ext_register_operand" "")
17933 (const_int 8)
17934 (const_int 8))
17935 (match_operand 1 "const_int_operand" ""))
17936 (const_int 0)))]
17937 "! TARGET_PARTIAL_REG_STALL
17938 && ix86_match_ccmode (insn, CCNOmode)
17939 && true_regnum (operands[0]) != 0
17940 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17941 [(parallel [(set (reg:CCNO 17)
17942 (compare:CCNO
17943 (and:SI
17944 (zero_extract:SI
17945 (match_dup 0)
17946 (const_int 8)
17947 (const_int 8))
17948 (match_dup 1))
17949 (const_int 0)))
17950 (set (zero_extract:SI (match_dup 0)
17951 (const_int 8)
17952 (const_int 8))
17953 (and:SI
17954 (zero_extract:SI
17955 (match_dup 0)
17956 (const_int 8)
17957 (const_int 8))
17958 (match_dup 1)))])]
17959 "")
17960
17961 ;; Don't do logical operations with memory inputs.
17962 (define_peephole2
17963 [(match_scratch:SI 2 "r")
17964 (parallel [(set (match_operand:SI 0 "register_operand" "")
17965 (match_operator:SI 3 "arith_or_logical_operator"
17966 [(match_dup 0)
17967 (match_operand:SI 1 "memory_operand" "")]))
17968 (clobber (reg:CC 17))])]
17969 "! optimize_size && ! TARGET_READ_MODIFY"
17970 [(set (match_dup 2) (match_dup 1))
17971 (parallel [(set (match_dup 0)
17972 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17973 (clobber (reg:CC 17))])]
17974 "")
17975
17976 (define_peephole2
17977 [(match_scratch:SI 2 "r")
17978 (parallel [(set (match_operand:SI 0 "register_operand" "")
17979 (match_operator:SI 3 "arith_or_logical_operator"
17980 [(match_operand:SI 1 "memory_operand" "")
17981 (match_dup 0)]))
17982 (clobber (reg:CC 17))])]
17983 "! optimize_size && ! TARGET_READ_MODIFY"
17984 [(set (match_dup 2) (match_dup 1))
17985 (parallel [(set (match_dup 0)
17986 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17987 (clobber (reg:CC 17))])]
17988 "")
17989
17990 ; Don't do logical operations with memory outputs
17991 ;
17992 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17993 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17994 ; the same decoder scheduling characteristics as the original.
17995
17996 (define_peephole2
17997 [(match_scratch:SI 2 "r")
17998 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17999 (match_operator:SI 3 "arith_or_logical_operator"
18000 [(match_dup 0)
18001 (match_operand:SI 1 "nonmemory_operand" "")]))
18002 (clobber (reg:CC 17))])]
18003 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18004 [(set (match_dup 2) (match_dup 0))
18005 (parallel [(set (match_dup 2)
18006 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18007 (clobber (reg:CC 17))])
18008 (set (match_dup 0) (match_dup 2))]
18009 "")
18010
18011 (define_peephole2
18012 [(match_scratch:SI 2 "r")
18013 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18014 (match_operator:SI 3 "arith_or_logical_operator"
18015 [(match_operand:SI 1 "nonmemory_operand" "")
18016 (match_dup 0)]))
18017 (clobber (reg:CC 17))])]
18018 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18019 [(set (match_dup 2) (match_dup 0))
18020 (parallel [(set (match_dup 2)
18021 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18022 (clobber (reg:CC 17))])
18023 (set (match_dup 0) (match_dup 2))]
18024 "")
18025
18026 ;; Attempt to always use XOR for zeroing registers.
18027 (define_peephole2
18028 [(set (match_operand 0 "register_operand" "")
18029 (const_int 0))]
18030 "(GET_MODE (operands[0]) == QImode
18031 || GET_MODE (operands[0]) == HImode
18032 || GET_MODE (operands[0]) == SImode
18033 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18034 && (! TARGET_USE_MOV0 || optimize_size)
18035 && peep2_regno_dead_p (0, FLAGS_REG)"
18036 [(parallel [(set (match_dup 0) (const_int 0))
18037 (clobber (reg:CC 17))])]
18038 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18039 operands[0]);")
18040
18041 (define_peephole2
18042 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18043 (const_int 0))]
18044 "(GET_MODE (operands[0]) == QImode
18045 || GET_MODE (operands[0]) == HImode)
18046 && (! TARGET_USE_MOV0 || optimize_size)
18047 && peep2_regno_dead_p (0, FLAGS_REG)"
18048 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18049 (clobber (reg:CC 17))])])
18050
18051 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18052 (define_peephole2
18053 [(set (match_operand 0 "register_operand" "")
18054 (const_int -1))]
18055 "(GET_MODE (operands[0]) == HImode
18056 || GET_MODE (operands[0]) == SImode
18057 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18058 && (optimize_size || TARGET_PENTIUM)
18059 && peep2_regno_dead_p (0, FLAGS_REG)"
18060 [(parallel [(set (match_dup 0) (const_int -1))
18061 (clobber (reg:CC 17))])]
18062 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18063 operands[0]);")
18064
18065 ;; Attempt to convert simple leas to adds. These can be created by
18066 ;; move expanders.
18067 (define_peephole2
18068 [(set (match_operand:SI 0 "register_operand" "")
18069 (plus:SI (match_dup 0)
18070 (match_operand:SI 1 "nonmemory_operand" "")))]
18071 "peep2_regno_dead_p (0, FLAGS_REG)"
18072 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18073 (clobber (reg:CC 17))])]
18074 "")
18075
18076 (define_peephole2
18077 [(set (match_operand:SI 0 "register_operand" "")
18078 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18079 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18080 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18081 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18082 (clobber (reg:CC 17))])]
18083 "operands[2] = gen_lowpart (SImode, operands[2]);")
18084
18085 (define_peephole2
18086 [(set (match_operand:DI 0 "register_operand" "")
18087 (plus:DI (match_dup 0)
18088 (match_operand:DI 1 "x86_64_general_operand" "")))]
18089 "peep2_regno_dead_p (0, FLAGS_REG)"
18090 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18091 (clobber (reg:CC 17))])]
18092 "")
18093
18094 (define_peephole2
18095 [(set (match_operand:SI 0 "register_operand" "")
18096 (mult:SI (match_dup 0)
18097 (match_operand:SI 1 "const_int_operand" "")))]
18098 "exact_log2 (INTVAL (operands[1])) >= 0
18099 && peep2_regno_dead_p (0, FLAGS_REG)"
18100 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18101 (clobber (reg:CC 17))])]
18102 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18103
18104 (define_peephole2
18105 [(set (match_operand:DI 0 "register_operand" "")
18106 (mult:DI (match_dup 0)
18107 (match_operand:DI 1 "const_int_operand" "")))]
18108 "exact_log2 (INTVAL (operands[1])) >= 0
18109 && peep2_regno_dead_p (0, FLAGS_REG)"
18110 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18111 (clobber (reg:CC 17))])]
18112 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18113
18114 (define_peephole2
18115 [(set (match_operand:SI 0 "register_operand" "")
18116 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18117 (match_operand:DI 2 "const_int_operand" "")) 0))]
18118 "exact_log2 (INTVAL (operands[2])) >= 0
18119 && REGNO (operands[0]) == REGNO (operands[1])
18120 && peep2_regno_dead_p (0, FLAGS_REG)"
18121 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18122 (clobber (reg:CC 17))])]
18123 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18124
18125 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18126 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18127 ;; many CPUs it is also faster, since special hardware to avoid esp
18128 ;; dependencies is present.
18129
18130 ;; While some of these conversions may be done using splitters, we use peepholes
18131 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18132
18133 ;; Convert prologue esp subtractions to push.
18134 ;; We need register to push. In order to keep verify_flow_info happy we have
18135 ;; two choices
18136 ;; - use scratch and clobber it in order to avoid dependencies
18137 ;; - use already live register
18138 ;; We can't use the second way right now, since there is no reliable way how to
18139 ;; verify that given register is live. First choice will also most likely in
18140 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18141 ;; call clobbered registers are dead. We may want to use base pointer as an
18142 ;; alternative when no register is available later.
18143
18144 (define_peephole2
18145 [(match_scratch:SI 0 "r")
18146 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18147 (clobber (reg:CC 17))
18148 (clobber (mem:BLK (scratch)))])]
18149 "optimize_size || !TARGET_SUB_ESP_4"
18150 [(clobber (match_dup 0))
18151 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18152 (clobber (mem:BLK (scratch)))])])
18153
18154 (define_peephole2
18155 [(match_scratch:SI 0 "r")
18156 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18157 (clobber (reg:CC 17))
18158 (clobber (mem:BLK (scratch)))])]
18159 "optimize_size || !TARGET_SUB_ESP_8"
18160 [(clobber (match_dup 0))
18161 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18162 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18163 (clobber (mem:BLK (scratch)))])])
18164
18165 ;; Convert esp subtractions to push.
18166 (define_peephole2
18167 [(match_scratch:SI 0 "r")
18168 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18169 (clobber (reg:CC 17))])]
18170 "optimize_size || !TARGET_SUB_ESP_4"
18171 [(clobber (match_dup 0))
18172 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18173
18174 (define_peephole2
18175 [(match_scratch:SI 0 "r")
18176 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18177 (clobber (reg:CC 17))])]
18178 "optimize_size || !TARGET_SUB_ESP_8"
18179 [(clobber (match_dup 0))
18180 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18181 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18182
18183 ;; Convert epilogue deallocator to pop.
18184 (define_peephole2
18185 [(match_scratch:SI 0 "r")
18186 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18187 (clobber (reg:CC 17))
18188 (clobber (mem:BLK (scratch)))])]
18189 "optimize_size || !TARGET_ADD_ESP_4"
18190 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18191 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18192 (clobber (mem:BLK (scratch)))])]
18193 "")
18194
18195 ;; Two pops case is tricky, since pop causes dependency on destination register.
18196 ;; We use two registers if available.
18197 (define_peephole2
18198 [(match_scratch:SI 0 "r")
18199 (match_scratch:SI 1 "r")
18200 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18201 (clobber (reg:CC 17))
18202 (clobber (mem:BLK (scratch)))])]
18203 "optimize_size || !TARGET_ADD_ESP_8"
18204 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18205 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18206 (clobber (mem:BLK (scratch)))])
18207 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18208 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18209 "")
18210
18211 (define_peephole2
18212 [(match_scratch:SI 0 "r")
18213 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18214 (clobber (reg:CC 17))
18215 (clobber (mem:BLK (scratch)))])]
18216 "optimize_size"
18217 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18218 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18219 (clobber (mem:BLK (scratch)))])
18220 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18221 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18222 "")
18223
18224 ;; Convert esp additions to pop.
18225 (define_peephole2
18226 [(match_scratch:SI 0 "r")
18227 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18228 (clobber (reg:CC 17))])]
18229 ""
18230 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18231 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18232 "")
18233
18234 ;; Two pops case is tricky, since pop causes dependency on destination register.
18235 ;; We use two registers if available.
18236 (define_peephole2
18237 [(match_scratch:SI 0 "r")
18238 (match_scratch:SI 1 "r")
18239 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18240 (clobber (reg:CC 17))])]
18241 ""
18242 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18243 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18244 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18245 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18246 "")
18247
18248 (define_peephole2
18249 [(match_scratch:SI 0 "r")
18250 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18251 (clobber (reg:CC 17))])]
18252 "optimize_size"
18253 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18254 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18255 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18256 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18257 "")
18258 \f
18259 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18260 ;; required and register dies.
18261 (define_peephole2
18262 [(set (reg 17)
18263 (compare (match_operand:SI 0 "register_operand" "")
18264 (match_operand:SI 1 "incdec_operand" "")))]
18265 "ix86_match_ccmode (insn, CCGCmode)
18266 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18267 [(parallel [(set (reg:CCGC 17)
18268 (compare:CCGC (match_dup 0)
18269 (match_dup 1)))
18270 (clobber (match_dup 0))])]
18271 "")
18272
18273 (define_peephole2
18274 [(set (reg 17)
18275 (compare (match_operand:HI 0 "register_operand" "")
18276 (match_operand:HI 1 "incdec_operand" "")))]
18277 "ix86_match_ccmode (insn, CCGCmode)
18278 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18279 [(parallel [(set (reg:CCGC 17)
18280 (compare:CCGC (match_dup 0)
18281 (match_dup 1)))
18282 (clobber (match_dup 0))])]
18283 "")
18284
18285 (define_peephole2
18286 [(set (reg 17)
18287 (compare (match_operand:QI 0 "register_operand" "")
18288 (match_operand:QI 1 "incdec_operand" "")))]
18289 "ix86_match_ccmode (insn, CCGCmode)
18290 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18291 [(parallel [(set (reg:CCGC 17)
18292 (compare:CCGC (match_dup 0)
18293 (match_dup 1)))
18294 (clobber (match_dup 0))])]
18295 "")
18296
18297 ;; Convert compares with 128 to shorter add -128
18298 (define_peephole2
18299 [(set (reg 17)
18300 (compare (match_operand:SI 0 "register_operand" "")
18301 (const_int 128)))]
18302 "ix86_match_ccmode (insn, CCGCmode)
18303 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18304 [(parallel [(set (reg:CCGC 17)
18305 (compare:CCGC (match_dup 0)
18306 (const_int 128)))
18307 (clobber (match_dup 0))])]
18308 "")
18309
18310 (define_peephole2
18311 [(set (reg 17)
18312 (compare (match_operand:HI 0 "register_operand" "")
18313 (const_int 128)))]
18314 "ix86_match_ccmode (insn, CCGCmode)
18315 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18316 [(parallel [(set (reg:CCGC 17)
18317 (compare:CCGC (match_dup 0)
18318 (const_int 128)))
18319 (clobber (match_dup 0))])]
18320 "")
18321 \f
18322 (define_peephole2
18323 [(match_scratch:DI 0 "r")
18324 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18325 (clobber (reg:CC 17))
18326 (clobber (mem:BLK (scratch)))])]
18327 "optimize_size || !TARGET_SUB_ESP_4"
18328 [(clobber (match_dup 0))
18329 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18330 (clobber (mem:BLK (scratch)))])])
18331
18332 (define_peephole2
18333 [(match_scratch:DI 0 "r")
18334 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18335 (clobber (reg:CC 17))
18336 (clobber (mem:BLK (scratch)))])]
18337 "optimize_size || !TARGET_SUB_ESP_8"
18338 [(clobber (match_dup 0))
18339 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18340 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18341 (clobber (mem:BLK (scratch)))])])
18342
18343 ;; Convert esp subtractions to push.
18344 (define_peephole2
18345 [(match_scratch:DI 0 "r")
18346 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18347 (clobber (reg:CC 17))])]
18348 "optimize_size || !TARGET_SUB_ESP_4"
18349 [(clobber (match_dup 0))
18350 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18351
18352 (define_peephole2
18353 [(match_scratch:DI 0 "r")
18354 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18355 (clobber (reg:CC 17))])]
18356 "optimize_size || !TARGET_SUB_ESP_8"
18357 [(clobber (match_dup 0))
18358 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18359 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18360
18361 ;; Convert epilogue deallocator to pop.
18362 (define_peephole2
18363 [(match_scratch:DI 0 "r")
18364 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18365 (clobber (reg:CC 17))
18366 (clobber (mem:BLK (scratch)))])]
18367 "optimize_size || !TARGET_ADD_ESP_4"
18368 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18369 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18370 (clobber (mem:BLK (scratch)))])]
18371 "")
18372
18373 ;; Two pops case is tricky, since pop causes dependency on destination register.
18374 ;; We use two registers if available.
18375 (define_peephole2
18376 [(match_scratch:DI 0 "r")
18377 (match_scratch:DI 1 "r")
18378 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18379 (clobber (reg:CC 17))
18380 (clobber (mem:BLK (scratch)))])]
18381 "optimize_size || !TARGET_ADD_ESP_8"
18382 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18383 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18384 (clobber (mem:BLK (scratch)))])
18385 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18386 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18387 "")
18388
18389 (define_peephole2
18390 [(match_scratch:DI 0 "r")
18391 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18392 (clobber (reg:CC 17))
18393 (clobber (mem:BLK (scratch)))])]
18394 "optimize_size"
18395 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18396 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18397 (clobber (mem:BLK (scratch)))])
18398 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18399 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18400 "")
18401
18402 ;; Convert esp additions to pop.
18403 (define_peephole2
18404 [(match_scratch:DI 0 "r")
18405 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18406 (clobber (reg:CC 17))])]
18407 ""
18408 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18409 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18410 "")
18411
18412 ;; Two pops case is tricky, since pop causes dependency on destination register.
18413 ;; We use two registers if available.
18414 (define_peephole2
18415 [(match_scratch:DI 0 "r")
18416 (match_scratch:DI 1 "r")
18417 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18418 (clobber (reg:CC 17))])]
18419 ""
18420 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18421 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18422 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18423 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18424 "")
18425
18426 (define_peephole2
18427 [(match_scratch:DI 0 "r")
18428 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18429 (clobber (reg:CC 17))])]
18430 "optimize_size"
18431 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18432 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18433 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18434 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18435 "")
18436 \f
18437 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18438 ;; imul $32bit_imm, reg, reg is direct decoded.
18439 (define_peephole2
18440 [(match_scratch:DI 3 "r")
18441 (parallel [(set (match_operand:DI 0 "register_operand" "")
18442 (mult:DI (match_operand:DI 1 "memory_operand" "")
18443 (match_operand:DI 2 "immediate_operand" "")))
18444 (clobber (reg:CC 17))])]
18445 "TARGET_K8 && !optimize_size
18446 && (GET_CODE (operands[2]) != CONST_INT
18447 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18448 [(set (match_dup 3) (match_dup 1))
18449 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18450 (clobber (reg:CC 17))])]
18451 "")
18452
18453 (define_peephole2
18454 [(match_scratch:SI 3 "r")
18455 (parallel [(set (match_operand:SI 0 "register_operand" "")
18456 (mult:SI (match_operand:SI 1 "memory_operand" "")
18457 (match_operand:SI 2 "immediate_operand" "")))
18458 (clobber (reg:CC 17))])]
18459 "TARGET_K8 && !optimize_size
18460 && (GET_CODE (operands[2]) != CONST_INT
18461 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18462 [(set (match_dup 3) (match_dup 1))
18463 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18464 (clobber (reg:CC 17))])]
18465 "")
18466
18467 (define_peephole2
18468 [(match_scratch:SI 3 "r")
18469 (parallel [(set (match_operand:DI 0 "register_operand" "")
18470 (zero_extend:DI
18471 (mult:SI (match_operand:SI 1 "memory_operand" "")
18472 (match_operand:SI 2 "immediate_operand" ""))))
18473 (clobber (reg:CC 17))])]
18474 "TARGET_K8 && !optimize_size
18475 && (GET_CODE (operands[2]) != CONST_INT
18476 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18477 [(set (match_dup 3) (match_dup 1))
18478 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18479 (clobber (reg:CC 17))])]
18480 "")
18481
18482 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18483 ;; Convert it into imul reg, reg
18484 ;; It would be better to force assembler to encode instruction using long
18485 ;; immediate, but there is apparently no way to do so.
18486 (define_peephole2
18487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18488 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18489 (match_operand:DI 2 "const_int_operand" "")))
18490 (clobber (reg:CC 17))])
18491 (match_scratch:DI 3 "r")]
18492 "TARGET_K8 && !optimize_size
18493 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18494 [(set (match_dup 3) (match_dup 2))
18495 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18496 (clobber (reg:CC 17))])]
18497 {
18498 if (!rtx_equal_p (operands[0], operands[1]))
18499 emit_move_insn (operands[0], operands[1]);
18500 })
18501
18502 (define_peephole2
18503 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18504 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18505 (match_operand:SI 2 "const_int_operand" "")))
18506 (clobber (reg:CC 17))])
18507 (match_scratch:SI 3 "r")]
18508 "TARGET_K8 && !optimize_size
18509 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18510 [(set (match_dup 3) (match_dup 2))
18511 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18512 (clobber (reg:CC 17))])]
18513 {
18514 if (!rtx_equal_p (operands[0], operands[1]))
18515 emit_move_insn (operands[0], operands[1]);
18516 })
18517
18518 (define_peephole2
18519 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18520 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18521 (match_operand:HI 2 "immediate_operand" "")))
18522 (clobber (reg:CC 17))])
18523 (match_scratch:HI 3 "r")]
18524 "TARGET_K8 && !optimize_size"
18525 [(set (match_dup 3) (match_dup 2))
18526 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18527 (clobber (reg:CC 17))])]
18528 {
18529 if (!rtx_equal_p (operands[0], operands[1]))
18530 emit_move_insn (operands[0], operands[1]);
18531 })
18532 \f
18533 ;; Call-value patterns last so that the wildcard operand does not
18534 ;; disrupt insn-recog's switch tables.
18535
18536 (define_insn "*call_value_pop_0"
18537 [(set (match_operand 0 "" "")
18538 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18539 (match_operand:SI 2 "" "")))
18540 (set (reg:SI 7) (plus:SI (reg:SI 7)
18541 (match_operand:SI 3 "immediate_operand" "")))]
18542 "!TARGET_64BIT"
18543 {
18544 if (SIBLING_CALL_P (insn))
18545 return "jmp\t%P1";
18546 else
18547 return "call\t%P1";
18548 }
18549 [(set_attr "type" "callv")])
18550
18551 (define_insn "*call_value_pop_1"
18552 [(set (match_operand 0 "" "")
18553 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18554 (match_operand:SI 2 "" "")))
18555 (set (reg:SI 7) (plus:SI (reg:SI 7)
18556 (match_operand:SI 3 "immediate_operand" "i")))]
18557 "!TARGET_64BIT"
18558 {
18559 if (constant_call_address_operand (operands[1], QImode))
18560 {
18561 if (SIBLING_CALL_P (insn))
18562 return "jmp\t%P1";
18563 else
18564 return "call\t%P1";
18565 }
18566 if (SIBLING_CALL_P (insn))
18567 return "jmp\t%A1";
18568 else
18569 return "call\t%A1";
18570 }
18571 [(set_attr "type" "callv")])
18572
18573 (define_insn "*call_value_0"
18574 [(set (match_operand 0 "" "")
18575 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18576 (match_operand:SI 2 "" "")))]
18577 "!TARGET_64BIT"
18578 {
18579 if (SIBLING_CALL_P (insn))
18580 return "jmp\t%P1";
18581 else
18582 return "call\t%P1";
18583 }
18584 [(set_attr "type" "callv")])
18585
18586 (define_insn "*call_value_0_rex64"
18587 [(set (match_operand 0 "" "")
18588 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18589 (match_operand:DI 2 "const_int_operand" "")))]
18590 "TARGET_64BIT"
18591 {
18592 if (SIBLING_CALL_P (insn))
18593 return "jmp\t%P1";
18594 else
18595 return "call\t%P1";
18596 }
18597 [(set_attr "type" "callv")])
18598
18599 (define_insn "*call_value_1"
18600 [(set (match_operand 0 "" "")
18601 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18602 (match_operand:SI 2 "" "")))]
18603 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18604 {
18605 if (constant_call_address_operand (operands[1], QImode))
18606 return "call\t%P1";
18607 return "call\t%*%1";
18608 }
18609 [(set_attr "type" "callv")])
18610
18611 (define_insn "*sibcall_value_1"
18612 [(set (match_operand 0 "" "")
18613 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18614 (match_operand:SI 2 "" "")))]
18615 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18616 {
18617 if (constant_call_address_operand (operands[1], QImode))
18618 return "jmp\t%P1";
18619 return "jmp\t%*%1";
18620 }
18621 [(set_attr "type" "callv")])
18622
18623 (define_insn "*call_value_1_rex64"
18624 [(set (match_operand 0 "" "")
18625 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18626 (match_operand:DI 2 "" "")))]
18627 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18628 {
18629 if (constant_call_address_operand (operands[1], QImode))
18630 return "call\t%P1";
18631 return "call\t%A1";
18632 }
18633 [(set_attr "type" "callv")])
18634
18635 (define_insn "*sibcall_value_1_rex64"
18636 [(set (match_operand 0 "" "")
18637 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18638 (match_operand:DI 2 "" "")))]
18639 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18640 "jmp\t%P1"
18641 [(set_attr "type" "callv")])
18642
18643 (define_insn "*sibcall_value_1_rex64_v"
18644 [(set (match_operand 0 "" "")
18645 (call (mem:QI (reg:DI 40))
18646 (match_operand:DI 1 "" "")))]
18647 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18648 "jmp\t*%%r11"
18649 [(set_attr "type" "callv")])
18650 \f
18651 (define_insn "trap"
18652 [(trap_if (const_int 1) (const_int 5))]
18653 ""
18654 "int\t$5")
18655
18656 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18657 ;;; for the sake of bounds checking. By emitting bounds checks as
18658 ;;; conditional traps rather than as conditional jumps around
18659 ;;; unconditional traps we avoid introducing spurious basic-block
18660 ;;; boundaries and facilitate elimination of redundant checks. In
18661 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18662 ;;; interrupt 5.
18663 ;;;
18664 ;;; FIXME: Static branch prediction rules for ix86 are such that
18665 ;;; forward conditional branches predict as untaken. As implemented
18666 ;;; below, pseudo conditional traps violate that rule. We should use
18667 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18668 ;;; section loaded at the end of the text segment and branch forward
18669 ;;; there on bounds-failure, and then jump back immediately (in case
18670 ;;; the system chooses to ignore bounds violations, or to report
18671 ;;; violations and continue execution).
18672
18673 (define_expand "conditional_trap"
18674 [(trap_if (match_operator 0 "comparison_operator"
18675 [(match_dup 2) (const_int 0)])
18676 (match_operand 1 "const_int_operand" ""))]
18677 ""
18678 {
18679 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18680 ix86_expand_compare (GET_CODE (operands[0]),
18681 NULL, NULL),
18682 operands[1]));
18683 DONE;
18684 })
18685
18686 (define_insn "*conditional_trap_1"
18687 [(trap_if (match_operator 0 "comparison_operator"
18688 [(reg 17) (const_int 0)])
18689 (match_operand 1 "const_int_operand" ""))]
18690 ""
18691 {
18692 operands[2] = gen_label_rtx ();
18693 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18694 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18695 CODE_LABEL_NUMBER (operands[2]));
18696 RET;
18697 })
18698
18699 ;; Pentium III SIMD instructions.
18700
18701 ;; Moves for SSE/MMX regs.
18702
18703 (define_insn "movv4sf_internal"
18704 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18705 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18706 "TARGET_SSE"
18707 "@
18708 xorps\t%0, %0
18709 movaps\t{%1, %0|%0, %1}
18710 movaps\t{%1, %0|%0, %1}"
18711 [(set_attr "type" "ssemov")
18712 (set_attr "mode" "V4SF")])
18713
18714 (define_split
18715 [(set (match_operand:V4SF 0 "register_operand" "")
18716 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18717 "TARGET_SSE"
18718 [(set (match_dup 0)
18719 (vec_merge:V4SF
18720 (vec_duplicate:V4SF (match_dup 1))
18721 (match_dup 2)
18722 (const_int 1)))]
18723 {
18724 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18725 operands[2] = CONST0_RTX (V4SFmode);
18726 })
18727
18728 (define_insn "movv4si_internal"
18729 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18730 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18731 "TARGET_SSE"
18732 {
18733 switch (which_alternative)
18734 {
18735 case 0:
18736 if (get_attr_mode (insn) == MODE_V4SF)
18737 return "xorps\t%0, %0";
18738 else
18739 return "pxor\t%0, %0";
18740 case 1:
18741 case 2:
18742 if (get_attr_mode (insn) == MODE_V4SF)
18743 return "movaps\t{%1, %0|%0, %1}";
18744 else
18745 return "movdqa\t{%1, %0|%0, %1}";
18746 default:
18747 abort ();
18748 }
18749 }
18750 [(set_attr "type" "ssemov")
18751 (set (attr "mode")
18752 (cond [(eq_attr "alternative" "0,1")
18753 (if_then_else
18754 (ne (symbol_ref "optimize_size")
18755 (const_int 0))
18756 (const_string "V4SF")
18757 (const_string "TI"))
18758 (eq_attr "alternative" "2")
18759 (if_then_else
18760 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18761 (const_int 0))
18762 (ne (symbol_ref "optimize_size")
18763 (const_int 0)))
18764 (const_string "V4SF")
18765 (const_string "TI"))]
18766 (const_string "TI")))])
18767
18768 (define_insn "movv2di_internal"
18769 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18770 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18771 "TARGET_SSE2"
18772 {
18773 switch (which_alternative)
18774 {
18775 case 0:
18776 if (get_attr_mode (insn) == MODE_V4SF)
18777 return "xorps\t%0, %0";
18778 else
18779 return "pxor\t%0, %0";
18780 case 1:
18781 case 2:
18782 if (get_attr_mode (insn) == MODE_V4SF)
18783 return "movaps\t{%1, %0|%0, %1}";
18784 else
18785 return "movdqa\t{%1, %0|%0, %1}";
18786 default:
18787 abort ();
18788 }
18789 }
18790 [(set_attr "type" "ssemov")
18791 (set (attr "mode")
18792 (cond [(eq_attr "alternative" "0,1")
18793 (if_then_else
18794 (ne (symbol_ref "optimize_size")
18795 (const_int 0))
18796 (const_string "V4SF")
18797 (const_string "TI"))
18798 (eq_attr "alternative" "2")
18799 (if_then_else
18800 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18801 (const_int 0))
18802 (ne (symbol_ref "optimize_size")
18803 (const_int 0)))
18804 (const_string "V4SF")
18805 (const_string "TI"))]
18806 (const_string "TI")))])
18807
18808 (define_split
18809 [(set (match_operand:V2DF 0 "register_operand" "")
18810 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18811 "TARGET_SSE2"
18812 [(set (match_dup 0)
18813 (vec_merge:V2DF
18814 (vec_duplicate:V2DF (match_dup 1))
18815 (match_dup 2)
18816 (const_int 1)))]
18817 {
18818 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18819 operands[2] = CONST0_RTX (V2DFmode);
18820 })
18821
18822 (define_insn "movv8qi_internal"
18823 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18824 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18825 "TARGET_MMX
18826 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18827 "@
18828 pxor\t%0, %0
18829 movq\t{%1, %0|%0, %1}
18830 movq\t{%1, %0|%0, %1}"
18831 [(set_attr "type" "mmxmov")
18832 (set_attr "mode" "DI")])
18833
18834 (define_insn "movv4hi_internal"
18835 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18836 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18837 "TARGET_MMX
18838 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18839 "@
18840 pxor\t%0, %0
18841 movq\t{%1, %0|%0, %1}
18842 movq\t{%1, %0|%0, %1}"
18843 [(set_attr "type" "mmxmov")
18844 (set_attr "mode" "DI")])
18845
18846 (define_insn "movv2si_internal"
18847 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18848 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18849 "TARGET_MMX
18850 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18851 "@
18852 pxor\t%0, %0
18853 movq\t{%1, %0|%0, %1}
18854 movq\t{%1, %0|%0, %1}"
18855 [(set_attr "type" "mmxcvt")
18856 (set_attr "mode" "DI")])
18857
18858 (define_insn "movv2sf_internal"
18859 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18860 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18861 "TARGET_3DNOW
18862 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18863 "@
18864 pxor\t%0, %0
18865 movq\t{%1, %0|%0, %1}
18866 movq\t{%1, %0|%0, %1}"
18867 [(set_attr "type" "mmxcvt")
18868 (set_attr "mode" "DI")])
18869
18870 (define_expand "movti"
18871 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18872 (match_operand:TI 1 "nonimmediate_operand" ""))]
18873 "TARGET_SSE || TARGET_64BIT"
18874 {
18875 if (TARGET_64BIT)
18876 ix86_expand_move (TImode, operands);
18877 else
18878 ix86_expand_vector_move (TImode, operands);
18879 DONE;
18880 })
18881
18882 (define_insn "movv2df_internal"
18883 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18884 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18885 "TARGET_SSE2
18886 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18887 {
18888 switch (which_alternative)
18889 {
18890 case 0:
18891 if (get_attr_mode (insn) == MODE_V4SF)
18892 return "xorps\t%0, %0";
18893 else
18894 return "xorpd\t%0, %0";
18895 case 1:
18896 case 2:
18897 if (get_attr_mode (insn) == MODE_V4SF)
18898 return "movaps\t{%1, %0|%0, %1}";
18899 else
18900 return "movapd\t{%1, %0|%0, %1}";
18901 default:
18902 abort ();
18903 }
18904 }
18905 [(set_attr "type" "ssemov")
18906 (set (attr "mode")
18907 (cond [(eq_attr "alternative" "0,1")
18908 (if_then_else
18909 (ne (symbol_ref "optimize_size")
18910 (const_int 0))
18911 (const_string "V4SF")
18912 (const_string "V2DF"))
18913 (eq_attr "alternative" "2")
18914 (if_then_else
18915 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18916 (const_int 0))
18917 (ne (symbol_ref "optimize_size")
18918 (const_int 0)))
18919 (const_string "V4SF")
18920 (const_string "V2DF"))]
18921 (const_string "V2DF")))])
18922
18923 (define_insn "movv8hi_internal"
18924 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18925 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18926 "TARGET_SSE2
18927 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18928 {
18929 switch (which_alternative)
18930 {
18931 case 0:
18932 if (get_attr_mode (insn) == MODE_V4SF)
18933 return "xorps\t%0, %0";
18934 else
18935 return "pxor\t%0, %0";
18936 case 1:
18937 case 2:
18938 if (get_attr_mode (insn) == MODE_V4SF)
18939 return "movaps\t{%1, %0|%0, %1}";
18940 else
18941 return "movdqa\t{%1, %0|%0, %1}";
18942 default:
18943 abort ();
18944 }
18945 }
18946 [(set_attr "type" "ssemov")
18947 (set (attr "mode")
18948 (cond [(eq_attr "alternative" "0,1")
18949 (if_then_else
18950 (ne (symbol_ref "optimize_size")
18951 (const_int 0))
18952 (const_string "V4SF")
18953 (const_string "TI"))
18954 (eq_attr "alternative" "2")
18955 (if_then_else
18956 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18957 (const_int 0))
18958 (ne (symbol_ref "optimize_size")
18959 (const_int 0)))
18960 (const_string "V4SF")
18961 (const_string "TI"))]
18962 (const_string "TI")))])
18963
18964 (define_insn "movv16qi_internal"
18965 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18966 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18967 "TARGET_SSE2
18968 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18969 {
18970 switch (which_alternative)
18971 {
18972 case 0:
18973 if (get_attr_mode (insn) == MODE_V4SF)
18974 return "xorps\t%0, %0";
18975 else
18976 return "pxor\t%0, %0";
18977 case 1:
18978 case 2:
18979 if (get_attr_mode (insn) == MODE_V4SF)
18980 return "movaps\t{%1, %0|%0, %1}";
18981 else
18982 return "movdqa\t{%1, %0|%0, %1}";
18983 default:
18984 abort ();
18985 }
18986 }
18987 [(set_attr "type" "ssemov")
18988 (set (attr "mode")
18989 (cond [(eq_attr "alternative" "0,1")
18990 (if_then_else
18991 (ne (symbol_ref "optimize_size")
18992 (const_int 0))
18993 (const_string "V4SF")
18994 (const_string "TI"))
18995 (eq_attr "alternative" "2")
18996 (if_then_else
18997 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18998 (const_int 0))
18999 (ne (symbol_ref "optimize_size")
19000 (const_int 0)))
19001 (const_string "V4SF")
19002 (const_string "TI"))]
19003 (const_string "TI")))])
19004
19005 (define_expand "movv2df"
19006 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19007 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19008 "TARGET_SSE2"
19009 {
19010 ix86_expand_vector_move (V2DFmode, operands);
19011 DONE;
19012 })
19013
19014 (define_expand "movv8hi"
19015 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19016 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19017 "TARGET_SSE2"
19018 {
19019 ix86_expand_vector_move (V8HImode, operands);
19020 DONE;
19021 })
19022
19023 (define_expand "movv16qi"
19024 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19025 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19026 "TARGET_SSE2"
19027 {
19028 ix86_expand_vector_move (V16QImode, operands);
19029 DONE;
19030 })
19031
19032 (define_expand "movv4sf"
19033 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19034 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19035 "TARGET_SSE"
19036 {
19037 ix86_expand_vector_move (V4SFmode, operands);
19038 DONE;
19039 })
19040
19041 (define_expand "movv4si"
19042 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19043 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19044 "TARGET_SSE"
19045 {
19046 ix86_expand_vector_move (V4SImode, operands);
19047 DONE;
19048 })
19049
19050 (define_expand "movv2di"
19051 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19052 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19053 "TARGET_SSE"
19054 {
19055 ix86_expand_vector_move (V2DImode, operands);
19056 DONE;
19057 })
19058
19059 (define_expand "movv2si"
19060 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19061 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19062 "TARGET_MMX"
19063 {
19064 ix86_expand_vector_move (V2SImode, operands);
19065 DONE;
19066 })
19067
19068 (define_expand "movv4hi"
19069 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19070 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19071 "TARGET_MMX"
19072 {
19073 ix86_expand_vector_move (V4HImode, operands);
19074 DONE;
19075 })
19076
19077 (define_expand "movv8qi"
19078 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19079 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19080 "TARGET_MMX"
19081 {
19082 ix86_expand_vector_move (V8QImode, operands);
19083 DONE;
19084 })
19085
19086 (define_expand "movv2sf"
19087 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19088 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19089 "TARGET_3DNOW"
19090 {
19091 ix86_expand_vector_move (V2SFmode, operands);
19092 DONE;
19093 })
19094
19095 (define_insn "*pushti"
19096 [(set (match_operand:TI 0 "push_operand" "=<")
19097 (match_operand:TI 1 "register_operand" "x"))]
19098 "TARGET_SSE"
19099 "#")
19100
19101 (define_insn "*pushv2df"
19102 [(set (match_operand:V2DF 0 "push_operand" "=<")
19103 (match_operand:V2DF 1 "register_operand" "x"))]
19104 "TARGET_SSE"
19105 "#")
19106
19107 (define_insn "*pushv2di"
19108 [(set (match_operand:V2DI 0 "push_operand" "=<")
19109 (match_operand:V2DI 1 "register_operand" "x"))]
19110 "TARGET_SSE2"
19111 "#")
19112
19113 (define_insn "*pushv8hi"
19114 [(set (match_operand:V8HI 0 "push_operand" "=<")
19115 (match_operand:V8HI 1 "register_operand" "x"))]
19116 "TARGET_SSE2"
19117 "#")
19118
19119 (define_insn "*pushv16qi"
19120 [(set (match_operand:V16QI 0 "push_operand" "=<")
19121 (match_operand:V16QI 1 "register_operand" "x"))]
19122 "TARGET_SSE2"
19123 "#")
19124
19125 (define_insn "*pushv4sf"
19126 [(set (match_operand:V4SF 0 "push_operand" "=<")
19127 (match_operand:V4SF 1 "register_operand" "x"))]
19128 "TARGET_SSE"
19129 "#")
19130
19131 (define_insn "*pushv4si"
19132 [(set (match_operand:V4SI 0 "push_operand" "=<")
19133 (match_operand:V4SI 1 "register_operand" "x"))]
19134 "TARGET_SSE2"
19135 "#")
19136
19137 (define_insn "*pushv2si"
19138 [(set (match_operand:V2SI 0 "push_operand" "=<")
19139 (match_operand:V2SI 1 "register_operand" "y"))]
19140 "TARGET_MMX"
19141 "#")
19142
19143 (define_insn "*pushv4hi"
19144 [(set (match_operand:V4HI 0 "push_operand" "=<")
19145 (match_operand:V4HI 1 "register_operand" "y"))]
19146 "TARGET_MMX"
19147 "#")
19148
19149 (define_insn "*pushv8qi"
19150 [(set (match_operand:V8QI 0 "push_operand" "=<")
19151 (match_operand:V8QI 1 "register_operand" "y"))]
19152 "TARGET_MMX"
19153 "#")
19154
19155 (define_insn "*pushv2sf"
19156 [(set (match_operand:V2SF 0 "push_operand" "=<")
19157 (match_operand:V2SF 1 "register_operand" "y"))]
19158 "TARGET_3DNOW"
19159 "#")
19160
19161 (define_split
19162 [(set (match_operand 0 "push_operand" "")
19163 (match_operand 1 "register_operand" ""))]
19164 "!TARGET_64BIT && reload_completed
19165 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19166 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19167 (set (match_dup 2) (match_dup 1))]
19168 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19169 stack_pointer_rtx);
19170 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19171
19172 (define_split
19173 [(set (match_operand 0 "push_operand" "")
19174 (match_operand 1 "register_operand" ""))]
19175 "TARGET_64BIT && reload_completed
19176 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19177 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19178 (set (match_dup 2) (match_dup 1))]
19179 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19180 stack_pointer_rtx);
19181 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19182
19183
19184 (define_insn "movti_internal"
19185 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19186 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19187 "TARGET_SSE && !TARGET_64BIT
19188 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19189 {
19190 switch (which_alternative)
19191 {
19192 case 0:
19193 if (get_attr_mode (insn) == MODE_V4SF)
19194 return "xorps\t%0, %0";
19195 else
19196 return "pxor\t%0, %0";
19197 case 1:
19198 case 2:
19199 if (get_attr_mode (insn) == MODE_V4SF)
19200 return "movaps\t{%1, %0|%0, %1}";
19201 else
19202 return "movdqa\t{%1, %0|%0, %1}";
19203 default:
19204 abort ();
19205 }
19206 }
19207 [(set_attr "type" "ssemov,ssemov,ssemov")
19208 (set (attr "mode")
19209 (cond [(eq_attr "alternative" "0,1")
19210 (if_then_else
19211 (ne (symbol_ref "optimize_size")
19212 (const_int 0))
19213 (const_string "V4SF")
19214 (const_string "TI"))
19215 (eq_attr "alternative" "2")
19216 (if_then_else
19217 (ne (symbol_ref "optimize_size")
19218 (const_int 0))
19219 (const_string "V4SF")
19220 (const_string "TI"))]
19221 (const_string "TI")))])
19222
19223 (define_insn "*movti_rex64"
19224 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19225 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19226 "TARGET_64BIT
19227 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19228 {
19229 switch (which_alternative)
19230 {
19231 case 0:
19232 case 1:
19233 return "#";
19234 case 2:
19235 if (get_attr_mode (insn) == MODE_V4SF)
19236 return "xorps\t%0, %0";
19237 else
19238 return "pxor\t%0, %0";
19239 case 3:
19240 case 4:
19241 if (get_attr_mode (insn) == MODE_V4SF)
19242 return "movaps\t{%1, %0|%0, %1}";
19243 else
19244 return "movdqa\t{%1, %0|%0, %1}";
19245 default:
19246 abort ();
19247 }
19248 }
19249 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19250 (set (attr "mode")
19251 (cond [(eq_attr "alternative" "2,3")
19252 (if_then_else
19253 (ne (symbol_ref "optimize_size")
19254 (const_int 0))
19255 (const_string "V4SF")
19256 (const_string "TI"))
19257 (eq_attr "alternative" "4")
19258 (if_then_else
19259 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19260 (const_int 0))
19261 (ne (symbol_ref "optimize_size")
19262 (const_int 0)))
19263 (const_string "V4SF")
19264 (const_string "TI"))]
19265 (const_string "DI")))])
19266
19267 (define_split
19268 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19269 (match_operand:TI 1 "general_operand" ""))]
19270 "reload_completed && !SSE_REG_P (operands[0])
19271 && !SSE_REG_P (operands[1])"
19272 [(const_int 0)]
19273 "ix86_split_long_move (operands); DONE;")
19274
19275 ;; These two patterns are useful for specifying exactly whether to use
19276 ;; movaps or movups
19277 (define_insn "sse_movaps"
19278 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19279 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19280 UNSPEC_MOVA))]
19281 "TARGET_SSE
19282 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19283 "movaps\t{%1, %0|%0, %1}"
19284 [(set_attr "type" "ssemov,ssemov")
19285 (set_attr "mode" "V4SF")])
19286
19287 (define_insn "sse_movups"
19288 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19289 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19290 UNSPEC_MOVU))]
19291 "TARGET_SSE
19292 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19293 "movups\t{%1, %0|%0, %1}"
19294 [(set_attr "type" "ssecvt,ssecvt")
19295 (set_attr "mode" "V4SF")])
19296
19297
19298 ;; SSE Strange Moves.
19299
19300 (define_insn "sse_movmskps"
19301 [(set (match_operand:SI 0 "register_operand" "=r")
19302 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19303 UNSPEC_MOVMSK))]
19304 "TARGET_SSE"
19305 "movmskps\t{%1, %0|%0, %1}"
19306 [(set_attr "type" "ssecvt")
19307 (set_attr "mode" "V4SF")])
19308
19309 (define_insn "mmx_pmovmskb"
19310 [(set (match_operand:SI 0 "register_operand" "=r")
19311 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19312 UNSPEC_MOVMSK))]
19313 "TARGET_SSE || TARGET_3DNOW_A"
19314 "pmovmskb\t{%1, %0|%0, %1}"
19315 [(set_attr "type" "ssecvt")
19316 (set_attr "mode" "V4SF")])
19317
19318
19319 (define_insn "mmx_maskmovq"
19320 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19321 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19322 (match_operand:V8QI 2 "register_operand" "y")]
19323 UNSPEC_MASKMOV))]
19324 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19325 ;; @@@ check ordering of operands in intel/nonintel syntax
19326 "maskmovq\t{%2, %1|%1, %2}"
19327 [(set_attr "type" "mmxcvt")
19328 (set_attr "mode" "DI")])
19329
19330 (define_insn "mmx_maskmovq_rex"
19331 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19332 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19333 (match_operand:V8QI 2 "register_operand" "y")]
19334 UNSPEC_MASKMOV))]
19335 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19336 ;; @@@ check ordering of operands in intel/nonintel syntax
19337 "maskmovq\t{%2, %1|%1, %2}"
19338 [(set_attr "type" "mmxcvt")
19339 (set_attr "mode" "DI")])
19340
19341 (define_insn "sse_movntv4sf"
19342 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19343 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19344 UNSPEC_MOVNT))]
19345 "TARGET_SSE"
19346 "movntps\t{%1, %0|%0, %1}"
19347 [(set_attr "type" "ssemov")
19348 (set_attr "mode" "V4SF")])
19349
19350 (define_insn "sse_movntdi"
19351 [(set (match_operand:DI 0 "memory_operand" "=m")
19352 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19353 UNSPEC_MOVNT))]
19354 "TARGET_SSE || TARGET_3DNOW_A"
19355 "movntq\t{%1, %0|%0, %1}"
19356 [(set_attr "type" "mmxmov")
19357 (set_attr "mode" "DI")])
19358
19359 (define_insn "sse_movhlps"
19360 [(set (match_operand:V4SF 0 "register_operand" "=x")
19361 (vec_merge:V4SF
19362 (match_operand:V4SF 1 "register_operand" "0")
19363 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19364 (parallel [(const_int 2)
19365 (const_int 3)
19366 (const_int 0)
19367 (const_int 1)]))
19368 (const_int 3)))]
19369 "TARGET_SSE"
19370 "movhlps\t{%2, %0|%0, %2}"
19371 [(set_attr "type" "ssecvt")
19372 (set_attr "mode" "V4SF")])
19373
19374 (define_insn "sse_movlhps"
19375 [(set (match_operand:V4SF 0 "register_operand" "=x")
19376 (vec_merge:V4SF
19377 (match_operand:V4SF 1 "register_operand" "0")
19378 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19379 (parallel [(const_int 2)
19380 (const_int 3)
19381 (const_int 0)
19382 (const_int 1)]))
19383 (const_int 12)))]
19384 "TARGET_SSE"
19385 "movlhps\t{%2, %0|%0, %2}"
19386 [(set_attr "type" "ssecvt")
19387 (set_attr "mode" "V4SF")])
19388
19389 (define_insn "sse_movhps"
19390 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19391 (vec_merge:V4SF
19392 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19393 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19394 (const_int 12)))]
19395 "TARGET_SSE
19396 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19397 "movhps\t{%2, %0|%0, %2}"
19398 [(set_attr "type" "ssecvt")
19399 (set_attr "mode" "V4SF")])
19400
19401 (define_insn "sse_movlps"
19402 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19403 (vec_merge:V4SF
19404 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19405 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19406 (const_int 3)))]
19407 "TARGET_SSE
19408 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19409 "movlps\t{%2, %0|%0, %2}"
19410 [(set_attr "type" "ssecvt")
19411 (set_attr "mode" "V4SF")])
19412
19413 (define_expand "sse_loadss"
19414 [(match_operand:V4SF 0 "register_operand" "")
19415 (match_operand:SF 1 "memory_operand" "")]
19416 "TARGET_SSE"
19417 {
19418 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19419 CONST0_RTX (V4SFmode)));
19420 DONE;
19421 })
19422
19423 (define_insn "sse_loadss_1"
19424 [(set (match_operand:V4SF 0 "register_operand" "=x")
19425 (vec_merge:V4SF
19426 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19427 (match_operand:V4SF 2 "const0_operand" "X")
19428 (const_int 1)))]
19429 "TARGET_SSE"
19430 "movss\t{%1, %0|%0, %1}"
19431 [(set_attr "type" "ssemov")
19432 (set_attr "mode" "SF")])
19433
19434 (define_insn "sse_movss"
19435 [(set (match_operand:V4SF 0 "register_operand" "=x")
19436 (vec_merge:V4SF
19437 (match_operand:V4SF 1 "register_operand" "0")
19438 (match_operand:V4SF 2 "register_operand" "x")
19439 (const_int 1)))]
19440 "TARGET_SSE"
19441 "movss\t{%2, %0|%0, %2}"
19442 [(set_attr "type" "ssemov")
19443 (set_attr "mode" "SF")])
19444
19445 (define_insn "sse_storess"
19446 [(set (match_operand:SF 0 "memory_operand" "=m")
19447 (vec_select:SF
19448 (match_operand:V4SF 1 "register_operand" "x")
19449 (parallel [(const_int 0)])))]
19450 "TARGET_SSE"
19451 "movss\t{%1, %0|%0, %1}"
19452 [(set_attr "type" "ssemov")
19453 (set_attr "mode" "SF")])
19454
19455 (define_insn "sse_shufps"
19456 [(set (match_operand:V4SF 0 "register_operand" "=x")
19457 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19458 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19459 (match_operand:SI 3 "immediate_operand" "i")]
19460 UNSPEC_SHUFFLE))]
19461 "TARGET_SSE"
19462 ;; @@@ check operand order for intel/nonintel syntax
19463 "shufps\t{%3, %2, %0|%0, %2, %3}"
19464 [(set_attr "type" "ssecvt")
19465 (set_attr "mode" "V4SF")])
19466
19467
19468 ;; SSE arithmetic
19469
19470 (define_insn "addv4sf3"
19471 [(set (match_operand:V4SF 0 "register_operand" "=x")
19472 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19473 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19474 "TARGET_SSE"
19475 "addps\t{%2, %0|%0, %2}"
19476 [(set_attr "type" "sseadd")
19477 (set_attr "mode" "V4SF")])
19478
19479 (define_insn "vmaddv4sf3"
19480 [(set (match_operand:V4SF 0 "register_operand" "=x")
19481 (vec_merge:V4SF
19482 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19483 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19484 (match_dup 1)
19485 (const_int 1)))]
19486 "TARGET_SSE"
19487 "addss\t{%2, %0|%0, %2}"
19488 [(set_attr "type" "sseadd")
19489 (set_attr "mode" "SF")])
19490
19491 (define_insn "subv4sf3"
19492 [(set (match_operand:V4SF 0 "register_operand" "=x")
19493 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19494 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19495 "TARGET_SSE"
19496 "subps\t{%2, %0|%0, %2}"
19497 [(set_attr "type" "sseadd")
19498 (set_attr "mode" "V4SF")])
19499
19500 (define_insn "vmsubv4sf3"
19501 [(set (match_operand:V4SF 0 "register_operand" "=x")
19502 (vec_merge:V4SF
19503 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19504 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19505 (match_dup 1)
19506 (const_int 1)))]
19507 "TARGET_SSE"
19508 "subss\t{%2, %0|%0, %2}"
19509 [(set_attr "type" "sseadd")
19510 (set_attr "mode" "SF")])
19511
19512 (define_insn "mulv4sf3"
19513 [(set (match_operand:V4SF 0 "register_operand" "=x")
19514 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19515 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19516 "TARGET_SSE"
19517 "mulps\t{%2, %0|%0, %2}"
19518 [(set_attr "type" "ssemul")
19519 (set_attr "mode" "V4SF")])
19520
19521 (define_insn "vmmulv4sf3"
19522 [(set (match_operand:V4SF 0 "register_operand" "=x")
19523 (vec_merge:V4SF
19524 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19525 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19526 (match_dup 1)
19527 (const_int 1)))]
19528 "TARGET_SSE"
19529 "mulss\t{%2, %0|%0, %2}"
19530 [(set_attr "type" "ssemul")
19531 (set_attr "mode" "SF")])
19532
19533 (define_insn "divv4sf3"
19534 [(set (match_operand:V4SF 0 "register_operand" "=x")
19535 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19536 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19537 "TARGET_SSE"
19538 "divps\t{%2, %0|%0, %2}"
19539 [(set_attr "type" "ssediv")
19540 (set_attr "mode" "V4SF")])
19541
19542 (define_insn "vmdivv4sf3"
19543 [(set (match_operand:V4SF 0 "register_operand" "=x")
19544 (vec_merge:V4SF
19545 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19546 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19547 (match_dup 1)
19548 (const_int 1)))]
19549 "TARGET_SSE"
19550 "divss\t{%2, %0|%0, %2}"
19551 [(set_attr "type" "ssediv")
19552 (set_attr "mode" "SF")])
19553
19554
19555 ;; SSE square root/reciprocal
19556
19557 (define_insn "rcpv4sf2"
19558 [(set (match_operand:V4SF 0 "register_operand" "=x")
19559 (unspec:V4SF
19560 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19561 "TARGET_SSE"
19562 "rcpps\t{%1, %0|%0, %1}"
19563 [(set_attr "type" "sse")
19564 (set_attr "mode" "V4SF")])
19565
19566 (define_insn "vmrcpv4sf2"
19567 [(set (match_operand:V4SF 0 "register_operand" "=x")
19568 (vec_merge:V4SF
19569 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19570 UNSPEC_RCP)
19571 (match_operand:V4SF 2 "register_operand" "0")
19572 (const_int 1)))]
19573 "TARGET_SSE"
19574 "rcpss\t{%1, %0|%0, %1}"
19575 [(set_attr "type" "sse")
19576 (set_attr "mode" "SF")])
19577
19578 (define_insn "rsqrtv4sf2"
19579 [(set (match_operand:V4SF 0 "register_operand" "=x")
19580 (unspec:V4SF
19581 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19582 "TARGET_SSE"
19583 "rsqrtps\t{%1, %0|%0, %1}"
19584 [(set_attr "type" "sse")
19585 (set_attr "mode" "V4SF")])
19586
19587 (define_insn "vmrsqrtv4sf2"
19588 [(set (match_operand:V4SF 0 "register_operand" "=x")
19589 (vec_merge:V4SF
19590 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19591 UNSPEC_RSQRT)
19592 (match_operand:V4SF 2 "register_operand" "0")
19593 (const_int 1)))]
19594 "TARGET_SSE"
19595 "rsqrtss\t{%1, %0|%0, %1}"
19596 [(set_attr "type" "sse")
19597 (set_attr "mode" "SF")])
19598
19599 (define_insn "sqrtv4sf2"
19600 [(set (match_operand:V4SF 0 "register_operand" "=x")
19601 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19602 "TARGET_SSE"
19603 "sqrtps\t{%1, %0|%0, %1}"
19604 [(set_attr "type" "sse")
19605 (set_attr "mode" "V4SF")])
19606
19607 (define_insn "vmsqrtv4sf2"
19608 [(set (match_operand:V4SF 0 "register_operand" "=x")
19609 (vec_merge:V4SF
19610 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19611 (match_operand:V4SF 2 "register_operand" "0")
19612 (const_int 1)))]
19613 "TARGET_SSE"
19614 "sqrtss\t{%1, %0|%0, %1}"
19615 [(set_attr "type" "sse")
19616 (set_attr "mode" "SF")])
19617
19618 ;; SSE logical operations.
19619
19620 ;; SSE defines logical operations on floating point values. This brings
19621 ;; interesting challenge to RTL representation where logicals are only valid
19622 ;; on integral types. We deal with this by representing the floating point
19623 ;; logical as logical on arguments casted to TImode as this is what hardware
19624 ;; really does. Unfortunately hardware requires the type information to be
19625 ;; present and thus we must avoid subregs from being simplified and eliminated
19626 ;; in later compilation phases.
19627 ;;
19628 ;; We have following variants from each instruction:
19629 ;; sse_andsf3 - the operation taking V4SF vector operands
19630 ;; and doing TImode cast on them
19631 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19632 ;; TImode, since backend insist on eliminating casts
19633 ;; on memory operands
19634 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19635 ;; We can not accept memory operand here as instruction reads
19636 ;; whole scalar. This is generated only post reload by GCC
19637 ;; scalar float operations that expands to logicals (fabs)
19638 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19639 ;; memory operand. Eventually combine can be able
19640 ;; to synthesize these using splitter.
19641 ;; sse2_anddf3, *sse2_anddf3_memory
19642 ;;
19643 ;;
19644 ;; These are not called andti3 etc. because we really really don't want
19645 ;; the compiler to widen DImode ands to TImode ands and then try to move
19646 ;; into DImode subregs of SSE registers, and them together, and move out
19647 ;; of DImode subregs again!
19648 ;; SSE1 single precision floating point logical operation
19649 (define_expand "sse_andv4sf3"
19650 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19651 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19652 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19653 "TARGET_SSE"
19654 "")
19655
19656 (define_insn "*sse_andv4sf3"
19657 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19658 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19659 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19660 "TARGET_SSE
19661 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19662 "andps\t{%2, %0|%0, %2}"
19663 [(set_attr "type" "sselog")
19664 (set_attr "mode" "V4SF")])
19665
19666 (define_insn "*sse_andsf3"
19667 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19668 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19669 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19670 "TARGET_SSE
19671 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19672 "andps\t{%2, %0|%0, %2}"
19673 [(set_attr "type" "sselog")
19674 (set_attr "mode" "V4SF")])
19675
19676 (define_expand "sse_nandv4sf3"
19677 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19678 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19679 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19680 "TARGET_SSE"
19681 "")
19682
19683 (define_insn "*sse_nandv4sf3"
19684 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19685 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19686 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19687 "TARGET_SSE"
19688 "andnps\t{%2, %0|%0, %2}"
19689 [(set_attr "type" "sselog")
19690 (set_attr "mode" "V4SF")])
19691
19692 (define_insn "*sse_nandsf3"
19693 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19694 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19695 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19696 "TARGET_SSE"
19697 "andnps\t{%2, %0|%0, %2}"
19698 [(set_attr "type" "sselog")
19699 (set_attr "mode" "V4SF")])
19700
19701 (define_expand "sse_iorv4sf3"
19702 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19703 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19704 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19705 "TARGET_SSE"
19706 "")
19707
19708 (define_insn "*sse_iorv4sf3"
19709 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19710 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19711 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19712 "TARGET_SSE
19713 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19714 "orps\t{%2, %0|%0, %2}"
19715 [(set_attr "type" "sselog")
19716 (set_attr "mode" "V4SF")])
19717
19718 (define_insn "*sse_iorsf3"
19719 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19720 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19721 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19722 "TARGET_SSE
19723 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19724 "orps\t{%2, %0|%0, %2}"
19725 [(set_attr "type" "sselog")
19726 (set_attr "mode" "V4SF")])
19727
19728 (define_expand "sse_xorv4sf3"
19729 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19730 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19731 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19732 "TARGET_SSE
19733 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19734 "")
19735
19736 (define_insn "*sse_xorv4sf3"
19737 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19738 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19739 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19740 "TARGET_SSE
19741 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19742 "xorps\t{%2, %0|%0, %2}"
19743 [(set_attr "type" "sselog")
19744 (set_attr "mode" "V4SF")])
19745
19746 (define_insn "*sse_xorsf3"
19747 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19748 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19749 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19750 "TARGET_SSE
19751 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19752 "xorps\t{%2, %0|%0, %2}"
19753 [(set_attr "type" "sselog")
19754 (set_attr "mode" "V4SF")])
19755
19756 ;; SSE2 double precision floating point logical operation
19757
19758 (define_expand "sse2_andv2df3"
19759 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19760 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19761 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19762 "TARGET_SSE2"
19763 "")
19764
19765 (define_insn "*sse2_andv2df3"
19766 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19767 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19768 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19769 "TARGET_SSE2
19770 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19771 "andpd\t{%2, %0|%0, %2}"
19772 [(set_attr "type" "sselog")
19773 (set_attr "mode" "V2DF")])
19774
19775 (define_insn "*sse2_andv2df3"
19776 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19777 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19778 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19779 "TARGET_SSE2
19780 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19781 "andpd\t{%2, %0|%0, %2}"
19782 [(set_attr "type" "sselog")
19783 (set_attr "mode" "V2DF")])
19784
19785 (define_expand "sse2_nandv2df3"
19786 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19787 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19788 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19789 "TARGET_SSE2"
19790 "")
19791
19792 (define_insn "*sse2_nandv2df3"
19793 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19794 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19795 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19796 "TARGET_SSE2"
19797 "andnpd\t{%2, %0|%0, %2}"
19798 [(set_attr "type" "sselog")
19799 (set_attr "mode" "V2DF")])
19800
19801 (define_insn "*sse_nandti3_df"
19802 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19803 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19804 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19805 "TARGET_SSE2"
19806 "andnpd\t{%2, %0|%0, %2}"
19807 [(set_attr "type" "sselog")
19808 (set_attr "mode" "V2DF")])
19809
19810 (define_expand "sse2_iorv2df3"
19811 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19812 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19813 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19814 "TARGET_SSE2"
19815 "")
19816
19817 (define_insn "*sse2_iorv2df3"
19818 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19819 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19820 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19821 "TARGET_SSE2
19822 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19823 "orpd\t{%2, %0|%0, %2}"
19824 [(set_attr "type" "sselog")
19825 (set_attr "mode" "V2DF")])
19826
19827 (define_insn "*sse2_iordf3"
19828 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19829 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19830 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19831 "TARGET_SSE2
19832 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19833 "orpd\t{%2, %0|%0, %2}"
19834 [(set_attr "type" "sselog")
19835 (set_attr "mode" "V2DF")])
19836
19837 (define_expand "sse2_xorv2df3"
19838 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19839 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19840 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19841 "TARGET_SSE2"
19842 "")
19843
19844 (define_insn "*sse2_xorv2df3"
19845 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19846 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19847 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19848 "TARGET_SSE2
19849 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19850 "xorpd\t{%2, %0|%0, %2}"
19851 [(set_attr "type" "sselog")
19852 (set_attr "mode" "V2DF")])
19853
19854 (define_insn "*sse2_xordf3"
19855 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19856 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19857 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19858 "TARGET_SSE2
19859 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19860 "xorpd\t{%2, %0|%0, %2}"
19861 [(set_attr "type" "sselog")
19862 (set_attr "mode" "V2DF")])
19863
19864 ;; SSE2 integral logicals. These patterns must always come after floating
19865 ;; point ones since we don't want compiler to use integer opcodes on floating
19866 ;; point SSE values to avoid matching of subregs in the match_operand.
19867 (define_insn "*sse2_andti3"
19868 [(set (match_operand:TI 0 "register_operand" "=x")
19869 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19870 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19871 "TARGET_SSE2
19872 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19873 "pand\t{%2, %0|%0, %2}"
19874 [(set_attr "type" "sselog")
19875 (set_attr "mode" "TI")])
19876
19877 (define_insn "sse2_andv2di3"
19878 [(set (match_operand:V2DI 0 "register_operand" "=x")
19879 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19880 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19881 "TARGET_SSE2
19882 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19883 "pand\t{%2, %0|%0, %2}"
19884 [(set_attr "type" "sselog")
19885 (set_attr "mode" "TI")])
19886
19887 (define_insn "*sse2_nandti3"
19888 [(set (match_operand:TI 0 "register_operand" "=x")
19889 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19890 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19891 "TARGET_SSE2"
19892 "pandn\t{%2, %0|%0, %2}"
19893 [(set_attr "type" "sselog")
19894 (set_attr "mode" "TI")])
19895
19896 (define_insn "sse2_nandv2di3"
19897 [(set (match_operand:V2DI 0 "register_operand" "=x")
19898 (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "0"))
19899 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19900 "TARGET_SSE2
19901 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19902 "pandn\t{%2, %0|%0, %2}"
19903 [(set_attr "type" "sselog")
19904 (set_attr "mode" "TI")])
19905
19906 (define_insn "*sse2_iorti3"
19907 [(set (match_operand:TI 0 "register_operand" "=x")
19908 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19909 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19910 "TARGET_SSE2
19911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19912 "por\t{%2, %0|%0, %2}"
19913 [(set_attr "type" "sselog")
19914 (set_attr "mode" "TI")])
19915
19916 (define_insn "sse2_iorv2di3"
19917 [(set (match_operand:V2DI 0 "register_operand" "=x")
19918 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19919 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19920 "TARGET_SSE2
19921 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19922 "por\t{%2, %0|%0, %2}"
19923 [(set_attr "type" "sselog")
19924 (set_attr "mode" "TI")])
19925
19926 (define_insn "*sse2_xorti3"
19927 [(set (match_operand:TI 0 "register_operand" "=x")
19928 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19929 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19930 "TARGET_SSE2
19931 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19932 "pxor\t{%2, %0|%0, %2}"
19933 [(set_attr "type" "sselog")
19934 (set_attr "mode" "TI")])
19935
19936 (define_insn "sse2_xorv2di3"
19937 [(set (match_operand:V2DI 0 "register_operand" "=x")
19938 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19939 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19940 "TARGET_SSE2
19941 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19942 "pxor\t{%2, %0|%0, %2}"
19943 [(set_attr "type" "sselog")
19944 (set_attr "mode" "TI")])
19945
19946 ;; Use xor, but don't show input operands so they aren't live before
19947 ;; this insn.
19948 (define_insn "sse_clrv4sf"
19949 [(set (match_operand:V4SF 0 "register_operand" "=x")
19950 (match_operand:V4SF 1 "const0_operand" "X"))]
19951 "TARGET_SSE"
19952 {
19953 if (get_attr_mode (insn) == MODE_TI)
19954 return "pxor\t{%0, %0|%0, %0}";
19955 else
19956 return "xorps\t{%0, %0|%0, %0}";
19957 }
19958 [(set_attr "type" "sselog")
19959 (set_attr "memory" "none")
19960 (set (attr "mode")
19961 (if_then_else
19962 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19963 (const_int 0))
19964 (ne (symbol_ref "TARGET_SSE2")
19965 (const_int 0)))
19966 (eq (symbol_ref "optimize_size")
19967 (const_int 0)))
19968 (const_string "TI")
19969 (const_string "V4SF")))])
19970
19971 ;; Use xor, but don't show input operands so they aren't live before
19972 ;; this insn.
19973 (define_insn "sse_clrv2df"
19974 [(set (match_operand:V2DF 0 "register_operand" "=x")
19975 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19976 "TARGET_SSE2"
19977 "xorpd\t{%0, %0|%0, %0}"
19978 [(set_attr "type" "sselog")
19979 (set_attr "memory" "none")
19980 (set_attr "mode" "V4SF")])
19981
19982 ;; SSE mask-generating compares
19983
19984 (define_insn "maskcmpv4sf3"
19985 [(set (match_operand:V4SI 0 "register_operand" "=x")
19986 (match_operator:V4SI 3 "sse_comparison_operator"
19987 [(match_operand:V4SF 1 "register_operand" "0")
19988 (match_operand:V4SF 2 "register_operand" "x")]))]
19989 "TARGET_SSE"
19990 "cmp%D3ps\t{%2, %0|%0, %2}"
19991 [(set_attr "type" "ssecmp")
19992 (set_attr "mode" "V4SF")])
19993
19994 (define_insn "maskncmpv4sf3"
19995 [(set (match_operand:V4SI 0 "register_operand" "=x")
19996 (not:V4SI
19997 (match_operator:V4SI 3 "sse_comparison_operator"
19998 [(match_operand:V4SF 1 "register_operand" "0")
19999 (match_operand:V4SF 2 "register_operand" "x")])))]
20000 "TARGET_SSE"
20001 {
20002 if (GET_CODE (operands[3]) == UNORDERED)
20003 return "cmpordps\t{%2, %0|%0, %2}";
20004 else
20005 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20006 }
20007 [(set_attr "type" "ssecmp")
20008 (set_attr "mode" "V4SF")])
20009
20010 (define_insn "vmmaskcmpv4sf3"
20011 [(set (match_operand:V4SI 0 "register_operand" "=x")
20012 (vec_merge:V4SI
20013 (match_operator:V4SI 3 "sse_comparison_operator"
20014 [(match_operand:V4SF 1 "register_operand" "0")
20015 (match_operand:V4SF 2 "register_operand" "x")])
20016 (subreg:V4SI (match_dup 1) 0)
20017 (const_int 1)))]
20018 "TARGET_SSE"
20019 "cmp%D3ss\t{%2, %0|%0, %2}"
20020 [(set_attr "type" "ssecmp")
20021 (set_attr "mode" "SF")])
20022
20023 (define_insn "vmmaskncmpv4sf3"
20024 [(set (match_operand:V4SI 0 "register_operand" "=x")
20025 (vec_merge:V4SI
20026 (not:V4SI
20027 (match_operator:V4SI 3 "sse_comparison_operator"
20028 [(match_operand:V4SF 1 "register_operand" "0")
20029 (match_operand:V4SF 2 "register_operand" "x")]))
20030 (subreg:V4SI (match_dup 1) 0)
20031 (const_int 1)))]
20032 "TARGET_SSE"
20033 {
20034 if (GET_CODE (operands[3]) == UNORDERED)
20035 return "cmpordss\t{%2, %0|%0, %2}";
20036 else
20037 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20038 }
20039 [(set_attr "type" "ssecmp")
20040 (set_attr "mode" "SF")])
20041
20042 (define_insn "sse_comi"
20043 [(set (reg:CCFP 17)
20044 (compare:CCFP (vec_select:SF
20045 (match_operand:V4SF 0 "register_operand" "x")
20046 (parallel [(const_int 0)]))
20047 (vec_select:SF
20048 (match_operand:V4SF 1 "register_operand" "x")
20049 (parallel [(const_int 0)]))))]
20050 "TARGET_SSE"
20051 "comiss\t{%1, %0|%0, %1}"
20052 [(set_attr "type" "ssecomi")
20053 (set_attr "mode" "SF")])
20054
20055 (define_insn "sse_ucomi"
20056 [(set (reg:CCFPU 17)
20057 (compare:CCFPU (vec_select:SF
20058 (match_operand:V4SF 0 "register_operand" "x")
20059 (parallel [(const_int 0)]))
20060 (vec_select:SF
20061 (match_operand:V4SF 1 "register_operand" "x")
20062 (parallel [(const_int 0)]))))]
20063 "TARGET_SSE"
20064 "ucomiss\t{%1, %0|%0, %1}"
20065 [(set_attr "type" "ssecomi")
20066 (set_attr "mode" "SF")])
20067
20068
20069 ;; SSE unpack
20070
20071 (define_insn "sse_unpckhps"
20072 [(set (match_operand:V4SF 0 "register_operand" "=x")
20073 (vec_merge:V4SF
20074 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20075 (parallel [(const_int 2)
20076 (const_int 0)
20077 (const_int 3)
20078 (const_int 1)]))
20079 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20080 (parallel [(const_int 0)
20081 (const_int 2)
20082 (const_int 1)
20083 (const_int 3)]))
20084 (const_int 5)))]
20085 "TARGET_SSE"
20086 "unpckhps\t{%2, %0|%0, %2}"
20087 [(set_attr "type" "ssecvt")
20088 (set_attr "mode" "V4SF")])
20089
20090 (define_insn "sse_unpcklps"
20091 [(set (match_operand:V4SF 0 "register_operand" "=x")
20092 (vec_merge:V4SF
20093 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20094 (parallel [(const_int 0)
20095 (const_int 2)
20096 (const_int 1)
20097 (const_int 3)]))
20098 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20099 (parallel [(const_int 2)
20100 (const_int 0)
20101 (const_int 3)
20102 (const_int 1)]))
20103 (const_int 5)))]
20104 "TARGET_SSE"
20105 "unpcklps\t{%2, %0|%0, %2}"
20106 [(set_attr "type" "ssecvt")
20107 (set_attr "mode" "V4SF")])
20108
20109
20110 ;; SSE min/max
20111
20112 (define_insn "smaxv4sf3"
20113 [(set (match_operand:V4SF 0 "register_operand" "=x")
20114 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20115 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20116 "TARGET_SSE"
20117 "maxps\t{%2, %0|%0, %2}"
20118 [(set_attr "type" "sse")
20119 (set_attr "mode" "V4SF")])
20120
20121 (define_insn "vmsmaxv4sf3"
20122 [(set (match_operand:V4SF 0 "register_operand" "=x")
20123 (vec_merge:V4SF
20124 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20125 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20126 (match_dup 1)
20127 (const_int 1)))]
20128 "TARGET_SSE"
20129 "maxss\t{%2, %0|%0, %2}"
20130 [(set_attr "type" "sse")
20131 (set_attr "mode" "SF")])
20132
20133 (define_insn "sminv4sf3"
20134 [(set (match_operand:V4SF 0 "register_operand" "=x")
20135 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20136 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20137 "TARGET_SSE"
20138 "minps\t{%2, %0|%0, %2}"
20139 [(set_attr "type" "sse")
20140 (set_attr "mode" "V4SF")])
20141
20142 (define_insn "vmsminv4sf3"
20143 [(set (match_operand:V4SF 0 "register_operand" "=x")
20144 (vec_merge:V4SF
20145 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20146 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20147 (match_dup 1)
20148 (const_int 1)))]
20149 "TARGET_SSE"
20150 "minss\t{%2, %0|%0, %2}"
20151 [(set_attr "type" "sse")
20152 (set_attr "mode" "SF")])
20153
20154 ;; SSE <-> integer/MMX conversions
20155
20156 (define_insn "cvtpi2ps"
20157 [(set (match_operand:V4SF 0 "register_operand" "=x")
20158 (vec_merge:V4SF
20159 (match_operand:V4SF 1 "register_operand" "0")
20160 (vec_duplicate:V4SF
20161 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20162 (const_int 12)))]
20163 "TARGET_SSE"
20164 "cvtpi2ps\t{%2, %0|%0, %2}"
20165 [(set_attr "type" "ssecvt")
20166 (set_attr "mode" "V4SF")])
20167
20168 (define_insn "cvtps2pi"
20169 [(set (match_operand:V2SI 0 "register_operand" "=y")
20170 (vec_select:V2SI
20171 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20172 (parallel [(const_int 0) (const_int 1)])))]
20173 "TARGET_SSE"
20174 "cvtps2pi\t{%1, %0|%0, %1}"
20175 [(set_attr "type" "ssecvt")
20176 (set_attr "mode" "V4SF")])
20177
20178 (define_insn "cvttps2pi"
20179 [(set (match_operand:V2SI 0 "register_operand" "=y")
20180 (vec_select:V2SI
20181 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20182 UNSPEC_FIX)
20183 (parallel [(const_int 0) (const_int 1)])))]
20184 "TARGET_SSE"
20185 "cvttps2pi\t{%1, %0|%0, %1}"
20186 [(set_attr "type" "ssecvt")
20187 (set_attr "mode" "SF")])
20188
20189 (define_insn "cvtsi2ss"
20190 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20191 (vec_merge:V4SF
20192 (match_operand:V4SF 1 "register_operand" "0,0")
20193 (vec_duplicate:V4SF
20194 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20195 (const_int 14)))]
20196 "TARGET_SSE"
20197 "cvtsi2ss\t{%2, %0|%0, %2}"
20198 [(set_attr "type" "sseicvt")
20199 (set_attr "athlon_decode" "vector,double")
20200 (set_attr "mode" "SF")])
20201
20202 (define_insn "cvtsi2ssq"
20203 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20204 (vec_merge:V4SF
20205 (match_operand:V4SF 1 "register_operand" "0,0")
20206 (vec_duplicate:V4SF
20207 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20208 (const_int 14)))]
20209 "TARGET_SSE && TARGET_64BIT"
20210 "cvtsi2ssq\t{%2, %0|%0, %2}"
20211 [(set_attr "type" "sseicvt")
20212 (set_attr "athlon_decode" "vector,double")
20213 (set_attr "mode" "SF")])
20214
20215 (define_insn "cvtss2si"
20216 [(set (match_operand:SI 0 "register_operand" "=r,r")
20217 (vec_select:SI
20218 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20219 (parallel [(const_int 0)])))]
20220 "TARGET_SSE"
20221 "cvtss2si\t{%1, %0|%0, %1}"
20222 [(set_attr "type" "sseicvt")
20223 (set_attr "athlon_decode" "double,vector")
20224 (set_attr "mode" "SF")])
20225
20226 (define_insn "cvtss2siq"
20227 [(set (match_operand:DI 0 "register_operand" "=r,r")
20228 (vec_select:DI
20229 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20230 (parallel [(const_int 0)])))]
20231 "TARGET_SSE"
20232 "cvtss2siq\t{%1, %0|%0, %1}"
20233 [(set_attr "type" "sseicvt")
20234 (set_attr "athlon_decode" "double,vector")
20235 (set_attr "mode" "SF")])
20236
20237 (define_insn "cvttss2si"
20238 [(set (match_operand:SI 0 "register_operand" "=r,r")
20239 (vec_select:SI
20240 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20241 UNSPEC_FIX)
20242 (parallel [(const_int 0)])))]
20243 "TARGET_SSE"
20244 "cvttss2si\t{%1, %0|%0, %1}"
20245 [(set_attr "type" "sseicvt")
20246 (set_attr "mode" "SF")
20247 (set_attr "athlon_decode" "double,vector")])
20248
20249 (define_insn "cvttss2siq"
20250 [(set (match_operand:DI 0 "register_operand" "=r,r")
20251 (vec_select:DI
20252 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20253 UNSPEC_FIX)
20254 (parallel [(const_int 0)])))]
20255 "TARGET_SSE && TARGET_64BIT"
20256 "cvttss2siq\t{%1, %0|%0, %1}"
20257 [(set_attr "type" "sseicvt")
20258 (set_attr "mode" "SF")
20259 (set_attr "athlon_decode" "double,vector")])
20260
20261
20262 ;; MMX insns
20263
20264 ;; MMX arithmetic
20265
20266 (define_insn "addv8qi3"
20267 [(set (match_operand:V8QI 0 "register_operand" "=y")
20268 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20269 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20270 "TARGET_MMX"
20271 "paddb\t{%2, %0|%0, %2}"
20272 [(set_attr "type" "mmxadd")
20273 (set_attr "mode" "DI")])
20274
20275 (define_insn "addv4hi3"
20276 [(set (match_operand:V4HI 0 "register_operand" "=y")
20277 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20278 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20279 "TARGET_MMX"
20280 "paddw\t{%2, %0|%0, %2}"
20281 [(set_attr "type" "mmxadd")
20282 (set_attr "mode" "DI")])
20283
20284 (define_insn "addv2si3"
20285 [(set (match_operand:V2SI 0 "register_operand" "=y")
20286 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20287 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20288 "TARGET_MMX"
20289 "paddd\t{%2, %0|%0, %2}"
20290 [(set_attr "type" "mmxadd")
20291 (set_attr "mode" "DI")])
20292
20293 (define_insn "mmx_adddi3"
20294 [(set (match_operand:DI 0 "register_operand" "=y")
20295 (unspec:DI
20296 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20297 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20298 UNSPEC_NOP))]
20299 "TARGET_MMX"
20300 "paddq\t{%2, %0|%0, %2}"
20301 [(set_attr "type" "mmxadd")
20302 (set_attr "mode" "DI")])
20303
20304 (define_insn "ssaddv8qi3"
20305 [(set (match_operand:V8QI 0 "register_operand" "=y")
20306 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20307 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20308 "TARGET_MMX"
20309 "paddsb\t{%2, %0|%0, %2}"
20310 [(set_attr "type" "mmxadd")
20311 (set_attr "mode" "DI")])
20312
20313 (define_insn "ssaddv4hi3"
20314 [(set (match_operand:V4HI 0 "register_operand" "=y")
20315 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20316 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20317 "TARGET_MMX"
20318 "paddsw\t{%2, %0|%0, %2}"
20319 [(set_attr "type" "mmxadd")
20320 (set_attr "mode" "DI")])
20321
20322 (define_insn "usaddv8qi3"
20323 [(set (match_operand:V8QI 0 "register_operand" "=y")
20324 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20325 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20326 "TARGET_MMX"
20327 "paddusb\t{%2, %0|%0, %2}"
20328 [(set_attr "type" "mmxadd")
20329 (set_attr "mode" "DI")])
20330
20331 (define_insn "usaddv4hi3"
20332 [(set (match_operand:V4HI 0 "register_operand" "=y")
20333 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20334 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20335 "TARGET_MMX"
20336 "paddusw\t{%2, %0|%0, %2}"
20337 [(set_attr "type" "mmxadd")
20338 (set_attr "mode" "DI")])
20339
20340 (define_insn "subv8qi3"
20341 [(set (match_operand:V8QI 0 "register_operand" "=y")
20342 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20343 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20344 "TARGET_MMX"
20345 "psubb\t{%2, %0|%0, %2}"
20346 [(set_attr "type" "mmxadd")
20347 (set_attr "mode" "DI")])
20348
20349 (define_insn "subv4hi3"
20350 [(set (match_operand:V4HI 0 "register_operand" "=y")
20351 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20352 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20353 "TARGET_MMX"
20354 "psubw\t{%2, %0|%0, %2}"
20355 [(set_attr "type" "mmxadd")
20356 (set_attr "mode" "DI")])
20357
20358 (define_insn "subv2si3"
20359 [(set (match_operand:V2SI 0 "register_operand" "=y")
20360 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20361 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20362 "TARGET_MMX"
20363 "psubd\t{%2, %0|%0, %2}"
20364 [(set_attr "type" "mmxadd")
20365 (set_attr "mode" "DI")])
20366
20367 (define_insn "mmx_subdi3"
20368 [(set (match_operand:DI 0 "register_operand" "=y")
20369 (unspec:DI
20370 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20371 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20372 UNSPEC_NOP))]
20373 "TARGET_MMX"
20374 "psubq\t{%2, %0|%0, %2}"
20375 [(set_attr "type" "mmxadd")
20376 (set_attr "mode" "DI")])
20377
20378 (define_insn "sssubv8qi3"
20379 [(set (match_operand:V8QI 0 "register_operand" "=y")
20380 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20381 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20382 "TARGET_MMX"
20383 "psubsb\t{%2, %0|%0, %2}"
20384 [(set_attr "type" "mmxadd")
20385 (set_attr "mode" "DI")])
20386
20387 (define_insn "sssubv4hi3"
20388 [(set (match_operand:V4HI 0 "register_operand" "=y")
20389 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20390 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20391 "TARGET_MMX"
20392 "psubsw\t{%2, %0|%0, %2}"
20393 [(set_attr "type" "mmxadd")
20394 (set_attr "mode" "DI")])
20395
20396 (define_insn "ussubv8qi3"
20397 [(set (match_operand:V8QI 0 "register_operand" "=y")
20398 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20399 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20400 "TARGET_MMX"
20401 "psubusb\t{%2, %0|%0, %2}"
20402 [(set_attr "type" "mmxadd")
20403 (set_attr "mode" "DI")])
20404
20405 (define_insn "ussubv4hi3"
20406 [(set (match_operand:V4HI 0 "register_operand" "=y")
20407 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20408 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20409 "TARGET_MMX"
20410 "psubusw\t{%2, %0|%0, %2}"
20411 [(set_attr "type" "mmxadd")
20412 (set_attr "mode" "DI")])
20413
20414 (define_insn "mulv4hi3"
20415 [(set (match_operand:V4HI 0 "register_operand" "=y")
20416 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20417 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20418 "TARGET_MMX"
20419 "pmullw\t{%2, %0|%0, %2}"
20420 [(set_attr "type" "mmxmul")
20421 (set_attr "mode" "DI")])
20422
20423 (define_insn "smulv4hi3_highpart"
20424 [(set (match_operand:V4HI 0 "register_operand" "=y")
20425 (truncate:V4HI
20426 (lshiftrt:V4SI
20427 (mult:V4SI (sign_extend:V4SI
20428 (match_operand:V4HI 1 "register_operand" "0"))
20429 (sign_extend:V4SI
20430 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20431 (const_int 16))))]
20432 "TARGET_MMX"
20433 "pmulhw\t{%2, %0|%0, %2}"
20434 [(set_attr "type" "mmxmul")
20435 (set_attr "mode" "DI")])
20436
20437 (define_insn "umulv4hi3_highpart"
20438 [(set (match_operand:V4HI 0 "register_operand" "=y")
20439 (truncate:V4HI
20440 (lshiftrt:V4SI
20441 (mult:V4SI (zero_extend:V4SI
20442 (match_operand:V4HI 1 "register_operand" "0"))
20443 (zero_extend:V4SI
20444 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20445 (const_int 16))))]
20446 "TARGET_SSE || TARGET_3DNOW_A"
20447 "pmulhuw\t{%2, %0|%0, %2}"
20448 [(set_attr "type" "mmxmul")
20449 (set_attr "mode" "DI")])
20450
20451 (define_insn "mmx_pmaddwd"
20452 [(set (match_operand:V2SI 0 "register_operand" "=y")
20453 (plus:V2SI
20454 (mult:V2SI
20455 (sign_extend:V2SI
20456 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20457 (parallel [(const_int 0) (const_int 2)])))
20458 (sign_extend:V2SI
20459 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20460 (parallel [(const_int 0) (const_int 2)]))))
20461 (mult:V2SI
20462 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20463 (parallel [(const_int 1)
20464 (const_int 3)])))
20465 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20466 (parallel [(const_int 1)
20467 (const_int 3)]))))))]
20468 "TARGET_MMX"
20469 "pmaddwd\t{%2, %0|%0, %2}"
20470 [(set_attr "type" "mmxmul")
20471 (set_attr "mode" "DI")])
20472
20473
20474 ;; MMX logical operations
20475 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20476 ;; normal code that also wants to use the FPU from getting broken.
20477 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20478 (define_insn "mmx_iordi3"
20479 [(set (match_operand:DI 0 "register_operand" "=y")
20480 (unspec:DI
20481 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20482 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20483 UNSPEC_NOP))]
20484 "TARGET_MMX"
20485 "por\t{%2, %0|%0, %2}"
20486 [(set_attr "type" "mmxadd")
20487 (set_attr "mode" "DI")])
20488
20489 (define_insn "mmx_xordi3"
20490 [(set (match_operand:DI 0 "register_operand" "=y")
20491 (unspec:DI
20492 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20493 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20494 UNSPEC_NOP))]
20495 "TARGET_MMX"
20496 "pxor\t{%2, %0|%0, %2}"
20497 [(set_attr "type" "mmxadd")
20498 (set_attr "mode" "DI")
20499 (set_attr "memory" "none")])
20500
20501 ;; Same as pxor, but don't show input operands so that we don't think
20502 ;; they are live.
20503 (define_insn "mmx_clrdi"
20504 [(set (match_operand:DI 0 "register_operand" "=y")
20505 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20506 "TARGET_MMX"
20507 "pxor\t{%0, %0|%0, %0}"
20508 [(set_attr "type" "mmxadd")
20509 (set_attr "mode" "DI")
20510 (set_attr "memory" "none")])
20511
20512 (define_insn "mmx_anddi3"
20513 [(set (match_operand:DI 0 "register_operand" "=y")
20514 (unspec:DI
20515 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20516 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20517 UNSPEC_NOP))]
20518 "TARGET_MMX"
20519 "pand\t{%2, %0|%0, %2}"
20520 [(set_attr "type" "mmxadd")
20521 (set_attr "mode" "DI")])
20522
20523 (define_insn "mmx_nanddi3"
20524 [(set (match_operand:DI 0 "register_operand" "=y")
20525 (unspec:DI
20526 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20527 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20528 UNSPEC_NOP))]
20529 "TARGET_MMX"
20530 "pandn\t{%2, %0|%0, %2}"
20531 [(set_attr "type" "mmxadd")
20532 (set_attr "mode" "DI")])
20533
20534
20535 ;; MMX unsigned averages/sum of absolute differences
20536
20537 (define_insn "mmx_uavgv8qi3"
20538 [(set (match_operand:V8QI 0 "register_operand" "=y")
20539 (ashiftrt:V8QI
20540 (plus:V8QI (plus:V8QI
20541 (match_operand:V8QI 1 "register_operand" "0")
20542 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20543 (const_vector:V8QI [(const_int 1)
20544 (const_int 1)
20545 (const_int 1)
20546 (const_int 1)
20547 (const_int 1)
20548 (const_int 1)
20549 (const_int 1)
20550 (const_int 1)]))
20551 (const_int 1)))]
20552 "TARGET_SSE || TARGET_3DNOW_A"
20553 "pavgb\t{%2, %0|%0, %2}"
20554 [(set_attr "type" "mmxshft")
20555 (set_attr "mode" "DI")])
20556
20557 (define_insn "mmx_uavgv4hi3"
20558 [(set (match_operand:V4HI 0 "register_operand" "=y")
20559 (ashiftrt:V4HI
20560 (plus:V4HI (plus:V4HI
20561 (match_operand:V4HI 1 "register_operand" "0")
20562 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20563 (const_vector:V4HI [(const_int 1)
20564 (const_int 1)
20565 (const_int 1)
20566 (const_int 1)]))
20567 (const_int 1)))]
20568 "TARGET_SSE || TARGET_3DNOW_A"
20569 "pavgw\t{%2, %0|%0, %2}"
20570 [(set_attr "type" "mmxshft")
20571 (set_attr "mode" "DI")])
20572
20573 (define_insn "mmx_psadbw"
20574 [(set (match_operand:DI 0 "register_operand" "=y")
20575 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20576 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20577 UNSPEC_PSADBW))]
20578 "TARGET_SSE || TARGET_3DNOW_A"
20579 "psadbw\t{%2, %0|%0, %2}"
20580 [(set_attr "type" "mmxshft")
20581 (set_attr "mode" "DI")])
20582
20583
20584 ;; MMX insert/extract/shuffle
20585
20586 (define_insn "mmx_pinsrw"
20587 [(set (match_operand:V4HI 0 "register_operand" "=y")
20588 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20589 (vec_duplicate:V4HI
20590 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20591 (match_operand:SI 3 "immediate_operand" "i")))]
20592 "TARGET_SSE || TARGET_3DNOW_A"
20593 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20594 [(set_attr "type" "mmxcvt")
20595 (set_attr "mode" "DI")])
20596
20597 (define_insn "mmx_pextrw"
20598 [(set (match_operand:SI 0 "register_operand" "=r")
20599 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20600 (parallel
20601 [(match_operand:SI 2 "immediate_operand" "i")]))))]
20602 "TARGET_SSE || TARGET_3DNOW_A"
20603 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20604 [(set_attr "type" "mmxcvt")
20605 (set_attr "mode" "DI")])
20606
20607 (define_insn "mmx_pshufw"
20608 [(set (match_operand:V4HI 0 "register_operand" "=y")
20609 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20610 (match_operand:SI 2 "immediate_operand" "i")]
20611 UNSPEC_SHUFFLE))]
20612 "TARGET_SSE || TARGET_3DNOW_A"
20613 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20614 [(set_attr "type" "mmxcvt")
20615 (set_attr "mode" "DI")])
20616
20617
20618 ;; MMX mask-generating comparisons
20619
20620 (define_insn "eqv8qi3"
20621 [(set (match_operand:V8QI 0 "register_operand" "=y")
20622 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20623 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20624 "TARGET_MMX"
20625 "pcmpeqb\t{%2, %0|%0, %2}"
20626 [(set_attr "type" "mmxcmp")
20627 (set_attr "mode" "DI")])
20628
20629 (define_insn "eqv4hi3"
20630 [(set (match_operand:V4HI 0 "register_operand" "=y")
20631 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20632 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20633 "TARGET_MMX"
20634 "pcmpeqw\t{%2, %0|%0, %2}"
20635 [(set_attr "type" "mmxcmp")
20636 (set_attr "mode" "DI")])
20637
20638 (define_insn "eqv2si3"
20639 [(set (match_operand:V2SI 0 "register_operand" "=y")
20640 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20641 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20642 "TARGET_MMX"
20643 "pcmpeqd\t{%2, %0|%0, %2}"
20644 [(set_attr "type" "mmxcmp")
20645 (set_attr "mode" "DI")])
20646
20647 (define_insn "gtv8qi3"
20648 [(set (match_operand:V8QI 0 "register_operand" "=y")
20649 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20650 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20651 "TARGET_MMX"
20652 "pcmpgtb\t{%2, %0|%0, %2}"
20653 [(set_attr "type" "mmxcmp")
20654 (set_attr "mode" "DI")])
20655
20656 (define_insn "gtv4hi3"
20657 [(set (match_operand:V4HI 0 "register_operand" "=y")
20658 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20659 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20660 "TARGET_MMX"
20661 "pcmpgtw\t{%2, %0|%0, %2}"
20662 [(set_attr "type" "mmxcmp")
20663 (set_attr "mode" "DI")])
20664
20665 (define_insn "gtv2si3"
20666 [(set (match_operand:V2SI 0 "register_operand" "=y")
20667 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20668 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20669 "TARGET_MMX"
20670 "pcmpgtd\t{%2, %0|%0, %2}"
20671 [(set_attr "type" "mmxcmp")
20672 (set_attr "mode" "DI")])
20673
20674
20675 ;; MMX max/min insns
20676
20677 (define_insn "umaxv8qi3"
20678 [(set (match_operand:V8QI 0 "register_operand" "=y")
20679 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20680 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20681 "TARGET_SSE || TARGET_3DNOW_A"
20682 "pmaxub\t{%2, %0|%0, %2}"
20683 [(set_attr "type" "mmxadd")
20684 (set_attr "mode" "DI")])
20685
20686 (define_insn "smaxv4hi3"
20687 [(set (match_operand:V4HI 0 "register_operand" "=y")
20688 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20689 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20690 "TARGET_SSE || TARGET_3DNOW_A"
20691 "pmaxsw\t{%2, %0|%0, %2}"
20692 [(set_attr "type" "mmxadd")
20693 (set_attr "mode" "DI")])
20694
20695 (define_insn "uminv8qi3"
20696 [(set (match_operand:V8QI 0 "register_operand" "=y")
20697 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20698 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20699 "TARGET_SSE || TARGET_3DNOW_A"
20700 "pminub\t{%2, %0|%0, %2}"
20701 [(set_attr "type" "mmxadd")
20702 (set_attr "mode" "DI")])
20703
20704 (define_insn "sminv4hi3"
20705 [(set (match_operand:V4HI 0 "register_operand" "=y")
20706 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20707 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20708 "TARGET_SSE || TARGET_3DNOW_A"
20709 "pminsw\t{%2, %0|%0, %2}"
20710 [(set_attr "type" "mmxadd")
20711 (set_attr "mode" "DI")])
20712
20713
20714 ;; MMX shifts
20715
20716 (define_insn "ashrv4hi3"
20717 [(set (match_operand:V4HI 0 "register_operand" "=y")
20718 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20719 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20720 "TARGET_MMX"
20721 "psraw\t{%2, %0|%0, %2}"
20722 [(set_attr "type" "mmxshft")
20723 (set_attr "mode" "DI")])
20724
20725 (define_insn "ashrv2si3"
20726 [(set (match_operand:V2SI 0 "register_operand" "=y")
20727 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20728 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20729 "TARGET_MMX"
20730 "psrad\t{%2, %0|%0, %2}"
20731 [(set_attr "type" "mmxshft")
20732 (set_attr "mode" "DI")])
20733
20734 (define_insn "lshrv4hi3"
20735 [(set (match_operand:V4HI 0 "register_operand" "=y")
20736 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20737 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20738 "TARGET_MMX"
20739 "psrlw\t{%2, %0|%0, %2}"
20740 [(set_attr "type" "mmxshft")
20741 (set_attr "mode" "DI")])
20742
20743 (define_insn "lshrv2si3"
20744 [(set (match_operand:V2SI 0 "register_operand" "=y")
20745 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20746 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20747 "TARGET_MMX"
20748 "psrld\t{%2, %0|%0, %2}"
20749 [(set_attr "type" "mmxshft")
20750 (set_attr "mode" "DI")])
20751
20752 ;; See logical MMX insns.
20753 (define_insn "mmx_lshrdi3"
20754 [(set (match_operand:DI 0 "register_operand" "=y")
20755 (unspec:DI
20756 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20757 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20758 UNSPEC_NOP))]
20759 "TARGET_MMX"
20760 "psrlq\t{%2, %0|%0, %2}"
20761 [(set_attr "type" "mmxshft")
20762 (set_attr "mode" "DI")])
20763
20764 (define_insn "ashlv4hi3"
20765 [(set (match_operand:V4HI 0 "register_operand" "=y")
20766 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20767 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20768 "TARGET_MMX"
20769 "psllw\t{%2, %0|%0, %2}"
20770 [(set_attr "type" "mmxshft")
20771 (set_attr "mode" "DI")])
20772
20773 (define_insn "ashlv2si3"
20774 [(set (match_operand:V2SI 0 "register_operand" "=y")
20775 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20776 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20777 "TARGET_MMX"
20778 "pslld\t{%2, %0|%0, %2}"
20779 [(set_attr "type" "mmxshft")
20780 (set_attr "mode" "DI")])
20781
20782 ;; See logical MMX insns.
20783 (define_insn "mmx_ashldi3"
20784 [(set (match_operand:DI 0 "register_operand" "=y")
20785 (unspec:DI
20786 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20787 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20788 UNSPEC_NOP))]
20789 "TARGET_MMX"
20790 "psllq\t{%2, %0|%0, %2}"
20791 [(set_attr "type" "mmxshft")
20792 (set_attr "mode" "DI")])
20793
20794
20795 ;; MMX pack/unpack insns.
20796
20797 (define_insn "mmx_packsswb"
20798 [(set (match_operand:V8QI 0 "register_operand" "=y")
20799 (vec_concat:V8QI
20800 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20801 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20802 "TARGET_MMX"
20803 "packsswb\t{%2, %0|%0, %2}"
20804 [(set_attr "type" "mmxshft")
20805 (set_attr "mode" "DI")])
20806
20807 (define_insn "mmx_packssdw"
20808 [(set (match_operand:V4HI 0 "register_operand" "=y")
20809 (vec_concat:V4HI
20810 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20811 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20812 "TARGET_MMX"
20813 "packssdw\t{%2, %0|%0, %2}"
20814 [(set_attr "type" "mmxshft")
20815 (set_attr "mode" "DI")])
20816
20817 (define_insn "mmx_packuswb"
20818 [(set (match_operand:V8QI 0 "register_operand" "=y")
20819 (vec_concat:V8QI
20820 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20821 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20822 "TARGET_MMX"
20823 "packuswb\t{%2, %0|%0, %2}"
20824 [(set_attr "type" "mmxshft")
20825 (set_attr "mode" "DI")])
20826
20827 (define_insn "mmx_punpckhbw"
20828 [(set (match_operand:V8QI 0 "register_operand" "=y")
20829 (vec_merge:V8QI
20830 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20831 (parallel [(const_int 4)
20832 (const_int 0)
20833 (const_int 5)
20834 (const_int 1)
20835 (const_int 6)
20836 (const_int 2)
20837 (const_int 7)
20838 (const_int 3)]))
20839 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20840 (parallel [(const_int 0)
20841 (const_int 4)
20842 (const_int 1)
20843 (const_int 5)
20844 (const_int 2)
20845 (const_int 6)
20846 (const_int 3)
20847 (const_int 7)]))
20848 (const_int 85)))]
20849 "TARGET_MMX"
20850 "punpckhbw\t{%2, %0|%0, %2}"
20851 [(set_attr "type" "mmxcvt")
20852 (set_attr "mode" "DI")])
20853
20854 (define_insn "mmx_punpckhwd"
20855 [(set (match_operand:V4HI 0 "register_operand" "=y")
20856 (vec_merge:V4HI
20857 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20858 (parallel [(const_int 0)
20859 (const_int 2)
20860 (const_int 1)
20861 (const_int 3)]))
20862 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20863 (parallel [(const_int 2)
20864 (const_int 0)
20865 (const_int 3)
20866 (const_int 1)]))
20867 (const_int 5)))]
20868 "TARGET_MMX"
20869 "punpckhwd\t{%2, %0|%0, %2}"
20870 [(set_attr "type" "mmxcvt")
20871 (set_attr "mode" "DI")])
20872
20873 (define_insn "mmx_punpckhdq"
20874 [(set (match_operand:V2SI 0 "register_operand" "=y")
20875 (vec_merge:V2SI
20876 (match_operand:V2SI 1 "register_operand" "0")
20877 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20878 (parallel [(const_int 1)
20879 (const_int 0)]))
20880 (const_int 1)))]
20881 "TARGET_MMX"
20882 "punpckhdq\t{%2, %0|%0, %2}"
20883 [(set_attr "type" "mmxcvt")
20884 (set_attr "mode" "DI")])
20885
20886 (define_insn "mmx_punpcklbw"
20887 [(set (match_operand:V8QI 0 "register_operand" "=y")
20888 (vec_merge:V8QI
20889 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20890 (parallel [(const_int 0)
20891 (const_int 4)
20892 (const_int 1)
20893 (const_int 5)
20894 (const_int 2)
20895 (const_int 6)
20896 (const_int 3)
20897 (const_int 7)]))
20898 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20899 (parallel [(const_int 4)
20900 (const_int 0)
20901 (const_int 5)
20902 (const_int 1)
20903 (const_int 6)
20904 (const_int 2)
20905 (const_int 7)
20906 (const_int 3)]))
20907 (const_int 85)))]
20908 "TARGET_MMX"
20909 "punpcklbw\t{%2, %0|%0, %2}"
20910 [(set_attr "type" "mmxcvt")
20911 (set_attr "mode" "DI")])
20912
20913 (define_insn "mmx_punpcklwd"
20914 [(set (match_operand:V4HI 0 "register_operand" "=y")
20915 (vec_merge:V4HI
20916 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20917 (parallel [(const_int 2)
20918 (const_int 0)
20919 (const_int 3)
20920 (const_int 1)]))
20921 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20922 (parallel [(const_int 0)
20923 (const_int 2)
20924 (const_int 1)
20925 (const_int 3)]))
20926 (const_int 5)))]
20927 "TARGET_MMX"
20928 "punpcklwd\t{%2, %0|%0, %2}"
20929 [(set_attr "type" "mmxcvt")
20930 (set_attr "mode" "DI")])
20931
20932 (define_insn "mmx_punpckldq"
20933 [(set (match_operand:V2SI 0 "register_operand" "=y")
20934 (vec_merge:V2SI
20935 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20936 (parallel [(const_int 1)
20937 (const_int 0)]))
20938 (match_operand:V2SI 2 "register_operand" "y")
20939 (const_int 1)))]
20940 "TARGET_MMX"
20941 "punpckldq\t{%2, %0|%0, %2}"
20942 [(set_attr "type" "mmxcvt")
20943 (set_attr "mode" "DI")])
20944
20945
20946 ;; Miscellaneous stuff
20947
20948 (define_insn "emms"
20949 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20950 (clobber (reg:XF 8))
20951 (clobber (reg:XF 9))
20952 (clobber (reg:XF 10))
20953 (clobber (reg:XF 11))
20954 (clobber (reg:XF 12))
20955 (clobber (reg:XF 13))
20956 (clobber (reg:XF 14))
20957 (clobber (reg:XF 15))
20958 (clobber (reg:DI 29))
20959 (clobber (reg:DI 30))
20960 (clobber (reg:DI 31))
20961 (clobber (reg:DI 32))
20962 (clobber (reg:DI 33))
20963 (clobber (reg:DI 34))
20964 (clobber (reg:DI 35))
20965 (clobber (reg:DI 36))]
20966 "TARGET_MMX"
20967 "emms"
20968 [(set_attr "type" "mmx")
20969 (set_attr "memory" "unknown")])
20970
20971 (define_insn "ldmxcsr"
20972 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20973 UNSPECV_LDMXCSR)]
20974 "TARGET_SSE"
20975 "ldmxcsr\t%0"
20976 [(set_attr "type" "sse")
20977 (set_attr "memory" "load")])
20978
20979 (define_insn "stmxcsr"
20980 [(set (match_operand:SI 0 "memory_operand" "=m")
20981 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20982 "TARGET_SSE"
20983 "stmxcsr\t%0"
20984 [(set_attr "type" "sse")
20985 (set_attr "memory" "store")])
20986
20987 (define_expand "sfence"
20988 [(set (match_dup 0)
20989 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20990 "TARGET_SSE || TARGET_3DNOW_A"
20991 {
20992 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20993 MEM_VOLATILE_P (operands[0]) = 1;
20994 })
20995
20996 (define_insn "*sfence_insn"
20997 [(set (match_operand:BLK 0 "" "")
20998 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20999 "TARGET_SSE || TARGET_3DNOW_A"
21000 "sfence"
21001 [(set_attr "type" "sse")
21002 (set_attr "memory" "unknown")])
21003
21004 (define_expand "sse_prologue_save"
21005 [(parallel [(set (match_operand:BLK 0 "" "")
21006 (unspec:BLK [(reg:DI 21)
21007 (reg:DI 22)
21008 (reg:DI 23)
21009 (reg:DI 24)
21010 (reg:DI 25)
21011 (reg:DI 26)
21012 (reg:DI 27)
21013 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21014 (use (match_operand:DI 1 "register_operand" ""))
21015 (use (match_operand:DI 2 "immediate_operand" ""))
21016 (use (label_ref:DI (match_operand 3 "" "")))])]
21017 "TARGET_64BIT"
21018 "")
21019
21020 (define_insn "*sse_prologue_save_insn"
21021 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21022 (match_operand:DI 4 "const_int_operand" "n")))
21023 (unspec:BLK [(reg:DI 21)
21024 (reg:DI 22)
21025 (reg:DI 23)
21026 (reg:DI 24)
21027 (reg:DI 25)
21028 (reg:DI 26)
21029 (reg:DI 27)
21030 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21031 (use (match_operand:DI 1 "register_operand" "r"))
21032 (use (match_operand:DI 2 "const_int_operand" "i"))
21033 (use (label_ref:DI (match_operand 3 "" "X")))]
21034 "TARGET_64BIT
21035 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21036 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21037 "*
21038 {
21039 int i;
21040 operands[0] = gen_rtx_MEM (Pmode,
21041 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21042 output_asm_insn (\"jmp\\t%A1\", operands);
21043 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21044 {
21045 operands[4] = adjust_address (operands[0], DImode, i*16);
21046 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21047 PUT_MODE (operands[4], TImode);
21048 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21049 output_asm_insn (\"rex\", operands);
21050 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21051 }
21052 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21053 CODE_LABEL_NUMBER (operands[3]));
21054 RET;
21055 }
21056 "
21057 [(set_attr "type" "other")
21058 (set_attr "length_immediate" "0")
21059 (set_attr "length_address" "0")
21060 (set_attr "length" "135")
21061 (set_attr "memory" "store")
21062 (set_attr "modrm" "0")
21063 (set_attr "mode" "DI")])
21064
21065 ;; 3Dnow! instructions
21066
21067 (define_insn "addv2sf3"
21068 [(set (match_operand:V2SF 0 "register_operand" "=y")
21069 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21070 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21071 "TARGET_3DNOW"
21072 "pfadd\\t{%2, %0|%0, %2}"
21073 [(set_attr "type" "mmxadd")
21074 (set_attr "mode" "V2SF")])
21075
21076 (define_insn "subv2sf3"
21077 [(set (match_operand:V2SF 0 "register_operand" "=y")
21078 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21079 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21080 "TARGET_3DNOW"
21081 "pfsub\\t{%2, %0|%0, %2}"
21082 [(set_attr "type" "mmxadd")
21083 (set_attr "mode" "V2SF")])
21084
21085 (define_insn "subrv2sf3"
21086 [(set (match_operand:V2SF 0 "register_operand" "=y")
21087 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21088 (match_operand:V2SF 1 "register_operand" "0")))]
21089 "TARGET_3DNOW"
21090 "pfsubr\\t{%2, %0|%0, %2}"
21091 [(set_attr "type" "mmxadd")
21092 (set_attr "mode" "V2SF")])
21093
21094 (define_insn "gtv2sf3"
21095 [(set (match_operand:V2SI 0 "register_operand" "=y")
21096 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21097 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21098 "TARGET_3DNOW"
21099 "pfcmpgt\\t{%2, %0|%0, %2}"
21100 [(set_attr "type" "mmxcmp")
21101 (set_attr "mode" "V2SF")])
21102
21103 (define_insn "gev2sf3"
21104 [(set (match_operand:V2SI 0 "register_operand" "=y")
21105 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21106 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21107 "TARGET_3DNOW"
21108 "pfcmpge\\t{%2, %0|%0, %2}"
21109 [(set_attr "type" "mmxcmp")
21110 (set_attr "mode" "V2SF")])
21111
21112 (define_insn "eqv2sf3"
21113 [(set (match_operand:V2SI 0 "register_operand" "=y")
21114 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21115 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21116 "TARGET_3DNOW"
21117 "pfcmpeq\\t{%2, %0|%0, %2}"
21118 [(set_attr "type" "mmxcmp")
21119 (set_attr "mode" "V2SF")])
21120
21121 (define_insn "pfmaxv2sf3"
21122 [(set (match_operand:V2SF 0 "register_operand" "=y")
21123 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21124 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21125 "TARGET_3DNOW"
21126 "pfmax\\t{%2, %0|%0, %2}"
21127 [(set_attr "type" "mmxadd")
21128 (set_attr "mode" "V2SF")])
21129
21130 (define_insn "pfminv2sf3"
21131 [(set (match_operand:V2SF 0 "register_operand" "=y")
21132 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21133 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21134 "TARGET_3DNOW"
21135 "pfmin\\t{%2, %0|%0, %2}"
21136 [(set_attr "type" "mmxadd")
21137 (set_attr "mode" "V2SF")])
21138
21139 (define_insn "mulv2sf3"
21140 [(set (match_operand:V2SF 0 "register_operand" "=y")
21141 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21142 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21143 "TARGET_3DNOW"
21144 "pfmul\\t{%2, %0|%0, %2}"
21145 [(set_attr "type" "mmxmul")
21146 (set_attr "mode" "V2SF")])
21147
21148 (define_insn "femms"
21149 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21150 (clobber (reg:XF 8))
21151 (clobber (reg:XF 9))
21152 (clobber (reg:XF 10))
21153 (clobber (reg:XF 11))
21154 (clobber (reg:XF 12))
21155 (clobber (reg:XF 13))
21156 (clobber (reg:XF 14))
21157 (clobber (reg:XF 15))
21158 (clobber (reg:DI 29))
21159 (clobber (reg:DI 30))
21160 (clobber (reg:DI 31))
21161 (clobber (reg:DI 32))
21162 (clobber (reg:DI 33))
21163 (clobber (reg:DI 34))
21164 (clobber (reg:DI 35))
21165 (clobber (reg:DI 36))]
21166 "TARGET_3DNOW"
21167 "femms"
21168 [(set_attr "type" "mmx")
21169 (set_attr "memory" "none")])
21170
21171 (define_insn "pf2id"
21172 [(set (match_operand:V2SI 0 "register_operand" "=y")
21173 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21174 "TARGET_3DNOW"
21175 "pf2id\\t{%1, %0|%0, %1}"
21176 [(set_attr "type" "mmxcvt")
21177 (set_attr "mode" "V2SF")])
21178
21179 (define_insn "pf2iw"
21180 [(set (match_operand:V2SI 0 "register_operand" "=y")
21181 (sign_extend:V2SI
21182 (ss_truncate:V2HI
21183 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21184 "TARGET_3DNOW_A"
21185 "pf2iw\\t{%1, %0|%0, %1}"
21186 [(set_attr "type" "mmxcvt")
21187 (set_attr "mode" "V2SF")])
21188
21189 (define_insn "pfacc"
21190 [(set (match_operand:V2SF 0 "register_operand" "=y")
21191 (vec_concat:V2SF
21192 (plus:SF
21193 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21194 (parallel [(const_int 0)]))
21195 (vec_select:SF (match_dup 1)
21196 (parallel [(const_int 1)])))
21197 (plus:SF
21198 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21199 (parallel [(const_int 0)]))
21200 (vec_select:SF (match_dup 2)
21201 (parallel [(const_int 1)])))))]
21202 "TARGET_3DNOW"
21203 "pfacc\\t{%2, %0|%0, %2}"
21204 [(set_attr "type" "mmxadd")
21205 (set_attr "mode" "V2SF")])
21206
21207 (define_insn "pfnacc"
21208 [(set (match_operand:V2SF 0 "register_operand" "=y")
21209 (vec_concat:V2SF
21210 (minus:SF
21211 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21212 (parallel [(const_int 0)]))
21213 (vec_select:SF (match_dup 1)
21214 (parallel [(const_int 1)])))
21215 (minus:SF
21216 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21217 (parallel [(const_int 0)]))
21218 (vec_select:SF (match_dup 2)
21219 (parallel [(const_int 1)])))))]
21220 "TARGET_3DNOW_A"
21221 "pfnacc\\t{%2, %0|%0, %2}"
21222 [(set_attr "type" "mmxadd")
21223 (set_attr "mode" "V2SF")])
21224
21225 (define_insn "pfpnacc"
21226 [(set (match_operand:V2SF 0 "register_operand" "=y")
21227 (vec_concat:V2SF
21228 (minus:SF
21229 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21230 (parallel [(const_int 0)]))
21231 (vec_select:SF (match_dup 1)
21232 (parallel [(const_int 1)])))
21233 (plus:SF
21234 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21235 (parallel [(const_int 0)]))
21236 (vec_select:SF (match_dup 2)
21237 (parallel [(const_int 1)])))))]
21238 "TARGET_3DNOW_A"
21239 "pfpnacc\\t{%2, %0|%0, %2}"
21240 [(set_attr "type" "mmxadd")
21241 (set_attr "mode" "V2SF")])
21242
21243 (define_insn "pi2fw"
21244 [(set (match_operand:V2SF 0 "register_operand" "=y")
21245 (float:V2SF
21246 (vec_concat:V2SI
21247 (sign_extend:SI
21248 (truncate:HI
21249 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21250 (parallel [(const_int 0)]))))
21251 (sign_extend:SI
21252 (truncate:HI
21253 (vec_select:SI (match_dup 1)
21254 (parallel [(const_int 1)])))))))]
21255 "TARGET_3DNOW_A"
21256 "pi2fw\\t{%1, %0|%0, %1}"
21257 [(set_attr "type" "mmxcvt")
21258 (set_attr "mode" "V2SF")])
21259
21260 (define_insn "floatv2si2"
21261 [(set (match_operand:V2SF 0 "register_operand" "=y")
21262 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21263 "TARGET_3DNOW"
21264 "pi2fd\\t{%1, %0|%0, %1}"
21265 [(set_attr "type" "mmxcvt")
21266 (set_attr "mode" "V2SF")])
21267
21268 ;; This insn is identical to pavgb in operation, but the opcode is
21269 ;; different. To avoid accidentally matching pavgb, use an unspec.
21270
21271 (define_insn "pavgusb"
21272 [(set (match_operand:V8QI 0 "register_operand" "=y")
21273 (unspec:V8QI
21274 [(match_operand:V8QI 1 "register_operand" "0")
21275 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21276 UNSPEC_PAVGUSB))]
21277 "TARGET_3DNOW"
21278 "pavgusb\\t{%2, %0|%0, %2}"
21279 [(set_attr "type" "mmxshft")
21280 (set_attr "mode" "TI")])
21281
21282 ;; 3DNow reciprocal and sqrt
21283
21284 (define_insn "pfrcpv2sf2"
21285 [(set (match_operand:V2SF 0 "register_operand" "=y")
21286 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21287 UNSPEC_PFRCP))]
21288 "TARGET_3DNOW"
21289 "pfrcp\\t{%1, %0|%0, %1}"
21290 [(set_attr "type" "mmx")
21291 (set_attr "mode" "TI")])
21292
21293 (define_insn "pfrcpit1v2sf3"
21294 [(set (match_operand:V2SF 0 "register_operand" "=y")
21295 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21296 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21297 UNSPEC_PFRCPIT1))]
21298 "TARGET_3DNOW"
21299 "pfrcpit1\\t{%2, %0|%0, %2}"
21300 [(set_attr "type" "mmx")
21301 (set_attr "mode" "TI")])
21302
21303 (define_insn "pfrcpit2v2sf3"
21304 [(set (match_operand:V2SF 0 "register_operand" "=y")
21305 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21306 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21307 UNSPEC_PFRCPIT2))]
21308 "TARGET_3DNOW"
21309 "pfrcpit2\\t{%2, %0|%0, %2}"
21310 [(set_attr "type" "mmx")
21311 (set_attr "mode" "TI")])
21312
21313 (define_insn "pfrsqrtv2sf2"
21314 [(set (match_operand:V2SF 0 "register_operand" "=y")
21315 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21316 UNSPEC_PFRSQRT))]
21317 "TARGET_3DNOW"
21318 "pfrsqrt\\t{%1, %0|%0, %1}"
21319 [(set_attr "type" "mmx")
21320 (set_attr "mode" "TI")])
21321
21322 (define_insn "pfrsqit1v2sf3"
21323 [(set (match_operand:V2SF 0 "register_operand" "=y")
21324 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21325 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21326 UNSPEC_PFRSQIT1))]
21327 "TARGET_3DNOW"
21328 "pfrsqit1\\t{%2, %0|%0, %2}"
21329 [(set_attr "type" "mmx")
21330 (set_attr "mode" "TI")])
21331
21332 (define_insn "pmulhrwv4hi3"
21333 [(set (match_operand:V4HI 0 "register_operand" "=y")
21334 (truncate:V4HI
21335 (lshiftrt:V4SI
21336 (plus:V4SI
21337 (mult:V4SI
21338 (sign_extend:V4SI
21339 (match_operand:V4HI 1 "register_operand" "0"))
21340 (sign_extend:V4SI
21341 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21342 (const_vector:V4SI [(const_int 32768)
21343 (const_int 32768)
21344 (const_int 32768)
21345 (const_int 32768)]))
21346 (const_int 16))))]
21347 "TARGET_3DNOW"
21348 "pmulhrw\\t{%2, %0|%0, %2}"
21349 [(set_attr "type" "mmxmul")
21350 (set_attr "mode" "TI")])
21351
21352 (define_insn "pswapdv2si2"
21353 [(set (match_operand:V2SI 0 "register_operand" "=y")
21354 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21355 (parallel [(const_int 1) (const_int 0)])))]
21356 "TARGET_3DNOW_A"
21357 "pswapd\\t{%1, %0|%0, %1}"
21358 [(set_attr "type" "mmxcvt")
21359 (set_attr "mode" "TI")])
21360
21361 (define_insn "pswapdv2sf2"
21362 [(set (match_operand:V2SF 0 "register_operand" "=y")
21363 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21364 (parallel [(const_int 1) (const_int 0)])))]
21365 "TARGET_3DNOW_A"
21366 "pswapd\\t{%1, %0|%0, %1}"
21367 [(set_attr "type" "mmxcvt")
21368 (set_attr "mode" "TI")])
21369
21370 (define_expand "prefetch"
21371 [(prefetch (match_operand 0 "address_operand" "")
21372 (match_operand:SI 1 "const_int_operand" "")
21373 (match_operand:SI 2 "const_int_operand" ""))]
21374 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21375 {
21376 int rw = INTVAL (operands[1]);
21377 int locality = INTVAL (operands[2]);
21378
21379 if (rw != 0 && rw != 1)
21380 abort ();
21381 if (locality < 0 || locality > 3)
21382 abort ();
21383 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21384 abort ();
21385
21386 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21387 suported by SSE counterpart or the SSE prefetch is not available
21388 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21389 of locality. */
21390 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21391 operands[2] = GEN_INT (3);
21392 else
21393 operands[1] = const0_rtx;
21394 })
21395
21396 (define_insn "*prefetch_sse"
21397 [(prefetch (match_operand:SI 0 "address_operand" "p")
21398 (const_int 0)
21399 (match_operand:SI 1 "const_int_operand" ""))]
21400 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21401 {
21402 static const char * const patterns[4] = {
21403 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21404 };
21405
21406 int locality = INTVAL (operands[1]);
21407 if (locality < 0 || locality > 3)
21408 abort ();
21409
21410 return patterns[locality];
21411 }
21412 [(set_attr "type" "sse")
21413 (set_attr "memory" "none")])
21414
21415 (define_insn "*prefetch_sse_rex"
21416 [(prefetch (match_operand:DI 0 "address_operand" "p")
21417 (const_int 0)
21418 (match_operand:SI 1 "const_int_operand" ""))]
21419 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21420 {
21421 static const char * const patterns[4] = {
21422 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21423 };
21424
21425 int locality = INTVAL (operands[1]);
21426 if (locality < 0 || locality > 3)
21427 abort ();
21428
21429 return patterns[locality];
21430 }
21431 [(set_attr "type" "sse")
21432 (set_attr "memory" "none")])
21433
21434 (define_insn "*prefetch_3dnow"
21435 [(prefetch (match_operand:SI 0 "address_operand" "p")
21436 (match_operand:SI 1 "const_int_operand" "n")
21437 (const_int 3))]
21438 "TARGET_3DNOW && !TARGET_64BIT"
21439 {
21440 if (INTVAL (operands[1]) == 0)
21441 return "prefetch\t%a0";
21442 else
21443 return "prefetchw\t%a0";
21444 }
21445 [(set_attr "type" "mmx")
21446 (set_attr "memory" "none")])
21447
21448 (define_insn "*prefetch_3dnow_rex"
21449 [(prefetch (match_operand:DI 0 "address_operand" "p")
21450 (match_operand:SI 1 "const_int_operand" "n")
21451 (const_int 3))]
21452 "TARGET_3DNOW && TARGET_64BIT"
21453 {
21454 if (INTVAL (operands[1]) == 0)
21455 return "prefetch\t%a0";
21456 else
21457 return "prefetchw\t%a0";
21458 }
21459 [(set_attr "type" "mmx")
21460 (set_attr "memory" "none")])
21461
21462 ;; SSE2 support
21463
21464 (define_insn "addv2df3"
21465 [(set (match_operand:V2DF 0 "register_operand" "=x")
21466 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21467 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21468 "TARGET_SSE2"
21469 "addpd\t{%2, %0|%0, %2}"
21470 [(set_attr "type" "sseadd")
21471 (set_attr "mode" "V2DF")])
21472
21473 (define_insn "vmaddv2df3"
21474 [(set (match_operand:V2DF 0 "register_operand" "=x")
21475 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21476 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21477 (match_dup 1)
21478 (const_int 1)))]
21479 "TARGET_SSE2"
21480 "addsd\t{%2, %0|%0, %2}"
21481 [(set_attr "type" "sseadd")
21482 (set_attr "mode" "DF")])
21483
21484 (define_insn "subv2df3"
21485 [(set (match_operand:V2DF 0 "register_operand" "=x")
21486 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21487 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21488 "TARGET_SSE2"
21489 "subpd\t{%2, %0|%0, %2}"
21490 [(set_attr "type" "sseadd")
21491 (set_attr "mode" "V2DF")])
21492
21493 (define_insn "vmsubv2df3"
21494 [(set (match_operand:V2DF 0 "register_operand" "=x")
21495 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21496 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21497 (match_dup 1)
21498 (const_int 1)))]
21499 "TARGET_SSE2"
21500 "subsd\t{%2, %0|%0, %2}"
21501 [(set_attr "type" "sseadd")
21502 (set_attr "mode" "DF")])
21503
21504 (define_insn "mulv2df3"
21505 [(set (match_operand:V2DF 0 "register_operand" "=x")
21506 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21507 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21508 "TARGET_SSE2"
21509 "mulpd\t{%2, %0|%0, %2}"
21510 [(set_attr "type" "ssemul")
21511 (set_attr "mode" "V2DF")])
21512
21513 (define_insn "vmmulv2df3"
21514 [(set (match_operand:V2DF 0 "register_operand" "=x")
21515 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21516 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21517 (match_dup 1)
21518 (const_int 1)))]
21519 "TARGET_SSE2"
21520 "mulsd\t{%2, %0|%0, %2}"
21521 [(set_attr "type" "ssemul")
21522 (set_attr "mode" "DF")])
21523
21524 (define_insn "divv2df3"
21525 [(set (match_operand:V2DF 0 "register_operand" "=x")
21526 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21527 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21528 "TARGET_SSE2"
21529 "divpd\t{%2, %0|%0, %2}"
21530 [(set_attr "type" "ssediv")
21531 (set_attr "mode" "V2DF")])
21532
21533 (define_insn "vmdivv2df3"
21534 [(set (match_operand:V2DF 0 "register_operand" "=x")
21535 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21536 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21537 (match_dup 1)
21538 (const_int 1)))]
21539 "TARGET_SSE2"
21540 "divsd\t{%2, %0|%0, %2}"
21541 [(set_attr "type" "ssediv")
21542 (set_attr "mode" "DF")])
21543
21544 ;; SSE min/max
21545
21546 (define_insn "smaxv2df3"
21547 [(set (match_operand:V2DF 0 "register_operand" "=x")
21548 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21549 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21550 "TARGET_SSE2"
21551 "maxpd\t{%2, %0|%0, %2}"
21552 [(set_attr "type" "sseadd")
21553 (set_attr "mode" "V2DF")])
21554
21555 (define_insn "vmsmaxv2df3"
21556 [(set (match_operand:V2DF 0 "register_operand" "=x")
21557 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21558 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21559 (match_dup 1)
21560 (const_int 1)))]
21561 "TARGET_SSE2"
21562 "maxsd\t{%2, %0|%0, %2}"
21563 [(set_attr "type" "sseadd")
21564 (set_attr "mode" "DF")])
21565
21566 (define_insn "sminv2df3"
21567 [(set (match_operand:V2DF 0 "register_operand" "=x")
21568 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21569 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21570 "TARGET_SSE2"
21571 "minpd\t{%2, %0|%0, %2}"
21572 [(set_attr "type" "sseadd")
21573 (set_attr "mode" "V2DF")])
21574
21575 (define_insn "vmsminv2df3"
21576 [(set (match_operand:V2DF 0 "register_operand" "=x")
21577 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21578 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21579 (match_dup 1)
21580 (const_int 1)))]
21581 "TARGET_SSE2"
21582 "minsd\t{%2, %0|%0, %2}"
21583 [(set_attr "type" "sseadd")
21584 (set_attr "mode" "DF")])
21585 ;; SSE2 square root. There doesn't appear to be an extension for the
21586 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21587
21588 (define_insn "sqrtv2df2"
21589 [(set (match_operand:V2DF 0 "register_operand" "=x")
21590 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21591 "TARGET_SSE2"
21592 "sqrtpd\t{%1, %0|%0, %1}"
21593 [(set_attr "type" "sse")
21594 (set_attr "mode" "V2DF")])
21595
21596 (define_insn "vmsqrtv2df2"
21597 [(set (match_operand:V2DF 0 "register_operand" "=x")
21598 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21599 (match_operand:V2DF 2 "register_operand" "0")
21600 (const_int 1)))]
21601 "TARGET_SSE2"
21602 "sqrtsd\t{%1, %0|%0, %1}"
21603 [(set_attr "type" "sse")
21604 (set_attr "mode" "SF")])
21605
21606 ;; SSE mask-generating compares
21607
21608 (define_insn "maskcmpv2df3"
21609 [(set (match_operand:V2DI 0 "register_operand" "=x")
21610 (match_operator:V2DI 3 "sse_comparison_operator"
21611 [(match_operand:V2DF 1 "register_operand" "0")
21612 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21613 "TARGET_SSE2"
21614 "cmp%D3pd\t{%2, %0|%0, %2}"
21615 [(set_attr "type" "ssecmp")
21616 (set_attr "mode" "V2DF")])
21617
21618 (define_insn "maskncmpv2df3"
21619 [(set (match_operand:V2DI 0 "register_operand" "=x")
21620 (not:V2DI
21621 (match_operator:V2DI 3 "sse_comparison_operator"
21622 [(match_operand:V2DF 1 "register_operand" "0")
21623 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21624 "TARGET_SSE2"
21625 {
21626 if (GET_CODE (operands[3]) == UNORDERED)
21627 return "cmpordps\t{%2, %0|%0, %2}";
21628 else
21629 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21630 }
21631 [(set_attr "type" "ssecmp")
21632 (set_attr "mode" "V2DF")])
21633
21634 (define_insn "vmmaskcmpv2df3"
21635 [(set (match_operand:V2DI 0 "register_operand" "=x")
21636 (vec_merge:V2DI
21637 (match_operator:V2DI 3 "sse_comparison_operator"
21638 [(match_operand:V2DF 1 "register_operand" "0")
21639 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21640 (subreg:V2DI (match_dup 1) 0)
21641 (const_int 1)))]
21642 "TARGET_SSE2"
21643 "cmp%D3sd\t{%2, %0|%0, %2}"
21644 [(set_attr "type" "ssecmp")
21645 (set_attr "mode" "DF")])
21646
21647 (define_insn "vmmaskncmpv2df3"
21648 [(set (match_operand:V2DI 0 "register_operand" "=x")
21649 (vec_merge:V2DI
21650 (not:V2DI
21651 (match_operator:V2DI 3 "sse_comparison_operator"
21652 [(match_operand:V2DF 1 "register_operand" "0")
21653 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21654 (subreg:V2DI (match_dup 1) 0)
21655 (const_int 1)))]
21656 "TARGET_SSE2"
21657 {
21658 if (GET_CODE (operands[3]) == UNORDERED)
21659 return "cmpordsd\t{%2, %0|%0, %2}";
21660 else
21661 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21662 }
21663 [(set_attr "type" "ssecmp")
21664 (set_attr "mode" "DF")])
21665
21666 (define_insn "sse2_comi"
21667 [(set (reg:CCFP 17)
21668 (compare:CCFP (vec_select:DF
21669 (match_operand:V2DF 0 "register_operand" "x")
21670 (parallel [(const_int 0)]))
21671 (vec_select:DF
21672 (match_operand:V2DF 1 "register_operand" "x")
21673 (parallel [(const_int 0)]))))]
21674 "TARGET_SSE2"
21675 "comisd\t{%1, %0|%0, %1}"
21676 [(set_attr "type" "ssecomi")
21677 (set_attr "mode" "DF")])
21678
21679 (define_insn "sse2_ucomi"
21680 [(set (reg:CCFPU 17)
21681 (compare:CCFPU (vec_select:DF
21682 (match_operand:V2DF 0 "register_operand" "x")
21683 (parallel [(const_int 0)]))
21684 (vec_select:DF
21685 (match_operand:V2DF 1 "register_operand" "x")
21686 (parallel [(const_int 0)]))))]
21687 "TARGET_SSE2"
21688 "ucomisd\t{%1, %0|%0, %1}"
21689 [(set_attr "type" "ssecomi")
21690 (set_attr "mode" "DF")])
21691
21692 ;; SSE Strange Moves.
21693
21694 (define_insn "sse2_movmskpd"
21695 [(set (match_operand:SI 0 "register_operand" "=r")
21696 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21697 UNSPEC_MOVMSK))]
21698 "TARGET_SSE2"
21699 "movmskpd\t{%1, %0|%0, %1}"
21700 [(set_attr "type" "ssecvt")
21701 (set_attr "mode" "V2DF")])
21702
21703 (define_insn "sse2_pmovmskb"
21704 [(set (match_operand:SI 0 "register_operand" "=r")
21705 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21706 UNSPEC_MOVMSK))]
21707 "TARGET_SSE2"
21708 "pmovmskb\t{%1, %0|%0, %1}"
21709 [(set_attr "type" "ssecvt")
21710 (set_attr "mode" "V2DF")])
21711
21712 (define_insn "sse2_maskmovdqu"
21713 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21714 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21715 (match_operand:V16QI 2 "register_operand" "x")]
21716 UNSPEC_MASKMOV))]
21717 "TARGET_SSE2"
21718 ;; @@@ check ordering of operands in intel/nonintel syntax
21719 "maskmovdqu\t{%2, %1|%1, %2}"
21720 [(set_attr "type" "ssecvt")
21721 (set_attr "mode" "TI")])
21722
21723 (define_insn "sse2_maskmovdqu_rex64"
21724 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21725 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21726 (match_operand:V16QI 2 "register_operand" "x")]
21727 UNSPEC_MASKMOV))]
21728 "TARGET_SSE2"
21729 ;; @@@ check ordering of operands in intel/nonintel syntax
21730 "maskmovdqu\t{%2, %1|%1, %2}"
21731 [(set_attr "type" "ssecvt")
21732 (set_attr "mode" "TI")])
21733
21734 (define_insn "sse2_movntv2df"
21735 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21736 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21737 UNSPEC_MOVNT))]
21738 "TARGET_SSE2"
21739 "movntpd\t{%1, %0|%0, %1}"
21740 [(set_attr "type" "ssecvt")
21741 (set_attr "mode" "V2DF")])
21742
21743 (define_insn "sse2_movntv2di"
21744 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21745 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21746 UNSPEC_MOVNT))]
21747 "TARGET_SSE2"
21748 "movntdq\t{%1, %0|%0, %1}"
21749 [(set_attr "type" "ssecvt")
21750 (set_attr "mode" "TI")])
21751
21752 (define_insn "sse2_movntsi"
21753 [(set (match_operand:SI 0 "memory_operand" "=m")
21754 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21755 UNSPEC_MOVNT))]
21756 "TARGET_SSE2"
21757 "movnti\t{%1, %0|%0, %1}"
21758 [(set_attr "type" "ssecvt")
21759 (set_attr "mode" "V2DF")])
21760
21761 ;; SSE <-> integer/MMX conversions
21762
21763 ;; Conversions between SI and SF
21764
21765 (define_insn "cvtdq2ps"
21766 [(set (match_operand:V4SF 0 "register_operand" "=x")
21767 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21768 "TARGET_SSE2"
21769 "cvtdq2ps\t{%1, %0|%0, %1}"
21770 [(set_attr "type" "ssecvt")
21771 (set_attr "mode" "V2DF")])
21772
21773 (define_insn "cvtps2dq"
21774 [(set (match_operand:V4SI 0 "register_operand" "=x")
21775 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21776 "TARGET_SSE2"
21777 "cvtps2dq\t{%1, %0|%0, %1}"
21778 [(set_attr "type" "ssecvt")
21779 (set_attr "mode" "TI")])
21780
21781 (define_insn "cvttps2dq"
21782 [(set (match_operand:V4SI 0 "register_operand" "=x")
21783 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21784 UNSPEC_FIX))]
21785 "TARGET_SSE2"
21786 "cvttps2dq\t{%1, %0|%0, %1}"
21787 [(set_attr "type" "ssecvt")
21788 (set_attr "mode" "TI")])
21789
21790 ;; Conversions between SI and DF
21791
21792 (define_insn "cvtdq2pd"
21793 [(set (match_operand:V2DF 0 "register_operand" "=x")
21794 (float:V2DF (vec_select:V2SI
21795 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21796 (parallel
21797 [(const_int 0)
21798 (const_int 1)]))))]
21799 "TARGET_SSE2"
21800 "cvtdq2pd\t{%1, %0|%0, %1}"
21801 [(set_attr "type" "ssecvt")
21802 (set_attr "mode" "V2DF")])
21803
21804 (define_insn "cvtpd2dq"
21805 [(set (match_operand:V4SI 0 "register_operand" "=x")
21806 (vec_concat:V4SI
21807 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21808 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21809 "TARGET_SSE2"
21810 "cvtpd2dq\t{%1, %0|%0, %1}"
21811 [(set_attr "type" "ssecvt")
21812 (set_attr "mode" "TI")])
21813
21814 (define_insn "cvttpd2dq"
21815 [(set (match_operand:V4SI 0 "register_operand" "=x")
21816 (vec_concat:V4SI
21817 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21818 UNSPEC_FIX)
21819 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21820 "TARGET_SSE2"
21821 "cvttpd2dq\t{%1, %0|%0, %1}"
21822 [(set_attr "type" "ssecvt")
21823 (set_attr "mode" "TI")])
21824
21825 (define_insn "cvtpd2pi"
21826 [(set (match_operand:V2SI 0 "register_operand" "=y")
21827 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21828 "TARGET_SSE2"
21829 "cvtpd2pi\t{%1, %0|%0, %1}"
21830 [(set_attr "type" "ssecvt")
21831 (set_attr "mode" "TI")])
21832
21833 (define_insn "cvttpd2pi"
21834 [(set (match_operand:V2SI 0 "register_operand" "=y")
21835 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21836 UNSPEC_FIX))]
21837 "TARGET_SSE2"
21838 "cvttpd2pi\t{%1, %0|%0, %1}"
21839 [(set_attr "type" "ssecvt")
21840 (set_attr "mode" "TI")])
21841
21842 (define_insn "cvtpi2pd"
21843 [(set (match_operand:V2DF 0 "register_operand" "=x")
21844 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21845 "TARGET_SSE2"
21846 "cvtpi2pd\t{%1, %0|%0, %1}"
21847 [(set_attr "type" "ssecvt")
21848 (set_attr "mode" "TI")])
21849
21850 ;; Conversions between SI and DF
21851
21852 (define_insn "cvtsd2si"
21853 [(set (match_operand:SI 0 "register_operand" "=r")
21854 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
21855 (parallel [(const_int 0)]))))]
21856 "TARGET_SSE2"
21857 "cvtsd2si\t{%1, %0|%0, %1}"
21858 [(set_attr "type" "sseicvt")
21859 (set_attr "mode" "SI")])
21860
21861 (define_insn "cvtsd2siq"
21862 [(set (match_operand:DI 0 "register_operand" "=r")
21863 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
21864 (parallel [(const_int 0)]))))]
21865 "TARGET_SSE2 && TARGET_64BIT"
21866 "cvtsd2siq\t{%1, %0|%0, %1}"
21867 [(set_attr "type" "sseicvt")
21868 (set_attr "mode" "SI")])
21869
21870 (define_insn "cvttsd2si"
21871 [(set (match_operand:SI 0 "register_operand" "=r,r")
21872 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21873 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21874 "TARGET_SSE2"
21875 "cvttsd2si\t{%1, %0|%0, %1}"
21876 [(set_attr "type" "sseicvt")
21877 (set_attr "mode" "SI")
21878 (set_attr "athlon_decode" "double,vector")])
21879
21880 (define_insn "cvttsd2siq"
21881 [(set (match_operand:DI 0 "register_operand" "=r,r")
21882 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21883 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21884 "TARGET_SSE2 && TARGET_64BIT"
21885 "cvttsd2siq\t{%1, %0|%0, %1}"
21886 [(set_attr "type" "sseicvt")
21887 (set_attr "mode" "DI")
21888 (set_attr "athlon_decode" "double,vector")])
21889
21890 (define_insn "cvtsi2sd"
21891 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21892 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21893 (vec_duplicate:V2DF
21894 (float:DF
21895 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21896 (const_int 2)))]
21897 "TARGET_SSE2"
21898 "cvtsi2sd\t{%2, %0|%0, %2}"
21899 [(set_attr "type" "sseicvt")
21900 (set_attr "mode" "DF")
21901 (set_attr "athlon_decode" "double,direct")])
21902
21903 (define_insn "cvtsi2sdq"
21904 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21905 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21906 (vec_duplicate:V2DF
21907 (float:DF
21908 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21909 (const_int 2)))]
21910 "TARGET_SSE2 && TARGET_64BIT"
21911 "cvtsi2sdq\t{%2, %0|%0, %2}"
21912 [(set_attr "type" "sseicvt")
21913 (set_attr "mode" "DF")
21914 (set_attr "athlon_decode" "double,direct")])
21915
21916 ;; Conversions between SF and DF
21917
21918 (define_insn "cvtsd2ss"
21919 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21920 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21921 (vec_duplicate:V4SF
21922 (float_truncate:V2SF
21923 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21924 (const_int 14)))]
21925 "TARGET_SSE2"
21926 "cvtsd2ss\t{%2, %0|%0, %2}"
21927 [(set_attr "type" "ssecvt")
21928 (set_attr "athlon_decode" "vector,double")
21929 (set_attr "mode" "SF")])
21930
21931 (define_insn "cvtss2sd"
21932 [(set (match_operand:V2DF 0 "register_operand" "=x")
21933 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21934 (float_extend:V2DF
21935 (vec_select:V2SF
21936 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21937 (parallel [(const_int 0)
21938 (const_int 1)])))
21939 (const_int 2)))]
21940 "TARGET_SSE2"
21941 "cvtss2sd\t{%2, %0|%0, %2}"
21942 [(set_attr "type" "ssecvt")
21943 (set_attr "mode" "DF")])
21944
21945 (define_insn "cvtpd2ps"
21946 [(set (match_operand:V4SF 0 "register_operand" "=x")
21947 (subreg:V4SF
21948 (vec_concat:V4SI
21949 (subreg:V2SI (float_truncate:V2SF
21950 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21951 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21952 "TARGET_SSE2"
21953 "cvtpd2ps\t{%1, %0|%0, %1}"
21954 [(set_attr "type" "ssecvt")
21955 (set_attr "mode" "V4SF")])
21956
21957 (define_insn "cvtps2pd"
21958 [(set (match_operand:V2DF 0 "register_operand" "=x")
21959 (float_extend:V2DF
21960 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21961 (parallel [(const_int 0)
21962 (const_int 1)]))))]
21963 "TARGET_SSE2"
21964 "cvtps2pd\t{%1, %0|%0, %1}"
21965 [(set_attr "type" "ssecvt")
21966 (set_attr "mode" "V2DF")])
21967
21968 ;; SSE2 variants of MMX insns
21969
21970 ;; MMX arithmetic
21971
21972 (define_insn "addv16qi3"
21973 [(set (match_operand:V16QI 0 "register_operand" "=x")
21974 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21975 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21976 "TARGET_SSE2"
21977 "paddb\t{%2, %0|%0, %2}"
21978 [(set_attr "type" "sseiadd")
21979 (set_attr "mode" "TI")])
21980
21981 (define_insn "addv8hi3"
21982 [(set (match_operand:V8HI 0 "register_operand" "=x")
21983 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21984 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21985 "TARGET_SSE2"
21986 "paddw\t{%2, %0|%0, %2}"
21987 [(set_attr "type" "sseiadd")
21988 (set_attr "mode" "TI")])
21989
21990 (define_insn "addv4si3"
21991 [(set (match_operand:V4SI 0 "register_operand" "=x")
21992 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21993 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21994 "TARGET_SSE2"
21995 "paddd\t{%2, %0|%0, %2}"
21996 [(set_attr "type" "sseiadd")
21997 (set_attr "mode" "TI")])
21998
21999 (define_insn "addv2di3"
22000 [(set (match_operand:V2DI 0 "register_operand" "=x")
22001 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22002 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22003 "TARGET_SSE2"
22004 "paddq\t{%2, %0|%0, %2}"
22005 [(set_attr "type" "sseiadd")
22006 (set_attr "mode" "TI")])
22007
22008 (define_insn "ssaddv16qi3"
22009 [(set (match_operand:V16QI 0 "register_operand" "=x")
22010 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22011 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22012 "TARGET_SSE2"
22013 "paddsb\t{%2, %0|%0, %2}"
22014 [(set_attr "type" "sseiadd")
22015 (set_attr "mode" "TI")])
22016
22017 (define_insn "ssaddv8hi3"
22018 [(set (match_operand:V8HI 0 "register_operand" "=x")
22019 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22020 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22021 "TARGET_SSE2"
22022 "paddsw\t{%2, %0|%0, %2}"
22023 [(set_attr "type" "sseiadd")
22024 (set_attr "mode" "TI")])
22025
22026 (define_insn "usaddv16qi3"
22027 [(set (match_operand:V16QI 0 "register_operand" "=x")
22028 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22029 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22030 "TARGET_SSE2"
22031 "paddusb\t{%2, %0|%0, %2}"
22032 [(set_attr "type" "sseiadd")
22033 (set_attr "mode" "TI")])
22034
22035 (define_insn "usaddv8hi3"
22036 [(set (match_operand:V8HI 0 "register_operand" "=x")
22037 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22038 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22039 "TARGET_SSE2"
22040 "paddusw\t{%2, %0|%0, %2}"
22041 [(set_attr "type" "sseiadd")
22042 (set_attr "mode" "TI")])
22043
22044 (define_insn "subv16qi3"
22045 [(set (match_operand:V16QI 0 "register_operand" "=x")
22046 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22047 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22048 "TARGET_SSE2"
22049 "psubb\t{%2, %0|%0, %2}"
22050 [(set_attr "type" "sseiadd")
22051 (set_attr "mode" "TI")])
22052
22053 (define_insn "subv8hi3"
22054 [(set (match_operand:V8HI 0 "register_operand" "=x")
22055 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22056 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22057 "TARGET_SSE2"
22058 "psubw\t{%2, %0|%0, %2}"
22059 [(set_attr "type" "sseiadd")
22060 (set_attr "mode" "TI")])
22061
22062 (define_insn "subv4si3"
22063 [(set (match_operand:V4SI 0 "register_operand" "=x")
22064 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22065 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22066 "TARGET_SSE2"
22067 "psubd\t{%2, %0|%0, %2}"
22068 [(set_attr "type" "sseiadd")
22069 (set_attr "mode" "TI")])
22070
22071 (define_insn "subv2di3"
22072 [(set (match_operand:V2DI 0 "register_operand" "=x")
22073 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22074 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22075 "TARGET_SSE2"
22076 "psubq\t{%2, %0|%0, %2}"
22077 [(set_attr "type" "sseiadd")
22078 (set_attr "mode" "TI")])
22079
22080 (define_insn "sssubv16qi3"
22081 [(set (match_operand:V16QI 0 "register_operand" "=x")
22082 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22083 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22084 "TARGET_SSE2"
22085 "psubsb\t{%2, %0|%0, %2}"
22086 [(set_attr "type" "sseiadd")
22087 (set_attr "mode" "TI")])
22088
22089 (define_insn "sssubv8hi3"
22090 [(set (match_operand:V8HI 0 "register_operand" "=x")
22091 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22092 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22093 "TARGET_SSE2"
22094 "psubsw\t{%2, %0|%0, %2}"
22095 [(set_attr "type" "sseiadd")
22096 (set_attr "mode" "TI")])
22097
22098 (define_insn "ussubv16qi3"
22099 [(set (match_operand:V16QI 0 "register_operand" "=x")
22100 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22101 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22102 "TARGET_SSE2"
22103 "psubusb\t{%2, %0|%0, %2}"
22104 [(set_attr "type" "sseiadd")
22105 (set_attr "mode" "TI")])
22106
22107 (define_insn "ussubv8hi3"
22108 [(set (match_operand:V8HI 0 "register_operand" "=x")
22109 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22110 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22111 "TARGET_SSE2"
22112 "psubusw\t{%2, %0|%0, %2}"
22113 [(set_attr "type" "sseiadd")
22114 (set_attr "mode" "TI")])
22115
22116 (define_insn "mulv8hi3"
22117 [(set (match_operand:V8HI 0 "register_operand" "=x")
22118 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22119 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22120 "TARGET_SSE2"
22121 "pmullw\t{%2, %0|%0, %2}"
22122 [(set_attr "type" "sseimul")
22123 (set_attr "mode" "TI")])
22124
22125 (define_insn "smulv8hi3_highpart"
22126 [(set (match_operand:V8HI 0 "register_operand" "=x")
22127 (truncate:V8HI
22128 (lshiftrt:V8SI
22129 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22130 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22131 (const_int 16))))]
22132 "TARGET_SSE2"
22133 "pmulhw\t{%2, %0|%0, %2}"
22134 [(set_attr "type" "sseimul")
22135 (set_attr "mode" "TI")])
22136
22137 (define_insn "umulv8hi3_highpart"
22138 [(set (match_operand:V8HI 0 "register_operand" "=x")
22139 (truncate:V8HI
22140 (lshiftrt:V8SI
22141 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22142 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22143 (const_int 16))))]
22144 "TARGET_SSE2"
22145 "pmulhuw\t{%2, %0|%0, %2}"
22146 [(set_attr "type" "sseimul")
22147 (set_attr "mode" "TI")])
22148
22149 (define_insn "sse2_umulsidi3"
22150 [(set (match_operand:DI 0 "register_operand" "=y")
22151 (mult:DI (zero_extend:DI (vec_select:SI
22152 (match_operand:V2SI 1 "register_operand" "0")
22153 (parallel [(const_int 0)])))
22154 (zero_extend:DI (vec_select:SI
22155 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22156 (parallel [(const_int 0)])))))]
22157 "TARGET_SSE2"
22158 "pmuludq\t{%2, %0|%0, %2}"
22159 [(set_attr "type" "sseimul")
22160 (set_attr "mode" "TI")])
22161
22162 (define_insn "sse2_umulv2siv2di3"
22163 [(set (match_operand:V2DI 0 "register_operand" "=x")
22164 (mult:V2DI (zero_extend:V2DI
22165 (vec_select:V2SI
22166 (match_operand:V4SI 1 "register_operand" "0")
22167 (parallel [(const_int 0) (const_int 2)])))
22168 (zero_extend:V2DI
22169 (vec_select:V2SI
22170 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22171 (parallel [(const_int 0) (const_int 2)])))))]
22172 "TARGET_SSE2"
22173 "pmuludq\t{%2, %0|%0, %2}"
22174 [(set_attr "type" "sseimul")
22175 (set_attr "mode" "TI")])
22176
22177 (define_insn "sse2_pmaddwd"
22178 [(set (match_operand:V4SI 0 "register_operand" "=x")
22179 (plus:V4SI
22180 (mult:V4SI
22181 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22182 (parallel [(const_int 0)
22183 (const_int 2)
22184 (const_int 4)
22185 (const_int 6)])))
22186 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22187 (parallel [(const_int 0)
22188 (const_int 2)
22189 (const_int 4)
22190 (const_int 6)]))))
22191 (mult:V4SI
22192 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22193 (parallel [(const_int 1)
22194 (const_int 3)
22195 (const_int 5)
22196 (const_int 7)])))
22197 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22198 (parallel [(const_int 1)
22199 (const_int 3)
22200 (const_int 5)
22201 (const_int 7)]))))))]
22202 "TARGET_SSE2"
22203 "pmaddwd\t{%2, %0|%0, %2}"
22204 [(set_attr "type" "sseiadd")
22205 (set_attr "mode" "TI")])
22206
22207 ;; Same as pxor, but don't show input operands so that we don't think
22208 ;; they are live.
22209 (define_insn "sse2_clrti"
22210 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22211 "TARGET_SSE2"
22212 {
22213 if (get_attr_mode (insn) == MODE_TI)
22214 return "pxor\t%0, %0";
22215 else
22216 return "xorps\t%0, %0";
22217 }
22218 [(set_attr "type" "ssemov")
22219 (set_attr "memory" "none")
22220 (set (attr "mode")
22221 (if_then_else
22222 (ne (symbol_ref "optimize_size")
22223 (const_int 0))
22224 (const_string "V4SF")
22225 (const_string "TI")))])
22226
22227 ;; MMX unsigned averages/sum of absolute differences
22228
22229 (define_insn "sse2_uavgv16qi3"
22230 [(set (match_operand:V16QI 0 "register_operand" "=x")
22231 (ashiftrt:V16QI
22232 (plus:V16QI (plus:V16QI
22233 (match_operand:V16QI 1 "register_operand" "0")
22234 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22235 (const_vector:V16QI [(const_int 1) (const_int 1)
22236 (const_int 1) (const_int 1)
22237 (const_int 1) (const_int 1)
22238 (const_int 1) (const_int 1)
22239 (const_int 1) (const_int 1)
22240 (const_int 1) (const_int 1)
22241 (const_int 1) (const_int 1)
22242 (const_int 1) (const_int 1)]))
22243 (const_int 1)))]
22244 "TARGET_SSE2"
22245 "pavgb\t{%2, %0|%0, %2}"
22246 [(set_attr "type" "sseiadd")
22247 (set_attr "mode" "TI")])
22248
22249 (define_insn "sse2_uavgv8hi3"
22250 [(set (match_operand:V8HI 0 "register_operand" "=x")
22251 (ashiftrt:V8HI
22252 (plus:V8HI (plus:V8HI
22253 (match_operand:V8HI 1 "register_operand" "0")
22254 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22255 (const_vector:V8HI [(const_int 1) (const_int 1)
22256 (const_int 1) (const_int 1)
22257 (const_int 1) (const_int 1)
22258 (const_int 1) (const_int 1)]))
22259 (const_int 1)))]
22260 "TARGET_SSE2"
22261 "pavgw\t{%2, %0|%0, %2}"
22262 [(set_attr "type" "sseiadd")
22263 (set_attr "mode" "TI")])
22264
22265 ;; @@@ this isn't the right representation.
22266 (define_insn "sse2_psadbw"
22267 [(set (match_operand:V2DI 0 "register_operand" "=x")
22268 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22269 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22270 UNSPEC_PSADBW))]
22271 "TARGET_SSE2"
22272 "psadbw\t{%2, %0|%0, %2}"
22273 [(set_attr "type" "sseiadd")
22274 (set_attr "mode" "TI")])
22275
22276
22277 ;; MMX insert/extract/shuffle
22278
22279 (define_insn "sse2_pinsrw"
22280 [(set (match_operand:V8HI 0 "register_operand" "=x")
22281 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22282 (vec_duplicate:V8HI
22283 (truncate:HI
22284 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22285 (match_operand:SI 3 "immediate_operand" "i")))]
22286 "TARGET_SSE2"
22287 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22288 [(set_attr "type" "ssecvt")
22289 (set_attr "mode" "TI")])
22290
22291 (define_insn "sse2_pextrw"
22292 [(set (match_operand:SI 0 "register_operand" "=r")
22293 (zero_extend:SI
22294 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22295 (parallel
22296 [(match_operand:SI 2 "immediate_operand" "i")]))))]
22297 "TARGET_SSE2"
22298 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22299 [(set_attr "type" "ssecvt")
22300 (set_attr "mode" "TI")])
22301
22302 (define_insn "sse2_pshufd"
22303 [(set (match_operand:V4SI 0 "register_operand" "=x")
22304 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22305 (match_operand:SI 2 "immediate_operand" "i")]
22306 UNSPEC_SHUFFLE))]
22307 "TARGET_SSE2"
22308 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22309 [(set_attr "type" "ssecvt")
22310 (set_attr "mode" "TI")])
22311
22312 (define_insn "sse2_pshuflw"
22313 [(set (match_operand:V8HI 0 "register_operand" "=x")
22314 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22315 (match_operand:SI 2 "immediate_operand" "i")]
22316 UNSPEC_PSHUFLW))]
22317 "TARGET_SSE2"
22318 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22319 [(set_attr "type" "ssecvt")
22320 (set_attr "mode" "TI")])
22321
22322 (define_insn "sse2_pshufhw"
22323 [(set (match_operand:V8HI 0 "register_operand" "=x")
22324 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22325 (match_operand:SI 2 "immediate_operand" "i")]
22326 UNSPEC_PSHUFHW))]
22327 "TARGET_SSE2"
22328 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22329 [(set_attr "type" "ssecvt")
22330 (set_attr "mode" "TI")])
22331
22332 ;; MMX mask-generating comparisons
22333
22334 (define_insn "eqv16qi3"
22335 [(set (match_operand:V16QI 0 "register_operand" "=x")
22336 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22337 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22338 "TARGET_SSE2"
22339 "pcmpeqb\t{%2, %0|%0, %2}"
22340 [(set_attr "type" "ssecmp")
22341 (set_attr "mode" "TI")])
22342
22343 (define_insn "eqv8hi3"
22344 [(set (match_operand:V8HI 0 "register_operand" "=x")
22345 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22346 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22347 "TARGET_SSE2"
22348 "pcmpeqw\t{%2, %0|%0, %2}"
22349 [(set_attr "type" "ssecmp")
22350 (set_attr "mode" "TI")])
22351
22352 (define_insn "eqv4si3"
22353 [(set (match_operand:V4SI 0 "register_operand" "=x")
22354 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22355 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22356 "TARGET_SSE2"
22357 "pcmpeqd\t{%2, %0|%0, %2}"
22358 [(set_attr "type" "ssecmp")
22359 (set_attr "mode" "TI")])
22360
22361 (define_insn "gtv16qi3"
22362 [(set (match_operand:V16QI 0 "register_operand" "=x")
22363 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22364 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22365 "TARGET_SSE2"
22366 "pcmpgtb\t{%2, %0|%0, %2}"
22367 [(set_attr "type" "ssecmp")
22368 (set_attr "mode" "TI")])
22369
22370 (define_insn "gtv8hi3"
22371 [(set (match_operand:V8HI 0 "register_operand" "=x")
22372 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22373 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22374 "TARGET_SSE2"
22375 "pcmpgtw\t{%2, %0|%0, %2}"
22376 [(set_attr "type" "ssecmp")
22377 (set_attr "mode" "TI")])
22378
22379 (define_insn "gtv4si3"
22380 [(set (match_operand:V4SI 0 "register_operand" "=x")
22381 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22382 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22383 "TARGET_SSE2"
22384 "pcmpgtd\t{%2, %0|%0, %2}"
22385 [(set_attr "type" "ssecmp")
22386 (set_attr "mode" "TI")])
22387
22388
22389 ;; MMX max/min insns
22390
22391 (define_insn "umaxv16qi3"
22392 [(set (match_operand:V16QI 0 "register_operand" "=x")
22393 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22394 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22395 "TARGET_SSE2"
22396 "pmaxub\t{%2, %0|%0, %2}"
22397 [(set_attr "type" "sseiadd")
22398 (set_attr "mode" "TI")])
22399
22400 (define_insn "smaxv8hi3"
22401 [(set (match_operand:V8HI 0 "register_operand" "=x")
22402 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22403 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22404 "TARGET_SSE2"
22405 "pmaxsw\t{%2, %0|%0, %2}"
22406 [(set_attr "type" "sseiadd")
22407 (set_attr "mode" "TI")])
22408
22409 (define_insn "uminv16qi3"
22410 [(set (match_operand:V16QI 0 "register_operand" "=x")
22411 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22412 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22413 "TARGET_SSE2"
22414 "pminub\t{%2, %0|%0, %2}"
22415 [(set_attr "type" "sseiadd")
22416 (set_attr "mode" "TI")])
22417
22418 (define_insn "sminv8hi3"
22419 [(set (match_operand:V8HI 0 "register_operand" "=x")
22420 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22421 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22422 "TARGET_SSE2"
22423 "pminsw\t{%2, %0|%0, %2}"
22424 [(set_attr "type" "sseiadd")
22425 (set_attr "mode" "TI")])
22426
22427
22428 ;; MMX shifts
22429
22430 (define_insn "ashrv8hi3"
22431 [(set (match_operand:V8HI 0 "register_operand" "=x")
22432 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22433 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22434 "TARGET_SSE2"
22435 "psraw\t{%2, %0|%0, %2}"
22436 [(set_attr "type" "sseishft")
22437 (set_attr "mode" "TI")])
22438
22439 (define_insn "ashrv4si3"
22440 [(set (match_operand:V4SI 0 "register_operand" "=x")
22441 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22442 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22443 "TARGET_SSE2"
22444 "psrad\t{%2, %0|%0, %2}"
22445 [(set_attr "type" "sseishft")
22446 (set_attr "mode" "TI")])
22447
22448 (define_insn "lshrv8hi3"
22449 [(set (match_operand:V8HI 0 "register_operand" "=x")
22450 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22451 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22452 "TARGET_SSE2"
22453 "psrlw\t{%2, %0|%0, %2}"
22454 [(set_attr "type" "sseishft")
22455 (set_attr "mode" "TI")])
22456
22457 (define_insn "lshrv4si3"
22458 [(set (match_operand:V4SI 0 "register_operand" "=x")
22459 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22460 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22461 "TARGET_SSE2"
22462 "psrld\t{%2, %0|%0, %2}"
22463 [(set_attr "type" "sseishft")
22464 (set_attr "mode" "TI")])
22465
22466 (define_insn "lshrv2di3"
22467 [(set (match_operand:V2DI 0 "register_operand" "=x")
22468 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22469 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22470 "TARGET_SSE2"
22471 "psrlq\t{%2, %0|%0, %2}"
22472 [(set_attr "type" "sseishft")
22473 (set_attr "mode" "TI")])
22474
22475 (define_insn "ashlv8hi3"
22476 [(set (match_operand:V8HI 0 "register_operand" "=x")
22477 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22478 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22479 "TARGET_SSE2"
22480 "psllw\t{%2, %0|%0, %2}"
22481 [(set_attr "type" "sseishft")
22482 (set_attr "mode" "TI")])
22483
22484 (define_insn "ashlv4si3"
22485 [(set (match_operand:V4SI 0 "register_operand" "=x")
22486 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22487 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22488 "TARGET_SSE2"
22489 "pslld\t{%2, %0|%0, %2}"
22490 [(set_attr "type" "sseishft")
22491 (set_attr "mode" "TI")])
22492
22493 (define_insn "ashlv2di3"
22494 [(set (match_operand:V2DI 0 "register_operand" "=x")
22495 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22496 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22497 "TARGET_SSE2"
22498 "psllq\t{%2, %0|%0, %2}"
22499 [(set_attr "type" "sseishft")
22500 (set_attr "mode" "TI")])
22501
22502 (define_insn "ashrv8hi3_ti"
22503 [(set (match_operand:V8HI 0 "register_operand" "=x")
22504 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22505 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22506 "TARGET_SSE2"
22507 "psraw\t{%2, %0|%0, %2}"
22508 [(set_attr "type" "sseishft")
22509 (set_attr "mode" "TI")])
22510
22511 (define_insn "ashrv4si3_ti"
22512 [(set (match_operand:V4SI 0 "register_operand" "=x")
22513 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22514 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22515 "TARGET_SSE2"
22516 "psrad\t{%2, %0|%0, %2}"
22517 [(set_attr "type" "sseishft")
22518 (set_attr "mode" "TI")])
22519
22520 (define_insn "lshrv8hi3_ti"
22521 [(set (match_operand:V8HI 0 "register_operand" "=x")
22522 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22523 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22524 "TARGET_SSE2"
22525 "psrlw\t{%2, %0|%0, %2}"
22526 [(set_attr "type" "sseishft")
22527 (set_attr "mode" "TI")])
22528
22529 (define_insn "lshrv4si3_ti"
22530 [(set (match_operand:V4SI 0 "register_operand" "=x")
22531 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22532 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22533 "TARGET_SSE2"
22534 "psrld\t{%2, %0|%0, %2}"
22535 [(set_attr "type" "sseishft")
22536 (set_attr "mode" "TI")])
22537
22538 (define_insn "lshrv2di3_ti"
22539 [(set (match_operand:V2DI 0 "register_operand" "=x")
22540 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22541 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22542 "TARGET_SSE2"
22543 "psrlq\t{%2, %0|%0, %2}"
22544 [(set_attr "type" "sseishft")
22545 (set_attr "mode" "TI")])
22546
22547 (define_insn "ashlv8hi3_ti"
22548 [(set (match_operand:V8HI 0 "register_operand" "=x")
22549 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22550 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22551 "TARGET_SSE2"
22552 "psllw\t{%2, %0|%0, %2}"
22553 [(set_attr "type" "sseishft")
22554 (set_attr "mode" "TI")])
22555
22556 (define_insn "ashlv4si3_ti"
22557 [(set (match_operand:V4SI 0 "register_operand" "=x")
22558 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22559 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22560 "TARGET_SSE2"
22561 "pslld\t{%2, %0|%0, %2}"
22562 [(set_attr "type" "sseishft")
22563 (set_attr "mode" "TI")])
22564
22565 (define_insn "ashlv2di3_ti"
22566 [(set (match_operand:V2DI 0 "register_operand" "=x")
22567 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22568 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22569 "TARGET_SSE2"
22570 "psllq\t{%2, %0|%0, %2}"
22571 [(set_attr "type" "sseishft")
22572 (set_attr "mode" "TI")])
22573
22574 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22575 ;; we wouldn't need here it since we never generate TImode arithmetic.
22576
22577 ;; There has to be some kind of prize for the weirdest new instruction...
22578 (define_insn "sse2_ashlti3"
22579 [(set (match_operand:TI 0 "register_operand" "=x")
22580 (unspec:TI
22581 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22582 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22583 (const_int 8)))] UNSPEC_NOP))]
22584 "TARGET_SSE2"
22585 "pslldq\t{%2, %0|%0, %2}"
22586 [(set_attr "type" "sseishft")
22587 (set_attr "mode" "TI")])
22588
22589 (define_insn "sse2_lshrti3"
22590 [(set (match_operand:TI 0 "register_operand" "=x")
22591 (unspec:TI
22592 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22593 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22594 (const_int 8)))] UNSPEC_NOP))]
22595 "TARGET_SSE2"
22596 "psrldq\t{%2, %0|%0, %2}"
22597 [(set_attr "type" "sseishft")
22598 (set_attr "mode" "TI")])
22599
22600 ;; SSE unpack
22601
22602 (define_insn "sse2_unpckhpd"
22603 [(set (match_operand:V2DF 0 "register_operand" "=x")
22604 (vec_concat:V2DF
22605 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22606 (parallel [(const_int 1)]))
22607 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22608 (parallel [(const_int 0)]))))]
22609 "TARGET_SSE2"
22610 "unpckhpd\t{%2, %0|%0, %2}"
22611 [(set_attr "type" "ssecvt")
22612 (set_attr "mode" "TI")])
22613
22614 (define_insn "sse2_unpcklpd"
22615 [(set (match_operand:V2DF 0 "register_operand" "=x")
22616 (vec_concat:V2DF
22617 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22618 (parallel [(const_int 0)]))
22619 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22620 (parallel [(const_int 1)]))))]
22621 "TARGET_SSE2"
22622 "unpcklpd\t{%2, %0|%0, %2}"
22623 [(set_attr "type" "ssecvt")
22624 (set_attr "mode" "TI")])
22625
22626 ;; MMX pack/unpack insns.
22627
22628 (define_insn "sse2_packsswb"
22629 [(set (match_operand:V16QI 0 "register_operand" "=x")
22630 (vec_concat:V16QI
22631 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22632 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22633 "TARGET_SSE2"
22634 "packsswb\t{%2, %0|%0, %2}"
22635 [(set_attr "type" "ssecvt")
22636 (set_attr "mode" "TI")])
22637
22638 (define_insn "sse2_packssdw"
22639 [(set (match_operand:V8HI 0 "register_operand" "=x")
22640 (vec_concat:V8HI
22641 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22642 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22643 "TARGET_SSE2"
22644 "packssdw\t{%2, %0|%0, %2}"
22645 [(set_attr "type" "ssecvt")
22646 (set_attr "mode" "TI")])
22647
22648 (define_insn "sse2_packuswb"
22649 [(set (match_operand:V16QI 0 "register_operand" "=x")
22650 (vec_concat:V16QI
22651 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22652 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22653 "TARGET_SSE2"
22654 "packuswb\t{%2, %0|%0, %2}"
22655 [(set_attr "type" "ssecvt")
22656 (set_attr "mode" "TI")])
22657
22658 (define_insn "sse2_punpckhbw"
22659 [(set (match_operand:V16QI 0 "register_operand" "=x")
22660 (vec_merge:V16QI
22661 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22662 (parallel [(const_int 8) (const_int 0)
22663 (const_int 9) (const_int 1)
22664 (const_int 10) (const_int 2)
22665 (const_int 11) (const_int 3)
22666 (const_int 12) (const_int 4)
22667 (const_int 13) (const_int 5)
22668 (const_int 14) (const_int 6)
22669 (const_int 15) (const_int 7)]))
22670 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22671 (parallel [(const_int 0) (const_int 8)
22672 (const_int 1) (const_int 9)
22673 (const_int 2) (const_int 10)
22674 (const_int 3) (const_int 11)
22675 (const_int 4) (const_int 12)
22676 (const_int 5) (const_int 13)
22677 (const_int 6) (const_int 14)
22678 (const_int 7) (const_int 15)]))
22679 (const_int 21845)))]
22680 "TARGET_SSE2"
22681 "punpckhbw\t{%2, %0|%0, %2}"
22682 [(set_attr "type" "ssecvt")
22683 (set_attr "mode" "TI")])
22684
22685 (define_insn "sse2_punpckhwd"
22686 [(set (match_operand:V8HI 0 "register_operand" "=x")
22687 (vec_merge:V8HI
22688 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22689 (parallel [(const_int 4) (const_int 0)
22690 (const_int 5) (const_int 1)
22691 (const_int 6) (const_int 2)
22692 (const_int 7) (const_int 3)]))
22693 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22694 (parallel [(const_int 0) (const_int 4)
22695 (const_int 1) (const_int 5)
22696 (const_int 2) (const_int 6)
22697 (const_int 3) (const_int 7)]))
22698 (const_int 85)))]
22699 "TARGET_SSE2"
22700 "punpckhwd\t{%2, %0|%0, %2}"
22701 [(set_attr "type" "ssecvt")
22702 (set_attr "mode" "TI")])
22703
22704 (define_insn "sse2_punpckhdq"
22705 [(set (match_operand:V4SI 0 "register_operand" "=x")
22706 (vec_merge:V4SI
22707 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22708 (parallel [(const_int 2) (const_int 0)
22709 (const_int 3) (const_int 1)]))
22710 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22711 (parallel [(const_int 0) (const_int 2)
22712 (const_int 1) (const_int 3)]))
22713 (const_int 5)))]
22714 "TARGET_SSE2"
22715 "punpckhdq\t{%2, %0|%0, %2}"
22716 [(set_attr "type" "ssecvt")
22717 (set_attr "mode" "TI")])
22718
22719 (define_insn "sse2_punpcklbw"
22720 [(set (match_operand:V16QI 0 "register_operand" "=x")
22721 (vec_merge:V16QI
22722 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22723 (parallel [(const_int 0) (const_int 8)
22724 (const_int 1) (const_int 9)
22725 (const_int 2) (const_int 10)
22726 (const_int 3) (const_int 11)
22727 (const_int 4) (const_int 12)
22728 (const_int 5) (const_int 13)
22729 (const_int 6) (const_int 14)
22730 (const_int 7) (const_int 15)]))
22731 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22732 (parallel [(const_int 8) (const_int 0)
22733 (const_int 9) (const_int 1)
22734 (const_int 10) (const_int 2)
22735 (const_int 11) (const_int 3)
22736 (const_int 12) (const_int 4)
22737 (const_int 13) (const_int 5)
22738 (const_int 14) (const_int 6)
22739 (const_int 15) (const_int 7)]))
22740 (const_int 21845)))]
22741 "TARGET_SSE2"
22742 "punpcklbw\t{%2, %0|%0, %2}"
22743 [(set_attr "type" "ssecvt")
22744 (set_attr "mode" "TI")])
22745
22746 (define_insn "sse2_punpcklwd"
22747 [(set (match_operand:V8HI 0 "register_operand" "=x")
22748 (vec_merge:V8HI
22749 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22750 (parallel [(const_int 0) (const_int 4)
22751 (const_int 1) (const_int 5)
22752 (const_int 2) (const_int 6)
22753 (const_int 3) (const_int 7)]))
22754 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22755 (parallel [(const_int 4) (const_int 0)
22756 (const_int 5) (const_int 1)
22757 (const_int 6) (const_int 2)
22758 (const_int 7) (const_int 3)]))
22759 (const_int 85)))]
22760 "TARGET_SSE2"
22761 "punpcklwd\t{%2, %0|%0, %2}"
22762 [(set_attr "type" "ssecvt")
22763 (set_attr "mode" "TI")])
22764
22765 (define_insn "sse2_punpckldq"
22766 [(set (match_operand:V4SI 0 "register_operand" "=x")
22767 (vec_merge:V4SI
22768 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22769 (parallel [(const_int 0) (const_int 2)
22770 (const_int 1) (const_int 3)]))
22771 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22772 (parallel [(const_int 2) (const_int 0)
22773 (const_int 3) (const_int 1)]))
22774 (const_int 5)))]
22775 "TARGET_SSE2"
22776 "punpckldq\t{%2, %0|%0, %2}"
22777 [(set_attr "type" "ssecvt")
22778 (set_attr "mode" "TI")])
22779
22780 (define_insn "sse2_punpcklqdq"
22781 [(set (match_operand:V2DI 0 "register_operand" "=x")
22782 (vec_merge:V2DI
22783 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22784 (parallel [(const_int 1)
22785 (const_int 0)]))
22786 (match_operand:V2DI 1 "register_operand" "0")
22787 (const_int 1)))]
22788 "TARGET_SSE2"
22789 "punpcklqdq\t{%2, %0|%0, %2}"
22790 [(set_attr "type" "ssecvt")
22791 (set_attr "mode" "TI")])
22792
22793 (define_insn "sse2_punpckhqdq"
22794 [(set (match_operand:V2DI 0 "register_operand" "=x")
22795 (vec_merge:V2DI
22796 (match_operand:V2DI 1 "register_operand" "0")
22797 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22798 (parallel [(const_int 1)
22799 (const_int 0)]))
22800 (const_int 1)))]
22801 "TARGET_SSE2"
22802 "punpckhqdq\t{%2, %0|%0, %2}"
22803 [(set_attr "type" "ssecvt")
22804 (set_attr "mode" "TI")])
22805
22806 ;; SSE2 moves
22807
22808 (define_insn "sse2_movapd"
22809 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22810 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22811 UNSPEC_MOVA))]
22812 "TARGET_SSE2
22813 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22814 "movapd\t{%1, %0|%0, %1}"
22815 [(set_attr "type" "ssemov")
22816 (set_attr "mode" "V2DF")])
22817
22818 (define_insn "sse2_movupd"
22819 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22820 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22821 UNSPEC_MOVU))]
22822 "TARGET_SSE2
22823 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22824 "movupd\t{%1, %0|%0, %1}"
22825 [(set_attr "type" "ssecvt")
22826 (set_attr "mode" "V2DF")])
22827
22828 (define_insn "sse2_movdqa"
22829 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22830 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22831 UNSPEC_MOVA))]
22832 "TARGET_SSE2
22833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22834 "movdqa\t{%1, %0|%0, %1}"
22835 [(set_attr "type" "ssemov")
22836 (set_attr "mode" "TI")])
22837
22838 (define_insn "sse2_movdqu"
22839 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22840 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22841 UNSPEC_MOVU))]
22842 "TARGET_SSE2
22843 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22844 "movdqu\t{%1, %0|%0, %1}"
22845 [(set_attr "type" "ssecvt")
22846 (set_attr "mode" "TI")])
22847
22848 (define_insn "sse2_movdq2q"
22849 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22850 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22851 (parallel [(const_int 0)])))]
22852 "TARGET_SSE2 && !TARGET_64BIT"
22853 "@
22854 movq\t{%1, %0|%0, %1}
22855 movdq2q\t{%1, %0|%0, %1}"
22856 [(set_attr "type" "ssecvt")
22857 (set_attr "mode" "TI")])
22858
22859 (define_insn "sse2_movdq2q_rex64"
22860 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22861 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22862 (parallel [(const_int 0)])))]
22863 "TARGET_SSE2 && TARGET_64BIT"
22864 "@
22865 movq\t{%1, %0|%0, %1}
22866 movdq2q\t{%1, %0|%0, %1}
22867 movd\t{%1, %0|%0, %1}"
22868 [(set_attr "type" "ssecvt")
22869 (set_attr "mode" "TI")])
22870
22871 (define_insn "sse2_movq2dq"
22872 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22873 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22874 (const_int 0)))]
22875 "TARGET_SSE2 && !TARGET_64BIT"
22876 "@
22877 movq\t{%1, %0|%0, %1}
22878 movq2dq\t{%1, %0|%0, %1}"
22879 [(set_attr "type" "ssecvt,ssemov")
22880 (set_attr "mode" "TI")])
22881
22882 (define_insn "sse2_movq2dq_rex64"
22883 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22884 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22885 (const_int 0)))]
22886 "TARGET_SSE2 && TARGET_64BIT"
22887 "@
22888 movq\t{%1, %0|%0, %1}
22889 movq2dq\t{%1, %0|%0, %1}
22890 movd\t{%1, %0|%0, %1}"
22891 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22892 (set_attr "mode" "TI")])
22893
22894 (define_insn "sse2_movq"
22895 [(set (match_operand:V2DI 0 "register_operand" "=x")
22896 (vec_concat:V2DI (vec_select:DI
22897 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22898 (parallel [(const_int 0)]))
22899 (const_int 0)))]
22900 "TARGET_SSE2"
22901 "movq\t{%1, %0|%0, %1}"
22902 [(set_attr "type" "ssemov")
22903 (set_attr "mode" "TI")])
22904
22905 (define_insn "sse2_loadd"
22906 [(set (match_operand:V4SI 0 "register_operand" "=x")
22907 (vec_merge:V4SI
22908 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22909 (const_vector:V4SI [(const_int 0)
22910 (const_int 0)
22911 (const_int 0)
22912 (const_int 0)])
22913 (const_int 1)))]
22914 "TARGET_SSE2"
22915 "movd\t{%1, %0|%0, %1}"
22916 [(set_attr "type" "ssemov")
22917 (set_attr "mode" "TI")])
22918
22919 (define_insn "sse2_stored"
22920 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22921 (vec_select:SI
22922 (match_operand:V4SI 1 "register_operand" "x")
22923 (parallel [(const_int 0)])))]
22924 "TARGET_SSE2"
22925 "movd\t{%1, %0|%0, %1}"
22926 [(set_attr "type" "ssemov")
22927 (set_attr "mode" "TI")])
22928
22929 (define_insn "sse2_movhpd"
22930 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22931 (vec_merge:V2DF
22932 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22933 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22934 (const_int 2)))]
22935 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22936 "movhpd\t{%2, %0|%0, %2}"
22937 [(set_attr "type" "ssecvt")
22938 (set_attr "mode" "V2DF")])
22939
22940 (define_insn "sse2_movlpd"
22941 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22942 (vec_merge:V2DF
22943 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22944 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22945 (const_int 1)))]
22946 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22947 "movlpd\t{%2, %0|%0, %2}"
22948 [(set_attr "type" "ssecvt")
22949 (set_attr "mode" "V2DF")])
22950
22951 (define_expand "sse2_loadsd"
22952 [(match_operand:V2DF 0 "register_operand" "")
22953 (match_operand:DF 1 "memory_operand" "")]
22954 "TARGET_SSE2"
22955 {
22956 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22957 CONST0_RTX (V2DFmode)));
22958 DONE;
22959 })
22960
22961 (define_insn "sse2_loadsd_1"
22962 [(set (match_operand:V2DF 0 "register_operand" "=x")
22963 (vec_merge:V2DF
22964 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22965 (match_operand:V2DF 2 "const0_operand" "X")
22966 (const_int 1)))]
22967 "TARGET_SSE2"
22968 "movsd\t{%1, %0|%0, %1}"
22969 [(set_attr "type" "ssecvt")
22970 (set_attr "mode" "DF")])
22971
22972 (define_insn "sse2_movsd"
22973 [(set (match_operand:V2DF 0 "register_operand" "=x")
22974 (vec_merge:V2DF
22975 (match_operand:V2DF 1 "register_operand" "0")
22976 (match_operand:V2DF 2 "register_operand" "x")
22977 (const_int 1)))]
22978 "TARGET_SSE2"
22979 "movsd\t{%2, %0|%0, %2}"
22980 [(set_attr "type" "ssecvt")
22981 (set_attr "mode" "DF")])
22982
22983 (define_insn "sse2_storesd"
22984 [(set (match_operand:DF 0 "memory_operand" "=m")
22985 (vec_select:DF
22986 (match_operand:V2DF 1 "register_operand" "x")
22987 (parallel [(const_int 0)])))]
22988 "TARGET_SSE2"
22989 "movsd\t{%1, %0|%0, %1}"
22990 [(set_attr "type" "ssecvt")
22991 (set_attr "mode" "DF")])
22992
22993 (define_insn "sse2_shufpd"
22994 [(set (match_operand:V2DF 0 "register_operand" "=x")
22995 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22996 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22997 (match_operand:SI 3 "immediate_operand" "i")]
22998 UNSPEC_SHUFFLE))]
22999 "TARGET_SSE2"
23000 ;; @@@ check operand order for intel/nonintel syntax
23001 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23002 [(set_attr "type" "ssecvt")
23003 (set_attr "mode" "V2DF")])
23004
23005 (define_insn "sse2_clflush"
23006 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23007 UNSPECV_CLFLUSH)]
23008 "TARGET_SSE2"
23009 "clflush %0"
23010 [(set_attr "type" "sse")
23011 (set_attr "memory" "unknown")])
23012
23013 (define_expand "sse2_mfence"
23014 [(set (match_dup 0)
23015 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23016 "TARGET_SSE2"
23017 {
23018 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23019 MEM_VOLATILE_P (operands[0]) = 1;
23020 })
23021
23022 (define_insn "*mfence_insn"
23023 [(set (match_operand:BLK 0 "" "")
23024 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23025 "TARGET_SSE2"
23026 "mfence"
23027 [(set_attr "type" "sse")
23028 (set_attr "memory" "unknown")])
23029
23030 (define_expand "sse2_lfence"
23031 [(set (match_dup 0)
23032 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23033 "TARGET_SSE2"
23034 {
23035 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23036 MEM_VOLATILE_P (operands[0]) = 1;
23037 })
23038
23039 (define_insn "*lfence_insn"
23040 [(set (match_operand:BLK 0 "" "")
23041 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23042 "TARGET_SSE2"
23043 "lfence"
23044 [(set_attr "type" "sse")
23045 (set_attr "memory" "unknown")])