]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
configure.in (HAVE_AS_TLS): New test.
[thirdparty/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, 2001, 2002
3 ;; Free Software Foundation, Inc.
4 ;; Mostly by William Schelter.
5 ;; x86_64 support added by Jan Hubicka
6 ;;
7 ;; This file is part of GNU CC.
8 ;;
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13 ;;
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18 ;;
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
30 ;; updates for most instructions.
31 ;;
32 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
33 ;; constraint letters.
34 ;;
35 ;; The special asm out single letter directives following a '%' are:
36 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
37 ;; operands[1].
38 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
39 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
40 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
41 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
42 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
43 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
44 ;; 'J' Print the appropriate jump operand.
45 ;;
46 ;; 'b' Print the QImode name of the register for the indicated operand.
47 ;; %b0 would print %al if operands[0] is reg 0.
48 ;; 'w' Likewise, print the HImode name of the register.
49 ;; 'k' Likewise, print the SImode name of the register.
50 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; 'y' Print "st(0)" instead of "st" as a register.
52
53 ;; UNSPEC usage:
54
55 (define_constants
56 [; Relocation specifiers
57 (UNSPEC_GOT 0)
58 (UNSPEC_GOTOFF 1)
59 (UNSPEC_GOTPCREL 2)
60 (UNSPEC_GOTTPOFF 3)
61 (UNSPEC_TPOFF 4)
62 (UNSPEC_NTPOFF 5)
63 (UNSPEC_DTPOFF 6)
64
65 ; Prologue support
66 (UNSPEC_STACK_PROBE 10)
67 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SET_GOT 12)
69 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70
71 ; TLS support
72 (UNSPEC_TP 15)
73 (UNSPEC_TLS_GD 16)
74 (UNSPEC_TLS_LD_BASE 17)
75
76 ; Other random patterns
77 (UNSPEC_SCAS 20)
78 (UNSPEC_SIN 21)
79 (UNSPEC_COS 22)
80 (UNSPEC_BSF 23)
81 (UNSPEC_FNSTSW 24)
82 (UNSPEC_SAHF 25)
83 (UNSPEC_FSTCW 26)
84 (UNSPEC_ADD_CARRY 27)
85 (UNSPEC_FLDCW 28)
86
87 ; For SSE/MMX support:
88 (UNSPEC_FIX 30)
89 (UNSPEC_MASKMOV 32)
90 (UNSPEC_MOVMSK 33)
91 (UNSPEC_MOVNT 34)
92 (UNSPEC_MOVA 38)
93 (UNSPEC_MOVU 39)
94 (UNSPEC_SHUFFLE 41)
95 (UNSPEC_RCP 42)
96 (UNSPEC_RSQRT 43)
97 (UNSPEC_SFENCE 44)
98 (UNSPEC_NOP 45) ; prevents combiner cleverness
99 (UNSPEC_PAVGUSB 49)
100 (UNSPEC_PFRCP 50)
101 (UNSPEC_PFRCPIT1 51)
102 (UNSPEC_PFRCPIT2 52)
103 (UNSPEC_PFRSQRT 53)
104 (UNSPEC_PFRSQIT1 54)
105 (UNSPEC_PSHUFLW 55)
106 (UNSPEC_PSHUFHW 56)
107 (UNSPEC_MFENCE 59)
108 (UNSPEC_LFENCE 60)
109 (UNSPEC_PSADBW 61)
110 ])
111
112 (define_constants
113 [(UNSPECV_BLOCKAGE 0)
114 (UNSPECV_EH_RETURN 13)
115 (UNSPECV_EMMS 31)
116 (UNSPECV_LDMXCSR 37)
117 (UNSPECV_STMXCSR 40)
118 (UNSPECV_FEMMS 46)
119 (UNSPECV_CLFLUSH 57)
120 ])
121
122 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
123 ;; from i386.c.
124
125 ;; In C guard expressions, put expressions which may be compile-time
126 ;; constants first. This allows for better optimization. For
127 ;; example, write "TARGET_64BIT && reload_completed", not
128 ;; "reload_completed && TARGET_64BIT".
129
130 \f
131 ;; Processor type. This attribute must exactly match the processor_type
132 ;; enumeration in i386.h.
133 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
134 (const (symbol_ref "ix86_cpu")))
135
136 ;; A basic instruction type. Refinements due to arguments to be
137 ;; provided in other attributes.
138 (define_attr "type"
139 "other,multi,
140 alu,alu1,negnot,imov,imovx,lea,
141 incdec,ishift,rotate,imul,idiv,
142 icmp,test,ibr,setcc,icmov,
143 push,pop,call,callv,
144 str,cld,
145 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
146 sselog,sseiadd,sseishft,sseimul,
147 sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
148 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
149 (const_string "other"))
150
151 ;; Main data type used by the insn
152 (define_attr "mode"
153 "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI,V4SF,V2DF,V2SF"
154 (const_string "unknown"))
155
156 ;; The CPU unit operations uses.
157 (define_attr "unit" "integer,i387,sse,mmx,unknown"
158 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
159 (const_string "i387")
160 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
161 sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv")
162 (const_string "sse")
163 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
164 (const_string "mmx")]
165 (const_string "integer")))
166
167 ;; The (bounding maximum) length of an instruction immediate.
168 (define_attr "length_immediate" ""
169 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv")
170 (const_int 0)
171 (eq_attr "unit" "i387,sse,mmx")
172 (const_int 0)
173 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,imul,
174 icmp,push,pop")
175 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
176 (eq_attr "type" "imov,test")
177 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
178 (eq_attr "type" "call")
179 (if_then_else (match_operand 0 "constant_call_address_operand" "")
180 (const_int 4)
181 (const_int 0))
182 (eq_attr "type" "callv")
183 (if_then_else (match_operand 1 "constant_call_address_operand" "")
184 (const_int 4)
185 (const_int 0))
186 (eq_attr "type" "ibr")
187 (if_then_else (and (ge (minus (match_dup 0) (pc))
188 (const_int -128))
189 (lt (minus (match_dup 0) (pc))
190 (const_int 124)))
191 (const_int 1)
192 (const_int 4))
193 ]
194 (symbol_ref "/* Update immediate_length and other attributes! */
195 abort(),1")))
196
197 ;; The (bounding maximum) length of an instruction address.
198 (define_attr "length_address" ""
199 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
200 (const_int 0)
201 (and (eq_attr "type" "call")
202 (match_operand 1 "constant_call_address_operand" ""))
203 (const_int 0)
204 (and (eq_attr "type" "callv")
205 (match_operand 1 "constant_call_address_operand" ""))
206 (const_int 0)
207 ]
208 (symbol_ref "ix86_attr_length_address_default (insn)")))
209
210 ;; Set when length prefix is used.
211 (define_attr "prefix_data16" ""
212 (if_then_else (ior (eq_attr "mode" "HI")
213 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
214 (const_int 1)
215 (const_int 0)))
216
217 ;; Set when string REP prefix is used.
218 (define_attr "prefix_rep" ""
219 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
220 (const_int 1)
221 (const_int 0)))
222
223 ;; Set when 0f opcode prefix is used.
224 (define_attr "prefix_0f" ""
225 (if_then_else
226 (eq_attr "type"
227 "imovx,setcc,icmov,
228 sselog,sseiadd,sseishft,sseimul,
229 sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
230 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
231 (const_int 1)
232 (const_int 0)))
233
234 ;; Set when modrm byte is used.
235 (define_attr "modrm" ""
236 (cond [(eq_attr "type" "str,cld")
237 (const_int 0)
238 (eq_attr "unit" "i387")
239 (const_int 0)
240 (and (eq_attr "type" "incdec")
241 (ior (match_operand:SI 1 "register_operand" "")
242 (match_operand:HI 1 "register_operand" "")))
243 (const_int 0)
244 (and (eq_attr "type" "push")
245 (not (match_operand 1 "memory_operand" "")))
246 (const_int 0)
247 (and (eq_attr "type" "pop")
248 (not (match_operand 0 "memory_operand" "")))
249 (const_int 0)
250 (and (eq_attr "type" "imov")
251 (and (match_operand 0 "register_operand" "")
252 (match_operand 1 "immediate_operand" "")))
253 (const_int 0)
254 ]
255 (const_int 1)))
256
257 ;; The (bounding maximum) length of an instruction in bytes.
258 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
259 ;; to split it and compute proper length as for other insns.
260 (define_attr "length" ""
261 (cond [(eq_attr "type" "other,multi,fistp")
262 (const_int 16)
263 (eq_attr "unit" "i387")
264 (plus (const_int 2)
265 (plus (attr "prefix_data16")
266 (attr "length_address")))]
267 (plus (plus (attr "modrm")
268 (plus (attr "prefix_0f")
269 (const_int 1)))
270 (plus (attr "prefix_rep")
271 (plus (attr "prefix_data16")
272 (plus (attr "length_immediate")
273 (attr "length_address")))))))
274
275 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
276 ;; `store' if there is a simple memory reference therein, or `unknown'
277 ;; if the instruction is complex.
278
279 (define_attr "memory" "none,load,store,both,unknown"
280 (cond [(eq_attr "type" "other,multi,str")
281 (const_string "unknown")
282 (eq_attr "type" "lea,fcmov,fpspc,cld")
283 (const_string "none")
284 (eq_attr "type" "fistp")
285 (const_string "both")
286 (eq_attr "type" "push")
287 (if_then_else (match_operand 1 "memory_operand" "")
288 (const_string "both")
289 (const_string "store"))
290 (eq_attr "type" "pop,setcc")
291 (if_then_else (match_operand 0 "memory_operand" "")
292 (const_string "both")
293 (const_string "load"))
294 (eq_attr "type" "icmp,test,ssecmp,mmxcmp,fcmp")
295 (if_then_else (ior (match_operand 0 "memory_operand" "")
296 (match_operand 1 "memory_operand" ""))
297 (const_string "load")
298 (const_string "none"))
299 (eq_attr "type" "ibr")
300 (if_then_else (match_operand 0 "memory_operand" "")
301 (const_string "load")
302 (const_string "none"))
303 (eq_attr "type" "call")
304 (if_then_else (match_operand 0 "constant_call_address_operand" "")
305 (const_string "none")
306 (const_string "load"))
307 (eq_attr "type" "callv")
308 (if_then_else (match_operand 1 "constant_call_address_operand" "")
309 (const_string "none")
310 (const_string "load"))
311 (and (eq_attr "type" "alu1,negnot")
312 (match_operand 1 "memory_operand" ""))
313 (const_string "both")
314 (and (match_operand 0 "memory_operand" "")
315 (match_operand 1 "memory_operand" ""))
316 (const_string "both")
317 (match_operand 0 "memory_operand" "")
318 (const_string "store")
319 (match_operand 1 "memory_operand" "")
320 (const_string "load")
321 (and (eq_attr "type"
322 "!alu1,negnot,
323 imov,imovx,icmp,test,
324 fmov,fcmp,fsgn,
325 sse,ssemov,ssecmp,ssecvt,
326 mmx,mmxmov,mmxcmp,mmxcvt")
327 (match_operand 2 "memory_operand" ""))
328 (const_string "load")
329 (and (eq_attr "type" "icmov")
330 (match_operand 3 "memory_operand" ""))
331 (const_string "load")
332 ]
333 (const_string "none")))
334
335 ;; Indicates if an instruction has both an immediate and a displacement.
336
337 (define_attr "imm_disp" "false,true,unknown"
338 (cond [(eq_attr "type" "other,multi")
339 (const_string "unknown")
340 (and (eq_attr "type" "icmp,test,imov")
341 (and (match_operand 0 "memory_displacement_operand" "")
342 (match_operand 1 "immediate_operand" "")))
343 (const_string "true")
344 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
345 (and (match_operand 0 "memory_displacement_operand" "")
346 (match_operand 2 "immediate_operand" "")))
347 (const_string "true")
348 ]
349 (const_string "false")))
350
351 ;; Indicates if an FP operation has an integer source.
352
353 (define_attr "fp_int_src" "false,true"
354 (const_string "false"))
355
356 ;; Describe a user's asm statement.
357 (define_asm_attributes
358 [(set_attr "length" "128")
359 (set_attr "type" "multi")])
360 \f
361 (include "pentium.md")
362 (include "ppro.md")
363 (include "k6.md")
364 (include "athlon.md")
365 \f
366 ;; Compare instructions.
367
368 ;; All compare insns have expanders that save the operands away without
369 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
370 ;; after the cmp) will actually emit the cmpM.
371
372 (define_expand "cmpdi"
373 [(set (reg:CC 17)
374 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
375 (match_operand:DI 1 "x86_64_general_operand" "")))]
376 ""
377 {
378 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
379 operands[0] = force_reg (DImode, operands[0]);
380 ix86_compare_op0 = operands[0];
381 ix86_compare_op1 = operands[1];
382 DONE;
383 })
384
385 (define_expand "cmpsi"
386 [(set (reg:CC 17)
387 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
388 (match_operand:SI 1 "general_operand" "")))]
389 ""
390 {
391 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
392 operands[0] = force_reg (SImode, operands[0]);
393 ix86_compare_op0 = operands[0];
394 ix86_compare_op1 = operands[1];
395 DONE;
396 })
397
398 (define_expand "cmphi"
399 [(set (reg:CC 17)
400 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
401 (match_operand:HI 1 "general_operand" "")))]
402 ""
403 {
404 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
405 operands[0] = force_reg (HImode, operands[0]);
406 ix86_compare_op0 = operands[0];
407 ix86_compare_op1 = operands[1];
408 DONE;
409 })
410
411 (define_expand "cmpqi"
412 [(set (reg:CC 17)
413 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
414 (match_operand:QI 1 "general_operand" "")))]
415 "TARGET_QIMODE_MATH"
416 {
417 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
418 operands[0] = force_reg (QImode, operands[0]);
419 ix86_compare_op0 = operands[0];
420 ix86_compare_op1 = operands[1];
421 DONE;
422 })
423
424 (define_insn "cmpdi_ccno_1_rex64"
425 [(set (reg 17)
426 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
427 (match_operand:DI 1 "const0_operand" "n,n")))]
428 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
429 "@
430 test{q}\t{%0, %0|%0, %0}
431 cmp{q}\t{%1, %0|%0, %1}"
432 [(set_attr "type" "test,icmp")
433 (set_attr "length_immediate" "0,1")
434 (set_attr "mode" "DI")])
435
436 (define_insn "*cmpdi_minus_1_rex64"
437 [(set (reg 17)
438 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
439 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
440 (const_int 0)))]
441 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
442 "cmp{q}\t{%1, %0|%0, %1}"
443 [(set_attr "type" "icmp")
444 (set_attr "mode" "DI")])
445
446 (define_expand "cmpdi_1_rex64"
447 [(set (reg:CC 17)
448 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
449 (match_operand:DI 1 "general_operand" "")))]
450 "TARGET_64BIT"
451 "")
452
453 (define_insn "cmpdi_1_insn_rex64"
454 [(set (reg 17)
455 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
456 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
457 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
458 "cmp{q}\t{%1, %0|%0, %1}"
459 [(set_attr "type" "icmp")
460 (set_attr "mode" "DI")])
461
462
463 (define_insn "*cmpsi_ccno_1"
464 [(set (reg 17)
465 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
466 (match_operand:SI 1 "const0_operand" "n,n")))]
467 "ix86_match_ccmode (insn, CCNOmode)"
468 "@
469 test{l}\t{%0, %0|%0, %0}
470 cmp{l}\t{%1, %0|%0, %1}"
471 [(set_attr "type" "test,icmp")
472 (set_attr "length_immediate" "0,1")
473 (set_attr "mode" "SI")])
474
475 (define_insn "*cmpsi_minus_1"
476 [(set (reg 17)
477 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
478 (match_operand:SI 1 "general_operand" "ri,mr"))
479 (const_int 0)))]
480 "ix86_match_ccmode (insn, CCGOCmode)"
481 "cmp{l}\t{%1, %0|%0, %1}"
482 [(set_attr "type" "icmp")
483 (set_attr "mode" "SI")])
484
485 (define_expand "cmpsi_1"
486 [(set (reg:CC 17)
487 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
488 (match_operand:SI 1 "general_operand" "ri,mr")))]
489 ""
490 "")
491
492 (define_insn "*cmpsi_1_insn"
493 [(set (reg 17)
494 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
495 (match_operand:SI 1 "general_operand" "ri,mr")))]
496 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
497 && ix86_match_ccmode (insn, CCmode)"
498 "cmp{l}\t{%1, %0|%0, %1}"
499 [(set_attr "type" "icmp")
500 (set_attr "mode" "SI")])
501
502 (define_insn "*cmphi_ccno_1"
503 [(set (reg 17)
504 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
505 (match_operand:HI 1 "const0_operand" "n,n")))]
506 "ix86_match_ccmode (insn, CCNOmode)"
507 "@
508 test{w}\t{%0, %0|%0, %0}
509 cmp{w}\t{%1, %0|%0, %1}"
510 [(set_attr "type" "test,icmp")
511 (set_attr "length_immediate" "0,1")
512 (set_attr "mode" "HI")])
513
514 (define_insn "*cmphi_minus_1"
515 [(set (reg 17)
516 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
517 (match_operand:HI 1 "general_operand" "ri,mr"))
518 (const_int 0)))]
519 "ix86_match_ccmode (insn, CCGOCmode)"
520 "cmp{w}\t{%1, %0|%0, %1}"
521 [(set_attr "type" "icmp")
522 (set_attr "mode" "HI")])
523
524 (define_insn "*cmphi_1"
525 [(set (reg 17)
526 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
527 (match_operand:HI 1 "general_operand" "ri,mr")))]
528 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
529 && ix86_match_ccmode (insn, CCmode)"
530 "cmp{w}\t{%1, %0|%0, %1}"
531 [(set_attr "type" "icmp")
532 (set_attr "mode" "HI")])
533
534 (define_insn "*cmpqi_ccno_1"
535 [(set (reg 17)
536 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
537 (match_operand:QI 1 "const0_operand" "n,n")))]
538 "ix86_match_ccmode (insn, CCNOmode)"
539 "@
540 test{b}\t{%0, %0|%0, %0}
541 cmp{b}\t{$0, %0|%0, 0}"
542 [(set_attr "type" "test,icmp")
543 (set_attr "length_immediate" "0,1")
544 (set_attr "mode" "QI")])
545
546 (define_insn "*cmpqi_1"
547 [(set (reg 17)
548 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
549 (match_operand:QI 1 "general_operand" "qi,mq")))]
550 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
551 && ix86_match_ccmode (insn, CCmode)"
552 "cmp{b}\t{%1, %0|%0, %1}"
553 [(set_attr "type" "icmp")
554 (set_attr "mode" "QI")])
555
556 (define_insn "*cmpqi_minus_1"
557 [(set (reg 17)
558 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
559 (match_operand:QI 1 "general_operand" "qi,mq"))
560 (const_int 0)))]
561 "ix86_match_ccmode (insn, CCGOCmode)"
562 "cmp{b}\t{%1, %0|%0, %1}"
563 [(set_attr "type" "icmp")
564 (set_attr "mode" "QI")])
565
566 (define_insn "*cmpqi_ext_1"
567 [(set (reg 17)
568 (compare
569 (match_operand:QI 0 "general_operand" "Qm")
570 (subreg:QI
571 (zero_extract:SI
572 (match_operand 1 "ext_register_operand" "Q")
573 (const_int 8)
574 (const_int 8)) 0)))]
575 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
576 "cmp{b}\t{%h1, %0|%0, %h1}"
577 [(set_attr "type" "icmp")
578 (set_attr "mode" "QI")])
579
580 (define_insn "*cmpqi_ext_1_rex64"
581 [(set (reg 17)
582 (compare
583 (match_operand:QI 0 "register_operand" "Q")
584 (subreg:QI
585 (zero_extract:SI
586 (match_operand 1 "ext_register_operand" "Q")
587 (const_int 8)
588 (const_int 8)) 0)))]
589 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
590 "cmp{b}\t{%h1, %0|%0, %h1}"
591 [(set_attr "type" "icmp")
592 (set_attr "mode" "QI")])
593
594 (define_insn "*cmpqi_ext_2"
595 [(set (reg 17)
596 (compare
597 (subreg:QI
598 (zero_extract:SI
599 (match_operand 0 "ext_register_operand" "Q")
600 (const_int 8)
601 (const_int 8)) 0)
602 (match_operand:QI 1 "const0_operand" "n")))]
603 "ix86_match_ccmode (insn, CCNOmode)"
604 "test{b}\t%h0, %h0"
605 [(set_attr "type" "test")
606 (set_attr "length_immediate" "0")
607 (set_attr "mode" "QI")])
608
609 (define_expand "cmpqi_ext_3"
610 [(set (reg:CC 17)
611 (compare:CC
612 (subreg:QI
613 (zero_extract:SI
614 (match_operand 0 "ext_register_operand" "")
615 (const_int 8)
616 (const_int 8)) 0)
617 (match_operand:QI 1 "general_operand" "")))]
618 ""
619 "")
620
621 (define_insn "cmpqi_ext_3_insn"
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 "general_operand" "Qmn")))]
630 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
631 "cmp{b}\t{%1, %h0|%h0, %1}"
632 [(set_attr "type" "icmp")
633 (set_attr "mode" "QI")])
634
635 (define_insn "cmpqi_ext_3_insn_rex64"
636 [(set (reg 17)
637 (compare
638 (subreg:QI
639 (zero_extract:SI
640 (match_operand 0 "ext_register_operand" "Q")
641 (const_int 8)
642 (const_int 8)) 0)
643 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
644 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
645 "cmp{b}\t{%1, %h0|%h0, %1}"
646 [(set_attr "type" "icmp")
647 (set_attr "mode" "QI")])
648
649 (define_insn "*cmpqi_ext_4"
650 [(set (reg 17)
651 (compare
652 (subreg:QI
653 (zero_extract:SI
654 (match_operand 0 "ext_register_operand" "Q")
655 (const_int 8)
656 (const_int 8)) 0)
657 (subreg:QI
658 (zero_extract:SI
659 (match_operand 1 "ext_register_operand" "Q")
660 (const_int 8)
661 (const_int 8)) 0)))]
662 "ix86_match_ccmode (insn, CCmode)"
663 "cmp{b}\t{%h1, %h0|%h0, %h1}"
664 [(set_attr "type" "icmp")
665 (set_attr "mode" "QI")])
666
667 ;; These implement float point compares.
668 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
669 ;; which would allow mix and match FP modes on the compares. Which is what
670 ;; the old patterns did, but with many more of them.
671
672 (define_expand "cmpxf"
673 [(set (reg:CC 17)
674 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
675 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
676 "!TARGET_64BIT && TARGET_80387"
677 {
678 ix86_compare_op0 = operands[0];
679 ix86_compare_op1 = operands[1];
680 DONE;
681 })
682
683 (define_expand "cmptf"
684 [(set (reg:CC 17)
685 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
686 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
687 "TARGET_80387"
688 {
689 ix86_compare_op0 = operands[0];
690 ix86_compare_op1 = operands[1];
691 DONE;
692 })
693
694 (define_expand "cmpdf"
695 [(set (reg:CC 17)
696 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
697 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
698 "TARGET_80387 || TARGET_SSE2"
699 {
700 ix86_compare_op0 = operands[0];
701 ix86_compare_op1 = operands[1];
702 DONE;
703 })
704
705 (define_expand "cmpsf"
706 [(set (reg:CC 17)
707 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
708 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
709 "TARGET_80387 || TARGET_SSE"
710 {
711 ix86_compare_op0 = operands[0];
712 ix86_compare_op1 = operands[1];
713 DONE;
714 })
715
716 ;; FP compares, step 1:
717 ;; Set the FP condition codes.
718 ;;
719 ;; CCFPmode compare with exceptions
720 ;; CCFPUmode compare with no exceptions
721
722 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
723 ;; and that fp moves clobber the condition codes, and that there is
724 ;; currently no way to describe this fact to reg-stack. So there are
725 ;; no splitters yet for this.
726
727 ;; %%% YIKES! This scheme does not retain a strong connection between
728 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
729 ;; work! Only allow tos/mem with tos in op 0.
730 ;;
731 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
732 ;; things aren't as bad as they sound...
733
734 (define_insn "*cmpfp_0"
735 [(set (match_operand:HI 0 "register_operand" "=a")
736 (unspec:HI
737 [(compare:CCFP (match_operand 1 "register_operand" "f")
738 (match_operand 2 "const0_operand" "X"))]
739 UNSPEC_FNSTSW))]
740 "TARGET_80387
741 && FLOAT_MODE_P (GET_MODE (operands[1]))
742 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
743 {
744 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
745 return "ftst\;fnstsw\t%0\;fstp\t%y0";
746 else
747 return "ftst\;fnstsw\t%0";
748 }
749 [(set_attr "type" "multi")
750 (set_attr "mode" "unknownfp")])
751
752 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
753 ;; used to manage the reg stack popping would not be preserved.
754
755 (define_insn "*cmpfp_2_sf"
756 [(set (reg:CCFP 18)
757 (compare:CCFP
758 (match_operand:SF 0 "register_operand" "f")
759 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
760 "TARGET_80387"
761 "* return output_fp_compare (insn, operands, 0, 0);"
762 [(set_attr "type" "fcmp")
763 (set_attr "mode" "SF")])
764
765 (define_insn "*cmpfp_2_sf_1"
766 [(set (match_operand:HI 0 "register_operand" "=a")
767 (unspec:HI
768 [(compare:CCFP
769 (match_operand:SF 1 "register_operand" "f")
770 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
771 UNSPEC_FNSTSW))]
772 "TARGET_80387"
773 "* return output_fp_compare (insn, operands, 2, 0);"
774 [(set_attr "type" "fcmp")
775 (set_attr "mode" "SF")])
776
777 (define_insn "*cmpfp_2_df"
778 [(set (reg:CCFP 18)
779 (compare:CCFP
780 (match_operand:DF 0 "register_operand" "f")
781 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
782 "TARGET_80387"
783 "* return output_fp_compare (insn, operands, 0, 0);"
784 [(set_attr "type" "fcmp")
785 (set_attr "mode" "DF")])
786
787 (define_insn "*cmpfp_2_df_1"
788 [(set (match_operand:HI 0 "register_operand" "=a")
789 (unspec:HI
790 [(compare:CCFP
791 (match_operand:DF 1 "register_operand" "f")
792 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
793 UNSPEC_FNSTSW))]
794 "TARGET_80387"
795 "* return output_fp_compare (insn, operands, 2, 0);"
796 [(set_attr "type" "multi")
797 (set_attr "mode" "DF")])
798
799 (define_insn "*cmpfp_2_xf"
800 [(set (reg:CCFP 18)
801 (compare:CCFP
802 (match_operand:XF 0 "register_operand" "f")
803 (match_operand:XF 1 "register_operand" "f")))]
804 "!TARGET_64BIT && TARGET_80387"
805 "* return output_fp_compare (insn, operands, 0, 0);"
806 [(set_attr "type" "fcmp")
807 (set_attr "mode" "XF")])
808
809 (define_insn "*cmpfp_2_tf"
810 [(set (reg:CCFP 18)
811 (compare:CCFP
812 (match_operand:TF 0 "register_operand" "f")
813 (match_operand:TF 1 "register_operand" "f")))]
814 "TARGET_80387"
815 "* return output_fp_compare (insn, operands, 0, 0);"
816 [(set_attr "type" "fcmp")
817 (set_attr "mode" "XF")])
818
819 (define_insn "*cmpfp_2_xf_1"
820 [(set (match_operand:HI 0 "register_operand" "=a")
821 (unspec:HI
822 [(compare:CCFP
823 (match_operand:XF 1 "register_operand" "f")
824 (match_operand:XF 2 "register_operand" "f"))]
825 UNSPEC_FNSTSW))]
826 "!TARGET_64BIT && TARGET_80387"
827 "* return output_fp_compare (insn, operands, 2, 0);"
828 [(set_attr "type" "multi")
829 (set_attr "mode" "XF")])
830
831 (define_insn "*cmpfp_2_tf_1"
832 [(set (match_operand:HI 0 "register_operand" "=a")
833 (unspec:HI
834 [(compare:CCFP
835 (match_operand:TF 1 "register_operand" "f")
836 (match_operand:TF 2 "register_operand" "f"))]
837 UNSPEC_FNSTSW))]
838 "TARGET_80387"
839 "* return output_fp_compare (insn, operands, 2, 0);"
840 [(set_attr "type" "multi")
841 (set_attr "mode" "XF")])
842
843 (define_insn "*cmpfp_2u"
844 [(set (reg:CCFPU 18)
845 (compare:CCFPU
846 (match_operand 0 "register_operand" "f")
847 (match_operand 1 "register_operand" "f")))]
848 "TARGET_80387
849 && FLOAT_MODE_P (GET_MODE (operands[0]))
850 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
851 "* return output_fp_compare (insn, operands, 0, 1);"
852 [(set_attr "type" "fcmp")
853 (set_attr "mode" "unknownfp")])
854
855 (define_insn "*cmpfp_2u_1"
856 [(set (match_operand:HI 0 "register_operand" "=a")
857 (unspec:HI
858 [(compare:CCFPU
859 (match_operand 1 "register_operand" "f")
860 (match_operand 2 "register_operand" "f"))]
861 UNSPEC_FNSTSW))]
862 "TARGET_80387
863 && FLOAT_MODE_P (GET_MODE (operands[1]))
864 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
865 "* return output_fp_compare (insn, operands, 2, 1);"
866 [(set_attr "type" "multi")
867 (set_attr "mode" "unknownfp")])
868
869 ;; Patterns to match the SImode-in-memory ficom instructions.
870 ;;
871 ;; %%% Play games with accepting gp registers, as otherwise we have to
872 ;; force them to memory during rtl generation, which is no good. We
873 ;; can get rid of this once we teach reload to do memory input reloads
874 ;; via pushes.
875
876 (define_insn "*ficom_1"
877 [(set (reg:CCFP 18)
878 (compare:CCFP
879 (match_operand 0 "register_operand" "f,f")
880 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
881 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
882 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
883 "#")
884
885 ;; Split the not-really-implemented gp register case into a
886 ;; push-op-pop sequence.
887 ;;
888 ;; %%% This is most efficient, but am I gonna get in trouble
889 ;; for separating cc0_setter and cc0_user?
890
891 (define_split
892 [(set (reg:CCFP 18)
893 (compare:CCFP
894 (match_operand:SF 0 "register_operand" "")
895 (float (match_operand:SI 1 "register_operand" ""))))]
896 "0 && TARGET_80387 && reload_completed"
897 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
898 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
899 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
900 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
901 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
902 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
903
904 ;; FP compares, step 2
905 ;; Move the fpsw to ax.
906
907 (define_insn "x86_fnstsw_1"
908 [(set (match_operand:HI 0 "register_operand" "=a")
909 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
910 "TARGET_80387"
911 "fnstsw\t%0"
912 [(set_attr "length" "2")
913 (set_attr "mode" "SI")
914 (set_attr "unit" "i387")
915 (set_attr "ppro_uops" "few")])
916
917 ;; FP compares, step 3
918 ;; Get ax into flags, general case.
919
920 (define_insn "x86_sahf_1"
921 [(set (reg:CC 17)
922 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
923 "!TARGET_64BIT"
924 "sahf"
925 [(set_attr "length" "1")
926 (set_attr "athlon_decode" "vector")
927 (set_attr "mode" "SI")
928 (set_attr "ppro_uops" "one")])
929
930 ;; Pentium Pro can do steps 1 through 3 in one go.
931
932 (define_insn "*cmpfp_i"
933 [(set (reg:CCFP 17)
934 (compare:CCFP (match_operand 0 "register_operand" "f")
935 (match_operand 1 "register_operand" "f")))]
936 "TARGET_80387 && TARGET_CMOVE
937 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
938 && FLOAT_MODE_P (GET_MODE (operands[0]))
939 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
940 "* return output_fp_compare (insn, operands, 1, 0);"
941 [(set_attr "type" "fcmp")
942 (set_attr "mode" "unknownfp")
943 (set_attr "athlon_decode" "vector")])
944
945 (define_insn "*cmpfp_i_sse"
946 [(set (reg:CCFP 17)
947 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
948 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
949 "TARGET_80387
950 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
951 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
952 "* return output_fp_compare (insn, operands, 1, 0);"
953 [(set_attr "type" "fcmp,ssecmp")
954 (set_attr "mode" "unknownfp")
955 (set_attr "athlon_decode" "vector")])
956
957 (define_insn "*cmpfp_i_sse_only"
958 [(set (reg:CCFP 17)
959 (compare:CCFP (match_operand 0 "register_operand" "x")
960 (match_operand 1 "nonimmediate_operand" "xm")))]
961 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
962 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
963 "* return output_fp_compare (insn, operands, 1, 0);"
964 [(set_attr "type" "ssecmp")
965 (set_attr "mode" "unknownfp")
966 (set_attr "athlon_decode" "vector")])
967
968 (define_insn "*cmpfp_iu"
969 [(set (reg:CCFPU 17)
970 (compare:CCFPU (match_operand 0 "register_operand" "f")
971 (match_operand 1 "register_operand" "f")))]
972 "TARGET_80387 && TARGET_CMOVE
973 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974 && FLOAT_MODE_P (GET_MODE (operands[0]))
975 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976 "* return output_fp_compare (insn, operands, 1, 1);"
977 [(set_attr "type" "fcmp")
978 (set_attr "mode" "unknownfp")
979 (set_attr "athlon_decode" "vector")])
980
981 (define_insn "*cmpfp_iu_sse"
982 [(set (reg:CCFPU 17)
983 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
984 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
985 "TARGET_80387
986 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988 "* return output_fp_compare (insn, operands, 1, 1);"
989 [(set_attr "type" "fcmp,ssecmp")
990 (set_attr "mode" "unknownfp")
991 (set_attr "athlon_decode" "vector")])
992
993 (define_insn "*cmpfp_iu_sse_only"
994 [(set (reg:CCFPU 17)
995 (compare:CCFPU (match_operand 0 "register_operand" "x")
996 (match_operand 1 "nonimmediate_operand" "xm")))]
997 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
998 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
999 "* return output_fp_compare (insn, operands, 1, 1);"
1000 [(set_attr "type" "ssecmp")
1001 (set_attr "mode" "unknownfp")
1002 (set_attr "athlon_decode" "vector")])
1003 \f
1004 ;; Move instructions.
1005
1006 ;; General case of fullword move.
1007
1008 (define_expand "movsi"
1009 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1010 (match_operand:SI 1 "general_operand" ""))]
1011 ""
1012 "ix86_expand_move (SImode, operands); DONE;")
1013
1014 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1015 ;; general_operand.
1016 ;;
1017 ;; %%% We don't use a post-inc memory reference because x86 is not a
1018 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1019 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1020 ;; targets without our curiosities, and it is just as easy to represent
1021 ;; this differently.
1022
1023 (define_insn "*pushsi2"
1024 [(set (match_operand:SI 0 "push_operand" "=<")
1025 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1026 "!TARGET_64BIT"
1027 "push{l}\t%1"
1028 [(set_attr "type" "push")
1029 (set_attr "mode" "SI")])
1030
1031 ;; For 64BIT abi we always round up to 8 bytes.
1032 (define_insn "*pushsi2_rex64"
1033 [(set (match_operand:SI 0 "push_operand" "=X")
1034 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1035 "TARGET_64BIT"
1036 "push{q}\t%q1"
1037 [(set_attr "type" "push")
1038 (set_attr "mode" "SI")])
1039
1040 (define_insn "*pushsi2_prologue"
1041 [(set (match_operand:SI 0 "push_operand" "=<")
1042 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1043 (clobber (mem:BLK (scratch)))]
1044 "!TARGET_64BIT"
1045 "push{l}\t%1"
1046 [(set_attr "type" "push")
1047 (set_attr "mode" "SI")])
1048
1049 (define_insn "*popsi1_epilogue"
1050 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1051 (mem:SI (reg:SI 7)))
1052 (set (reg:SI 7)
1053 (plus:SI (reg:SI 7) (const_int 4)))
1054 (clobber (mem:BLK (scratch)))]
1055 "!TARGET_64BIT"
1056 "pop{l}\t%0"
1057 [(set_attr "type" "pop")
1058 (set_attr "mode" "SI")])
1059
1060 (define_insn "popsi1"
1061 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1062 (mem:SI (reg:SI 7)))
1063 (set (reg:SI 7)
1064 (plus:SI (reg:SI 7) (const_int 4)))]
1065 "!TARGET_64BIT"
1066 "pop{l}\t%0"
1067 [(set_attr "type" "pop")
1068 (set_attr "mode" "SI")])
1069
1070 (define_insn "*movsi_xor"
1071 [(set (match_operand:SI 0 "register_operand" "=r")
1072 (match_operand:SI 1 "const0_operand" "i"))
1073 (clobber (reg:CC 17))]
1074 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1075 "xor{l}\t{%0, %0|%0, %0}"
1076 [(set_attr "type" "alu1")
1077 (set_attr "mode" "SI")
1078 (set_attr "length_immediate" "0")])
1079
1080 (define_insn "*movsi_or"
1081 [(set (match_operand:SI 0 "register_operand" "=r")
1082 (match_operand:SI 1 "immediate_operand" "i"))
1083 (clobber (reg:CC 17))]
1084 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1085 && INTVAL (operands[1]) == -1
1086 && (TARGET_PENTIUM || optimize_size)"
1087 {
1088 operands[1] = constm1_rtx;
1089 return "or{l}\t{%1, %0|%0, %1}";
1090 }
1091 [(set_attr "type" "alu1")
1092 (set_attr "mode" "SI")
1093 (set_attr "length_immediate" "1")])
1094
1095 ; The first alternative is used only to compute proper length of instruction.
1096 ; Reload's algorithm does not take into account the cost of spill instructions
1097 ; needed to free register in given class, so avoid it from choosing the first
1098 ; alternative when eax is not available.
1099
1100 (define_insn "*movsi_1"
1101 [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1102 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
1103 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1104 {
1105 switch (get_attr_type (insn))
1106 {
1107 case TYPE_SSEMOV:
1108 if (get_attr_mode (insn) == TImode)
1109 return "movdqa\t{%1, %0|%0, %1}";
1110 return "movd\t{%1, %0|%0, %1}";
1111
1112 case TYPE_MMXMOV:
1113 if (get_attr_mode (insn) == DImode)
1114 return "movq\t{%1, %0|%0, %1}";
1115 return "movd\t{%1, %0|%0, %1}";
1116
1117 case TYPE_LEA:
1118 return "lea{l}\t{%1, %0|%0, %1}";
1119
1120 default:
1121 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1122 abort();
1123 return "mov{l}\t{%1, %0|%0, %1}";
1124 }
1125 }
1126 [(set (attr "type")
1127 (cond [(eq_attr "alternative" "4,5,6")
1128 (const_string "mmxmov")
1129 (eq_attr "alternative" "7,8,9")
1130 (const_string "ssemov")
1131 (and (ne (symbol_ref "flag_pic") (const_int 0))
1132 (match_operand:SI 1 "symbolic_operand" ""))
1133 (const_string "lea")
1134 ]
1135 (const_string "imov")))
1136 (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
1137 (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
1138
1139 ;; Stores and loads of ax to arbitary constant address.
1140 ;; We fake an second form of instruction to force reload to load address
1141 ;; into register when rax is not available
1142 (define_insn "*movabssi_1_rex64"
1143 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1144 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1145 "TARGET_64BIT"
1146 "@
1147 movabs{l}\t{%1, %P0|%P0, %1}
1148 mov{l}\t{%1, %a0|%a0, %1}
1149 movabs{l}\t{%1, %a0|%a0, %1}"
1150 [(set_attr "type" "imov")
1151 (set_attr "modrm" "0,*,*")
1152 (set_attr "length_address" "8,0,0")
1153 (set_attr "length_immediate" "0,*,*")
1154 (set_attr "memory" "store")
1155 (set_attr "mode" "SI")])
1156
1157 (define_insn "*movabssi_2_rex64"
1158 [(set (match_operand:SI 0 "register_operand" "=a,r")
1159 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1160 "TARGET_64BIT"
1161 "@
1162 movabs{l}\t{%P1, %0|%0, %P1}
1163 mov{l}\t{%a1, %0|%0, %a1}"
1164 [(set_attr "type" "imov")
1165 (set_attr "modrm" "0,*")
1166 (set_attr "length_address" "8,0")
1167 (set_attr "length_immediate" "0")
1168 (set_attr "memory" "load")
1169 (set_attr "mode" "SI")])
1170
1171 (define_insn "*swapsi"
1172 [(set (match_operand:SI 0 "register_operand" "+r")
1173 (match_operand:SI 1 "register_operand" "+r"))
1174 (set (match_dup 1)
1175 (match_dup 0))]
1176 ""
1177 "xchg{l}\t%1, %0"
1178 [(set_attr "type" "imov")
1179 (set_attr "pent_pair" "np")
1180 (set_attr "athlon_decode" "vector")
1181 (set_attr "mode" "SI")
1182 (set_attr "modrm" "0")
1183 (set_attr "ppro_uops" "few")])
1184
1185 (define_expand "movhi"
1186 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1187 (match_operand:HI 1 "general_operand" ""))]
1188 ""
1189 "ix86_expand_move (HImode, operands); DONE;")
1190
1191 (define_insn "*pushhi2"
1192 [(set (match_operand:HI 0 "push_operand" "=<,<")
1193 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1194 "!TARGET_64BIT"
1195 "@
1196 push{w}\t{|WORD PTR }%1
1197 push{w}\t%1"
1198 [(set_attr "type" "push")
1199 (set_attr "mode" "HI")])
1200
1201 ;; For 64BIT abi we always round up to 8 bytes.
1202 (define_insn "*pushhi2_rex64"
1203 [(set (match_operand:HI 0 "push_operand" "=X")
1204 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1205 "TARGET_64BIT"
1206 "push{q}\t%q1"
1207 [(set_attr "type" "push")
1208 (set_attr "mode" "QI")])
1209
1210 ; The first alternative is used only to compute proper length of instruction.
1211 ; Reload's algorithm does not take into account the cost of spill instructions
1212 ; needed to free register in given class, so avoid it from choosing the first
1213 ; alternative when eax is not available.
1214
1215 (define_insn "*movhi_1"
1216 [(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
1217 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1218 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1219 {
1220 switch (get_attr_type (insn))
1221 {
1222 case TYPE_IMOVX:
1223 /* movzwl is faster than movw on p2 due to partial word stalls,
1224 though not as fast as an aligned movl. */
1225 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1226 default:
1227 if (get_attr_mode (insn) == MODE_SI)
1228 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1229 else
1230 return "mov{w}\t{%1, %0|%0, %1}";
1231 }
1232 }
1233 [(set (attr "type")
1234 (cond [(and (eq_attr "alternative" "0,1")
1235 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1236 (const_int 0))
1237 (eq (symbol_ref "TARGET_HIMODE_MATH")
1238 (const_int 0))))
1239 (const_string "imov")
1240 (and (eq_attr "alternative" "2,3,4")
1241 (match_operand:HI 1 "aligned_operand" ""))
1242 (const_string "imov")
1243 (and (ne (symbol_ref "TARGET_MOVX")
1244 (const_int 0))
1245 (eq_attr "alternative" "0,1,3,4"))
1246 (const_string "imovx")
1247 ]
1248 (const_string "imov")))
1249 (set (attr "mode")
1250 (cond [(eq_attr "type" "imovx")
1251 (const_string "SI")
1252 (and (eq_attr "alternative" "2,3,4")
1253 (match_operand:HI 1 "aligned_operand" ""))
1254 (const_string "SI")
1255 (and (eq_attr "alternative" "0,1")
1256 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1257 (const_int 0))
1258 (eq (symbol_ref "TARGET_HIMODE_MATH")
1259 (const_int 0))))
1260 (const_string "SI")
1261 ]
1262 (const_string "HI")))
1263 (set_attr "modrm" "0,*,*,0,*,*")])
1264
1265 ;; Stores and loads of ax to arbitary constant address.
1266 ;; We fake an second form of instruction to force reload to load address
1267 ;; into register when rax is not available
1268 (define_insn "*movabshi_1_rex64"
1269 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1270 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1271 "TARGET_64BIT"
1272 "@
1273 movabs{w}\t{%1, %P0|%P0, %1}
1274 mov{w}\t{%1, %a0|%a0, %1}
1275 movabs{w}\t{%1, %a0|%a0, %1}"
1276 [(set_attr "type" "imov")
1277 (set_attr "modrm" "0,*,*")
1278 (set_attr "length_address" "8,0,0")
1279 (set_attr "length_immediate" "0,*,*")
1280 (set_attr "memory" "store")
1281 (set_attr "mode" "HI")])
1282
1283 (define_insn "*movabshi_2_rex64"
1284 [(set (match_operand:HI 0 "register_operand" "=a,r")
1285 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1286 "TARGET_64BIT"
1287 "@
1288 movabs{w}\t{%P1, %0|%0, %P1}
1289 mov{w}\t{%a1, %0|%0, %a1}"
1290 [(set_attr "type" "imov")
1291 (set_attr "modrm" "0,*")
1292 (set_attr "length_address" "8,0")
1293 (set_attr "length_immediate" "0")
1294 (set_attr "memory" "load")
1295 (set_attr "mode" "HI")])
1296
1297 (define_insn "*swaphi_1"
1298 [(set (match_operand:HI 0 "register_operand" "+r")
1299 (match_operand:HI 1 "register_operand" "+r"))
1300 (set (match_dup 1)
1301 (match_dup 0))]
1302 "TARGET_PARTIAL_REG_STALL"
1303 "xchg{w}\t%1, %0"
1304 [(set_attr "type" "imov")
1305 (set_attr "pent_pair" "np")
1306 (set_attr "mode" "HI")
1307 (set_attr "modrm" "0")
1308 (set_attr "ppro_uops" "few")])
1309
1310 (define_insn "*swaphi_2"
1311 [(set (match_operand:HI 0 "register_operand" "+r")
1312 (match_operand:HI 1 "register_operand" "+r"))
1313 (set (match_dup 1)
1314 (match_dup 0))]
1315 "! TARGET_PARTIAL_REG_STALL"
1316 "xchg{l}\t%k1, %k0"
1317 [(set_attr "type" "imov")
1318 (set_attr "pent_pair" "np")
1319 (set_attr "mode" "SI")
1320 (set_attr "modrm" "0")
1321 (set_attr "ppro_uops" "few")])
1322
1323 (define_expand "movstricthi"
1324 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1325 (match_operand:HI 1 "general_operand" ""))]
1326 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1327 {
1328 /* Don't generate memory->memory moves, go through a register */
1329 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1330 operands[1] = force_reg (HImode, operands[1]);
1331 })
1332
1333 (define_insn "*movstricthi_1"
1334 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1335 (match_operand:HI 1 "general_operand" "rn,m"))]
1336 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1337 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1338 "mov{w}\t{%1, %0|%0, %1}"
1339 [(set_attr "type" "imov")
1340 (set_attr "mode" "HI")])
1341
1342 (define_insn "*movstricthi_xor"
1343 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1344 (match_operand:HI 1 "const0_operand" "i"))
1345 (clobber (reg:CC 17))]
1346 "reload_completed
1347 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1348 "xor{w}\t{%0, %0|%0, %0}"
1349 [(set_attr "type" "alu1")
1350 (set_attr "mode" "HI")
1351 (set_attr "length_immediate" "0")])
1352
1353 (define_expand "movqi"
1354 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1355 (match_operand:QI 1 "general_operand" ""))]
1356 ""
1357 "ix86_expand_move (QImode, operands); DONE;")
1358
1359 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1360 ;; "push a byte". But actually we use pushw, which has the effect
1361 ;; of rounding the amount pushed up to a halfword.
1362
1363 (define_insn "*pushqi2"
1364 [(set (match_operand:QI 0 "push_operand" "=X,X")
1365 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1366 "!TARGET_64BIT"
1367 "@
1368 push{w}\t{|word ptr }%1
1369 push{w}\t%w1"
1370 [(set_attr "type" "push")
1371 (set_attr "mode" "HI")])
1372
1373 ;; For 64BIT abi we always round up to 8 bytes.
1374 (define_insn "*pushqi2_rex64"
1375 [(set (match_operand:QI 0 "push_operand" "=X")
1376 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1377 "TARGET_64BIT"
1378 "push{q}\t%q1"
1379 [(set_attr "type" "push")
1380 (set_attr "mode" "QI")])
1381
1382 ;; Situation is quite tricky about when to choose full sized (SImode) move
1383 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1384 ;; partial register dependency machines (such as AMD Athlon), where QImode
1385 ;; moves issue extra dependency and for partial register stalls machines
1386 ;; that don't use QImode patterns (and QImode move cause stall on the next
1387 ;; instruction).
1388 ;;
1389 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1390 ;; register stall machines with, where we use QImode instructions, since
1391 ;; partial register stall can be caused there. Then we use movzx.
1392 (define_insn "*movqi_1"
1393 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1394 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1395 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1396 {
1397 switch (get_attr_type (insn))
1398 {
1399 case TYPE_IMOVX:
1400 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1401 abort ();
1402 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1403 default:
1404 if (get_attr_mode (insn) == MODE_SI)
1405 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1406 else
1407 return "mov{b}\t{%1, %0|%0, %1}";
1408 }
1409 }
1410 [(set (attr "type")
1411 (cond [(and (eq_attr "alternative" "3")
1412 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1413 (const_int 0))
1414 (eq (symbol_ref "TARGET_QIMODE_MATH")
1415 (const_int 0))))
1416 (const_string "imov")
1417 (eq_attr "alternative" "3,5")
1418 (const_string "imovx")
1419 (and (ne (symbol_ref "TARGET_MOVX")
1420 (const_int 0))
1421 (eq_attr "alternative" "2"))
1422 (const_string "imovx")
1423 ]
1424 (const_string "imov")))
1425 (set (attr "mode")
1426 (cond [(eq_attr "alternative" "3,4,5")
1427 (const_string "SI")
1428 (eq_attr "alternative" "6")
1429 (const_string "QI")
1430 (eq_attr "type" "imovx")
1431 (const_string "SI")
1432 (and (eq_attr "type" "imov")
1433 (and (eq_attr "alternative" "0,1,2")
1434 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1435 (const_int 0))))
1436 (const_string "SI")
1437 ;; Avoid partial register stalls when not using QImode arithmetic
1438 (and (eq_attr "type" "imov")
1439 (and (eq_attr "alternative" "0,1,2")
1440 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1441 (const_int 0))
1442 (eq (symbol_ref "TARGET_QIMODE_MATH")
1443 (const_int 0)))))
1444 (const_string "SI")
1445 ]
1446 (const_string "QI")))])
1447
1448 (define_expand "reload_outqi"
1449 [(parallel [(match_operand:QI 0 "" "=m")
1450 (match_operand:QI 1 "register_operand" "r")
1451 (match_operand:QI 2 "register_operand" "=&q")])]
1452 ""
1453 {
1454 rtx op0, op1, op2;
1455 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1456
1457 if (reg_overlap_mentioned_p (op2, op0))
1458 abort ();
1459 if (! q_regs_operand (op1, QImode))
1460 {
1461 emit_insn (gen_movqi (op2, op1));
1462 op1 = op2;
1463 }
1464 emit_insn (gen_movqi (op0, op1));
1465 DONE;
1466 })
1467
1468 (define_insn "*swapqi"
1469 [(set (match_operand:QI 0 "register_operand" "+r")
1470 (match_operand:QI 1 "register_operand" "+r"))
1471 (set (match_dup 1)
1472 (match_dup 0))]
1473 ""
1474 "xchg{b}\t%1, %0"
1475 [(set_attr "type" "imov")
1476 (set_attr "pent_pair" "np")
1477 (set_attr "mode" "QI")
1478 (set_attr "modrm" "0")
1479 (set_attr "ppro_uops" "few")])
1480
1481 (define_expand "movstrictqi"
1482 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1483 (match_operand:QI 1 "general_operand" ""))]
1484 "! TARGET_PARTIAL_REG_STALL"
1485 {
1486 /* Don't generate memory->memory moves, go through a register. */
1487 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1488 operands[1] = force_reg (QImode, operands[1]);
1489 })
1490
1491 (define_insn "*movstrictqi_1"
1492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1493 (match_operand:QI 1 "general_operand" "*qn,m"))]
1494 "! TARGET_PARTIAL_REG_STALL
1495 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1496 "mov{b}\t{%1, %0|%0, %1}"
1497 [(set_attr "type" "imov")
1498 (set_attr "mode" "QI")])
1499
1500 (define_insn "*movstrictqi_xor"
1501 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1502 (match_operand:QI 1 "const0_operand" "i"))
1503 (clobber (reg:CC 17))]
1504 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1505 "xor{b}\t{%0, %0|%0, %0}"
1506 [(set_attr "type" "alu1")
1507 (set_attr "mode" "QI")
1508 (set_attr "length_immediate" "0")])
1509
1510 (define_insn "*movsi_extv_1"
1511 [(set (match_operand:SI 0 "register_operand" "=R")
1512 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1513 (const_int 8)
1514 (const_int 8)))]
1515 ""
1516 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1517 [(set_attr "type" "imovx")
1518 (set_attr "mode" "SI")])
1519
1520 (define_insn "*movhi_extv_1"
1521 [(set (match_operand:HI 0 "register_operand" "=R")
1522 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1523 (const_int 8)
1524 (const_int 8)))]
1525 ""
1526 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1527 [(set_attr "type" "imovx")
1528 (set_attr "mode" "SI")])
1529
1530 (define_insn "*movqi_extv_1"
1531 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1532 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1533 (const_int 8)
1534 (const_int 8)))]
1535 "!TARGET_64BIT"
1536 {
1537 switch (get_attr_type (insn))
1538 {
1539 case TYPE_IMOVX:
1540 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1541 default:
1542 return "mov{b}\t{%h1, %0|%0, %h1}";
1543 }
1544 }
1545 [(set (attr "type")
1546 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1547 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1548 (ne (symbol_ref "TARGET_MOVX")
1549 (const_int 0))))
1550 (const_string "imovx")
1551 (const_string "imov")))
1552 (set (attr "mode")
1553 (if_then_else (eq_attr "type" "imovx")
1554 (const_string "SI")
1555 (const_string "QI")))])
1556
1557 (define_insn "*movqi_extv_1_rex64"
1558 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1559 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1560 (const_int 8)
1561 (const_int 8)))]
1562 "TARGET_64BIT"
1563 {
1564 switch (get_attr_type (insn))
1565 {
1566 case TYPE_IMOVX:
1567 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1568 default:
1569 return "mov{b}\t{%h1, %0|%0, %h1}";
1570 }
1571 }
1572 [(set (attr "type")
1573 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1574 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1575 (ne (symbol_ref "TARGET_MOVX")
1576 (const_int 0))))
1577 (const_string "imovx")
1578 (const_string "imov")))
1579 (set (attr "mode")
1580 (if_then_else (eq_attr "type" "imovx")
1581 (const_string "SI")
1582 (const_string "QI")))])
1583
1584 ;; Stores and loads of ax to arbitary constant address.
1585 ;; We fake an second form of instruction to force reload to load address
1586 ;; into register when rax is not available
1587 (define_insn "*movabsqi_1_rex64"
1588 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1589 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1590 "TARGET_64BIT"
1591 "@
1592 movabs{b}\t{%1, %P0|%P0, %1}
1593 mov{b}\t{%1, %a0|%a0, %1}
1594 movabs{b}\t{%1, %a0|%a0, %1}"
1595 [(set_attr "type" "imov")
1596 (set_attr "modrm" "0,*,*")
1597 (set_attr "length_address" "8,0,0")
1598 (set_attr "length_immediate" "0,*,*")
1599 (set_attr "memory" "store")
1600 (set_attr "mode" "QI")])
1601
1602 (define_insn "*movabsqi_2_rex64"
1603 [(set (match_operand:QI 0 "register_operand" "=a,r")
1604 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1605 "TARGET_64BIT"
1606 "@
1607 movabs{b}\t{%P1, %0|%0, %P1}
1608 mov{b}\t{%a1, %0|%0, %a1}"
1609 [(set_attr "type" "imov")
1610 (set_attr "modrm" "0,*")
1611 (set_attr "length_address" "8,0")
1612 (set_attr "length_immediate" "0")
1613 (set_attr "memory" "load")
1614 (set_attr "mode" "QI")])
1615
1616 (define_insn "*movsi_extzv_1"
1617 [(set (match_operand:SI 0 "register_operand" "=R")
1618 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1619 (const_int 8)
1620 (const_int 8)))]
1621 ""
1622 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1623 [(set_attr "type" "imovx")
1624 (set_attr "mode" "SI")])
1625
1626 (define_insn "*movqi_extzv_2"
1627 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1628 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1629 (const_int 8)
1630 (const_int 8)) 0))]
1631 "!TARGET_64BIT"
1632 {
1633 switch (get_attr_type (insn))
1634 {
1635 case TYPE_IMOVX:
1636 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1637 default:
1638 return "mov{b}\t{%h1, %0|%0, %h1}";
1639 }
1640 }
1641 [(set (attr "type")
1642 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1643 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1644 (ne (symbol_ref "TARGET_MOVX")
1645 (const_int 0))))
1646 (const_string "imovx")
1647 (const_string "imov")))
1648 (set (attr "mode")
1649 (if_then_else (eq_attr "type" "imovx")
1650 (const_string "SI")
1651 (const_string "QI")))])
1652
1653 (define_insn "*movqi_extzv_2_rex64"
1654 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1655 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1656 (const_int 8)
1657 (const_int 8)) 0))]
1658 "TARGET_64BIT"
1659 {
1660 switch (get_attr_type (insn))
1661 {
1662 case TYPE_IMOVX:
1663 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1664 default:
1665 return "mov{b}\t{%h1, %0|%0, %h1}";
1666 }
1667 }
1668 [(set (attr "type")
1669 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670 (ne (symbol_ref "TARGET_MOVX")
1671 (const_int 0)))
1672 (const_string "imovx")
1673 (const_string "imov")))
1674 (set (attr "mode")
1675 (if_then_else (eq_attr "type" "imovx")
1676 (const_string "SI")
1677 (const_string "QI")))])
1678
1679 (define_insn "movsi_insv_1"
1680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1681 (const_int 8)
1682 (const_int 8))
1683 (match_operand:SI 1 "general_operand" "Qmn"))]
1684 "!TARGET_64BIT"
1685 "mov{b}\t{%b1, %h0|%h0, %b1}"
1686 [(set_attr "type" "imov")
1687 (set_attr "mode" "QI")])
1688
1689 (define_insn "*movsi_insv_1_rex64"
1690 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1691 (const_int 8)
1692 (const_int 8))
1693 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1694 "TARGET_64BIT"
1695 "mov{b}\t{%b1, %h0|%h0, %b1}"
1696 [(set_attr "type" "imov")
1697 (set_attr "mode" "QI")])
1698
1699 (define_insn "*movqi_insv_2"
1700 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1701 (const_int 8)
1702 (const_int 8))
1703 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1704 (const_int 8))
1705 (const_int 255)))]
1706 ""
1707 "mov{b}\t{%h1, %h0|%h0, %h1}"
1708 [(set_attr "type" "imov")
1709 (set_attr "mode" "QI")])
1710
1711 (define_expand "movdi"
1712 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1713 (match_operand:DI 1 "general_operand" ""))]
1714 ""
1715 "ix86_expand_move (DImode, operands); DONE;")
1716
1717 (define_insn "*pushdi"
1718 [(set (match_operand:DI 0 "push_operand" "=<")
1719 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1720 "!TARGET_64BIT"
1721 "#")
1722
1723 (define_insn "pushdi2_rex64"
1724 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1725 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1726 "TARGET_64BIT"
1727 "@
1728 push{q}\t%1
1729 #"
1730 [(set_attr "type" "push,multi")
1731 (set_attr "mode" "DI")])
1732
1733 ;; Convert impossible pushes of immediate to existing instructions.
1734 ;; First try to get scratch register and go through it. In case this
1735 ;; fails, push sign extended lower part first and then overwrite
1736 ;; upper part by 32bit move.
1737 (define_peephole2
1738 [(match_scratch:DI 2 "r")
1739 (set (match_operand:DI 0 "push_operand" "")
1740 (match_operand:DI 1 "immediate_operand" ""))]
1741 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1742 && !x86_64_immediate_operand (operands[1], DImode)"
1743 [(set (match_dup 2) (match_dup 1))
1744 (set (match_dup 0) (match_dup 2))]
1745 "")
1746
1747 ;; We need to define this as both peepholer and splitter for case
1748 ;; peephole2 pass is not run.
1749 (define_peephole2
1750 [(set (match_operand:DI 0 "push_operand" "")
1751 (match_operand:DI 1 "immediate_operand" ""))]
1752 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1753 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1754 [(set (match_dup 0) (match_dup 1))
1755 (set (match_dup 2) (match_dup 3))]
1756 "split_di (operands + 1, 1, operands + 2, operands + 3);
1757 operands[1] = gen_lowpart (DImode, operands[2]);
1758 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1759 GEN_INT (4)));
1760 ")
1761
1762 (define_split
1763 [(set (match_operand:DI 0 "push_operand" "")
1764 (match_operand:DI 1 "immediate_operand" ""))]
1765 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1766 && !symbolic_operand (operands[1], DImode)
1767 && !x86_64_immediate_operand (operands[1], DImode)"
1768 [(set (match_dup 0) (match_dup 1))
1769 (set (match_dup 2) (match_dup 3))]
1770 "split_di (operands + 1, 1, operands + 2, operands + 3);
1771 operands[1] = gen_lowpart (DImode, operands[2]);
1772 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1773 GEN_INT (4)));
1774 ")
1775
1776 (define_insn "*pushdi2_prologue_rex64"
1777 [(set (match_operand:DI 0 "push_operand" "=<")
1778 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1779 (clobber (mem:BLK (scratch)))]
1780 "TARGET_64BIT"
1781 "push{q}\t%1"
1782 [(set_attr "type" "push")
1783 (set_attr "mode" "DI")])
1784
1785 (define_insn "*popdi1_epilogue_rex64"
1786 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1787 (mem:DI (reg:DI 7)))
1788 (set (reg:DI 7)
1789 (plus:DI (reg:DI 7) (const_int 8)))
1790 (clobber (mem:BLK (scratch)))]
1791 "TARGET_64BIT"
1792 "pop{q}\t%0"
1793 [(set_attr "type" "pop")
1794 (set_attr "mode" "DI")])
1795
1796 (define_insn "popdi1"
1797 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1798 (mem:DI (reg:DI 7)))
1799 (set (reg:DI 7)
1800 (plus:DI (reg:DI 7) (const_int 8)))]
1801 "TARGET_64BIT"
1802 "pop{q}\t%0"
1803 [(set_attr "type" "pop")
1804 (set_attr "mode" "DI")])
1805
1806 (define_insn "*movdi_xor_rex64"
1807 [(set (match_operand:DI 0 "register_operand" "=r")
1808 (match_operand:DI 1 "const0_operand" "i"))
1809 (clobber (reg:CC 17))]
1810 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1811 && reload_completed"
1812 "xor{l}\t{%k0, %k0|%k0, %k0}"
1813 [(set_attr "type" "alu1")
1814 (set_attr "mode" "SI")
1815 (set_attr "length_immediate" "0")])
1816
1817 (define_insn "*movdi_or_rex64"
1818 [(set (match_operand:DI 0 "register_operand" "=r")
1819 (match_operand:DI 1 "const_int_operand" "i"))
1820 (clobber (reg:CC 17))]
1821 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1822 && reload_completed
1823 && GET_CODE (operands[1]) == CONST_INT
1824 && INTVAL (operands[1]) == -1"
1825 {
1826 operands[1] = constm1_rtx;
1827 return "or{q}\t{%1, %0|%0, %1}";
1828 }
1829 [(set_attr "type" "alu1")
1830 (set_attr "mode" "DI")
1831 (set_attr "length_immediate" "1")])
1832
1833 (define_insn "*movdi_2"
1834 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1835 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1836 "!TARGET_64BIT
1837 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1838 "@
1839 #
1840 #
1841 movq\t{%1, %0|%0, %1}
1842 movq\t{%1, %0|%0, %1}
1843 movq\t{%1, %0|%0, %1}
1844 movdqa\t{%1, %0|%0, %1}
1845 movq\t{%1, %0|%0, %1}"
1846 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1847 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1848
1849 (define_split
1850 [(set (match_operand:DI 0 "push_operand" "")
1851 (match_operand:DI 1 "general_operand" ""))]
1852 "!TARGET_64BIT && reload_completed
1853 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1854 [(const_int 0)]
1855 "ix86_split_long_move (operands); DONE;")
1856
1857 ;; %%% This multiword shite has got to go.
1858 (define_split
1859 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1860 (match_operand:DI 1 "general_operand" ""))]
1861 "!TARGET_64BIT && reload_completed
1862 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1863 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1864 [(const_int 0)]
1865 "ix86_split_long_move (operands); DONE;")
1866
1867 (define_insn "*movdi_1_rex64"
1868 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
1869 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
1870 "TARGET_64BIT
1871 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1872 {
1873 switch (get_attr_type (insn))
1874 {
1875 case TYPE_SSEMOV:
1876 if (register_operand (operands[0], DImode)
1877 && register_operand (operands[1], DImode))
1878 return "movdqa\t{%1, %0|%0, %1}";
1879 /* FALLTHRU */
1880 case TYPE_MMXMOV:
1881 return "movq\t{%1, %0|%0, %1}";
1882 case TYPE_MULTI:
1883 return "#";
1884 case TYPE_LEA:
1885 return "lea{q}\t{%a1, %0|%0, %a1}";
1886 default:
1887 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1888 abort ();
1889 if (get_attr_mode (insn) == MODE_SI)
1890 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1891 else if (which_alternative == 2)
1892 return "movabs{q}\t{%1, %0|%0, %1}";
1893 else
1894 return "mov{q}\t{%1, %0|%0, %1}";
1895 }
1896 }
1897 [(set (attr "type")
1898 (cond [(eq_attr "alternative" "5,6")
1899 (const_string "mmxmov")
1900 (eq_attr "alternative" "7,8")
1901 (const_string "ssemov")
1902 (eq_attr "alternative" "4")
1903 (const_string "multi")
1904 (and (ne (symbol_ref "flag_pic") (const_int 0))
1905 (match_operand:DI 1 "symbolic_operand" ""))
1906 (const_string "lea")
1907 ]
1908 (const_string "imov")))
1909 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
1910 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
1911 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
1912
1913 ;; Stores and loads of ax to arbitary constant address.
1914 ;; We fake an second form of instruction to force reload to load address
1915 ;; into register when rax is not available
1916 (define_insn "*movabsdi_1_rex64"
1917 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1918 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
1919 "TARGET_64BIT"
1920 "@
1921 movabs{q}\t{%1, %P0|%P0, %1}
1922 mov{q}\t{%1, %a0|%a0, %1}
1923 movabs{q}\t{%1, %a0|%a0, %1}"
1924 [(set_attr "type" "imov")
1925 (set_attr "modrm" "0,*,*")
1926 (set_attr "length_address" "8,0,0")
1927 (set_attr "length_immediate" "0,*,*")
1928 (set_attr "memory" "store")
1929 (set_attr "mode" "DI")])
1930
1931 (define_insn "*movabsdi_2_rex64"
1932 [(set (match_operand:DI 0 "register_operand" "=a,r")
1933 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1934 "TARGET_64BIT"
1935 "@
1936 movabs{q}\t{%P1, %0|%0, %P1}
1937 mov{q}\t{%a1, %0|%0, %a1}"
1938 [(set_attr "type" "imov")
1939 (set_attr "modrm" "0,*")
1940 (set_attr "length_address" "8,0")
1941 (set_attr "length_immediate" "0")
1942 (set_attr "memory" "load")
1943 (set_attr "mode" "DI")])
1944
1945 ;; Convert impossible stores of immediate to existing instructions.
1946 ;; First try to get scratch register and go through it. In case this
1947 ;; fails, move by 32bit parts.
1948 (define_peephole2
1949 [(match_scratch:DI 2 "r")
1950 (set (match_operand:DI 0 "memory_operand" "")
1951 (match_operand:DI 1 "immediate_operand" ""))]
1952 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1953 && !x86_64_immediate_operand (operands[1], DImode)"
1954 [(set (match_dup 2) (match_dup 1))
1955 (set (match_dup 0) (match_dup 2))]
1956 "")
1957
1958 ;; We need to define this as both peepholer and splitter for case
1959 ;; peephole2 pass is not run.
1960 (define_peephole2
1961 [(set (match_operand:DI 0 "memory_operand" "")
1962 (match_operand:DI 1 "immediate_operand" ""))]
1963 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1964 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1965 [(set (match_dup 2) (match_dup 3))
1966 (set (match_dup 4) (match_dup 5))]
1967 "split_di (operands, 2, operands + 2, operands + 4);")
1968
1969 (define_split
1970 [(set (match_operand:DI 0 "memory_operand" "")
1971 (match_operand:DI 1 "immediate_operand" ""))]
1972 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1973 && !symbolic_operand (operands[1], DImode)
1974 && !x86_64_immediate_operand (operands[1], DImode)"
1975 [(set (match_dup 2) (match_dup 3))
1976 (set (match_dup 4) (match_dup 5))]
1977 "split_di (operands, 2, operands + 2, operands + 4);")
1978
1979 (define_insn "*swapdi_rex64"
1980 [(set (match_operand:DI 0 "register_operand" "+r")
1981 (match_operand:DI 1 "register_operand" "+r"))
1982 (set (match_dup 1)
1983 (match_dup 0))]
1984 "TARGET_64BIT"
1985 "xchg{q}\t%1, %0"
1986 [(set_attr "type" "imov")
1987 (set_attr "pent_pair" "np")
1988 (set_attr "athlon_decode" "vector")
1989 (set_attr "mode" "DI")
1990 (set_attr "modrm" "0")
1991 (set_attr "ppro_uops" "few")])
1992
1993
1994 (define_expand "movsf"
1995 [(set (match_operand:SF 0 "nonimmediate_operand" "")
1996 (match_operand:SF 1 "general_operand" ""))]
1997 ""
1998 "ix86_expand_move (SFmode, operands); DONE;")
1999
2000 (define_insn "*pushsf"
2001 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2002 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2003 "!TARGET_64BIT"
2004 {
2005 switch (which_alternative)
2006 {
2007 case 0:
2008 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2009 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2010 operands[2] = stack_pointer_rtx;
2011 operands[3] = GEN_INT (4);
2012 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2013 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2014 else
2015 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2016
2017 case 1:
2018 return "push{l}\t%1";
2019 case 2:
2020 return "#";
2021
2022 default:
2023 abort ();
2024 }
2025 }
2026 [(set_attr "type" "multi,push,multi")
2027 (set_attr "mode" "SF,SI,SF")])
2028
2029 (define_insn "*pushsf_rex64"
2030 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2031 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2032 "TARGET_64BIT"
2033 {
2034 switch (which_alternative)
2035 {
2036 case 0:
2037 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2038 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2039 operands[2] = stack_pointer_rtx;
2040 operands[3] = GEN_INT (8);
2041 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2042 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2043 else
2044 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2045
2046 case 1:
2047 return "push{q}\t%q1";
2048
2049 case 2:
2050 return "#";
2051
2052 default:
2053 abort ();
2054 }
2055 }
2056 [(set_attr "type" "multi,push,multi")
2057 (set_attr "mode" "SF,DI,SF")])
2058
2059 (define_split
2060 [(set (match_operand:SF 0 "push_operand" "")
2061 (match_operand:SF 1 "memory_operand" ""))]
2062 "reload_completed
2063 && GET_CODE (operands[1]) == MEM
2064 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2065 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2066 [(set (match_dup 0)
2067 (match_dup 1))]
2068 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2069
2070
2071 ;; %%% Kill this when call knows how to work this out.
2072 (define_split
2073 [(set (match_operand:SF 0 "push_operand" "")
2074 (match_operand:SF 1 "register_operand" ""))]
2075 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2076 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2077 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2078
2079 (define_split
2080 [(set (match_operand:SF 0 "push_operand" "")
2081 (match_operand:SF 1 "register_operand" ""))]
2082 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2083 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2084 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2085
2086 (define_insn "*movsf_1"
2087 [(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")
2088 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
2089 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2090 && (reload_in_progress || reload_completed
2091 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2092 || GET_CODE (operands[1]) != CONST_DOUBLE
2093 || memory_operand (operands[0], SFmode))"
2094 {
2095 switch (which_alternative)
2096 {
2097 case 0:
2098 if (REG_P (operands[1])
2099 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2100 return "fstp\t%y0";
2101 else if (STACK_TOP_P (operands[0]))
2102 return "fld%z1\t%y1";
2103 else
2104 return "fst\t%y0";
2105
2106 case 1:
2107 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2108 return "fstp%z0\t%y0";
2109 else
2110 return "fst%z0\t%y0";
2111
2112 case 2:
2113 switch (standard_80387_constant_p (operands[1]))
2114 {
2115 case 1:
2116 return "fldz";
2117 case 2:
2118 return "fld1";
2119 }
2120 abort();
2121
2122 case 3:
2123 case 4:
2124 return "mov{l}\t{%1, %0|%0, %1}";
2125 case 5:
2126 if (TARGET_SSE2)
2127 return "pxor\t%0, %0";
2128 else
2129 return "xorps\t%0, %0";
2130 case 6:
2131 if (TARGET_PARTIAL_REG_DEPENDENCY)
2132 return "movaps\t{%1, %0|%0, %1}";
2133 else
2134 return "movss\t{%1, %0|%0, %1}";
2135 case 7:
2136 case 8:
2137 return "movss\t{%1, %0|%0, %1}";
2138
2139 case 9:
2140 case 10:
2141 return "movd\t{%1, %0|%0, %1}";
2142
2143 case 11:
2144 return "movq\t{%1, %0|%0, %1}";
2145
2146 default:
2147 abort();
2148 }
2149 }
2150 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2151 (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
2152
2153 (define_insn "*swapsf"
2154 [(set (match_operand:SF 0 "register_operand" "+f")
2155 (match_operand:SF 1 "register_operand" "+f"))
2156 (set (match_dup 1)
2157 (match_dup 0))]
2158 "reload_completed || !TARGET_SSE"
2159 {
2160 if (STACK_TOP_P (operands[0]))
2161 return "fxch\t%1";
2162 else
2163 return "fxch\t%0";
2164 }
2165 [(set_attr "type" "fxch")
2166 (set_attr "mode" "SF")])
2167
2168 (define_expand "movdf"
2169 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2170 (match_operand:DF 1 "general_operand" ""))]
2171 ""
2172 "ix86_expand_move (DFmode, operands); DONE;")
2173
2174 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2175 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2176 ;; On the average, pushdf using integers can be still shorter. Allow this
2177 ;; pattern for optimize_size too.
2178
2179 (define_insn "*pushdf_nointeger"
2180 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2181 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2182 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2183 {
2184 switch (which_alternative)
2185 {
2186 case 0:
2187 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2188 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2189 operands[2] = stack_pointer_rtx;
2190 operands[3] = GEN_INT (8);
2191 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2192 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2193 else
2194 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2195
2196 case 1:
2197 case 2:
2198 case 3:
2199 return "#";
2200
2201 default:
2202 abort ();
2203 }
2204 }
2205 [(set_attr "type" "multi")
2206 (set_attr "mode" "DF,SI,SI,DF")])
2207
2208 (define_insn "*pushdf_integer"
2209 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2210 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2211 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2212 {
2213 switch (which_alternative)
2214 {
2215 case 0:
2216 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2217 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2218 operands[2] = stack_pointer_rtx;
2219 operands[3] = GEN_INT (8);
2220 if (TARGET_64BIT)
2221 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2222 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2223 else
2224 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2225 else
2226 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2227 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2228 else
2229 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2230
2231
2232 case 1:
2233 case 2:
2234 return "#";
2235
2236 default:
2237 abort ();
2238 }
2239 }
2240 [(set_attr "type" "multi")
2241 (set_attr "mode" "DF,SI,DF")])
2242
2243 ;; %%% Kill this when call knows how to work this out.
2244 (define_split
2245 [(set (match_operand:DF 0 "push_operand" "")
2246 (match_operand:DF 1 "register_operand" ""))]
2247 "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2248 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2249 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2250 "")
2251
2252 (define_split
2253 [(set (match_operand:DF 0 "push_operand" "")
2254 (match_operand:DF 1 "register_operand" ""))]
2255 "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2256 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2257 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2258 "")
2259
2260 (define_split
2261 [(set (match_operand:DF 0 "push_operand" "")
2262 (match_operand:DF 1 "general_operand" ""))]
2263 "reload_completed"
2264 [(const_int 0)]
2265 "ix86_split_long_move (operands); DONE;")
2266
2267 ;; Moving is usually shorter when only FP registers are used. This separate
2268 ;; movdf pattern avoids the use of integer registers for FP operations
2269 ;; when optimizing for size.
2270
2271 (define_insn "*movdf_nointeger"
2272 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2273 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
2274 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2275 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2276 && (reload_in_progress || reload_completed
2277 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2278 || GET_CODE (operands[1]) != CONST_DOUBLE
2279 || memory_operand (operands[0], DFmode))"
2280 {
2281 switch (which_alternative)
2282 {
2283 case 0:
2284 if (REG_P (operands[1])
2285 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2286 return "fstp\t%y0";
2287 else if (STACK_TOP_P (operands[0]))
2288 return "fld%z1\t%y1";
2289 else
2290 return "fst\t%y0";
2291
2292 case 1:
2293 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2294 return "fstp%z0\t%y0";
2295 else
2296 return "fst%z0\t%y0";
2297
2298 case 2:
2299 switch (standard_80387_constant_p (operands[1]))
2300 {
2301 case 1:
2302 return "fldz";
2303 case 2:
2304 return "fld1";
2305 }
2306 abort();
2307
2308 case 3:
2309 case 4:
2310 return "#";
2311 case 5:
2312 return "pxor\t%0, %0";
2313 case 6:
2314 if (TARGET_PARTIAL_REG_DEPENDENCY)
2315 return "movapd\t{%1, %0|%0, %1}";
2316 else
2317 return "movsd\t{%1, %0|%0, %1}";
2318 case 7:
2319 case 8:
2320 return "movsd\t{%1, %0|%0, %1}";
2321
2322 default:
2323 abort();
2324 }
2325 }
2326 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2327 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2328
2329 (define_insn "*movdf_integer"
2330 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2331 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
2332 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2333 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2334 && (reload_in_progress || reload_completed
2335 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2336 || GET_CODE (operands[1]) != CONST_DOUBLE
2337 || memory_operand (operands[0], DFmode))"
2338 {
2339 switch (which_alternative)
2340 {
2341 case 0:
2342 if (REG_P (operands[1])
2343 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2344 return "fstp\t%y0";
2345 else if (STACK_TOP_P (operands[0]))
2346 return "fld%z1\t%y1";
2347 else
2348 return "fst\t%y0";
2349
2350 case 1:
2351 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2352 return "fstp%z0\t%y0";
2353 else
2354 return "fst%z0\t%y0";
2355
2356 case 2:
2357 switch (standard_80387_constant_p (operands[1]))
2358 {
2359 case 1:
2360 return "fldz";
2361 case 2:
2362 return "fld1";
2363 }
2364 abort();
2365
2366 case 3:
2367 case 4:
2368 return "#";
2369
2370 case 5:
2371 return "pxor\t%0, %0";
2372 case 6:
2373 if (TARGET_PARTIAL_REG_DEPENDENCY)
2374 return "movapd\t{%1, %0|%0, %1}";
2375 else
2376 return "movsd\t{%1, %0|%0, %1}";
2377 case 7:
2378 case 8:
2379 return "movsd\t{%1, %0|%0, %1}";
2380
2381 default:
2382 abort();
2383 }
2384 }
2385 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2386 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2387
2388 (define_split
2389 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2390 (match_operand:DF 1 "general_operand" ""))]
2391 "reload_completed
2392 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2393 && ! (ANY_FP_REG_P (operands[0]) ||
2394 (GET_CODE (operands[0]) == SUBREG
2395 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2396 && ! (ANY_FP_REG_P (operands[1]) ||
2397 (GET_CODE (operands[1]) == SUBREG
2398 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2399 [(const_int 0)]
2400 "ix86_split_long_move (operands); DONE;")
2401
2402 (define_insn "*swapdf"
2403 [(set (match_operand:DF 0 "register_operand" "+f")
2404 (match_operand:DF 1 "register_operand" "+f"))
2405 (set (match_dup 1)
2406 (match_dup 0))]
2407 "reload_completed || !TARGET_SSE2"
2408 {
2409 if (STACK_TOP_P (operands[0]))
2410 return "fxch\t%1";
2411 else
2412 return "fxch\t%0";
2413 }
2414 [(set_attr "type" "fxch")
2415 (set_attr "mode" "DF")])
2416
2417 (define_expand "movxf"
2418 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2419 (match_operand:XF 1 "general_operand" ""))]
2420 "!TARGET_64BIT"
2421 "ix86_expand_move (XFmode, operands); DONE;")
2422
2423 (define_expand "movtf"
2424 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2425 (match_operand:TF 1 "general_operand" ""))]
2426 ""
2427 "ix86_expand_move (TFmode, operands); DONE;")
2428
2429 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2430 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2431 ;; Pushing using integer instructions is longer except for constants
2432 ;; and direct memory references.
2433 ;; (assuming that any given constant is pushed only once, but this ought to be
2434 ;; handled elsewhere).
2435
2436 (define_insn "*pushxf_nointeger"
2437 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2438 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2439 "!TARGET_64BIT && optimize_size"
2440 {
2441 switch (which_alternative)
2442 {
2443 case 0:
2444 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2445 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2446 operands[2] = stack_pointer_rtx;
2447 operands[3] = GEN_INT (12);
2448 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2449 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2450 else
2451 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2452
2453 case 1:
2454 case 2:
2455 return "#";
2456
2457 default:
2458 abort ();
2459 }
2460 }
2461 [(set_attr "type" "multi")
2462 (set_attr "mode" "XF,SI,SI")])
2463
2464 (define_insn "*pushtf_nointeger"
2465 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2466 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2467 "optimize_size"
2468 {
2469 switch (which_alternative)
2470 {
2471 case 0:
2472 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2473 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2474 operands[2] = stack_pointer_rtx;
2475 operands[3] = GEN_INT (16);
2476 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2477 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2478 else
2479 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2480
2481 case 1:
2482 case 2:
2483 return "#";
2484
2485 default:
2486 abort ();
2487 }
2488 }
2489 [(set_attr "type" "multi")
2490 (set_attr "mode" "XF,SI,SI")])
2491
2492 (define_insn "*pushxf_integer"
2493 [(set (match_operand:XF 0 "push_operand" "=<,<")
2494 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2495 "!TARGET_64BIT && !optimize_size"
2496 {
2497 switch (which_alternative)
2498 {
2499 case 0:
2500 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2501 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2502 operands[2] = stack_pointer_rtx;
2503 operands[3] = GEN_INT (12);
2504 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2505 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2506 else
2507 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2508
2509 case 1:
2510 return "#";
2511
2512 default:
2513 abort ();
2514 }
2515 }
2516 [(set_attr "type" "multi")
2517 (set_attr "mode" "XF,SI")])
2518
2519 (define_insn "*pushtf_integer"
2520 [(set (match_operand:TF 0 "push_operand" "=<,<")
2521 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2522 "!optimize_size"
2523 {
2524 switch (which_alternative)
2525 {
2526 case 0:
2527 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2528 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2529 operands[2] = stack_pointer_rtx;
2530 operands[3] = GEN_INT (16);
2531 if (TARGET_64BIT)
2532 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2533 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2534 else
2535 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2536 else
2537 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2538 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2539 else
2540 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2541
2542 case 1:
2543 return "#";
2544
2545 default:
2546 abort ();
2547 }
2548 }
2549 [(set_attr "type" "multi")
2550 (set_attr "mode" "XF,SI")])
2551
2552 (define_split
2553 [(set (match_operand 0 "push_operand" "")
2554 (match_operand 1 "general_operand" ""))]
2555 "reload_completed
2556 && (GET_MODE (operands[0]) == XFmode
2557 || GET_MODE (operands[0]) == TFmode
2558 || GET_MODE (operands[0]) == DFmode)
2559 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
2560 [(const_int 0)]
2561 "ix86_split_long_move (operands); DONE;")
2562
2563 (define_split
2564 [(set (match_operand:XF 0 "push_operand" "")
2565 (match_operand:XF 1 "register_operand" ""))]
2566 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2567 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2568 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2569
2570 (define_split
2571 [(set (match_operand:TF 0 "push_operand" "")
2572 (match_operand:TF 1 "register_operand" ""))]
2573 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2574 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2575 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2576
2577 (define_split
2578 [(set (match_operand:TF 0 "push_operand" "")
2579 (match_operand:TF 1 "register_operand" ""))]
2580 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2581 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2582 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2583
2584 ;; Do not use integer registers when optimizing for size
2585 (define_insn "*movxf_nointeger"
2586 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2587 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2588 "!TARGET_64BIT
2589 && optimize_size
2590 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2591 && (reload_in_progress || reload_completed
2592 || GET_CODE (operands[1]) != CONST_DOUBLE
2593 || memory_operand (operands[0], XFmode))"
2594 {
2595 switch (which_alternative)
2596 {
2597 case 0:
2598 if (REG_P (operands[1])
2599 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2600 return "fstp\t%y0";
2601 else if (STACK_TOP_P (operands[0]))
2602 return "fld%z1\t%y1";
2603 else
2604 return "fst\t%y0";
2605
2606 case 1:
2607 /* There is no non-popping store to memory for XFmode. So if
2608 we need one, follow the store with a load. */
2609 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2610 return "fstp%z0\t%y0\;fld%z0\t%y0";
2611 else
2612 return "fstp%z0\t%y0";
2613
2614 case 2:
2615 switch (standard_80387_constant_p (operands[1]))
2616 {
2617 case 1:
2618 return "fldz";
2619 case 2:
2620 return "fld1";
2621 }
2622 break;
2623
2624 case 3: case 4:
2625 return "#";
2626 }
2627 abort();
2628 }
2629 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2630 (set_attr "mode" "XF,XF,XF,SI,SI")])
2631
2632 (define_insn "*movtf_nointeger"
2633 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2634 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2635 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2636 && optimize_size
2637 && (reload_in_progress || reload_completed
2638 || GET_CODE (operands[1]) != CONST_DOUBLE
2639 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2640 || memory_operand (operands[0], TFmode))"
2641 {
2642 switch (which_alternative)
2643 {
2644 case 0:
2645 if (REG_P (operands[1])
2646 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2647 return "fstp\t%y0";
2648 else if (STACK_TOP_P (operands[0]))
2649 return "fld%z1\t%y1";
2650 else
2651 return "fst\t%y0";
2652
2653 case 1:
2654 /* There is no non-popping store to memory for XFmode. So if
2655 we need one, follow the store with a load. */
2656 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2657 return "fstp%z0\t%y0\;fld%z0\t%y0";
2658 else
2659 return "fstp%z0\t%y0";
2660
2661 case 2:
2662 switch (standard_80387_constant_p (operands[1]))
2663 {
2664 case 1:
2665 return "fldz";
2666 case 2:
2667 return "fld1";
2668 }
2669 break;
2670
2671 case 3: case 4:
2672 return "#";
2673 }
2674 abort();
2675 }
2676 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2677 (set_attr "mode" "XF,XF,XF,SI,SI")])
2678
2679 (define_insn "*movxf_integer"
2680 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2681 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2682 "!TARGET_64BIT
2683 && !optimize_size
2684 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2685 && (reload_in_progress || reload_completed
2686 || GET_CODE (operands[1]) != CONST_DOUBLE
2687 || memory_operand (operands[0], XFmode))"
2688 {
2689 switch (which_alternative)
2690 {
2691 case 0:
2692 if (REG_P (operands[1])
2693 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2694 return "fstp\t%y0";
2695 else if (STACK_TOP_P (operands[0]))
2696 return "fld%z1\t%y1";
2697 else
2698 return "fst\t%y0";
2699
2700 case 1:
2701 /* There is no non-popping store to memory for XFmode. So if
2702 we need one, follow the store with a load. */
2703 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2704 return "fstp%z0\t%y0\;fld%z0\t%y0";
2705 else
2706 return "fstp%z0\t%y0";
2707
2708 case 2:
2709 switch (standard_80387_constant_p (operands[1]))
2710 {
2711 case 1:
2712 return "fldz";
2713 case 2:
2714 return "fld1";
2715 }
2716 break;
2717
2718 case 3: case 4:
2719 return "#";
2720 }
2721 abort();
2722 }
2723 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2724 (set_attr "mode" "XF,XF,XF,SI,SI")])
2725
2726 (define_insn "*movtf_integer"
2727 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2728 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2729 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2730 && !optimize_size
2731 && (reload_in_progress || reload_completed
2732 || GET_CODE (operands[1]) != CONST_DOUBLE
2733 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2734 || memory_operand (operands[0], TFmode))"
2735 {
2736 switch (which_alternative)
2737 {
2738 case 0:
2739 if (REG_P (operands[1])
2740 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2741 return "fstp\t%y0";
2742 else if (STACK_TOP_P (operands[0]))
2743 return "fld%z1\t%y1";
2744 else
2745 return "fst\t%y0";
2746
2747 case 1:
2748 /* There is no non-popping store to memory for XFmode. So if
2749 we need one, follow the store with a load. */
2750 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2751 return "fstp%z0\t%y0\;fld%z0\t%y0";
2752 else
2753 return "fstp%z0\t%y0";
2754
2755 case 2:
2756 switch (standard_80387_constant_p (operands[1]))
2757 {
2758 case 1:
2759 return "fldz";
2760 case 2:
2761 return "fld1";
2762 }
2763 break;
2764
2765 case 3: case 4:
2766 return "#";
2767 }
2768 abort();
2769 }
2770 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2771 (set_attr "mode" "XF,XF,XF,SI,SI")])
2772
2773 (define_split
2774 [(set (match_operand 0 "nonimmediate_operand" "")
2775 (match_operand 1 "general_operand" ""))]
2776 "reload_completed
2777 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
2779 && ! (ANY_FP_REG_P (operands[0]) ||
2780 (GET_CODE (operands[0]) == SUBREG
2781 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2782 && ! (ANY_FP_REG_P (operands[1]) ||
2783 (GET_CODE (operands[1]) == SUBREG
2784 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2785 [(const_int 0)]
2786 "ix86_split_long_move (operands); DONE;")
2787
2788 (define_split
2789 [(set (match_operand 0 "register_operand" "")
2790 (match_operand 1 "memory_operand" ""))]
2791 "reload_completed
2792 && GET_CODE (operands[1]) == MEM
2793 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
2794 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2795 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2796 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2797 && (!(SSE_REG_P (operands[0]) ||
2798 (GET_CODE (operands[0]) == SUBREG
2799 && SSE_REG_P (SUBREG_REG (operands[0]))))
2800 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
2801 && (!(FP_REG_P (operands[0]) ||
2802 (GET_CODE (operands[0]) == SUBREG
2803 && FP_REG_P (SUBREG_REG (operands[0]))))
2804 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2805 [(set (match_dup 0)
2806 (match_dup 1))]
2807 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2808
2809 (define_insn "swapxf"
2810 [(set (match_operand:XF 0 "register_operand" "+f")
2811 (match_operand:XF 1 "register_operand" "+f"))
2812 (set (match_dup 1)
2813 (match_dup 0))]
2814 ""
2815 {
2816 if (STACK_TOP_P (operands[0]))
2817 return "fxch\t%1";
2818 else
2819 return "fxch\t%0";
2820 }
2821 [(set_attr "type" "fxch")
2822 (set_attr "mode" "XF")])
2823
2824 (define_insn "swaptf"
2825 [(set (match_operand:TF 0 "register_operand" "+f")
2826 (match_operand:TF 1 "register_operand" "+f"))
2827 (set (match_dup 1)
2828 (match_dup 0))]
2829 ""
2830 {
2831 if (STACK_TOP_P (operands[0]))
2832 return "fxch\t%1";
2833 else
2834 return "fxch\t%0";
2835 }
2836 [(set_attr "type" "fxch")
2837 (set_attr "mode" "XF")])
2838 \f
2839 ;; Zero extension instructions
2840
2841 (define_expand "zero_extendhisi2"
2842 [(set (match_operand:SI 0 "register_operand" "")
2843 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2844 ""
2845 {
2846 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2847 {
2848 operands[1] = force_reg (HImode, operands[1]);
2849 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2850 DONE;
2851 }
2852 })
2853
2854 (define_insn "zero_extendhisi2_and"
2855 [(set (match_operand:SI 0 "register_operand" "=r")
2856 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2857 (clobber (reg:CC 17))]
2858 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2859 "#"
2860 [(set_attr "type" "alu1")
2861 (set_attr "mode" "SI")])
2862
2863 (define_split
2864 [(set (match_operand:SI 0 "register_operand" "")
2865 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2866 (clobber (reg:CC 17))]
2867 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2868 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2869 (clobber (reg:CC 17))])]
2870 "")
2871
2872 (define_insn "*zero_extendhisi2_movzwl"
2873 [(set (match_operand:SI 0 "register_operand" "=r")
2874 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2875 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2876 "movz{wl|x}\t{%1, %0|%0, %1}"
2877 [(set_attr "type" "imovx")
2878 (set_attr "mode" "SI")])
2879
2880 (define_expand "zero_extendqihi2"
2881 [(parallel
2882 [(set (match_operand:HI 0 "register_operand" "")
2883 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2884 (clobber (reg:CC 17))])]
2885 ""
2886 "")
2887
2888 (define_insn "*zero_extendqihi2_and"
2889 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2890 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2891 (clobber (reg:CC 17))]
2892 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2893 "#"
2894 [(set_attr "type" "alu1")
2895 (set_attr "mode" "HI")])
2896
2897 (define_insn "*zero_extendqihi2_movzbw_and"
2898 [(set (match_operand:HI 0 "register_operand" "=r,r")
2899 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2900 (clobber (reg:CC 17))]
2901 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2902 "#"
2903 [(set_attr "type" "imovx,alu1")
2904 (set_attr "mode" "HI")])
2905
2906 (define_insn "*zero_extendqihi2_movzbw"
2907 [(set (match_operand:HI 0 "register_operand" "=r")
2908 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2909 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2910 "movz{bw|x}\t{%1, %0|%0, %1}"
2911 [(set_attr "type" "imovx")
2912 (set_attr "mode" "HI")])
2913
2914 ;; For the movzbw case strip only the clobber
2915 (define_split
2916 [(set (match_operand:HI 0 "register_operand" "")
2917 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2918 (clobber (reg:CC 17))]
2919 "reload_completed
2920 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2921 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2922 [(set (match_operand:HI 0 "register_operand" "")
2923 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2924
2925 ;; When source and destination does not overlap, clear destination
2926 ;; first and then do the movb
2927 (define_split
2928 [(set (match_operand:HI 0 "register_operand" "")
2929 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2930 (clobber (reg:CC 17))]
2931 "reload_completed
2932 && ANY_QI_REG_P (operands[0])
2933 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2934 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2935 [(set (match_dup 0) (const_int 0))
2936 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2937 "operands[2] = gen_lowpart (QImode, operands[0]);")
2938
2939 ;; Rest is handled by single and.
2940 (define_split
2941 [(set (match_operand:HI 0 "register_operand" "")
2942 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2943 (clobber (reg:CC 17))]
2944 "reload_completed
2945 && true_regnum (operands[0]) == true_regnum (operands[1])"
2946 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2947 (clobber (reg:CC 17))])]
2948 "")
2949
2950 (define_expand "zero_extendqisi2"
2951 [(parallel
2952 [(set (match_operand:SI 0 "register_operand" "")
2953 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2954 (clobber (reg:CC 17))])]
2955 ""
2956 "")
2957
2958 (define_insn "*zero_extendqisi2_and"
2959 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2960 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2961 (clobber (reg:CC 17))]
2962 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2963 "#"
2964 [(set_attr "type" "alu1")
2965 (set_attr "mode" "SI")])
2966
2967 (define_insn "*zero_extendqisi2_movzbw_and"
2968 [(set (match_operand:SI 0 "register_operand" "=r,r")
2969 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2970 (clobber (reg:CC 17))]
2971 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2972 "#"
2973 [(set_attr "type" "imovx,alu1")
2974 (set_attr "mode" "SI")])
2975
2976 (define_insn "*zero_extendqisi2_movzbw"
2977 [(set (match_operand:SI 0 "register_operand" "=r")
2978 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2979 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2980 "movz{bl|x}\t{%1, %0|%0, %1}"
2981 [(set_attr "type" "imovx")
2982 (set_attr "mode" "SI")])
2983
2984 ;; For the movzbl case strip only the clobber
2985 (define_split
2986 [(set (match_operand:SI 0 "register_operand" "")
2987 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2988 (clobber (reg:CC 17))]
2989 "reload_completed
2990 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2991 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2992 [(set (match_dup 0)
2993 (zero_extend:SI (match_dup 1)))])
2994
2995 ;; When source and destination does not overlap, clear destination
2996 ;; first and then do the movb
2997 (define_split
2998 [(set (match_operand:SI 0 "register_operand" "")
2999 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3000 (clobber (reg:CC 17))]
3001 "reload_completed
3002 && ANY_QI_REG_P (operands[0])
3003 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3004 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3005 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3006 [(set (match_dup 0) (const_int 0))
3007 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3008 "operands[2] = gen_lowpart (QImode, operands[0]);")
3009
3010 ;; Rest is handled by single and.
3011 (define_split
3012 [(set (match_operand:SI 0 "register_operand" "")
3013 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3014 (clobber (reg:CC 17))]
3015 "reload_completed
3016 && true_regnum (operands[0]) == true_regnum (operands[1])"
3017 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3018 (clobber (reg:CC 17))])]
3019 "")
3020
3021 ;; %%% Kill me once multi-word ops are sane.
3022 (define_expand "zero_extendsidi2"
3023 [(set (match_operand:DI 0 "register_operand" "=r")
3024 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3025 ""
3026 "if (!TARGET_64BIT)
3027 {
3028 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3029 DONE;
3030 }
3031 ")
3032
3033 (define_insn "zero_extendsidi2_32"
3034 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3035 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3036 (clobber (reg:CC 17))]
3037 "!TARGET_64BIT"
3038 "#"
3039 [(set_attr "mode" "SI")])
3040
3041 (define_insn "zero_extendsidi2_rex64"
3042 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3043 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3044 "TARGET_64BIT"
3045 "@
3046 mov\t{%k1, %k0|%k0, %k1}
3047 #"
3048 [(set_attr "type" "imovx,imov")
3049 (set_attr "mode" "SI,DI")])
3050
3051 (define_split
3052 [(set (match_operand:DI 0 "memory_operand" "")
3053 (zero_extend:DI (match_dup 0)))]
3054 "TARGET_64BIT"
3055 [(set (match_dup 4) (const_int 0))]
3056 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3057
3058 (define_split
3059 [(set (match_operand:DI 0 "register_operand" "")
3060 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3061 (clobber (reg:CC 17))]
3062 "!TARGET_64BIT && reload_completed
3063 && true_regnum (operands[0]) == true_regnum (operands[1])"
3064 [(set (match_dup 4) (const_int 0))]
3065 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3066
3067 (define_split
3068 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3069 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3070 (clobber (reg:CC 17))]
3071 "!TARGET_64BIT && reload_completed"
3072 [(set (match_dup 3) (match_dup 1))
3073 (set (match_dup 4) (const_int 0))]
3074 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3075
3076 (define_insn "zero_extendhidi2"
3077 [(set (match_operand:DI 0 "register_operand" "=r,r")
3078 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3079 "TARGET_64BIT"
3080 "@
3081 movz{wl|x}\t{%1, %k0|%k0, %1}
3082 movz{wq|x}\t{%1, %0|%0, %1}"
3083 [(set_attr "type" "imovx")
3084 (set_attr "mode" "SI,DI")])
3085
3086 (define_insn "zero_extendqidi2"
3087 [(set (match_operand:DI 0 "register_operand" "=r,r")
3088 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3089 "TARGET_64BIT"
3090 "@
3091 movz{bl|x}\t{%1, %k0|%k0, %1}
3092 movz{bq|x}\t{%1, %0|%0, %1}"
3093 [(set_attr "type" "imovx")
3094 (set_attr "mode" "SI,DI")])
3095 \f
3096 ;; Sign extension instructions
3097
3098 (define_expand "extendsidi2"
3099 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3100 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3101 (clobber (reg:CC 17))
3102 (clobber (match_scratch:SI 2 ""))])]
3103 ""
3104 {
3105 if (TARGET_64BIT)
3106 {
3107 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3108 DONE;
3109 }
3110 })
3111
3112 (define_insn "*extendsidi2_1"
3113 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3114 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3115 (clobber (reg:CC 17))
3116 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3117 "!TARGET_64BIT"
3118 "#")
3119
3120 (define_insn "extendsidi2_rex64"
3121 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3122 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3123 "TARGET_64BIT"
3124 "@
3125 {cltq|cdqe}
3126 movs{lq|x}\t{%1,%0|%0, %1}"
3127 [(set_attr "type" "imovx")
3128 (set_attr "mode" "DI")
3129 (set_attr "prefix_0f" "0")
3130 (set_attr "modrm" "0,1")])
3131
3132 (define_insn "extendhidi2"
3133 [(set (match_operand:DI 0 "register_operand" "=r")
3134 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3135 "TARGET_64BIT"
3136 "movs{wq|x}\t{%1,%0|%0, %1}"
3137 [(set_attr "type" "imovx")
3138 (set_attr "mode" "DI")])
3139
3140 (define_insn "extendqidi2"
3141 [(set (match_operand:DI 0 "register_operand" "=r")
3142 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3143 "TARGET_64BIT"
3144 "movs{bq|x}\t{%1,%0|%0, %1}"
3145 [(set_attr "type" "imovx")
3146 (set_attr "mode" "DI")])
3147
3148 ;; Extend to memory case when source register does die.
3149 (define_split
3150 [(set (match_operand:DI 0 "memory_operand" "")
3151 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3152 (clobber (reg:CC 17))
3153 (clobber (match_operand:SI 2 "register_operand" ""))]
3154 "(reload_completed
3155 && dead_or_set_p (insn, operands[1])
3156 && !reg_mentioned_p (operands[1], operands[0]))"
3157 [(set (match_dup 3) (match_dup 1))
3158 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3159 (clobber (reg:CC 17))])
3160 (set (match_dup 4) (match_dup 1))]
3161 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3162
3163 ;; Extend to memory case when source register does not die.
3164 (define_split
3165 [(set (match_operand:DI 0 "memory_operand" "")
3166 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3167 (clobber (reg:CC 17))
3168 (clobber (match_operand:SI 2 "register_operand" ""))]
3169 "reload_completed"
3170 [(const_int 0)]
3171 {
3172 split_di (&operands[0], 1, &operands[3], &operands[4]);
3173
3174 emit_move_insn (operands[3], operands[1]);
3175
3176 /* Generate a cltd if possible and doing so it profitable. */
3177 if (true_regnum (operands[1]) == 0
3178 && true_regnum (operands[2]) == 1
3179 && (optimize_size || TARGET_USE_CLTD))
3180 {
3181 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3182 }
3183 else
3184 {
3185 emit_move_insn (operands[2], operands[1]);
3186 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3187 }
3188 emit_move_insn (operands[4], operands[2]);
3189 DONE;
3190 })
3191
3192 ;; Extend to register case. Optimize case where source and destination
3193 ;; registers match and cases where we can use cltd.
3194 (define_split
3195 [(set (match_operand:DI 0 "register_operand" "")
3196 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3197 (clobber (reg:CC 17))
3198 (clobber (match_scratch:SI 2 ""))]
3199 "reload_completed"
3200 [(const_int 0)]
3201 {
3202 split_di (&operands[0], 1, &operands[3], &operands[4]);
3203
3204 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3205 emit_move_insn (operands[3], operands[1]);
3206
3207 /* Generate a cltd if possible and doing so it profitable. */
3208 if (true_regnum (operands[3]) == 0
3209 && (optimize_size || TARGET_USE_CLTD))
3210 {
3211 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3212 DONE;
3213 }
3214
3215 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3216 emit_move_insn (operands[4], operands[1]);
3217
3218 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3219 DONE;
3220 })
3221
3222 (define_insn "extendhisi2"
3223 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3224 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3225 ""
3226 {
3227 switch (get_attr_prefix_0f (insn))
3228 {
3229 case 0:
3230 return "{cwtl|cwde}";
3231 default:
3232 return "movs{wl|x}\t{%1,%0|%0, %1}";
3233 }
3234 }
3235 [(set_attr "type" "imovx")
3236 (set_attr "mode" "SI")
3237 (set (attr "prefix_0f")
3238 ;; movsx is short decodable while cwtl is vector decoded.
3239 (if_then_else (and (eq_attr "cpu" "!k6")
3240 (eq_attr "alternative" "0"))
3241 (const_string "0")
3242 (const_string "1")))
3243 (set (attr "modrm")
3244 (if_then_else (eq_attr "prefix_0f" "0")
3245 (const_string "0")
3246 (const_string "1")))])
3247
3248 (define_insn "*extendhisi2_zext"
3249 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3250 (zero_extend:DI
3251 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3252 "TARGET_64BIT"
3253 {
3254 switch (get_attr_prefix_0f (insn))
3255 {
3256 case 0:
3257 return "{cwtl|cwde}";
3258 default:
3259 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3260 }
3261 }
3262 [(set_attr "type" "imovx")
3263 (set_attr "mode" "SI")
3264 (set (attr "prefix_0f")
3265 ;; movsx is short decodable while cwtl is vector decoded.
3266 (if_then_else (and (eq_attr "cpu" "!k6")
3267 (eq_attr "alternative" "0"))
3268 (const_string "0")
3269 (const_string "1")))
3270 (set (attr "modrm")
3271 (if_then_else (eq_attr "prefix_0f" "0")
3272 (const_string "0")
3273 (const_string "1")))])
3274
3275 (define_insn "extendqihi2"
3276 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3277 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3278 ""
3279 {
3280 switch (get_attr_prefix_0f (insn))
3281 {
3282 case 0:
3283 return "{cbtw|cbw}";
3284 default:
3285 return "movs{bw|x}\t{%1,%0|%0, %1}";
3286 }
3287 }
3288 [(set_attr "type" "imovx")
3289 (set_attr "mode" "HI")
3290 (set (attr "prefix_0f")
3291 ;; movsx is short decodable while cwtl is vector decoded.
3292 (if_then_else (and (eq_attr "cpu" "!k6")
3293 (eq_attr "alternative" "0"))
3294 (const_string "0")
3295 (const_string "1")))
3296 (set (attr "modrm")
3297 (if_then_else (eq_attr "prefix_0f" "0")
3298 (const_string "0")
3299 (const_string "1")))])
3300
3301 (define_insn "extendqisi2"
3302 [(set (match_operand:SI 0 "register_operand" "=r")
3303 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3304 ""
3305 "movs{bl|x}\t{%1,%0|%0, %1}"
3306 [(set_attr "type" "imovx")
3307 (set_attr "mode" "SI")])
3308
3309 (define_insn "*extendqisi2_zext"
3310 [(set (match_operand:DI 0 "register_operand" "=r")
3311 (zero_extend:DI
3312 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3313 "TARGET_64BIT"
3314 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3315 [(set_attr "type" "imovx")
3316 (set_attr "mode" "SI")])
3317 \f
3318 ;; Conversions between float and double.
3319
3320 ;; These are all no-ops in the model used for the 80387. So just
3321 ;; emit moves.
3322
3323 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3324 (define_insn "*dummy_extendsfdf2"
3325 [(set (match_operand:DF 0 "push_operand" "=<")
3326 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3327 "0"
3328 "#")
3329
3330 (define_split
3331 [(set (match_operand:DF 0 "push_operand" "")
3332 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3333 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3334 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3335 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3336
3337 (define_split
3338 [(set (match_operand:DF 0 "push_operand" "")
3339 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3340 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3341 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3342 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3343
3344 (define_insn "*dummy_extendsfxf2"
3345 [(set (match_operand:XF 0 "push_operand" "=<")
3346 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3347 "0"
3348 "#")
3349
3350 (define_split
3351 [(set (match_operand:XF 0 "push_operand" "")
3352 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3353 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3354 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3355 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3356
3357 (define_insn "*dummy_extendsftf2"
3358 [(set (match_operand:TF 0 "push_operand" "=<")
3359 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3360 "0"
3361 "#")
3362
3363 (define_split
3364 [(set (match_operand:TF 0 "push_operand" "")
3365 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3366 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3367 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3368 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3369
3370 (define_split
3371 [(set (match_operand:TF 0 "push_operand" "")
3372 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3373 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3374 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3375 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3376
3377 (define_insn "*dummy_extenddfxf2"
3378 [(set (match_operand:XF 0 "push_operand" "=<")
3379 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3380 "0"
3381 "#")
3382
3383 (define_split
3384 [(set (match_operand:XF 0 "push_operand" "")
3385 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
3386 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3387 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3388 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3389
3390 (define_insn "*dummy_extenddftf2"
3391 [(set (match_operand:TF 0 "push_operand" "=<")
3392 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3393 "0"
3394 "#")
3395
3396 (define_split
3397 [(set (match_operand:TF 0 "push_operand" "")
3398 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3399 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3400 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3401 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3402
3403 (define_split
3404 [(set (match_operand:TF 0 "push_operand" "")
3405 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3406 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3407 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3408 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3409
3410 (define_expand "extendsfdf2"
3411 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3412 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3413 "TARGET_80387 || TARGET_SSE2"
3414 {
3415 /* ??? Needed for compress_float_constant since all fp constants
3416 are LEGITIMATE_CONSTANT_P. */
3417 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3418 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3419 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3420 operands[1] = force_reg (SFmode, operands[1]);
3421 })
3422
3423 (define_insn "*extendsfdf2_1"
3424 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3425 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3426 "(TARGET_80387 || TARGET_SSE2)
3427 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3428 {
3429 switch (which_alternative)
3430 {
3431 case 0:
3432 if (REG_P (operands[1])
3433 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3434 return "fstp\t%y0";
3435 else if (STACK_TOP_P (operands[0]))
3436 return "fld%z1\t%y1";
3437 else
3438 return "fst\t%y0";
3439
3440 case 1:
3441 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3442 return "fstp%z0\t%y0";
3443
3444 else
3445 return "fst%z0\t%y0";
3446 case 2:
3447 return "cvtss2sd\t{%1, %0|%0, %1}";
3448
3449 default:
3450 abort ();
3451 }
3452 }
3453 [(set_attr "type" "fmov,fmov,ssecvt")
3454 (set_attr "mode" "SF,XF,DF")])
3455
3456 (define_insn "*extendsfdf2_1_sse_only"
3457 [(set (match_operand:DF 0 "register_operand" "=Y")
3458 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3459 "!TARGET_80387 && TARGET_SSE2
3460 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3461 "cvtss2sd\t{%1, %0|%0, %1}"
3462 [(set_attr "type" "ssecvt")
3463 (set_attr "mode" "DF")])
3464
3465 (define_expand "extendsfxf2"
3466 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3467 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3468 "!TARGET_64BIT && TARGET_80387"
3469 {
3470 /* ??? Needed for compress_float_constant since all fp constants
3471 are LEGITIMATE_CONSTANT_P. */
3472 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3473 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3474 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3475 operands[1] = force_reg (SFmode, operands[1]);
3476 })
3477
3478 (define_insn "*extendsfxf2_1"
3479 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3480 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3481 "!TARGET_64BIT && TARGET_80387
3482 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3483 {
3484 switch (which_alternative)
3485 {
3486 case 0:
3487 if (REG_P (operands[1])
3488 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3489 return "fstp\t%y0";
3490 else if (STACK_TOP_P (operands[0]))
3491 return "fld%z1\t%y1";
3492 else
3493 return "fst\t%y0";
3494
3495 case 1:
3496 /* There is no non-popping store to memory for XFmode. So if
3497 we need one, follow the store with a load. */
3498 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3499 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3500 else
3501 return "fstp%z0\t%y0";
3502
3503 default:
3504 abort ();
3505 }
3506 }
3507 [(set_attr "type" "fmov")
3508 (set_attr "mode" "SF,XF")])
3509
3510 (define_expand "extendsftf2"
3511 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3512 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3513 "TARGET_80387"
3514 {
3515 /* ??? Needed for compress_float_constant since all fp constants
3516 are LEGITIMATE_CONSTANT_P. */
3517 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3518 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3519 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3520 operands[1] = force_reg (SFmode, operands[1]);
3521 })
3522
3523 (define_insn "*extendsftf2_1"
3524 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3525 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3526 "TARGET_80387
3527 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3528 {
3529 switch (which_alternative)
3530 {
3531 case 0:
3532 if (REG_P (operands[1])
3533 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3534 return "fstp\t%y0";
3535 else if (STACK_TOP_P (operands[0]))
3536 return "fld%z1\t%y1";
3537 else
3538 return "fst\t%y0";
3539
3540 case 1:
3541 /* There is no non-popping store to memory for XFmode. So if
3542 we need one, follow the store with a load. */
3543 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3544 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3545 else
3546 return "fstp%z0\t%y0";
3547
3548 default:
3549 abort ();
3550 }
3551 }
3552 [(set_attr "type" "fmov")
3553 (set_attr "mode" "SF,XF")])
3554
3555 (define_expand "extenddfxf2"
3556 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3557 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3558 "!TARGET_64BIT && TARGET_80387"
3559 {
3560 /* ??? Needed for compress_float_constant since all fp constants
3561 are LEGITIMATE_CONSTANT_P. */
3562 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3564 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3565 operands[1] = force_reg (DFmode, operands[1]);
3566 })
3567
3568 (define_insn "*extenddfxf2_1"
3569 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3570 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3571 "!TARGET_64BIT && TARGET_80387
3572 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3573 {
3574 switch (which_alternative)
3575 {
3576 case 0:
3577 if (REG_P (operands[1])
3578 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3579 return "fstp\t%y0";
3580 else if (STACK_TOP_P (operands[0]))
3581 return "fld%z1\t%y1";
3582 else
3583 return "fst\t%y0";
3584
3585 case 1:
3586 /* There is no non-popping store to memory for XFmode. So if
3587 we need one, follow the store with a load. */
3588 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3590 else
3591 return "fstp%z0\t%y0";
3592
3593 default:
3594 abort ();
3595 }
3596 }
3597 [(set_attr "type" "fmov")
3598 (set_attr "mode" "DF,XF")])
3599
3600 (define_expand "extenddftf2"
3601 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3602 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3603 "TARGET_80387"
3604 {
3605 /* ??? Needed for compress_float_constant since all fp constants
3606 are LEGITIMATE_CONSTANT_P. */
3607 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3609 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3610 operands[1] = force_reg (DFmode, operands[1]);
3611 })
3612
3613 (define_insn "*extenddftf2_1"
3614 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3615 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3616 "TARGET_80387
3617 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3618 {
3619 switch (which_alternative)
3620 {
3621 case 0:
3622 if (REG_P (operands[1])
3623 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624 return "fstp\t%y0";
3625 else if (STACK_TOP_P (operands[0]))
3626 return "fld%z1\t%y1";
3627 else
3628 return "fst\t%y0";
3629
3630 case 1:
3631 /* There is no non-popping store to memory for XFmode. So if
3632 we need one, follow the store with a load. */
3633 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3634 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3635 else
3636 return "fstp%z0\t%y0";
3637
3638 default:
3639 abort ();
3640 }
3641 }
3642 [(set_attr "type" "fmov")
3643 (set_attr "mode" "DF,XF")])
3644
3645 ;; %%% This seems bad bad news.
3646 ;; This cannot output into an f-reg because there is no way to be sure
3647 ;; of truncating in that case. Otherwise this is just like a simple move
3648 ;; insn. So we pretend we can output to a reg in order to get better
3649 ;; register preferencing, but we really use a stack slot.
3650
3651 (define_expand "truncdfsf2"
3652 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3653 (float_truncate:SF
3654 (match_operand:DF 1 "register_operand" "")))
3655 (clobber (match_dup 2))])]
3656 "TARGET_80387 || TARGET_SSE2"
3657 "
3658 if (TARGET_80387)
3659 operands[2] = assign_386_stack_local (SFmode, 0);
3660 else
3661 {
3662 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3663 DONE;
3664 }
3665 ")
3666
3667 (define_insn "*truncdfsf2_1"
3668 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3669 (float_truncate:SF
3670 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3671 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3672 "TARGET_80387 && !TARGET_SSE2"
3673 {
3674 switch (which_alternative)
3675 {
3676 case 0:
3677 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3678 return "fstp%z0\t%y0";
3679 else
3680 return "fst%z0\t%y0";
3681 default:
3682 abort ();
3683 }
3684 }
3685 [(set_attr "type" "fmov,multi,multi,multi")
3686 (set_attr "mode" "SF,SF,SF,SF")])
3687
3688 (define_insn "*truncdfsf2_1_sse"
3689 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
3690 (float_truncate:SF
3691 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
3692 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3693 "TARGET_80387 && TARGET_SSE2"
3694 {
3695 switch (which_alternative)
3696 {
3697 case 0:
3698 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3699 return "fstp%z0\t%y0";
3700 else
3701 return "fst%z0\t%y0";
3702 case 4:
3703 return "cvtsd2ss\t{%1, %0|%0, %1}";
3704 default:
3705 abort ();
3706 }
3707 }
3708 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3709 (set_attr "mode" "SF,SF,SF,SF,DF")])
3710
3711 (define_insn "*truncdfsf2_2"
3712 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
3713 (float_truncate:SF
3714 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3715 "TARGET_80387 && TARGET_SSE2
3716 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3717 {
3718 switch (which_alternative)
3719 {
3720 case 0:
3721 return "cvtsd2ss\t{%1, %0|%0, %1}";
3722 case 1:
3723 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3724 return "fstp%z0\t%y0";
3725 else
3726 return "fst%z0\t%y0";
3727 default:
3728 abort ();
3729 }
3730 }
3731 [(set_attr "type" "ssecvt,fmov")
3732 (set_attr "mode" "DF,SF")])
3733
3734 (define_insn "truncdfsf2_3"
3735 [(set (match_operand:SF 0 "memory_operand" "=m")
3736 (float_truncate:SF
3737 (match_operand:DF 1 "register_operand" "f")))]
3738 "TARGET_80387"
3739 {
3740 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741 return "fstp%z0\t%y0";
3742 else
3743 return "fst%z0\t%y0";
3744 }
3745 [(set_attr "type" "fmov")
3746 (set_attr "mode" "SF")])
3747
3748 (define_insn "truncdfsf2_sse_only"
3749 [(set (match_operand:SF 0 "register_operand" "=Y")
3750 (float_truncate:SF
3751 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3752 "!TARGET_80387 && TARGET_SSE2"
3753 "cvtsd2ss\t{%1, %0|%0, %1}"
3754 [(set_attr "type" "ssecvt")
3755 (set_attr "mode" "DF")])
3756
3757 (define_split
3758 [(set (match_operand:SF 0 "memory_operand" "")
3759 (float_truncate:SF
3760 (match_operand:DF 1 "register_operand" "")))
3761 (clobber (match_operand:SF 2 "memory_operand" ""))]
3762 "TARGET_80387"
3763 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3764 "")
3765
3766 (define_split
3767 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3768 (float_truncate:SF
3769 (match_operand:DF 1 "nonimmediate_operand" "")))
3770 (clobber (match_operand 2 "" ""))]
3771 "TARGET_80387 && reload_completed
3772 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
3773 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3774 "")
3775
3776 (define_split
3777 [(set (match_operand:SF 0 "register_operand" "")
3778 (float_truncate:SF
3779 (match_operand:DF 1 "register_operand" "")))
3780 (clobber (match_operand:SF 2 "memory_operand" ""))]
3781 "TARGET_80387 && reload_completed
3782 && FP_REG_P (operands[1])"
3783 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3784 (set (match_dup 0) (match_dup 2))]
3785 "")
3786
3787 (define_expand "truncxfsf2"
3788 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3789 (float_truncate:SF
3790 (match_operand:XF 1 "register_operand" "")))
3791 (clobber (match_dup 2))])]
3792 "!TARGET_64BIT && TARGET_80387"
3793 "operands[2] = assign_386_stack_local (SFmode, 0);")
3794
3795 (define_insn "*truncxfsf2_1"
3796 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3797 (float_truncate:SF
3798 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3799 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3800 "!TARGET_64BIT && TARGET_80387"
3801 {
3802 switch (which_alternative)
3803 {
3804 case 0:
3805 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3806 return "fstp%z0\t%y0";
3807 else
3808 return "fst%z0\t%y0";
3809 default:
3810 abort();
3811 }
3812 }
3813 [(set_attr "type" "fmov,multi,multi,multi")
3814 (set_attr "mode" "SF")])
3815
3816 (define_insn "*truncxfsf2_2"
3817 [(set (match_operand:SF 0 "memory_operand" "=m")
3818 (float_truncate:SF
3819 (match_operand:XF 1 "register_operand" "f")))]
3820 "!TARGET_64BIT && TARGET_80387"
3821 {
3822 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3823 return "fstp%z0\t%y0";
3824 else
3825 return "fst%z0\t%y0";
3826 }
3827 [(set_attr "type" "fmov")
3828 (set_attr "mode" "SF")])
3829
3830 (define_split
3831 [(set (match_operand:SF 0 "memory_operand" "")
3832 (float_truncate:SF
3833 (match_operand:XF 1 "register_operand" "")))
3834 (clobber (match_operand:SF 2 "memory_operand" ""))]
3835 "TARGET_80387"
3836 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3837 "")
3838
3839 (define_split
3840 [(set (match_operand:SF 0 "register_operand" "")
3841 (float_truncate:SF
3842 (match_operand:XF 1 "register_operand" "")))
3843 (clobber (match_operand:SF 2 "memory_operand" ""))]
3844 "TARGET_80387 && reload_completed"
3845 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3846 (set (match_dup 0) (match_dup 2))]
3847 "")
3848
3849 (define_expand "trunctfsf2"
3850 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3851 (float_truncate:SF
3852 (match_operand:TF 1 "register_operand" "")))
3853 (clobber (match_dup 2))])]
3854 "TARGET_80387"
3855 "operands[2] = assign_386_stack_local (SFmode, 0);")
3856
3857 (define_insn "*trunctfsf2_1"
3858 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3859 (float_truncate:SF
3860 (match_operand:TF 1 "register_operand" "f,f,f,f")))
3861 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3862 "TARGET_80387"
3863 {
3864 switch (which_alternative)
3865 {
3866 case 0:
3867 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3868 return "fstp%z0\t%y0";
3869 else
3870 return "fst%z0\t%y0";
3871 default:
3872 abort();
3873 }
3874 }
3875 [(set_attr "type" "fmov,multi,multi,multi")
3876 (set_attr "mode" "SF")])
3877
3878 (define_insn "*trunctfsf2_2"
3879 [(set (match_operand:SF 0 "memory_operand" "=m")
3880 (float_truncate:SF
3881 (match_operand:TF 1 "register_operand" "f")))]
3882 "TARGET_80387"
3883 {
3884 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3885 return "fstp%z0\t%y0";
3886 else
3887 return "fst%z0\t%y0";
3888 }
3889 [(set_attr "type" "fmov")
3890 (set_attr "mode" "SF")])
3891
3892 (define_split
3893 [(set (match_operand:SF 0 "memory_operand" "")
3894 (float_truncate:SF
3895 (match_operand:TF 1 "register_operand" "")))
3896 (clobber (match_operand:SF 2 "memory_operand" ""))]
3897 "TARGET_80387"
3898 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3899 "")
3900
3901 (define_split
3902 [(set (match_operand:SF 0 "register_operand" "")
3903 (float_truncate:SF
3904 (match_operand:TF 1 "register_operand" "")))
3905 (clobber (match_operand:SF 2 "memory_operand" ""))]
3906 "TARGET_80387 && reload_completed"
3907 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3908 (set (match_dup 0) (match_dup 2))]
3909 "")
3910
3911
3912 (define_expand "truncxfdf2"
3913 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3914 (float_truncate:DF
3915 (match_operand:XF 1 "register_operand" "")))
3916 (clobber (match_dup 2))])]
3917 "!TARGET_64BIT && TARGET_80387"
3918 "operands[2] = assign_386_stack_local (DFmode, 0);")
3919
3920 (define_insn "*truncxfdf2_1"
3921 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3922 (float_truncate:DF
3923 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3924 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3925 "!TARGET_64BIT && TARGET_80387"
3926 {
3927 switch (which_alternative)
3928 {
3929 case 0:
3930 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931 return "fstp%z0\t%y0";
3932 else
3933 return "fst%z0\t%y0";
3934 default:
3935 abort();
3936 }
3937 abort ();
3938 }
3939 [(set_attr "type" "fmov,multi,multi,multi")
3940 (set_attr "mode" "DF")])
3941
3942 (define_insn "*truncxfdf2_2"
3943 [(set (match_operand:DF 0 "memory_operand" "=m")
3944 (float_truncate:DF
3945 (match_operand:XF 1 "register_operand" "f")))]
3946 "!TARGET_64BIT && TARGET_80387"
3947 {
3948 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3949 return "fstp%z0\t%y0";
3950 else
3951 return "fst%z0\t%y0";
3952 }
3953 [(set_attr "type" "fmov")
3954 (set_attr "mode" "DF")])
3955
3956 (define_split
3957 [(set (match_operand:DF 0 "memory_operand" "")
3958 (float_truncate:DF
3959 (match_operand:XF 1 "register_operand" "")))
3960 (clobber (match_operand:DF 2 "memory_operand" ""))]
3961 "TARGET_80387"
3962 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3963 "")
3964
3965 (define_split
3966 [(set (match_operand:DF 0 "register_operand" "")
3967 (float_truncate:DF
3968 (match_operand:XF 1 "register_operand" "")))
3969 (clobber (match_operand:DF 2 "memory_operand" ""))]
3970 "TARGET_80387 && reload_completed"
3971 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3972 (set (match_dup 0) (match_dup 2))]
3973 "")
3974
3975 (define_expand "trunctfdf2"
3976 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3977 (float_truncate:DF
3978 (match_operand:TF 1 "register_operand" "")))
3979 (clobber (match_dup 2))])]
3980 "TARGET_80387"
3981 "operands[2] = assign_386_stack_local (DFmode, 0);")
3982
3983 (define_insn "*trunctfdf2_1"
3984 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3985 (float_truncate:DF
3986 (match_operand:TF 1 "register_operand" "f,f,f,f")))
3987 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3988 "TARGET_80387"
3989 {
3990 switch (which_alternative)
3991 {
3992 case 0:
3993 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994 return "fstp%z0\t%y0";
3995 else
3996 return "fst%z0\t%y0";
3997 default:
3998 abort();
3999 }
4000 abort ();
4001 }
4002 [(set_attr "type" "fmov,multi,multi,multi")
4003 (set_attr "mode" "DF")])
4004
4005 (define_insn "*trunctfdf2_2"
4006 [(set (match_operand:DF 0 "memory_operand" "=m")
4007 (float_truncate:DF
4008 (match_operand:TF 1 "register_operand" "f")))]
4009 "TARGET_80387"
4010 {
4011 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4012 return "fstp%z0\t%y0";
4013 else
4014 return "fst%z0\t%y0";
4015 }
4016 [(set_attr "type" "fmov")
4017 (set_attr "mode" "DF")])
4018
4019 (define_split
4020 [(set (match_operand:DF 0 "memory_operand" "")
4021 (float_truncate:DF
4022 (match_operand:TF 1 "register_operand" "")))
4023 (clobber (match_operand:DF 2 "memory_operand" ""))]
4024 "TARGET_80387"
4025 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4026 "")
4027
4028 (define_split
4029 [(set (match_operand:DF 0 "register_operand" "")
4030 (float_truncate:DF
4031 (match_operand:TF 1 "register_operand" "")))
4032 (clobber (match_operand:DF 2 "memory_operand" ""))]
4033 "TARGET_80387 && reload_completed"
4034 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4035 (set (match_dup 0) (match_dup 2))]
4036 "")
4037
4038 \f
4039 ;; %%% Break up all these bad boys.
4040
4041 ;; Signed conversion to DImode.
4042
4043 (define_expand "fix_truncxfdi2"
4044 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4045 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4046 "!TARGET_64BIT && TARGET_80387"
4047 "")
4048
4049 (define_expand "fix_trunctfdi2"
4050 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4051 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4052 "TARGET_80387"
4053 "")
4054
4055 (define_expand "fix_truncdfdi2"
4056 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4057 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4058 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4059 {
4060 if (TARGET_64BIT && TARGET_SSE2)
4061 {
4062 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4063 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4064 if (out != operands[0])
4065 emit_move_insn (operands[0], out);
4066 DONE;
4067 }
4068 })
4069
4070 (define_expand "fix_truncsfdi2"
4071 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4073 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4074 {
4075 if (TARGET_SSE && TARGET_64BIT)
4076 {
4077 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4078 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4079 if (out != operands[0])
4080 emit_move_insn (operands[0], out);
4081 DONE;
4082 }
4083 })
4084
4085 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4086 ;; of the machinery.
4087 (define_insn_and_split "*fix_truncdi_1"
4088 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4089 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4090 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4091 && !reload_completed && !reload_in_progress
4092 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4093 "#"
4094 "&& 1"
4095 [(const_int 0)]
4096 {
4097 operands[2] = assign_386_stack_local (HImode, 1);
4098 operands[3] = assign_386_stack_local (HImode, 2);
4099 if (memory_operand (operands[0], VOIDmode))
4100 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4101 operands[2], operands[3]));
4102 else
4103 {
4104 operands[4] = assign_386_stack_local (DImode, 0);
4105 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4106 operands[2], operands[3],
4107 operands[4]));
4108 }
4109 DONE;
4110 }
4111 [(set_attr "type" "fistp")])
4112
4113 (define_insn "fix_truncdi_nomemory"
4114 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4115 (fix:DI (match_operand 1 "register_operand" "f,f")))
4116 (use (match_operand:HI 2 "memory_operand" "m,m"))
4117 (use (match_operand:HI 3 "memory_operand" "m,m"))
4118 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4119 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4120 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4121 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4122 "#"
4123 [(set_attr "type" "fistp")])
4124
4125 (define_insn "fix_truncdi_memory"
4126 [(set (match_operand:DI 0 "memory_operand" "=m")
4127 (fix:DI (match_operand 1 "register_operand" "f")))
4128 (use (match_operand:HI 2 "memory_operand" "m"))
4129 (use (match_operand:HI 3 "memory_operand" "m"))
4130 (clobber (match_scratch:DF 4 "=&1f"))]
4131 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4132 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4133 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4134 [(set_attr "type" "fistp")])
4135
4136 (define_split
4137 [(set (match_operand:DI 0 "register_operand" "")
4138 (fix:DI (match_operand 1 "register_operand" "")))
4139 (use (match_operand:HI 2 "memory_operand" ""))
4140 (use (match_operand:HI 3 "memory_operand" ""))
4141 (clobber (match_operand:DI 4 "memory_operand" ""))
4142 (clobber (match_scratch 5 ""))]
4143 "reload_completed"
4144 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4145 (use (match_dup 2))
4146 (use (match_dup 3))
4147 (clobber (match_dup 5))])
4148 (set (match_dup 0) (match_dup 4))]
4149 "")
4150
4151 (define_split
4152 [(set (match_operand:DI 0 "memory_operand" "")
4153 (fix:DI (match_operand 1 "register_operand" "")))
4154 (use (match_operand:HI 2 "memory_operand" ""))
4155 (use (match_operand:HI 3 "memory_operand" ""))
4156 (clobber (match_operand:DI 4 "memory_operand" ""))
4157 (clobber (match_scratch 5 ""))]
4158 "reload_completed"
4159 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4160 (use (match_dup 2))
4161 (use (match_dup 3))
4162 (clobber (match_dup 5))])]
4163 "")
4164
4165 ;; When SSE available, it is always faster to use it!
4166 (define_insn "fix_truncsfdi_sse"
4167 [(set (match_operand:DI 0 "register_operand" "=r")
4168 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4169 "TARGET_64BIT && TARGET_SSE"
4170 "cvttss2si{q}\t{%1, %0|%0, %1}"
4171 [(set_attr "type" "ssecvt")])
4172
4173 (define_insn "fix_truncdfdi_sse"
4174 [(set (match_operand:DI 0 "register_operand" "=r")
4175 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4176 "TARGET_64BIT && TARGET_SSE2"
4177 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4178 [(set_attr "type" "ssecvt")])
4179
4180 ;; Signed conversion to SImode.
4181
4182 (define_expand "fix_truncxfsi2"
4183 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4184 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4185 "!TARGET_64BIT && TARGET_80387"
4186 "")
4187
4188 (define_expand "fix_trunctfsi2"
4189 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4190 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4191 "TARGET_80387"
4192 "")
4193
4194 (define_expand "fix_truncdfsi2"
4195 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4196 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4197 "TARGET_80387 || TARGET_SSE2"
4198 {
4199 if (TARGET_SSE2)
4200 {
4201 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4202 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4203 if (out != operands[0])
4204 emit_move_insn (operands[0], out);
4205 DONE;
4206 }
4207 })
4208
4209 (define_expand "fix_truncsfsi2"
4210 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4211 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4212 "TARGET_80387 || TARGET_SSE"
4213 {
4214 if (TARGET_SSE)
4215 {
4216 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4217 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4218 if (out != operands[0])
4219 emit_move_insn (operands[0], out);
4220 DONE;
4221 }
4222 })
4223
4224 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4225 ;; of the machinery.
4226 (define_insn_and_split "*fix_truncsi_1"
4227 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4228 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4229 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4230 && !reload_completed && !reload_in_progress
4231 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4232 "#"
4233 "&& 1"
4234 [(const_int 0)]
4235 {
4236 operands[2] = assign_386_stack_local (HImode, 1);
4237 operands[3] = assign_386_stack_local (HImode, 2);
4238 if (memory_operand (operands[0], VOIDmode))
4239 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4240 operands[2], operands[3]));
4241 else
4242 {
4243 operands[4] = assign_386_stack_local (SImode, 0);
4244 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4245 operands[2], operands[3],
4246 operands[4]));
4247 }
4248 DONE;
4249 }
4250 [(set_attr "type" "fistp")])
4251
4252 (define_insn "fix_truncsi_nomemory"
4253 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4254 (fix:SI (match_operand 1 "register_operand" "f,f")))
4255 (use (match_operand:HI 2 "memory_operand" "m,m"))
4256 (use (match_operand:HI 3 "memory_operand" "m,m"))
4257 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4258 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4259 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4260 "#"
4261 [(set_attr "type" "fistp")])
4262
4263 (define_insn "fix_truncsi_memory"
4264 [(set (match_operand:SI 0 "memory_operand" "=m")
4265 (fix:SI (match_operand 1 "register_operand" "f")))
4266 (use (match_operand:HI 2 "memory_operand" "m"))
4267 (use (match_operand:HI 3 "memory_operand" "m"))]
4268 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4269 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4270 "* return output_fix_trunc (insn, operands);"
4271 [(set_attr "type" "fistp")])
4272
4273 ;; When SSE available, it is always faster to use it!
4274 (define_insn "fix_truncsfsi_sse"
4275 [(set (match_operand:SI 0 "register_operand" "=r")
4276 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4277 "TARGET_SSE"
4278 "cvttss2si\t{%1, %0|%0, %1}"
4279 [(set_attr "type" "ssecvt")])
4280
4281 (define_insn "fix_truncdfsi_sse"
4282 [(set (match_operand:SI 0 "register_operand" "=r")
4283 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4284 "TARGET_SSE2"
4285 "cvttsd2si\t{%1, %0|%0, %1}"
4286 [(set_attr "type" "ssecvt")])
4287
4288 (define_split
4289 [(set (match_operand:SI 0 "register_operand" "")
4290 (fix:SI (match_operand 1 "register_operand" "")))
4291 (use (match_operand:HI 2 "memory_operand" ""))
4292 (use (match_operand:HI 3 "memory_operand" ""))
4293 (clobber (match_operand:SI 4 "memory_operand" ""))]
4294 "reload_completed"
4295 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4296 (use (match_dup 2))
4297 (use (match_dup 3))])
4298 (set (match_dup 0) (match_dup 4))]
4299 "")
4300
4301 (define_split
4302 [(set (match_operand:SI 0 "memory_operand" "")
4303 (fix:SI (match_operand 1 "register_operand" "")))
4304 (use (match_operand:HI 2 "memory_operand" ""))
4305 (use (match_operand:HI 3 "memory_operand" ""))
4306 (clobber (match_operand:SI 4 "memory_operand" ""))]
4307 "reload_completed"
4308 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4309 (use (match_dup 2))
4310 (use (match_dup 3))])]
4311 "")
4312
4313 ;; Signed conversion to HImode.
4314
4315 (define_expand "fix_truncxfhi2"
4316 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4317 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4318 "!TARGET_64BIT && TARGET_80387"
4319 "")
4320
4321 (define_expand "fix_trunctfhi2"
4322 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4323 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4324 "TARGET_80387"
4325 "")
4326
4327 (define_expand "fix_truncdfhi2"
4328 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4329 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4330 "TARGET_80387 && !TARGET_SSE2"
4331 "")
4332
4333 (define_expand "fix_truncsfhi2"
4334 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4336 "TARGET_80387 && !TARGET_SSE"
4337 "")
4338
4339 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4340 ;; of the machinery.
4341 (define_insn_and_split "*fix_trunchi_1"
4342 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4343 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4344 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4345 && !reload_completed && !reload_in_progress
4346 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4347 "#"
4348 ""
4349 [(const_int 0)]
4350 {
4351 operands[2] = assign_386_stack_local (HImode, 1);
4352 operands[3] = assign_386_stack_local (HImode, 2);
4353 if (memory_operand (operands[0], VOIDmode))
4354 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4355 operands[2], operands[3]));
4356 else
4357 {
4358 operands[4] = assign_386_stack_local (HImode, 0);
4359 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4360 operands[2], operands[3],
4361 operands[4]));
4362 }
4363 DONE;
4364 }
4365 [(set_attr "type" "fistp")])
4366
4367 (define_insn "fix_trunchi_nomemory"
4368 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4369 (fix:HI (match_operand 1 "register_operand" "f,f")))
4370 (use (match_operand:HI 2 "memory_operand" "m,m"))
4371 (use (match_operand:HI 3 "memory_operand" "m,m"))
4372 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4373 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4374 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4375 "#"
4376 [(set_attr "type" "fistp")])
4377
4378 (define_insn "fix_trunchi_memory"
4379 [(set (match_operand:HI 0 "memory_operand" "=m")
4380 (fix:HI (match_operand 1 "register_operand" "f")))
4381 (use (match_operand:HI 2 "memory_operand" "m"))
4382 (use (match_operand:HI 3 "memory_operand" "m"))]
4383 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4384 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4385 "* return output_fix_trunc (insn, operands);"
4386 [(set_attr "type" "fistp")])
4387
4388 (define_split
4389 [(set (match_operand:HI 0 "memory_operand" "")
4390 (fix:HI (match_operand 1 "register_operand" "")))
4391 (use (match_operand:HI 2 "memory_operand" ""))
4392 (use (match_operand:HI 3 "memory_operand" ""))
4393 (clobber (match_operand:HI 4 "memory_operand" ""))]
4394 "reload_completed"
4395 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4396 (use (match_dup 2))
4397 (use (match_dup 3))])]
4398 "")
4399
4400 (define_split
4401 [(set (match_operand:HI 0 "register_operand" "")
4402 (fix:HI (match_operand 1 "register_operand" "")))
4403 (use (match_operand:HI 2 "memory_operand" ""))
4404 (use (match_operand:HI 3 "memory_operand" ""))
4405 (clobber (match_operand:HI 4 "memory_operand" ""))]
4406 "reload_completed"
4407 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4408 (use (match_dup 2))
4409 (use (match_dup 3))
4410 (clobber (match_dup 4))])
4411 (set (match_dup 0) (match_dup 4))]
4412 "")
4413
4414 ;; %% Not used yet.
4415 (define_insn "x86_fnstcw_1"
4416 [(set (match_operand:HI 0 "memory_operand" "=m")
4417 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4418 "TARGET_80387"
4419 "fnstcw\t%0"
4420 [(set_attr "length" "2")
4421 (set_attr "mode" "HI")
4422 (set_attr "unit" "i387")
4423 (set_attr "ppro_uops" "few")])
4424
4425 (define_insn "x86_fldcw_1"
4426 [(set (reg:HI 18)
4427 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4428 "TARGET_80387"
4429 "fldcw\t%0"
4430 [(set_attr "length" "2")
4431 (set_attr "mode" "HI")
4432 (set_attr "unit" "i387")
4433 (set_attr "athlon_decode" "vector")
4434 (set_attr "ppro_uops" "few")])
4435 \f
4436 ;; Conversion between fixed point and floating point.
4437
4438 ;; Even though we only accept memory inputs, the backend _really_
4439 ;; wants to be able to do this between registers.
4440
4441 (define_insn "floathisf2"
4442 [(set (match_operand:SF 0 "register_operand" "=f,f")
4443 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4444 "TARGET_80387 && !TARGET_SSE"
4445 "@
4446 fild%z1\t%1
4447 #"
4448 [(set_attr "type" "fmov,multi")
4449 (set_attr "mode" "SF")
4450 (set_attr "fp_int_src" "true")])
4451
4452 (define_expand "floatsisf2"
4453 [(set (match_operand:SF 0 "register_operand" "")
4454 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4455 "TARGET_SSE || TARGET_80387"
4456 "")
4457
4458 (define_insn "*floatsisf2_i387"
4459 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
4460 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4461 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4462 "@
4463 fild%z1\t%1
4464 #
4465 cvtsi2ss\t{%1, %0|%0, %1}"
4466 [(set_attr "type" "fmov,multi,ssecvt")
4467 (set_attr "mode" "SF")
4468 (set_attr "fp_int_src" "true")])
4469
4470 (define_insn "*floatsisf2_sse"
4471 [(set (match_operand:SF 0 "register_operand" "=x")
4472 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4473 "TARGET_SSE"
4474 "cvtsi2ss\t{%1, %0|%0, %1}"
4475 [(set_attr "type" "ssecvt")
4476 (set_attr "mode" "SF")
4477 (set_attr "fp_int_src" "true")])
4478
4479 (define_expand "floatdisf2"
4480 [(set (match_operand:SF 0 "register_operand" "")
4481 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4482 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4483 "")
4484
4485 (define_insn "*floatdisf2_i387_only"
4486 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4487 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4488 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4489 "@
4490 fild%z1\t%1
4491 #"
4492 [(set_attr "type" "fmov,multi")
4493 (set_attr "mode" "SF")
4494 (set_attr "fp_int_src" "true")])
4495
4496 (define_insn "*floatdisf2_i387"
4497 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
4498 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
4499 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4500 "@
4501 fild%z1\t%1
4502 #
4503 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4504 [(set_attr "type" "fmov,multi,ssecvt")
4505 (set_attr "mode" "SF")
4506 (set_attr "fp_int_src" "true")])
4507
4508 (define_insn "*floatdisf2_sse"
4509 [(set (match_operand:SF 0 "register_operand" "=x")
4510 (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
4511 "TARGET_64BIT && TARGET_SSE"
4512 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4513 [(set_attr "type" "ssecvt")
4514 (set_attr "mode" "SF")
4515 (set_attr "fp_int_src" "true")])
4516
4517 (define_insn "floathidf2"
4518 [(set (match_operand:DF 0 "register_operand" "=f,f")
4519 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4520 "TARGET_80387 && !TARGET_SSE2"
4521 "@
4522 fild%z1\t%1
4523 #"
4524 [(set_attr "type" "fmov,multi")
4525 (set_attr "mode" "DF")
4526 (set_attr "fp_int_src" "true")])
4527
4528 (define_expand "floatsidf2"
4529 [(set (match_operand:DF 0 "register_operand" "")
4530 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4531 "TARGET_80387 || TARGET_SSE2"
4532 "")
4533
4534 (define_insn "*floatsidf2_i387"
4535 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
4536 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4537 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4538 "@
4539 fild%z1\t%1
4540 #
4541 cvtsi2sd\t{%1, %0|%0, %1}"
4542 [(set_attr "type" "fmov,multi,ssecvt")
4543 (set_attr "mode" "DF")
4544 (set_attr "fp_int_src" "true")])
4545
4546 (define_insn "*floatsidf2_sse"
4547 [(set (match_operand:DF 0 "register_operand" "=Y")
4548 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4549 "TARGET_SSE2"
4550 "cvtsi2sd\t{%1, %0|%0, %1}"
4551 [(set_attr "type" "ssecvt")
4552 (set_attr "mode" "DF")
4553 (set_attr "fp_int_src" "true")])
4554
4555 (define_expand "floatdidf2"
4556 [(set (match_operand:DF 0 "register_operand" "")
4557 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4558 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4559 "")
4560
4561 (define_insn "*floatdidf2_i387_only"
4562 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4563 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4564 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4565 "@
4566 fild%z1\t%1
4567 #"
4568 [(set_attr "type" "fmov,multi")
4569 (set_attr "mode" "DF")
4570 (set_attr "fp_int_src" "true")])
4571
4572 (define_insn "*floatdidf2_i387"
4573 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
4574 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
4575 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4576 "@
4577 fild%z1\t%1
4578 #
4579 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4580 [(set_attr "type" "fmov,multi,ssecvt")
4581 (set_attr "mode" "DF")
4582 (set_attr "fp_int_src" "true")])
4583
4584 (define_insn "*floatdidf2_sse"
4585 [(set (match_operand:DF 0 "register_operand" "=Y")
4586 (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
4587 "TARGET_SSE2"
4588 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4589 [(set_attr "type" "ssecvt")
4590 (set_attr "mode" "DF")
4591 (set_attr "fp_int_src" "true")])
4592
4593 (define_insn "floathixf2"
4594 [(set (match_operand:XF 0 "register_operand" "=f,f")
4595 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4596 "!TARGET_64BIT && TARGET_80387"
4597 "@
4598 fild%z1\t%1
4599 #"
4600 [(set_attr "type" "fmov,multi")
4601 (set_attr "mode" "XF")
4602 (set_attr "fp_int_src" "true")])
4603
4604 (define_insn "floathitf2"
4605 [(set (match_operand:TF 0 "register_operand" "=f,f")
4606 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4607 "TARGET_80387"
4608 "@
4609 fild%z1\t%1
4610 #"
4611 [(set_attr "type" "fmov,multi")
4612 (set_attr "mode" "XF")
4613 (set_attr "fp_int_src" "true")])
4614
4615 (define_insn "floatsixf2"
4616 [(set (match_operand:XF 0 "register_operand" "=f,f")
4617 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4618 "!TARGET_64BIT && TARGET_80387"
4619 "@
4620 fild%z1\t%1
4621 #"
4622 [(set_attr "type" "fmov,multi")
4623 (set_attr "mode" "XF")
4624 (set_attr "fp_int_src" "true")])
4625
4626 (define_insn "floatsitf2"
4627 [(set (match_operand:TF 0 "register_operand" "=f,f")
4628 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4629 "TARGET_80387"
4630 "@
4631 fild%z1\t%1
4632 #"
4633 [(set_attr "type" "fmov,multi")
4634 (set_attr "mode" "XF")
4635 (set_attr "fp_int_src" "true")])
4636
4637 (define_insn "floatdixf2"
4638 [(set (match_operand:XF 0 "register_operand" "=f,f")
4639 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4640 "!TARGET_64BIT && TARGET_80387"
4641 "@
4642 fild%z1\t%1
4643 #"
4644 [(set_attr "type" "fmov,multi")
4645 (set_attr "mode" "XF")
4646 (set_attr "fp_int_src" "true")])
4647
4648 (define_insn "floatditf2"
4649 [(set (match_operand:TF 0 "register_operand" "=f,f")
4650 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4651 "TARGET_80387"
4652 "@
4653 fild%z1\t%1
4654 #"
4655 [(set_attr "type" "fmov,multi")
4656 (set_attr "mode" "XF")
4657 (set_attr "fp_int_src" "true")])
4658
4659 ;; %%% Kill these when reload knows how to do it.
4660 (define_split
4661 [(set (match_operand 0 "register_operand" "")
4662 (float (match_operand 1 "register_operand" "")))]
4663 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
4664 && FP_REG_P (operands[0])"
4665 [(const_int 0)]
4666 {
4667 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4668 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4669 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4670 ix86_free_from_memory (GET_MODE (operands[1]));
4671 DONE;
4672 })
4673 \f
4674 ;; Add instructions
4675
4676 ;; %%% splits for addsidi3
4677 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4678 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4679 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4680
4681 (define_expand "adddi3"
4682 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4683 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4684 (match_operand:DI 2 "x86_64_general_operand" "")))
4685 (clobber (reg:CC 17))]
4686 ""
4687 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4688
4689 (define_insn "*adddi3_1"
4690 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4691 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4692 (match_operand:DI 2 "general_operand" "roiF,riF")))
4693 (clobber (reg:CC 17))]
4694 "!TARGET_64BIT"
4695 "#")
4696
4697 (define_split
4698 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4699 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4700 (match_operand:DI 2 "general_operand" "")))
4701 (clobber (reg:CC 17))]
4702 "!TARGET_64BIT && reload_completed"
4703 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4704 UNSPEC_ADD_CARRY))
4705 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4706 (parallel [(set (match_dup 3)
4707 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4708 (match_dup 4))
4709 (match_dup 5)))
4710 (clobber (reg:CC 17))])]
4711 "split_di (operands+0, 1, operands+0, operands+3);
4712 split_di (operands+1, 1, operands+1, operands+4);
4713 split_di (operands+2, 1, operands+2, operands+5);")
4714
4715 (define_insn "*adddi3_carry_rex64"
4716 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4717 (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
4718 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4719 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4720 (clobber (reg:CC 17))]
4721 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4722 "adc{q}\t{%2, %0|%0, %2}"
4723 [(set_attr "type" "alu")
4724 (set_attr "pent_pair" "pu")
4725 (set_attr "mode" "DI")
4726 (set_attr "ppro_uops" "few")])
4727
4728 (define_insn "*adddi3_cc_rex64"
4729 [(set (reg:CC 17)
4730 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4731 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4732 UNSPEC_ADD_CARRY))
4733 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4734 (plus:DI (match_dup 1) (match_dup 2)))]
4735 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4736 "add{q}\t{%2, %0|%0, %2}"
4737 [(set_attr "type" "alu")
4738 (set_attr "mode" "DI")])
4739
4740 (define_insn "*addsi3_carry"
4741 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4742 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4743 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4744 (match_operand:SI 2 "general_operand" "ri,rm")))
4745 (clobber (reg:CC 17))]
4746 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4747 "adc{l}\t{%2, %0|%0, %2}"
4748 [(set_attr "type" "alu")
4749 (set_attr "pent_pair" "pu")
4750 (set_attr "mode" "SI")
4751 (set_attr "ppro_uops" "few")])
4752
4753 (define_insn "*addsi3_carry_zext"
4754 [(set (match_operand:DI 0 "register_operand" "=r")
4755 (zero_extend:DI
4756 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4757 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4758 (match_operand:SI 2 "general_operand" "rim"))))
4759 (clobber (reg:CC 17))]
4760 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4761 "adc{l}\t{%2, %k0|%k0, %2}"
4762 [(set_attr "type" "alu")
4763 (set_attr "pent_pair" "pu")
4764 (set_attr "mode" "SI")
4765 (set_attr "ppro_uops" "few")])
4766
4767 (define_insn "*addsi3_cc"
4768 [(set (reg:CC 17)
4769 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4770 (match_operand:SI 2 "general_operand" "ri,rm")]
4771 UNSPEC_ADD_CARRY))
4772 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4773 (plus:SI (match_dup 1) (match_dup 2)))]
4774 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4775 "add{l}\t{%2, %0|%0, %2}"
4776 [(set_attr "type" "alu")
4777 (set_attr "mode" "SI")])
4778
4779 (define_insn "addqi3_cc"
4780 [(set (reg:CC 17)
4781 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4782 (match_operand:QI 2 "general_operand" "qi,qm")]
4783 UNSPEC_ADD_CARRY))
4784 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4785 (plus:QI (match_dup 1) (match_dup 2)))]
4786 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4787 "add{b}\t{%2, %0|%0, %2}"
4788 [(set_attr "type" "alu")
4789 (set_attr "mode" "QI")])
4790
4791 (define_expand "addsi3"
4792 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4793 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4794 (match_operand:SI 2 "general_operand" "")))
4795 (clobber (reg:CC 17))])]
4796 ""
4797 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4798
4799 (define_insn "*lea_1"
4800 [(set (match_operand:SI 0 "register_operand" "=r")
4801 (match_operand:SI 1 "address_operand" "p"))]
4802 "!TARGET_64BIT"
4803 "lea{l}\t{%a1, %0|%0, %a1}"
4804 [(set_attr "type" "lea")
4805 (set_attr "mode" "SI")])
4806
4807 (define_insn "*lea_1_rex64"
4808 [(set (match_operand:SI 0 "register_operand" "=r")
4809 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
4810 "TARGET_64BIT"
4811 "lea{l}\t{%a1, %0|%0, %a1}"
4812 [(set_attr "type" "lea")
4813 (set_attr "mode" "SI")])
4814
4815 (define_insn "*lea_1_zext"
4816 [(set (match_operand:DI 0 "register_operand" "=r")
4817 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
4818 "TARGET_64BIT"
4819 "lea{l}\t{%a1, %k0|%k0, %a1}"
4820 [(set_attr "type" "lea")
4821 (set_attr "mode" "SI")])
4822
4823 (define_insn "*lea_2_rex64"
4824 [(set (match_operand:DI 0 "register_operand" "=r")
4825 (match_operand:DI 1 "address_operand" "p"))]
4826 "TARGET_64BIT"
4827 "lea{q}\t{%a1, %0|%0, %a1}"
4828 [(set_attr "type" "lea")
4829 (set_attr "mode" "DI")])
4830
4831 ;; The lea patterns for non-Pmodes needs to be matched by several
4832 ;; insns converted to real lea by splitters.
4833
4834 (define_insn_and_split "*lea_general_1"
4835 [(set (match_operand 0 "register_operand" "=r")
4836 (plus (plus (match_operand 1 "register_operand" "r")
4837 (match_operand 2 "register_operand" "r"))
4838 (match_operand 3 "immediate_operand" "i")))]
4839 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4840 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4841 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4842 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4843 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4844 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4845 || GET_MODE (operands[3]) == VOIDmode)"
4846 "#"
4847 "&& reload_completed"
4848 [(const_int 0)]
4849 {
4850 rtx pat;
4851 operands[0] = gen_lowpart (SImode, operands[0]);
4852 operands[1] = gen_lowpart (Pmode, operands[1]);
4853 operands[2] = gen_lowpart (Pmode, operands[2]);
4854 operands[3] = gen_lowpart (Pmode, operands[3]);
4855 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4856 operands[3]);
4857 if (Pmode != SImode)
4858 pat = gen_rtx_SUBREG (SImode, pat, 0);
4859 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4860 DONE;
4861 }
4862 [(set_attr "type" "lea")
4863 (set_attr "mode" "SI")])
4864
4865 (define_insn_and_split "*lea_general_1_zext"
4866 [(set (match_operand:DI 0 "register_operand" "=r")
4867 (zero_extend:DI
4868 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
4869 (match_operand:SI 2 "register_operand" "r"))
4870 (match_operand:SI 3 "immediate_operand" "i"))))]
4871 "TARGET_64BIT"
4872 "#"
4873 "&& reload_completed"
4874 [(set (match_dup 0)
4875 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4876 (match_dup 2))
4877 (match_dup 3)) 0)))]
4878 {
4879 operands[1] = gen_lowpart (Pmode, operands[1]);
4880 operands[2] = gen_lowpart (Pmode, operands[2]);
4881 operands[3] = gen_lowpart (Pmode, operands[3]);
4882 }
4883 [(set_attr "type" "lea")
4884 (set_attr "mode" "SI")])
4885
4886 (define_insn_and_split "*lea_general_2"
4887 [(set (match_operand 0 "register_operand" "=r")
4888 (plus (mult (match_operand 1 "register_operand" "r")
4889 (match_operand 2 "const248_operand" "i"))
4890 (match_operand 3 "nonmemory_operand" "ri")))]
4891 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4892 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4893 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4894 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4895 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4896 || GET_MODE (operands[3]) == VOIDmode)"
4897 "#"
4898 "&& reload_completed"
4899 [(const_int 0)]
4900 {
4901 rtx pat;
4902 operands[0] = gen_lowpart (SImode, operands[0]);
4903 operands[1] = gen_lowpart (Pmode, operands[1]);
4904 operands[3] = gen_lowpart (Pmode, operands[3]);
4905 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4906 operands[3]);
4907 if (Pmode != SImode)
4908 pat = gen_rtx_SUBREG (SImode, pat, 0);
4909 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4910 DONE;
4911 }
4912 [(set_attr "type" "lea")
4913 (set_attr "mode" "SI")])
4914
4915 (define_insn_and_split "*lea_general_2_zext"
4916 [(set (match_operand:DI 0 "register_operand" "=r")
4917 (zero_extend:DI
4918 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
4919 (match_operand:SI 2 "const248_operand" "n"))
4920 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4921 "TARGET_64BIT"
4922 "#"
4923 "&& reload_completed"
4924 [(set (match_dup 0)
4925 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4926 (match_dup 2))
4927 (match_dup 3)) 0)))]
4928 {
4929 operands[1] = gen_lowpart (Pmode, operands[1]);
4930 operands[3] = gen_lowpart (Pmode, operands[3]);
4931 }
4932 [(set_attr "type" "lea")
4933 (set_attr "mode" "SI")])
4934
4935 (define_insn_and_split "*lea_general_3"
4936 [(set (match_operand 0 "register_operand" "=r")
4937 (plus (plus (mult (match_operand 1 "register_operand" "r")
4938 (match_operand 2 "const248_operand" "i"))
4939 (match_operand 3 "register_operand" "r"))
4940 (match_operand 4 "immediate_operand" "i")))]
4941 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4942 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4944 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4945 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4946 "#"
4947 "&& reload_completed"
4948 [(const_int 0)]
4949 {
4950 rtx pat;
4951 operands[0] = gen_lowpart (SImode, operands[0]);
4952 operands[1] = gen_lowpart (Pmode, operands[1]);
4953 operands[3] = gen_lowpart (Pmode, operands[3]);
4954 operands[4] = gen_lowpart (Pmode, operands[4]);
4955 pat = gen_rtx_PLUS (Pmode,
4956 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4957 operands[2]),
4958 operands[3]),
4959 operands[4]);
4960 if (Pmode != SImode)
4961 pat = gen_rtx_SUBREG (SImode, pat, 0);
4962 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4963 DONE;
4964 }
4965 [(set_attr "type" "lea")
4966 (set_attr "mode" "SI")])
4967
4968 (define_insn_and_split "*lea_general_3_zext"
4969 [(set (match_operand:DI 0 "register_operand" "=r")
4970 (zero_extend:DI
4971 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
4972 (match_operand:SI 2 "const248_operand" "n"))
4973 (match_operand:SI 3 "register_operand" "r"))
4974 (match_operand:SI 4 "immediate_operand" "i"))))]
4975 "TARGET_64BIT"
4976 "#"
4977 "&& reload_completed"
4978 [(set (match_dup 0)
4979 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
4980 (match_dup 2))
4981 (match_dup 3))
4982 (match_dup 4)) 0)))]
4983 {
4984 operands[1] = gen_lowpart (Pmode, operands[1]);
4985 operands[3] = gen_lowpart (Pmode, operands[3]);
4986 operands[4] = gen_lowpart (Pmode, operands[4]);
4987 }
4988 [(set_attr "type" "lea")
4989 (set_attr "mode" "SI")])
4990
4991 (define_insn "*adddi_1_rex64"
4992 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
4993 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
4994 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
4995 (clobber (reg:CC 17))]
4996 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4997 {
4998 switch (get_attr_type (insn))
4999 {
5000 case TYPE_LEA:
5001 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5002 return "lea{q}\t{%a2, %0|%0, %a2}";
5003
5004 case TYPE_INCDEC:
5005 if (! rtx_equal_p (operands[0], operands[1]))
5006 abort ();
5007 if (operands[2] == const1_rtx)
5008 return "inc{q}\t%0";
5009 else if (operands[2] == constm1_rtx)
5010 return "dec{q}\t%0";
5011 else
5012 abort ();
5013
5014 default:
5015 if (! rtx_equal_p (operands[0], operands[1]))
5016 abort ();
5017
5018 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5019 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5020 if (GET_CODE (operands[2]) == CONST_INT
5021 /* Avoid overflows. */
5022 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5023 && (INTVAL (operands[2]) == 128
5024 || (INTVAL (operands[2]) < 0
5025 && INTVAL (operands[2]) != -128)))
5026 {
5027 operands[2] = GEN_INT (-INTVAL (operands[2]));
5028 return "sub{q}\t{%2, %0|%0, %2}";
5029 }
5030 return "add{q}\t{%2, %0|%0, %2}";
5031 }
5032 }
5033 [(set (attr "type")
5034 (cond [(eq_attr "alternative" "2")
5035 (const_string "lea")
5036 ; Current assemblers are broken and do not allow @GOTOFF in
5037 ; ought but a memory context.
5038 (match_operand:DI 2 "pic_symbolic_operand" "")
5039 (const_string "lea")
5040 (match_operand:DI 2 "incdec_operand" "")
5041 (const_string "incdec")
5042 ]
5043 (const_string "alu")))
5044 (set_attr "mode" "DI")])
5045
5046 ;; Convert lea to the lea pattern to avoid flags dependency.
5047 (define_split
5048 [(set (match_operand:DI 0 "register_operand" "")
5049 (plus:DI (match_operand:DI 1 "register_operand" "")
5050 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5051 (clobber (reg:CC 17))]
5052 "TARGET_64BIT && reload_completed
5053 && true_regnum (operands[0]) != true_regnum (operands[1])"
5054 [(set (match_dup 0)
5055 (plus:DI (match_dup 1)
5056 (match_dup 2)))]
5057 "")
5058
5059 (define_insn "*adddi_2_rex64"
5060 [(set (reg 17)
5061 (compare
5062 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5063 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5064 (const_int 0)))
5065 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5066 (plus:DI (match_dup 1) (match_dup 2)))]
5067 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5068 && ix86_binary_operator_ok (PLUS, DImode, operands)
5069 /* Current assemblers are broken and do not allow @GOTOFF in
5070 ought but a memory context. */
5071 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5072 {
5073 switch (get_attr_type (insn))
5074 {
5075 case TYPE_INCDEC:
5076 if (! rtx_equal_p (operands[0], operands[1]))
5077 abort ();
5078 if (operands[2] == const1_rtx)
5079 return "inc{q}\t%0";
5080 else if (operands[2] == constm1_rtx)
5081 return "dec{q}\t%0";
5082 else
5083 abort ();
5084
5085 default:
5086 if (! rtx_equal_p (operands[0], operands[1]))
5087 abort ();
5088 /* ???? We ought to handle there the 32bit case too
5089 - do we need new constrant? */
5090 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5091 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5092 if (GET_CODE (operands[2]) == CONST_INT
5093 /* Avoid overflows. */
5094 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5095 && (INTVAL (operands[2]) == 128
5096 || (INTVAL (operands[2]) < 0
5097 && INTVAL (operands[2]) != -128)))
5098 {
5099 operands[2] = GEN_INT (-INTVAL (operands[2]));
5100 return "sub{q}\t{%2, %0|%0, %2}";
5101 }
5102 return "add{q}\t{%2, %0|%0, %2}";
5103 }
5104 }
5105 [(set (attr "type")
5106 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5107 (const_string "incdec")
5108 (const_string "alu")))
5109 (set_attr "mode" "DI")])
5110
5111 (define_insn "*adddi_3_rex64"
5112 [(set (reg 17)
5113 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5114 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5115 (clobber (match_scratch:DI 0 "=r"))]
5116 "TARGET_64BIT
5117 && ix86_match_ccmode (insn, CCZmode)
5118 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5119 /* Current assemblers are broken and do not allow @GOTOFF in
5120 ought but a memory context. */
5121 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5122 {
5123 switch (get_attr_type (insn))
5124 {
5125 case TYPE_INCDEC:
5126 if (! rtx_equal_p (operands[0], operands[1]))
5127 abort ();
5128 if (operands[2] == const1_rtx)
5129 return "inc{q}\t%0";
5130 else if (operands[2] == constm1_rtx)
5131 return "dec{q}\t%0";
5132 else
5133 abort ();
5134
5135 default:
5136 if (! rtx_equal_p (operands[0], operands[1]))
5137 abort ();
5138 /* ???? We ought to handle there the 32bit case too
5139 - do we need new constrant? */
5140 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5141 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5142 if (GET_CODE (operands[2]) == CONST_INT
5143 /* Avoid overflows. */
5144 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5145 && (INTVAL (operands[2]) == 128
5146 || (INTVAL (operands[2]) < 0
5147 && INTVAL (operands[2]) != -128)))
5148 {
5149 operands[2] = GEN_INT (-INTVAL (operands[2]));
5150 return "sub{q}\t{%2, %0|%0, %2}";
5151 }
5152 return "add{q}\t{%2, %0|%0, %2}";
5153 }
5154 }
5155 [(set (attr "type")
5156 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5157 (const_string "incdec")
5158 (const_string "alu")))
5159 (set_attr "mode" "DI")])
5160
5161 ; For comparisons against 1, -1 and 128, we may generate better code
5162 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5163 ; is matched then. We can't accept general immediate, because for
5164 ; case of overflows, the result is messed up.
5165 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5166 ; when negated.
5167 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5168 ; only for comparisons not depending on it.
5169 (define_insn "*adddi_4_rex64"
5170 [(set (reg 17)
5171 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5172 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5173 (clobber (match_scratch:DI 0 "=rm"))]
5174 "TARGET_64BIT
5175 && ix86_match_ccmode (insn, CCGCmode)"
5176 {
5177 switch (get_attr_type (insn))
5178 {
5179 case TYPE_INCDEC:
5180 if (operands[2] == constm1_rtx)
5181 return "inc{q}\t%0";
5182 else if (operands[2] == const1_rtx)
5183 return "dec{q}\t%0";
5184 else
5185 abort();
5186
5187 default:
5188 if (! rtx_equal_p (operands[0], operands[1]))
5189 abort ();
5190 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5191 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5192 if ((INTVAL (operands[2]) == -128
5193 || (INTVAL (operands[2]) > 0
5194 && INTVAL (operands[2]) != 128))
5195 /* Avoid overflows. */
5196 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5197 return "sub{q}\t{%2, %0|%0, %2}";
5198 operands[2] = GEN_INT (-INTVAL (operands[2]));
5199 return "add{q}\t{%2, %0|%0, %2}";
5200 }
5201 }
5202 [(set (attr "type")
5203 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5204 (const_string "incdec")
5205 (const_string "alu")))
5206 (set_attr "mode" "DI")])
5207
5208 (define_insn "*adddi_5_rex64"
5209 [(set (reg 17)
5210 (compare
5211 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5212 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5213 (const_int 0)))
5214 (clobber (match_scratch:DI 0 "=r"))]
5215 "TARGET_64BIT
5216 && ix86_match_ccmode (insn, CCGOCmode)
5217 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5218 /* Current assemblers are broken and do not allow @GOTOFF in
5219 ought but a memory context. */
5220 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5221 {
5222 switch (get_attr_type (insn))
5223 {
5224 case TYPE_INCDEC:
5225 if (! rtx_equal_p (operands[0], operands[1]))
5226 abort ();
5227 if (operands[2] == const1_rtx)
5228 return "inc{q}\t%0";
5229 else if (operands[2] == constm1_rtx)
5230 return "dec{q}\t%0";
5231 else
5232 abort();
5233
5234 default:
5235 if (! rtx_equal_p (operands[0], operands[1]))
5236 abort ();
5237 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5238 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5239 if (GET_CODE (operands[2]) == CONST_INT
5240 /* Avoid overflows. */
5241 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5242 && (INTVAL (operands[2]) == 128
5243 || (INTVAL (operands[2]) < 0
5244 && INTVAL (operands[2]) != -128)))
5245 {
5246 operands[2] = GEN_INT (-INTVAL (operands[2]));
5247 return "sub{q}\t{%2, %0|%0, %2}";
5248 }
5249 return "add{q}\t{%2, %0|%0, %2}";
5250 }
5251 }
5252 [(set (attr "type")
5253 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5254 (const_string "incdec")
5255 (const_string "alu")))
5256 (set_attr "mode" "DI")])
5257
5258
5259 (define_insn "*addsi_1"
5260 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5261 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5262 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5263 (clobber (reg:CC 17))]
5264 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5265 {
5266 switch (get_attr_type (insn))
5267 {
5268 case TYPE_LEA:
5269 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5270 return "lea{l}\t{%a2, %0|%0, %a2}";
5271
5272 case TYPE_INCDEC:
5273 if (! rtx_equal_p (operands[0], operands[1]))
5274 abort ();
5275 if (operands[2] == const1_rtx)
5276 return "inc{l}\t%0";
5277 else if (operands[2] == constm1_rtx)
5278 return "dec{l}\t%0";
5279 else
5280 abort();
5281
5282 default:
5283 if (! rtx_equal_p (operands[0], operands[1]))
5284 abort ();
5285
5286 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5287 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5288 if (GET_CODE (operands[2]) == CONST_INT
5289 && (INTVAL (operands[2]) == 128
5290 || (INTVAL (operands[2]) < 0
5291 && INTVAL (operands[2]) != -128)))
5292 {
5293 operands[2] = GEN_INT (-INTVAL (operands[2]));
5294 return "sub{l}\t{%2, %0|%0, %2}";
5295 }
5296 return "add{l}\t{%2, %0|%0, %2}";
5297 }
5298 }
5299 [(set (attr "type")
5300 (cond [(eq_attr "alternative" "2")
5301 (const_string "lea")
5302 ; Current assemblers are broken and do not allow @GOTOFF in
5303 ; ought but a memory context.
5304 (match_operand:SI 2 "pic_symbolic_operand" "")
5305 (const_string "lea")
5306 (match_operand:SI 2 "incdec_operand" "")
5307 (const_string "incdec")
5308 ]
5309 (const_string "alu")))
5310 (set_attr "mode" "SI")])
5311
5312 ;; Convert lea to the lea pattern to avoid flags dependency.
5313 (define_split
5314 [(set (match_operand 0 "register_operand" "")
5315 (plus (match_operand 1 "register_operand" "")
5316 (match_operand 2 "nonmemory_operand" "")))
5317 (clobber (reg:CC 17))]
5318 "reload_completed
5319 && true_regnum (operands[0]) != true_regnum (operands[1])"
5320 [(const_int 0)]
5321 {
5322 rtx pat;
5323 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5324 may confuse gen_lowpart. */
5325 if (GET_MODE (operands[0]) != Pmode)
5326 {
5327 operands[1] = gen_lowpart (Pmode, operands[1]);
5328 operands[2] = gen_lowpart (Pmode, operands[2]);
5329 }
5330 operands[0] = gen_lowpart (SImode, operands[0]);
5331 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5332 if (Pmode != SImode)
5333 pat = gen_rtx_SUBREG (SImode, pat, 0);
5334 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5335 DONE;
5336 })
5337
5338 ;; It may seem that nonimmediate operand is proper one for operand 1.
5339 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5340 ;; we take care in ix86_binary_operator_ok to not allow two memory
5341 ;; operands so proper swapping will be done in reload. This allow
5342 ;; patterns constructed from addsi_1 to match.
5343 (define_insn "addsi_1_zext"
5344 [(set (match_operand:DI 0 "register_operand" "=r,r")
5345 (zero_extend:DI
5346 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5347 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5348 (clobber (reg:CC 17))]
5349 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5350 {
5351 switch (get_attr_type (insn))
5352 {
5353 case TYPE_LEA:
5354 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5356
5357 case TYPE_INCDEC:
5358 if (operands[2] == const1_rtx)
5359 return "inc{l}\t%k0";
5360 else if (operands[2] == constm1_rtx)
5361 return "dec{l}\t%k0";
5362 else
5363 abort();
5364
5365 default:
5366 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5367 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5368 if (GET_CODE (operands[2]) == CONST_INT
5369 && (INTVAL (operands[2]) == 128
5370 || (INTVAL (operands[2]) < 0
5371 && INTVAL (operands[2]) != -128)))
5372 {
5373 operands[2] = GEN_INT (-INTVAL (operands[2]));
5374 return "sub{l}\t{%2, %k0|%k0, %2}";
5375 }
5376 return "add{l}\t{%2, %k0|%k0, %2}";
5377 }
5378 }
5379 [(set (attr "type")
5380 (cond [(eq_attr "alternative" "1")
5381 (const_string "lea")
5382 ; Current assemblers are broken and do not allow @GOTOFF in
5383 ; ought but a memory context.
5384 (match_operand:SI 2 "pic_symbolic_operand" "")
5385 (const_string "lea")
5386 (match_operand:SI 2 "incdec_operand" "")
5387 (const_string "incdec")
5388 ]
5389 (const_string "alu")))
5390 (set_attr "mode" "SI")])
5391
5392 ;; Convert lea to the lea pattern to avoid flags dependency.
5393 (define_split
5394 [(set (match_operand:DI 0 "register_operand" "")
5395 (zero_extend:DI
5396 (plus:SI (match_operand:SI 1 "register_operand" "")
5397 (match_operand:SI 2 "nonmemory_operand" ""))))
5398 (clobber (reg:CC 17))]
5399 "reload_completed
5400 && true_regnum (operands[0]) != true_regnum (operands[1])"
5401 [(set (match_dup 0)
5402 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5403 {
5404 operands[1] = gen_lowpart (Pmode, operands[1]);
5405 operands[2] = gen_lowpart (Pmode, operands[2]);
5406 })
5407
5408 (define_insn "*addsi_2"
5409 [(set (reg 17)
5410 (compare
5411 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5412 (match_operand:SI 2 "general_operand" "rmni,rni"))
5413 (const_int 0)))
5414 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5415 (plus:SI (match_dup 1) (match_dup 2)))]
5416 "ix86_match_ccmode (insn, CCGOCmode)
5417 && ix86_binary_operator_ok (PLUS, SImode, operands)
5418 /* Current assemblers are broken and do not allow @GOTOFF in
5419 ought but a memory context. */
5420 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5421 {
5422 switch (get_attr_type (insn))
5423 {
5424 case TYPE_INCDEC:
5425 if (! rtx_equal_p (operands[0], operands[1]))
5426 abort ();
5427 if (operands[2] == const1_rtx)
5428 return "inc{l}\t%0";
5429 else if (operands[2] == constm1_rtx)
5430 return "dec{l}\t%0";
5431 else
5432 abort();
5433
5434 default:
5435 if (! rtx_equal_p (operands[0], operands[1]))
5436 abort ();
5437 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5438 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5439 if (GET_CODE (operands[2]) == CONST_INT
5440 && (INTVAL (operands[2]) == 128
5441 || (INTVAL (operands[2]) < 0
5442 && INTVAL (operands[2]) != -128)))
5443 {
5444 operands[2] = GEN_INT (-INTVAL (operands[2]));
5445 return "sub{l}\t{%2, %0|%0, %2}";
5446 }
5447 return "add{l}\t{%2, %0|%0, %2}";
5448 }
5449 }
5450 [(set (attr "type")
5451 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5452 (const_string "incdec")
5453 (const_string "alu")))
5454 (set_attr "mode" "SI")])
5455
5456 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5457 (define_insn "*addsi_2_zext"
5458 [(set (reg 17)
5459 (compare
5460 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5461 (match_operand:SI 2 "general_operand" "rmni"))
5462 (const_int 0)))
5463 (set (match_operand:DI 0 "register_operand" "=r")
5464 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5465 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5466 && ix86_binary_operator_ok (PLUS, SImode, operands)
5467 /* Current assemblers are broken and do not allow @GOTOFF in
5468 ought but a memory context. */
5469 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5470 {
5471 switch (get_attr_type (insn))
5472 {
5473 case TYPE_INCDEC:
5474 if (operands[2] == const1_rtx)
5475 return "inc{l}\t%k0";
5476 else if (operands[2] == constm1_rtx)
5477 return "dec{l}\t%k0";
5478 else
5479 abort();
5480
5481 default:
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 && (INTVAL (operands[2]) == 128
5486 || (INTVAL (operands[2]) < 0
5487 && INTVAL (operands[2]) != -128)))
5488 {
5489 operands[2] = GEN_INT (-INTVAL (operands[2]));
5490 return "sub{l}\t{%2, %k0|%k0, %2}";
5491 }
5492 return "add{l}\t{%2, %k0|%k0, %2}";
5493 }
5494 }
5495 [(set (attr "type")
5496 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5497 (const_string "incdec")
5498 (const_string "alu")))
5499 (set_attr "mode" "SI")])
5500
5501 (define_insn "*addsi_3"
5502 [(set (reg 17)
5503 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5504 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5505 (clobber (match_scratch:SI 0 "=r"))]
5506 "ix86_match_ccmode (insn, CCZmode)
5507 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5508 /* Current assemblers are broken and do not allow @GOTOFF in
5509 ought but a memory context. */
5510 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5511 {
5512 switch (get_attr_type (insn))
5513 {
5514 case TYPE_INCDEC:
5515 if (! rtx_equal_p (operands[0], operands[1]))
5516 abort ();
5517 if (operands[2] == const1_rtx)
5518 return "inc{l}\t%0";
5519 else if (operands[2] == constm1_rtx)
5520 return "dec{l}\t%0";
5521 else
5522 abort();
5523
5524 default:
5525 if (! rtx_equal_p (operands[0], operands[1]))
5526 abort ();
5527 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5528 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5529 if (GET_CODE (operands[2]) == CONST_INT
5530 && (INTVAL (operands[2]) == 128
5531 || (INTVAL (operands[2]) < 0
5532 && INTVAL (operands[2]) != -128)))
5533 {
5534 operands[2] = GEN_INT (-INTVAL (operands[2]));
5535 return "sub{l}\t{%2, %0|%0, %2}";
5536 }
5537 return "add{l}\t{%2, %0|%0, %2}";
5538 }
5539 }
5540 [(set (attr "type")
5541 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5542 (const_string "incdec")
5543 (const_string "alu")))
5544 (set_attr "mode" "SI")])
5545
5546 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5547 (define_insn "*addsi_3_zext"
5548 [(set (reg 17)
5549 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5550 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5551 (set (match_operand:DI 0 "register_operand" "=r")
5552 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5553 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5554 && ix86_binary_operator_ok (PLUS, SImode, operands)
5555 /* Current assemblers are broken and do not allow @GOTOFF in
5556 ought but a memory context. */
5557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5558 {
5559 switch (get_attr_type (insn))
5560 {
5561 case TYPE_INCDEC:
5562 if (operands[2] == const1_rtx)
5563 return "inc{l}\t%k0";
5564 else if (operands[2] == constm1_rtx)
5565 return "dec{l}\t%k0";
5566 else
5567 abort();
5568
5569 default:
5570 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5571 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5572 if (GET_CODE (operands[2]) == CONST_INT
5573 && (INTVAL (operands[2]) == 128
5574 || (INTVAL (operands[2]) < 0
5575 && INTVAL (operands[2]) != -128)))
5576 {
5577 operands[2] = GEN_INT (-INTVAL (operands[2]));
5578 return "sub{l}\t{%2, %k0|%k0, %2}";
5579 }
5580 return "add{l}\t{%2, %k0|%k0, %2}";
5581 }
5582 }
5583 [(set (attr "type")
5584 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5585 (const_string "incdec")
5586 (const_string "alu")))
5587 (set_attr "mode" "SI")])
5588
5589 ; For comparisons agains 1, -1 and 128, we may generate better code
5590 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5591 ; is matched then. We can't accept general immediate, because for
5592 ; case of overflows, the result is messed up.
5593 ; This pattern also don't hold of 0x80000000, since the value overflows
5594 ; when negated.
5595 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5596 ; only for comparisons not depending on it.
5597 (define_insn "*addsi_4"
5598 [(set (reg 17)
5599 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5600 (match_operand:SI 2 "const_int_operand" "n")))
5601 (clobber (match_scratch:SI 0 "=rm"))]
5602 "ix86_match_ccmode (insn, CCGCmode)
5603 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5604 {
5605 switch (get_attr_type (insn))
5606 {
5607 case TYPE_INCDEC:
5608 if (operands[2] == constm1_rtx)
5609 return "inc{l}\t%0";
5610 else if (operands[2] == const1_rtx)
5611 return "dec{l}\t%0";
5612 else
5613 abort();
5614
5615 default:
5616 if (! rtx_equal_p (operands[0], operands[1]))
5617 abort ();
5618 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5619 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5620 if ((INTVAL (operands[2]) == -128
5621 || (INTVAL (operands[2]) > 0
5622 && INTVAL (operands[2]) != 128)))
5623 return "sub{l}\t{%2, %0|%0, %2}";
5624 operands[2] = GEN_INT (-INTVAL (operands[2]));
5625 return "add{l}\t{%2, %0|%0, %2}";
5626 }
5627 }
5628 [(set (attr "type")
5629 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630 (const_string "incdec")
5631 (const_string "alu")))
5632 (set_attr "mode" "SI")])
5633
5634 (define_insn "*addsi_5"
5635 [(set (reg 17)
5636 (compare
5637 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5638 (match_operand:SI 2 "general_operand" "rmni"))
5639 (const_int 0)))
5640 (clobber (match_scratch:SI 0 "=r"))]
5641 "ix86_match_ccmode (insn, CCGOCmode)
5642 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5643 /* Current assemblers are broken and do not allow @GOTOFF in
5644 ought but a memory context. */
5645 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5646 {
5647 switch (get_attr_type (insn))
5648 {
5649 case TYPE_INCDEC:
5650 if (! rtx_equal_p (operands[0], operands[1]))
5651 abort ();
5652 if (operands[2] == const1_rtx)
5653 return "inc{l}\t%0";
5654 else if (operands[2] == constm1_rtx)
5655 return "dec{l}\t%0";
5656 else
5657 abort();
5658
5659 default:
5660 if (! rtx_equal_p (operands[0], operands[1]))
5661 abort ();
5662 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5663 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5664 if (GET_CODE (operands[2]) == CONST_INT
5665 && (INTVAL (operands[2]) == 128
5666 || (INTVAL (operands[2]) < 0
5667 && INTVAL (operands[2]) != -128)))
5668 {
5669 operands[2] = GEN_INT (-INTVAL (operands[2]));
5670 return "sub{l}\t{%2, %0|%0, %2}";
5671 }
5672 return "add{l}\t{%2, %0|%0, %2}";
5673 }
5674 }
5675 [(set (attr "type")
5676 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5677 (const_string "incdec")
5678 (const_string "alu")))
5679 (set_attr "mode" "SI")])
5680
5681 (define_expand "addhi3"
5682 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5683 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5684 (match_operand:HI 2 "general_operand" "")))
5685 (clobber (reg:CC 17))])]
5686 "TARGET_HIMODE_MATH"
5687 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5688
5689 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5690 ;; type optimizations enabled by define-splits. This is not important
5691 ;; for PII, and in fact harmful because of partial register stalls.
5692
5693 (define_insn "*addhi_1_lea"
5694 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5695 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5696 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5697 (clobber (reg:CC 17))]
5698 "!TARGET_PARTIAL_REG_STALL
5699 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5700 {
5701 switch (get_attr_type (insn))
5702 {
5703 case TYPE_LEA:
5704 return "#";
5705 case TYPE_INCDEC:
5706 if (operands[2] == const1_rtx)
5707 return "inc{w}\t%0";
5708 else if (operands[2] == constm1_rtx
5709 || (GET_CODE (operands[2]) == CONST_INT
5710 && INTVAL (operands[2]) == 65535))
5711 return "dec{w}\t%0";
5712 abort();
5713
5714 default:
5715 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5716 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5717 if (GET_CODE (operands[2]) == CONST_INT
5718 && (INTVAL (operands[2]) == 128
5719 || (INTVAL (operands[2]) < 0
5720 && INTVAL (operands[2]) != -128)))
5721 {
5722 operands[2] = GEN_INT (-INTVAL (operands[2]));
5723 return "sub{w}\t{%2, %0|%0, %2}";
5724 }
5725 return "add{w}\t{%2, %0|%0, %2}";
5726 }
5727 }
5728 [(set (attr "type")
5729 (if_then_else (eq_attr "alternative" "2")
5730 (const_string "lea")
5731 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5732 (const_string "incdec")
5733 (const_string "alu"))))
5734 (set_attr "mode" "HI,HI,SI")])
5735
5736 (define_insn "*addhi_1"
5737 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5738 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5739 (match_operand:HI 2 "general_operand" "ri,rm")))
5740 (clobber (reg:CC 17))]
5741 "TARGET_PARTIAL_REG_STALL
5742 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5743 {
5744 switch (get_attr_type (insn))
5745 {
5746 case TYPE_INCDEC:
5747 if (operands[2] == const1_rtx)
5748 return "inc{w}\t%0";
5749 else if (operands[2] == constm1_rtx
5750 || (GET_CODE (operands[2]) == CONST_INT
5751 && INTVAL (operands[2]) == 65535))
5752 return "dec{w}\t%0";
5753 abort();
5754
5755 default:
5756 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5757 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5758 if (GET_CODE (operands[2]) == CONST_INT
5759 && (INTVAL (operands[2]) == 128
5760 || (INTVAL (operands[2]) < 0
5761 && INTVAL (operands[2]) != -128)))
5762 {
5763 operands[2] = GEN_INT (-INTVAL (operands[2]));
5764 return "sub{w}\t{%2, %0|%0, %2}";
5765 }
5766 return "add{w}\t{%2, %0|%0, %2}";
5767 }
5768 }
5769 [(set (attr "type")
5770 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5771 (const_string "incdec")
5772 (const_string "alu")))
5773 (set_attr "mode" "HI")])
5774
5775 (define_insn "*addhi_2"
5776 [(set (reg 17)
5777 (compare
5778 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5779 (match_operand:HI 2 "general_operand" "rmni,rni"))
5780 (const_int 0)))
5781 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5782 (plus:HI (match_dup 1) (match_dup 2)))]
5783 "ix86_match_ccmode (insn, CCGOCmode)
5784 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785 {
5786 switch (get_attr_type (insn))
5787 {
5788 case TYPE_INCDEC:
5789 if (operands[2] == const1_rtx)
5790 return "inc{w}\t%0";
5791 else if (operands[2] == constm1_rtx
5792 || (GET_CODE (operands[2]) == CONST_INT
5793 && INTVAL (operands[2]) == 65535))
5794 return "dec{w}\t%0";
5795 abort();
5796
5797 default:
5798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5800 if (GET_CODE (operands[2]) == CONST_INT
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5804 {
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
5806 return "sub{w}\t{%2, %0|%0, %2}";
5807 }
5808 return "add{w}\t{%2, %0|%0, %2}";
5809 }
5810 }
5811 [(set (attr "type")
5812 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5813 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "HI")])
5816
5817 (define_insn "*addhi_3"
5818 [(set (reg 17)
5819 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5820 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5821 (clobber (match_scratch:HI 0 "=r"))]
5822 "ix86_match_ccmode (insn, CCZmode)
5823 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5824 {
5825 switch (get_attr_type (insn))
5826 {
5827 case TYPE_INCDEC:
5828 if (operands[2] == const1_rtx)
5829 return "inc{w}\t%0";
5830 else if (operands[2] == constm1_rtx
5831 || (GET_CODE (operands[2]) == CONST_INT
5832 && INTVAL (operands[2]) == 65535))
5833 return "dec{w}\t%0";
5834 abort();
5835
5836 default:
5837 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5838 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5839 if (GET_CODE (operands[2]) == CONST_INT
5840 && (INTVAL (operands[2]) == 128
5841 || (INTVAL (operands[2]) < 0
5842 && INTVAL (operands[2]) != -128)))
5843 {
5844 operands[2] = GEN_INT (-INTVAL (operands[2]));
5845 return "sub{w}\t{%2, %0|%0, %2}";
5846 }
5847 return "add{w}\t{%2, %0|%0, %2}";
5848 }
5849 }
5850 [(set (attr "type")
5851 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5852 (const_string "incdec")
5853 (const_string "alu")))
5854 (set_attr "mode" "HI")])
5855
5856 ; See comments above addsi_3_imm for details.
5857 (define_insn "*addhi_4"
5858 [(set (reg 17)
5859 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5860 (match_operand:HI 2 "const_int_operand" "n")))
5861 (clobber (match_scratch:HI 0 "=rm"))]
5862 "ix86_match_ccmode (insn, CCGCmode)
5863 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5864 {
5865 switch (get_attr_type (insn))
5866 {
5867 case TYPE_INCDEC:
5868 if (operands[2] == constm1_rtx
5869 || (GET_CODE (operands[2]) == CONST_INT
5870 && INTVAL (operands[2]) == 65535))
5871 return "inc{w}\t%0";
5872 else if (operands[2] == const1_rtx)
5873 return "dec{w}\t%0";
5874 else
5875 abort();
5876
5877 default:
5878 if (! rtx_equal_p (operands[0], operands[1]))
5879 abort ();
5880 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5881 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5882 if ((INTVAL (operands[2]) == -128
5883 || (INTVAL (operands[2]) > 0
5884 && INTVAL (operands[2]) != 128)))
5885 return "sub{w}\t{%2, %0|%0, %2}";
5886 operands[2] = GEN_INT (-INTVAL (operands[2]));
5887 return "add{w}\t{%2, %0|%0, %2}";
5888 }
5889 }
5890 [(set (attr "type")
5891 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5892 (const_string "incdec")
5893 (const_string "alu")))
5894 (set_attr "mode" "SI")])
5895
5896
5897 (define_insn "*addhi_5"
5898 [(set (reg 17)
5899 (compare
5900 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5901 (match_operand:HI 2 "general_operand" "rmni"))
5902 (const_int 0)))
5903 (clobber (match_scratch:HI 0 "=r"))]
5904 "ix86_match_ccmode (insn, CCGOCmode)
5905 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5906 {
5907 switch (get_attr_type (insn))
5908 {
5909 case TYPE_INCDEC:
5910 if (operands[2] == const1_rtx)
5911 return "inc{w}\t%0";
5912 else if (operands[2] == constm1_rtx
5913 || (GET_CODE (operands[2]) == CONST_INT
5914 && INTVAL (operands[2]) == 65535))
5915 return "dec{w}\t%0";
5916 abort();
5917
5918 default:
5919 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5920 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5921 if (GET_CODE (operands[2]) == CONST_INT
5922 && (INTVAL (operands[2]) == 128
5923 || (INTVAL (operands[2]) < 0
5924 && INTVAL (operands[2]) != -128)))
5925 {
5926 operands[2] = GEN_INT (-INTVAL (operands[2]));
5927 return "sub{w}\t{%2, %0|%0, %2}";
5928 }
5929 return "add{w}\t{%2, %0|%0, %2}";
5930 }
5931 }
5932 [(set (attr "type")
5933 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5934 (const_string "incdec")
5935 (const_string "alu")))
5936 (set_attr "mode" "HI")])
5937
5938 (define_expand "addqi3"
5939 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5940 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5941 (match_operand:QI 2 "general_operand" "")))
5942 (clobber (reg:CC 17))])]
5943 "TARGET_QIMODE_MATH"
5944 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5945
5946 ;; %%% Potential partial reg stall on alternative 2. What to do?
5947 (define_insn "*addqi_1_lea"
5948 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5949 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5950 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
5951 (clobber (reg:CC 17))]
5952 "!TARGET_PARTIAL_REG_STALL
5953 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5954 {
5955 int widen = (which_alternative == 2);
5956 switch (get_attr_type (insn))
5957 {
5958 case TYPE_LEA:
5959 return "#";
5960 case TYPE_INCDEC:
5961 if (operands[2] == const1_rtx)
5962 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5963 else if (operands[2] == constm1_rtx
5964 || (GET_CODE (operands[2]) == CONST_INT
5965 && INTVAL (operands[2]) == 255))
5966 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5967 abort();
5968
5969 default:
5970 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5972 if (GET_CODE (operands[2]) == CONST_INT
5973 && (INTVAL (operands[2]) == 128
5974 || (INTVAL (operands[2]) < 0
5975 && INTVAL (operands[2]) != -128)))
5976 {
5977 operands[2] = GEN_INT (-INTVAL (operands[2]));
5978 if (widen)
5979 return "sub{l}\t{%2, %k0|%k0, %2}";
5980 else
5981 return "sub{b}\t{%2, %0|%0, %2}";
5982 }
5983 if (widen)
5984 return "add{l}\t{%k2, %k0|%k0, %k2}";
5985 else
5986 return "add{b}\t{%2, %0|%0, %2}";
5987 }
5988 }
5989 [(set (attr "type")
5990 (if_then_else (eq_attr "alternative" "3")
5991 (const_string "lea")
5992 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5993 (const_string "incdec")
5994 (const_string "alu"))))
5995 (set_attr "mode" "QI,QI,SI,SI")])
5996
5997 (define_insn "*addqi_1"
5998 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5999 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6000 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6001 (clobber (reg:CC 17))]
6002 "TARGET_PARTIAL_REG_STALL
6003 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6004 {
6005 int widen = (which_alternative == 2);
6006 switch (get_attr_type (insn))
6007 {
6008 case TYPE_INCDEC:
6009 if (operands[2] == const1_rtx)
6010 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6011 else if (operands[2] == constm1_rtx
6012 || (GET_CODE (operands[2]) == CONST_INT
6013 && INTVAL (operands[2]) == 255))
6014 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6015 abort();
6016
6017 default:
6018 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6019 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6020 if (GET_CODE (operands[2]) == CONST_INT
6021 && (INTVAL (operands[2]) == 128
6022 || (INTVAL (operands[2]) < 0
6023 && INTVAL (operands[2]) != -128)))
6024 {
6025 operands[2] = GEN_INT (-INTVAL (operands[2]));
6026 if (widen)
6027 return "sub{l}\t{%2, %k0|%k0, %2}";
6028 else
6029 return "sub{b}\t{%2, %0|%0, %2}";
6030 }
6031 if (widen)
6032 return "add{l}\t{%k2, %k0|%k0, %k2}";
6033 else
6034 return "add{b}\t{%2, %0|%0, %2}";
6035 }
6036 }
6037 [(set (attr "type")
6038 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6039 (const_string "incdec")
6040 (const_string "alu")))
6041 (set_attr "mode" "QI,QI,SI")])
6042
6043 (define_insn "*addqi_2"
6044 [(set (reg 17)
6045 (compare
6046 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6047 (match_operand:QI 2 "general_operand" "qmni,qni"))
6048 (const_int 0)))
6049 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6050 (plus:QI (match_dup 1) (match_dup 2)))]
6051 "ix86_match_ccmode (insn, CCGOCmode)
6052 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6053 {
6054 switch (get_attr_type (insn))
6055 {
6056 case TYPE_INCDEC:
6057 if (operands[2] == const1_rtx)
6058 return "inc{b}\t%0";
6059 else if (operands[2] == constm1_rtx
6060 || (GET_CODE (operands[2]) == CONST_INT
6061 && INTVAL (operands[2]) == 255))
6062 return "dec{b}\t%0";
6063 abort();
6064
6065 default:
6066 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6067 if (GET_CODE (operands[2]) == CONST_INT
6068 && INTVAL (operands[2]) < 0)
6069 {
6070 operands[2] = GEN_INT (-INTVAL (operands[2]));
6071 return "sub{b}\t{%2, %0|%0, %2}";
6072 }
6073 return "add{b}\t{%2, %0|%0, %2}";
6074 }
6075 }
6076 [(set (attr "type")
6077 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6078 (const_string "incdec")
6079 (const_string "alu")))
6080 (set_attr "mode" "QI")])
6081
6082 (define_insn "*addqi_3"
6083 [(set (reg 17)
6084 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6085 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6086 (clobber (match_scratch:QI 0 "=q"))]
6087 "ix86_match_ccmode (insn, CCZmode)
6088 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6089 {
6090 switch (get_attr_type (insn))
6091 {
6092 case TYPE_INCDEC:
6093 if (operands[2] == const1_rtx)
6094 return "inc{b}\t%0";
6095 else if (operands[2] == constm1_rtx
6096 || (GET_CODE (operands[2]) == CONST_INT
6097 && INTVAL (operands[2]) == 255))
6098 return "dec{b}\t%0";
6099 abort();
6100
6101 default:
6102 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6103 if (GET_CODE (operands[2]) == CONST_INT
6104 && INTVAL (operands[2]) < 0)
6105 {
6106 operands[2] = GEN_INT (-INTVAL (operands[2]));
6107 return "sub{b}\t{%2, %0|%0, %2}";
6108 }
6109 return "add{b}\t{%2, %0|%0, %2}";
6110 }
6111 }
6112 [(set (attr "type")
6113 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6114 (const_string "incdec")
6115 (const_string "alu")))
6116 (set_attr "mode" "QI")])
6117
6118 ; See comments above addsi_3_imm for details.
6119 (define_insn "*addqi_4"
6120 [(set (reg 17)
6121 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6122 (match_operand:QI 2 "const_int_operand" "n")))
6123 (clobber (match_scratch:QI 0 "=qm"))]
6124 "ix86_match_ccmode (insn, CCGCmode)
6125 && (INTVAL (operands[2]) & 0xff) != 0x80"
6126 {
6127 switch (get_attr_type (insn))
6128 {
6129 case TYPE_INCDEC:
6130 if (operands[2] == constm1_rtx
6131 || (GET_CODE (operands[2]) == CONST_INT
6132 && INTVAL (operands[2]) == 255))
6133 return "inc{b}\t%0";
6134 else if (operands[2] == const1_rtx)
6135 return "dec{b}\t%0";
6136 else
6137 abort();
6138
6139 default:
6140 if (! rtx_equal_p (operands[0], operands[1]))
6141 abort ();
6142 if (INTVAL (operands[2]) < 0)
6143 {
6144 operands[2] = GEN_INT (-INTVAL (operands[2]));
6145 return "add{b}\t{%2, %0|%0, %2}";
6146 }
6147 return "sub{b}\t{%2, %0|%0, %2}";
6148 }
6149 }
6150 [(set (attr "type")
6151 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6152 (const_string "incdec")
6153 (const_string "alu")))
6154 (set_attr "mode" "QI")])
6155
6156
6157 (define_insn "*addqi_5"
6158 [(set (reg 17)
6159 (compare
6160 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6161 (match_operand:QI 2 "general_operand" "qmni"))
6162 (const_int 0)))
6163 (clobber (match_scratch:QI 0 "=q"))]
6164 "ix86_match_ccmode (insn, CCGOCmode)
6165 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6166 {
6167 switch (get_attr_type (insn))
6168 {
6169 case TYPE_INCDEC:
6170 if (operands[2] == const1_rtx)
6171 return "inc{b}\t%0";
6172 else if (operands[2] == constm1_rtx
6173 || (GET_CODE (operands[2]) == CONST_INT
6174 && INTVAL (operands[2]) == 255))
6175 return "dec{b}\t%0";
6176 abort();
6177
6178 default:
6179 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6180 if (GET_CODE (operands[2]) == CONST_INT
6181 && INTVAL (operands[2]) < 0)
6182 {
6183 operands[2] = GEN_INT (-INTVAL (operands[2]));
6184 return "sub{b}\t{%2, %0|%0, %2}";
6185 }
6186 return "add{b}\t{%2, %0|%0, %2}";
6187 }
6188 }
6189 [(set (attr "type")
6190 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6191 (const_string "incdec")
6192 (const_string "alu")))
6193 (set_attr "mode" "QI")])
6194
6195
6196 (define_insn "addqi_ext_1"
6197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6198 (const_int 8)
6199 (const_int 8))
6200 (plus:SI
6201 (zero_extract:SI
6202 (match_operand 1 "ext_register_operand" "0")
6203 (const_int 8)
6204 (const_int 8))
6205 (match_operand:QI 2 "general_operand" "Qmn")))
6206 (clobber (reg:CC 17))]
6207 "!TARGET_64BIT"
6208 {
6209 switch (get_attr_type (insn))
6210 {
6211 case TYPE_INCDEC:
6212 if (operands[2] == const1_rtx)
6213 return "inc{b}\t%h0";
6214 else if (operands[2] == constm1_rtx
6215 || (GET_CODE (operands[2]) == CONST_INT
6216 && INTVAL (operands[2]) == 255))
6217 return "dec{b}\t%h0";
6218 abort();
6219
6220 default:
6221 return "add{b}\t{%2, %h0|%h0, %2}";
6222 }
6223 }
6224 [(set (attr "type")
6225 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu")))
6228 (set_attr "mode" "QI")])
6229
6230 (define_insn "*addqi_ext_1_rex64"
6231 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6232 (const_int 8)
6233 (const_int 8))
6234 (plus:SI
6235 (zero_extract:SI
6236 (match_operand 1 "ext_register_operand" "0")
6237 (const_int 8)
6238 (const_int 8))
6239 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6240 (clobber (reg:CC 17))]
6241 "TARGET_64BIT"
6242 {
6243 switch (get_attr_type (insn))
6244 {
6245 case TYPE_INCDEC:
6246 if (operands[2] == const1_rtx)
6247 return "inc{b}\t%h0";
6248 else if (operands[2] == constm1_rtx
6249 || (GET_CODE (operands[2]) == CONST_INT
6250 && INTVAL (operands[2]) == 255))
6251 return "dec{b}\t%h0";
6252 abort();
6253
6254 default:
6255 return "add{b}\t{%2, %h0|%h0, %2}";
6256 }
6257 }
6258 [(set (attr "type")
6259 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6260 (const_string "incdec")
6261 (const_string "alu")))
6262 (set_attr "mode" "QI")])
6263
6264 (define_insn "*addqi_ext_2"
6265 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6266 (const_int 8)
6267 (const_int 8))
6268 (plus:SI
6269 (zero_extract:SI
6270 (match_operand 1 "ext_register_operand" "%0")
6271 (const_int 8)
6272 (const_int 8))
6273 (zero_extract:SI
6274 (match_operand 2 "ext_register_operand" "Q")
6275 (const_int 8)
6276 (const_int 8))))
6277 (clobber (reg:CC 17))]
6278 ""
6279 "add{b}\t{%h2, %h0|%h0, %h2}"
6280 [(set_attr "type" "alu")
6281 (set_attr "mode" "QI")])
6282
6283 ;; The patterns that match these are at the end of this file.
6284
6285 (define_expand "addxf3"
6286 [(set (match_operand:XF 0 "register_operand" "")
6287 (plus:XF (match_operand:XF 1 "register_operand" "")
6288 (match_operand:XF 2 "register_operand" "")))]
6289 "!TARGET_64BIT && TARGET_80387"
6290 "")
6291
6292 (define_expand "addtf3"
6293 [(set (match_operand:TF 0 "register_operand" "")
6294 (plus:TF (match_operand:TF 1 "register_operand" "")
6295 (match_operand:TF 2 "register_operand" "")))]
6296 "TARGET_80387"
6297 "")
6298
6299 (define_expand "adddf3"
6300 [(set (match_operand:DF 0 "register_operand" "")
6301 (plus:DF (match_operand:DF 1 "register_operand" "")
6302 (match_operand:DF 2 "nonimmediate_operand" "")))]
6303 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6304 "")
6305
6306 (define_expand "addsf3"
6307 [(set (match_operand:SF 0 "register_operand" "")
6308 (plus:SF (match_operand:SF 1 "register_operand" "")
6309 (match_operand:SF 2 "nonimmediate_operand" "")))]
6310 "TARGET_80387 || TARGET_SSE_MATH"
6311 "")
6312 \f
6313 ;; Subtract instructions
6314
6315 ;; %%% splits for subsidi3
6316
6317 (define_expand "subdi3"
6318 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6319 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6320 (match_operand:DI 2 "x86_64_general_operand" "")))
6321 (clobber (reg:CC 17))])]
6322 ""
6323 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6324
6325 (define_insn "*subdi3_1"
6326 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6327 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6328 (match_operand:DI 2 "general_operand" "roiF,riF")))
6329 (clobber (reg:CC 17))]
6330 "!TARGET_64BIT"
6331 "#")
6332
6333 (define_split
6334 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6335 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6336 (match_operand:DI 2 "general_operand" "")))
6337 (clobber (reg:CC 17))]
6338 "!TARGET_64BIT && reload_completed"
6339 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6340 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6341 (parallel [(set (match_dup 3)
6342 (minus:SI (match_dup 4)
6343 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6344 (match_dup 5))))
6345 (clobber (reg:CC 17))])]
6346 "split_di (operands+0, 1, operands+0, operands+3);
6347 split_di (operands+1, 1, operands+1, operands+4);
6348 split_di (operands+2, 1, operands+2, operands+5);")
6349
6350 (define_insn "subdi3_carry_rex64"
6351 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6352 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6353 (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6354 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6355 (clobber (reg:CC 17))]
6356 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6357 "sbb{q}\t{%2, %0|%0, %2}"
6358 [(set_attr "type" "alu")
6359 (set_attr "pent_pair" "pu")
6360 (set_attr "ppro_uops" "few")
6361 (set_attr "mode" "DI")])
6362
6363 (define_insn "*subdi_1_rex64"
6364 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6365 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6366 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6367 (clobber (reg:CC 17))]
6368 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6369 "sub{q}\t{%2, %0|%0, %2}"
6370 [(set_attr "type" "alu")
6371 (set_attr "mode" "DI")])
6372
6373 (define_insn "*subdi_2_rex64"
6374 [(set (reg 17)
6375 (compare
6376 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6377 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6378 (const_int 0)))
6379 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6380 (minus:DI (match_dup 1) (match_dup 2)))]
6381 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6382 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6383 "sub{q}\t{%2, %0|%0, %2}"
6384 [(set_attr "type" "alu")
6385 (set_attr "mode" "DI")])
6386
6387 (define_insn "*subdi_3_rex63"
6388 [(set (reg 17)
6389 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6390 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6391 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6392 (minus:DI (match_dup 1) (match_dup 2)))]
6393 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6394 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6395 "sub{q}\t{%2, %0|%0, %2}"
6396 [(set_attr "type" "alu")
6397 (set_attr "mode" "DI")])
6398
6399
6400 (define_insn "subsi3_carry"
6401 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6402 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6403 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6404 (match_operand:SI 2 "general_operand" "ri,rm"))))
6405 (clobber (reg:CC 17))]
6406 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6407 "sbb{l}\t{%2, %0|%0, %2}"
6408 [(set_attr "type" "alu")
6409 (set_attr "pent_pair" "pu")
6410 (set_attr "ppro_uops" "few")
6411 (set_attr "mode" "SI")])
6412
6413 (define_insn "subsi3_carry_zext"
6414 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6415 (zero_extend:DI
6416 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6417 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6418 (match_operand:SI 2 "general_operand" "ri,rm")))))
6419 (clobber (reg:CC 17))]
6420 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6421 "sbb{l}\t{%2, %k0|%k0, %2}"
6422 [(set_attr "type" "alu")
6423 (set_attr "pent_pair" "pu")
6424 (set_attr "ppro_uops" "few")
6425 (set_attr "mode" "SI")])
6426
6427 (define_expand "subsi3"
6428 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6429 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6430 (match_operand:SI 2 "general_operand" "")))
6431 (clobber (reg:CC 17))])]
6432 ""
6433 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6434
6435 (define_insn "*subsi_1"
6436 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6437 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6438 (match_operand:SI 2 "general_operand" "ri,rm")))
6439 (clobber (reg:CC 17))]
6440 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6441 "sub{l}\t{%2, %0|%0, %2}"
6442 [(set_attr "type" "alu")
6443 (set_attr "mode" "SI")])
6444
6445 (define_insn "*subsi_1_zext"
6446 [(set (match_operand:DI 0 "register_operand" "=r")
6447 (zero_extend:DI
6448 (minus:SI (match_operand:SI 1 "register_operand" "0")
6449 (match_operand:SI 2 "general_operand" "rim"))))
6450 (clobber (reg:CC 17))]
6451 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6452 "sub{l}\t{%2, %k0|%k0, %2}"
6453 [(set_attr "type" "alu")
6454 (set_attr "mode" "SI")])
6455
6456 (define_insn "*subsi_2"
6457 [(set (reg 17)
6458 (compare
6459 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6460 (match_operand:SI 2 "general_operand" "ri,rm"))
6461 (const_int 0)))
6462 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6463 (minus:SI (match_dup 1) (match_dup 2)))]
6464 "ix86_match_ccmode (insn, CCGOCmode)
6465 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466 "sub{l}\t{%2, %0|%0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "SI")])
6469
6470 (define_insn "*subsi_2_zext"
6471 [(set (reg 17)
6472 (compare
6473 (minus:SI (match_operand:SI 1 "register_operand" "0")
6474 (match_operand:SI 2 "general_operand" "rim"))
6475 (const_int 0)))
6476 (set (match_operand:DI 0 "register_operand" "=r")
6477 (zero_extend:DI
6478 (minus:SI (match_dup 1)
6479 (match_dup 2))))]
6480 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6481 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6482 "sub{l}\t{%2, %k0|%k0, %2}"
6483 [(set_attr "type" "alu")
6484 (set_attr "mode" "SI")])
6485
6486 (define_insn "*subsi_3"
6487 [(set (reg 17)
6488 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6489 (match_operand:SI 2 "general_operand" "ri,rm")))
6490 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6491 (minus:SI (match_dup 1) (match_dup 2)))]
6492 "ix86_match_ccmode (insn, CCmode)
6493 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6494 "sub{l}\t{%2, %0|%0, %2}"
6495 [(set_attr "type" "alu")
6496 (set_attr "mode" "SI")])
6497
6498 (define_insn "*subsi_3_zext"
6499 [(set (reg 17)
6500 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6501 (match_operand:SI 2 "general_operand" "rim")))
6502 (set (match_operand:DI 0 "register_operand" "=r")
6503 (zero_extend:DI
6504 (minus:SI (match_dup 1)
6505 (match_dup 2))))]
6506 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6507 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6508 "sub{q}\t{%2, %0|%0, %2}"
6509 [(set_attr "type" "alu")
6510 (set_attr "mode" "DI")])
6511
6512 (define_expand "subhi3"
6513 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6514 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6515 (match_operand:HI 2 "general_operand" "")))
6516 (clobber (reg:CC 17))])]
6517 "TARGET_HIMODE_MATH"
6518 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6519
6520 (define_insn "*subhi_1"
6521 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6522 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6523 (match_operand:HI 2 "general_operand" "ri,rm")))
6524 (clobber (reg:CC 17))]
6525 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6526 "sub{w}\t{%2, %0|%0, %2}"
6527 [(set_attr "type" "alu")
6528 (set_attr "mode" "HI")])
6529
6530 (define_insn "*subhi_2"
6531 [(set (reg 17)
6532 (compare
6533 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6534 (match_operand:HI 2 "general_operand" "ri,rm"))
6535 (const_int 0)))
6536 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6537 (minus:HI (match_dup 1) (match_dup 2)))]
6538 "ix86_match_ccmode (insn, CCGOCmode)
6539 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6540 "sub{w}\t{%2, %0|%0, %2}"
6541 [(set_attr "type" "alu")
6542 (set_attr "mode" "HI")])
6543
6544 (define_insn "*subhi_3"
6545 [(set (reg 17)
6546 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6547 (match_operand:HI 2 "general_operand" "ri,rm")))
6548 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6549 (minus:HI (match_dup 1) (match_dup 2)))]
6550 "ix86_match_ccmode (insn, CCmode)
6551 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6552 "sub{w}\t{%2, %0|%0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "mode" "HI")])
6555
6556 (define_expand "subqi3"
6557 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6558 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6559 (match_operand:QI 2 "general_operand" "")))
6560 (clobber (reg:CC 17))])]
6561 "TARGET_QIMODE_MATH"
6562 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6563
6564 (define_insn "*subqi_1"
6565 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6566 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6567 (match_operand:QI 2 "general_operand" "qn,qmn")))
6568 (clobber (reg:CC 17))]
6569 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6570 "sub{b}\t{%2, %0|%0, %2}"
6571 [(set_attr "type" "alu")
6572 (set_attr "mode" "QI")])
6573
6574 (define_insn "*subqi_2"
6575 [(set (reg 17)
6576 (compare
6577 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6578 (match_operand:QI 2 "general_operand" "qi,qm"))
6579 (const_int 0)))
6580 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6581 (minus:HI (match_dup 1) (match_dup 2)))]
6582 "ix86_match_ccmode (insn, CCGOCmode)
6583 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6584 "sub{b}\t{%2, %0|%0, %2}"
6585 [(set_attr "type" "alu")
6586 (set_attr "mode" "QI")])
6587
6588 (define_insn "*subqi_3"
6589 [(set (reg 17)
6590 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6591 (match_operand:QI 2 "general_operand" "qi,qm")))
6592 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6593 (minus:HI (match_dup 1) (match_dup 2)))]
6594 "ix86_match_ccmode (insn, CCmode)
6595 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6596 "sub{b}\t{%2, %0|%0, %2}"
6597 [(set_attr "type" "alu")
6598 (set_attr "mode" "QI")])
6599
6600 ;; The patterns that match these are at the end of this file.
6601
6602 (define_expand "subxf3"
6603 [(set (match_operand:XF 0 "register_operand" "")
6604 (minus:XF (match_operand:XF 1 "register_operand" "")
6605 (match_operand:XF 2 "register_operand" "")))]
6606 "!TARGET_64BIT && TARGET_80387"
6607 "")
6608
6609 (define_expand "subtf3"
6610 [(set (match_operand:TF 0 "register_operand" "")
6611 (minus:TF (match_operand:TF 1 "register_operand" "")
6612 (match_operand:TF 2 "register_operand" "")))]
6613 "TARGET_80387"
6614 "")
6615
6616 (define_expand "subdf3"
6617 [(set (match_operand:DF 0 "register_operand" "")
6618 (minus:DF (match_operand:DF 1 "register_operand" "")
6619 (match_operand:DF 2 "nonimmediate_operand" "")))]
6620 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6621 "")
6622
6623 (define_expand "subsf3"
6624 [(set (match_operand:SF 0 "register_operand" "")
6625 (minus:SF (match_operand:SF 1 "register_operand" "")
6626 (match_operand:SF 2 "nonimmediate_operand" "")))]
6627 "TARGET_80387 || TARGET_SSE_MATH"
6628 "")
6629 \f
6630 ;; Multiply instructions
6631
6632 (define_expand "muldi3"
6633 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6634 (mult:DI (match_operand:DI 1 "register_operand" "")
6635 (match_operand:DI 2 "x86_64_general_operand" "")))
6636 (clobber (reg:CC 17))])]
6637 "TARGET_64BIT"
6638 "")
6639
6640 (define_insn "*muldi3_1_rex64"
6641 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6642 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
6643 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6644 (clobber (reg:CC 17))]
6645 "TARGET_64BIT
6646 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6647 "@
6648 imul{q}\t{%2, %1, %0|%0, %1, %2}
6649 imul{q}\t{%2, %1, %0|%0, %1, %2}
6650 imul{q}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "imul")
6652 (set_attr "prefix_0f" "0,0,1")
6653 (set_attr "mode" "DI")])
6654
6655 (define_expand "mulsi3"
6656 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6657 (mult:SI (match_operand:SI 1 "register_operand" "")
6658 (match_operand:SI 2 "general_operand" "")))
6659 (clobber (reg:CC 17))])]
6660 ""
6661 "")
6662
6663 (define_insn "*mulsi3_1"
6664 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6665 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
6666 (match_operand:SI 2 "general_operand" "K,i,mr")))
6667 (clobber (reg:CC 17))]
6668 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6669 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
6670 ; there are two ways of writing the exact same machine instruction
6671 ; in assembly language. One, for example, is:
6672 ;
6673 ; imul $12, %eax
6674 ;
6675 ; while the other is:
6676 ;
6677 ; imul $12, %eax, %eax
6678 ;
6679 ; The first is simply short-hand for the latter. But, some assemblers,
6680 ; like the SCO OSR5 COFF assembler, don't handle the first form.
6681 "@
6682 imul{l}\t{%2, %1, %0|%0, %1, %2}
6683 imul{l}\t{%2, %1, %0|%0, %1, %2}
6684 imul{l}\t{%2, %0|%0, %2}"
6685 [(set_attr "type" "imul")
6686 (set_attr "prefix_0f" "0,0,1")
6687 (set_attr "mode" "SI")])
6688
6689 (define_insn "*mulsi3_1_zext"
6690 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6691 (zero_extend:DI
6692 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
6693 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6694 (clobber (reg:CC 17))]
6695 "TARGET_64BIT
6696 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6697 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
6698 ; there are two ways of writing the exact same machine instruction
6699 ; in assembly language. One, for example, is:
6700 ;
6701 ; imul $12, %eax
6702 ;
6703 ; while the other is:
6704 ;
6705 ; imul $12, %eax, %eax
6706 ;
6707 ; The first is simply short-hand for the latter. But, some assemblers,
6708 ; like the SCO OSR5 COFF assembler, don't handle the first form.
6709 "@
6710 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6711 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6712 imul{l}\t{%2, %k0|%k0, %2}"
6713 [(set_attr "type" "imul")
6714 (set_attr "prefix_0f" "0,0,1")
6715 (set_attr "mode" "SI")])
6716
6717 (define_expand "mulhi3"
6718 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6719 (mult:HI (match_operand:HI 1 "register_operand" "")
6720 (match_operand:HI 2 "general_operand" "")))
6721 (clobber (reg:CC 17))])]
6722 "TARGET_HIMODE_MATH"
6723 "")
6724
6725 (define_insn "*mulhi3_1"
6726 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6727 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
6728 (match_operand:HI 2 "general_operand" "K,i,mr")))
6729 (clobber (reg:CC 17))]
6730 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6731 ; %%% There was a note about "Assembler has weird restrictions",
6732 ; concerning alternative 1 when op1 == op0. True?
6733 "@
6734 imul{w}\t{%2, %1, %0|%0, %1, %2}
6735 imul{w}\t{%2, %1, %0|%0, %1, %2}
6736 imul{w}\t{%2, %0|%0, %2}"
6737 [(set_attr "type" "imul")
6738 (set_attr "prefix_0f" "0,0,1")
6739 (set_attr "mode" "HI")])
6740
6741 (define_expand "mulqi3"
6742 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6743 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6744 (match_operand:QI 2 "register_operand" "")))
6745 (clobber (reg:CC 17))])]
6746 "TARGET_QIMODE_MATH"
6747 "")
6748
6749 (define_insn "*mulqi3_1"
6750 [(set (match_operand:QI 0 "register_operand" "=a")
6751 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6752 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6753 (clobber (reg:CC 17))]
6754 "TARGET_QIMODE_MATH
6755 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6756 "mul{b}\t%2"
6757 [(set_attr "type" "imul")
6758 (set_attr "length_immediate" "0")
6759 (set_attr "mode" "QI")])
6760
6761 (define_expand "umulqihi3"
6762 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6763 (mult:HI (zero_extend:HI
6764 (match_operand:QI 1 "nonimmediate_operand" ""))
6765 (zero_extend:HI
6766 (match_operand:QI 2 "register_operand" ""))))
6767 (clobber (reg:CC 17))])]
6768 "TARGET_QIMODE_MATH"
6769 "")
6770
6771 (define_insn "*umulqihi3_1"
6772 [(set (match_operand:HI 0 "register_operand" "=a")
6773 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6774 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6775 (clobber (reg:CC 17))]
6776 "TARGET_QIMODE_MATH
6777 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6778 "mul{b}\t%2"
6779 [(set_attr "type" "imul")
6780 (set_attr "length_immediate" "0")
6781 (set_attr "mode" "QI")])
6782
6783 (define_expand "mulqihi3"
6784 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6785 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6786 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6787 (clobber (reg:CC 17))])]
6788 "TARGET_QIMODE_MATH"
6789 "")
6790
6791 (define_insn "*mulqihi3_insn"
6792 [(set (match_operand:HI 0 "register_operand" "=a")
6793 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6794 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6795 (clobber (reg:CC 17))]
6796 "TARGET_QIMODE_MATH
6797 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6798 "imul{b}\t%2"
6799 [(set_attr "type" "imul")
6800 (set_attr "length_immediate" "0")
6801 (set_attr "mode" "QI")])
6802
6803 (define_expand "umulditi3"
6804 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6805 (mult:TI (zero_extend:TI
6806 (match_operand:DI 1 "nonimmediate_operand" ""))
6807 (zero_extend:TI
6808 (match_operand:DI 2 "register_operand" ""))))
6809 (clobber (reg:CC 17))])]
6810 "TARGET_64BIT"
6811 "")
6812
6813 (define_insn "*umulditi3_insn"
6814 [(set (match_operand:TI 0 "register_operand" "=A")
6815 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6816 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6817 (clobber (reg:CC 17))]
6818 "TARGET_64BIT
6819 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6820 "mul{q}\t%2"
6821 [(set_attr "type" "imul")
6822 (set_attr "ppro_uops" "few")
6823 (set_attr "length_immediate" "0")
6824 (set_attr "mode" "DI")])
6825
6826 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6827 (define_expand "umulsidi3"
6828 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6829 (mult:DI (zero_extend:DI
6830 (match_operand:SI 1 "nonimmediate_operand" ""))
6831 (zero_extend:DI
6832 (match_operand:SI 2 "register_operand" ""))))
6833 (clobber (reg:CC 17))])]
6834 "!TARGET_64BIT"
6835 "")
6836
6837 (define_insn "*umulsidi3_insn"
6838 [(set (match_operand:DI 0 "register_operand" "=A")
6839 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6840 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6841 (clobber (reg:CC 17))]
6842 "!TARGET_64BIT
6843 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6844 "mul{l}\t%2"
6845 [(set_attr "type" "imul")
6846 (set_attr "ppro_uops" "few")
6847 (set_attr "length_immediate" "0")
6848 (set_attr "mode" "SI")])
6849
6850 (define_expand "mulditi3"
6851 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6852 (mult:TI (sign_extend:TI
6853 (match_operand:DI 1 "nonimmediate_operand" ""))
6854 (sign_extend:TI
6855 (match_operand:DI 2 "register_operand" ""))))
6856 (clobber (reg:CC 17))])]
6857 "TARGET_64BIT"
6858 "")
6859
6860 (define_insn "*mulditi3_insn"
6861 [(set (match_operand:TI 0 "register_operand" "=A")
6862 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6863 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6864 (clobber (reg:CC 17))]
6865 "TARGET_64BIT
6866 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6867 "imul{q}\t%2"
6868 [(set_attr "type" "imul")
6869 (set_attr "length_immediate" "0")
6870 (set_attr "mode" "DI")])
6871
6872 (define_expand "mulsidi3"
6873 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6874 (mult:DI (sign_extend:DI
6875 (match_operand:SI 1 "nonimmediate_operand" ""))
6876 (sign_extend:DI
6877 (match_operand:SI 2 "register_operand" ""))))
6878 (clobber (reg:CC 17))])]
6879 "!TARGET_64BIT"
6880 "")
6881
6882 (define_insn "*mulsidi3_insn"
6883 [(set (match_operand:DI 0 "register_operand" "=A")
6884 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6885 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6886 (clobber (reg:CC 17))]
6887 "!TARGET_64BIT
6888 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6889 "imul{l}\t%2"
6890 [(set_attr "type" "imul")
6891 (set_attr "length_immediate" "0")
6892 (set_attr "mode" "SI")])
6893
6894 (define_expand "umuldi3_highpart"
6895 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6896 (truncate:DI
6897 (lshiftrt:TI
6898 (mult:TI (zero_extend:TI
6899 (match_operand:DI 1 "nonimmediate_operand" ""))
6900 (zero_extend:TI
6901 (match_operand:DI 2 "register_operand" "")))
6902 (const_int 64))))
6903 (clobber (match_scratch:DI 3 ""))
6904 (clobber (reg:CC 17))])]
6905 "TARGET_64BIT"
6906 "")
6907
6908 (define_insn "*umuldi3_highpart_rex64"
6909 [(set (match_operand:DI 0 "register_operand" "=d")
6910 (truncate:DI
6911 (lshiftrt:TI
6912 (mult:TI (zero_extend:TI
6913 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6914 (zero_extend:TI
6915 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6916 (const_int 64))))
6917 (clobber (match_scratch:DI 3 "=1"))
6918 (clobber (reg:CC 17))]
6919 "TARGET_64BIT
6920 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6921 "mul{q}\t%2"
6922 [(set_attr "type" "imul")
6923 (set_attr "ppro_uops" "few")
6924 (set_attr "length_immediate" "0")
6925 (set_attr "mode" "DI")])
6926
6927 (define_expand "umulsi3_highpart"
6928 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6929 (truncate:SI
6930 (lshiftrt:DI
6931 (mult:DI (zero_extend:DI
6932 (match_operand:SI 1 "nonimmediate_operand" ""))
6933 (zero_extend:DI
6934 (match_operand:SI 2 "register_operand" "")))
6935 (const_int 32))))
6936 (clobber (match_scratch:SI 3 ""))
6937 (clobber (reg:CC 17))])]
6938 ""
6939 "")
6940
6941 (define_insn "*umulsi3_highpart_insn"
6942 [(set (match_operand:SI 0 "register_operand" "=d")
6943 (truncate:SI
6944 (lshiftrt:DI
6945 (mult:DI (zero_extend:DI
6946 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6947 (zero_extend:DI
6948 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6949 (const_int 32))))
6950 (clobber (match_scratch:SI 3 "=1"))
6951 (clobber (reg:CC 17))]
6952 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6953 "mul{l}\t%2"
6954 [(set_attr "type" "imul")
6955 (set_attr "ppro_uops" "few")
6956 (set_attr "length_immediate" "0")
6957 (set_attr "mode" "SI")])
6958
6959 (define_insn "*umulsi3_highpart_zext"
6960 [(set (match_operand:DI 0 "register_operand" "=d")
6961 (zero_extend:DI (truncate:SI
6962 (lshiftrt:DI
6963 (mult:DI (zero_extend:DI
6964 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6965 (zero_extend:DI
6966 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6967 (const_int 32)))))
6968 (clobber (match_scratch:SI 3 "=1"))
6969 (clobber (reg:CC 17))]
6970 "TARGET_64BIT
6971 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6972 "mul{l}\t%2"
6973 [(set_attr "type" "imul")
6974 (set_attr "ppro_uops" "few")
6975 (set_attr "length_immediate" "0")
6976 (set_attr "mode" "SI")])
6977
6978 (define_expand "smuldi3_highpart"
6979 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
6980 (truncate:DI
6981 (lshiftrt:TI
6982 (mult:TI (sign_extend:TI
6983 (match_operand:DI 1 "nonimmediate_operand" ""))
6984 (sign_extend:TI
6985 (match_operand:DI 2 "register_operand" "")))
6986 (const_int 64))))
6987 (clobber (match_scratch:DI 3 ""))
6988 (clobber (reg:CC 17))])]
6989 "TARGET_64BIT"
6990 "")
6991
6992 (define_insn "*smuldi3_highpart_rex64"
6993 [(set (match_operand:DI 0 "register_operand" "=d")
6994 (truncate:DI
6995 (lshiftrt:TI
6996 (mult:TI (sign_extend:TI
6997 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6998 (sign_extend:TI
6999 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7000 (const_int 64))))
7001 (clobber (match_scratch:DI 3 "=1"))
7002 (clobber (reg:CC 17))]
7003 "TARGET_64BIT
7004 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7005 "imul{q}\t%2"
7006 [(set_attr "type" "imul")
7007 (set_attr "ppro_uops" "few")
7008 (set_attr "mode" "DI")])
7009
7010 (define_expand "smulsi3_highpart"
7011 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7012 (truncate:SI
7013 (lshiftrt:DI
7014 (mult:DI (sign_extend:DI
7015 (match_operand:SI 1 "nonimmediate_operand" ""))
7016 (sign_extend:DI
7017 (match_operand:SI 2 "register_operand" "")))
7018 (const_int 32))))
7019 (clobber (match_scratch:SI 3 ""))
7020 (clobber (reg:CC 17))])]
7021 ""
7022 "")
7023
7024 (define_insn "*smulsi3_highpart_insn"
7025 [(set (match_operand:SI 0 "register_operand" "=d")
7026 (truncate:SI
7027 (lshiftrt:DI
7028 (mult:DI (sign_extend:DI
7029 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7030 (sign_extend:DI
7031 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7032 (const_int 32))))
7033 (clobber (match_scratch:SI 3 "=1"))
7034 (clobber (reg:CC 17))]
7035 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7036 "imul{l}\t%2"
7037 [(set_attr "type" "imul")
7038 (set_attr "ppro_uops" "few")
7039 (set_attr "mode" "SI")])
7040
7041 (define_insn "*smulsi3_highpart_zext"
7042 [(set (match_operand:DI 0 "register_operand" "=d")
7043 (zero_extend:DI (truncate:SI
7044 (lshiftrt:DI
7045 (mult:DI (sign_extend:DI
7046 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7047 (sign_extend:DI
7048 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7049 (const_int 32)))))
7050 (clobber (match_scratch:SI 3 "=1"))
7051 (clobber (reg:CC 17))]
7052 "TARGET_64BIT
7053 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7054 "imul{l}\t%2"
7055 [(set_attr "type" "imul")
7056 (set_attr "ppro_uops" "few")
7057 (set_attr "mode" "SI")])
7058
7059 ;; The patterns that match these are at the end of this file.
7060
7061 (define_expand "mulxf3"
7062 [(set (match_operand:XF 0 "register_operand" "")
7063 (mult:XF (match_operand:XF 1 "register_operand" "")
7064 (match_operand:XF 2 "register_operand" "")))]
7065 "!TARGET_64BIT && TARGET_80387"
7066 "")
7067
7068 (define_expand "multf3"
7069 [(set (match_operand:TF 0 "register_operand" "")
7070 (mult:TF (match_operand:TF 1 "register_operand" "")
7071 (match_operand:TF 2 "register_operand" "")))]
7072 "TARGET_80387"
7073 "")
7074
7075 (define_expand "muldf3"
7076 [(set (match_operand:DF 0 "register_operand" "")
7077 (mult:DF (match_operand:DF 1 "register_operand" "")
7078 (match_operand:DF 2 "nonimmediate_operand" "")))]
7079 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7080 "")
7081
7082 (define_expand "mulsf3"
7083 [(set (match_operand:SF 0 "register_operand" "")
7084 (mult:SF (match_operand:SF 1 "register_operand" "")
7085 (match_operand:SF 2 "nonimmediate_operand" "")))]
7086 "TARGET_80387 || TARGET_SSE_MATH"
7087 "")
7088 \f
7089 ;; Divide instructions
7090
7091 (define_insn "divqi3"
7092 [(set (match_operand:QI 0 "register_operand" "=a")
7093 (div:QI (match_operand:HI 1 "register_operand" "0")
7094 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7095 (clobber (reg:CC 17))]
7096 "TARGET_QIMODE_MATH"
7097 "idiv{b}\t%2"
7098 [(set_attr "type" "idiv")
7099 (set_attr "mode" "QI")
7100 (set_attr "ppro_uops" "few")])
7101
7102 (define_insn "udivqi3"
7103 [(set (match_operand:QI 0 "register_operand" "=a")
7104 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7105 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7106 (clobber (reg:CC 17))]
7107 "TARGET_QIMODE_MATH"
7108 "div{b}\t%2"
7109 [(set_attr "type" "idiv")
7110 (set_attr "mode" "QI")
7111 (set_attr "ppro_uops" "few")])
7112
7113 ;; The patterns that match these are at the end of this file.
7114
7115 (define_expand "divxf3"
7116 [(set (match_operand:XF 0 "register_operand" "")
7117 (div:XF (match_operand:XF 1 "register_operand" "")
7118 (match_operand:XF 2 "register_operand" "")))]
7119 "!TARGET_64BIT && TARGET_80387"
7120 "")
7121
7122 (define_expand "divtf3"
7123 [(set (match_operand:TF 0 "register_operand" "")
7124 (div:TF (match_operand:TF 1 "register_operand" "")
7125 (match_operand:TF 2 "register_operand" "")))]
7126 "TARGET_80387"
7127 "")
7128
7129 (define_expand "divdf3"
7130 [(set (match_operand:DF 0 "register_operand" "")
7131 (div:DF (match_operand:DF 1 "register_operand" "")
7132 (match_operand:DF 2 "nonimmediate_operand" "")))]
7133 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7134 "")
7135
7136 (define_expand "divsf3"
7137 [(set (match_operand:SF 0 "register_operand" "")
7138 (div:SF (match_operand:SF 1 "register_operand" "")
7139 (match_operand:SF 2 "nonimmediate_operand" "")))]
7140 "TARGET_80387 || TARGET_SSE_MATH"
7141 "")
7142 \f
7143 ;; Remainder instructions.
7144
7145 (define_expand "divmoddi4"
7146 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7147 (div:DI (match_operand:DI 1 "register_operand" "")
7148 (match_operand:DI 2 "nonimmediate_operand" "")))
7149 (set (match_operand:DI 3 "register_operand" "")
7150 (mod:DI (match_dup 1) (match_dup 2)))
7151 (clobber (reg:CC 17))])]
7152 "TARGET_64BIT"
7153 "")
7154
7155 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7156 ;; Penalize eax case sligthly because it results in worse scheduling
7157 ;; of code.
7158 (define_insn "*divmoddi4_nocltd_rex64"
7159 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7160 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7161 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7162 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7163 (mod:DI (match_dup 2) (match_dup 3)))
7164 (clobber (reg:CC 17))]
7165 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7166 "#"
7167 [(set_attr "type" "multi")])
7168
7169 (define_insn "*divmoddi4_cltd_rex64"
7170 [(set (match_operand:DI 0 "register_operand" "=a")
7171 (div:DI (match_operand:DI 2 "register_operand" "a")
7172 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7173 (set (match_operand:DI 1 "register_operand" "=&d")
7174 (mod:DI (match_dup 2) (match_dup 3)))
7175 (clobber (reg:CC 17))]
7176 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7177 "#"
7178 [(set_attr "type" "multi")])
7179
7180 (define_insn "*divmoddi_noext_rex64"
7181 [(set (match_operand:DI 0 "register_operand" "=a")
7182 (div:DI (match_operand:DI 1 "register_operand" "0")
7183 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7184 (set (match_operand:DI 3 "register_operand" "=d")
7185 (mod:DI (match_dup 1) (match_dup 2)))
7186 (use (match_operand:DI 4 "register_operand" "3"))
7187 (clobber (reg:CC 17))]
7188 "TARGET_64BIT"
7189 "idiv{q}\t%2"
7190 [(set_attr "type" "idiv")
7191 (set_attr "mode" "DI")
7192 (set_attr "ppro_uops" "few")])
7193
7194 (define_split
7195 [(set (match_operand:DI 0 "register_operand" "")
7196 (div:DI (match_operand:DI 1 "register_operand" "")
7197 (match_operand:DI 2 "nonimmediate_operand" "")))
7198 (set (match_operand:DI 3 "register_operand" "")
7199 (mod:DI (match_dup 1) (match_dup 2)))
7200 (clobber (reg:CC 17))]
7201 "TARGET_64BIT && reload_completed"
7202 [(parallel [(set (match_dup 3)
7203 (ashiftrt:DI (match_dup 4) (const_int 63)))
7204 (clobber (reg:CC 17))])
7205 (parallel [(set (match_dup 0)
7206 (div:DI (reg:DI 0) (match_dup 2)))
7207 (set (match_dup 3)
7208 (mod:DI (reg:DI 0) (match_dup 2)))
7209 (use (match_dup 3))
7210 (clobber (reg:CC 17))])]
7211 {
7212 /* Avoid use of cltd in favour of a mov+shift. */
7213 if (!TARGET_USE_CLTD && !optimize_size)
7214 {
7215 if (true_regnum (operands[1]))
7216 emit_move_insn (operands[0], operands[1]);
7217 else
7218 emit_move_insn (operands[3], operands[1]);
7219 operands[4] = operands[3];
7220 }
7221 else
7222 {
7223 if (true_regnum (operands[1]))
7224 abort();
7225 operands[4] = operands[1];
7226 }
7227 })
7228
7229
7230 (define_expand "divmodsi4"
7231 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7232 (div:SI (match_operand:SI 1 "register_operand" "")
7233 (match_operand:SI 2 "nonimmediate_operand" "")))
7234 (set (match_operand:SI 3 "register_operand" "")
7235 (mod:SI (match_dup 1) (match_dup 2)))
7236 (clobber (reg:CC 17))])]
7237 ""
7238 "")
7239
7240 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7241 ;; Penalize eax case sligthly because it results in worse scheduling
7242 ;; of code.
7243 (define_insn "*divmodsi4_nocltd"
7244 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7245 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7246 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7247 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7248 (mod:SI (match_dup 2) (match_dup 3)))
7249 (clobber (reg:CC 17))]
7250 "!optimize_size && !TARGET_USE_CLTD"
7251 "#"
7252 [(set_attr "type" "multi")])
7253
7254 (define_insn "*divmodsi4_cltd"
7255 [(set (match_operand:SI 0 "register_operand" "=a")
7256 (div:SI (match_operand:SI 2 "register_operand" "a")
7257 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7258 (set (match_operand:SI 1 "register_operand" "=&d")
7259 (mod:SI (match_dup 2) (match_dup 3)))
7260 (clobber (reg:CC 17))]
7261 "optimize_size || TARGET_USE_CLTD"
7262 "#"
7263 [(set_attr "type" "multi")])
7264
7265 (define_insn "*divmodsi_noext"
7266 [(set (match_operand:SI 0 "register_operand" "=a")
7267 (div:SI (match_operand:SI 1 "register_operand" "0")
7268 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7269 (set (match_operand:SI 3 "register_operand" "=d")
7270 (mod:SI (match_dup 1) (match_dup 2)))
7271 (use (match_operand:SI 4 "register_operand" "3"))
7272 (clobber (reg:CC 17))]
7273 ""
7274 "idiv{l}\t%2"
7275 [(set_attr "type" "idiv")
7276 (set_attr "mode" "SI")
7277 (set_attr "ppro_uops" "few")])
7278
7279 (define_split
7280 [(set (match_operand:SI 0 "register_operand" "")
7281 (div:SI (match_operand:SI 1 "register_operand" "")
7282 (match_operand:SI 2 "nonimmediate_operand" "")))
7283 (set (match_operand:SI 3 "register_operand" "")
7284 (mod:SI (match_dup 1) (match_dup 2)))
7285 (clobber (reg:CC 17))]
7286 "reload_completed"
7287 [(parallel [(set (match_dup 3)
7288 (ashiftrt:SI (match_dup 4) (const_int 31)))
7289 (clobber (reg:CC 17))])
7290 (parallel [(set (match_dup 0)
7291 (div:SI (reg:SI 0) (match_dup 2)))
7292 (set (match_dup 3)
7293 (mod:SI (reg:SI 0) (match_dup 2)))
7294 (use (match_dup 3))
7295 (clobber (reg:CC 17))])]
7296 {
7297 /* Avoid use of cltd in favour of a mov+shift. */
7298 if (!TARGET_USE_CLTD && !optimize_size)
7299 {
7300 if (true_regnum (operands[1]))
7301 emit_move_insn (operands[0], operands[1]);
7302 else
7303 emit_move_insn (operands[3], operands[1]);
7304 operands[4] = operands[3];
7305 }
7306 else
7307 {
7308 if (true_regnum (operands[1]))
7309 abort();
7310 operands[4] = operands[1];
7311 }
7312 })
7313 ;; %%% Split me.
7314 (define_insn "divmodhi4"
7315 [(set (match_operand:HI 0 "register_operand" "=a")
7316 (div:HI (match_operand:HI 1 "register_operand" "0")
7317 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7318 (set (match_operand:HI 3 "register_operand" "=&d")
7319 (mod:HI (match_dup 1) (match_dup 2)))
7320 (clobber (reg:CC 17))]
7321 "TARGET_HIMODE_MATH"
7322 "cwtd\;idiv{w}\t%2"
7323 [(set_attr "type" "multi")
7324 (set_attr "length_immediate" "0")
7325 (set_attr "mode" "SI")])
7326
7327 (define_insn "udivmoddi4"
7328 [(set (match_operand:DI 0 "register_operand" "=a")
7329 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7330 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7331 (set (match_operand:DI 3 "register_operand" "=&d")
7332 (umod:DI (match_dup 1) (match_dup 2)))
7333 (clobber (reg:CC 17))]
7334 "TARGET_64BIT"
7335 "xor{q}\t%3, %3\;div{q}\t%2"
7336 [(set_attr "type" "multi")
7337 (set_attr "length_immediate" "0")
7338 (set_attr "mode" "DI")])
7339
7340 (define_insn "*udivmoddi4_noext"
7341 [(set (match_operand:DI 0 "register_operand" "=a")
7342 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7343 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7344 (set (match_operand:DI 3 "register_operand" "=d")
7345 (umod:DI (match_dup 1) (match_dup 2)))
7346 (use (match_dup 3))
7347 (clobber (reg:CC 17))]
7348 "TARGET_64BIT"
7349 "div{q}\t%2"
7350 [(set_attr "type" "idiv")
7351 (set_attr "ppro_uops" "few")
7352 (set_attr "mode" "DI")])
7353
7354 (define_split
7355 [(set (match_operand:DI 0 "register_operand" "")
7356 (udiv:DI (match_operand:DI 1 "register_operand" "")
7357 (match_operand:DI 2 "nonimmediate_operand" "")))
7358 (set (match_operand:DI 3 "register_operand" "")
7359 (umod:DI (match_dup 1) (match_dup 2)))
7360 (clobber (reg:CC 17))]
7361 "TARGET_64BIT && reload_completed"
7362 [(set (match_dup 3) (const_int 0))
7363 (parallel [(set (match_dup 0)
7364 (udiv:DI (match_dup 1) (match_dup 2)))
7365 (set (match_dup 3)
7366 (umod:DI (match_dup 1) (match_dup 2)))
7367 (use (match_dup 3))
7368 (clobber (reg:CC 17))])]
7369 "")
7370
7371 (define_insn "udivmodsi4"
7372 [(set (match_operand:SI 0 "register_operand" "=a")
7373 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7374 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7375 (set (match_operand:SI 3 "register_operand" "=&d")
7376 (umod:SI (match_dup 1) (match_dup 2)))
7377 (clobber (reg:CC 17))]
7378 ""
7379 "xor{l}\t%3, %3\;div{l}\t%2"
7380 [(set_attr "type" "multi")
7381 (set_attr "length_immediate" "0")
7382 (set_attr "mode" "SI")])
7383
7384 (define_insn "*udivmodsi4_noext"
7385 [(set (match_operand:SI 0 "register_operand" "=a")
7386 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7387 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7388 (set (match_operand:SI 3 "register_operand" "=d")
7389 (umod:SI (match_dup 1) (match_dup 2)))
7390 (use (match_dup 3))
7391 (clobber (reg:CC 17))]
7392 ""
7393 "div{l}\t%2"
7394 [(set_attr "type" "idiv")
7395 (set_attr "ppro_uops" "few")
7396 (set_attr "mode" "SI")])
7397
7398 (define_split
7399 [(set (match_operand:SI 0 "register_operand" "")
7400 (udiv:SI (match_operand:SI 1 "register_operand" "")
7401 (match_operand:SI 2 "nonimmediate_operand" "")))
7402 (set (match_operand:SI 3 "register_operand" "")
7403 (umod:SI (match_dup 1) (match_dup 2)))
7404 (clobber (reg:CC 17))]
7405 "reload_completed"
7406 [(set (match_dup 3) (const_int 0))
7407 (parallel [(set (match_dup 0)
7408 (udiv:SI (match_dup 1) (match_dup 2)))
7409 (set (match_dup 3)
7410 (umod:SI (match_dup 1) (match_dup 2)))
7411 (use (match_dup 3))
7412 (clobber (reg:CC 17))])]
7413 "")
7414
7415 (define_expand "udivmodhi4"
7416 [(set (match_dup 4) (const_int 0))
7417 (parallel [(set (match_operand:HI 0 "register_operand" "")
7418 (udiv:HI (match_operand:HI 1 "register_operand" "")
7419 (match_operand:HI 2 "nonimmediate_operand" "")))
7420 (set (match_operand:HI 3 "register_operand" "")
7421 (umod:HI (match_dup 1) (match_dup 2)))
7422 (use (match_dup 4))
7423 (clobber (reg:CC 17))])]
7424 "TARGET_HIMODE_MATH"
7425 "operands[4] = gen_reg_rtx (HImode);")
7426
7427 (define_insn "*udivmodhi_noext"
7428 [(set (match_operand:HI 0 "register_operand" "=a")
7429 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7430 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7431 (set (match_operand:HI 3 "register_operand" "=d")
7432 (umod:HI (match_dup 1) (match_dup 2)))
7433 (use (match_operand:HI 4 "register_operand" "3"))
7434 (clobber (reg:CC 17))]
7435 ""
7436 "div{w}\t%2"
7437 [(set_attr "type" "idiv")
7438 (set_attr "mode" "HI")
7439 (set_attr "ppro_uops" "few")])
7440
7441 ;; We can not use div/idiv for double division, because it causes
7442 ;; "division by zero" on the overflow and that's not what we expect
7443 ;; from truncate. Because true (non truncating) double division is
7444 ;; never generated, we can't create this insn anyway.
7445 ;
7446 ;(define_insn ""
7447 ; [(set (match_operand:SI 0 "register_operand" "=a")
7448 ; (truncate:SI
7449 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7450 ; (zero_extend:DI
7451 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7452 ; (set (match_operand:SI 3 "register_operand" "=d")
7453 ; (truncate:SI
7454 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7455 ; (clobber (reg:CC 17))]
7456 ; ""
7457 ; "div{l}\t{%2, %0|%0, %2}"
7458 ; [(set_attr "type" "idiv")
7459 ; (set_attr "ppro_uops" "few")])
7460 \f
7461 ;;- Logical AND instructions
7462
7463 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7464 ;; Note that this excludes ah.
7465
7466 (define_insn "*testdi_1_rex64"
7467 [(set (reg 17)
7468 (compare
7469 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
7470 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
7471 (const_int 0)))]
7472 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7473 "@
7474 test{l}\t{%k1, %k0|%k0, %k1}
7475 test{l}\t{%k1, %k0|%k0, %k1}
7476 test{q}\t{%1, %0|%0, %1}
7477 test{q}\t{%1, %0|%0, %1}
7478 test{q}\t{%1, %0|%0, %1}"
7479 [(set_attr "type" "test")
7480 (set_attr "modrm" "0,1,0,1,1")
7481 (set_attr "mode" "SI,SI,DI,DI,DI")
7482 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7483
7484 (define_insn "testsi_1"
7485 [(set (reg 17)
7486 (compare
7487 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
7488 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
7489 (const_int 0)))]
7490 "ix86_match_ccmode (insn, CCNOmode)"
7491 "test{l}\t{%1, %0|%0, %1}"
7492 [(set_attr "type" "test")
7493 (set_attr "modrm" "0,1,1")
7494 (set_attr "mode" "SI")
7495 (set_attr "pent_pair" "uv,np,uv")])
7496
7497 (define_expand "testsi_ccno_1"
7498 [(set (reg:CCNO 17)
7499 (compare:CCNO
7500 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7501 (match_operand:SI 1 "nonmemory_operand" ""))
7502 (const_int 0)))]
7503 ""
7504 "")
7505
7506 (define_insn "*testhi_1"
7507 [(set (reg 17)
7508 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
7509 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
7510 (const_int 0)))]
7511 "ix86_match_ccmode (insn, CCNOmode)"
7512 "test{w}\t{%1, %0|%0, %1}"
7513 [(set_attr "type" "test")
7514 (set_attr "modrm" "0,1,1")
7515 (set_attr "mode" "HI")
7516 (set_attr "pent_pair" "uv,np,uv")])
7517
7518 (define_expand "testqi_ccz_1"
7519 [(set (reg:CCZ 17)
7520 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7521 (match_operand:QI 1 "nonmemory_operand" ""))
7522 (const_int 0)))]
7523 ""
7524 "")
7525
7526 (define_insn "*testqi_1"
7527 [(set (reg 17)
7528 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
7529 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
7530 (const_int 0)))]
7531 "ix86_match_ccmode (insn, CCNOmode)"
7532 {
7533 if (which_alternative == 3)
7534 {
7535 if (GET_CODE (operands[1]) == CONST_INT
7536 && (INTVAL (operands[1]) & 0xffffff00))
7537 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7538 return "test{l}\t{%1, %k0|%k0, %1}";
7539 }
7540 return "test{b}\t{%1, %0|%0, %1}";
7541 }
7542 [(set_attr "type" "test")
7543 (set_attr "modrm" "0,1,1,1")
7544 (set_attr "mode" "QI,QI,QI,SI")
7545 (set_attr "pent_pair" "uv,np,uv,np")])
7546
7547 (define_expand "testqi_ext_ccno_0"
7548 [(set (reg:CCNO 17)
7549 (compare:CCNO
7550 (and:SI
7551 (zero_extract:SI
7552 (match_operand 0 "ext_register_operand" "")
7553 (const_int 8)
7554 (const_int 8))
7555 (match_operand 1 "const_int_operand" ""))
7556 (const_int 0)))]
7557 ""
7558 "")
7559
7560 (define_insn "*testqi_ext_0"
7561 [(set (reg 17)
7562 (compare
7563 (and:SI
7564 (zero_extract:SI
7565 (match_operand 0 "ext_register_operand" "Q")
7566 (const_int 8)
7567 (const_int 8))
7568 (match_operand 1 "const_int_operand" "n"))
7569 (const_int 0)))]
7570 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
7571 && ix86_match_ccmode (insn, CCNOmode)"
7572 "test{b}\t{%1, %h0|%h0, %1}"
7573 [(set_attr "type" "test")
7574 (set_attr "mode" "QI")
7575 (set_attr "length_immediate" "1")
7576 (set_attr "pent_pair" "np")])
7577
7578 (define_insn "*testqi_ext_1"
7579 [(set (reg 17)
7580 (compare
7581 (and:SI
7582 (zero_extract:SI
7583 (match_operand 0 "ext_register_operand" "Q")
7584 (const_int 8)
7585 (const_int 8))
7586 (zero_extend:SI
7587 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
7588 (const_int 0)))]
7589 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7590 "test{b}\t{%1, %h0|%h0, %1}"
7591 [(set_attr "type" "test")
7592 (set_attr "mode" "QI")])
7593
7594 (define_insn "*testqi_ext_1_rex64"
7595 [(set (reg 17)
7596 (compare
7597 (and:SI
7598 (zero_extract:SI
7599 (match_operand 0 "ext_register_operand" "Q")
7600 (const_int 8)
7601 (const_int 8))
7602 (zero_extend:SI
7603 (match_operand:QI 1 "register_operand" "Q")))
7604 (const_int 0)))]
7605 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7606 "test{b}\t{%1, %h0|%h0, %1}"
7607 [(set_attr "type" "test")
7608 (set_attr "mode" "QI")])
7609
7610 (define_insn "*testqi_ext_2"
7611 [(set (reg 17)
7612 (compare
7613 (and:SI
7614 (zero_extract:SI
7615 (match_operand 0 "ext_register_operand" "Q")
7616 (const_int 8)
7617 (const_int 8))
7618 (zero_extract:SI
7619 (match_operand 1 "ext_register_operand" "Q")
7620 (const_int 8)
7621 (const_int 8)))
7622 (const_int 0)))]
7623 "ix86_match_ccmode (insn, CCNOmode)"
7624 "test{b}\t{%h1, %h0|%h0, %h1}"
7625 [(set_attr "type" "test")
7626 (set_attr "mode" "QI")])
7627
7628 ;; Combine likes to form bit extractions for some tests. Humor it.
7629 (define_insn "*testqi_ext_3"
7630 [(set (reg 17)
7631 (compare (zero_extract:SI
7632 (match_operand 0 "nonimmediate_operand" "rm")
7633 (match_operand:SI 1 "const_int_operand" "")
7634 (match_operand:SI 2 "const_int_operand" ""))
7635 (const_int 0)))]
7636 "ix86_match_ccmode (insn, CCNOmode)
7637 && (GET_MODE (operands[0]) == SImode
7638 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7639 || GET_MODE (operands[0]) == HImode
7640 || GET_MODE (operands[0]) == QImode)"
7641 "#")
7642
7643 (define_insn "*testqi_ext_3_rex64"
7644 [(set (reg 17)
7645 (compare (zero_extract:DI
7646 (match_operand 0 "nonimmediate_operand" "rm")
7647 (match_operand:DI 1 "const_int_operand" "")
7648 (match_operand:DI 2 "const_int_operand" ""))
7649 (const_int 0)))]
7650 "TARGET_64BIT
7651 && ix86_match_ccmode (insn, CCNOmode)
7652 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7653 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7654 /* Ensure that resulting mask is zero or sign extended operand. */
7655 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7656 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7657 && INTVAL (operands[1]) > 32))
7658 && (GET_MODE (operands[0]) == SImode
7659 || GET_MODE (operands[0]) == DImode
7660 || GET_MODE (operands[0]) == HImode
7661 || GET_MODE (operands[0]) == QImode)"
7662 "#")
7663
7664 (define_split
7665 [(set (reg 17)
7666 (compare (zero_extract
7667 (match_operand 0 "nonimmediate_operand" "")
7668 (match_operand 1 "const_int_operand" "")
7669 (match_operand 2 "const_int_operand" ""))
7670 (const_int 0)))]
7671 "ix86_match_ccmode (insn, CCNOmode)"
7672 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7673 {
7674 HOST_WIDE_INT len = INTVAL (operands[1]);
7675 HOST_WIDE_INT pos = INTVAL (operands[2]);
7676 HOST_WIDE_INT mask;
7677 enum machine_mode mode, submode;
7678
7679 mode = GET_MODE (operands[0]);
7680 if (GET_CODE (operands[0]) == MEM)
7681 {
7682 /* ??? Combine likes to put non-volatile mem extractions in QImode
7683 no matter the size of the test. So find a mode that works. */
7684 if (! MEM_VOLATILE_P (operands[0]))
7685 {
7686 mode = smallest_mode_for_size (pos + len, MODE_INT);
7687 operands[0] = adjust_address (operands[0], mode, 0);
7688 }
7689 }
7690 else if (GET_CODE (operands[0]) == SUBREG
7691 && (submode = GET_MODE (SUBREG_REG (operands[0])),
7692 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7693 && pos + len <= GET_MODE_BITSIZE (submode))
7694 {
7695 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7696 mode = submode;
7697 operands[0] = SUBREG_REG (operands[0]);
7698 }
7699 else if (mode == HImode && pos + len <= 8)
7700 {
7701 /* Small HImode tests can be converted to QImode. */
7702 mode = QImode;
7703 operands[0] = gen_lowpart (QImode, operands[0]);
7704 }
7705
7706 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7707 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7708
7709 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
7710 })
7711
7712 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7713 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7714 ;; this is relatively important trick.
7715 ;; Do the converison only post-reload to avoid limiting of the register class
7716 ;; to QI regs.
7717 (define_split
7718 [(set (reg 17)
7719 (compare
7720 (and (match_operand 0 "register_operand" "")
7721 (match_operand 1 "const_int_operand" ""))
7722 (const_int 0)))]
7723 "(!TARGET_PROMOTE_QImode || optimize_size)
7724 && reload_completed
7725 && QI_REG_P (operands[0])
7726 && ((ix86_match_ccmode (insn, CCZmode)
7727 && !(INTVAL (operands[1]) & ~(255 << 8)))
7728 || (ix86_match_ccmode (insn, CCNOmode)
7729 && !(INTVAL (operands[1]) & ~(127 << 8))))
7730 && GET_MODE (operands[0]) != QImode"
7731 [(set (reg:CCNO 17)
7732 (compare:CCNO
7733 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7734 (match_dup 1))
7735 (const_int 0)))]
7736 "operands[0] = gen_lowpart (SImode, operands[0]);
7737 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
7738
7739 (define_split
7740 [(set (reg 17)
7741 (compare
7742 (and (match_operand 0 "nonimmediate_operand" "")
7743 (match_operand 1 "const_int_operand" ""))
7744 (const_int 0)))]
7745 "(!TARGET_PROMOTE_QImode || optimize_size)
7746 && reload_completed
7747 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
7748 && ((ix86_match_ccmode (insn, CCZmode)
7749 && !(INTVAL (operands[1]) & ~255))
7750 || (ix86_match_ccmode (insn, CCNOmode)
7751 && !(INTVAL (operands[1]) & ~127)))
7752 && GET_MODE (operands[0]) != QImode"
7753 [(set (reg:CCNO 17)
7754 (compare:CCNO
7755 (and:QI (match_dup 0)
7756 (match_dup 1))
7757 (const_int 0)))]
7758 "operands[0] = gen_lowpart (QImode, operands[0]);
7759 operands[1] = gen_lowpart (QImode, operands[1]);")
7760
7761
7762 ;; %%% This used to optimize known byte-wide and operations to memory,
7763 ;; and sometimes to QImode registers. If this is considered useful,
7764 ;; it should be done with splitters.
7765
7766 (define_expand "anddi3"
7767 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7768 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7769 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7770 (clobber (reg:CC 17))]
7771 "TARGET_64BIT"
7772 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7773
7774 (define_insn "*anddi_1_rex64"
7775 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7776 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7777 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7778 (clobber (reg:CC 17))]
7779 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7780 {
7781 switch (get_attr_type (insn))
7782 {
7783 case TYPE_IMOVX:
7784 {
7785 enum machine_mode mode;
7786
7787 if (GET_CODE (operands[2]) != CONST_INT)
7788 abort ();
7789 if (INTVAL (operands[2]) == 0xff)
7790 mode = QImode;
7791 else if (INTVAL (operands[2]) == 0xffff)
7792 mode = HImode;
7793 else
7794 abort ();
7795
7796 operands[1] = gen_lowpart (mode, operands[1]);
7797 if (mode == QImode)
7798 return "movz{bq|x}\t{%1,%0|%0, %1}";
7799 else
7800 return "movz{wq|x}\t{%1,%0|%0, %1}";
7801 }
7802
7803 default:
7804 if (! rtx_equal_p (operands[0], operands[1]))
7805 abort ();
7806 if (get_attr_mode (insn) == MODE_SI)
7807 return "and{l}\t{%k2, %k0|%k0, %k2}";
7808 else
7809 return "and{q}\t{%2, %0|%0, %2}";
7810 }
7811 }
7812 [(set_attr "type" "alu,alu,alu,imovx")
7813 (set_attr "length_immediate" "*,*,*,0")
7814 (set_attr "mode" "SI,DI,DI,DI")])
7815
7816 (define_insn "*anddi_2"
7817 [(set (reg 17)
7818 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7819 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7820 (const_int 0)))
7821 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7822 (and:DI (match_dup 1) (match_dup 2)))]
7823 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7824 && ix86_binary_operator_ok (AND, DImode, operands)"
7825 "@
7826 and{l}\t{%k2, %k0|%k0, %k2}
7827 and{q}\t{%2, %0|%0, %2}
7828 and{q}\t{%2, %0|%0, %2}"
7829 [(set_attr "type" "alu")
7830 (set_attr "mode" "SI,DI,DI")])
7831
7832 (define_expand "andsi3"
7833 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7834 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7835 (match_operand:SI 2 "general_operand" "")))
7836 (clobber (reg:CC 17))]
7837 ""
7838 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7839
7840 (define_insn "*andsi_1"
7841 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7842 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7843 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7844 (clobber (reg:CC 17))]
7845 "ix86_binary_operator_ok (AND, SImode, operands)"
7846 {
7847 switch (get_attr_type (insn))
7848 {
7849 case TYPE_IMOVX:
7850 {
7851 enum machine_mode mode;
7852
7853 if (GET_CODE (operands[2]) != CONST_INT)
7854 abort ();
7855 if (INTVAL (operands[2]) == 0xff)
7856 mode = QImode;
7857 else if (INTVAL (operands[2]) == 0xffff)
7858 mode = HImode;
7859 else
7860 abort ();
7861
7862 operands[1] = gen_lowpart (mode, operands[1]);
7863 if (mode == QImode)
7864 return "movz{bl|x}\t{%1,%0|%0, %1}";
7865 else
7866 return "movz{wl|x}\t{%1,%0|%0, %1}";
7867 }
7868
7869 default:
7870 if (! rtx_equal_p (operands[0], operands[1]))
7871 abort ();
7872 return "and{l}\t{%2, %0|%0, %2}";
7873 }
7874 }
7875 [(set_attr "type" "alu,alu,imovx")
7876 (set_attr "length_immediate" "*,*,0")
7877 (set_attr "mode" "SI")])
7878
7879 (define_split
7880 [(set (match_operand 0 "register_operand" "")
7881 (and (match_dup 0)
7882 (const_int -65536)))
7883 (clobber (reg:CC 17))]
7884 "optimize_size"
7885 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7886 "operands[1] = gen_lowpart (HImode, operands[0]);")
7887
7888 (define_split
7889 [(set (match_operand 0 "ext_register_operand" "")
7890 (and (match_dup 0)
7891 (const_int -256)))
7892 (clobber (reg:CC 17))]
7893 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
7894 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895 "operands[1] = gen_lowpart (QImode, operands[0]);")
7896
7897 (define_split
7898 [(set (match_operand 0 "ext_register_operand" "")
7899 (and (match_dup 0)
7900 (const_int -65281)))
7901 (clobber (reg:CC 17))]
7902 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
7903 [(parallel [(set (zero_extract:SI (match_dup 0)
7904 (const_int 8)
7905 (const_int 8))
7906 (xor:SI
7907 (zero_extract:SI (match_dup 0)
7908 (const_int 8)
7909 (const_int 8))
7910 (zero_extract:SI (match_dup 0)
7911 (const_int 8)
7912 (const_int 8))))
7913 (clobber (reg:CC 17))])]
7914 "operands[0] = gen_lowpart (SImode, operands[0]);")
7915
7916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7917 (define_insn "*andsi_1_zext"
7918 [(set (match_operand:DI 0 "register_operand" "=r")
7919 (zero_extend:DI
7920 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7921 (match_operand:SI 2 "general_operand" "rim"))))
7922 (clobber (reg:CC 17))]
7923 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7924 "and{l}\t{%2, %k0|%k0, %2}"
7925 [(set_attr "type" "alu")
7926 (set_attr "mode" "SI")])
7927
7928 (define_insn "*andsi_2"
7929 [(set (reg 17)
7930 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
7931 (match_operand:SI 2 "general_operand" "rim,ri"))
7932 (const_int 0)))
7933 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
7934 (and:SI (match_dup 1) (match_dup 2)))]
7935 "ix86_match_ccmode (insn, CCNOmode)
7936 && ix86_binary_operator_ok (AND, SImode, operands)"
7937 "and{l}\t{%2, %0|%0, %2}"
7938 [(set_attr "type" "alu")
7939 (set_attr "mode" "SI")])
7940
7941 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7942 (define_insn "*andsi_2_zext"
7943 [(set (reg 17)
7944 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7945 (match_operand:SI 2 "general_operand" "rim"))
7946 (const_int 0)))
7947 (set (match_operand:DI 0 "register_operand" "=r")
7948 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7949 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7950 && ix86_binary_operator_ok (AND, SImode, operands)"
7951 "and{l}\t{%2, %k0|%k0, %2}"
7952 [(set_attr "type" "alu")
7953 (set_attr "mode" "SI")])
7954
7955 (define_expand "andhi3"
7956 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7957 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
7958 (match_operand:HI 2 "general_operand" "")))
7959 (clobber (reg:CC 17))]
7960 "TARGET_HIMODE_MATH"
7961 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
7962
7963 (define_insn "*andhi_1"
7964 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7965 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7966 (match_operand:HI 2 "general_operand" "ri,rm,L")))
7967 (clobber (reg:CC 17))]
7968 "ix86_binary_operator_ok (AND, HImode, operands)"
7969 {
7970 switch (get_attr_type (insn))
7971 {
7972 case TYPE_IMOVX:
7973 if (GET_CODE (operands[2]) != CONST_INT)
7974 abort ();
7975 if (INTVAL (operands[2]) == 0xff)
7976 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7977 abort ();
7978
7979 default:
7980 if (! rtx_equal_p (operands[0], operands[1]))
7981 abort ();
7982
7983 return "and{w}\t{%2, %0|%0, %2}";
7984 }
7985 }
7986 [(set_attr "type" "alu,alu,imovx")
7987 (set_attr "length_immediate" "*,*,0")
7988 (set_attr "mode" "HI,HI,SI")])
7989
7990 (define_insn "*andhi_2"
7991 [(set (reg 17)
7992 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7993 (match_operand:HI 2 "general_operand" "rim,ri"))
7994 (const_int 0)))
7995 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7996 (and:HI (match_dup 1) (match_dup 2)))]
7997 "ix86_match_ccmode (insn, CCNOmode)
7998 && ix86_binary_operator_ok (AND, HImode, operands)"
7999 "and{w}\t{%2, %0|%0, %2}"
8000 [(set_attr "type" "alu")
8001 (set_attr "mode" "HI")])
8002
8003 (define_expand "andqi3"
8004 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8005 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8006 (match_operand:QI 2 "general_operand" "")))
8007 (clobber (reg:CC 17))]
8008 "TARGET_QIMODE_MATH"
8009 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8010
8011 ;; %%% Potential partial reg stall on alternative 2. What to do?
8012 (define_insn "*andqi_1"
8013 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8014 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8015 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8016 (clobber (reg:CC 17))]
8017 "ix86_binary_operator_ok (AND, QImode, operands)"
8018 "@
8019 and{b}\t{%2, %0|%0, %2}
8020 and{b}\t{%2, %0|%0, %2}
8021 and{l}\t{%k2, %k0|%k0, %k2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "mode" "QI,QI,SI")])
8024
8025 (define_insn "*andqi_1_slp"
8026 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8027 (and:QI (match_dup 0)
8028 (match_operand:QI 1 "general_operand" "qi,qmi")))
8029 (clobber (reg:CC 17))]
8030 ""
8031 "and{b}\t{%1, %0|%0, %1}"
8032 [(set_attr "type" "alu1")
8033 (set_attr "mode" "QI")])
8034
8035 (define_insn "*andqi_2"
8036 [(set (reg 17)
8037 (compare (and:QI
8038 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8039 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8040 (const_int 0)))
8041 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8042 (and:QI (match_dup 1) (match_dup 2)))]
8043 "ix86_match_ccmode (insn, CCNOmode)
8044 && ix86_binary_operator_ok (AND, QImode, operands)"
8045 {
8046 if (which_alternative == 2)
8047 {
8048 if (GET_CODE (operands[2]) == CONST_INT
8049 && (INTVAL (operands[2]) & 0xffffff00))
8050 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8051 return "and{l}\t{%2, %k0|%k0, %2}";
8052 }
8053 return "and{b}\t{%2, %0|%0, %2}";
8054 }
8055 [(set_attr "type" "alu")
8056 (set_attr "mode" "QI,QI,SI")])
8057
8058 (define_insn "*andqi_2_slp"
8059 [(set (reg 17)
8060 (compare (and:QI
8061 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8062 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8063 (const_int 0)))
8064 (set (strict_low_part (match_dup 0))
8065 (and:QI (match_dup 0) (match_dup 1)))]
8066 "ix86_match_ccmode (insn, CCNOmode)"
8067 "and{b}\t{%1, %0|%0, %1}"
8068 [(set_attr "type" "alu1")
8069 (set_attr "mode" "QI")])
8070
8071 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8072 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8073 ;; for a QImode operand, which of course failed.
8074
8075 (define_insn "andqi_ext_0"
8076 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8077 (const_int 8)
8078 (const_int 8))
8079 (and:SI
8080 (zero_extract:SI
8081 (match_operand 1 "ext_register_operand" "0")
8082 (const_int 8)
8083 (const_int 8))
8084 (match_operand 2 "const_int_operand" "n")))
8085 (clobber (reg:CC 17))]
8086 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8087 "and{b}\t{%2, %h0|%h0, %2}"
8088 [(set_attr "type" "alu")
8089 (set_attr "length_immediate" "1")
8090 (set_attr "mode" "QI")])
8091
8092 ;; Generated by peephole translating test to and. This shows up
8093 ;; often in fp comparisons.
8094
8095 (define_insn "*andqi_ext_0_cc"
8096 [(set (reg 17)
8097 (compare
8098 (and:SI
8099 (zero_extract:SI
8100 (match_operand 1 "ext_register_operand" "0")
8101 (const_int 8)
8102 (const_int 8))
8103 (match_operand 2 "const_int_operand" "n"))
8104 (const_int 0)))
8105 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8106 (const_int 8)
8107 (const_int 8))
8108 (and:SI
8109 (zero_extract:SI
8110 (match_dup 1)
8111 (const_int 8)
8112 (const_int 8))
8113 (match_dup 2)))]
8114 "ix86_match_ccmode (insn, CCNOmode)
8115 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8116 "and{b}\t{%2, %h0|%h0, %2}"
8117 [(set_attr "type" "alu")
8118 (set_attr "length_immediate" "1")
8119 (set_attr "mode" "QI")])
8120
8121 (define_insn "*andqi_ext_1"
8122 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8123 (const_int 8)
8124 (const_int 8))
8125 (and:SI
8126 (zero_extract:SI
8127 (match_operand 1 "ext_register_operand" "0")
8128 (const_int 8)
8129 (const_int 8))
8130 (zero_extend:SI
8131 (match_operand:QI 2 "general_operand" "Qm"))))
8132 (clobber (reg:CC 17))]
8133 "!TARGET_64BIT"
8134 "and{b}\t{%2, %h0|%h0, %2}"
8135 [(set_attr "type" "alu")
8136 (set_attr "length_immediate" "0")
8137 (set_attr "mode" "QI")])
8138
8139 (define_insn "*andqi_ext_1_rex64"
8140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8141 (const_int 8)
8142 (const_int 8))
8143 (and:SI
8144 (zero_extract:SI
8145 (match_operand 1 "ext_register_operand" "0")
8146 (const_int 8)
8147 (const_int 8))
8148 (zero_extend:SI
8149 (match_operand 2 "ext_register_operand" "Q"))))
8150 (clobber (reg:CC 17))]
8151 "TARGET_64BIT"
8152 "and{b}\t{%2, %h0|%h0, %2}"
8153 [(set_attr "type" "alu")
8154 (set_attr "length_immediate" "0")
8155 (set_attr "mode" "QI")])
8156
8157 (define_insn "*andqi_ext_2"
8158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8159 (const_int 8)
8160 (const_int 8))
8161 (and:SI
8162 (zero_extract:SI
8163 (match_operand 1 "ext_register_operand" "%0")
8164 (const_int 8)
8165 (const_int 8))
8166 (zero_extract:SI
8167 (match_operand 2 "ext_register_operand" "Q")
8168 (const_int 8)
8169 (const_int 8))))
8170 (clobber (reg:CC 17))]
8171 ""
8172 "and{b}\t{%h2, %h0|%h0, %h2}"
8173 [(set_attr "type" "alu")
8174 (set_attr "length_immediate" "0")
8175 (set_attr "mode" "QI")])
8176 \f
8177 ;; Logical inclusive OR instructions
8178
8179 ;; %%% This used to optimize known byte-wide and operations to memory.
8180 ;; If this is considered useful, it should be done with splitters.
8181
8182 (define_expand "iordi3"
8183 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8184 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8185 (match_operand:DI 2 "x86_64_general_operand" "")))
8186 (clobber (reg:CC 17))]
8187 "TARGET_64BIT"
8188 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8189
8190 (define_insn "*iordi_1_rex64"
8191 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8192 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8193 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8194 (clobber (reg:CC 17))]
8195 "TARGET_64BIT
8196 && ix86_binary_operator_ok (IOR, DImode, operands)"
8197 "or{q}\t{%2, %0|%0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "mode" "DI")])
8200
8201 (define_insn "*iordi_2_rex64"
8202 [(set (reg 17)
8203 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8204 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8205 (const_int 0)))
8206 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8207 (ior:DI (match_dup 1) (match_dup 2)))]
8208 "TARGET_64BIT
8209 && ix86_match_ccmode (insn, CCNOmode)
8210 && ix86_binary_operator_ok (IOR, DImode, operands)"
8211 "or{q}\t{%2, %0|%0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "DI")])
8214
8215 (define_insn "*iordi_3_rex64"
8216 [(set (reg 17)
8217 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8218 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8219 (const_int 0)))
8220 (clobber (match_scratch:DI 0 "=r"))]
8221 "TARGET_64BIT
8222 && ix86_match_ccmode (insn, CCNOmode)
8223 && ix86_binary_operator_ok (IOR, DImode, operands)"
8224 "or{q}\t{%2, %0|%0, %2}"
8225 [(set_attr "type" "alu")
8226 (set_attr "mode" "DI")])
8227
8228
8229 (define_expand "iorsi3"
8230 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8231 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8232 (match_operand:SI 2 "general_operand" "")))
8233 (clobber (reg:CC 17))]
8234 ""
8235 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8236
8237 (define_insn "*iorsi_1"
8238 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8239 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8240 (match_operand:SI 2 "general_operand" "ri,rmi")))
8241 (clobber (reg:CC 17))]
8242 "ix86_binary_operator_ok (IOR, SImode, operands)"
8243 "or{l}\t{%2, %0|%0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "mode" "SI")])
8246
8247 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8248 (define_insn "*iorsi_1_zext"
8249 [(set (match_operand:DI 0 "register_operand" "=rm")
8250 (zero_extend:DI
8251 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8252 (match_operand:SI 2 "general_operand" "rim"))))
8253 (clobber (reg:CC 17))]
8254 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8255 "or{l}\t{%2, %k0|%k0, %2}"
8256 [(set_attr "type" "alu")
8257 (set_attr "mode" "SI")])
8258
8259 (define_insn "*iorsi_1_zext_imm"
8260 [(set (match_operand:DI 0 "register_operand" "=rm")
8261 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8262 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8263 (clobber (reg:CC 17))]
8264 "TARGET_64BIT"
8265 "or{l}\t{%2, %k0|%k0, %2}"
8266 [(set_attr "type" "alu")
8267 (set_attr "mode" "SI")])
8268
8269 (define_insn "*iorsi_2"
8270 [(set (reg 17)
8271 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8272 (match_operand:SI 2 "general_operand" "rim,ri"))
8273 (const_int 0)))
8274 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8275 (ior:SI (match_dup 1) (match_dup 2)))]
8276 "ix86_match_ccmode (insn, CCNOmode)
8277 && ix86_binary_operator_ok (IOR, SImode, operands)"
8278 "or{l}\t{%2, %0|%0, %2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "mode" "SI")])
8281
8282 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8283 ;; ??? Special case for immediate operand is missing - it is tricky.
8284 (define_insn "*iorsi_2_zext"
8285 [(set (reg 17)
8286 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8287 (match_operand:SI 2 "general_operand" "rim"))
8288 (const_int 0)))
8289 (set (match_operand:DI 0 "register_operand" "=r")
8290 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8291 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8292 && ix86_binary_operator_ok (IOR, SImode, operands)"
8293 "or{l}\t{%2, %k0|%k0, %2}"
8294 [(set_attr "type" "alu")
8295 (set_attr "mode" "SI")])
8296
8297 (define_insn "*iorsi_2_zext_imm"
8298 [(set (reg 17)
8299 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8300 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8301 (const_int 0)))
8302 (set (match_operand:DI 0 "register_operand" "=r")
8303 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8304 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8305 && ix86_binary_operator_ok (IOR, SImode, operands)"
8306 "or{l}\t{%2, %k0|%k0, %2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "SI")])
8309
8310 (define_insn "*iorsi_3"
8311 [(set (reg 17)
8312 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8313 (match_operand:SI 2 "general_operand" "rim"))
8314 (const_int 0)))
8315 (clobber (match_scratch:SI 0 "=r"))]
8316 "ix86_match_ccmode (insn, CCNOmode)
8317 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8318 "or{l}\t{%2, %0|%0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "SI")])
8321
8322 (define_expand "iorhi3"
8323 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8324 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8325 (match_operand:HI 2 "general_operand" "")))
8326 (clobber (reg:CC 17))]
8327 "TARGET_HIMODE_MATH"
8328 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8329
8330 (define_insn "*iorhi_1"
8331 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8332 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8333 (match_operand:HI 2 "general_operand" "rmi,ri")))
8334 (clobber (reg:CC 17))]
8335 "ix86_binary_operator_ok (IOR, HImode, operands)"
8336 "or{w}\t{%2, %0|%0, %2}"
8337 [(set_attr "type" "alu")
8338 (set_attr "mode" "HI")])
8339
8340 (define_insn "*iorhi_2"
8341 [(set (reg 17)
8342 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8343 (match_operand:HI 2 "general_operand" "rim,ri"))
8344 (const_int 0)))
8345 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8346 (ior:HI (match_dup 1) (match_dup 2)))]
8347 "ix86_match_ccmode (insn, CCNOmode)
8348 && ix86_binary_operator_ok (IOR, HImode, operands)"
8349 "or{w}\t{%2, %0|%0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "mode" "HI")])
8352
8353 (define_insn "*iorhi_3"
8354 [(set (reg 17)
8355 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8356 (match_operand:HI 2 "general_operand" "rim"))
8357 (const_int 0)))
8358 (clobber (match_scratch:HI 0 "=r"))]
8359 "ix86_match_ccmode (insn, CCNOmode)
8360 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8361 "or{w}\t{%2, %0|%0, %2}"
8362 [(set_attr "type" "alu")
8363 (set_attr "mode" "HI")])
8364
8365 (define_expand "iorqi3"
8366 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8367 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8368 (match_operand:QI 2 "general_operand" "")))
8369 (clobber (reg:CC 17))]
8370 "TARGET_QIMODE_MATH"
8371 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8372
8373 ;; %%% Potential partial reg stall on alternative 2. What to do?
8374 (define_insn "*iorqi_1"
8375 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8376 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8377 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8378 (clobber (reg:CC 17))]
8379 "ix86_binary_operator_ok (IOR, QImode, operands)"
8380 "@
8381 or{b}\t{%2, %0|%0, %2}
8382 or{b}\t{%2, %0|%0, %2}
8383 or{l}\t{%k2, %k0|%k0, %k2}"
8384 [(set_attr "type" "alu")
8385 (set_attr "mode" "QI,QI,SI")])
8386
8387 (define_insn "*iorqi_1_slp"
8388 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8389 (ior:QI (match_dup 0)
8390 (match_operand:QI 1 "general_operand" "qmi,qi")))
8391 (clobber (reg:CC 17))]
8392 ""
8393 "or{b}\t{%1, %0|%0, %1}"
8394 [(set_attr "type" "alu1")
8395 (set_attr "mode" "QI")])
8396
8397 (define_insn "*iorqi_2"
8398 [(set (reg 17)
8399 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8400 (match_operand:QI 2 "general_operand" "qim,qi"))
8401 (const_int 0)))
8402 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8403 (ior:QI (match_dup 1) (match_dup 2)))]
8404 "ix86_match_ccmode (insn, CCNOmode)
8405 && ix86_binary_operator_ok (IOR, QImode, operands)"
8406 "or{b}\t{%2, %0|%0, %2}"
8407 [(set_attr "type" "alu")
8408 (set_attr "mode" "QI")])
8409
8410 (define_insn "*iorqi_2_slp"
8411 [(set (reg 17)
8412 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8413 (match_operand:QI 1 "general_operand" "qim,qi"))
8414 (const_int 0)))
8415 (set (strict_low_part (match_dup 0))
8416 (ior:QI (match_dup 0) (match_dup 1)))]
8417 "ix86_match_ccmode (insn, CCNOmode)"
8418 "or{b}\t{%1, %0|%0, %1}"
8419 [(set_attr "type" "alu1")
8420 (set_attr "mode" "QI")])
8421
8422 (define_insn "*iorqi_3"
8423 [(set (reg 17)
8424 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8425 (match_operand:QI 2 "general_operand" "qim"))
8426 (const_int 0)))
8427 (clobber (match_scratch:QI 0 "=q"))]
8428 "ix86_match_ccmode (insn, CCNOmode)
8429 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8430 "or{b}\t{%2, %0|%0, %2}"
8431 [(set_attr "type" "alu")
8432 (set_attr "mode" "QI")])
8433
8434 \f
8435 ;; Logical XOR instructions
8436
8437 ;; %%% This used to optimize known byte-wide and operations to memory.
8438 ;; If this is considered useful, it should be done with splitters.
8439
8440 (define_expand "xordi3"
8441 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8442 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8443 (match_operand:DI 2 "x86_64_general_operand" "")))
8444 (clobber (reg:CC 17))]
8445 "TARGET_64BIT"
8446 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8447
8448 (define_insn "*xordi_1_rex64"
8449 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8450 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8451 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8452 (clobber (reg:CC 17))]
8453 "TARGET_64BIT
8454 && ix86_binary_operator_ok (XOR, DImode, operands)"
8455 "@
8456 xor{q}\t{%2, %0|%0, %2}
8457 xor{q}\t{%2, %0|%0, %2}"
8458 [(set_attr "type" "alu")
8459 (set_attr "mode" "DI,DI")])
8460
8461 (define_insn "*xordi_2_rex64"
8462 [(set (reg 17)
8463 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8464 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8465 (const_int 0)))
8466 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8467 (xor:DI (match_dup 1) (match_dup 2)))]
8468 "TARGET_64BIT
8469 && ix86_match_ccmode (insn, CCNOmode)
8470 && ix86_binary_operator_ok (XOR, DImode, operands)"
8471 "@
8472 xor{q}\t{%2, %0|%0, %2}
8473 xor{q}\t{%2, %0|%0, %2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "mode" "DI,DI")])
8476
8477 (define_insn "*xordi_3_rex64"
8478 [(set (reg 17)
8479 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8480 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8481 (const_int 0)))
8482 (clobber (match_scratch:DI 0 "=r"))]
8483 "TARGET_64BIT
8484 && ix86_match_ccmode (insn, CCNOmode)
8485 && ix86_binary_operator_ok (XOR, DImode, operands)"
8486 "xor{q}\t{%2, %0|%0, %2}"
8487 [(set_attr "type" "alu")
8488 (set_attr "mode" "DI")])
8489
8490 (define_expand "xorsi3"
8491 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8492 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8493 (match_operand:SI 2 "general_operand" "")))
8494 (clobber (reg:CC 17))]
8495 ""
8496 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8497
8498 (define_insn "*xorsi_1"
8499 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8500 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8501 (match_operand:SI 2 "general_operand" "ri,rm")))
8502 (clobber (reg:CC 17))]
8503 "ix86_binary_operator_ok (XOR, SImode, operands)"
8504 "xor{l}\t{%2, %0|%0, %2}"
8505 [(set_attr "type" "alu")
8506 (set_attr "mode" "SI")])
8507
8508 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8509 ;; Add speccase for immediates
8510 (define_insn "*xorsi_1_zext"
8511 [(set (match_operand:DI 0 "register_operand" "=r")
8512 (zero_extend:DI
8513 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8514 (match_operand:SI 2 "general_operand" "rim"))))
8515 (clobber (reg:CC 17))]
8516 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8517 "xor{l}\t{%2, %k0|%k0, %2}"
8518 [(set_attr "type" "alu")
8519 (set_attr "mode" "SI")])
8520
8521 (define_insn "*xorsi_1_zext_imm"
8522 [(set (match_operand:DI 0 "register_operand" "=r")
8523 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8524 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8525 (clobber (reg:CC 17))]
8526 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8527 "xor{l}\t{%2, %k0|%k0, %2}"
8528 [(set_attr "type" "alu")
8529 (set_attr "mode" "SI")])
8530
8531 (define_insn "*xorsi_2"
8532 [(set (reg 17)
8533 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8534 (match_operand:SI 2 "general_operand" "rim,ri"))
8535 (const_int 0)))
8536 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8537 (xor:SI (match_dup 1) (match_dup 2)))]
8538 "ix86_match_ccmode (insn, CCNOmode)
8539 && ix86_binary_operator_ok (XOR, SImode, operands)"
8540 "xor{l}\t{%2, %0|%0, %2}"
8541 [(set_attr "type" "alu")
8542 (set_attr "mode" "SI")])
8543
8544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8545 ;; ??? Special case for immediate operand is missing - it is tricky.
8546 (define_insn "*xorsi_2_zext"
8547 [(set (reg 17)
8548 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8549 (match_operand:SI 2 "general_operand" "rim"))
8550 (const_int 0)))
8551 (set (match_operand:DI 0 "register_operand" "=r")
8552 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8553 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8554 && ix86_binary_operator_ok (XOR, SImode, operands)"
8555 "xor{l}\t{%2, %k0|%k0, %2}"
8556 [(set_attr "type" "alu")
8557 (set_attr "mode" "SI")])
8558
8559 (define_insn "*xorsi_2_zext_imm"
8560 [(set (reg 17)
8561 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8562 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8563 (const_int 0)))
8564 (set (match_operand:DI 0 "register_operand" "=r")
8565 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8566 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8567 && ix86_binary_operator_ok (XOR, SImode, operands)"
8568 "xor{l}\t{%2, %k0|%k0, %2}"
8569 [(set_attr "type" "alu")
8570 (set_attr "mode" "SI")])
8571
8572 (define_insn "*xorsi_3"
8573 [(set (reg 17)
8574 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8575 (match_operand:SI 2 "general_operand" "rim"))
8576 (const_int 0)))
8577 (clobber (match_scratch:SI 0 "=r"))]
8578 "ix86_match_ccmode (insn, CCNOmode)
8579 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8580 "xor{l}\t{%2, %0|%0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "mode" "SI")])
8583
8584 (define_expand "xorhi3"
8585 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8586 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8587 (match_operand:HI 2 "general_operand" "")))
8588 (clobber (reg:CC 17))]
8589 "TARGET_HIMODE_MATH"
8590 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8591
8592 (define_insn "*xorhi_1"
8593 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8594 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8595 (match_operand:HI 2 "general_operand" "rmi,ri")))
8596 (clobber (reg:CC 17))]
8597 "ix86_binary_operator_ok (XOR, HImode, operands)"
8598 "xor{w}\t{%2, %0|%0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "mode" "HI")])
8601
8602 (define_insn "*xorhi_2"
8603 [(set (reg 17)
8604 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8605 (match_operand:HI 2 "general_operand" "rim,ri"))
8606 (const_int 0)))
8607 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8608 (xor:HI (match_dup 1) (match_dup 2)))]
8609 "ix86_match_ccmode (insn, CCNOmode)
8610 && ix86_binary_operator_ok (XOR, HImode, operands)"
8611 "xor{w}\t{%2, %0|%0, %2}"
8612 [(set_attr "type" "alu")
8613 (set_attr "mode" "HI")])
8614
8615 (define_insn "*xorhi_3"
8616 [(set (reg 17)
8617 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8618 (match_operand:HI 2 "general_operand" "rim"))
8619 (const_int 0)))
8620 (clobber (match_scratch:HI 0 "=r"))]
8621 "ix86_match_ccmode (insn, CCNOmode)
8622 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8623 "xor{w}\t{%2, %0|%0, %2}"
8624 [(set_attr "type" "alu")
8625 (set_attr "mode" "HI")])
8626
8627 (define_expand "xorqi3"
8628 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8629 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8630 (match_operand:QI 2 "general_operand" "")))
8631 (clobber (reg:CC 17))]
8632 "TARGET_QIMODE_MATH"
8633 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8634
8635 ;; %%% Potential partial reg stall on alternative 2. What to do?
8636 (define_insn "*xorqi_1"
8637 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8638 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8639 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8640 (clobber (reg:CC 17))]
8641 "ix86_binary_operator_ok (XOR, QImode, operands)"
8642 "@
8643 xor{b}\t{%2, %0|%0, %2}
8644 xor{b}\t{%2, %0|%0, %2}
8645 xor{l}\t{%k2, %k0|%k0, %k2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "mode" "QI,QI,SI")])
8648
8649 (define_insn "*xorqi_ext_1"
8650 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8651 (const_int 8)
8652 (const_int 8))
8653 (xor:SI
8654 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8655 (const_int 8)
8656 (const_int 8))
8657 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8658 (const_int 8)
8659 (const_int 8))))
8660 (clobber (reg:CC 17))]
8661 ""
8662 "xor{b}\t{%h2, %h0|%h0, %h2}"
8663 [(set_attr "type" "alu")
8664 (set_attr "length_immediate" "0")
8665 (set_attr "mode" "QI")])
8666
8667 (define_insn "*xorqi_cc_1"
8668 [(set (reg 17)
8669 (compare
8670 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8671 (match_operand:QI 2 "general_operand" "qim,qi"))
8672 (const_int 0)))
8673 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8674 (xor:QI (match_dup 1) (match_dup 2)))]
8675 "ix86_match_ccmode (insn, CCNOmode)
8676 && ix86_binary_operator_ok (XOR, QImode, operands)"
8677 "xor{b}\t{%2, %0|%0, %2}"
8678 [(set_attr "type" "alu")
8679 (set_attr "mode" "QI")])
8680
8681 (define_insn "*xorqi_cc_2"
8682 [(set (reg 17)
8683 (compare
8684 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8685 (match_operand:QI 2 "general_operand" "qim"))
8686 (const_int 0)))
8687 (clobber (match_scratch:QI 0 "=q"))]
8688 "ix86_match_ccmode (insn, CCNOmode)
8689 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8690 "xor{b}\t{%2, %0|%0, %2}"
8691 [(set_attr "type" "alu")
8692 (set_attr "mode" "QI")])
8693
8694 (define_insn "*xorqi_cc_ext_1"
8695 [(set (reg 17)
8696 (compare
8697 (xor:SI
8698 (zero_extract:SI
8699 (match_operand 1 "ext_register_operand" "0")
8700 (const_int 8)
8701 (const_int 8))
8702 (match_operand:QI 2 "general_operand" "qmn"))
8703 (const_int 0)))
8704 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8705 (const_int 8)
8706 (const_int 8))
8707 (xor:SI
8708 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
8709 (match_dup 2)))]
8710 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8711 "xor{b}\t{%2, %h0|%h0, %2}"
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "QI")])
8714
8715 (define_insn "*xorqi_cc_ext_1_rex64"
8716 [(set (reg 17)
8717 (compare
8718 (xor:SI
8719 (zero_extract:SI
8720 (match_operand 1 "ext_register_operand" "0")
8721 (const_int 8)
8722 (const_int 8))
8723 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8724 (const_int 0)))
8725 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8726 (const_int 8)
8727 (const_int 8))
8728 (xor:SI
8729 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
8730 (match_dup 2)))]
8731 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8732 "xor{b}\t{%2, %h0|%h0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "mode" "QI")])
8735
8736 (define_expand "xorqi_cc_ext_1"
8737 [(parallel [
8738 (set (reg:CCNO 17)
8739 (compare:CCNO
8740 (xor:SI
8741 (zero_extract:SI
8742 (match_operand 1 "ext_register_operand" "")
8743 (const_int 8)
8744 (const_int 8))
8745 (match_operand:QI 2 "general_operand" ""))
8746 (const_int 0)))
8747 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8748 (const_int 8)
8749 (const_int 8))
8750 (xor:SI
8751 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
8752 (match_dup 2)))])]
8753 ""
8754 "")
8755 \f
8756 ;; Negation instructions
8757
8758 (define_expand "negdi2"
8759 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
8760 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
8761 (clobber (reg:CC 17))])]
8762 ""
8763 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
8764
8765 (define_insn "*negdi2_1"
8766 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
8767 (neg:DI (match_operand:DI 1 "general_operand" "0")))
8768 (clobber (reg:CC 17))]
8769 "!TARGET_64BIT
8770 && ix86_unary_operator_ok (NEG, DImode, operands)"
8771 "#")
8772
8773 (define_split
8774 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8775 (neg:DI (match_operand:DI 1 "general_operand" "")))
8776 (clobber (reg:CC 17))]
8777 "!TARGET_64BIT && reload_completed"
8778 [(parallel
8779 [(set (reg:CCZ 17)
8780 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
8781 (set (match_dup 0) (neg:SI (match_dup 2)))])
8782 (parallel
8783 [(set (match_dup 1)
8784 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
8785 (match_dup 3))
8786 (const_int 0)))
8787 (clobber (reg:CC 17))])
8788 (parallel
8789 [(set (match_dup 1)
8790 (neg:SI (match_dup 1)))
8791 (clobber (reg:CC 17))])]
8792 "split_di (operands+1, 1, operands+2, operands+3);
8793 split_di (operands+0, 1, operands+0, operands+1);")
8794
8795 (define_insn "*negdi2_1_rex64"
8796 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8797 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
8798 (clobber (reg:CC 17))]
8799 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
8800 "neg{q}\t%0"
8801 [(set_attr "type" "negnot")
8802 (set_attr "mode" "DI")])
8803
8804 ;; The problem with neg is that it does not perform (compare x 0),
8805 ;; it really performs (compare 0 x), which leaves us with the zero
8806 ;; flag being the only useful item.
8807
8808 (define_insn "*negdi2_cmpz_rex64"
8809 [(set (reg:CCZ 17)
8810 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
8811 (const_int 0)))
8812 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8813 (neg:DI (match_dup 1)))]
8814 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
8815 "neg{q}\t%0"
8816 [(set_attr "type" "negnot")
8817 (set_attr "mode" "DI")])
8818
8819
8820 (define_expand "negsi2"
8821 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
8822 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
8823 (clobber (reg:CC 17))])]
8824 ""
8825 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
8826
8827 (define_insn "*negsi2_1"
8828 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8829 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
8830 (clobber (reg:CC 17))]
8831 "ix86_unary_operator_ok (NEG, SImode, operands)"
8832 "neg{l}\t%0"
8833 [(set_attr "type" "negnot")
8834 (set_attr "mode" "SI")])
8835
8836 ;; Combine is quite creative about this pattern.
8837 (define_insn "*negsi2_1_zext"
8838 [(set (match_operand:DI 0 "register_operand" "=r")
8839 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8840 (const_int 32)))
8841 (const_int 32)))
8842 (clobber (reg:CC 17))]
8843 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8844 "neg{l}\t%k0"
8845 [(set_attr "type" "negnot")
8846 (set_attr "mode" "SI")])
8847
8848 ;; The problem with neg is that it does not perform (compare x 0),
8849 ;; it really performs (compare 0 x), which leaves us with the zero
8850 ;; flag being the only useful item.
8851
8852 (define_insn "*negsi2_cmpz"
8853 [(set (reg:CCZ 17)
8854 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
8855 (const_int 0)))
8856 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8857 (neg:SI (match_dup 1)))]
8858 "ix86_unary_operator_ok (NEG, SImode, operands)"
8859 "neg{l}\t%0"
8860 [(set_attr "type" "negnot")
8861 (set_attr "mode" "SI")])
8862
8863 (define_insn "*negsi2_cmpz_zext"
8864 [(set (reg:CCZ 17)
8865 (compare:CCZ (lshiftrt:DI
8866 (neg:DI (ashift:DI
8867 (match_operand:DI 1 "register_operand" "0")
8868 (const_int 32)))
8869 (const_int 32))
8870 (const_int 0)))
8871 (set (match_operand:DI 0 "register_operand" "=r")
8872 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8873 (const_int 32)))
8874 (const_int 32)))]
8875 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8876 "neg{l}\t%k0"
8877 [(set_attr "type" "negnot")
8878 (set_attr "mode" "SI")])
8879
8880 (define_expand "neghi2"
8881 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
8882 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
8883 (clobber (reg:CC 17))])]
8884 "TARGET_HIMODE_MATH"
8885 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
8886
8887 (define_insn "*neghi2_1"
8888 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8889 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
8890 (clobber (reg:CC 17))]
8891 "ix86_unary_operator_ok (NEG, HImode, operands)"
8892 "neg{w}\t%0"
8893 [(set_attr "type" "negnot")
8894 (set_attr "mode" "HI")])
8895
8896 (define_insn "*neghi2_cmpz"
8897 [(set (reg:CCZ 17)
8898 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
8899 (const_int 0)))
8900 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8901 (neg:HI (match_dup 1)))]
8902 "ix86_unary_operator_ok (NEG, HImode, operands)"
8903 "neg{w}\t%0"
8904 [(set_attr "type" "negnot")
8905 (set_attr "mode" "HI")])
8906
8907 (define_expand "negqi2"
8908 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
8909 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
8910 (clobber (reg:CC 17))])]
8911 "TARGET_QIMODE_MATH"
8912 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
8913
8914 (define_insn "*negqi2_1"
8915 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8916 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
8917 (clobber (reg:CC 17))]
8918 "ix86_unary_operator_ok (NEG, QImode, operands)"
8919 "neg{b}\t%0"
8920 [(set_attr "type" "negnot")
8921 (set_attr "mode" "QI")])
8922
8923 (define_insn "*negqi2_cmpz"
8924 [(set (reg:CCZ 17)
8925 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
8926 (const_int 0)))
8927 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8928 (neg:QI (match_dup 1)))]
8929 "ix86_unary_operator_ok (NEG, QImode, operands)"
8930 "neg{b}\t%0"
8931 [(set_attr "type" "negnot")
8932 (set_attr "mode" "QI")])
8933
8934 ;; Changing of sign for FP values is doable using integer unit too.
8935
8936 (define_expand "negsf2"
8937 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
8938 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
8939 (clobber (reg:CC 17))])]
8940 "TARGET_80387"
8941 "if (TARGET_SSE)
8942 {
8943 /* In case operand is in memory, we will not use SSE. */
8944 if (memory_operand (operands[0], VOIDmode)
8945 && rtx_equal_p (operands[0], operands[1]))
8946 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
8947 else
8948 {
8949 /* Using SSE is tricky, since we need bitwise negation of -0
8950 in register. */
8951 rtx reg = gen_reg_rtx (SFmode);
8952 rtx dest = operands[0];
8953
8954 operands[1] = force_reg (SFmode, operands[1]);
8955 operands[0] = force_reg (SFmode, operands[0]);
8956 emit_move_insn (reg,
8957 gen_lowpart (SFmode,
8958 gen_int_mode (0x80000000, SImode)));
8959 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
8960 if (dest != operands[0])
8961 emit_move_insn (dest, operands[0]);
8962 }
8963 DONE;
8964 }
8965 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
8966
8967 (define_insn "negsf2_memory"
8968 [(set (match_operand:SF 0 "memory_operand" "=m")
8969 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
8970 (clobber (reg:CC 17))]
8971 "ix86_unary_operator_ok (NEG, SFmode, operands)"
8972 "#")
8973
8974 (define_insn "negsf2_ifs"
8975 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
8976 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
8977 (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
8978 (clobber (reg:CC 17))]
8979 "TARGET_SSE
8980 && (reload_in_progress || reload_completed
8981 || (register_operand (operands[0], VOIDmode)
8982 && register_operand (operands[1], VOIDmode)))"
8983 "#")
8984
8985 (define_split
8986 [(set (match_operand:SF 0 "memory_operand" "")
8987 (neg:SF (match_operand:SF 1 "memory_operand" "")))
8988 (use (match_operand:SF 2 "" ""))
8989 (clobber (reg:CC 17))]
8990 ""
8991 [(parallel [(set (match_dup 0)
8992 (neg:SF (match_dup 1)))
8993 (clobber (reg:CC 17))])])
8994
8995 (define_split
8996 [(set (match_operand:SF 0 "register_operand" "")
8997 (neg:SF (match_operand:SF 1 "register_operand" "")))
8998 (use (match_operand:SF 2 "" ""))
8999 (clobber (reg:CC 17))]
9000 "reload_completed && !SSE_REG_P (operands[0])"
9001 [(parallel [(set (match_dup 0)
9002 (neg:SF (match_dup 1)))
9003 (clobber (reg:CC 17))])])
9004
9005 (define_split
9006 [(set (match_operand:SF 0 "register_operand" "")
9007 (neg:SF (match_operand:SF 1 "register_operand" "")))
9008 (use (match_operand:SF 2 "register_operand" ""))
9009 (clobber (reg:CC 17))]
9010 "reload_completed && SSE_REG_P (operands[0])"
9011 [(set (subreg:TI (match_dup 0) 0)
9012 (xor:TI (subreg:TI (match_dup 1) 0)
9013 (subreg:TI (match_dup 2) 0)))]
9014 {
9015 if (operands_match_p (operands[0], operands[2]))
9016 {
9017 rtx tmp;
9018 tmp = operands[1];
9019 operands[1] = operands[2];
9020 operands[2] = tmp;
9021 }
9022 })
9023
9024
9025 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9026 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9027 ;; to itself.
9028 (define_insn "*negsf2_if"
9029 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9030 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9031 (clobber (reg:CC 17))]
9032 "TARGET_80387 && !TARGET_SSE
9033 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9034 "#")
9035
9036 (define_split
9037 [(set (match_operand:SF 0 "register_operand" "")
9038 (neg:SF (match_operand:SF 1 "register_operand" "")))
9039 (clobber (reg:CC 17))]
9040 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9041 [(set (match_dup 0)
9042 (neg:SF (match_dup 1)))]
9043 "")
9044
9045 (define_split
9046 [(set (match_operand:SF 0 "register_operand" "")
9047 (neg:SF (match_operand:SF 1 "register_operand" "")))
9048 (clobber (reg:CC 17))]
9049 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9050 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9051 (clobber (reg:CC 17))])]
9052 "operands[1] = gen_int_mode (0x80000000, SImode);
9053 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9054
9055 (define_split
9056 [(set (match_operand 0 "memory_operand" "")
9057 (neg (match_operand 1 "memory_operand" "")))
9058 (clobber (reg:CC 17))]
9059 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9060 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9061 (clobber (reg:CC 17))])]
9062 {
9063 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9064
9065 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9066 if (size >= 12)
9067 size = 10;
9068 operands[0] = adjust_address (operands[0], QImode, size - 1);
9069 operands[1] = gen_int_mode (0x80, QImode);
9070 })
9071
9072 (define_expand "negdf2"
9073 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9074 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9075 (clobber (reg:CC 17))])]
9076 "TARGET_80387"
9077 "if (TARGET_SSE2)
9078 {
9079 /* In case operand is in memory, we will not use SSE. */
9080 if (memory_operand (operands[0], VOIDmode)
9081 && rtx_equal_p (operands[0], operands[1]))
9082 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9083 else
9084 {
9085 /* Using SSE is tricky, since we need bitwise negation of -0
9086 in register. */
9087 rtx reg = gen_reg_rtx (DFmode);
9088 #if HOST_BITS_PER_WIDE_INT >= 64
9089 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9090 #else
9091 rtx imm = immed_double_const (0, 0x80000000, DImode);
9092 #endif
9093 rtx dest = operands[0];
9094
9095 operands[1] = force_reg (DFmode, operands[1]);
9096 operands[0] = force_reg (DFmode, operands[0]);
9097 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9098 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9099 if (dest != operands[0])
9100 emit_move_insn (dest, operands[0]);
9101 }
9102 DONE;
9103 }
9104 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9105
9106 (define_insn "negdf2_memory"
9107 [(set (match_operand:DF 0 "memory_operand" "=m")
9108 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9109 (clobber (reg:CC 17))]
9110 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9111 "#")
9112
9113 (define_insn "negdf2_ifs"
9114 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9115 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9116 (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
9117 (clobber (reg:CC 17))]
9118 "!TARGET_64BIT && TARGET_SSE2
9119 && (reload_in_progress || reload_completed
9120 || (register_operand (operands[0], VOIDmode)
9121 && register_operand (operands[1], VOIDmode)))"
9122 "#")
9123
9124 (define_insn "*negdf2_ifs_rex64"
9125 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
9126 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9127 (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
9128 (clobber (reg:CC 17))]
9129 "TARGET_64BIT && TARGET_SSE2
9130 && (reload_in_progress || reload_completed
9131 || (register_operand (operands[0], VOIDmode)
9132 && register_operand (operands[1], VOIDmode)))"
9133 "#")
9134
9135 (define_split
9136 [(set (match_operand:DF 0 "memory_operand" "")
9137 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9138 (use (match_operand:DF 2 "" ""))
9139 (clobber (reg:CC 17))]
9140 ""
9141 [(parallel [(set (match_dup 0)
9142 (neg:DF (match_dup 1)))
9143 (clobber (reg:CC 17))])])
9144
9145 (define_split
9146 [(set (match_operand:DF 0 "register_operand" "")
9147 (neg:DF (match_operand:DF 1 "register_operand" "")))
9148 (use (match_operand:DF 2 "" ""))
9149 (clobber (reg:CC 17))]
9150 "reload_completed && !SSE_REG_P (operands[0])
9151 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9152 [(parallel [(set (match_dup 0)
9153 (neg:DF (match_dup 1)))
9154 (clobber (reg:CC 17))])])
9155
9156 (define_split
9157 [(set (match_operand:DF 0 "register_operand" "")
9158 (neg:DF (match_operand:DF 1 "register_operand" "")))
9159 (use (match_operand:DF 2 "" ""))
9160 (clobber (reg:CC 17))]
9161 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9162 [(parallel [(set (match_dup 0)
9163 (xor:DI (match_dup 1) (match_dup 2)))
9164 (clobber (reg:CC 17))])]
9165 "operands[0] = gen_lowpart (DImode, operands[0]);
9166 operands[1] = gen_lowpart (DImode, operands[1]);
9167 operands[2] = gen_lowpart (DImode, operands[2]);")
9168
9169 (define_split
9170 [(set (match_operand:DF 0 "register_operand" "")
9171 (neg:DF (match_operand:DF 1 "register_operand" "")))
9172 (use (match_operand:DF 2 "register_operand" ""))
9173 (clobber (reg:CC 17))]
9174 "reload_completed && SSE_REG_P (operands[0])"
9175 [(set (subreg:TI (match_dup 0) 0)
9176 (xor:TI (subreg:TI (match_dup 1) 0)
9177 (subreg:TI (match_dup 2) 0)))]
9178 {
9179 if (operands_match_p (operands[0], operands[2]))
9180 {
9181 rtx tmp;
9182 tmp = operands[1];
9183 operands[1] = operands[2];
9184 operands[2] = tmp;
9185 }
9186 })
9187
9188 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9189 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9190 ;; to itself.
9191 (define_insn "*negdf2_if"
9192 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9193 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9194 (clobber (reg:CC 17))]
9195 "!TARGET_64BIT && TARGET_80387
9196 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9197 "#")
9198
9199 ;; FIXME: We should to allow integer registers here. Problem is that
9200 ;; we need another scratch register to get constant from.
9201 ;; Forcing constant to mem if no register available in peep2 should be
9202 ;; safe even for PIC mode, because of RIP relative addressing.
9203 (define_insn "*negdf2_if_rex64"
9204 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9205 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9206 (clobber (reg:CC 17))]
9207 "TARGET_64BIT && TARGET_80387
9208 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9209 "#")
9210
9211 (define_split
9212 [(set (match_operand:DF 0 "register_operand" "")
9213 (neg:DF (match_operand:DF 1 "register_operand" "")))
9214 (clobber (reg:CC 17))]
9215 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9216 [(set (match_dup 0)
9217 (neg:DF (match_dup 1)))]
9218 "")
9219
9220 (define_split
9221 [(set (match_operand:DF 0 "register_operand" "")
9222 (neg:DF (match_operand:DF 1 "register_operand" "")))
9223 (clobber (reg:CC 17))]
9224 "!TARGET_64BIT && TARGET_80387 && reload_completed
9225 && !FP_REGNO_P (REGNO (operands[0]))"
9226 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9227 (clobber (reg:CC 17))])]
9228 "operands[4] = gen_int_mode (0x80000000, SImode);
9229 split_di (operands+0, 1, operands+2, operands+3);")
9230
9231 (define_expand "negxf2"
9232 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9233 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9234 (clobber (reg:CC 17))])]
9235 "!TARGET_64BIT && TARGET_80387"
9236 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9237
9238 (define_expand "negtf2"
9239 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9240 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9241 (clobber (reg:CC 17))])]
9242 "TARGET_80387"
9243 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9244
9245 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9246 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9247 ;; to itself.
9248 (define_insn "*negxf2_if"
9249 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9250 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9251 (clobber (reg:CC 17))]
9252 "!TARGET_64BIT && TARGET_80387
9253 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9254 "#")
9255
9256 (define_split
9257 [(set (match_operand:XF 0 "register_operand" "")
9258 (neg:XF (match_operand:XF 1 "register_operand" "")))
9259 (clobber (reg:CC 17))]
9260 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9261 [(set (match_dup 0)
9262 (neg:XF (match_dup 1)))]
9263 "")
9264
9265 (define_split
9266 [(set (match_operand:XF 0 "register_operand" "")
9267 (neg:XF (match_operand:XF 1 "register_operand" "")))
9268 (clobber (reg:CC 17))]
9269 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9270 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9271 (clobber (reg:CC 17))])]
9272 "operands[1] = GEN_INT (0x8000);
9273 operands[0] = gen_rtx_REG (SImode,
9274 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9275
9276 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9277 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9278 ;; to itself.
9279 (define_insn "*negtf2_if"
9280 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9281 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9282 (clobber (reg:CC 17))]
9283 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9284 "#")
9285
9286 (define_split
9287 [(set (match_operand:TF 0 "register_operand" "")
9288 (neg:TF (match_operand:TF 1 "register_operand" "")))
9289 (clobber (reg:CC 17))]
9290 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9291 [(set (match_dup 0)
9292 (neg:TF (match_dup 1)))]
9293 "")
9294
9295 (define_split
9296 [(set (match_operand:TF 0 "register_operand" "")
9297 (neg:TF (match_operand:TF 1 "register_operand" "")))
9298 (clobber (reg:CC 17))]
9299 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9300 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9301 (clobber (reg:CC 17))])]
9302 "operands[1] = GEN_INT (0x8000);
9303 operands[0] = gen_rtx_REG (SImode,
9304 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9305
9306 ;; Conditionize these after reload. If they matches before reload, we
9307 ;; lose the clobber and ability to use integer instructions.
9308
9309 (define_insn "*negsf2_1"
9310 [(set (match_operand:SF 0 "register_operand" "=f")
9311 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9312 "TARGET_80387 && reload_completed"
9313 "fchs"
9314 [(set_attr "type" "fsgn")
9315 (set_attr "mode" "SF")
9316 (set_attr "ppro_uops" "few")])
9317
9318 (define_insn "*negdf2_1"
9319 [(set (match_operand:DF 0 "register_operand" "=f")
9320 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9321 "TARGET_80387 && reload_completed"
9322 "fchs"
9323 [(set_attr "type" "fsgn")
9324 (set_attr "mode" "DF")
9325 (set_attr "ppro_uops" "few")])
9326
9327 (define_insn "*negextendsfdf2"
9328 [(set (match_operand:DF 0 "register_operand" "=f")
9329 (neg:DF (float_extend:DF
9330 (match_operand:SF 1 "register_operand" "0"))))]
9331 "TARGET_80387"
9332 "fchs"
9333 [(set_attr "type" "fsgn")
9334 (set_attr "mode" "DF")
9335 (set_attr "ppro_uops" "few")])
9336
9337 (define_insn "*negxf2_1"
9338 [(set (match_operand:XF 0 "register_operand" "=f")
9339 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9340 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9341 "fchs"
9342 [(set_attr "type" "fsgn")
9343 (set_attr "mode" "XF")
9344 (set_attr "ppro_uops" "few")])
9345
9346 (define_insn "*negextenddfxf2"
9347 [(set (match_operand:XF 0 "register_operand" "=f")
9348 (neg:XF (float_extend:XF
9349 (match_operand:DF 1 "register_operand" "0"))))]
9350 "!TARGET_64BIT && TARGET_80387"
9351 "fchs"
9352 [(set_attr "type" "fsgn")
9353 (set_attr "mode" "XF")
9354 (set_attr "ppro_uops" "few")])
9355
9356 (define_insn "*negextendsfxf2"
9357 [(set (match_operand:XF 0 "register_operand" "=f")
9358 (neg:XF (float_extend:XF
9359 (match_operand:SF 1 "register_operand" "0"))))]
9360 "!TARGET_64BIT && TARGET_80387"
9361 "fchs"
9362 [(set_attr "type" "fsgn")
9363 (set_attr "mode" "XF")
9364 (set_attr "ppro_uops" "few")])
9365
9366 (define_insn "*negtf2_1"
9367 [(set (match_operand:TF 0 "register_operand" "=f")
9368 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9369 "TARGET_80387 && reload_completed"
9370 "fchs"
9371 [(set_attr "type" "fsgn")
9372 (set_attr "mode" "XF")
9373 (set_attr "ppro_uops" "few")])
9374
9375 (define_insn "*negextenddftf2"
9376 [(set (match_operand:TF 0 "register_operand" "=f")
9377 (neg:TF (float_extend:TF
9378 (match_operand:DF 1 "register_operand" "0"))))]
9379 "TARGET_80387"
9380 "fchs"
9381 [(set_attr "type" "fsgn")
9382 (set_attr "mode" "XF")
9383 (set_attr "ppro_uops" "few")])
9384
9385 (define_insn "*negextendsftf2"
9386 [(set (match_operand:TF 0 "register_operand" "=f")
9387 (neg:TF (float_extend:TF
9388 (match_operand:SF 1 "register_operand" "0"))))]
9389 "TARGET_80387"
9390 "fchs"
9391 [(set_attr "type" "fsgn")
9392 (set_attr "mode" "XF")
9393 (set_attr "ppro_uops" "few")])
9394 \f
9395 ;; Absolute value instructions
9396
9397 (define_expand "abssf2"
9398 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9399 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9400 (clobber (reg:CC 17))])]
9401 "TARGET_80387"
9402 "if (TARGET_SSE)
9403 {
9404 /* In case operand is in memory, we will not use SSE. */
9405 if (memory_operand (operands[0], VOIDmode)
9406 && rtx_equal_p (operands[0], operands[1]))
9407 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9408 else
9409 {
9410 /* Using SSE is tricky, since we need bitwise negation of -0
9411 in register. */
9412 rtx reg = gen_reg_rtx (SFmode);
9413 rtx dest = operands[0];
9414
9415 operands[1] = force_reg (SFmode, operands[1]);
9416 operands[0] = force_reg (SFmode, operands[0]);
9417 emit_move_insn (reg,
9418 gen_lowpart (SFmode,
9419 gen_int_mode (0x80000000, SImode)));
9420 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9421 if (dest != operands[0])
9422 emit_move_insn (dest, operands[0]);
9423 }
9424 DONE;
9425 }
9426 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9427
9428 (define_insn "abssf2_memory"
9429 [(set (match_operand:SF 0 "memory_operand" "=m")
9430 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9431 (clobber (reg:CC 17))]
9432 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9433 "#")
9434
9435 (define_insn "abssf2_ifs"
9436 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
9437 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
9438 (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
9439 (clobber (reg:CC 17))]
9440 "TARGET_SSE
9441 && (reload_in_progress || reload_completed
9442 || (register_operand (operands[0], VOIDmode)
9443 && register_operand (operands[1], VOIDmode)))"
9444 "#")
9445
9446 (define_split
9447 [(set (match_operand:SF 0 "memory_operand" "")
9448 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9449 (use (match_operand:SF 2 "" ""))
9450 (clobber (reg:CC 17))]
9451 ""
9452 [(parallel [(set (match_dup 0)
9453 (abs:SF (match_dup 1)))
9454 (clobber (reg:CC 17))])])
9455
9456 (define_split
9457 [(set (match_operand:SF 0 "register_operand" "")
9458 (abs:SF (match_operand:SF 1 "register_operand" "")))
9459 (use (match_operand:SF 2 "" ""))
9460 (clobber (reg:CC 17))]
9461 "reload_completed && !SSE_REG_P (operands[0])"
9462 [(parallel [(set (match_dup 0)
9463 (abs:SF (match_dup 1)))
9464 (clobber (reg:CC 17))])])
9465
9466 (define_split
9467 [(set (match_operand:SF 0 "register_operand" "")
9468 (abs:SF (match_operand:SF 1 "register_operand" "")))
9469 (use (match_operand:SF 2 "register_operand" ""))
9470 (clobber (reg:CC 17))]
9471 "reload_completed && SSE_REG_P (operands[0])"
9472 [(set (subreg:TI (match_dup 0) 0)
9473 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9474 (subreg:TI (match_dup 1) 0)))])
9475
9476 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9477 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9478 ;; to itself.
9479 (define_insn "*abssf2_if"
9480 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9481 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9482 (clobber (reg:CC 17))]
9483 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
9484 "#")
9485
9486 (define_split
9487 [(set (match_operand:SF 0 "register_operand" "")
9488 (abs:SF (match_operand:SF 1 "register_operand" "")))
9489 (clobber (reg:CC 17))]
9490 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
9491 [(set (match_dup 0)
9492 (abs:SF (match_dup 1)))]
9493 "")
9494
9495 (define_split
9496 [(set (match_operand:SF 0 "register_operand" "")
9497 (abs:SF (match_operand:SF 1 "register_operand" "")))
9498 (clobber (reg:CC 17))]
9499 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9500 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9501 (clobber (reg:CC 17))])]
9502 "operands[1] = gen_int_mode (~0x80000000, SImode);
9503 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9504
9505 (define_split
9506 [(set (match_operand 0 "memory_operand" "")
9507 (abs (match_operand 1 "memory_operand" "")))
9508 (clobber (reg:CC 17))]
9509 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9510 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9511 (clobber (reg:CC 17))])]
9512 {
9513 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9514
9515 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9516 if (size >= 12)
9517 size = 10;
9518 operands[0] = adjust_address (operands[0], QImode, size - 1);
9519 operands[1] = gen_int_mode (~0x80, QImode);
9520 })
9521
9522 (define_expand "absdf2"
9523 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9524 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9525 (clobber (reg:CC 17))])]
9526 "TARGET_80387"
9527 "if (TARGET_SSE2)
9528 {
9529 /* In case operand is in memory, we will not use SSE. */
9530 if (memory_operand (operands[0], VOIDmode)
9531 && rtx_equal_p (operands[0], operands[1]))
9532 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9533 else
9534 {
9535 /* Using SSE is tricky, since we need bitwise negation of -0
9536 in register. */
9537 rtx reg = gen_reg_rtx (DFmode);
9538 #if HOST_BITS_PER_WIDE_INT >= 64
9539 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9540 #else
9541 rtx imm = immed_double_const (0, 0x80000000, DImode);
9542 #endif
9543 rtx dest = operands[0];
9544
9545 operands[1] = force_reg (DFmode, operands[1]);
9546 operands[0] = force_reg (DFmode, operands[0]);
9547 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9548 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
9549 if (dest != operands[0])
9550 emit_move_insn (dest, operands[0]);
9551 }
9552 DONE;
9553 }
9554 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9555
9556 (define_insn "absdf2_memory"
9557 [(set (match_operand:DF 0 "memory_operand" "=m")
9558 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9559 (clobber (reg:CC 17))]
9560 "ix86_unary_operator_ok (ABS, DFmode, operands)"
9561 "#")
9562
9563 (define_insn "absdf2_ifs"
9564 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
9565 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
9566 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
9567 (clobber (reg:CC 17))]
9568 "!TARGET_64BIT && TARGET_SSE2
9569 && (reload_in_progress || reload_completed
9570 || (register_operand (operands[0], VOIDmode)
9571 && register_operand (operands[1], VOIDmode)))"
9572 "#")
9573
9574 (define_insn "*absdf2_ifs_rex64"
9575 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
9576 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
9577 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
9578 (clobber (reg:CC 17))]
9579 "TARGET_64BIT && TARGET_SSE2
9580 && (reload_in_progress || reload_completed
9581 || (register_operand (operands[0], VOIDmode)
9582 && register_operand (operands[1], VOIDmode)))"
9583 "#")
9584
9585 (define_split
9586 [(set (match_operand:DF 0 "memory_operand" "")
9587 (abs:DF (match_operand:DF 1 "memory_operand" "")))
9588 (use (match_operand:DF 2 "" ""))
9589 (clobber (reg:CC 17))]
9590 ""
9591 [(parallel [(set (match_dup 0)
9592 (abs:DF (match_dup 1)))
9593 (clobber (reg:CC 17))])])
9594
9595 (define_split
9596 [(set (match_operand:DF 0 "register_operand" "")
9597 (abs:DF (match_operand:DF 1 "register_operand" "")))
9598 (use (match_operand:DF 2 "" ""))
9599 (clobber (reg:CC 17))]
9600 "reload_completed && !SSE_REG_P (operands[0])"
9601 [(parallel [(set (match_dup 0)
9602 (abs:DF (match_dup 1)))
9603 (clobber (reg:CC 17))])])
9604
9605 (define_split
9606 [(set (match_operand:DF 0 "register_operand" "")
9607 (abs:DF (match_operand:DF 1 "register_operand" "")))
9608 (use (match_operand:DF 2 "register_operand" ""))
9609 (clobber (reg:CC 17))]
9610 "reload_completed && SSE_REG_P (operands[0])"
9611 [(set (subreg:TI (match_dup 0) 0)
9612 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9613 (subreg:TI (match_dup 1) 0)))])
9614
9615
9616 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9617 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9618 ;; to itself.
9619 (define_insn "*absdf2_if"
9620 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9621 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9622 (clobber (reg:CC 17))]
9623 "!TARGET_64BIT && TARGET_80387
9624 && ix86_unary_operator_ok (ABS, DFmode, operands)"
9625 "#")
9626
9627 ;; FIXME: We should to allow integer registers here. Problem is that
9628 ;; we need another scratch register to get constant from.
9629 ;; Forcing constant to mem if no register available in peep2 should be
9630 ;; safe even for PIC mode, because of RIP relative addressing.
9631 (define_insn "*absdf2_if_rex64"
9632 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9633 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9634 (clobber (reg:CC 17))]
9635 "TARGET_64BIT && TARGET_80387
9636 && ix86_unary_operator_ok (ABS, DFmode, operands)"
9637 "#")
9638
9639 (define_split
9640 [(set (match_operand:DF 0 "register_operand" "")
9641 (abs:DF (match_operand:DF 1 "register_operand" "")))
9642 (clobber (reg:CC 17))]
9643 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9644 [(set (match_dup 0)
9645 (abs:DF (match_dup 1)))]
9646 "")
9647
9648 (define_split
9649 [(set (match_operand:DF 0 "register_operand" "")
9650 (abs:DF (match_operand:DF 1 "register_operand" "")))
9651 (clobber (reg:CC 17))]
9652 "!TARGET_64BIT && TARGET_80387 && reload_completed &&
9653 !FP_REGNO_P (REGNO (operands[0]))"
9654 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
9655 (clobber (reg:CC 17))])]
9656 "operands[4] = gen_int_mode (~0x80000000, SImode);
9657 split_di (operands+0, 1, operands+2, operands+3);")
9658
9659 (define_expand "absxf2"
9660 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9661 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9662 (clobber (reg:CC 17))])]
9663 "!TARGET_64BIT && TARGET_80387"
9664 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
9665
9666 (define_expand "abstf2"
9667 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9668 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9669 (clobber (reg:CC 17))])]
9670 "TARGET_80387"
9671 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
9672
9673 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9674 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9675 ;; to itself.
9676 (define_insn "*absxf2_if"
9677 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9678 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9679 (clobber (reg:CC 17))]
9680 "!TARGET_64BIT && TARGET_80387
9681 && ix86_unary_operator_ok (ABS, XFmode, operands)"
9682 "#")
9683
9684 (define_split
9685 [(set (match_operand:XF 0 "register_operand" "")
9686 (abs:XF (match_operand:XF 1 "register_operand" "")))
9687 (clobber (reg:CC 17))]
9688 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9689 [(set (match_dup 0)
9690 (abs:XF (match_dup 1)))]
9691 "")
9692
9693 (define_split
9694 [(set (match_operand:XF 0 "register_operand" "")
9695 (abs:XF (match_operand:XF 1 "register_operand" "")))
9696 (clobber (reg:CC 17))]
9697 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9698 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9699 (clobber (reg:CC 17))])]
9700 "operands[1] = GEN_INT (~0x8000);
9701 operands[0] = gen_rtx_REG (SImode,
9702 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9703
9704 (define_insn "*abstf2_if"
9705 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9706 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9707 (clobber (reg:CC 17))]
9708 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
9709 "#")
9710
9711 (define_split
9712 [(set (match_operand:TF 0 "register_operand" "")
9713 (abs:TF (match_operand:TF 1 "register_operand" "")))
9714 (clobber (reg:CC 17))]
9715 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9716 [(set (match_dup 0)
9717 (abs:TF (match_dup 1)))]
9718 "")
9719
9720 (define_split
9721 [(set (match_operand:TF 0 "register_operand" "")
9722 (abs:TF (match_operand:TF 1 "register_operand" "")))
9723 (clobber (reg:CC 17))]
9724 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9725 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9726 (clobber (reg:CC 17))])]
9727 "operands[1] = GEN_INT (~0x8000);
9728 operands[0] = gen_rtx_REG (SImode,
9729 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9730
9731 (define_insn "*abssf2_1"
9732 [(set (match_operand:SF 0 "register_operand" "=f")
9733 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9734 "TARGET_80387 && reload_completed"
9735 "fabs"
9736 [(set_attr "type" "fsgn")
9737 (set_attr "mode" "SF")])
9738
9739 (define_insn "*absdf2_1"
9740 [(set (match_operand:DF 0 "register_operand" "=f")
9741 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9742 "TARGET_80387 && reload_completed"
9743 "fabs"
9744 [(set_attr "type" "fsgn")
9745 (set_attr "mode" "DF")])
9746
9747 (define_insn "*absextendsfdf2"
9748 [(set (match_operand:DF 0 "register_operand" "=f")
9749 (abs:DF (float_extend:DF
9750 (match_operand:SF 1 "register_operand" "0"))))]
9751 "TARGET_80387"
9752 "fabs"
9753 [(set_attr "type" "fsgn")
9754 (set_attr "mode" "DF")])
9755
9756 (define_insn "*absxf2_1"
9757 [(set (match_operand:XF 0 "register_operand" "=f")
9758 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9759 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9760 "fabs"
9761 [(set_attr "type" "fsgn")
9762 (set_attr "mode" "DF")])
9763
9764 (define_insn "*absextenddfxf2"
9765 [(set (match_operand:XF 0 "register_operand" "=f")
9766 (abs:XF (float_extend:XF
9767 (match_operand:DF 1 "register_operand" "0"))))]
9768 "!TARGET_64BIT && TARGET_80387"
9769 "fabs"
9770 [(set_attr "type" "fsgn")
9771 (set_attr "mode" "XF")])
9772
9773 (define_insn "*absextendsfxf2"
9774 [(set (match_operand:XF 0 "register_operand" "=f")
9775 (abs:XF (float_extend:XF
9776 (match_operand:SF 1 "register_operand" "0"))))]
9777 "!TARGET_64BIT && TARGET_80387"
9778 "fabs"
9779 [(set_attr "type" "fsgn")
9780 (set_attr "mode" "XF")])
9781
9782 (define_insn "*abstf2_1"
9783 [(set (match_operand:TF 0 "register_operand" "=f")
9784 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
9785 "TARGET_80387 && reload_completed"
9786 "fabs"
9787 [(set_attr "type" "fsgn")
9788 (set_attr "mode" "DF")])
9789
9790 (define_insn "*absextenddftf2"
9791 [(set (match_operand:TF 0 "register_operand" "=f")
9792 (abs:TF (float_extend:TF
9793 (match_operand:DF 1 "register_operand" "0"))))]
9794 "TARGET_80387"
9795 "fabs"
9796 [(set_attr "type" "fsgn")
9797 (set_attr "mode" "XF")])
9798
9799 (define_insn "*absextendsftf2"
9800 [(set (match_operand:TF 0 "register_operand" "=f")
9801 (abs:TF (float_extend:TF
9802 (match_operand:SF 1 "register_operand" "0"))))]
9803 "TARGET_80387"
9804 "fabs"
9805 [(set_attr "type" "fsgn")
9806 (set_attr "mode" "XF")])
9807 \f
9808 ;; One complement instructions
9809
9810 (define_expand "one_cmpldi2"
9811 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9812 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9813 "TARGET_64BIT"
9814 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9815
9816 (define_insn "*one_cmpldi2_1_rex64"
9817 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9818 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9819 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9820 "not{q}\t%0"
9821 [(set_attr "type" "negnot")
9822 (set_attr "mode" "DI")])
9823
9824 (define_insn "*one_cmpldi2_2_rex64"
9825 [(set (reg 17)
9826 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9827 (const_int 0)))
9828 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9829 (not:DI (match_dup 1)))]
9830 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9831 && ix86_unary_operator_ok (NOT, DImode, operands)"
9832 "#"
9833 [(set_attr "type" "alu1")
9834 (set_attr "mode" "DI")])
9835
9836 (define_split
9837 [(set (reg 17)
9838 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
9839 (const_int 0)))
9840 (set (match_operand:DI 0 "nonimmediate_operand" "")
9841 (not:DI (match_dup 1)))]
9842 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9843 [(parallel [(set (reg:CCNO 17)
9844 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
9845 (const_int 0)))
9846 (set (match_dup 0)
9847 (xor:DI (match_dup 1) (const_int -1)))])]
9848 "")
9849
9850 (define_expand "one_cmplsi2"
9851 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9852 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9853 ""
9854 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9855
9856 (define_insn "*one_cmplsi2_1"
9857 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9858 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9859 "ix86_unary_operator_ok (NOT, SImode, operands)"
9860 "not{l}\t%0"
9861 [(set_attr "type" "negnot")
9862 (set_attr "mode" "SI")])
9863
9864 ;; ??? Currently never generated - xor is used instead.
9865 (define_insn "*one_cmplsi2_1_zext"
9866 [(set (match_operand:DI 0 "register_operand" "=r")
9867 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9868 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9869 "not{l}\t%k0"
9870 [(set_attr "type" "negnot")
9871 (set_attr "mode" "SI")])
9872
9873 (define_insn "*one_cmplsi2_2"
9874 [(set (reg 17)
9875 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9876 (const_int 0)))
9877 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9878 (not:SI (match_dup 1)))]
9879 "ix86_match_ccmode (insn, CCNOmode)
9880 && ix86_unary_operator_ok (NOT, SImode, operands)"
9881 "#"
9882 [(set_attr "type" "alu1")
9883 (set_attr "mode" "SI")])
9884
9885 (define_split
9886 [(set (reg 17)
9887 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
9888 (const_int 0)))
9889 (set (match_operand:SI 0 "nonimmediate_operand" "")
9890 (not:SI (match_dup 1)))]
9891 "ix86_match_ccmode (insn, CCNOmode)"
9892 [(parallel [(set (reg:CCNO 17)
9893 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
9894 (const_int 0)))
9895 (set (match_dup 0)
9896 (xor:SI (match_dup 1) (const_int -1)))])]
9897 "")
9898
9899 ;; ??? Currently never generated - xor is used instead.
9900 (define_insn "*one_cmplsi2_2_zext"
9901 [(set (reg 17)
9902 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9903 (const_int 0)))
9904 (set (match_operand:DI 0 "register_operand" "=r")
9905 (zero_extend:DI (not:SI (match_dup 1))))]
9906 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9907 && ix86_unary_operator_ok (NOT, SImode, operands)"
9908 "#"
9909 [(set_attr "type" "alu1")
9910 (set_attr "mode" "SI")])
9911
9912 (define_split
9913 [(set (reg 17)
9914 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
9915 (const_int 0)))
9916 (set (match_operand:DI 0 "register_operand" "")
9917 (zero_extend:DI (not:SI (match_dup 1))))]
9918 "ix86_match_ccmode (insn, CCNOmode)"
9919 [(parallel [(set (reg:CCNO 17)
9920 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
9921 (const_int 0)))
9922 (set (match_dup 0)
9923 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
9924 "")
9925
9926 (define_expand "one_cmplhi2"
9927 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9928 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9929 "TARGET_HIMODE_MATH"
9930 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9931
9932 (define_insn "*one_cmplhi2_1"
9933 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9934 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9935 "ix86_unary_operator_ok (NOT, HImode, operands)"
9936 "not{w}\t%0"
9937 [(set_attr "type" "negnot")
9938 (set_attr "mode" "HI")])
9939
9940 (define_insn "*one_cmplhi2_2"
9941 [(set (reg 17)
9942 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9943 (const_int 0)))
9944 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9945 (not:HI (match_dup 1)))]
9946 "ix86_match_ccmode (insn, CCNOmode)
9947 && ix86_unary_operator_ok (NEG, HImode, operands)"
9948 "#"
9949 [(set_attr "type" "alu1")
9950 (set_attr "mode" "HI")])
9951
9952 (define_split
9953 [(set (reg 17)
9954 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
9955 (const_int 0)))
9956 (set (match_operand:HI 0 "nonimmediate_operand" "")
9957 (not:HI (match_dup 1)))]
9958 "ix86_match_ccmode (insn, CCNOmode)"
9959 [(parallel [(set (reg:CCNO 17)
9960 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
9961 (const_int 0)))
9962 (set (match_dup 0)
9963 (xor:HI (match_dup 1) (const_int -1)))])]
9964 "")
9965
9966 ;; %%% Potential partial reg stall on alternative 1. What to do?
9967 (define_expand "one_cmplqi2"
9968 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9969 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
9970 "TARGET_QIMODE_MATH"
9971 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
9972
9973 (define_insn "*one_cmplqi2_1"
9974 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9975 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9976 "ix86_unary_operator_ok (NOT, QImode, operands)"
9977 "@
9978 not{b}\t%0
9979 not{l}\t%k0"
9980 [(set_attr "type" "negnot")
9981 (set_attr "mode" "QI,SI")])
9982
9983 (define_insn "*one_cmplqi2_2"
9984 [(set (reg 17)
9985 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9986 (const_int 0)))
9987 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9988 (not:QI (match_dup 1)))]
9989 "ix86_match_ccmode (insn, CCNOmode)
9990 && ix86_unary_operator_ok (NOT, QImode, operands)"
9991 "#"
9992 [(set_attr "type" "alu1")
9993 (set_attr "mode" "QI")])
9994
9995 (define_split
9996 [(set (reg 17)
9997 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
9998 (const_int 0)))
9999 (set (match_operand:QI 0 "nonimmediate_operand" "")
10000 (not:QI (match_dup 1)))]
10001 "ix86_match_ccmode (insn, CCNOmode)"
10002 [(parallel [(set (reg:CCNO 17)
10003 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10004 (const_int 0)))
10005 (set (match_dup 0)
10006 (xor:QI (match_dup 1) (const_int -1)))])]
10007 "")
10008 \f
10009 ;; Arithmetic shift instructions
10010
10011 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10012 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10013 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10014 ;; from the assembler input.
10015 ;;
10016 ;; This instruction shifts the target reg/mem as usual, but instead of
10017 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10018 ;; is a left shift double, bits are taken from the high order bits of
10019 ;; reg, else if the insn is a shift right double, bits are taken from the
10020 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10021 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10022 ;;
10023 ;; Since sh[lr]d does not change the `reg' operand, that is done
10024 ;; separately, making all shifts emit pairs of shift double and normal
10025 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10026 ;; support a 63 bit shift, each shift where the count is in a reg expands
10027 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10028 ;;
10029 ;; If the shift count is a constant, we need never emit more than one
10030 ;; shift pair, instead using moves and sign extension for counts greater
10031 ;; than 31.
10032
10033 (define_expand "ashldi3"
10034 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10035 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10036 (match_operand:QI 2 "nonmemory_operand" "")))
10037 (clobber (reg:CC 17))])]
10038 ""
10039 {
10040 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10041 {
10042 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10043 DONE;
10044 }
10045 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10046 DONE;
10047 })
10048
10049 (define_insn "*ashldi3_1_rex64"
10050 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10051 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10052 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10053 (clobber (reg:CC 17))]
10054 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10055 {
10056 switch (get_attr_type (insn))
10057 {
10058 case TYPE_ALU:
10059 if (operands[2] != const1_rtx)
10060 abort ();
10061 if (!rtx_equal_p (operands[0], operands[1]))
10062 abort ();
10063 return "add{q}\t{%0, %0|%0, %0}";
10064
10065 case TYPE_LEA:
10066 if (GET_CODE (operands[2]) != CONST_INT
10067 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10068 abort ();
10069 operands[1] = gen_rtx_MULT (DImode, operands[1],
10070 GEN_INT (1 << INTVAL (operands[2])));
10071 return "lea{q}\t{%a1, %0|%0, %a1}";
10072
10073 default:
10074 if (REG_P (operands[2]))
10075 return "sal{q}\t{%b2, %0|%0, %b2}";
10076 else if (GET_CODE (operands[2]) == CONST_INT
10077 && INTVAL (operands[2]) == 1
10078 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10079 return "sal{q}\t%0";
10080 else
10081 return "sal{q}\t{%2, %0|%0, %2}";
10082 }
10083 }
10084 [(set (attr "type")
10085 (cond [(eq_attr "alternative" "1")
10086 (const_string "lea")
10087 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10088 (const_int 0))
10089 (match_operand 0 "register_operand" ""))
10090 (match_operand 2 "const1_operand" ""))
10091 (const_string "alu")
10092 ]
10093 (const_string "ishift")))
10094 (set_attr "mode" "DI")])
10095
10096 ;; Convert lea to the lea pattern to avoid flags dependency.
10097 (define_split
10098 [(set (match_operand:DI 0 "register_operand" "")
10099 (ashift:DI (match_operand:DI 1 "register_operand" "")
10100 (match_operand:QI 2 "immediate_operand" "")))
10101 (clobber (reg:CC 17))]
10102 "TARGET_64BIT && reload_completed
10103 && true_regnum (operands[0]) != true_regnum (operands[1])"
10104 [(set (match_dup 0)
10105 (mult:DI (match_dup 1)
10106 (match_dup 2)))]
10107 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10108
10109 ;; This pattern can't accept a variable shift count, since shifts by
10110 ;; zero don't affect the flags. We assume that shifts by constant
10111 ;; zero are optimized away.
10112 (define_insn "*ashldi3_cmp_rex64"
10113 [(set (reg 17)
10114 (compare
10115 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10116 (match_operand:QI 2 "immediate_operand" "e"))
10117 (const_int 0)))
10118 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10119 (ashift:DI (match_dup 1) (match_dup 2)))]
10120 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10121 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10122 {
10123 switch (get_attr_type (insn))
10124 {
10125 case TYPE_ALU:
10126 if (operands[2] != const1_rtx)
10127 abort ();
10128 return "add{q}\t{%0, %0|%0, %0}";
10129
10130 default:
10131 if (REG_P (operands[2]))
10132 return "sal{q}\t{%b2, %0|%0, %b2}";
10133 else if (GET_CODE (operands[2]) == CONST_INT
10134 && INTVAL (operands[2]) == 1
10135 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10136 return "sal{q}\t%0";
10137 else
10138 return "sal{q}\t{%2, %0|%0, %2}";
10139 }
10140 }
10141 [(set (attr "type")
10142 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10143 (const_int 0))
10144 (match_operand 0 "register_operand" ""))
10145 (match_operand 2 "const1_operand" ""))
10146 (const_string "alu")
10147 ]
10148 (const_string "ishift")))
10149 (set_attr "mode" "DI")])
10150
10151 (define_insn "ashldi3_1"
10152 [(set (match_operand:DI 0 "register_operand" "=r")
10153 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10154 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10155 (clobber (match_scratch:SI 3 "=&r"))
10156 (clobber (reg:CC 17))]
10157 "!TARGET_64BIT && TARGET_CMOVE"
10158 "#"
10159 [(set_attr "type" "multi")])
10160
10161 (define_insn "*ashldi3_2"
10162 [(set (match_operand:DI 0 "register_operand" "=r")
10163 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10164 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10165 (clobber (reg:CC 17))]
10166 "!TARGET_64BIT"
10167 "#"
10168 [(set_attr "type" "multi")])
10169
10170 (define_split
10171 [(set (match_operand:DI 0 "register_operand" "")
10172 (ashift:DI (match_operand:DI 1 "register_operand" "")
10173 (match_operand:QI 2 "nonmemory_operand" "")))
10174 (clobber (match_scratch:SI 3 ""))
10175 (clobber (reg:CC 17))]
10176 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10177 [(const_int 0)]
10178 "ix86_split_ashldi (operands, operands[3]); DONE;")
10179
10180 (define_split
10181 [(set (match_operand:DI 0 "register_operand" "")
10182 (ashift:DI (match_operand:DI 1 "register_operand" "")
10183 (match_operand:QI 2 "nonmemory_operand" "")))
10184 (clobber (reg:CC 17))]
10185 "!TARGET_64BIT && reload_completed"
10186 [(const_int 0)]
10187 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10188
10189 (define_insn "x86_shld_1"
10190 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10191 (ior:SI (ashift:SI (match_dup 0)
10192 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10193 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10194 (minus:QI (const_int 32) (match_dup 2)))))
10195 (clobber (reg:CC 17))]
10196 ""
10197 "@
10198 shld{l}\t{%2, %1, %0|%0, %1, %2}
10199 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10200 [(set_attr "type" "ishift")
10201 (set_attr "prefix_0f" "1")
10202 (set_attr "mode" "SI")
10203 (set_attr "pent_pair" "np")
10204 (set_attr "athlon_decode" "vector")
10205 (set_attr "ppro_uops" "few")])
10206
10207 (define_expand "x86_shift_adj_1"
10208 [(set (reg:CCZ 17)
10209 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10210 (const_int 32))
10211 (const_int 0)))
10212 (set (match_operand:SI 0 "register_operand" "")
10213 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10214 (match_operand:SI 1 "register_operand" "")
10215 (match_dup 0)))
10216 (set (match_dup 1)
10217 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10218 (match_operand:SI 3 "register_operand" "r")
10219 (match_dup 1)))]
10220 "TARGET_CMOVE"
10221 "")
10222
10223 (define_expand "x86_shift_adj_2"
10224 [(use (match_operand:SI 0 "register_operand" ""))
10225 (use (match_operand:SI 1 "register_operand" ""))
10226 (use (match_operand:QI 2 "register_operand" ""))]
10227 ""
10228 {
10229 rtx label = gen_label_rtx ();
10230 rtx tmp;
10231
10232 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10233
10234 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10235 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10236 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10237 gen_rtx_LABEL_REF (VOIDmode, label),
10238 pc_rtx);
10239 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10240 JUMP_LABEL (tmp) = label;
10241
10242 emit_move_insn (operands[0], operands[1]);
10243 emit_move_insn (operands[1], const0_rtx);
10244
10245 emit_label (label);
10246 LABEL_NUSES (label) = 1;
10247
10248 DONE;
10249 })
10250
10251 (define_expand "ashlsi3"
10252 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10253 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10254 (match_operand:QI 2 "nonmemory_operand" "")))
10255 (clobber (reg:CC 17))]
10256 ""
10257 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10258
10259 (define_insn "*ashlsi3_1"
10260 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10261 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10262 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10263 (clobber (reg:CC 17))]
10264 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10265 {
10266 switch (get_attr_type (insn))
10267 {
10268 case TYPE_ALU:
10269 if (operands[2] != const1_rtx)
10270 abort ();
10271 if (!rtx_equal_p (operands[0], operands[1]))
10272 abort ();
10273 return "add{l}\t{%0, %0|%0, %0}";
10274
10275 case TYPE_LEA:
10276 return "#";
10277
10278 default:
10279 if (REG_P (operands[2]))
10280 return "sal{l}\t{%b2, %0|%0, %b2}";
10281 else if (GET_CODE (operands[2]) == CONST_INT
10282 && INTVAL (operands[2]) == 1
10283 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10284 return "sal{l}\t%0";
10285 else
10286 return "sal{l}\t{%2, %0|%0, %2}";
10287 }
10288 }
10289 [(set (attr "type")
10290 (cond [(eq_attr "alternative" "1")
10291 (const_string "lea")
10292 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10293 (const_int 0))
10294 (match_operand 0 "register_operand" ""))
10295 (match_operand 2 "const1_operand" ""))
10296 (const_string "alu")
10297 ]
10298 (const_string "ishift")))
10299 (set_attr "mode" "SI")])
10300
10301 ;; Convert lea to the lea pattern to avoid flags dependency.
10302 (define_split
10303 [(set (match_operand 0 "register_operand" "")
10304 (ashift (match_operand 1 "register_operand" "")
10305 (match_operand:QI 2 "const_int_operand" "")))
10306 (clobber (reg:CC 17))]
10307 "reload_completed
10308 && true_regnum (operands[0]) != true_regnum (operands[1])"
10309 [(const_int 0)]
10310 {
10311 rtx pat;
10312 operands[0] = gen_lowpart (SImode, operands[0]);
10313 operands[1] = gen_lowpart (Pmode, operands[1]);
10314 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10315 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10316 if (Pmode != SImode)
10317 pat = gen_rtx_SUBREG (SImode, pat, 0);
10318 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10319 DONE;
10320 })
10321
10322 (define_insn "*ashlsi3_1_zext"
10323 [(set (match_operand:DI 0 "register_operand" "=r,r")
10324 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10325 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10326 (clobber (reg:CC 17))]
10327 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10328 {
10329 switch (get_attr_type (insn))
10330 {
10331 case TYPE_ALU:
10332 if (operands[2] != const1_rtx)
10333 abort ();
10334 return "add{l}\t{%k0, %k0|%k0, %k0}";
10335
10336 case TYPE_LEA:
10337 return "#";
10338
10339 default:
10340 if (REG_P (operands[2]))
10341 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10342 else if (GET_CODE (operands[2]) == CONST_INT
10343 && INTVAL (operands[2]) == 1
10344 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10345 return "sal{l}\t%k0";
10346 else
10347 return "sal{l}\t{%2, %k0|%k0, %2}";
10348 }
10349 }
10350 [(set (attr "type")
10351 (cond [(eq_attr "alternative" "1")
10352 (const_string "lea")
10353 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10354 (const_int 0))
10355 (match_operand 2 "const1_operand" ""))
10356 (const_string "alu")
10357 ]
10358 (const_string "ishift")))
10359 (set_attr "mode" "SI")])
10360
10361 ;; Convert lea to the lea pattern to avoid flags dependency.
10362 (define_split
10363 [(set (match_operand:DI 0 "register_operand" "")
10364 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10365 (match_operand:QI 2 "const_int_operand" ""))))
10366 (clobber (reg:CC 17))]
10367 "reload_completed
10368 && true_regnum (operands[0]) != true_regnum (operands[1])"
10369 [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10370 {
10371 operands[1] = gen_lowpart (Pmode, operands[1]);
10372 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10373 })
10374
10375 ;; This pattern can't accept a variable shift count, since shifts by
10376 ;; zero don't affect the flags. We assume that shifts by constant
10377 ;; zero are optimized away.
10378 (define_insn "*ashlsi3_cmp"
10379 [(set (reg 17)
10380 (compare
10381 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10382 (match_operand:QI 2 "immediate_operand" "I"))
10383 (const_int 0)))
10384 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10385 (ashift:SI (match_dup 1) (match_dup 2)))]
10386 "ix86_match_ccmode (insn, CCGOCmode)
10387 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10388 {
10389 switch (get_attr_type (insn))
10390 {
10391 case TYPE_ALU:
10392 if (operands[2] != const1_rtx)
10393 abort ();
10394 return "add{l}\t{%0, %0|%0, %0}";
10395
10396 default:
10397 if (REG_P (operands[2]))
10398 return "sal{l}\t{%b2, %0|%0, %b2}";
10399 else if (GET_CODE (operands[2]) == CONST_INT
10400 && INTVAL (operands[2]) == 1
10401 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10402 return "sal{l}\t%0";
10403 else
10404 return "sal{l}\t{%2, %0|%0, %2}";
10405 }
10406 }
10407 [(set (attr "type")
10408 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10409 (const_int 0))
10410 (match_operand 0 "register_operand" ""))
10411 (match_operand 2 "const1_operand" ""))
10412 (const_string "alu")
10413 ]
10414 (const_string "ishift")))
10415 (set_attr "mode" "SI")])
10416
10417 (define_insn "*ashlsi3_cmp_zext"
10418 [(set (reg 17)
10419 (compare
10420 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10421 (match_operand:QI 2 "immediate_operand" "I"))
10422 (const_int 0)))
10423 (set (match_operand:DI 0 "register_operand" "=r")
10424 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10425 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10426 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10427 {
10428 switch (get_attr_type (insn))
10429 {
10430 case TYPE_ALU:
10431 if (operands[2] != const1_rtx)
10432 abort ();
10433 return "add{l}\t{%k0, %k0|%k0, %k0}";
10434
10435 default:
10436 if (REG_P (operands[2]))
10437 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10438 else if (GET_CODE (operands[2]) == CONST_INT
10439 && INTVAL (operands[2]) == 1
10440 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10441 return "sal{l}\t%k0";
10442 else
10443 return "sal{l}\t{%2, %k0|%k0, %2}";
10444 }
10445 }
10446 [(set (attr "type")
10447 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10448 (const_int 0))
10449 (match_operand 2 "const1_operand" ""))
10450 (const_string "alu")
10451 ]
10452 (const_string "ishift")))
10453 (set_attr "mode" "SI")])
10454
10455 (define_expand "ashlhi3"
10456 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10457 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10458 (match_operand:QI 2 "nonmemory_operand" "")))
10459 (clobber (reg:CC 17))]
10460 "TARGET_HIMODE_MATH"
10461 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10462
10463 (define_insn "*ashlhi3_1_lea"
10464 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10465 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10466 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10467 (clobber (reg:CC 17))]
10468 "!TARGET_PARTIAL_REG_STALL
10469 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10470 {
10471 switch (get_attr_type (insn))
10472 {
10473 case TYPE_LEA:
10474 return "#";
10475 case TYPE_ALU:
10476 if (operands[2] != const1_rtx)
10477 abort ();
10478 return "add{w}\t{%0, %0|%0, %0}";
10479
10480 default:
10481 if (REG_P (operands[2]))
10482 return "sal{w}\t{%b2, %0|%0, %b2}";
10483 else if (GET_CODE (operands[2]) == CONST_INT
10484 && INTVAL (operands[2]) == 1
10485 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10486 return "sal{w}\t%0";
10487 else
10488 return "sal{w}\t{%2, %0|%0, %2}";
10489 }
10490 }
10491 [(set (attr "type")
10492 (cond [(eq_attr "alternative" "1")
10493 (const_string "lea")
10494 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10495 (const_int 0))
10496 (match_operand 0 "register_operand" ""))
10497 (match_operand 2 "const1_operand" ""))
10498 (const_string "alu")
10499 ]
10500 (const_string "ishift")))
10501 (set_attr "mode" "HI,SI")])
10502
10503 (define_insn "*ashlhi3_1"
10504 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10505 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10506 (match_operand:QI 2 "nonmemory_operand" "cI")))
10507 (clobber (reg:CC 17))]
10508 "TARGET_PARTIAL_REG_STALL
10509 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10510 {
10511 switch (get_attr_type (insn))
10512 {
10513 case TYPE_ALU:
10514 if (operands[2] != const1_rtx)
10515 abort ();
10516 return "add{w}\t{%0, %0|%0, %0}";
10517
10518 default:
10519 if (REG_P (operands[2]))
10520 return "sal{w}\t{%b2, %0|%0, %b2}";
10521 else if (GET_CODE (operands[2]) == CONST_INT
10522 && INTVAL (operands[2]) == 1
10523 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10524 return "sal{w}\t%0";
10525 else
10526 return "sal{w}\t{%2, %0|%0, %2}";
10527 }
10528 }
10529 [(set (attr "type")
10530 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10531 (const_int 0))
10532 (match_operand 0 "register_operand" ""))
10533 (match_operand 2 "const1_operand" ""))
10534 (const_string "alu")
10535 ]
10536 (const_string "ishift")))
10537 (set_attr "mode" "HI")])
10538
10539 ;; This pattern can't accept a variable shift count, since shifts by
10540 ;; zero don't affect the flags. We assume that shifts by constant
10541 ;; zero are optimized away.
10542 (define_insn "*ashlhi3_cmp"
10543 [(set (reg 17)
10544 (compare
10545 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10546 (match_operand:QI 2 "immediate_operand" "I"))
10547 (const_int 0)))
10548 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10549 (ashift:HI (match_dup 1) (match_dup 2)))]
10550 "ix86_match_ccmode (insn, CCGOCmode)
10551 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10552 {
10553 switch (get_attr_type (insn))
10554 {
10555 case TYPE_ALU:
10556 if (operands[2] != const1_rtx)
10557 abort ();
10558 return "add{w}\t{%0, %0|%0, %0}";
10559
10560 default:
10561 if (REG_P (operands[2]))
10562 return "sal{w}\t{%b2, %0|%0, %b2}";
10563 else if (GET_CODE (operands[2]) == CONST_INT
10564 && INTVAL (operands[2]) == 1
10565 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10566 return "sal{w}\t%0";
10567 else
10568 return "sal{w}\t{%2, %0|%0, %2}";
10569 }
10570 }
10571 [(set (attr "type")
10572 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10573 (const_int 0))
10574 (match_operand 0 "register_operand" ""))
10575 (match_operand 2 "const1_operand" ""))
10576 (const_string "alu")
10577 ]
10578 (const_string "ishift")))
10579 (set_attr "mode" "HI")])
10580
10581 (define_expand "ashlqi3"
10582 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10583 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10584 (match_operand:QI 2 "nonmemory_operand" "")))
10585 (clobber (reg:CC 17))]
10586 "TARGET_QIMODE_MATH"
10587 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10588
10589 ;; %%% Potential partial reg stall on alternative 2. What to do?
10590
10591 (define_insn "*ashlqi3_1_lea"
10592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10593 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
10594 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10595 (clobber (reg:CC 17))]
10596 "!TARGET_PARTIAL_REG_STALL
10597 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10598 {
10599 switch (get_attr_type (insn))
10600 {
10601 case TYPE_LEA:
10602 return "#";
10603 case TYPE_ALU:
10604 if (operands[2] != const1_rtx)
10605 abort ();
10606 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10607 return "add{l}\t{%k0, %k0|%k0, %k0}";
10608 else
10609 return "add{b}\t{%0, %0|%0, %0}";
10610
10611 default:
10612 if (REG_P (operands[2]))
10613 {
10614 if (get_attr_mode (insn) == MODE_SI)
10615 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10616 else
10617 return "sal{b}\t{%b2, %0|%0, %b2}";
10618 }
10619 else if (GET_CODE (operands[2]) == CONST_INT
10620 && INTVAL (operands[2]) == 1
10621 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10622 {
10623 if (get_attr_mode (insn) == MODE_SI)
10624 return "sal{l}\t%0";
10625 else
10626 return "sal{b}\t%0";
10627 }
10628 else
10629 {
10630 if (get_attr_mode (insn) == MODE_SI)
10631 return "sal{l}\t{%2, %k0|%k0, %2}";
10632 else
10633 return "sal{b}\t{%2, %0|%0, %2}";
10634 }
10635 }
10636 }
10637 [(set (attr "type")
10638 (cond [(eq_attr "alternative" "2")
10639 (const_string "lea")
10640 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10641 (const_int 0))
10642 (match_operand 0 "register_operand" ""))
10643 (match_operand 2 "const1_operand" ""))
10644 (const_string "alu")
10645 ]
10646 (const_string "ishift")))
10647 (set_attr "mode" "QI,SI,SI")])
10648
10649 (define_insn "*ashlqi3_1"
10650 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10651 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10652 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10653 (clobber (reg:CC 17))]
10654 "TARGET_PARTIAL_REG_STALL
10655 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10656 {
10657 switch (get_attr_type (insn))
10658 {
10659 case TYPE_ALU:
10660 if (operands[2] != const1_rtx)
10661 abort ();
10662 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10663 return "add{l}\t{%k0, %k0|%k0, %k0}";
10664 else
10665 return "add{b}\t{%0, %0|%0, %0}";
10666
10667 default:
10668 if (REG_P (operands[2]))
10669 {
10670 if (get_attr_mode (insn) == MODE_SI)
10671 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10672 else
10673 return "sal{b}\t{%b2, %0|%0, %b2}";
10674 }
10675 else if (GET_CODE (operands[2]) == CONST_INT
10676 && INTVAL (operands[2]) == 1
10677 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10678 {
10679 if (get_attr_mode (insn) == MODE_SI)
10680 return "sal{l}\t%0";
10681 else
10682 return "sal{b}\t%0";
10683 }
10684 else
10685 {
10686 if (get_attr_mode (insn) == MODE_SI)
10687 return "sal{l}\t{%2, %k0|%k0, %2}";
10688 else
10689 return "sal{b}\t{%2, %0|%0, %2}";
10690 }
10691 }
10692 }
10693 [(set (attr "type")
10694 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10695 (const_int 0))
10696 (match_operand 0 "register_operand" ""))
10697 (match_operand 2 "const1_operand" ""))
10698 (const_string "alu")
10699 ]
10700 (const_string "ishift")))
10701 (set_attr "mode" "QI,SI")])
10702
10703 ;; This pattern can't accept a variable shift count, since shifts by
10704 ;; zero don't affect the flags. We assume that shifts by constant
10705 ;; zero are optimized away.
10706 (define_insn "*ashlqi3_cmp"
10707 [(set (reg 17)
10708 (compare
10709 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10710 (match_operand:QI 2 "immediate_operand" "I"))
10711 (const_int 0)))
10712 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10713 (ashift:QI (match_dup 1) (match_dup 2)))]
10714 "ix86_match_ccmode (insn, CCGOCmode)
10715 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10716 {
10717 switch (get_attr_type (insn))
10718 {
10719 case TYPE_ALU:
10720 if (operands[2] != const1_rtx)
10721 abort ();
10722 return "add{b}\t{%0, %0|%0, %0}";
10723
10724 default:
10725 if (REG_P (operands[2]))
10726 return "sal{b}\t{%b2, %0|%0, %b2}";
10727 else if (GET_CODE (operands[2]) == CONST_INT
10728 && INTVAL (operands[2]) == 1
10729 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10730 return "sal{b}\t%0";
10731 else
10732 return "sal{b}\t{%2, %0|%0, %2}";
10733 }
10734 }
10735 [(set (attr "type")
10736 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10737 (const_int 0))
10738 (match_operand 0 "register_operand" ""))
10739 (match_operand 2 "const1_operand" ""))
10740 (const_string "alu")
10741 ]
10742 (const_string "ishift")))
10743 (set_attr "mode" "QI")])
10744
10745 ;; See comment above `ashldi3' about how this works.
10746
10747 (define_expand "ashrdi3"
10748 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10749 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10750 (match_operand:QI 2 "nonmemory_operand" "")))
10751 (clobber (reg:CC 17))])]
10752 ""
10753 {
10754 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10755 {
10756 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
10757 DONE;
10758 }
10759 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
10760 DONE;
10761 })
10762
10763 (define_insn "ashrdi3_63_rex64"
10764 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10765 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10766 (match_operand:DI 2 "const_int_operand" "i,i")))
10767 (clobber (reg:CC 17))]
10768 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
10769 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10770 "@
10771 {cqto|cqo}
10772 sar{q}\t{%2, %0|%0, %2}"
10773 [(set_attr "type" "imovx,ishift")
10774 (set_attr "prefix_0f" "0,*")
10775 (set_attr "length_immediate" "0,*")
10776 (set_attr "modrm" "0,1")
10777 (set_attr "mode" "DI")])
10778
10779 (define_insn "*ashrdi3_1_one_bit_rex64"
10780 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10781 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10782 (match_operand:QI 2 "const_int_1_operand" "")))
10783 (clobber (reg:CC 17))]
10784 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10785 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
10786 "sar{q}\t%0"
10787 [(set_attr "type" "ishift")
10788 (set (attr "length")
10789 (if_then_else (match_operand:DI 0 "register_operand" "")
10790 (const_string "2")
10791 (const_string "*")))])
10792
10793 (define_insn "*ashrdi3_1_rex64"
10794 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10795 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10796 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10797 (clobber (reg:CC 17))]
10798 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10799 "@
10800 sar{q}\t{%2, %0|%0, %2}
10801 sar{q}\t{%b2, %0|%0, %b2}"
10802 [(set_attr "type" "ishift")
10803 (set_attr "mode" "DI")])
10804
10805 ;; This pattern can't accept a variable shift count, since shifts by
10806 ;; zero don't affect the flags. We assume that shifts by constant
10807 ;; zero are optimized away.
10808 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10809 [(set (reg 17)
10810 (compare
10811 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10812 (match_operand:QI 2 "const_int_1_operand" ""))
10813 (const_int 0)))
10814 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10815 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10816 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10817 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
10818 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10819 "sar{q}\t%0"
10820 [(set_attr "type" "ishift")
10821 (set (attr "length")
10822 (if_then_else (match_operand:DI 0 "register_operand" "")
10823 (const_string "2")
10824 (const_string "*")))])
10825
10826 ;; This pattern can't accept a variable shift count, since shifts by
10827 ;; zero don't affect the flags. We assume that shifts by constant
10828 ;; zero are optimized away.
10829 (define_insn "*ashrdi3_cmp_rex64"
10830 [(set (reg 17)
10831 (compare
10832 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10833 (match_operand:QI 2 "const_int_operand" "n"))
10834 (const_int 0)))
10835 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10836 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10837 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10838 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10839 "sar{q}\t{%2, %0|%0, %2}"
10840 [(set_attr "type" "ishift")
10841 (set_attr "mode" "DI")])
10842
10843
10844 (define_insn "ashrdi3_1"
10845 [(set (match_operand:DI 0 "register_operand" "=r")
10846 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10847 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10848 (clobber (match_scratch:SI 3 "=&r"))
10849 (clobber (reg:CC 17))]
10850 "!TARGET_64BIT && TARGET_CMOVE"
10851 "#"
10852 [(set_attr "type" "multi")])
10853
10854 (define_insn "*ashrdi3_2"
10855 [(set (match_operand:DI 0 "register_operand" "=r")
10856 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10857 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10858 (clobber (reg:CC 17))]
10859 "!TARGET_64BIT"
10860 "#"
10861 [(set_attr "type" "multi")])
10862
10863 (define_split
10864 [(set (match_operand:DI 0 "register_operand" "")
10865 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10866 (match_operand:QI 2 "nonmemory_operand" "")))
10867 (clobber (match_scratch:SI 3 ""))
10868 (clobber (reg:CC 17))]
10869 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10870 [(const_int 0)]
10871 "ix86_split_ashrdi (operands, operands[3]); DONE;")
10872
10873 (define_split
10874 [(set (match_operand:DI 0 "register_operand" "")
10875 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10876 (match_operand:QI 2 "nonmemory_operand" "")))
10877 (clobber (reg:CC 17))]
10878 "!TARGET_64BIT && reload_completed"
10879 [(const_int 0)]
10880 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10881
10882 (define_insn "x86_shrd_1"
10883 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10884 (ior:SI (ashiftrt:SI (match_dup 0)
10885 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10886 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10887 (minus:QI (const_int 32) (match_dup 2)))))
10888 (clobber (reg:CC 17))]
10889 ""
10890 "@
10891 shrd{l}\t{%2, %1, %0|%0, %1, %2}
10892 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10893 [(set_attr "type" "ishift")
10894 (set_attr "prefix_0f" "1")
10895 (set_attr "pent_pair" "np")
10896 (set_attr "ppro_uops" "few")
10897 (set_attr "mode" "SI")])
10898
10899 (define_expand "x86_shift_adj_3"
10900 [(use (match_operand:SI 0 "register_operand" ""))
10901 (use (match_operand:SI 1 "register_operand" ""))
10902 (use (match_operand:QI 2 "register_operand" ""))]
10903 ""
10904 {
10905 rtx label = gen_label_rtx ();
10906 rtx tmp;
10907
10908 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10909
10910 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10911 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10912 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10913 gen_rtx_LABEL_REF (VOIDmode, label),
10914 pc_rtx);
10915 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10916 JUMP_LABEL (tmp) = label;
10917
10918 emit_move_insn (operands[0], operands[1]);
10919 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10920
10921 emit_label (label);
10922 LABEL_NUSES (label) = 1;
10923
10924 DONE;
10925 })
10926
10927 (define_insn "ashrsi3_31"
10928 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10929 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10930 (match_operand:SI 2 "const_int_operand" "i,i")))
10931 (clobber (reg:CC 17))]
10932 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10933 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10934 "@
10935 {cltd|cdq}
10936 sar{l}\t{%2, %0|%0, %2}"
10937 [(set_attr "type" "imovx,ishift")
10938 (set_attr "prefix_0f" "0,*")
10939 (set_attr "length_immediate" "0,*")
10940 (set_attr "modrm" "0,1")
10941 (set_attr "mode" "SI")])
10942
10943 (define_insn "*ashrsi3_31_zext"
10944 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10945 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10946 (match_operand:SI 2 "const_int_operand" "i,i"))))
10947 (clobber (reg:CC 17))]
10948 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10949 && INTVAL (operands[2]) == 31
10950 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10951 "@
10952 {cltd|cdq}
10953 sar{l}\t{%2, %k0|%k0, %2}"
10954 [(set_attr "type" "imovx,ishift")
10955 (set_attr "prefix_0f" "0,*")
10956 (set_attr "length_immediate" "0,*")
10957 (set_attr "modrm" "0,1")
10958 (set_attr "mode" "SI")])
10959
10960 (define_expand "ashrsi3"
10961 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10962 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10963 (match_operand:QI 2 "nonmemory_operand" "")))
10964 (clobber (reg:CC 17))]
10965 ""
10966 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10967
10968 (define_insn "*ashrsi3_1_one_bit"
10969 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10970 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10971 (match_operand:QI 2 "const_int_1_operand" "")))
10972 (clobber (reg:CC 17))]
10973 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10974 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
10975 "sar{l}\t%0"
10976 [(set_attr "type" "ishift")
10977 (set (attr "length")
10978 (if_then_else (match_operand:SI 0 "register_operand" "")
10979 (const_string "2")
10980 (const_string "*")))])
10981
10982 (define_insn "*ashrsi3_1_one_bit_zext"
10983 [(set (match_operand:DI 0 "register_operand" "=r")
10984 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10985 (match_operand:QI 2 "const_int_1_operand" ""))))
10986 (clobber (reg:CC 17))]
10987 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10988 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
10989 "sar{l}\t%k0"
10990 [(set_attr "type" "ishift")
10991 (set_attr "length" "2")])
10992
10993 (define_insn "*ashrsi3_1"
10994 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
10995 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
10996 (match_operand:QI 2 "nonmemory_operand" "I,c")))
10997 (clobber (reg:CC 17))]
10998 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10999 "@
11000 sar{l}\t{%2, %0|%0, %2}
11001 sar{l}\t{%b2, %0|%0, %b2}"
11002 [(set_attr "type" "ishift")
11003 (set_attr "mode" "SI")])
11004
11005 (define_insn "*ashrsi3_1_zext"
11006 [(set (match_operand:DI 0 "register_operand" "=r,r")
11007 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11008 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11009 (clobber (reg:CC 17))]
11010 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11011 "@
11012 sar{l}\t{%2, %k0|%k0, %2}
11013 sar{l}\t{%b2, %k0|%k0, %b2}"
11014 [(set_attr "type" "ishift")
11015 (set_attr "mode" "SI")])
11016
11017 ;; This pattern can't accept a variable shift count, since shifts by
11018 ;; zero don't affect the flags. We assume that shifts by constant
11019 ;; zero are optimized away.
11020 (define_insn "*ashrsi3_one_bit_cmp"
11021 [(set (reg 17)
11022 (compare
11023 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11024 (match_operand:QI 2 "const_int_1_operand" ""))
11025 (const_int 0)))
11026 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11027 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11028 "ix86_match_ccmode (insn, CCGOCmode)
11029 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11030 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11031 "sar{l}\t%0"
11032 [(set_attr "type" "ishift")
11033 (set (attr "length")
11034 (if_then_else (match_operand:SI 0 "register_operand" "")
11035 (const_string "2")
11036 (const_string "*")))])
11037
11038 (define_insn "*ashrsi3_one_bit_cmp_zext"
11039 [(set (reg 17)
11040 (compare
11041 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11042 (match_operand:QI 2 "const_int_1_operand" ""))
11043 (const_int 0)))
11044 (set (match_operand:DI 0 "register_operand" "=r")
11045 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11046 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11047 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11048 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11049 "sar{l}\t%k0"
11050 [(set_attr "type" "ishift")
11051 (set_attr "length" "2")])
11052
11053 ;; This pattern can't accept a variable shift count, since shifts by
11054 ;; zero don't affect the flags. We assume that shifts by constant
11055 ;; zero are optimized away.
11056 (define_insn "*ashrsi3_cmp"
11057 [(set (reg 17)
11058 (compare
11059 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11060 (match_operand:QI 2 "immediate_operand" "I"))
11061 (const_int 0)))
11062 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11063 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11064 "ix86_match_ccmode (insn, CCGOCmode)
11065 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11066 "sar{l}\t{%2, %0|%0, %2}"
11067 [(set_attr "type" "ishift")
11068 (set_attr "mode" "SI")])
11069
11070 (define_insn "*ashrsi3_cmp_zext"
11071 [(set (reg 17)
11072 (compare
11073 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11074 (match_operand:QI 2 "immediate_operand" "I"))
11075 (const_int 0)))
11076 (set (match_operand:DI 0 "register_operand" "=r")
11077 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11079 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11080 "sar{l}\t{%2, %k0|%k0, %2}"
11081 [(set_attr "type" "ishift")
11082 (set_attr "mode" "SI")])
11083
11084 (define_expand "ashrhi3"
11085 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11086 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11087 (match_operand:QI 2 "nonmemory_operand" "")))
11088 (clobber (reg:CC 17))]
11089 "TARGET_HIMODE_MATH"
11090 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11091
11092 (define_insn "*ashrhi3_1_one_bit"
11093 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11094 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11095 (match_operand:QI 2 "const_int_1_operand" "")))
11096 (clobber (reg:CC 17))]
11097 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11098 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11099 "sar{w}\t%0"
11100 [(set_attr "type" "ishift")
11101 (set (attr "length")
11102 (if_then_else (match_operand 0 "register_operand" "")
11103 (const_string "2")
11104 (const_string "*")))])
11105
11106 (define_insn "*ashrhi3_1"
11107 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11108 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11109 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11110 (clobber (reg:CC 17))]
11111 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11112 "@
11113 sar{w}\t{%2, %0|%0, %2}
11114 sar{w}\t{%b2, %0|%0, %b2}"
11115 [(set_attr "type" "ishift")
11116 (set_attr "mode" "HI")])
11117
11118 ;; This pattern can't accept a variable shift count, since shifts by
11119 ;; zero don't affect the flags. We assume that shifts by constant
11120 ;; zero are optimized away.
11121 (define_insn "*ashrhi3_one_bit_cmp"
11122 [(set (reg 17)
11123 (compare
11124 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11125 (match_operand:QI 2 "const_int_1_operand" ""))
11126 (const_int 0)))
11127 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11128 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11129 "ix86_match_ccmode (insn, CCGOCmode)
11130 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11131 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11132 "sar{w}\t%0"
11133 [(set_attr "type" "ishift")
11134 (set (attr "length")
11135 (if_then_else (match_operand 0 "register_operand" "")
11136 (const_string "2")
11137 (const_string "*")))])
11138
11139 ;; This pattern can't accept a variable shift count, since shifts by
11140 ;; zero don't affect the flags. We assume that shifts by constant
11141 ;; zero are optimized away.
11142 (define_insn "*ashrhi3_cmp"
11143 [(set (reg 17)
11144 (compare
11145 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11146 (match_operand:QI 2 "immediate_operand" "I"))
11147 (const_int 0)))
11148 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11149 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11150 "ix86_match_ccmode (insn, CCGOCmode)
11151 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11152 "sar{w}\t{%2, %0|%0, %2}"
11153 [(set_attr "type" "ishift")
11154 (set_attr "mode" "HI")])
11155
11156 (define_expand "ashrqi3"
11157 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11158 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11159 (match_operand:QI 2 "nonmemory_operand" "")))
11160 (clobber (reg:CC 17))]
11161 "TARGET_QIMODE_MATH"
11162 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11163
11164 (define_insn "*ashrqi3_1_one_bit"
11165 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11166 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11167 (match_operand:QI 2 "const_int_1_operand" "")))
11168 (clobber (reg:CC 17))]
11169 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11170 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11171 "sar{b}\t%0"
11172 [(set_attr "type" "ishift")
11173 (set (attr "length")
11174 (if_then_else (match_operand 0 "register_operand" "")
11175 (const_string "2")
11176 (const_string "*")))])
11177
11178 (define_insn "*ashrqi3_1"
11179 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11180 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11181 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11182 (clobber (reg:CC 17))]
11183 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11184 "@
11185 sar{b}\t{%2, %0|%0, %2}
11186 sar{b}\t{%b2, %0|%0, %b2}"
11187 [(set_attr "type" "ishift")
11188 (set_attr "mode" "QI")])
11189
11190 ;; This pattern can't accept a variable shift count, since shifts by
11191 ;; zero don't affect the flags. We assume that shifts by constant
11192 ;; zero are optimized away.
11193 (define_insn "*ashrqi3_one_bit_cmp"
11194 [(set (reg 17)
11195 (compare
11196 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11197 (match_operand:QI 2 "const_int_1_operand" "I"))
11198 (const_int 0)))
11199 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11200 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11201 "ix86_match_ccmode (insn, CCGOCmode)
11202 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11203 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11204 "sar{b}\t%0"
11205 [(set_attr "type" "ishift")
11206 (set (attr "length")
11207 (if_then_else (match_operand 0 "register_operand" "")
11208 (const_string "2")
11209 (const_string "*")))])
11210
11211 ;; This pattern can't accept a variable shift count, since shifts by
11212 ;; zero don't affect the flags. We assume that shifts by constant
11213 ;; zero are optimized away.
11214 (define_insn "*ashrqi3_cmp"
11215 [(set (reg 17)
11216 (compare
11217 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11218 (match_operand:QI 2 "immediate_operand" "I"))
11219 (const_int 0)))
11220 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11221 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11222 "ix86_match_ccmode (insn, CCGOCmode)
11223 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11224 "sar{b}\t{%2, %0|%0, %2}"
11225 [(set_attr "type" "ishift")
11226 (set_attr "mode" "QI")])
11227 \f
11228 ;; Logical shift instructions
11229
11230 ;; See comment above `ashldi3' about how this works.
11231
11232 (define_expand "lshrdi3"
11233 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11234 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11235 (match_operand:QI 2 "nonmemory_operand" "")))
11236 (clobber (reg:CC 17))])]
11237 ""
11238 {
11239 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11240 {
11241 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11242 DONE;
11243 }
11244 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11245 DONE;
11246 })
11247
11248 (define_insn "*lshrdi3_1_one_bit_rex64"
11249 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11250 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11251 (match_operand:QI 2 "const_int_1_operand" "")))
11252 (clobber (reg:CC 17))]
11253 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11254 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11255 "shr{q}\t%0"
11256 [(set_attr "type" "ishift")
11257 (set (attr "length")
11258 (if_then_else (match_operand:DI 0 "register_operand" "")
11259 (const_string "2")
11260 (const_string "*")))])
11261
11262 (define_insn "*lshrdi3_1_rex64"
11263 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11264 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11265 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11266 (clobber (reg:CC 17))]
11267 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11268 "@
11269 shr{q}\t{%2, %0|%0, %2}
11270 shr{q}\t{%b2, %0|%0, %b2}"
11271 [(set_attr "type" "ishift")
11272 (set_attr "mode" "DI")])
11273
11274 ;; This pattern can't accept a variable shift count, since shifts by
11275 ;; zero don't affect the flags. We assume that shifts by constant
11276 ;; zero are optimized away.
11277 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11278 [(set (reg 17)
11279 (compare
11280 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11281 (match_operand:QI 2 "const_int_1_operand" ""))
11282 (const_int 0)))
11283 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11284 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11285 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11286 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11287 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11288 "shr{q}\t%0"
11289 [(set_attr "type" "ishift")
11290 (set (attr "length")
11291 (if_then_else (match_operand:DI 0 "register_operand" "")
11292 (const_string "2")
11293 (const_string "*")))])
11294
11295 ;; This pattern can't accept a variable shift count, since shifts by
11296 ;; zero don't affect the flags. We assume that shifts by constant
11297 ;; zero are optimized away.
11298 (define_insn "*lshrdi3_cmp_rex64"
11299 [(set (reg 17)
11300 (compare
11301 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11302 (match_operand:QI 2 "const_int_operand" "e"))
11303 (const_int 0)))
11304 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11305 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11306 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11307 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11308 "shr{q}\t{%2, %0|%0, %2}"
11309 [(set_attr "type" "ishift")
11310 (set_attr "mode" "DI")])
11311
11312 (define_insn "lshrdi3_1"
11313 [(set (match_operand:DI 0 "register_operand" "=r")
11314 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11315 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11316 (clobber (match_scratch:SI 3 "=&r"))
11317 (clobber (reg:CC 17))]
11318 "!TARGET_64BIT && TARGET_CMOVE"
11319 "#"
11320 [(set_attr "type" "multi")])
11321
11322 (define_insn "*lshrdi3_2"
11323 [(set (match_operand:DI 0 "register_operand" "=r")
11324 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11325 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11326 (clobber (reg:CC 17))]
11327 "!TARGET_64BIT"
11328 "#"
11329 [(set_attr "type" "multi")])
11330
11331 (define_split
11332 [(set (match_operand:DI 0 "register_operand" "")
11333 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11334 (match_operand:QI 2 "nonmemory_operand" "")))
11335 (clobber (match_scratch:SI 3 ""))
11336 (clobber (reg:CC 17))]
11337 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11338 [(const_int 0)]
11339 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11340
11341 (define_split
11342 [(set (match_operand:DI 0 "register_operand" "")
11343 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11344 (match_operand:QI 2 "nonmemory_operand" "")))
11345 (clobber (reg:CC 17))]
11346 "!TARGET_64BIT && reload_completed"
11347 [(const_int 0)]
11348 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11349
11350 (define_expand "lshrsi3"
11351 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11352 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11353 (match_operand:QI 2 "nonmemory_operand" "")))
11354 (clobber (reg:CC 17))]
11355 ""
11356 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11357
11358 (define_insn "*lshrsi3_1_one_bit"
11359 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11360 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11361 (match_operand:QI 2 "const_int_1_operand" "")))
11362 (clobber (reg:CC 17))]
11363 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11364 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11365 "shr{l}\t%0"
11366 [(set_attr "type" "ishift")
11367 (set (attr "length")
11368 (if_then_else (match_operand:SI 0 "register_operand" "")
11369 (const_string "2")
11370 (const_string "*")))])
11371
11372 (define_insn "*lshrsi3_1_one_bit_zext"
11373 [(set (match_operand:DI 0 "register_operand" "=r")
11374 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11375 (match_operand:QI 2 "const_int_1_operand" "")))
11376 (clobber (reg:CC 17))]
11377 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11378 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11379 "shr{l}\t%k0"
11380 [(set_attr "type" "ishift")
11381 (set_attr "length" "2")])
11382
11383 (define_insn "*lshrsi3_1"
11384 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11385 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11386 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11387 (clobber (reg:CC 17))]
11388 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11389 "@
11390 shr{l}\t{%2, %0|%0, %2}
11391 shr{l}\t{%b2, %0|%0, %b2}"
11392 [(set_attr "type" "ishift")
11393 (set_attr "mode" "SI")])
11394
11395 (define_insn "*lshrsi3_1_zext"
11396 [(set (match_operand:DI 0 "register_operand" "=r,r")
11397 (zero_extend:DI
11398 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11399 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11400 (clobber (reg:CC 17))]
11401 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11402 "@
11403 shr{l}\t{%2, %k0|%k0, %2}
11404 shr{l}\t{%b2, %k0|%k0, %b2}"
11405 [(set_attr "type" "ishift")
11406 (set_attr "mode" "SI")])
11407
11408 ;; This pattern can't accept a variable shift count, since shifts by
11409 ;; zero don't affect the flags. We assume that shifts by constant
11410 ;; zero are optimized away.
11411 (define_insn "*lshrsi3_one_bit_cmp"
11412 [(set (reg 17)
11413 (compare
11414 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11415 (match_operand:QI 2 "const_int_1_operand" ""))
11416 (const_int 0)))
11417 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11418 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11419 "ix86_match_ccmode (insn, CCGOCmode)
11420 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11421 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11422 "shr{l}\t%0"
11423 [(set_attr "type" "ishift")
11424 (set (attr "length")
11425 (if_then_else (match_operand:SI 0 "register_operand" "")
11426 (const_string "2")
11427 (const_string "*")))])
11428
11429 (define_insn "*lshrsi3_cmp_one_bit_zext"
11430 [(set (reg 17)
11431 (compare
11432 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11433 (match_operand:QI 2 "const_int_1_operand" ""))
11434 (const_int 0)))
11435 (set (match_operand:DI 0 "register_operand" "=r")
11436 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11437 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11438 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11439 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11440 "shr{l}\t%k0"
11441 [(set_attr "type" "ishift")
11442 (set_attr "length" "2")])
11443
11444 ;; This pattern can't accept a variable shift count, since shifts by
11445 ;; zero don't affect the flags. We assume that shifts by constant
11446 ;; zero are optimized away.
11447 (define_insn "*lshrsi3_cmp"
11448 [(set (reg 17)
11449 (compare
11450 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11451 (match_operand:QI 2 "immediate_operand" "I"))
11452 (const_int 0)))
11453 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11454 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11455 "ix86_match_ccmode (insn, CCGOCmode)
11456 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11457 "shr{l}\t{%2, %0|%0, %2}"
11458 [(set_attr "type" "ishift")
11459 (set_attr "mode" "SI")])
11460
11461 (define_insn "*lshrsi3_cmp_zext"
11462 [(set (reg 17)
11463 (compare
11464 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11465 (match_operand:QI 2 "immediate_operand" "I"))
11466 (const_int 0)))
11467 (set (match_operand:DI 0 "register_operand" "=r")
11468 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11469 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11470 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11471 "shr{l}\t{%2, %k0|%k0, %2}"
11472 [(set_attr "type" "ishift")
11473 (set_attr "mode" "SI")])
11474
11475 (define_expand "lshrhi3"
11476 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11477 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11478 (match_operand:QI 2 "nonmemory_operand" "")))
11479 (clobber (reg:CC 17))]
11480 "TARGET_HIMODE_MATH"
11481 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11482
11483 (define_insn "*lshrhi3_1_one_bit"
11484 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11485 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11486 (match_operand:QI 2 "const_int_1_operand" "")))
11487 (clobber (reg:CC 17))]
11488 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11489 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11490 "shr{w}\t%0"
11491 [(set_attr "type" "ishift")
11492 (set (attr "length")
11493 (if_then_else (match_operand 0 "register_operand" "")
11494 (const_string "2")
11495 (const_string "*")))])
11496
11497 (define_insn "*lshrhi3_1"
11498 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11499 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11500 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11501 (clobber (reg:CC 17))]
11502 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11503 "@
11504 shr{w}\t{%2, %0|%0, %2}
11505 shr{w}\t{%b2, %0|%0, %b2}"
11506 [(set_attr "type" "ishift")
11507 (set_attr "mode" "HI")])
11508
11509 ;; This pattern can't accept a variable shift count, since shifts by
11510 ;; zero don't affect the flags. We assume that shifts by constant
11511 ;; zero are optimized away.
11512 (define_insn "*lshrhi3_one_bit_cmp"
11513 [(set (reg 17)
11514 (compare
11515 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11516 (match_operand:QI 2 "const_int_1_operand" ""))
11517 (const_int 0)))
11518 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11519 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11520 "ix86_match_ccmode (insn, CCGOCmode)
11521 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11522 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11523 "shr{w}\t%0"
11524 [(set_attr "type" "ishift")
11525 (set (attr "length")
11526 (if_then_else (match_operand:SI 0 "register_operand" "")
11527 (const_string "2")
11528 (const_string "*")))])
11529
11530 ;; This pattern can't accept a variable shift count, since shifts by
11531 ;; zero don't affect the flags. We assume that shifts by constant
11532 ;; zero are optimized away.
11533 (define_insn "*lshrhi3_cmp"
11534 [(set (reg 17)
11535 (compare
11536 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11537 (match_operand:QI 2 "immediate_operand" "I"))
11538 (const_int 0)))
11539 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11540 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11541 "ix86_match_ccmode (insn, CCGOCmode)
11542 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11543 "shr{w}\t{%2, %0|%0, %2}"
11544 [(set_attr "type" "ishift")
11545 (set_attr "mode" "HI")])
11546
11547 (define_expand "lshrqi3"
11548 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11549 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11550 (match_operand:QI 2 "nonmemory_operand" "")))
11551 (clobber (reg:CC 17))]
11552 "TARGET_QIMODE_MATH"
11553 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11554
11555 (define_insn "*lshrqi3_1_one_bit"
11556 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11557 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11558 (match_operand:QI 2 "const_int_1_operand" "")))
11559 (clobber (reg:CC 17))]
11560 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11561 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11562 "shr{b}\t%0"
11563 [(set_attr "type" "ishift")
11564 (set (attr "length")
11565 (if_then_else (match_operand 0 "register_operand" "")
11566 (const_string "2")
11567 (const_string "*")))])
11568
11569 (define_insn "*lshrqi3_1"
11570 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11571 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11572 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11573 (clobber (reg:CC 17))]
11574 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11575 "@
11576 shr{b}\t{%2, %0|%0, %2}
11577 shr{b}\t{%b2, %0|%0, %b2}"
11578 [(set_attr "type" "ishift")
11579 (set_attr "mode" "QI")])
11580
11581 ;; This pattern can't accept a variable shift count, since shifts by
11582 ;; zero don't affect the flags. We assume that shifts by constant
11583 ;; zero are optimized away.
11584 (define_insn "*lshrqi2_one_bit_cmp"
11585 [(set (reg 17)
11586 (compare
11587 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11588 (match_operand:QI 2 "const_int_1_operand" ""))
11589 (const_int 0)))
11590 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11591 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11592 "ix86_match_ccmode (insn, CCGOCmode)
11593 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11594 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11595 "shr{b}\t%0"
11596 [(set_attr "type" "ishift")
11597 (set (attr "length")
11598 (if_then_else (match_operand:SI 0 "register_operand" "")
11599 (const_string "2")
11600 (const_string "*")))])
11601
11602 ;; This pattern can't accept a variable shift count, since shifts by
11603 ;; zero don't affect the flags. We assume that shifts by constant
11604 ;; zero are optimized away.
11605 (define_insn "*lshrqi2_cmp"
11606 [(set (reg 17)
11607 (compare
11608 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11609 (match_operand:QI 2 "immediate_operand" "I"))
11610 (const_int 0)))
11611 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11612 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11613 "ix86_match_ccmode (insn, CCGOCmode)
11614 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11615 "shr{b}\t{%2, %0|%0, %2}"
11616 [(set_attr "type" "ishift")
11617 (set_attr "mode" "QI")])
11618 \f
11619 ;; Rotate instructions
11620
11621 (define_expand "rotldi3"
11622 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11623 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11624 (match_operand:QI 2 "nonmemory_operand" "")))
11625 (clobber (reg:CC 17))]
11626 "TARGET_64BIT"
11627 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11628
11629 (define_insn "*rotlsi3_1_one_bit_rex64"
11630 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11631 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11632 (match_operand:QI 2 "const_int_1_operand" "")))
11633 (clobber (reg:CC 17))]
11634 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11635 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11636 "rol{q}\t%0"
11637 [(set_attr "type" "rotate")
11638 (set (attr "length")
11639 (if_then_else (match_operand:DI 0 "register_operand" "")
11640 (const_string "2")
11641 (const_string "*")))])
11642
11643 (define_insn "*rotldi3_1_rex64"
11644 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11645 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11646 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11647 (clobber (reg:CC 17))]
11648 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11649 "@
11650 rol{q}\t{%2, %0|%0, %2}
11651 rol{q}\t{%b2, %0|%0, %b2}"
11652 [(set_attr "type" "rotate")
11653 (set_attr "mode" "DI")])
11654
11655 (define_expand "rotlsi3"
11656 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11657 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11658 (match_operand:QI 2 "nonmemory_operand" "")))
11659 (clobber (reg:CC 17))]
11660 ""
11661 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11662
11663 (define_insn "*rotlsi3_1_one_bit"
11664 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11665 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const_int_1_operand" "")))
11667 (clobber (reg:CC 17))]
11668 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11669 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11670 "rol{l}\t%0"
11671 [(set_attr "type" "rotate")
11672 (set (attr "length")
11673 (if_then_else (match_operand:SI 0 "register_operand" "")
11674 (const_string "2")
11675 (const_string "*")))])
11676
11677 (define_insn "*rotlsi3_1_one_bit_zext"
11678 [(set (match_operand:DI 0 "register_operand" "=r")
11679 (zero_extend:DI
11680 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11681 (match_operand:QI 2 "const_int_1_operand" ""))))
11682 (clobber (reg:CC 17))]
11683 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11684 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11685 "rol{l}\t%k0"
11686 [(set_attr "type" "rotate")
11687 (set_attr "length" "2")])
11688
11689 (define_insn "*rotlsi3_1"
11690 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11691 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11692 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11693 (clobber (reg:CC 17))]
11694 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11695 "@
11696 rol{l}\t{%2, %0|%0, %2}
11697 rol{l}\t{%b2, %0|%0, %b2}"
11698 [(set_attr "type" "rotate")
11699 (set_attr "mode" "SI")])
11700
11701 (define_insn "*rotlsi3_1_zext"
11702 [(set (match_operand:DI 0 "register_operand" "=r,r")
11703 (zero_extend:DI
11704 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11705 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11706 (clobber (reg:CC 17))]
11707 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11708 "@
11709 rol{l}\t{%2, %k0|%k0, %2}
11710 rol{l}\t{%b2, %k0|%k0, %b2}"
11711 [(set_attr "type" "rotate")
11712 (set_attr "mode" "SI")])
11713
11714 (define_expand "rotlhi3"
11715 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11716 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11717 (match_operand:QI 2 "nonmemory_operand" "")))
11718 (clobber (reg:CC 17))]
11719 "TARGET_HIMODE_MATH"
11720 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11721
11722 (define_insn "*rotlhi3_1_one_bit"
11723 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11724 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11725 (match_operand:QI 2 "const_int_1_operand" "")))
11726 (clobber (reg:CC 17))]
11727 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11728 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11729 "rol{w}\t%0"
11730 [(set_attr "type" "rotate")
11731 (set (attr "length")
11732 (if_then_else (match_operand 0 "register_operand" "")
11733 (const_string "2")
11734 (const_string "*")))])
11735
11736 (define_insn "*rotlhi3_1"
11737 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11738 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11739 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11740 (clobber (reg:CC 17))]
11741 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11742 "@
11743 rol{w}\t{%2, %0|%0, %2}
11744 rol{w}\t{%b2, %0|%0, %b2}"
11745 [(set_attr "type" "rotate")
11746 (set_attr "mode" "HI")])
11747
11748 (define_expand "rotlqi3"
11749 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11750 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11751 (match_operand:QI 2 "nonmemory_operand" "")))
11752 (clobber (reg:CC 17))]
11753 "TARGET_QIMODE_MATH"
11754 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11755
11756 (define_insn "*rotlqi3_1_one_bit"
11757 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11758 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11759 (match_operand:QI 2 "const_int_1_operand" "")))
11760 (clobber (reg:CC 17))]
11761 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11762 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11763 "rol{b}\t%0"
11764 [(set_attr "type" "rotate")
11765 (set (attr "length")
11766 (if_then_else (match_operand 0 "register_operand" "")
11767 (const_string "2")
11768 (const_string "*")))])
11769
11770 (define_insn "*rotlqi3_1"
11771 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11772 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11773 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11774 (clobber (reg:CC 17))]
11775 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11776 "@
11777 rol{b}\t{%2, %0|%0, %2}
11778 rol{b}\t{%b2, %0|%0, %b2}"
11779 [(set_attr "type" "rotate")
11780 (set_attr "mode" "QI")])
11781
11782 (define_expand "rotrdi3"
11783 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11784 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11785 (match_operand:QI 2 "nonmemory_operand" "")))
11786 (clobber (reg:CC 17))]
11787 "TARGET_64BIT"
11788 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11789
11790 (define_insn "*rotrdi3_1_one_bit_rex64"
11791 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11792 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11793 (match_operand:QI 2 "const_int_1_operand" "")))
11794 (clobber (reg:CC 17))]
11795 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11796 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11797 "ror{q}\t%0"
11798 [(set_attr "type" "rotate")
11799 (set (attr "length")
11800 (if_then_else (match_operand:DI 0 "register_operand" "")
11801 (const_string "2")
11802 (const_string "*")))])
11803
11804 (define_insn "*rotrdi3_1_rex64"
11805 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11806 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11807 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11808 (clobber (reg:CC 17))]
11809 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11810 "@
11811 ror{q}\t{%2, %0|%0, %2}
11812 ror{q}\t{%b2, %0|%0, %b2}"
11813 [(set_attr "type" "rotate")
11814 (set_attr "mode" "DI")])
11815
11816 (define_expand "rotrsi3"
11817 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11818 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11819 (match_operand:QI 2 "nonmemory_operand" "")))
11820 (clobber (reg:CC 17))]
11821 ""
11822 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11823
11824 (define_insn "*rotrsi3_1_one_bit"
11825 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11826 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11827 (match_operand:QI 2 "const_int_1_operand" "")))
11828 (clobber (reg:CC 17))]
11829 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11830 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11831 "ror{l}\t%0"
11832 [(set_attr "type" "rotate")
11833 (set (attr "length")
11834 (if_then_else (match_operand:SI 0 "register_operand" "")
11835 (const_string "2")
11836 (const_string "*")))])
11837
11838 (define_insn "*rotrsi3_1_one_bit_zext"
11839 [(set (match_operand:DI 0 "register_operand" "=r")
11840 (zero_extend:DI
11841 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11842 (match_operand:QI 2 "const_int_1_operand" ""))))
11843 (clobber (reg:CC 17))]
11844 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11845 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11846 "ror{l}\t%k0"
11847 [(set_attr "type" "rotate")
11848 (set (attr "length")
11849 (if_then_else (match_operand:SI 0 "register_operand" "")
11850 (const_string "2")
11851 (const_string "*")))])
11852
11853 (define_insn "*rotrsi3_1"
11854 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11855 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11856 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11857 (clobber (reg:CC 17))]
11858 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11859 "@
11860 ror{l}\t{%2, %0|%0, %2}
11861 ror{l}\t{%b2, %0|%0, %b2}"
11862 [(set_attr "type" "rotate")
11863 (set_attr "mode" "SI")])
11864
11865 (define_insn "*rotrsi3_1_zext"
11866 [(set (match_operand:DI 0 "register_operand" "=r,r")
11867 (zero_extend:DI
11868 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11869 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11870 (clobber (reg:CC 17))]
11871 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11872 "@
11873 ror{l}\t{%2, %k0|%k0, %2}
11874 ror{l}\t{%b2, %k0|%k0, %b2}"
11875 [(set_attr "type" "rotate")
11876 (set_attr "mode" "SI")])
11877
11878 (define_expand "rotrhi3"
11879 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11880 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11881 (match_operand:QI 2 "nonmemory_operand" "")))
11882 (clobber (reg:CC 17))]
11883 "TARGET_HIMODE_MATH"
11884 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11885
11886 (define_insn "*rotrhi3_one_bit"
11887 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11888 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11889 (match_operand:QI 2 "const_int_1_operand" "")))
11890 (clobber (reg:CC 17))]
11891 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11892 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11893 "ror{w}\t%0"
11894 [(set_attr "type" "rotate")
11895 (set (attr "length")
11896 (if_then_else (match_operand 0 "register_operand" "")
11897 (const_string "2")
11898 (const_string "*")))])
11899
11900 (define_insn "*rotrhi3"
11901 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11902 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11903 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11904 (clobber (reg:CC 17))]
11905 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11906 "@
11907 ror{w}\t{%2, %0|%0, %2}
11908 ror{w}\t{%b2, %0|%0, %b2}"
11909 [(set_attr "type" "rotate")
11910 (set_attr "mode" "HI")])
11911
11912 (define_expand "rotrqi3"
11913 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11914 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11915 (match_operand:QI 2 "nonmemory_operand" "")))
11916 (clobber (reg:CC 17))]
11917 "TARGET_QIMODE_MATH"
11918 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11919
11920 (define_insn "*rotrqi3_1_one_bit"
11921 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11922 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11923 (match_operand:QI 2 "const_int_1_operand" "")))
11924 (clobber (reg:CC 17))]
11925 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
11926 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11927 "ror{b}\t%0"
11928 [(set_attr "type" "rotate")
11929 (set (attr "length")
11930 (if_then_else (match_operand 0 "register_operand" "")
11931 (const_string "2")
11932 (const_string "*")))])
11933
11934 (define_insn "*rotrqi3_1"
11935 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11936 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11937 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11938 (clobber (reg:CC 17))]
11939 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
11940 "@
11941 ror{b}\t{%2, %0|%0, %2}
11942 ror{b}\t{%b2, %0|%0, %b2}"
11943 [(set_attr "type" "rotate")
11944 (set_attr "mode" "QI")])
11945 \f
11946 ;; Bit set / bit test instructions
11947
11948 (define_expand "extv"
11949 [(set (match_operand:SI 0 "register_operand" "")
11950 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
11951 (match_operand:SI 2 "immediate_operand" "")
11952 (match_operand:SI 3 "immediate_operand" "")))]
11953 ""
11954 {
11955 /* Handle extractions from %ah et al. */
11956 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11957 FAIL;
11958
11959 /* From mips.md: extract_bit_field doesn't verify that our source
11960 matches the predicate, so check it again here. */
11961 if (! register_operand (operands[1], VOIDmode))
11962 FAIL;
11963 })
11964
11965 (define_expand "extzv"
11966 [(set (match_operand:SI 0 "register_operand" "")
11967 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
11968 (match_operand:SI 2 "immediate_operand" "")
11969 (match_operand:SI 3 "immediate_operand" "")))]
11970 ""
11971 {
11972 /* Handle extractions from %ah et al. */
11973 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
11974 FAIL;
11975
11976 /* From mips.md: extract_bit_field doesn't verify that our source
11977 matches the predicate, so check it again here. */
11978 if (! register_operand (operands[1], VOIDmode))
11979 FAIL;
11980 })
11981
11982 (define_expand "insv"
11983 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
11984 (match_operand:SI 1 "immediate_operand" "")
11985 (match_operand:SI 2 "immediate_operand" ""))
11986 (match_operand:SI 3 "register_operand" ""))]
11987 ""
11988 {
11989 /* Handle extractions from %ah et al. */
11990 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
11991 FAIL;
11992
11993 /* From mips.md: insert_bit_field doesn't verify that our source
11994 matches the predicate, so check it again here. */
11995 if (! register_operand (operands[0], VOIDmode))
11996 FAIL;
11997 })
11998
11999 ;; %%% bts, btr, btc, bt.
12000 \f
12001 ;; Store-flag instructions.
12002
12003 ;; For all sCOND expanders, also expand the compare or test insn that
12004 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12005
12006 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12007 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12008 ;; way, which can later delete the movzx if only QImode is needed.
12009
12010 (define_expand "seq"
12011 [(set (match_operand:QI 0 "register_operand" "")
12012 (eq:QI (reg:CC 17) (const_int 0)))]
12013 ""
12014 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12015
12016 (define_expand "sne"
12017 [(set (match_operand:QI 0 "register_operand" "")
12018 (ne:QI (reg:CC 17) (const_int 0)))]
12019 ""
12020 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12021
12022 (define_expand "sgt"
12023 [(set (match_operand:QI 0 "register_operand" "")
12024 (gt:QI (reg:CC 17) (const_int 0)))]
12025 ""
12026 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12027
12028 (define_expand "sgtu"
12029 [(set (match_operand:QI 0 "register_operand" "")
12030 (gtu:QI (reg:CC 17) (const_int 0)))]
12031 ""
12032 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12033
12034 (define_expand "slt"
12035 [(set (match_operand:QI 0 "register_operand" "")
12036 (lt:QI (reg:CC 17) (const_int 0)))]
12037 ""
12038 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12039
12040 (define_expand "sltu"
12041 [(set (match_operand:QI 0 "register_operand" "")
12042 (ltu:QI (reg:CC 17) (const_int 0)))]
12043 ""
12044 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12045
12046 (define_expand "sge"
12047 [(set (match_operand:QI 0 "register_operand" "")
12048 (ge:QI (reg:CC 17) (const_int 0)))]
12049 ""
12050 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12051
12052 (define_expand "sgeu"
12053 [(set (match_operand:QI 0 "register_operand" "")
12054 (geu:QI (reg:CC 17) (const_int 0)))]
12055 ""
12056 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12057
12058 (define_expand "sle"
12059 [(set (match_operand:QI 0 "register_operand" "")
12060 (le:QI (reg:CC 17) (const_int 0)))]
12061 ""
12062 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12063
12064 (define_expand "sleu"
12065 [(set (match_operand:QI 0 "register_operand" "")
12066 (leu:QI (reg:CC 17) (const_int 0)))]
12067 ""
12068 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12069
12070 (define_expand "sunordered"
12071 [(set (match_operand:QI 0 "register_operand" "")
12072 (unordered:QI (reg:CC 17) (const_int 0)))]
12073 "TARGET_80387 || TARGET_SSE"
12074 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12075
12076 (define_expand "sordered"
12077 [(set (match_operand:QI 0 "register_operand" "")
12078 (ordered:QI (reg:CC 17) (const_int 0)))]
12079 "TARGET_80387"
12080 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12081
12082 (define_expand "suneq"
12083 [(set (match_operand:QI 0 "register_operand" "")
12084 (uneq:QI (reg:CC 17) (const_int 0)))]
12085 "TARGET_80387 || TARGET_SSE"
12086 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12087
12088 (define_expand "sunge"
12089 [(set (match_operand:QI 0 "register_operand" "")
12090 (unge:QI (reg:CC 17) (const_int 0)))]
12091 "TARGET_80387 || TARGET_SSE"
12092 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12093
12094 (define_expand "sungt"
12095 [(set (match_operand:QI 0 "register_operand" "")
12096 (ungt:QI (reg:CC 17) (const_int 0)))]
12097 "TARGET_80387 || TARGET_SSE"
12098 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12099
12100 (define_expand "sunle"
12101 [(set (match_operand:QI 0 "register_operand" "")
12102 (unle:QI (reg:CC 17) (const_int 0)))]
12103 "TARGET_80387 || TARGET_SSE"
12104 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12105
12106 (define_expand "sunlt"
12107 [(set (match_operand:QI 0 "register_operand" "")
12108 (unlt:QI (reg:CC 17) (const_int 0)))]
12109 "TARGET_80387 || TARGET_SSE"
12110 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12111
12112 (define_expand "sltgt"
12113 [(set (match_operand:QI 0 "register_operand" "")
12114 (ltgt:QI (reg:CC 17) (const_int 0)))]
12115 "TARGET_80387 || TARGET_SSE"
12116 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12117
12118 (define_insn "*setcc_1"
12119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12120 (match_operator:QI 1 "ix86_comparison_operator"
12121 [(reg 17) (const_int 0)]))]
12122 ""
12123 "set%C1\t%0"
12124 [(set_attr "type" "setcc")
12125 (set_attr "mode" "QI")])
12126
12127 (define_insn "setcc_2"
12128 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12129 (match_operator:QI 1 "ix86_comparison_operator"
12130 [(reg 17) (const_int 0)]))]
12131 ""
12132 "set%C1\t%0"
12133 [(set_attr "type" "setcc")
12134 (set_attr "mode" "QI")])
12135
12136 ;; In general it is not safe to assume too much about CCmode registers,
12137 ;; so simplify-rtx stops when it sees a second one. Under certain
12138 ;; conditions this is safe on x86, so help combine not create
12139 ;;
12140 ;; seta %al
12141 ;; testb %al, %al
12142 ;; sete %al
12143
12144 (define_split
12145 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12146 (ne:QI (match_operator 1 "ix86_comparison_operator"
12147 [(reg 17) (const_int 0)])
12148 (const_int 0)))]
12149 ""
12150 [(set (match_dup 0) (match_dup 1))]
12151 {
12152 PUT_MODE (operands[1], QImode);
12153 })
12154
12155 (define_split
12156 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12157 (ne:QI (match_operator 1 "ix86_comparison_operator"
12158 [(reg 17) (const_int 0)])
12159 (const_int 0)))]
12160 ""
12161 [(set (match_dup 0) (match_dup 1))]
12162 {
12163 PUT_MODE (operands[1], QImode);
12164 })
12165
12166 (define_split
12167 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12168 (eq:QI (match_operator 1 "ix86_comparison_operator"
12169 [(reg 17) (const_int 0)])
12170 (const_int 0)))]
12171 ""
12172 [(set (match_dup 0) (match_dup 1))]
12173 {
12174 rtx new_op1 = copy_rtx (operands[1]);
12175 operands[1] = new_op1;
12176 PUT_MODE (new_op1, QImode);
12177 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12178 GET_MODE (XEXP (new_op1, 0))));
12179
12180 /* Make sure that (a) the CCmode we have for the flags is strong
12181 enough for the reversed compare or (b) we have a valid FP compare. */
12182 if (! ix86_comparison_operator (new_op1, VOIDmode))
12183 FAIL;
12184 })
12185
12186 (define_split
12187 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12188 (eq:QI (match_operator 1 "ix86_comparison_operator"
12189 [(reg 17) (const_int 0)])
12190 (const_int 0)))]
12191 ""
12192 [(set (match_dup 0) (match_dup 1))]
12193 {
12194 rtx new_op1 = copy_rtx (operands[1]);
12195 operands[1] = new_op1;
12196 PUT_MODE (new_op1, QImode);
12197 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12198 GET_MODE (XEXP (new_op1, 0))));
12199
12200 /* Make sure that (a) the CCmode we have for the flags is strong
12201 enough for the reversed compare or (b) we have a valid FP compare. */
12202 if (! ix86_comparison_operator (new_op1, VOIDmode))
12203 FAIL;
12204 })
12205
12206 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12207 ;; subsequent logical operations are used to imitate conditional moves.
12208 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12209 ;; it directly. Futher holding this value in pseudo register might bring
12210 ;; problem in implicit normalization in spill code.
12211 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12212 ;; instructions after reload by splitting the conditional move patterns.
12213
12214 (define_insn "*sse_setccsf"
12215 [(set (match_operand:SF 0 "register_operand" "=x")
12216 (match_operator:SF 1 "sse_comparison_operator"
12217 [(match_operand:SF 2 "register_operand" "0")
12218 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12219 "TARGET_SSE && reload_completed"
12220 "cmp%D1ss\t{%3, %0|%0, %3}"
12221 [(set_attr "type" "ssecmp")
12222 (set_attr "mode" "SF")])
12223
12224 (define_insn "*sse_setccdf"
12225 [(set (match_operand:DF 0 "register_operand" "=Y")
12226 (match_operator:DF 1 "sse_comparison_operator"
12227 [(match_operand:DF 2 "register_operand" "0")
12228 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12229 "TARGET_SSE2 && reload_completed"
12230 "cmp%D1sd\t{%3, %0|%0, %3}"
12231 [(set_attr "type" "ssecmp")
12232 (set_attr "mode" "DF")])
12233 \f
12234 ;; Basic conditional jump instructions.
12235 ;; We ignore the overflow flag for signed branch instructions.
12236
12237 ;; For all bCOND expanders, also expand the compare or test insn that
12238 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12239
12240 (define_expand "beq"
12241 [(set (pc)
12242 (if_then_else (match_dup 1)
12243 (label_ref (match_operand 0 "" ""))
12244 (pc)))]
12245 ""
12246 "ix86_expand_branch (EQ, operands[0]); DONE;")
12247
12248 (define_expand "bne"
12249 [(set (pc)
12250 (if_then_else (match_dup 1)
12251 (label_ref (match_operand 0 "" ""))
12252 (pc)))]
12253 ""
12254 "ix86_expand_branch (NE, operands[0]); DONE;")
12255
12256 (define_expand "bgt"
12257 [(set (pc)
12258 (if_then_else (match_dup 1)
12259 (label_ref (match_operand 0 "" ""))
12260 (pc)))]
12261 ""
12262 "ix86_expand_branch (GT, operands[0]); DONE;")
12263
12264 (define_expand "bgtu"
12265 [(set (pc)
12266 (if_then_else (match_dup 1)
12267 (label_ref (match_operand 0 "" ""))
12268 (pc)))]
12269 ""
12270 "ix86_expand_branch (GTU, operands[0]); DONE;")
12271
12272 (define_expand "blt"
12273 [(set (pc)
12274 (if_then_else (match_dup 1)
12275 (label_ref (match_operand 0 "" ""))
12276 (pc)))]
12277 ""
12278 "ix86_expand_branch (LT, operands[0]); DONE;")
12279
12280 (define_expand "bltu"
12281 [(set (pc)
12282 (if_then_else (match_dup 1)
12283 (label_ref (match_operand 0 "" ""))
12284 (pc)))]
12285 ""
12286 "ix86_expand_branch (LTU, operands[0]); DONE;")
12287
12288 (define_expand "bge"
12289 [(set (pc)
12290 (if_then_else (match_dup 1)
12291 (label_ref (match_operand 0 "" ""))
12292 (pc)))]
12293 ""
12294 "ix86_expand_branch (GE, operands[0]); DONE;")
12295
12296 (define_expand "bgeu"
12297 [(set (pc)
12298 (if_then_else (match_dup 1)
12299 (label_ref (match_operand 0 "" ""))
12300 (pc)))]
12301 ""
12302 "ix86_expand_branch (GEU, operands[0]); DONE;")
12303
12304 (define_expand "ble"
12305 [(set (pc)
12306 (if_then_else (match_dup 1)
12307 (label_ref (match_operand 0 "" ""))
12308 (pc)))]
12309 ""
12310 "ix86_expand_branch (LE, operands[0]); DONE;")
12311
12312 (define_expand "bleu"
12313 [(set (pc)
12314 (if_then_else (match_dup 1)
12315 (label_ref (match_operand 0 "" ""))
12316 (pc)))]
12317 ""
12318 "ix86_expand_branch (LEU, operands[0]); DONE;")
12319
12320 (define_expand "bunordered"
12321 [(set (pc)
12322 (if_then_else (match_dup 1)
12323 (label_ref (match_operand 0 "" ""))
12324 (pc)))]
12325 "TARGET_80387 || TARGET_SSE"
12326 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12327
12328 (define_expand "bordered"
12329 [(set (pc)
12330 (if_then_else (match_dup 1)
12331 (label_ref (match_operand 0 "" ""))
12332 (pc)))]
12333 "TARGET_80387 || TARGET_SSE"
12334 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12335
12336 (define_expand "buneq"
12337 [(set (pc)
12338 (if_then_else (match_dup 1)
12339 (label_ref (match_operand 0 "" ""))
12340 (pc)))]
12341 "TARGET_80387 || TARGET_SSE"
12342 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12343
12344 (define_expand "bunge"
12345 [(set (pc)
12346 (if_then_else (match_dup 1)
12347 (label_ref (match_operand 0 "" ""))
12348 (pc)))]
12349 "TARGET_80387 || TARGET_SSE"
12350 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12351
12352 (define_expand "bungt"
12353 [(set (pc)
12354 (if_then_else (match_dup 1)
12355 (label_ref (match_operand 0 "" ""))
12356 (pc)))]
12357 "TARGET_80387 || TARGET_SSE"
12358 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12359
12360 (define_expand "bunle"
12361 [(set (pc)
12362 (if_then_else (match_dup 1)
12363 (label_ref (match_operand 0 "" ""))
12364 (pc)))]
12365 "TARGET_80387 || TARGET_SSE"
12366 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12367
12368 (define_expand "bunlt"
12369 [(set (pc)
12370 (if_then_else (match_dup 1)
12371 (label_ref (match_operand 0 "" ""))
12372 (pc)))]
12373 "TARGET_80387 || TARGET_SSE"
12374 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12375
12376 (define_expand "bltgt"
12377 [(set (pc)
12378 (if_then_else (match_dup 1)
12379 (label_ref (match_operand 0 "" ""))
12380 (pc)))]
12381 "TARGET_80387 || TARGET_SSE"
12382 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12383
12384 (define_insn "*jcc_1"
12385 [(set (pc)
12386 (if_then_else (match_operator 1 "ix86_comparison_operator"
12387 [(reg 17) (const_int 0)])
12388 (label_ref (match_operand 0 "" ""))
12389 (pc)))]
12390 ""
12391 "%+j%C1\t%l0"
12392 [(set_attr "type" "ibr")
12393 (set (attr "prefix_0f")
12394 (if_then_else (and (ge (minus (match_dup 0) (pc))
12395 (const_int -128))
12396 (lt (minus (match_dup 0) (pc))
12397 (const_int 124)))
12398 (const_int 0)
12399 (const_int 1)))])
12400
12401 (define_insn "*jcc_2"
12402 [(set (pc)
12403 (if_then_else (match_operator 1 "ix86_comparison_operator"
12404 [(reg 17) (const_int 0)])
12405 (pc)
12406 (label_ref (match_operand 0 "" ""))))]
12407 ""
12408 "%+j%c1\t%l0"
12409 [(set_attr "type" "ibr")
12410 (set (attr "prefix_0f")
12411 (if_then_else (and (ge (minus (match_dup 0) (pc))
12412 (const_int -128))
12413 (lt (minus (match_dup 0) (pc))
12414 (const_int 124)))
12415 (const_int 0)
12416 (const_int 1)))])
12417
12418 ;; In general it is not safe to assume too much about CCmode registers,
12419 ;; so simplify-rtx stops when it sees a second one. Under certain
12420 ;; conditions this is safe on x86, so help combine not create
12421 ;;
12422 ;; seta %al
12423 ;; testb %al, %al
12424 ;; je Lfoo
12425
12426 (define_split
12427 [(set (pc)
12428 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12429 [(reg 17) (const_int 0)])
12430 (const_int 0))
12431 (label_ref (match_operand 1 "" ""))
12432 (pc)))]
12433 ""
12434 [(set (pc)
12435 (if_then_else (match_dup 0)
12436 (label_ref (match_dup 1))
12437 (pc)))]
12438 {
12439 PUT_MODE (operands[0], VOIDmode);
12440 })
12441
12442 (define_split
12443 [(set (pc)
12444 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12445 [(reg 17) (const_int 0)])
12446 (const_int 0))
12447 (label_ref (match_operand 1 "" ""))
12448 (pc)))]
12449 ""
12450 [(set (pc)
12451 (if_then_else (match_dup 0)
12452 (label_ref (match_dup 1))
12453 (pc)))]
12454 {
12455 rtx new_op0 = copy_rtx (operands[0]);
12456 operands[0] = new_op0;
12457 PUT_MODE (new_op0, VOIDmode);
12458 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
12459 GET_MODE (XEXP (new_op0, 0))));
12460
12461 /* Make sure that (a) the CCmode we have for the flags is strong
12462 enough for the reversed compare or (b) we have a valid FP compare. */
12463 if (! ix86_comparison_operator (new_op0, VOIDmode))
12464 FAIL;
12465 })
12466
12467 ;; Define combination compare-and-branch fp compare instructions to use
12468 ;; during early optimization. Splitting the operation apart early makes
12469 ;; for bad code when we want to reverse the operation.
12470
12471 (define_insn "*fp_jcc_1"
12472 [(set (pc)
12473 (if_then_else (match_operator 0 "comparison_operator"
12474 [(match_operand 1 "register_operand" "f")
12475 (match_operand 2 "register_operand" "f")])
12476 (label_ref (match_operand 3 "" ""))
12477 (pc)))
12478 (clobber (reg:CCFP 18))
12479 (clobber (reg:CCFP 17))]
12480 "TARGET_CMOVE && TARGET_80387
12481 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12482 && FLOAT_MODE_P (GET_MODE (operands[1]))
12483 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12484 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12485 "#")
12486
12487 (define_insn "*fp_jcc_1_sse"
12488 [(set (pc)
12489 (if_then_else (match_operator 0 "comparison_operator"
12490 [(match_operand 1 "register_operand" "f#x,x#f")
12491 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12492 (label_ref (match_operand 3 "" ""))
12493 (pc)))
12494 (clobber (reg:CCFP 18))
12495 (clobber (reg:CCFP 17))]
12496 "TARGET_80387
12497 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12498 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12499 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12500 "#")
12501
12502 (define_insn "*fp_jcc_1_sse_only"
12503 [(set (pc)
12504 (if_then_else (match_operator 0 "comparison_operator"
12505 [(match_operand 1 "register_operand" "x")
12506 (match_operand 2 "nonimmediate_operand" "xm")])
12507 (label_ref (match_operand 3 "" ""))
12508 (pc)))
12509 (clobber (reg:CCFP 18))
12510 (clobber (reg:CCFP 17))]
12511 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12512 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12513 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12514 "#")
12515
12516 (define_insn "*fp_jcc_2"
12517 [(set (pc)
12518 (if_then_else (match_operator 0 "comparison_operator"
12519 [(match_operand 1 "register_operand" "f")
12520 (match_operand 2 "register_operand" "f")])
12521 (pc)
12522 (label_ref (match_operand 3 "" ""))))
12523 (clobber (reg:CCFP 18))
12524 (clobber (reg:CCFP 17))]
12525 "TARGET_CMOVE && TARGET_80387
12526 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12527 && FLOAT_MODE_P (GET_MODE (operands[1]))
12528 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12529 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12530 "#")
12531
12532 (define_insn "*fp_jcc_2_sse"
12533 [(set (pc)
12534 (if_then_else (match_operator 0 "comparison_operator"
12535 [(match_operand 1 "register_operand" "f#x,x#f")
12536 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12537 (pc)
12538 (label_ref (match_operand 3 "" ""))))
12539 (clobber (reg:CCFP 18))
12540 (clobber (reg:CCFP 17))]
12541 "TARGET_80387
12542 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12543 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12544 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12545 "#")
12546
12547 (define_insn "*fp_jcc_2_sse_only"
12548 [(set (pc)
12549 (if_then_else (match_operator 0 "comparison_operator"
12550 [(match_operand 1 "register_operand" "x")
12551 (match_operand 2 "nonimmediate_operand" "xm")])
12552 (pc)
12553 (label_ref (match_operand 3 "" ""))))
12554 (clobber (reg:CCFP 18))
12555 (clobber (reg:CCFP 17))]
12556 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12557 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12558 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12559 "#")
12560
12561 (define_insn "*fp_jcc_3"
12562 [(set (pc)
12563 (if_then_else (match_operator 0 "comparison_operator"
12564 [(match_operand 1 "register_operand" "f")
12565 (match_operand 2 "nonimmediate_operand" "fm")])
12566 (label_ref (match_operand 3 "" ""))
12567 (pc)))
12568 (clobber (reg:CCFP 18))
12569 (clobber (reg:CCFP 17))
12570 (clobber (match_scratch:HI 4 "=a"))]
12571 "TARGET_80387
12572 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12573 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12574 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12575 && SELECT_CC_MODE (GET_CODE (operands[0]),
12576 operands[1], operands[2]) == CCFPmode
12577 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12578 "#")
12579
12580 (define_insn "*fp_jcc_4"
12581 [(set (pc)
12582 (if_then_else (match_operator 0 "comparison_operator"
12583 [(match_operand 1 "register_operand" "f")
12584 (match_operand 2 "nonimmediate_operand" "fm")])
12585 (pc)
12586 (label_ref (match_operand 3 "" ""))))
12587 (clobber (reg:CCFP 18))
12588 (clobber (reg:CCFP 17))
12589 (clobber (match_scratch:HI 4 "=a"))]
12590 "TARGET_80387
12591 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12592 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12593 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12594 && SELECT_CC_MODE (GET_CODE (operands[0]),
12595 operands[1], operands[2]) == CCFPmode
12596 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12597 "#")
12598
12599 (define_insn "*fp_jcc_5"
12600 [(set (pc)
12601 (if_then_else (match_operator 0 "comparison_operator"
12602 [(match_operand 1 "register_operand" "f")
12603 (match_operand 2 "register_operand" "f")])
12604 (label_ref (match_operand 3 "" ""))
12605 (pc)))
12606 (clobber (reg:CCFP 18))
12607 (clobber (reg:CCFP 17))
12608 (clobber (match_scratch:HI 4 "=a"))]
12609 "TARGET_80387
12610 && FLOAT_MODE_P (GET_MODE (operands[1]))
12611 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12612 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12613 "#")
12614
12615 (define_insn "*fp_jcc_6"
12616 [(set (pc)
12617 (if_then_else (match_operator 0 "comparison_operator"
12618 [(match_operand 1 "register_operand" "f")
12619 (match_operand 2 "register_operand" "f")])
12620 (pc)
12621 (label_ref (match_operand 3 "" ""))))
12622 (clobber (reg:CCFP 18))
12623 (clobber (reg:CCFP 17))
12624 (clobber (match_scratch:HI 4 "=a"))]
12625 "TARGET_80387
12626 && FLOAT_MODE_P (GET_MODE (operands[1]))
12627 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12628 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12629 "#")
12630
12631 (define_split
12632 [(set (pc)
12633 (if_then_else (match_operator 0 "comparison_operator"
12634 [(match_operand 1 "register_operand" "")
12635 (match_operand 2 "nonimmediate_operand" "")])
12636 (match_operand 3 "" "")
12637 (match_operand 4 "" "")))
12638 (clobber (reg:CCFP 18))
12639 (clobber (reg:CCFP 17))]
12640 "reload_completed"
12641 [(const_int 0)]
12642 {
12643 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12644 operands[3], operands[4], NULL_RTX);
12645 DONE;
12646 })
12647
12648 (define_split
12649 [(set (pc)
12650 (if_then_else (match_operator 0 "comparison_operator"
12651 [(match_operand 1 "register_operand" "")
12652 (match_operand 2 "nonimmediate_operand" "")])
12653 (match_operand 3 "" "")
12654 (match_operand 4 "" "")))
12655 (clobber (reg:CCFP 18))
12656 (clobber (reg:CCFP 17))
12657 (clobber (match_scratch:HI 5 "=a"))]
12658 "reload_completed"
12659 [(set (pc)
12660 (if_then_else (match_dup 6)
12661 (match_dup 3)
12662 (match_dup 4)))]
12663 {
12664 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12665 operands[3], operands[4], operands[5]);
12666 DONE;
12667 })
12668 \f
12669 ;; Unconditional and other jump instructions
12670
12671 (define_insn "jump"
12672 [(set (pc)
12673 (label_ref (match_operand 0 "" "")))]
12674 ""
12675 "jmp\t%l0"
12676 [(set_attr "type" "ibr")])
12677
12678 (define_expand "indirect_jump"
12679 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
12680 ""
12681 "")
12682
12683 (define_insn "*indirect_jump"
12684 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
12685 "!TARGET_64BIT"
12686 "jmp\t%A0"
12687 [(set_attr "type" "ibr")
12688 (set_attr "length_immediate" "0")])
12689
12690 (define_insn "*indirect_jump_rtx64"
12691 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
12692 "TARGET_64BIT"
12693 "jmp\t%A0"
12694 [(set_attr "type" "ibr")
12695 (set_attr "length_immediate" "0")])
12696
12697 (define_expand "tablejump"
12698 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
12699 (use (label_ref (match_operand 1 "" "")))])]
12700 ""
12701 {
12702 /* In PIC mode, the table entries are stored GOT-relative. Convert
12703 the relative address to an absolute address. */
12704 if (flag_pic)
12705 {
12706 if (TARGET_64BIT)
12707 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
12708 gen_rtx_LABEL_REF (Pmode, operands[1]),
12709 NULL_RTX, 0,
12710 OPTAB_DIRECT);
12711 else if (HAVE_AS_GOTOFF_IN_DATA)
12712 {
12713 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
12714 pic_offset_table_rtx, NULL_RTX,
12715 1, OPTAB_DIRECT);
12716 current_function_uses_pic_offset_table = 1;
12717 }
12718 else
12719 {
12720 operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
12721 operands[0], NULL_RTX, 1,
12722 OPTAB_DIRECT);
12723 current_function_uses_pic_offset_table = 1;
12724 }
12725 }
12726 })
12727
12728 (define_insn "*tablejump_1"
12729 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
12730 (use (label_ref (match_operand 1 "" "")))]
12731 "!TARGET_64BIT"
12732 "jmp\t%A0"
12733 [(set_attr "type" "ibr")
12734 (set_attr "length_immediate" "0")])
12735
12736 (define_insn "*tablejump_1_rtx64"
12737 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
12738 (use (label_ref (match_operand 1 "" "")))]
12739 "TARGET_64BIT"
12740 "jmp\t%A0"
12741 [(set_attr "type" "ibr")
12742 (set_attr "length_immediate" "0")])
12743 \f
12744 ;; Loop instruction
12745 ;;
12746 ;; This is all complicated by the fact that since this is a jump insn
12747 ;; we must handle our own reloads.
12748
12749 (define_expand "doloop_end"
12750 [(use (match_operand 0 "" "")) ; loop pseudo
12751 (use (match_operand 1 "" "")) ; iterations; zero if unknown
12752 (use (match_operand 2 "" "")) ; max iterations
12753 (use (match_operand 3 "" "")) ; loop level
12754 (use (match_operand 4 "" ""))] ; label
12755 "!TARGET_64BIT && TARGET_USE_LOOP"
12756 "
12757 {
12758 /* Only use cloop on innermost loops. */
12759 if (INTVAL (operands[3]) > 1)
12760 FAIL;
12761 if (GET_MODE (operands[0]) != SImode)
12762 FAIL;
12763 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
12764 operands[0]));
12765 DONE;
12766 }")
12767
12768 (define_insn "doloop_end_internal"
12769 [(set (pc)
12770 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
12771 (const_int 1))
12772 (label_ref (match_operand 0 "" ""))
12773 (pc)))
12774 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
12775 (plus:SI (match_dup 1)
12776 (const_int -1)))
12777 (clobber (match_scratch:SI 3 "=X,X,r"))
12778 (clobber (reg:CC 17))]
12779 "!TARGET_64BIT && TARGET_USE_LOOP"
12780 {
12781 if (which_alternative != 0)
12782 return "#";
12783 if (get_attr_length (insn) == 2)
12784 return "%+loop\t%l0";
12785 else
12786 return "dec{l}\t%1\;%+jne\t%l0";
12787 }
12788 [(set_attr "ppro_uops" "many")
12789 (set (attr "type")
12790 (if_then_else (and (eq_attr "alternative" "0")
12791 (and (ge (minus (match_dup 0) (pc))
12792 (const_int -128))
12793 (lt (minus (match_dup 0) (pc))
12794 (const_int 124))))
12795 (const_string "ibr")
12796 (const_string "multi")))])
12797
12798 (define_split
12799 [(set (pc)
12800 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
12801 (const_int 1))
12802 (match_operand 0 "" "")
12803 (pc)))
12804 (set (match_dup 1)
12805 (plus:SI (match_dup 1)
12806 (const_int -1)))
12807 (clobber (match_scratch:SI 2 ""))
12808 (clobber (reg:CC 17))]
12809 "!TARGET_64BIT && TARGET_USE_LOOP
12810 && reload_completed
12811 && REGNO (operands[1]) != 2"
12812 [(parallel [(set (reg:CCZ 17)
12813 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
12814 (const_int 0)))
12815 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
12816 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
12817 (match_dup 0)
12818 (pc)))]
12819 "")
12820
12821 (define_split
12822 [(set (pc)
12823 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
12824 (const_int 1))
12825 (match_operand 0 "" "")
12826 (pc)))
12827 (set (match_operand:SI 2 "nonimmediate_operand" "")
12828 (plus:SI (match_dup 1)
12829 (const_int -1)))
12830 (clobber (match_scratch:SI 3 ""))
12831 (clobber (reg:CC 17))]
12832 "!TARGET_64BIT && TARGET_USE_LOOP
12833 && reload_completed
12834 && (! REG_P (operands[2])
12835 || ! rtx_equal_p (operands[1], operands[2]))"
12836 [(set (match_dup 3) (match_dup 1))
12837 (parallel [(set (reg:CCZ 17)
12838 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
12839 (const_int 0)))
12840 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
12841 (set (match_dup 2) (match_dup 3))
12842 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
12843 (match_dup 0)
12844 (pc)))]
12845 "")
12846
12847 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12848
12849 (define_peephole2
12850 [(set (reg 17) (match_operand 0 "" ""))
12851 (set (match_operand:QI 1 "register_operand" "")
12852 (match_operator:QI 2 "ix86_comparison_operator"
12853 [(reg 17) (const_int 0)]))
12854 (set (match_operand 3 "q_regs_operand" "")
12855 (zero_extend (match_dup 1)))]
12856 "(peep2_reg_dead_p (3, operands[1])
12857 || operands_match_p (operands[1], operands[3]))
12858 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
12859 [(set (match_dup 4) (match_dup 0))
12860 (set (strict_low_part (match_dup 5))
12861 (match_dup 2))]
12862 {
12863 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
12864 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
12865 ix86_expand_clear (operands[3]);
12866 })
12867
12868 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
12869
12870 (define_peephole2
12871 [(set (reg 17) (match_operand 0 "" ""))
12872 (set (match_operand:QI 1 "register_operand" "")
12873 (match_operator:QI 2 "ix86_comparison_operator"
12874 [(reg 17) (const_int 0)]))
12875 (parallel [(set (match_operand 3 "q_regs_operand" "")
12876 (zero_extend (match_dup 1)))
12877 (clobber (reg:CC 17))])]
12878 "(peep2_reg_dead_p (3, operands[1])
12879 || operands_match_p (operands[1], operands[3]))
12880 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
12881 [(set (match_dup 4) (match_dup 0))
12882 (set (strict_low_part (match_dup 5))
12883 (match_dup 2))]
12884 {
12885 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
12886 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
12887 ix86_expand_clear (operands[3]);
12888 })
12889 \f
12890 ;; Call instructions.
12891
12892 ;; The predicates normally associated with named expanders are not properly
12893 ;; checked for calls. This is a bug in the generic code, but it isn't that
12894 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12895
12896 ;; Call subroutine returning no value.
12897
12898 (define_expand "call_pop"
12899 [(parallel [(call (match_operand:QI 0 "" "")
12900 (match_operand:SI 1 "" ""))
12901 (set (reg:SI 7)
12902 (plus:SI (reg:SI 7)
12903 (match_operand:SI 3 "" "")))])]
12904 "!TARGET_64BIT"
12905 {
12906 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3]);
12907 DONE;
12908 })
12909
12910 (define_insn "*call_pop_0"
12911 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
12912 (match_operand:SI 1 "" ""))
12913 (set (reg:SI 7) (plus:SI (reg:SI 7)
12914 (match_operand:SI 2 "immediate_operand" "")))]
12915 "!TARGET_64BIT"
12916 {
12917 if (SIBLING_CALL_P (insn))
12918 return "jmp\t%P0";
12919 else
12920 return "call\t%P0";
12921 }
12922 [(set_attr "type" "call")])
12923
12924 (define_insn "*call_pop_1"
12925 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
12926 (match_operand:SI 1 "" ""))
12927 (set (reg:SI 7) (plus:SI (reg:SI 7)
12928 (match_operand:SI 2 "immediate_operand" "i")))]
12929 "!TARGET_64BIT"
12930 {
12931 if (constant_call_address_operand (operands[0], Pmode))
12932 {
12933 if (SIBLING_CALL_P (insn))
12934 return "jmp\t%P0";
12935 else
12936 return "call\t%P0";
12937 }
12938 if (SIBLING_CALL_P (insn))
12939 return "jmp\t%A0";
12940 else
12941 return "call\t%A0";
12942 }
12943 [(set_attr "type" "call")])
12944
12945 (define_expand "call"
12946 [(call (match_operand:QI 0 "" "")
12947 (match_operand 1 "" ""))
12948 (use (match_operand 2 "" ""))]
12949 ""
12950 {
12951 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL);
12952 DONE;
12953 })
12954
12955 (define_insn "*call_0"
12956 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
12957 (match_operand 1 "" ""))]
12958 ""
12959 {
12960 if (SIBLING_CALL_P (insn))
12961 return "jmp\t%P0";
12962 else
12963 return "call\t%P0";
12964 }
12965 [(set_attr "type" "call")])
12966
12967 (define_insn "*call_1"
12968 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
12969 (match_operand 1 "" ""))]
12970 "!TARGET_64BIT"
12971 {
12972 if (constant_call_address_operand (operands[0], QImode))
12973 {
12974 if (SIBLING_CALL_P (insn))
12975 return "jmp\t%P0";
12976 else
12977 return "call\t%P0";
12978 }
12979 if (SIBLING_CALL_P (insn))
12980 return "jmp\t%A0";
12981 else
12982 return "call\t%A0";
12983 }
12984 [(set_attr "type" "call")])
12985
12986 (define_insn "*call_1_rex64"
12987 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
12988 (match_operand 1 "" ""))]
12989 "TARGET_64BIT"
12990 {
12991 if (constant_call_address_operand (operands[0], QImode))
12992 {
12993 if (SIBLING_CALL_P (insn))
12994 return "jmp\t%P0";
12995 else
12996 return "call\t%P0";
12997 }
12998 if (SIBLING_CALL_P (insn))
12999 return "jmp\t%A0";
13000 else
13001 return "call\t%A0";
13002 }
13003 [(set_attr "type" "call")])
13004
13005 ;; Call subroutine, returning value in operand 0
13006
13007 (define_expand "call_value_pop"
13008 [(parallel [(set (match_operand 0 "" "")
13009 (call (match_operand:QI 1 "" "")
13010 (match_operand:SI 2 "" "")))
13011 (set (reg:SI 7)
13012 (plus:SI (reg:SI 7)
13013 (match_operand:SI 4 "" "")))])]
13014 "!TARGET_64BIT"
13015 {
13016 ix86_expand_call (operands[0], operands[1], operands[2],
13017 operands[3], operands[4]);
13018 DONE;
13019 })
13020
13021 (define_expand "call_value"
13022 [(set (match_operand 0 "" "")
13023 (call (match_operand:QI 1 "" "")
13024 (match_operand:SI 2 "" "")))
13025 (use (match_operand:SI 3 "" ""))]
13026 ;; Operand 2 not used on the i386.
13027 ""
13028 {
13029 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL);
13030 DONE;
13031 })
13032
13033 ;; Call subroutine returning any type.
13034
13035 (define_expand "untyped_call"
13036 [(parallel [(call (match_operand 0 "" "")
13037 (const_int 0))
13038 (match_operand 1 "" "")
13039 (match_operand 2 "" "")])]
13040 ""
13041 {
13042 int i;
13043
13044 /* In order to give reg-stack an easier job in validating two
13045 coprocessor registers as containing a possible return value,
13046 simply pretend the untyped call returns a complex long double
13047 value. */
13048
13049 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13050 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13051 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13052 NULL);
13053
13054 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13055 {
13056 rtx set = XVECEXP (operands[2], 0, i);
13057 emit_move_insn (SET_DEST (set), SET_SRC (set));
13058 }
13059
13060 /* The optimizer does not know that the call sets the function value
13061 registers we stored in the result block. We avoid problems by
13062 claiming that all hard registers are used and clobbered at this
13063 point. */
13064 emit_insn (gen_blockage ());
13065
13066 DONE;
13067 })
13068 \f
13069 ;; Prologue and epilogue instructions
13070
13071 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13072 ;; all of memory. This blocks insns from being moved across this point.
13073
13074 (define_insn "blockage"
13075 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13076 ""
13077 ""
13078 [(set_attr "length" "0")])
13079
13080 ;; Insn emitted into the body of a function to return from a function.
13081 ;; This is only done if the function's epilogue is known to be simple.
13082 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13083
13084 (define_expand "return"
13085 [(return)]
13086 "ix86_can_use_return_insn_p ()"
13087 {
13088 if (current_function_pops_args)
13089 {
13090 rtx popc = GEN_INT (current_function_pops_args);
13091 emit_jump_insn (gen_return_pop_internal (popc));
13092 DONE;
13093 }
13094 })
13095
13096 (define_insn "return_internal"
13097 [(return)]
13098 "reload_completed"
13099 "ret"
13100 [(set_attr "length" "1")
13101 (set_attr "length_immediate" "0")
13102 (set_attr "modrm" "0")])
13103
13104 (define_insn "return_pop_internal"
13105 [(return)
13106 (use (match_operand:SI 0 "const_int_operand" ""))]
13107 "reload_completed"
13108 "ret\t%0"
13109 [(set_attr "length" "3")
13110 (set_attr "length_immediate" "2")
13111 (set_attr "modrm" "0")])
13112
13113 (define_insn "return_indirect_internal"
13114 [(return)
13115 (use (match_operand:SI 0 "register_operand" "r"))]
13116 "reload_completed"
13117 "jmp\t%A0"
13118 [(set_attr "type" "ibr")
13119 (set_attr "length_immediate" "0")])
13120
13121 (define_insn "nop"
13122 [(const_int 0)]
13123 ""
13124 "nop"
13125 [(set_attr "length" "1")
13126 (set_attr "length_immediate" "0")
13127 (set_attr "modrm" "0")
13128 (set_attr "ppro_uops" "one")])
13129
13130 (define_expand "prologue"
13131 [(const_int 1)]
13132 ""
13133 "ix86_expand_prologue (); DONE;")
13134
13135 (define_expand "set_got"
13136 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13137 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13138 (clobber (reg:CC 17))])]
13139 "!TARGET_64BIT"
13140 "")
13141
13142 (define_insn "*set_got_nopic"
13143 [(set (match_operand:SI 0 "register_operand" "=r")
13144 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13145 (clobber (reg:CC 17))]
13146 "!TARGET_64BIT && !flag_pic"
13147 { return output_set_got (operands[0]); }
13148 [(set_attr "type" "multi")
13149 (set_attr "length" "11")])
13150
13151 (define_insn "*set_got_deep"
13152 [(set (match_operand:SI 0 "register_operand" "=b")
13153 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13154 (clobber (reg:CC 17))]
13155 "!TARGET_64BIT && TARGET_DEEP_BRANCH_PREDICTION"
13156 { return output_set_got (operands[0]); }
13157 [(set_attr "type" "multi")
13158 (set_attr "length" "11")])
13159
13160 (define_insn "*set_got_nodeep"
13161 [(set (match_operand:SI 0 "register_operand" "=r")
13162 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13163 (clobber (reg:CC 17))]
13164 "!TARGET_64BIT"
13165 { return output_set_got (operands[0]); }
13166 [(set_attr "type" "multi")
13167 (set_attr "length" "12")])
13168
13169 (define_expand "epilogue"
13170 [(const_int 1)]
13171 ""
13172 "ix86_expand_epilogue (1); DONE;")
13173
13174 (define_expand "sibcall_epilogue"
13175 [(const_int 1)]
13176 ""
13177 "ix86_expand_epilogue (0); DONE;")
13178
13179 (define_expand "eh_return"
13180 [(use (match_operand 0 "register_operand" ""))
13181 (use (match_operand 1 "register_operand" ""))]
13182 ""
13183 {
13184 rtx tmp, sa = operands[0], ra = operands[1];
13185
13186 /* Tricky bit: we write the address of the handler to which we will
13187 be returning into someone else's stack frame, one word below the
13188 stack address we wish to restore. */
13189 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13190 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13191 tmp = gen_rtx_MEM (Pmode, tmp);
13192 emit_move_insn (tmp, ra);
13193
13194 if (Pmode == SImode)
13195 emit_insn (gen_eh_return_si (sa));
13196 else
13197 emit_insn (gen_eh_return_di (sa));
13198 emit_barrier ();
13199 DONE;
13200 })
13201
13202 (define_insn_and_split "eh_return_si"
13203 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13204 UNSPECV_EH_RETURN)]
13205 "!TARGET_64BIT"
13206 "#"
13207 "reload_completed"
13208 [(const_int 1)]
13209 "ix86_expand_epilogue (2); DONE;")
13210
13211 (define_insn_and_split "eh_return_di"
13212 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13213 UNSPECV_EH_RETURN)]
13214 "TARGET_64BIT"
13215 "#"
13216 "reload_completed"
13217 [(const_int 1)]
13218 "ix86_expand_epilogue (2); DONE;")
13219
13220 (define_insn "leave"
13221 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13222 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13223 (clobber (mem:BLK (scratch)))]
13224 "!TARGET_64BIT"
13225 "leave"
13226 [(set_attr "length_immediate" "0")
13227 (set_attr "length" "1")
13228 (set_attr "modrm" "0")
13229 (set_attr "modrm" "0")
13230 (set_attr "athlon_decode" "vector")
13231 (set_attr "ppro_uops" "few")])
13232
13233 (define_insn "leave_rex64"
13234 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13235 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13236 (clobber (mem:BLK (scratch)))]
13237 "TARGET_64BIT"
13238 "leave"
13239 [(set_attr "length_immediate" "0")
13240 (set_attr "length" "1")
13241 (set_attr "modrm" "0")
13242 (set_attr "modrm" "0")
13243 (set_attr "athlon_decode" "vector")
13244 (set_attr "ppro_uops" "few")])
13245 \f
13246 (define_expand "ffssi2"
13247 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13248 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13249 ""
13250 {
13251 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13252 rtx in = operands[1];
13253
13254 if (TARGET_CMOVE)
13255 {
13256 emit_move_insn (tmp, constm1_rtx);
13257 emit_insn (gen_ffssi_1 (out, in));
13258 emit_insn (gen_rtx_SET (VOIDmode, out,
13259 gen_rtx_IF_THEN_ELSE (SImode,
13260 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13261 const0_rtx),
13262 tmp,
13263 out)));
13264 emit_insn (gen_addsi3 (out, out, const1_rtx));
13265 emit_move_insn (operands[0], out);
13266 }
13267
13268 /* Pentium bsf instruction is extremly slow. The following code is
13269 recommended by the Intel Optimizing Manual as a reasonable replacement:
13270 TEST EAX,EAX
13271 JZ SHORT BS2
13272 XOR ECX,ECX
13273 MOV DWORD PTR [TEMP+4],ECX
13274 SUB ECX,EAX
13275 AND EAX,ECX
13276 MOV DWORD PTR [TEMP],EAX
13277 FILD QWORD PTR [TEMP]
13278 FSTP QWORD PTR [TEMP]
13279 WAIT ; WAIT only needed for compatibility with
13280 ; earlier processors
13281 MOV ECX, DWORD PTR [TEMP+4]
13282 SHR ECX,20
13283 SUB ECX,3FFH
13284 TEST EAX,EAX ; clear zero flag
13285 BS2:
13286 Following piece of code expand ffs to similar beast.
13287 */
13288
13289 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13290 {
13291 rtx label = gen_label_rtx ();
13292 rtx lo, hi;
13293 rtx mem = assign_386_stack_local (DImode, 0);
13294 rtx fptmp = gen_reg_rtx (DFmode);
13295 split_di (&mem, 1, &lo, &hi);
13296
13297 emit_move_insn (out, const0_rtx);
13298
13299 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
13300
13301 emit_move_insn (hi, out);
13302 emit_insn (gen_subsi3 (out, out, in));
13303 emit_insn (gen_andsi3 (out, out, in));
13304 emit_move_insn (lo, out);
13305 emit_insn (gen_floatdidf2 (fptmp,mem));
13306 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13307 emit_move_insn (out, hi);
13308 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
13309 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
13310
13311 emit_label (label);
13312 LABEL_NUSES (label) = 1;
13313
13314 emit_move_insn (operands[0], out);
13315 }
13316 else
13317 {
13318 emit_move_insn (tmp, const0_rtx);
13319 emit_insn (gen_ffssi_1 (out, in));
13320 emit_insn (gen_rtx_SET (VOIDmode,
13321 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
13322 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
13323 const0_rtx)));
13324 emit_insn (gen_negsi2 (tmp, tmp));
13325 emit_insn (gen_iorsi3 (out, out, tmp));
13326 emit_insn (gen_addsi3 (out, out, const1_rtx));
13327 emit_move_insn (operands[0], out);
13328 }
13329 DONE;
13330 })
13331
13332 (define_insn "ffssi_1"
13333 [(set (reg:CCZ 17)
13334 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13335 (const_int 0)))
13336 (set (match_operand:SI 0 "register_operand" "=r")
13337 (unspec:SI [(match_dup 1)] UNSPEC_BSF))]
13338 ""
13339 "bsf{l}\t{%1, %0|%0, %1}"
13340 [(set_attr "prefix_0f" "1")
13341 (set_attr "ppro_uops" "few")])
13342
13343 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13344 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
13345 \f
13346 ;; Thread-local storage patterns for ELF.
13347 ;;
13348 ;; Note that these code sequences must appear exactly as shown
13349 ;; in order to allow linker relaxation.
13350
13351 (define_insn "*tls_global_dynamic_gnu"
13352 [(set (match_operand:SI 0 "register_operand" "=a")
13353 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13354 (match_operand:SI 2 "tls_symbolic_operand" "")
13355 (match_operand:SI 3 "call_insn_operand" "")]
13356 UNSPEC_TLS_GD))
13357 (clobber (match_scratch:SI 4 "=d"))
13358 (clobber (match_scratch:SI 5 "=c"))
13359 (clobber (reg:CC 17))]
13360 "TARGET_GNU_TLS"
13361 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13362 [(set_attr "type" "multi")
13363 (set_attr "length" "12")])
13364
13365 (define_insn "*tls_global_dynamic_sun"
13366 [(set (match_operand:SI 0 "register_operand" "=a")
13367 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13368 (match_operand:SI 2 "tls_symbolic_operand" "")
13369 (match_operand:SI 3 "call_insn_operand" "")]
13370 UNSPEC_TLS_GD))
13371 (clobber (match_scratch:SI 4 "=d"))
13372 (clobber (match_scratch:SI 5 "=c"))
13373 (clobber (reg:CC 17))]
13374 "TARGET_SUN_TLS"
13375 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13376 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13377 [(set_attr "type" "multi")
13378 (set_attr "length" "14")])
13379
13380 (define_expand "tls_global_dynamic"
13381 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13382 (unspec:SI
13383 [(match_dup 2)
13384 (match_operand:SI 1 "tls_symbolic_operand" "")
13385 (match_dup 3)]
13386 UNSPEC_TLS_GD))
13387 (clobber (match_scratch:SI 4 ""))
13388 (clobber (match_scratch:SI 5 ""))
13389 (clobber (reg:CC 17))])]
13390 ""
13391 {
13392 if (!flag_pic)
13393 abort ();
13394 current_function_uses_pic_offset_table = 1;
13395 operands[2] = pic_offset_table_rtx;
13396 operands[3] = ix86_tls_get_addr ();
13397 })
13398
13399 (define_insn "*tls_local_dynamic_base_gnu"
13400 [(set (match_operand:SI 0 "register_operand" "=a")
13401 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13402 (match_operand:SI 2 "call_insn_operand" "")]
13403 UNSPEC_TLS_LD_BASE))
13404 (clobber (match_scratch:SI 3 "=d"))
13405 (clobber (match_scratch:SI 4 "=c"))
13406 (clobber (reg:CC 17))]
13407 "TARGET_GNU_TLS"
13408 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13409 [(set_attr "type" "multi")
13410 (set_attr "length" "11")])
13411
13412 (define_insn "*tls_local_dynamic_base_sun"
13413 [(set (match_operand:SI 0 "register_operand" "=a")
13414 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13415 (match_operand:SI 2 "call_insn_operand" "")]
13416 UNSPEC_TLS_LD_BASE))
13417 (clobber (match_scratch:SI 3 "=d"))
13418 (clobber (match_scratch:SI 4 "=c"))
13419 (clobber (reg:CC 17))]
13420 "TARGET_SUN_TLS"
13421 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13422 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13423 [(set_attr "type" "multi")
13424 (set_attr "length" "13")])
13425
13426 (define_expand "tls_local_dynamic_base"
13427 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13428 (unspec:SI [(match_dup 1) (match_dup 2)]
13429 UNSPEC_TLS_LD_BASE))
13430 (clobber (match_scratch:SI 3 ""))
13431 (clobber (match_scratch:SI 4 ""))
13432 (clobber (reg:CC 17))])]
13433 ""
13434 {
13435 if (!flag_pic)
13436 abort ();
13437 current_function_uses_pic_offset_table = 1;
13438 operands[1] = pic_offset_table_rtx;
13439 operands[2] = ix86_tls_get_addr ();
13440 })
13441
13442 ;; Local dynamic of a single variable is a lose. Show combine how
13443 ;; to convert that back to global dynamic.
13444
13445 (define_insn_and_split "*tls_local_dynamic_once"
13446 [(set (match_operand:SI 0 "register_operand" "=a")
13447 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13448 (match_operand:SI 2 "call_insn_operand" "")]
13449 UNSPEC_TLS_LD_BASE)
13450 (const:SI (unspec:SI
13451 [(match_operand:SI 3 "tls_symbolic_operand" "")]
13452 UNSPEC_DTPOFF))))
13453 (clobber (match_scratch:SI 4 "=d"))
13454 (clobber (match_scratch:SI 5 "=c"))
13455 (clobber (reg:CC 17))]
13456 ""
13457 "#"
13458 ""
13459 [(parallel [(set (match_dup 0)
13460 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13461 UNSPEC_TLS_GD))
13462 (clobber (match_dup 4))
13463 (clobber (match_dup 5))
13464 (clobber (reg:CC 17))])]
13465 "")
13466 \f
13467 ;; These patterns match the binary 387 instructions for addM3, subM3,
13468 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13469 ;; SFmode. The first is the normal insn, the second the same insn but
13470 ;; with one operand a conversion, and the third the same insn but with
13471 ;; the other operand a conversion. The conversion may be SFmode or
13472 ;; SImode if the target mode DFmode, but only SImode if the target mode
13473 ;; is SFmode.
13474
13475 ;; Gcc is slightly more smart about handling normal two address instructions
13476 ;; so use special patterns for add and mull.
13477 (define_insn "*fop_sf_comm_nosse"
13478 [(set (match_operand:SF 0 "register_operand" "=f")
13479 (match_operator:SF 3 "binary_fp_operator"
13480 [(match_operand:SF 1 "nonimmediate_operand" "%0")
13481 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13482 "TARGET_80387 && !TARGET_SSE_MATH
13483 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13484 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13485 "* return output_387_binary_op (insn, operands);"
13486 [(set (attr "type")
13487 (if_then_else (match_operand:SF 3 "mult_operator" "")
13488 (const_string "fmul")
13489 (const_string "fop")))
13490 (set_attr "mode" "SF")])
13491
13492 (define_insn "*fop_sf_comm"
13493 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13494 (match_operator:SF 3 "binary_fp_operator"
13495 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13496 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13497 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13498 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13499 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13500 "* return output_387_binary_op (insn, operands);"
13501 [(set (attr "type")
13502 (if_then_else (eq_attr "alternative" "1")
13503 (if_then_else (match_operand:SF 3 "mult_operator" "")
13504 (const_string "ssemul")
13505 (const_string "sseadd"))
13506 (if_then_else (match_operand:SF 3 "mult_operator" "")
13507 (const_string "fmul")
13508 (const_string "fop"))))
13509 (set_attr "mode" "SF")])
13510
13511 (define_insn "*fop_sf_comm_sse"
13512 [(set (match_operand:SF 0 "register_operand" "=x")
13513 (match_operator:SF 3 "binary_fp_operator"
13514 [(match_operand:SF 1 "nonimmediate_operand" "%0")
13515 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13516 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13517 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13518 "* return output_387_binary_op (insn, operands);"
13519 [(set (attr "type")
13520 (if_then_else (match_operand:SF 3 "mult_operator" "")
13521 (const_string "ssemul")
13522 (const_string "sseadd")))
13523 (set_attr "mode" "SF")])
13524
13525 (define_insn "*fop_df_comm_nosse"
13526 [(set (match_operand:DF 0 "register_operand" "=f")
13527 (match_operator:DF 3 "binary_fp_operator"
13528 [(match_operand:DF 1 "nonimmediate_operand" "%0")
13529 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
13530 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
13531 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13532 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13533 "* return output_387_binary_op (insn, operands);"
13534 [(set (attr "type")
13535 (if_then_else (match_operand:SF 3 "mult_operator" "")
13536 (const_string "fmul")
13537 (const_string "fop")))
13538 (set_attr "mode" "DF")])
13539
13540 (define_insn "*fop_df_comm"
13541 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
13542 (match_operator:DF 3 "binary_fp_operator"
13543 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
13544 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
13545 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
13546 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13547 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13548 "* return output_387_binary_op (insn, operands);"
13549 [(set (attr "type")
13550 (if_then_else (eq_attr "alternative" "1")
13551 (if_then_else (match_operand:SF 3 "mult_operator" "")
13552 (const_string "ssemul")
13553 (const_string "sseadd"))
13554 (if_then_else (match_operand:SF 3 "mult_operator" "")
13555 (const_string "fmul")
13556 (const_string "fop"))))
13557 (set_attr "mode" "DF")])
13558
13559 (define_insn "*fop_df_comm_sse"
13560 [(set (match_operand:DF 0 "register_operand" "=Y")
13561 (match_operator:DF 3 "binary_fp_operator"
13562 [(match_operand:DF 1 "nonimmediate_operand" "%0")
13563 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13564 "TARGET_SSE2 && TARGET_SSE_MATH
13565 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
13566 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13567 "* return output_387_binary_op (insn, operands);"
13568 [(set (attr "type")
13569 (if_then_else (match_operand:SF 3 "mult_operator" "")
13570 (const_string "ssemul")
13571 (const_string "sseadd")))
13572 (set_attr "mode" "DF")])
13573
13574 (define_insn "*fop_xf_comm"
13575 [(set (match_operand:XF 0 "register_operand" "=f")
13576 (match_operator:XF 3 "binary_fp_operator"
13577 [(match_operand:XF 1 "register_operand" "%0")
13578 (match_operand:XF 2 "register_operand" "f")]))]
13579 "!TARGET_64BIT && TARGET_80387
13580 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13581 "* return output_387_binary_op (insn, operands);"
13582 [(set (attr "type")
13583 (if_then_else (match_operand:XF 3 "mult_operator" "")
13584 (const_string "fmul")
13585 (const_string "fop")))
13586 (set_attr "mode" "XF")])
13587
13588 (define_insn "*fop_tf_comm"
13589 [(set (match_operand:TF 0 "register_operand" "=f")
13590 (match_operator:TF 3 "binary_fp_operator"
13591 [(match_operand:TF 1 "register_operand" "%0")
13592 (match_operand:TF 2 "register_operand" "f")]))]
13593 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13594 "* return output_387_binary_op (insn, operands);"
13595 [(set (attr "type")
13596 (if_then_else (match_operand:TF 3 "mult_operator" "")
13597 (const_string "fmul")
13598 (const_string "fop")))
13599 (set_attr "mode" "XF")])
13600
13601 (define_insn "*fop_sf_1_nosse"
13602 [(set (match_operand:SF 0 "register_operand" "=f,f")
13603 (match_operator:SF 3 "binary_fp_operator"
13604 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
13605 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
13606 "TARGET_80387 && !TARGET_SSE_MATH
13607 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13608 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13609 "* return output_387_binary_op (insn, operands);"
13610 [(set (attr "type")
13611 (cond [(match_operand:SF 3 "mult_operator" "")
13612 (const_string "fmul")
13613 (match_operand:SF 3 "div_operator" "")
13614 (const_string "fdiv")
13615 ]
13616 (const_string "fop")))
13617 (set_attr "mode" "SF")])
13618
13619 (define_insn "*fop_sf_1"
13620 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13621 (match_operator:SF 3 "binary_fp_operator"
13622 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13623 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13624 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13625 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13626 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13627 "* return output_387_binary_op (insn, operands);"
13628 [(set (attr "type")
13629 (cond [(and (eq_attr "alternative" "2")
13630 (match_operand:SF 3 "mult_operator" ""))
13631 (const_string "ssemul")
13632 (and (eq_attr "alternative" "2")
13633 (match_operand:SF 3 "div_operator" ""))
13634 (const_string "ssediv")
13635 (eq_attr "alternative" "2")
13636 (const_string "sseadd")
13637 (match_operand:SF 3 "mult_operator" "")
13638 (const_string "fmul")
13639 (match_operand:SF 3 "div_operator" "")
13640 (const_string "fdiv")
13641 ]
13642 (const_string "fop")))
13643 (set_attr "mode" "SF")])
13644
13645 (define_insn "*fop_sf_1_sse"
13646 [(set (match_operand:SF 0 "register_operand" "=x")
13647 (match_operator:SF 3 "binary_fp_operator"
13648 [(match_operand:SF 1 "register_operand" "0")
13649 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13650 "TARGET_SSE_MATH
13651 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13652 "* return output_387_binary_op (insn, operands);"
13653 [(set (attr "type")
13654 (cond [(match_operand:SF 3 "mult_operator" "")
13655 (const_string "ssemul")
13656 (match_operand:SF 3 "div_operator" "")
13657 (const_string "ssediv")
13658 ]
13659 (const_string "sseadd")))
13660 (set_attr "mode" "SF")])
13661
13662 ;; ??? Add SSE splitters for these!
13663 (define_insn "*fop_sf_2"
13664 [(set (match_operand:SF 0 "register_operand" "=f,f")
13665 (match_operator:SF 3 "binary_fp_operator"
13666 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13667 (match_operand:SF 2 "register_operand" "0,0")]))]
13668 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
13669 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13670 [(set (attr "type")
13671 (cond [(match_operand:SF 3 "mult_operator" "")
13672 (const_string "fmul")
13673 (match_operand:SF 3 "div_operator" "")
13674 (const_string "fdiv")
13675 ]
13676 (const_string "fop")))
13677 (set_attr "fp_int_src" "true")
13678 (set_attr "ppro_uops" "many")
13679 (set_attr "mode" "SI")])
13680
13681 (define_insn "*fop_sf_3"
13682 [(set (match_operand:SF 0 "register_operand" "=f,f")
13683 (match_operator:SF 3 "binary_fp_operator"
13684 [(match_operand:SF 1 "register_operand" "0,0")
13685 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13686 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
13687 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13688 [(set (attr "type")
13689 (cond [(match_operand:SF 3 "mult_operator" "")
13690 (const_string "fmul")
13691 (match_operand:SF 3 "div_operator" "")
13692 (const_string "fdiv")
13693 ]
13694 (const_string "fop")))
13695 (set_attr "fp_int_src" "true")
13696 (set_attr "ppro_uops" "many")
13697 (set_attr "mode" "SI")])
13698
13699 (define_insn "*fop_df_1_nosse"
13700 [(set (match_operand:DF 0 "register_operand" "=f,f")
13701 (match_operator:DF 3 "binary_fp_operator"
13702 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
13703 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
13704 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
13705 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13706 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13707 "* return output_387_binary_op (insn, operands);"
13708 [(set (attr "type")
13709 (cond [(match_operand:DF 3 "mult_operator" "")
13710 (const_string "fmul")
13711 (match_operand:DF 3 "div_operator" "")
13712 (const_string "fdiv")
13713 ]
13714 (const_string "fop")))
13715 (set_attr "mode" "DF")])
13716
13717
13718 (define_insn "*fop_df_1"
13719 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
13720 (match_operator:DF 3 "binary_fp_operator"
13721 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
13722 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
13723 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13724 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13725 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13726 "* return output_387_binary_op (insn, operands);"
13727 [(set (attr "type")
13728 (cond [(and (eq_attr "alternative" "2")
13729 (match_operand:SF 3 "mult_operator" ""))
13730 (const_string "ssemul")
13731 (and (eq_attr "alternative" "2")
13732 (match_operand:SF 3 "div_operator" ""))
13733 (const_string "ssediv")
13734 (eq_attr "alternative" "2")
13735 (const_string "sseadd")
13736 (match_operand:DF 3 "mult_operator" "")
13737 (const_string "fmul")
13738 (match_operand:DF 3 "div_operator" "")
13739 (const_string "fdiv")
13740 ]
13741 (const_string "fop")))
13742 (set_attr "mode" "DF")])
13743
13744 (define_insn "*fop_df_1_sse"
13745 [(set (match_operand:DF 0 "register_operand" "=Y")
13746 (match_operator:DF 3 "binary_fp_operator"
13747 [(match_operand:DF 1 "register_operand" "0")
13748 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13749 "TARGET_SSE2 && TARGET_SSE_MATH
13750 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13751 "* return output_387_binary_op (insn, operands);"
13752 [(set_attr "mode" "DF")
13753 (set (attr "type")
13754 (cond [(match_operand:SF 3 "mult_operator" "")
13755 (const_string "ssemul")
13756 (match_operand:SF 3 "div_operator" "")
13757 (const_string "ssediv")
13758 ]
13759 (const_string "sseadd")))])
13760
13761 ;; ??? Add SSE splitters for these!
13762 (define_insn "*fop_df_2"
13763 [(set (match_operand:DF 0 "register_operand" "=f,f")
13764 (match_operator:DF 3 "binary_fp_operator"
13765 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13766 (match_operand:DF 2 "register_operand" "0,0")]))]
13767 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13768 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13769 [(set (attr "type")
13770 (cond [(match_operand:DF 3 "mult_operator" "")
13771 (const_string "fmul")
13772 (match_operand:DF 3 "div_operator" "")
13773 (const_string "fdiv")
13774 ]
13775 (const_string "fop")))
13776 (set_attr "fp_int_src" "true")
13777 (set_attr "ppro_uops" "many")
13778 (set_attr "mode" "SI")])
13779
13780 (define_insn "*fop_df_3"
13781 [(set (match_operand:DF 0 "register_operand" "=f,f")
13782 (match_operator:DF 3 "binary_fp_operator"
13783 [(match_operand:DF 1 "register_operand" "0,0")
13784 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13785 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13786 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13787 [(set (attr "type")
13788 (cond [(match_operand:DF 3 "mult_operator" "")
13789 (const_string "fmul")
13790 (match_operand:DF 3 "div_operator" "")
13791 (const_string "fdiv")
13792 ]
13793 (const_string "fop")))
13794 (set_attr "fp_int_src" "true")
13795 (set_attr "ppro_uops" "many")
13796 (set_attr "mode" "SI")])
13797
13798 (define_insn "*fop_df_4"
13799 [(set (match_operand:DF 0 "register_operand" "=f,f")
13800 (match_operator:DF 3 "binary_fp_operator"
13801 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13802 (match_operand:DF 2 "register_operand" "0,f")]))]
13803 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
13804 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13805 "* return output_387_binary_op (insn, operands);"
13806 [(set (attr "type")
13807 (cond [(match_operand:DF 3 "mult_operator" "")
13808 (const_string "fmul")
13809 (match_operand:DF 3 "div_operator" "")
13810 (const_string "fdiv")
13811 ]
13812 (const_string "fop")))
13813 (set_attr "mode" "SF")])
13814
13815 (define_insn "*fop_df_5"
13816 [(set (match_operand:DF 0 "register_operand" "=f,f")
13817 (match_operator:DF 3 "binary_fp_operator"
13818 [(match_operand:DF 1 "register_operand" "0,f")
13819 (float_extend:DF
13820 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13821 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13822 "* return output_387_binary_op (insn, operands);"
13823 [(set (attr "type")
13824 (cond [(match_operand:DF 3 "mult_operator" "")
13825 (const_string "fmul")
13826 (match_operand:DF 3 "div_operator" "")
13827 (const_string "fdiv")
13828 ]
13829 (const_string "fop")))
13830 (set_attr "mode" "SF")])
13831
13832 (define_insn "*fop_xf_1"
13833 [(set (match_operand:XF 0 "register_operand" "=f,f")
13834 (match_operator:XF 3 "binary_fp_operator"
13835 [(match_operand:XF 1 "register_operand" "0,f")
13836 (match_operand:XF 2 "register_operand" "f,0")]))]
13837 "!TARGET_64BIT && TARGET_80387
13838 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13839 "* return output_387_binary_op (insn, operands);"
13840 [(set (attr "type")
13841 (cond [(match_operand:XF 3 "mult_operator" "")
13842 (const_string "fmul")
13843 (match_operand:XF 3 "div_operator" "")
13844 (const_string "fdiv")
13845 ]
13846 (const_string "fop")))
13847 (set_attr "mode" "XF")])
13848
13849 (define_insn "*fop_tf_1"
13850 [(set (match_operand:TF 0 "register_operand" "=f,f")
13851 (match_operator:TF 3 "binary_fp_operator"
13852 [(match_operand:TF 1 "register_operand" "0,f")
13853 (match_operand:TF 2 "register_operand" "f,0")]))]
13854 "TARGET_80387
13855 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13856 "* return output_387_binary_op (insn, operands);"
13857 [(set (attr "type")
13858 (cond [(match_operand:TF 3 "mult_operator" "")
13859 (const_string "fmul")
13860 (match_operand:TF 3 "div_operator" "")
13861 (const_string "fdiv")
13862 ]
13863 (const_string "fop")))
13864 (set_attr "mode" "XF")])
13865
13866 (define_insn "*fop_xf_2"
13867 [(set (match_operand:XF 0 "register_operand" "=f,f")
13868 (match_operator:XF 3 "binary_fp_operator"
13869 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13870 (match_operand:XF 2 "register_operand" "0,0")]))]
13871 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
13872 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13873 [(set (attr "type")
13874 (cond [(match_operand:XF 3 "mult_operator" "")
13875 (const_string "fmul")
13876 (match_operand:XF 3 "div_operator" "")
13877 (const_string "fdiv")
13878 ]
13879 (const_string "fop")))
13880 (set_attr "fp_int_src" "true")
13881 (set_attr "mode" "SI")
13882 (set_attr "ppro_uops" "many")])
13883
13884 (define_insn "*fop_tf_2"
13885 [(set (match_operand:TF 0 "register_operand" "=f,f")
13886 (match_operator:TF 3 "binary_fp_operator"
13887 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13888 (match_operand:TF 2 "register_operand" "0,0")]))]
13889 "TARGET_80387 && TARGET_USE_FIOP"
13890 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13891 [(set (attr "type")
13892 (cond [(match_operand:TF 3 "mult_operator" "")
13893 (const_string "fmul")
13894 (match_operand:TF 3 "div_operator" "")
13895 (const_string "fdiv")
13896 ]
13897 (const_string "fop")))
13898 (set_attr "fp_int_src" "true")
13899 (set_attr "mode" "SI")
13900 (set_attr "ppro_uops" "many")])
13901
13902 (define_insn "*fop_xf_3"
13903 [(set (match_operand:XF 0 "register_operand" "=f,f")
13904 (match_operator:XF 3 "binary_fp_operator"
13905 [(match_operand:XF 1 "register_operand" "0,0")
13906 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13907 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
13908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13909 [(set (attr "type")
13910 (cond [(match_operand:XF 3 "mult_operator" "")
13911 (const_string "fmul")
13912 (match_operand:XF 3 "div_operator" "")
13913 (const_string "fdiv")
13914 ]
13915 (const_string "fop")))
13916 (set_attr "fp_int_src" "true")
13917 (set_attr "mode" "SI")
13918 (set_attr "ppro_uops" "many")])
13919
13920 (define_insn "*fop_tf_3"
13921 [(set (match_operand:TF 0 "register_operand" "=f,f")
13922 (match_operator:TF 3 "binary_fp_operator"
13923 [(match_operand:TF 1 "register_operand" "0,0")
13924 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13925 "TARGET_80387 && TARGET_USE_FIOP"
13926 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13927 [(set (attr "type")
13928 (cond [(match_operand:TF 3 "mult_operator" "")
13929 (const_string "fmul")
13930 (match_operand:TF 3 "div_operator" "")
13931 (const_string "fdiv")
13932 ]
13933 (const_string "fop")))
13934 (set_attr "fp_int_src" "true")
13935 (set_attr "mode" "SI")
13936 (set_attr "ppro_uops" "many")])
13937
13938 (define_insn "*fop_xf_4"
13939 [(set (match_operand:XF 0 "register_operand" "=f,f")
13940 (match_operator:XF 3 "binary_fp_operator"
13941 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13942 (match_operand:XF 2 "register_operand" "0,f")]))]
13943 "!TARGET_64BIT && TARGET_80387"
13944 "* return output_387_binary_op (insn, operands);"
13945 [(set (attr "type")
13946 (cond [(match_operand:XF 3 "mult_operator" "")
13947 (const_string "fmul")
13948 (match_operand:XF 3 "div_operator" "")
13949 (const_string "fdiv")
13950 ]
13951 (const_string "fop")))
13952 (set_attr "mode" "SF")])
13953
13954 (define_insn "*fop_tf_4"
13955 [(set (match_operand:TF 0 "register_operand" "=f,f")
13956 (match_operator:TF 3 "binary_fp_operator"
13957 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13958 (match_operand:TF 2 "register_operand" "0,f")]))]
13959 "TARGET_80387"
13960 "* return output_387_binary_op (insn, operands);"
13961 [(set (attr "type")
13962 (cond [(match_operand:TF 3 "mult_operator" "")
13963 (const_string "fmul")
13964 (match_operand:TF 3 "div_operator" "")
13965 (const_string "fdiv")
13966 ]
13967 (const_string "fop")))
13968 (set_attr "mode" "SF")])
13969
13970 (define_insn "*fop_xf_5"
13971 [(set (match_operand:XF 0 "register_operand" "=f,f")
13972 (match_operator:XF 3 "binary_fp_operator"
13973 [(match_operand:XF 1 "register_operand" "0,f")
13974 (float_extend:XF
13975 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13976 "!TARGET_64BIT && TARGET_80387"
13977 "* return output_387_binary_op (insn, operands);"
13978 [(set (attr "type")
13979 (cond [(match_operand:XF 3 "mult_operator" "")
13980 (const_string "fmul")
13981 (match_operand:XF 3 "div_operator" "")
13982 (const_string "fdiv")
13983 ]
13984 (const_string "fop")))
13985 (set_attr "mode" "SF")])
13986
13987 (define_insn "*fop_tf_5"
13988 [(set (match_operand:TF 0 "register_operand" "=f,f")
13989 (match_operator:TF 3 "binary_fp_operator"
13990 [(match_operand:TF 1 "register_operand" "0,f")
13991 (float_extend:TF
13992 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13993 "TARGET_80387"
13994 "* return output_387_binary_op (insn, operands);"
13995 [(set (attr "type")
13996 (cond [(match_operand:TF 3 "mult_operator" "")
13997 (const_string "fmul")
13998 (match_operand:TF 3 "div_operator" "")
13999 (const_string "fdiv")
14000 ]
14001 (const_string "fop")))
14002 (set_attr "mode" "SF")])
14003
14004 (define_insn "*fop_xf_6"
14005 [(set (match_operand:XF 0 "register_operand" "=f,f")
14006 (match_operator:XF 3 "binary_fp_operator"
14007 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14008 (match_operand:XF 2 "register_operand" "0,f")]))]
14009 "!TARGET_64BIT && TARGET_80387"
14010 "* return output_387_binary_op (insn, operands);"
14011 [(set (attr "type")
14012 (cond [(match_operand:XF 3 "mult_operator" "")
14013 (const_string "fmul")
14014 (match_operand:XF 3 "div_operator" "")
14015 (const_string "fdiv")
14016 ]
14017 (const_string "fop")))
14018 (set_attr "mode" "DF")])
14019
14020 (define_insn "*fop_tf_6"
14021 [(set (match_operand:TF 0 "register_operand" "=f,f")
14022 (match_operator:TF 3 "binary_fp_operator"
14023 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14024 (match_operand:TF 2 "register_operand" "0,f")]))]
14025 "TARGET_80387"
14026 "* return output_387_binary_op (insn, operands);"
14027 [(set (attr "type")
14028 (cond [(match_operand:TF 3 "mult_operator" "")
14029 (const_string "fmul")
14030 (match_operand:TF 3 "div_operator" "")
14031 (const_string "fdiv")
14032 ]
14033 (const_string "fop")))
14034 (set_attr "mode" "DF")])
14035
14036 (define_insn "*fop_xf_7"
14037 [(set (match_operand:XF 0 "register_operand" "=f,f")
14038 (match_operator:XF 3 "binary_fp_operator"
14039 [(match_operand:XF 1 "register_operand" "0,f")
14040 (float_extend:XF
14041 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14042 "!TARGET_64BIT && TARGET_80387"
14043 "* return output_387_binary_op (insn, operands);"
14044 [(set (attr "type")
14045 (cond [(match_operand:XF 3 "mult_operator" "")
14046 (const_string "fmul")
14047 (match_operand:XF 3 "div_operator" "")
14048 (const_string "fdiv")
14049 ]
14050 (const_string "fop")))
14051 (set_attr "mode" "DF")])
14052
14053 (define_insn "*fop_tf_7"
14054 [(set (match_operand:TF 0 "register_operand" "=f,f")
14055 (match_operator:TF 3 "binary_fp_operator"
14056 [(match_operand:TF 1 "register_operand" "0,f")
14057 (float_extend:TF
14058 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14059 "TARGET_80387"
14060 "* return output_387_binary_op (insn, operands);"
14061 [(set (attr "type")
14062 (cond [(match_operand:TF 3 "mult_operator" "")
14063 (const_string "fmul")
14064 (match_operand:TF 3 "div_operator" "")
14065 (const_string "fdiv")
14066 ]
14067 (const_string "fop")))
14068 (set_attr "mode" "DF")])
14069
14070 (define_split
14071 [(set (match_operand 0 "register_operand" "")
14072 (match_operator 3 "binary_fp_operator"
14073 [(float (match_operand:SI 1 "register_operand" ""))
14074 (match_operand 2 "register_operand" "")]))]
14075 "TARGET_80387 && reload_completed
14076 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14077 [(const_int 0)]
14078 {
14079 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14080 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14081 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14082 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14083 GET_MODE (operands[3]),
14084 operands[4],
14085 operands[2])));
14086 ix86_free_from_memory (GET_MODE (operands[1]));
14087 DONE;
14088 })
14089
14090 (define_split
14091 [(set (match_operand 0 "register_operand" "")
14092 (match_operator 3 "binary_fp_operator"
14093 [(match_operand 1 "register_operand" "")
14094 (float (match_operand:SI 2 "register_operand" ""))]))]
14095 "TARGET_80387 && reload_completed
14096 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14097 [(const_int 0)]
14098 {
14099 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14100 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14101 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14102 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14103 GET_MODE (operands[3]),
14104 operands[1],
14105 operands[4])));
14106 ix86_free_from_memory (GET_MODE (operands[2]));
14107 DONE;
14108 })
14109 \f
14110 ;; FPU special functions.
14111
14112 (define_expand "sqrtsf2"
14113 [(set (match_operand:SF 0 "register_operand" "")
14114 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14115 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14116 {
14117 if (!TARGET_SSE_MATH)
14118 operands[1] = force_reg (SFmode, operands[1]);
14119 })
14120
14121 (define_insn "sqrtsf2_1"
14122 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14123 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14124 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14125 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14126 "@
14127 fsqrt
14128 sqrtss\t{%1, %0|%0, %1}"
14129 [(set_attr "type" "fpspc,sse")
14130 (set_attr "mode" "SF,SF")
14131 (set_attr "athlon_decode" "direct,*")])
14132
14133 (define_insn "sqrtsf2_1_sse_only"
14134 [(set (match_operand:SF 0 "register_operand" "=x")
14135 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14136 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14137 "sqrtss\t{%1, %0|%0, %1}"
14138 [(set_attr "type" "sse")
14139 (set_attr "mode" "SF")
14140 (set_attr "athlon_decode" "*")])
14141
14142 (define_insn "sqrtsf2_i387"
14143 [(set (match_operand:SF 0 "register_operand" "=f")
14144 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14145 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14146 && !TARGET_SSE_MATH"
14147 "fsqrt"
14148 [(set_attr "type" "fpspc")
14149 (set_attr "mode" "SF")
14150 (set_attr "athlon_decode" "direct")])
14151
14152 (define_expand "sqrtdf2"
14153 [(set (match_operand:DF 0 "register_operand" "")
14154 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14155 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14156 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14157 {
14158 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14159 operands[1] = force_reg (DFmode, operands[1]);
14160 })
14161
14162 (define_insn "sqrtdf2_1"
14163 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14164 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14165 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14166 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14167 "@
14168 fsqrt
14169 sqrtsd\t{%1, %0|%0, %1}"
14170 [(set_attr "type" "fpspc,sse")
14171 (set_attr "mode" "DF,DF")
14172 (set_attr "athlon_decode" "direct,*")])
14173
14174 (define_insn "sqrtdf2_1_sse_only"
14175 [(set (match_operand:DF 0 "register_operand" "=Y")
14176 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14177 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14178 "sqrtsd\t{%1, %0|%0, %1}"
14179 [(set_attr "type" "sse")
14180 (set_attr "mode" "DF")
14181 (set_attr "athlon_decode" "*")])
14182
14183 (define_insn "sqrtdf2_i387"
14184 [(set (match_operand:DF 0 "register_operand" "=f")
14185 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14186 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14187 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14188 "fsqrt"
14189 [(set_attr "type" "fpspc")
14190 (set_attr "mode" "DF")
14191 (set_attr "athlon_decode" "direct")])
14192
14193 (define_insn "*sqrtextendsfdf2"
14194 [(set (match_operand:DF 0 "register_operand" "=f")
14195 (sqrt:DF (float_extend:DF
14196 (match_operand:SF 1 "register_operand" "0"))))]
14197 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14198 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14199 "fsqrt"
14200 [(set_attr "type" "fpspc")
14201 (set_attr "mode" "DF")
14202 (set_attr "athlon_decode" "direct")])
14203
14204 (define_insn "sqrtxf2"
14205 [(set (match_operand:XF 0 "register_operand" "=f")
14206 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14207 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14208 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14209 "fsqrt"
14210 [(set_attr "type" "fpspc")
14211 (set_attr "mode" "XF")
14212 (set_attr "athlon_decode" "direct")])
14213
14214 (define_insn "sqrttf2"
14215 [(set (match_operand:TF 0 "register_operand" "=f")
14216 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14217 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14218 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14219 "fsqrt"
14220 [(set_attr "type" "fpspc")
14221 (set_attr "mode" "XF")
14222 (set_attr "athlon_decode" "direct")])
14223
14224 (define_insn "*sqrtextenddfxf2"
14225 [(set (match_operand:XF 0 "register_operand" "=f")
14226 (sqrt:XF (float_extend:XF
14227 (match_operand:DF 1 "register_operand" "0"))))]
14228 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14229 "fsqrt"
14230 [(set_attr "type" "fpspc")
14231 (set_attr "mode" "XF")
14232 (set_attr "athlon_decode" "direct")])
14233
14234 (define_insn "*sqrtextenddftf2"
14235 [(set (match_operand:TF 0 "register_operand" "=f")
14236 (sqrt:TF (float_extend:TF
14237 (match_operand:DF 1 "register_operand" "0"))))]
14238 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14239 "fsqrt"
14240 [(set_attr "type" "fpspc")
14241 (set_attr "mode" "XF")
14242 (set_attr "athlon_decode" "direct")])
14243
14244 (define_insn "*sqrtextendsfxf2"
14245 [(set (match_operand:XF 0 "register_operand" "=f")
14246 (sqrt:XF (float_extend:XF
14247 (match_operand:SF 1 "register_operand" "0"))))]
14248 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14249 "fsqrt"
14250 [(set_attr "type" "fpspc")
14251 (set_attr "mode" "XF")
14252 (set_attr "athlon_decode" "direct")])
14253
14254 (define_insn "*sqrtextendsftf2"
14255 [(set (match_operand:TF 0 "register_operand" "=f")
14256 (sqrt:TF (float_extend:TF
14257 (match_operand:SF 1 "register_operand" "0"))))]
14258 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14259 "fsqrt"
14260 [(set_attr "type" "fpspc")
14261 (set_attr "mode" "XF")
14262 (set_attr "athlon_decode" "direct")])
14263
14264 (define_insn "sindf2"
14265 [(set (match_operand:DF 0 "register_operand" "=f")
14266 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14267 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14268 && flag_unsafe_math_optimizations"
14269 "fsin"
14270 [(set_attr "type" "fpspc")
14271 (set_attr "mode" "DF")])
14272
14273 (define_insn "sinsf2"
14274 [(set (match_operand:SF 0 "register_operand" "=f")
14275 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14276 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14277 && flag_unsafe_math_optimizations"
14278 "fsin"
14279 [(set_attr "type" "fpspc")
14280 (set_attr "mode" "SF")])
14281
14282 (define_insn "*sinextendsfdf2"
14283 [(set (match_operand:DF 0 "register_operand" "=f")
14284 (unspec:DF [(float_extend:DF
14285 (match_operand:SF 1 "register_operand" "0"))]
14286 UNSPEC_SIN))]
14287 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14288 && flag_unsafe_math_optimizations"
14289 "fsin"
14290 [(set_attr "type" "fpspc")
14291 (set_attr "mode" "DF")])
14292
14293 (define_insn "sinxf2"
14294 [(set (match_operand:XF 0 "register_operand" "=f")
14295 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14296 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14297 && flag_unsafe_math_optimizations"
14298 "fsin"
14299 [(set_attr "type" "fpspc")
14300 (set_attr "mode" "XF")])
14301
14302 (define_insn "sintf2"
14303 [(set (match_operand:TF 0 "register_operand" "=f")
14304 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
14305 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14306 && flag_unsafe_math_optimizations"
14307 "fsin"
14308 [(set_attr "type" "fpspc")
14309 (set_attr "mode" "XF")])
14310
14311 (define_insn "cosdf2"
14312 [(set (match_operand:DF 0 "register_operand" "=f")
14313 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14314 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14315 && flag_unsafe_math_optimizations"
14316 "fcos"
14317 [(set_attr "type" "fpspc")
14318 (set_attr "mode" "DF")])
14319
14320 (define_insn "cossf2"
14321 [(set (match_operand:SF 0 "register_operand" "=f")
14322 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14323 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14324 && flag_unsafe_math_optimizations"
14325 "fcos"
14326 [(set_attr "type" "fpspc")
14327 (set_attr "mode" "SF")])
14328
14329 (define_insn "*cosextendsfdf2"
14330 [(set (match_operand:DF 0 "register_operand" "=f")
14331 (unspec:DF [(float_extend:DF
14332 (match_operand:SF 1 "register_operand" "0"))]
14333 UNSPEC_COS))]
14334 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14335 && flag_unsafe_math_optimizations"
14336 "fcos"
14337 [(set_attr "type" "fpspc")
14338 (set_attr "mode" "DF")])
14339
14340 (define_insn "cosxf2"
14341 [(set (match_operand:XF 0 "register_operand" "=f")
14342 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14343 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14344 && flag_unsafe_math_optimizations"
14345 "fcos"
14346 [(set_attr "type" "fpspc")
14347 (set_attr "mode" "XF")])
14348
14349 (define_insn "costf2"
14350 [(set (match_operand:TF 0 "register_operand" "=f")
14351 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
14352 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14353 && flag_unsafe_math_optimizations"
14354 "fcos"
14355 [(set_attr "type" "fpspc")
14356 (set_attr "mode" "XF")])
14357 \f
14358 ;; Block operation instructions
14359
14360 (define_insn "cld"
14361 [(set (reg:SI 19) (const_int 0))]
14362 ""
14363 "cld"
14364 [(set_attr "type" "cld")])
14365
14366 (define_expand "movstrsi"
14367 [(use (match_operand:BLK 0 "memory_operand" ""))
14368 (use (match_operand:BLK 1 "memory_operand" ""))
14369 (use (match_operand:SI 2 "nonmemory_operand" ""))
14370 (use (match_operand:SI 3 "const_int_operand" ""))]
14371 ""
14372 {
14373 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14374 DONE;
14375 else
14376 FAIL;
14377 })
14378
14379 (define_expand "movstrdi"
14380 [(use (match_operand:BLK 0 "memory_operand" ""))
14381 (use (match_operand:BLK 1 "memory_operand" ""))
14382 (use (match_operand:DI 2 "nonmemory_operand" ""))
14383 (use (match_operand:DI 3 "const_int_operand" ""))]
14384 "TARGET_64BIT"
14385 {
14386 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14387 DONE;
14388 else
14389 FAIL;
14390 })
14391
14392 ;; Most CPUs don't like single string operations
14393 ;; Handle this case here to simplify previous expander.
14394
14395 (define_expand "strmovdi_rex64"
14396 [(set (match_dup 2)
14397 (mem:DI (match_operand:DI 1 "register_operand" "")))
14398 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14399 (match_dup 2))
14400 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14401 (clobber (reg:CC 17))])
14402 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14403 (clobber (reg:CC 17))])]
14404 "TARGET_64BIT"
14405 {
14406 if (TARGET_SINGLE_STRINGOP || optimize_size)
14407 {
14408 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14409 operands[1]));
14410 DONE;
14411 }
14412 else
14413 operands[2] = gen_reg_rtx (DImode);
14414 })
14415
14416
14417 (define_expand "strmovsi"
14418 [(set (match_dup 2)
14419 (mem:SI (match_operand:SI 1 "register_operand" "")))
14420 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14421 (match_dup 2))
14422 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14423 (clobber (reg:CC 17))])
14424 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14425 (clobber (reg:CC 17))])]
14426 ""
14427 {
14428 if (TARGET_64BIT)
14429 {
14430 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14431 DONE;
14432 }
14433 if (TARGET_SINGLE_STRINGOP || optimize_size)
14434 {
14435 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14436 operands[1]));
14437 DONE;
14438 }
14439 else
14440 operands[2] = gen_reg_rtx (SImode);
14441 })
14442
14443 (define_expand "strmovsi_rex64"
14444 [(set (match_dup 2)
14445 (mem:SI (match_operand:DI 1 "register_operand" "")))
14446 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14447 (match_dup 2))
14448 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14449 (clobber (reg:CC 17))])
14450 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14451 (clobber (reg:CC 17))])]
14452 "TARGET_64BIT"
14453 {
14454 if (TARGET_SINGLE_STRINGOP || optimize_size)
14455 {
14456 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14457 operands[1]));
14458 DONE;
14459 }
14460 else
14461 operands[2] = gen_reg_rtx (SImode);
14462 })
14463
14464 (define_expand "strmovhi"
14465 [(set (match_dup 2)
14466 (mem:HI (match_operand:SI 1 "register_operand" "")))
14467 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14468 (match_dup 2))
14469 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14470 (clobber (reg:CC 17))])
14471 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14472 (clobber (reg:CC 17))])]
14473 ""
14474 {
14475 if (TARGET_64BIT)
14476 {
14477 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14478 DONE;
14479 }
14480 if (TARGET_SINGLE_STRINGOP || optimize_size)
14481 {
14482 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14483 operands[1]));
14484 DONE;
14485 }
14486 else
14487 operands[2] = gen_reg_rtx (HImode);
14488 })
14489
14490 (define_expand "strmovhi_rex64"
14491 [(set (match_dup 2)
14492 (mem:HI (match_operand:DI 1 "register_operand" "")))
14493 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14494 (match_dup 2))
14495 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14496 (clobber (reg:CC 17))])
14497 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14498 (clobber (reg:CC 17))])]
14499 "TARGET_64BIT"
14500 {
14501 if (TARGET_SINGLE_STRINGOP || optimize_size)
14502 {
14503 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
14504 operands[1]));
14505 DONE;
14506 }
14507 else
14508 operands[2] = gen_reg_rtx (HImode);
14509 })
14510
14511 (define_expand "strmovqi"
14512 [(set (match_dup 2)
14513 (mem:QI (match_operand:SI 1 "register_operand" "")))
14514 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
14515 (match_dup 2))
14516 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14517 (clobber (reg:CC 17))])
14518 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
14519 (clobber (reg:CC 17))])]
14520 ""
14521 {
14522 if (TARGET_64BIT)
14523 {
14524 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
14525 DONE;
14526 }
14527 if (TARGET_SINGLE_STRINGOP || optimize_size)
14528 {
14529 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
14530 operands[1]));
14531 DONE;
14532 }
14533 else
14534 operands[2] = gen_reg_rtx (QImode);
14535 })
14536
14537 (define_expand "strmovqi_rex64"
14538 [(set (match_dup 2)
14539 (mem:QI (match_operand:DI 1 "register_operand" "")))
14540 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
14541 (match_dup 2))
14542 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14543 (clobber (reg:CC 17))])
14544 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
14545 (clobber (reg:CC 17))])]
14546 "TARGET_64BIT"
14547 {
14548 if (TARGET_SINGLE_STRINGOP || optimize_size)
14549 {
14550 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
14551 operands[1]));
14552 DONE;
14553 }
14554 else
14555 operands[2] = gen_reg_rtx (QImode);
14556 })
14557
14558 (define_insn "strmovdi_rex_1"
14559 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
14560 (mem:DI (match_operand:DI 3 "register_operand" "1")))
14561 (set (match_operand:DI 0 "register_operand" "=D")
14562 (plus:DI (match_dup 2)
14563 (const_int 8)))
14564 (set (match_operand:DI 1 "register_operand" "=S")
14565 (plus:DI (match_dup 3)
14566 (const_int 8)))
14567 (use (reg:SI 19))]
14568 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14569 "movsq"
14570 [(set_attr "type" "str")
14571 (set_attr "mode" "DI")
14572 (set_attr "memory" "both")])
14573
14574 (define_insn "strmovsi_1"
14575 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
14576 (mem:SI (match_operand:SI 3 "register_operand" "1")))
14577 (set (match_operand:SI 0 "register_operand" "=D")
14578 (plus:SI (match_dup 2)
14579 (const_int 4)))
14580 (set (match_operand:SI 1 "register_operand" "=S")
14581 (plus:SI (match_dup 3)
14582 (const_int 4)))
14583 (use (reg:SI 19))]
14584 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14585 "{movsl|movsd}"
14586 [(set_attr "type" "str")
14587 (set_attr "mode" "SI")
14588 (set_attr "memory" "both")])
14589
14590 (define_insn "strmovsi_rex_1"
14591 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
14592 (mem:SI (match_operand:DI 3 "register_operand" "1")))
14593 (set (match_operand:DI 0 "register_operand" "=D")
14594 (plus:DI (match_dup 2)
14595 (const_int 4)))
14596 (set (match_operand:DI 1 "register_operand" "=S")
14597 (plus:DI (match_dup 3)
14598 (const_int 4)))
14599 (use (reg:SI 19))]
14600 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14601 "{movsl|movsd}"
14602 [(set_attr "type" "str")
14603 (set_attr "mode" "SI")
14604 (set_attr "memory" "both")])
14605
14606 (define_insn "strmovhi_1"
14607 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
14608 (mem:HI (match_operand:SI 3 "register_operand" "1")))
14609 (set (match_operand:SI 0 "register_operand" "=D")
14610 (plus:SI (match_dup 2)
14611 (const_int 2)))
14612 (set (match_operand:SI 1 "register_operand" "=S")
14613 (plus:SI (match_dup 3)
14614 (const_int 2)))
14615 (use (reg:SI 19))]
14616 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14617 "movsw"
14618 [(set_attr "type" "str")
14619 (set_attr "memory" "both")
14620 (set_attr "mode" "HI")])
14621
14622 (define_insn "strmovhi_rex_1"
14623 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
14624 (mem:HI (match_operand:DI 3 "register_operand" "1")))
14625 (set (match_operand:DI 0 "register_operand" "=D")
14626 (plus:DI (match_dup 2)
14627 (const_int 2)))
14628 (set (match_operand:DI 1 "register_operand" "=S")
14629 (plus:DI (match_dup 3)
14630 (const_int 2)))
14631 (use (reg:SI 19))]
14632 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14633 "movsw"
14634 [(set_attr "type" "str")
14635 (set_attr "memory" "both")
14636 (set_attr "mode" "HI")])
14637
14638 (define_insn "strmovqi_1"
14639 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
14640 (mem:QI (match_operand:SI 3 "register_operand" "1")))
14641 (set (match_operand:SI 0 "register_operand" "=D")
14642 (plus:SI (match_dup 2)
14643 (const_int 1)))
14644 (set (match_operand:SI 1 "register_operand" "=S")
14645 (plus:SI (match_dup 3)
14646 (const_int 1)))
14647 (use (reg:SI 19))]
14648 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14649 "movsb"
14650 [(set_attr "type" "str")
14651 (set_attr "memory" "both")
14652 (set_attr "mode" "QI")])
14653
14654 (define_insn "strmovqi_rex_1"
14655 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
14656 (mem:QI (match_operand:DI 3 "register_operand" "1")))
14657 (set (match_operand:DI 0 "register_operand" "=D")
14658 (plus:DI (match_dup 2)
14659 (const_int 1)))
14660 (set (match_operand:DI 1 "register_operand" "=S")
14661 (plus:DI (match_dup 3)
14662 (const_int 1)))
14663 (use (reg:SI 19))]
14664 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14665 "movsb"
14666 [(set_attr "type" "str")
14667 (set_attr "memory" "both")
14668 (set_attr "mode" "QI")])
14669
14670 (define_insn "rep_movdi_rex64"
14671 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14672 (set (match_operand:DI 0 "register_operand" "=D")
14673 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14674 (const_int 3))
14675 (match_operand:DI 3 "register_operand" "0")))
14676 (set (match_operand:DI 1 "register_operand" "=S")
14677 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
14678 (match_operand:DI 4 "register_operand" "1")))
14679 (set (mem:BLK (match_dup 3))
14680 (mem:BLK (match_dup 4)))
14681 (use (match_dup 5))
14682 (use (reg:SI 19))]
14683 "TARGET_64BIT"
14684 "{rep\;movsq|rep movsq}"
14685 [(set_attr "type" "str")
14686 (set_attr "prefix_rep" "1")
14687 (set_attr "memory" "both")
14688 (set_attr "mode" "DI")])
14689
14690 (define_insn "rep_movsi"
14691 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
14692 (set (match_operand:SI 0 "register_operand" "=D")
14693 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
14694 (const_int 2))
14695 (match_operand:SI 3 "register_operand" "0")))
14696 (set (match_operand:SI 1 "register_operand" "=S")
14697 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
14698 (match_operand:SI 4 "register_operand" "1")))
14699 (set (mem:BLK (match_dup 3))
14700 (mem:BLK (match_dup 4)))
14701 (use (match_dup 5))
14702 (use (reg:SI 19))]
14703 "!TARGET_64BIT"
14704 "{rep\;movsl|rep movsd}"
14705 [(set_attr "type" "str")
14706 (set_attr "prefix_rep" "1")
14707 (set_attr "memory" "both")
14708 (set_attr "mode" "SI")])
14709
14710 (define_insn "rep_movsi_rex64"
14711 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14712 (set (match_operand:DI 0 "register_operand" "=D")
14713 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14714 (const_int 2))
14715 (match_operand:DI 3 "register_operand" "0")))
14716 (set (match_operand:DI 1 "register_operand" "=S")
14717 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
14718 (match_operand:DI 4 "register_operand" "1")))
14719 (set (mem:BLK (match_dup 3))
14720 (mem:BLK (match_dup 4)))
14721 (use (match_dup 5))
14722 (use (reg:SI 19))]
14723 "TARGET_64BIT"
14724 "{rep\;movsl|rep movsd}"
14725 [(set_attr "type" "str")
14726 (set_attr "prefix_rep" "1")
14727 (set_attr "memory" "both")
14728 (set_attr "mode" "SI")])
14729
14730 (define_insn "rep_movqi"
14731 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
14732 (set (match_operand:SI 0 "register_operand" "=D")
14733 (plus:SI (match_operand:SI 3 "register_operand" "0")
14734 (match_operand:SI 5 "register_operand" "2")))
14735 (set (match_operand:SI 1 "register_operand" "=S")
14736 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
14737 (set (mem:BLK (match_dup 3))
14738 (mem:BLK (match_dup 4)))
14739 (use (match_dup 5))
14740 (use (reg:SI 19))]
14741 "!TARGET_64BIT"
14742 "{rep\;movsb|rep movsb}"
14743 [(set_attr "type" "str")
14744 (set_attr "prefix_rep" "1")
14745 (set_attr "memory" "both")
14746 (set_attr "mode" "SI")])
14747
14748 (define_insn "rep_movqi_rex64"
14749 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14750 (set (match_operand:DI 0 "register_operand" "=D")
14751 (plus:DI (match_operand:DI 3 "register_operand" "0")
14752 (match_operand:DI 5 "register_operand" "2")))
14753 (set (match_operand:DI 1 "register_operand" "=S")
14754 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
14755 (set (mem:BLK (match_dup 3))
14756 (mem:BLK (match_dup 4)))
14757 (use (match_dup 5))
14758 (use (reg:SI 19))]
14759 "TARGET_64BIT"
14760 "{rep\;movsb|rep movsb}"
14761 [(set_attr "type" "str")
14762 (set_attr "prefix_rep" "1")
14763 (set_attr "memory" "both")
14764 (set_attr "mode" "SI")])
14765
14766 (define_expand "clrstrsi"
14767 [(use (match_operand:BLK 0 "memory_operand" ""))
14768 (use (match_operand:SI 1 "nonmemory_operand" ""))
14769 (use (match_operand 2 "const_int_operand" ""))]
14770 ""
14771 {
14772 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14773 DONE;
14774 else
14775 FAIL;
14776 })
14777
14778 (define_expand "clrstrdi"
14779 [(use (match_operand:BLK 0 "memory_operand" ""))
14780 (use (match_operand:DI 1 "nonmemory_operand" ""))
14781 (use (match_operand 2 "const_int_operand" ""))]
14782 "TARGET_64BIT"
14783 {
14784 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14785 DONE;
14786 else
14787 FAIL;
14788 })
14789
14790 ;; Most CPUs don't like single string operations
14791 ;; Handle this case here to simplify previous expander.
14792
14793 (define_expand "strsetdi_rex64"
14794 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
14795 (match_operand:DI 1 "register_operand" ""))
14796 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14797 (clobber (reg:CC 17))])]
14798 "TARGET_64BIT"
14799 {
14800 if (TARGET_SINGLE_STRINGOP || optimize_size)
14801 {
14802 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
14803 DONE;
14804 }
14805 })
14806
14807 (define_expand "strsetsi"
14808 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
14809 (match_operand:SI 1 "register_operand" ""))
14810 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14811 (clobber (reg:CC 17))])]
14812 ""
14813 {
14814 if (TARGET_64BIT)
14815 {
14816 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
14817 DONE;
14818 }
14819 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14820 {
14821 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
14822 DONE;
14823 }
14824 })
14825
14826 (define_expand "strsetsi_rex64"
14827 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
14828 (match_operand:SI 1 "register_operand" ""))
14829 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14830 (clobber (reg:CC 17))])]
14831 "TARGET_64BIT"
14832 {
14833 if (TARGET_SINGLE_STRINGOP || optimize_size)
14834 {
14835 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
14836 DONE;
14837 }
14838 })
14839
14840 (define_expand "strsethi"
14841 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
14842 (match_operand:HI 1 "register_operand" ""))
14843 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14844 (clobber (reg:CC 17))])]
14845 ""
14846 {
14847 if (TARGET_64BIT)
14848 {
14849 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
14850 DONE;
14851 }
14852 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14853 {
14854 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
14855 DONE;
14856 }
14857 })
14858
14859 (define_expand "strsethi_rex64"
14860 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
14861 (match_operand:HI 1 "register_operand" ""))
14862 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14863 (clobber (reg:CC 17))])]
14864 "TARGET_64BIT"
14865 {
14866 if (TARGET_SINGLE_STRINGOP || optimize_size)
14867 {
14868 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
14869 DONE;
14870 }
14871 })
14872
14873 (define_expand "strsetqi"
14874 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
14875 (match_operand:QI 1 "register_operand" ""))
14876 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14877 (clobber (reg:CC 17))])]
14878 ""
14879 {
14880 if (TARGET_64BIT)
14881 {
14882 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
14883 DONE;
14884 }
14885 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14886 {
14887 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
14888 DONE;
14889 }
14890 })
14891
14892 (define_expand "strsetqi_rex64"
14893 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
14894 (match_operand:QI 1 "register_operand" ""))
14895 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14896 (clobber (reg:CC 17))])]
14897 "TARGET_64BIT"
14898 {
14899 if (TARGET_SINGLE_STRINGOP || optimize_size)
14900 {
14901 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
14902 DONE;
14903 }
14904 })
14905
14906 (define_insn "strsetdi_rex_1"
14907 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
14908 (match_operand:SI 2 "register_operand" "a"))
14909 (set (match_operand:DI 0 "register_operand" "=D")
14910 (plus:DI (match_dup 1)
14911 (const_int 8)))
14912 (use (reg:SI 19))]
14913 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14914 "stosq"
14915 [(set_attr "type" "str")
14916 (set_attr "memory" "store")
14917 (set_attr "mode" "DI")])
14918
14919 (define_insn "strsetsi_1"
14920 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
14921 (match_operand:SI 2 "register_operand" "a"))
14922 (set (match_operand:SI 0 "register_operand" "=D")
14923 (plus:SI (match_dup 1)
14924 (const_int 4)))
14925 (use (reg:SI 19))]
14926 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14927 "{stosl|stosd}"
14928 [(set_attr "type" "str")
14929 (set_attr "memory" "store")
14930 (set_attr "mode" "SI")])
14931
14932 (define_insn "strsetsi_rex_1"
14933 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
14934 (match_operand:SI 2 "register_operand" "a"))
14935 (set (match_operand:DI 0 "register_operand" "=D")
14936 (plus:DI (match_dup 1)
14937 (const_int 4)))
14938 (use (reg:SI 19))]
14939 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14940 "{stosl|stosd}"
14941 [(set_attr "type" "str")
14942 (set_attr "memory" "store")
14943 (set_attr "mode" "SI")])
14944
14945 (define_insn "strsethi_1"
14946 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
14947 (match_operand:HI 2 "register_operand" "a"))
14948 (set (match_operand:SI 0 "register_operand" "=D")
14949 (plus:SI (match_dup 1)
14950 (const_int 2)))
14951 (use (reg:SI 19))]
14952 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14953 "stosw"
14954 [(set_attr "type" "str")
14955 (set_attr "memory" "store")
14956 (set_attr "mode" "HI")])
14957
14958 (define_insn "strsethi_rex_1"
14959 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
14960 (match_operand:HI 2 "register_operand" "a"))
14961 (set (match_operand:DI 0 "register_operand" "=D")
14962 (plus:DI (match_dup 1)
14963 (const_int 2)))
14964 (use (reg:SI 19))]
14965 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14966 "stosw"
14967 [(set_attr "type" "str")
14968 (set_attr "memory" "store")
14969 (set_attr "mode" "HI")])
14970
14971 (define_insn "strsetqi_1"
14972 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
14973 (match_operand:QI 2 "register_operand" "a"))
14974 (set (match_operand:SI 0 "register_operand" "=D")
14975 (plus:SI (match_dup 1)
14976 (const_int 1)))
14977 (use (reg:SI 19))]
14978 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14979 "stosb"
14980 [(set_attr "type" "str")
14981 (set_attr "memory" "store")
14982 (set_attr "mode" "QI")])
14983
14984 (define_insn "strsetqi_rex_1"
14985 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
14986 (match_operand:QI 2 "register_operand" "a"))
14987 (set (match_operand:DI 0 "register_operand" "=D")
14988 (plus:DI (match_dup 1)
14989 (const_int 1)))
14990 (use (reg:SI 19))]
14991 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14992 "stosb"
14993 [(set_attr "type" "str")
14994 (set_attr "memory" "store")
14995 (set_attr "mode" "QI")])
14996
14997 (define_insn "rep_stosdi_rex64"
14998 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
14999 (set (match_operand:DI 0 "register_operand" "=D")
15000 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15001 (const_int 3))
15002 (match_operand:DI 3 "register_operand" "0")))
15003 (set (mem:BLK (match_dup 3))
15004 (const_int 0))
15005 (use (match_operand:DI 2 "register_operand" "a"))
15006 (use (match_dup 4))
15007 (use (reg:SI 19))]
15008 "TARGET_64BIT"
15009 "{rep\;stosq|rep stosq}"
15010 [(set_attr "type" "str")
15011 (set_attr "prefix_rep" "1")
15012 (set_attr "memory" "store")
15013 (set_attr "mode" "DI")])
15014
15015 (define_insn "rep_stossi"
15016 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15017 (set (match_operand:SI 0 "register_operand" "=D")
15018 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15019 (const_int 2))
15020 (match_operand:SI 3 "register_operand" "0")))
15021 (set (mem:BLK (match_dup 3))
15022 (const_int 0))
15023 (use (match_operand:SI 2 "register_operand" "a"))
15024 (use (match_dup 4))
15025 (use (reg:SI 19))]
15026 "!TARGET_64BIT"
15027 "{rep\;stosl|rep stosd}"
15028 [(set_attr "type" "str")
15029 (set_attr "prefix_rep" "1")
15030 (set_attr "memory" "store")
15031 (set_attr "mode" "SI")])
15032
15033 (define_insn "rep_stossi_rex64"
15034 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15035 (set (match_operand:DI 0 "register_operand" "=D")
15036 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15037 (const_int 2))
15038 (match_operand:DI 3 "register_operand" "0")))
15039 (set (mem:BLK (match_dup 3))
15040 (const_int 0))
15041 (use (match_operand:SI 2 "register_operand" "a"))
15042 (use (match_dup 4))
15043 (use (reg:SI 19))]
15044 "TARGET_64BIT"
15045 "{rep\;stosl|rep stosd}"
15046 [(set_attr "type" "str")
15047 (set_attr "prefix_rep" "1")
15048 (set_attr "memory" "store")
15049 (set_attr "mode" "SI")])
15050
15051 (define_insn "rep_stosqi"
15052 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15053 (set (match_operand:SI 0 "register_operand" "=D")
15054 (plus:SI (match_operand:SI 3 "register_operand" "0")
15055 (match_operand:SI 4 "register_operand" "1")))
15056 (set (mem:BLK (match_dup 3))
15057 (const_int 0))
15058 (use (match_operand:QI 2 "register_operand" "a"))
15059 (use (match_dup 4))
15060 (use (reg:SI 19))]
15061 "!TARGET_64BIT"
15062 "{rep\;stosb|rep stosb}"
15063 [(set_attr "type" "str")
15064 (set_attr "prefix_rep" "1")
15065 (set_attr "memory" "store")
15066 (set_attr "mode" "QI")])
15067
15068 (define_insn "rep_stosqi_rex64"
15069 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15070 (set (match_operand:DI 0 "register_operand" "=D")
15071 (plus:DI (match_operand:DI 3 "register_operand" "0")
15072 (match_operand:DI 4 "register_operand" "1")))
15073 (set (mem:BLK (match_dup 3))
15074 (const_int 0))
15075 (use (match_operand:QI 2 "register_operand" "a"))
15076 (use (match_dup 4))
15077 (use (reg:DI 19))]
15078 "TARGET_64BIT"
15079 "{rep\;stosb|rep stosb}"
15080 [(set_attr "type" "str")
15081 (set_attr "prefix_rep" "1")
15082 (set_attr "memory" "store")
15083 (set_attr "mode" "QI")])
15084
15085 (define_expand "cmpstrsi"
15086 [(set (match_operand:SI 0 "register_operand" "")
15087 (compare:SI (match_operand:BLK 1 "general_operand" "")
15088 (match_operand:BLK 2 "general_operand" "")))
15089 (use (match_operand 3 "general_operand" ""))
15090 (use (match_operand 4 "immediate_operand" ""))]
15091 ""
15092 {
15093 rtx addr1, addr2, out, outlow, count, countreg, align;
15094
15095 out = operands[0];
15096 if (GET_CODE (out) != REG)
15097 out = gen_reg_rtx (SImode);
15098
15099 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15100 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15101
15102 count = operands[3];
15103 countreg = ix86_zero_extend_to_Pmode (count);
15104
15105 /* %%% Iff we are testing strict equality, we can use known alignment
15106 to good advantage. This may be possible with combine, particularly
15107 once cc0 is dead. */
15108 align = operands[4];
15109
15110 emit_insn (gen_cld ());
15111 if (GET_CODE (count) == CONST_INT)
15112 {
15113 if (INTVAL (count) == 0)
15114 {
15115 emit_move_insn (operands[0], const0_rtx);
15116 DONE;
15117 }
15118 if (TARGET_64BIT)
15119 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15120 addr1, addr2, countreg));
15121 else
15122 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15123 addr1, addr2, countreg));
15124 }
15125 else
15126 {
15127 if (TARGET_64BIT)
15128 {
15129 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15130 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15131 addr1, addr2, countreg));
15132 }
15133 else
15134 {
15135 emit_insn (gen_cmpsi_1 (countreg, countreg));
15136 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15137 addr1, addr2, countreg));
15138 }
15139 }
15140
15141 outlow = gen_lowpart (QImode, out);
15142 emit_insn (gen_cmpintqi (outlow));
15143 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15144
15145 if (operands[0] != out)
15146 emit_move_insn (operands[0], out);
15147
15148 DONE;
15149 })
15150
15151 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15152
15153 (define_expand "cmpintqi"
15154 [(set (match_dup 1)
15155 (gtu:QI (reg:CC 17) (const_int 0)))
15156 (set (match_dup 2)
15157 (ltu:QI (reg:CC 17) (const_int 0)))
15158 (parallel [(set (match_operand:QI 0 "register_operand" "")
15159 (minus:QI (match_dup 1)
15160 (match_dup 2)))
15161 (clobber (reg:CC 17))])]
15162 ""
15163 "operands[1] = gen_reg_rtx (QImode);
15164 operands[2] = gen_reg_rtx (QImode);")
15165
15166 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15167 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15168
15169 (define_insn "cmpstrqi_nz_1"
15170 [(set (reg:CC 17)
15171 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15172 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15173 (use (match_operand:SI 6 "register_operand" "2"))
15174 (use (match_operand:SI 3 "immediate_operand" "i"))
15175 (use (reg:SI 19))
15176 (clobber (match_operand:SI 0 "register_operand" "=S"))
15177 (clobber (match_operand:SI 1 "register_operand" "=D"))
15178 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15179 "!TARGET_64BIT"
15180 "repz{\;| }cmpsb"
15181 [(set_attr "type" "str")
15182 (set_attr "mode" "QI")
15183 (set_attr "prefix_rep" "1")])
15184
15185 (define_insn "cmpstrqi_nz_rex_1"
15186 [(set (reg:CC 17)
15187 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15188 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15189 (use (match_operand:DI 6 "register_operand" "2"))
15190 (use (match_operand:SI 3 "immediate_operand" "i"))
15191 (use (reg:SI 19))
15192 (clobber (match_operand:DI 0 "register_operand" "=S"))
15193 (clobber (match_operand:DI 1 "register_operand" "=D"))
15194 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15195 "TARGET_64BIT"
15196 "repz{\;| }cmpsb"
15197 [(set_attr "type" "str")
15198 (set_attr "mode" "QI")
15199 (set_attr "prefix_rep" "1")])
15200
15201 ;; The same, but the count is not known to not be zero.
15202
15203 (define_insn "cmpstrqi_1"
15204 [(set (reg:CC 17)
15205 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15206 (const_int 0))
15207 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15208 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15209 (const_int 0)))
15210 (use (match_operand:SI 3 "immediate_operand" "i"))
15211 (use (reg:CC 17))
15212 (use (reg:SI 19))
15213 (clobber (match_operand:SI 0 "register_operand" "=S"))
15214 (clobber (match_operand:SI 1 "register_operand" "=D"))
15215 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15216 "!TARGET_64BIT"
15217 "repz{\;| }cmpsb"
15218 [(set_attr "type" "str")
15219 (set_attr "mode" "QI")
15220 (set_attr "prefix_rep" "1")])
15221
15222 (define_insn "cmpstrqi_rex_1"
15223 [(set (reg:CC 17)
15224 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15225 (const_int 0))
15226 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15227 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15228 (const_int 0)))
15229 (use (match_operand:SI 3 "immediate_operand" "i"))
15230 (use (reg:CC 17))
15231 (use (reg:SI 19))
15232 (clobber (match_operand:DI 0 "register_operand" "=S"))
15233 (clobber (match_operand:DI 1 "register_operand" "=D"))
15234 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15235 "TARGET_64BIT"
15236 "repz{\;| }cmpsb"
15237 [(set_attr "type" "str")
15238 (set_attr "mode" "QI")
15239 (set_attr "prefix_rep" "1")])
15240
15241 (define_expand "strlensi"
15242 [(set (match_operand:SI 0 "register_operand" "")
15243 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15244 (match_operand:QI 2 "immediate_operand" "")
15245 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15246 ""
15247 {
15248 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15249 DONE;
15250 else
15251 FAIL;
15252 })
15253
15254 (define_expand "strlendi"
15255 [(set (match_operand:DI 0 "register_operand" "")
15256 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15257 (match_operand:QI 2 "immediate_operand" "")
15258 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15259 ""
15260 {
15261 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15262 DONE;
15263 else
15264 FAIL;
15265 })
15266
15267 (define_insn "strlenqi_1"
15268 [(set (match_operand:SI 0 "register_operand" "=&c")
15269 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15270 (match_operand:QI 2 "register_operand" "a")
15271 (match_operand:SI 3 "immediate_operand" "i")
15272 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15273 (use (reg:SI 19))
15274 (clobber (match_operand:SI 1 "register_operand" "=D"))
15275 (clobber (reg:CC 17))]
15276 "!TARGET_64BIT"
15277 "repnz{\;| }scasb"
15278 [(set_attr "type" "str")
15279 (set_attr "mode" "QI")
15280 (set_attr "prefix_rep" "1")])
15281
15282 (define_insn "strlenqi_rex_1"
15283 [(set (match_operand:DI 0 "register_operand" "=&c")
15284 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15285 (match_operand:QI 2 "register_operand" "a")
15286 (match_operand:DI 3 "immediate_operand" "i")
15287 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15288 (use (reg:SI 19))
15289 (clobber (match_operand:DI 1 "register_operand" "=D"))
15290 (clobber (reg:CC 17))]
15291 "TARGET_64BIT"
15292 "repnz{\;| }scasb"
15293 [(set_attr "type" "str")
15294 (set_attr "mode" "QI")
15295 (set_attr "prefix_rep" "1")])
15296
15297 ;; Peephole optimizations to clean up after cmpstr*. This should be
15298 ;; handled in combine, but it is not currently up to the task.
15299 ;; When used for their truth value, the cmpstr* expanders generate
15300 ;; code like this:
15301 ;;
15302 ;; repz cmpsb
15303 ;; seta %al
15304 ;; setb %dl
15305 ;; cmpb %al, %dl
15306 ;; jcc label
15307 ;;
15308 ;; The intermediate three instructions are unnecessary.
15309
15310 ;; This one handles cmpstr*_nz_1...
15311 (define_peephole2
15312 [(parallel[
15313 (set (reg:CC 17)
15314 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15315 (mem:BLK (match_operand 5 "register_operand" ""))))
15316 (use (match_operand 6 "register_operand" ""))
15317 (use (match_operand:SI 3 "immediate_operand" ""))
15318 (use (reg:SI 19))
15319 (clobber (match_operand 0 "register_operand" ""))
15320 (clobber (match_operand 1 "register_operand" ""))
15321 (clobber (match_operand 2 "register_operand" ""))])
15322 (set (match_operand:QI 7 "register_operand" "")
15323 (gtu:QI (reg:CC 17) (const_int 0)))
15324 (set (match_operand:QI 8 "register_operand" "")
15325 (ltu:QI (reg:CC 17) (const_int 0)))
15326 (set (reg 17)
15327 (compare (match_dup 7) (match_dup 8)))
15328 ]
15329 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15330 [(parallel[
15331 (set (reg:CC 17)
15332 (compare:CC (mem:BLK (match_dup 4))
15333 (mem:BLK (match_dup 5))))
15334 (use (match_dup 6))
15335 (use (match_dup 3))
15336 (use (reg:SI 19))
15337 (clobber (match_dup 0))
15338 (clobber (match_dup 1))
15339 (clobber (match_dup 2))])]
15340 "")
15341
15342 ;; ...and this one handles cmpstr*_1.
15343 (define_peephole2
15344 [(parallel[
15345 (set (reg:CC 17)
15346 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15347 (const_int 0))
15348 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15349 (mem:BLK (match_operand 5 "register_operand" "")))
15350 (const_int 0)))
15351 (use (match_operand:SI 3 "immediate_operand" ""))
15352 (use (reg:CC 17))
15353 (use (reg:SI 19))
15354 (clobber (match_operand 0 "register_operand" ""))
15355 (clobber (match_operand 1 "register_operand" ""))
15356 (clobber (match_operand 2 "register_operand" ""))])
15357 (set (match_operand:QI 7 "register_operand" "")
15358 (gtu:QI (reg:CC 17) (const_int 0)))
15359 (set (match_operand:QI 8 "register_operand" "")
15360 (ltu:QI (reg:CC 17) (const_int 0)))
15361 (set (reg 17)
15362 (compare (match_dup 7) (match_dup 8)))
15363 ]
15364 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15365 [(parallel[
15366 (set (reg:CC 17)
15367 (if_then_else:CC (ne (match_dup 6)
15368 (const_int 0))
15369 (compare:CC (mem:BLK (match_dup 4))
15370 (mem:BLK (match_dup 5)))
15371 (const_int 0)))
15372 (use (match_dup 3))
15373 (use (reg:CC 17))
15374 (use (reg:SI 19))
15375 (clobber (match_dup 0))
15376 (clobber (match_dup 1))
15377 (clobber (match_dup 2))])]
15378 "")
15379
15380
15381 \f
15382 ;; Conditional move instructions.
15383
15384 (define_expand "movdicc"
15385 [(set (match_operand:DI 0 "register_operand" "")
15386 (if_then_else:DI (match_operand 1 "comparison_operator" "")
15387 (match_operand:DI 2 "general_operand" "")
15388 (match_operand:DI 3 "general_operand" "")))]
15389 "TARGET_64BIT"
15390 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15391
15392 (define_insn "x86_movdicc_0_m1_rex64"
15393 [(set (match_operand:DI 0 "register_operand" "=r")
15394 (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15395 (const_int -1)
15396 (const_int 0)))
15397 (clobber (reg:CC 17))]
15398 "TARGET_64BIT"
15399 "sbb{q}\t%0, %0"
15400 ; Since we don't have the proper number of operands for an alu insn,
15401 ; fill in all the blanks.
15402 [(set_attr "type" "alu")
15403 (set_attr "pent_pair" "pu")
15404 (set_attr "memory" "none")
15405 (set_attr "imm_disp" "false")
15406 (set_attr "mode" "DI")
15407 (set_attr "length_immediate" "0")])
15408
15409 (define_insn "*movdicc_c_rex64"
15410 [(set (match_operand:DI 0 "register_operand" "=r,r")
15411 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
15412 [(reg 17) (const_int 0)])
15413 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15414 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15415 "TARGET_64BIT && TARGET_CMOVE
15416 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15417 "@
15418 cmov%O2%C1\t{%2, %0|%0, %2}
15419 cmov%O2%c1\t{%3, %0|%0, %3}"
15420 [(set_attr "type" "icmov")
15421 (set_attr "mode" "DI")])
15422
15423 (define_expand "movsicc"
15424 [(set (match_operand:SI 0 "register_operand" "")
15425 (if_then_else:SI (match_operand 1 "comparison_operator" "")
15426 (match_operand:SI 2 "general_operand" "")
15427 (match_operand:SI 3 "general_operand" "")))]
15428 ""
15429 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15430
15431 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15432 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15433 ;; So just document what we're doing explicitly.
15434
15435 (define_insn "x86_movsicc_0_m1"
15436 [(set (match_operand:SI 0 "register_operand" "=r")
15437 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15438 (const_int -1)
15439 (const_int 0)))
15440 (clobber (reg:CC 17))]
15441 ""
15442 "sbb{l}\t%0, %0"
15443 ; Since we don't have the proper number of operands for an alu insn,
15444 ; fill in all the blanks.
15445 [(set_attr "type" "alu")
15446 (set_attr "pent_pair" "pu")
15447 (set_attr "memory" "none")
15448 (set_attr "imm_disp" "false")
15449 (set_attr "mode" "SI")
15450 (set_attr "length_immediate" "0")])
15451
15452 (define_insn "*movsicc_noc"
15453 [(set (match_operand:SI 0 "register_operand" "=r,r")
15454 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
15455 [(reg 17) (const_int 0)])
15456 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15457 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
15458 "TARGET_CMOVE
15459 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15460 "@
15461 cmov%O2%C1\t{%2, %0|%0, %2}
15462 cmov%O2%c1\t{%3, %0|%0, %3}"
15463 [(set_attr "type" "icmov")
15464 (set_attr "mode" "SI")])
15465
15466 (define_expand "movhicc"
15467 [(set (match_operand:HI 0 "register_operand" "")
15468 (if_then_else:HI (match_operand 1 "comparison_operator" "")
15469 (match_operand:HI 2 "nonimmediate_operand" "")
15470 (match_operand:HI 3 "nonimmediate_operand" "")))]
15471 "TARGET_CMOVE && TARGET_HIMODE_MATH"
15472 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15473
15474 (define_insn "*movhicc_noc"
15475 [(set (match_operand:HI 0 "register_operand" "=r,r")
15476 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
15477 [(reg 17) (const_int 0)])
15478 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15479 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
15480 "TARGET_CMOVE
15481 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15482 "@
15483 cmov%O2%C1\t{%2, %0|%0, %2}
15484 cmov%O2%c1\t{%3, %0|%0, %3}"
15485 [(set_attr "type" "icmov")
15486 (set_attr "mode" "HI")])
15487
15488 (define_expand "movsfcc"
15489 [(set (match_operand:SF 0 "register_operand" "")
15490 (if_then_else:SF (match_operand 1 "comparison_operator" "")
15491 (match_operand:SF 2 "register_operand" "")
15492 (match_operand:SF 3 "register_operand" "")))]
15493 "TARGET_CMOVE"
15494 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15495
15496 (define_insn "*movsfcc_1"
15497 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15498 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15499 [(reg 17) (const_int 0)])
15500 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15501 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15502 "TARGET_CMOVE
15503 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15504 "@
15505 fcmov%F1\t{%2, %0|%0, %2}
15506 fcmov%f1\t{%3, %0|%0, %3}
15507 cmov%O2%C1\t{%2, %0|%0, %2}
15508 cmov%O2%c1\t{%3, %0|%0, %3}"
15509 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15510 (set_attr "mode" "SF,SF,SI,SI")])
15511
15512 (define_expand "movdfcc"
15513 [(set (match_operand:DF 0 "register_operand" "")
15514 (if_then_else:DF (match_operand 1 "comparison_operator" "")
15515 (match_operand:DF 2 "register_operand" "")
15516 (match_operand:DF 3 "register_operand" "")))]
15517 "TARGET_CMOVE"
15518 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15519
15520 (define_insn "*movdfcc_1"
15521 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15522 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15523 [(reg 17) (const_int 0)])
15524 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15525 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15526 "!TARGET_64BIT && TARGET_CMOVE
15527 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15528 "@
15529 fcmov%F1\t{%2, %0|%0, %2}
15530 fcmov%f1\t{%3, %0|%0, %3}
15531 #
15532 #"
15533 [(set_attr "type" "fcmov,fcmov,multi,multi")
15534 (set_attr "mode" "DF")])
15535
15536 (define_insn "*movdfcc_1_rex64"
15537 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15538 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15539 [(reg 17) (const_int 0)])
15540 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15541 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15542 "TARGET_64BIT && TARGET_CMOVE
15543 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15544 "@
15545 fcmov%F1\t{%2, %0|%0, %2}
15546 fcmov%f1\t{%3, %0|%0, %3}
15547 cmov%O2%C1\t{%2, %0|%0, %2}
15548 cmov%O2%c1\t{%3, %0|%0, %3}"
15549 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15550 (set_attr "mode" "DF")])
15551
15552 (define_split
15553 [(set (match_operand:DF 0 "register_operand" "")
15554 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15555 [(match_operand 4 "" "") (const_int 0)])
15556 (match_operand:DF 2 "nonimmediate_operand" "")
15557 (match_operand:DF 3 "nonimmediate_operand" "")))]
15558 "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
15559 [(set (match_dup 2)
15560 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15561 (match_dup 5)
15562 (match_dup 7)))
15563 (set (match_dup 3)
15564 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15565 (match_dup 6)
15566 (match_dup 8)))]
15567 "split_di (operands+2, 1, operands+5, operands+6);
15568 split_di (operands+3, 1, operands+7, operands+8);
15569 split_di (operands, 1, operands+2, operands+3);")
15570
15571 (define_expand "movxfcc"
15572 [(set (match_operand:XF 0 "register_operand" "")
15573 (if_then_else:XF (match_operand 1 "comparison_operator" "")
15574 (match_operand:XF 2 "register_operand" "")
15575 (match_operand:XF 3 "register_operand" "")))]
15576 "!TARGET_64BIT && TARGET_CMOVE"
15577 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15578
15579 (define_expand "movtfcc"
15580 [(set (match_operand:TF 0 "register_operand" "")
15581 (if_then_else:TF (match_operand 1 "comparison_operator" "")
15582 (match_operand:TF 2 "register_operand" "")
15583 (match_operand:TF 3 "register_operand" "")))]
15584 "TARGET_CMOVE"
15585 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15586
15587 (define_insn "*movxfcc_1"
15588 [(set (match_operand:XF 0 "register_operand" "=f,f")
15589 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15590 [(reg 17) (const_int 0)])
15591 (match_operand:XF 2 "register_operand" "f,0")
15592 (match_operand:XF 3 "register_operand" "0,f")))]
15593 "!TARGET_64BIT && TARGET_CMOVE"
15594 "@
15595 fcmov%F1\t{%2, %0|%0, %2}
15596 fcmov%f1\t{%3, %0|%0, %3}"
15597 [(set_attr "type" "fcmov")
15598 (set_attr "mode" "XF")])
15599
15600 (define_insn "*movtfcc_1"
15601 [(set (match_operand:TF 0 "register_operand" "=f,f")
15602 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
15603 [(reg 17) (const_int 0)])
15604 (match_operand:TF 2 "register_operand" "f,0")
15605 (match_operand:TF 3 "register_operand" "0,f")))]
15606 "TARGET_CMOVE"
15607 "@
15608 fcmov%F1\t{%2, %0|%0, %2}
15609 fcmov%f1\t{%3, %0|%0, %3}"
15610 [(set_attr "type" "fcmov")
15611 (set_attr "mode" "XF")])
15612
15613 (define_expand "minsf3"
15614 [(parallel [
15615 (set (match_operand:SF 0 "register_operand" "")
15616 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15617 (match_operand:SF 2 "nonimmediate_operand" ""))
15618 (match_dup 1)
15619 (match_dup 2)))
15620 (clobber (reg:CC 17))])]
15621 "TARGET_SSE"
15622 "")
15623
15624 (define_insn "*minsf"
15625 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15626 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
15627 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15628 (match_dup 1)
15629 (match_dup 2)))
15630 (clobber (reg:CC 17))]
15631 "TARGET_SSE && TARGET_IEEE_FP"
15632 "#")
15633
15634 (define_insn "*minsf_nonieee"
15635 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15636 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
15637 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
15638 (match_dup 1)
15639 (match_dup 2)))
15640 (clobber (reg:CC 17))]
15641 "TARGET_SSE && !TARGET_IEEE_FP
15642 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15643 "#")
15644
15645 (define_split
15646 [(set (match_operand:SF 0 "register_operand" "")
15647 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15648 (match_operand:SF 2 "nonimmediate_operand" ""))
15649 (match_operand:SF 3 "register_operand" "")
15650 (match_operand:SF 4 "nonimmediate_operand" "")))
15651 (clobber (reg:CC 17))]
15652 "SSE_REG_P (operands[0]) && reload_completed
15653 && ((operands_match_p (operands[1], operands[3])
15654 && operands_match_p (operands[2], operands[4]))
15655 || (operands_match_p (operands[1], operands[4])
15656 && operands_match_p (operands[2], operands[3])))"
15657 [(set (match_dup 0)
15658 (if_then_else:SF (lt (match_dup 1)
15659 (match_dup 2))
15660 (match_dup 1)
15661 (match_dup 2)))])
15662
15663 ;; We can't represent the LT test directly. Do this by swapping the operands.
15664
15665 (define_split
15666 [(set (match_operand:SF 0 "register_operand" "")
15667 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15668 (match_operand:SF 2 "register_operand" ""))
15669 (match_operand:SF 3 "register_operand" "")
15670 (match_operand:SF 4 "register_operand" "")))
15671 (clobber (reg:CC 17))]
15672 "FP_REG_P (operands[0]) && reload_completed
15673 && ((operands_match_p (operands[1], operands[3])
15674 && operands_match_p (operands[2], operands[4]))
15675 || (operands_match_p (operands[1], operands[4])
15676 && operands_match_p (operands[2], operands[3])))"
15677 [(set (reg:CCFP 17)
15678 (compare:CCFP (match_dup 2)
15679 (match_dup 1)))
15680 (set (match_dup 0)
15681 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
15682 (match_dup 1)
15683 (match_dup 2)))])
15684
15685 (define_insn "*minsf_sse"
15686 [(set (match_operand:SF 0 "register_operand" "=x")
15687 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
15688 (match_operand:SF 2 "nonimmediate_operand" "xm"))
15689 (match_dup 1)
15690 (match_dup 2)))]
15691 "TARGET_SSE && reload_completed"
15692 "minss\t{%2, %0|%0, %2}"
15693 [(set_attr "type" "sse")
15694 (set_attr "mode" "SF")])
15695
15696 (define_expand "mindf3"
15697 [(parallel [
15698 (set (match_operand:DF 0 "register_operand" "")
15699 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15700 (match_operand:DF 2 "nonimmediate_operand" ""))
15701 (match_dup 1)
15702 (match_dup 2)))
15703 (clobber (reg:CC 17))])]
15704 "TARGET_SSE2 && TARGET_SSE_MATH"
15705 "#")
15706
15707 (define_insn "*mindf"
15708 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15709 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15710 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
15711 (match_dup 1)
15712 (match_dup 2)))
15713 (clobber (reg:CC 17))]
15714 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
15715 "#")
15716
15717 (define_insn "*mindf_nonieee"
15718 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15719 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
15720 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
15721 (match_dup 1)
15722 (match_dup 2)))
15723 (clobber (reg:CC 17))]
15724 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
15725 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15726 "#")
15727
15728 (define_split
15729 [(set (match_operand:DF 0 "register_operand" "")
15730 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15731 (match_operand:DF 2 "nonimmediate_operand" ""))
15732 (match_operand:DF 3 "register_operand" "")
15733 (match_operand:DF 4 "nonimmediate_operand" "")))
15734 (clobber (reg:CC 17))]
15735 "SSE_REG_P (operands[0]) && reload_completed
15736 && ((operands_match_p (operands[1], operands[3])
15737 && operands_match_p (operands[2], operands[4]))
15738 || (operands_match_p (operands[1], operands[4])
15739 && operands_match_p (operands[2], operands[3])))"
15740 [(set (match_dup 0)
15741 (if_then_else:DF (lt (match_dup 1)
15742 (match_dup 2))
15743 (match_dup 1)
15744 (match_dup 2)))])
15745
15746 ;; We can't represent the LT test directly. Do this by swapping the operands.
15747 (define_split
15748 [(set (match_operand:DF 0 "register_operand" "")
15749 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15750 (match_operand:DF 2 "register_operand" ""))
15751 (match_operand:DF 3 "register_operand" "")
15752 (match_operand:DF 4 "register_operand" "")))
15753 (clobber (reg:CC 17))]
15754 "FP_REG_P (operands[0]) && reload_completed
15755 && ((operands_match_p (operands[1], operands[3])
15756 && operands_match_p (operands[2], operands[4]))
15757 || (operands_match_p (operands[1], operands[4])
15758 && operands_match_p (operands[2], operands[3])))"
15759 [(set (reg:CCFP 17)
15760 (compare:CCFP (match_dup 2)
15761 (match_dup 2)))
15762 (set (match_dup 0)
15763 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
15764 (match_dup 1)
15765 (match_dup 2)))])
15766
15767 (define_insn "*mindf_sse"
15768 [(set (match_operand:DF 0 "register_operand" "=Y")
15769 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
15770 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
15771 (match_dup 1)
15772 (match_dup 2)))]
15773 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
15774 "minsd\t{%2, %0|%0, %2}"
15775 [(set_attr "type" "sse")
15776 (set_attr "mode" "DF")])
15777
15778 (define_expand "maxsf3"
15779 [(parallel [
15780 (set (match_operand:SF 0 "register_operand" "")
15781 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15782 (match_operand:SF 2 "nonimmediate_operand" ""))
15783 (match_dup 1)
15784 (match_dup 2)))
15785 (clobber (reg:CC 17))])]
15786 "TARGET_SSE"
15787 "#")
15788
15789 (define_insn "*maxsf"
15790 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15791 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
15792 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15793 (match_dup 1)
15794 (match_dup 2)))
15795 (clobber (reg:CC 17))]
15796 "TARGET_SSE && TARGET_IEEE_FP"
15797 "#")
15798
15799 (define_insn "*maxsf_nonieee"
15800 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15801 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
15802 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
15803 (match_dup 1)
15804 (match_dup 2)))
15805 (clobber (reg:CC 17))]
15806 "TARGET_SSE && !TARGET_IEEE_FP
15807 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15808 "#")
15809
15810 (define_split
15811 [(set (match_operand:SF 0 "register_operand" "")
15812 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15813 (match_operand:SF 2 "nonimmediate_operand" ""))
15814 (match_operand:SF 3 "register_operand" "")
15815 (match_operand:SF 4 "nonimmediate_operand" "")))
15816 (clobber (reg:CC 17))]
15817 "SSE_REG_P (operands[0]) && reload_completed
15818 && ((operands_match_p (operands[1], operands[3])
15819 && operands_match_p (operands[2], operands[4]))
15820 || (operands_match_p (operands[1], operands[4])
15821 && operands_match_p (operands[2], operands[3])))"
15822 [(set (match_dup 0)
15823 (if_then_else:SF (gt (match_dup 1)
15824 (match_dup 2))
15825 (match_dup 1)
15826 (match_dup 2)))])
15827
15828 (define_split
15829 [(set (match_operand:SF 0 "register_operand" "")
15830 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15831 (match_operand:SF 2 "register_operand" ""))
15832 (match_operand:SF 3 "register_operand" "")
15833 (match_operand:SF 4 "register_operand" "")))
15834 (clobber (reg:CC 17))]
15835 "FP_REG_P (operands[0]) && reload_completed
15836 && ((operands_match_p (operands[1], operands[3])
15837 && operands_match_p (operands[2], operands[4]))
15838 || (operands_match_p (operands[1], operands[4])
15839 && operands_match_p (operands[2], operands[3])))"
15840 [(set (reg:CCFP 17)
15841 (compare:CCFP (match_dup 1)
15842 (match_dup 2)))
15843 (set (match_dup 0)
15844 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
15845 (match_dup 1)
15846 (match_dup 2)))])
15847
15848 (define_insn "*maxsf_sse"
15849 [(set (match_operand:SF 0 "register_operand" "=x")
15850 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
15851 (match_operand:SF 2 "nonimmediate_operand" "xm"))
15852 (match_dup 1)
15853 (match_dup 2)))]
15854 "TARGET_SSE && reload_completed"
15855 "maxss\t{%2, %0|%0, %2}"
15856 [(set_attr "type" "sse")
15857 (set_attr "mode" "SF")])
15858
15859 (define_expand "maxdf3"
15860 [(parallel [
15861 (set (match_operand:DF 0 "register_operand" "")
15862 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15863 (match_operand:DF 2 "nonimmediate_operand" ""))
15864 (match_dup 1)
15865 (match_dup 2)))
15866 (clobber (reg:CC 17))])]
15867 "TARGET_SSE2 && TARGET_SSE_MATH"
15868 "#")
15869
15870 (define_insn "*maxdf"
15871 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15872 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15873 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
15874 (match_dup 1)
15875 (match_dup 2)))
15876 (clobber (reg:CC 17))]
15877 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
15878 "#")
15879
15880 (define_insn "*maxdf_nonieee"
15881 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15882 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
15883 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
15884 (match_dup 1)
15885 (match_dup 2)))
15886 (clobber (reg:CC 17))]
15887 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
15888 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15889 "#")
15890
15891 (define_split
15892 [(set (match_operand:DF 0 "register_operand" "")
15893 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15894 (match_operand:DF 2 "nonimmediate_operand" ""))
15895 (match_operand:DF 3 "register_operand" "")
15896 (match_operand:DF 4 "nonimmediate_operand" "")))
15897 (clobber (reg:CC 17))]
15898 "SSE_REG_P (operands[0]) && reload_completed
15899 && ((operands_match_p (operands[1], operands[3])
15900 && operands_match_p (operands[2], operands[4]))
15901 || (operands_match_p (operands[1], operands[4])
15902 && operands_match_p (operands[2], operands[3])))"
15903 [(set (match_dup 0)
15904 (if_then_else:DF (gt (match_dup 1)
15905 (match_dup 2))
15906 (match_dup 1)
15907 (match_dup 2)))])
15908
15909 (define_split
15910 [(set (match_operand:DF 0 "register_operand" "")
15911 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15912 (match_operand:DF 2 "register_operand" ""))
15913 (match_operand:DF 3 "register_operand" "")
15914 (match_operand:DF 4 "register_operand" "")))
15915 (clobber (reg:CC 17))]
15916 "FP_REG_P (operands[0]) && reload_completed
15917 && ((operands_match_p (operands[1], operands[3])
15918 && operands_match_p (operands[2], operands[4]))
15919 || (operands_match_p (operands[1], operands[4])
15920 && operands_match_p (operands[2], operands[3])))"
15921 [(set (reg:CCFP 17)
15922 (compare:CCFP (match_dup 1)
15923 (match_dup 2)))
15924 (set (match_dup 0)
15925 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
15926 (match_dup 1)
15927 (match_dup 2)))])
15928
15929 (define_insn "*maxdf_sse"
15930 [(set (match_operand:DF 0 "register_operand" "=Y")
15931 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
15932 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
15933 (match_dup 1)
15934 (match_dup 2)))]
15935 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
15936 "maxsd\t{%2, %0|%0, %2}"
15937 [(set_attr "type" "sse")
15938 (set_attr "mode" "DF")])
15939 \f
15940 ;; Misc patterns (?)
15941
15942 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
15943 ;; Otherwise there will be nothing to keep
15944 ;;
15945 ;; [(set (reg ebp) (reg esp))]
15946 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
15947 ;; (clobber (eflags)]
15948 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
15949 ;;
15950 ;; in proper program order.
15951 (define_expand "pro_epilogue_adjust_stack"
15952 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
15953 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
15954 (match_operand:SI 2 "immediate_operand" "i,i")))
15955 (clobber (reg:CC 17))
15956 (clobber (mem:BLK (scratch)))])]
15957 ""
15958 {
15959 if (TARGET_64BIT)
15960 {
15961 emit_insn (gen_pro_epilogue_adjust_stack_rex64
15962 (operands[0], operands[1], operands[2]));
15963 DONE;
15964 }
15965 })
15966
15967 (define_insn "*pro_epilogue_adjust_stack_1"
15968 [(set (match_operand:SI 0 "register_operand" "=r,r")
15969 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
15970 (match_operand:SI 2 "immediate_operand" "i,i")))
15971 (clobber (reg:CC 17))
15972 (clobber (mem:BLK (scratch)))]
15973 "!TARGET_64BIT"
15974 {
15975 switch (get_attr_type (insn))
15976 {
15977 case TYPE_IMOV:
15978 return "mov{l}\t{%1, %0|%0, %1}";
15979
15980 case TYPE_ALU:
15981 if (GET_CODE (operands[2]) == CONST_INT
15982 && (INTVAL (operands[2]) == 128
15983 || (INTVAL (operands[2]) < 0
15984 && INTVAL (operands[2]) != -128)))
15985 {
15986 operands[2] = GEN_INT (-INTVAL (operands[2]));
15987 return "sub{l}\t{%2, %0|%0, %2}";
15988 }
15989 return "add{l}\t{%2, %0|%0, %2}";
15990
15991 case TYPE_LEA:
15992 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
15993 return "lea{l}\t{%a2, %0|%0, %a2}";
15994
15995 default:
15996 abort ();
15997 }
15998 }
15999 [(set (attr "type")
16000 (cond [(eq_attr "alternative" "0")
16001 (const_string "alu")
16002 (match_operand:SI 2 "const0_operand" "")
16003 (const_string "imov")
16004 ]
16005 (const_string "lea")))
16006 (set_attr "mode" "SI")])
16007
16008 (define_insn "pro_epilogue_adjust_stack_rex64"
16009 [(set (match_operand:DI 0 "register_operand" "=r,r")
16010 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16011 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16012 (clobber (reg:CC 17))
16013 (clobber (mem:BLK (scratch)))]
16014 "TARGET_64BIT"
16015 {
16016 switch (get_attr_type (insn))
16017 {
16018 case TYPE_IMOV:
16019 return "mov{q}\t{%1, %0|%0, %1}";
16020
16021 case TYPE_ALU:
16022 if (GET_CODE (operands[2]) == CONST_INT
16023 && (INTVAL (operands[2]) == 128
16024 || (INTVAL (operands[2]) < 0
16025 && INTVAL (operands[2]) != -128)))
16026 {
16027 operands[2] = GEN_INT (-INTVAL (operands[2]));
16028 return "sub{q}\t{%2, %0|%0, %2}";
16029 }
16030 return "add{q}\t{%2, %0|%0, %2}";
16031
16032 case TYPE_LEA:
16033 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16034 return "lea{q}\t{%a2, %0|%0, %a2}";
16035
16036 default:
16037 abort ();
16038 }
16039 }
16040 [(set (attr "type")
16041 (cond [(eq_attr "alternative" "0")
16042 (const_string "alu")
16043 (match_operand:DI 2 "const0_operand" "")
16044 (const_string "imov")
16045 ]
16046 (const_string "lea")))
16047 (set_attr "mode" "DI")])
16048
16049
16050 ;; Placeholder for the conditional moves. This one is split either to SSE
16051 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16052 ;; fact is that compares supported by the cmp??ss instructions are exactly
16053 ;; swapped of those supported by cmove sequence.
16054 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16055 ;; supported by i387 comparisons and we do need to emit two conditional moves
16056 ;; in tandem.
16057
16058 (define_insn "sse_movsfcc"
16059 [(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")
16060 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16061 [(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")
16062 (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")])
16063 (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")
16064 (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")))
16065 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16066 (clobber (reg:CC 17))]
16067 "TARGET_SSE
16068 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16069 && (!TARGET_IEEE_FP
16070 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16071 "#")
16072
16073 (define_insn "sse_movsfcc_eq"
16074 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16075 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16076 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16077 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16078 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16079 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16080 (clobber (reg:CC 17))]
16081 "TARGET_SSE
16082 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16083 "#")
16084
16085 (define_insn "sse_movdfcc"
16086 [(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")
16087 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16088 [(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")
16089 (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")])
16090 (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")
16091 (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")))
16092 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16093 (clobber (reg:CC 17))]
16094 "TARGET_SSE2
16095 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16096 && (!TARGET_IEEE_FP
16097 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16098 "#")
16099
16100 (define_insn "sse_movdfcc_eq"
16101 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16102 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16103 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16104 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16105 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
16106 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16107 (clobber (reg:CC 17))]
16108 "TARGET_SSE
16109 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16110 "#")
16111
16112 ;; For non-sse moves just expand the usual cmove sequence.
16113 (define_split
16114 [(set (match_operand 0 "register_operand" "")
16115 (if_then_else (match_operator 1 "comparison_operator"
16116 [(match_operand 4 "nonimmediate_operand" "")
16117 (match_operand 5 "register_operand" "")])
16118 (match_operand 2 "nonimmediate_operand" "")
16119 (match_operand 3 "nonimmediate_operand" "")))
16120 (clobber (match_operand 6 "" ""))
16121 (clobber (reg:CC 17))]
16122 "!SSE_REG_P (operands[0]) && reload_completed
16123 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16124 [(const_int 0)]
16125 {
16126 ix86_compare_op0 = operands[5];
16127 ix86_compare_op1 = operands[4];
16128 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16129 VOIDmode, operands[5], operands[4]);
16130 ix86_expand_fp_movcc (operands);
16131 DONE;
16132 })
16133
16134 ;; Split SSE based conditional move into seqence:
16135 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
16136 ;; and op2, op0 - zero op2 if comparison was false
16137 ;; nand op0, op3 - load op3 to op0 if comparison was false
16138 ;; or op2, op0 - get the non-zero one into the result.
16139 (define_split
16140 [(set (match_operand 0 "register_operand" "")
16141 (if_then_else (match_operator 1 "sse_comparison_operator"
16142 [(match_operand 4 "register_operand" "")
16143 (match_operand 5 "nonimmediate_operand" "")])
16144 (match_operand 2 "register_operand" "")
16145 (match_operand 3 "register_operand" "")))
16146 (clobber (match_operand 6 "" ""))
16147 (clobber (reg:CC 17))]
16148 "SSE_REG_P (operands[0]) && reload_completed"
16149 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16150 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
16151 (subreg:TI (match_dup 4) 0)))
16152 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
16153 (subreg:TI (match_dup 3) 0)))
16154 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16155 (subreg:TI (match_dup 7) 0)))]
16156 {
16157 /* If op2 == op3, op3 will be clobbered before it is used.
16158 This should be optimized out though. */
16159 if (operands_match_p (operands[2], operands[3]))
16160 abort ();
16161 PUT_MODE (operands[1], GET_MODE (operands[0]));
16162 if (operands_match_p (operands[0], operands[4]))
16163 operands[6] = operands[4], operands[7] = operands[2];
16164 else
16165 operands[6] = operands[2], operands[7] = operands[4];
16166 })
16167
16168 ;; Special case of conditional move we can handle effectivly.
16169 ;; Do not brother with the integer/floating point case, since these are
16170 ;; bot considerably slower, unlike in the generic case.
16171 (define_insn "*sse_movsfcc_const0_1"
16172 [(set (match_operand:SF 0 "register_operand" "=&x")
16173 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16174 [(match_operand:SF 4 "register_operand" "0")
16175 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16176 (match_operand:SF 2 "register_operand" "x")
16177 (match_operand:SF 3 "const0_operand" "X")))]
16178 "TARGET_SSE"
16179 "#")
16180
16181 (define_insn "*sse_movsfcc_const0_2"
16182 [(set (match_operand:SF 0 "register_operand" "=&x")
16183 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16184 [(match_operand:SF 4 "register_operand" "0")
16185 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16186 (match_operand:SF 2 "const0_operand" "X")
16187 (match_operand:SF 3 "register_operand" "x")))]
16188 "TARGET_SSE"
16189 "#")
16190
16191 (define_insn "*sse_movsfcc_const0_3"
16192 [(set (match_operand:SF 0 "register_operand" "=&x")
16193 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16194 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16195 (match_operand:SF 5 "register_operand" "0")])
16196 (match_operand:SF 2 "register_operand" "x")
16197 (match_operand:SF 3 "const0_operand" "X")))]
16198 "TARGET_SSE"
16199 "#")
16200
16201 (define_insn "*sse_movsfcc_const0_4"
16202 [(set (match_operand:SF 0 "register_operand" "=&x")
16203 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16204 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16205 (match_operand:SF 5 "register_operand" "0")])
16206 (match_operand:SF 2 "const0_operand" "X")
16207 (match_operand:SF 3 "register_operand" "x")))]
16208 "TARGET_SSE"
16209 "#")
16210
16211 (define_insn "*sse_movdfcc_const0_1"
16212 [(set (match_operand:DF 0 "register_operand" "=&Y")
16213 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16214 [(match_operand:DF 4 "register_operand" "0")
16215 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16216 (match_operand:DF 2 "register_operand" "Y")
16217 (match_operand:DF 3 "const0_operand" "X")))]
16218 "TARGET_SSE2"
16219 "#")
16220
16221 (define_insn "*sse_movdfcc_const0_2"
16222 [(set (match_operand:DF 0 "register_operand" "=&Y")
16223 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16224 [(match_operand:DF 4 "register_operand" "0")
16225 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16226 (match_operand:DF 2 "const0_operand" "X")
16227 (match_operand:DF 3 "register_operand" "Y")))]
16228 "TARGET_SSE2"
16229 "#")
16230
16231 (define_insn "*sse_movdfcc_const0_3"
16232 [(set (match_operand:DF 0 "register_operand" "=&Y")
16233 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16234 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
16235 (match_operand:DF 5 "register_operand" "0")])
16236 (match_operand:DF 2 "register_operand" "Y")
16237 (match_operand:DF 3 "const0_operand" "X")))]
16238 "TARGET_SSE2"
16239 "#")
16240
16241 (define_insn "*sse_movdfcc_const0_4"
16242 [(set (match_operand:DF 0 "register_operand" "=&Y")
16243 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16244 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
16245 (match_operand:DF 5 "register_operand" "0")])
16246 (match_operand:DF 2 "const0_operand" "X")
16247 (match_operand:DF 3 "register_operand" "Y")))]
16248 "TARGET_SSE2"
16249 "#")
16250
16251 (define_split
16252 [(set (match_operand 0 "register_operand" "")
16253 (if_then_else (match_operator 1 "comparison_operator"
16254 [(match_operand 4 "register_operand" "")
16255 (match_operand 5 "nonimmediate_operand" "")])
16256 (match_operand 2 "nonmemory_operand" "")
16257 (match_operand 3 "nonmemory_operand" "")))]
16258 "SSE_REG_P (operands[0]) && reload_completed
16259 && (const0_operand (operands[2], GET_MODE (operands[0]))
16260 || const0_operand (operands[3], GET_MODE (operands[0])))"
16261 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16262 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16263 (subreg:TI (match_dup 7) 0)))]
16264 {
16265 PUT_MODE (operands[1], GET_MODE (operands[0]));
16266 if (!sse_comparison_operator (operands[1], VOIDmode))
16267 {
16268 rtx tmp = operands[5];
16269 operands[5] = operands[4];
16270 operands[4] = tmp;
16271 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16272 }
16273 if (const0_operand (operands[2], GET_MODE (operands[0])))
16274 {
16275 operands[7] = operands[3];
16276 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16277 0));
16278 }
16279 else
16280 {
16281 operands[7] = operands[2];
16282 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16283 }
16284 })
16285
16286 (define_expand "allocate_stack_worker"
16287 [(match_operand:SI 0 "register_operand" "")]
16288 "TARGET_STACK_PROBE"
16289 {
16290 if (TARGET_64BIT)
16291 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16292 else
16293 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16294 DONE;
16295 })
16296
16297 (define_insn "allocate_stack_worker_1"
16298 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
16299 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
16300 (clobber (match_dup 0))
16301 (clobber (reg:CC 17))]
16302 "!TARGET_64BIT && TARGET_STACK_PROBE"
16303 "call\t__alloca"
16304 [(set_attr "type" "multi")
16305 (set_attr "length" "5")])
16306
16307 (define_insn "allocate_stack_worker_rex64"
16308 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
16309 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16310 (clobber (match_dup 0))
16311 (clobber (reg:CC 17))]
16312 "TARGET_64BIT && TARGET_STACK_PROBE"
16313 "call\t__alloca"
16314 [(set_attr "type" "multi")
16315 (set_attr "length" "5")])
16316
16317 (define_expand "allocate_stack"
16318 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16319 (minus:SI (reg:SI 7)
16320 (match_operand:SI 1 "general_operand" "")))
16321 (clobber (reg:CC 17))])
16322 (parallel [(set (reg:SI 7)
16323 (minus:SI (reg:SI 7) (match_dup 1)))
16324 (clobber (reg:CC 17))])]
16325 "TARGET_STACK_PROBE"
16326 {
16327 #ifdef CHECK_STACK_LIMIT
16328 if (GET_CODE (operands[1]) == CONST_INT
16329 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16330 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
16331 operands[1]));
16332 else
16333 #endif
16334 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
16335 operands[1])));
16336
16337 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16338 DONE;
16339 })
16340
16341 (define_expand "builtin_setjmp_receiver"
16342 [(label_ref (match_operand 0 "" ""))]
16343 "!TARGET_64BIT && flag_pic"
16344 {
16345 emit_insn (gen_set_got (pic_offset_table_rtx));
16346 DONE;
16347 })
16348 \f
16349 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16350
16351 (define_split
16352 [(set (match_operand 0 "register_operand" "")
16353 (match_operator 3 "promotable_binary_operator"
16354 [(match_operand 1 "register_operand" "")
16355 (match_operand 2 "aligned_operand" "")]))
16356 (clobber (reg:CC 17))]
16357 "! TARGET_PARTIAL_REG_STALL && reload_completed
16358 && ((GET_MODE (operands[0]) == HImode
16359 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
16360 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16361 || (GET_MODE (operands[0]) == QImode
16362 && (TARGET_PROMOTE_QImode || optimize_size)))"
16363 [(parallel [(set (match_dup 0)
16364 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16365 (clobber (reg:CC 17))])]
16366 "operands[0] = gen_lowpart (SImode, operands[0]);
16367 operands[1] = gen_lowpart (SImode, operands[1]);
16368 if (GET_CODE (operands[3]) != ASHIFT)
16369 operands[2] = gen_lowpart (SImode, operands[2]);
16370 PUT_MODE (operands[3], SImode);")
16371
16372 (define_split
16373 [(set (reg 17)
16374 (compare (and (match_operand 1 "aligned_operand" "")
16375 (match_operand 2 "const_int_operand" ""))
16376 (const_int 0)))
16377 (set (match_operand 0 "register_operand" "")
16378 (and (match_dup 1) (match_dup 2)))]
16379 "! TARGET_PARTIAL_REG_STALL && reload_completed
16380 && ix86_match_ccmode (insn, CCNOmode)
16381 && (GET_MODE (operands[0]) == HImode
16382 || (GET_MODE (operands[0]) == QImode
16383 && (TARGET_PROMOTE_QImode || optimize_size)))"
16384 [(parallel [(set (reg:CCNO 17)
16385 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16386 (const_int 0)))
16387 (set (match_dup 0)
16388 (and:SI (match_dup 1) (match_dup 2)))])]
16389 "operands[2]
16390 = gen_int_mode (INTVAL (operands[2])
16391 & GET_MODE_MASK (GET_MODE (operands[0])),
16392 SImode);
16393 operands[0] = gen_lowpart (SImode, operands[0]);
16394 operands[1] = gen_lowpart (SImode, operands[1]);")
16395
16396 (define_split
16397 [(set (reg 17)
16398 (compare (and (match_operand 0 "aligned_operand" "")
16399 (match_operand 1 "const_int_operand" ""))
16400 (const_int 0)))]
16401 "! TARGET_PARTIAL_REG_STALL && reload_completed
16402 && ix86_match_ccmode (insn, CCNOmode)
16403 && (GET_MODE (operands[0]) == HImode
16404 || (GET_MODE (operands[0]) == QImode
16405 && (TARGET_PROMOTE_QImode || optimize_size)))"
16406 [(set (reg:CCNO 17)
16407 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16408 (const_int 0)))]
16409 "operands[1]
16410 = gen_int_mode (INTVAL (operands[1])
16411 & GET_MODE_MASK (GET_MODE (operands[0])),
16412 SImode);
16413 operands[0] = gen_lowpart (SImode, operands[0]);")
16414
16415 (define_split
16416 [(set (match_operand 0 "register_operand" "")
16417 (neg (match_operand 1 "register_operand" "")))
16418 (clobber (reg:CC 17))]
16419 "! TARGET_PARTIAL_REG_STALL && reload_completed
16420 && (GET_MODE (operands[0]) == HImode
16421 || (GET_MODE (operands[0]) == QImode
16422 && (TARGET_PROMOTE_QImode || optimize_size)))"
16423 [(parallel [(set (match_dup 0)
16424 (neg:SI (match_dup 1)))
16425 (clobber (reg:CC 17))])]
16426 "operands[0] = gen_lowpart (SImode, operands[0]);
16427 operands[1] = gen_lowpart (SImode, operands[1]);")
16428
16429 (define_split
16430 [(set (match_operand 0 "register_operand" "")
16431 (not (match_operand 1 "register_operand" "")))]
16432 "! TARGET_PARTIAL_REG_STALL && reload_completed
16433 && (GET_MODE (operands[0]) == HImode
16434 || (GET_MODE (operands[0]) == QImode
16435 && (TARGET_PROMOTE_QImode || optimize_size)))"
16436 [(set (match_dup 0)
16437 (not:SI (match_dup 1)))]
16438 "operands[0] = gen_lowpart (SImode, operands[0]);
16439 operands[1] = gen_lowpart (SImode, operands[1]);")
16440
16441 (define_split
16442 [(set (match_operand 0 "register_operand" "")
16443 (if_then_else (match_operator 1 "comparison_operator"
16444 [(reg 17) (const_int 0)])
16445 (match_operand 2 "register_operand" "")
16446 (match_operand 3 "register_operand" "")))]
16447 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16448 && (GET_MODE (operands[0]) == HImode
16449 || (GET_MODE (operands[0]) == QImode
16450 && (TARGET_PROMOTE_QImode || optimize_size)))"
16451 [(set (match_dup 0)
16452 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16453 "operands[0] = gen_lowpart (SImode, operands[0]);
16454 operands[2] = gen_lowpart (SImode, operands[2]);
16455 operands[3] = gen_lowpart (SImode, operands[3]);")
16456
16457 \f
16458 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16459 ;; transform a complex memory operation into two memory to register operations.
16460
16461 ;; Don't push memory operands
16462 (define_peephole2
16463 [(set (match_operand:SI 0 "push_operand" "")
16464 (match_operand:SI 1 "memory_operand" ""))
16465 (match_scratch:SI 2 "r")]
16466 "! optimize_size && ! TARGET_PUSH_MEMORY"
16467 [(set (match_dup 2) (match_dup 1))
16468 (set (match_dup 0) (match_dup 2))]
16469 "")
16470
16471 (define_peephole2
16472 [(set (match_operand:DI 0 "push_operand" "")
16473 (match_operand:DI 1 "memory_operand" ""))
16474 (match_scratch:DI 2 "r")]
16475 "! optimize_size && ! TARGET_PUSH_MEMORY"
16476 [(set (match_dup 2) (match_dup 1))
16477 (set (match_dup 0) (match_dup 2))]
16478 "")
16479
16480 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16481 ;; SImode pushes.
16482 (define_peephole2
16483 [(set (match_operand:SF 0 "push_operand" "")
16484 (match_operand:SF 1 "memory_operand" ""))
16485 (match_scratch:SF 2 "r")]
16486 "! optimize_size && ! TARGET_PUSH_MEMORY"
16487 [(set (match_dup 2) (match_dup 1))
16488 (set (match_dup 0) (match_dup 2))]
16489 "")
16490
16491 (define_peephole2
16492 [(set (match_operand:HI 0 "push_operand" "")
16493 (match_operand:HI 1 "memory_operand" ""))
16494 (match_scratch:HI 2 "r")]
16495 "! optimize_size && ! TARGET_PUSH_MEMORY"
16496 [(set (match_dup 2) (match_dup 1))
16497 (set (match_dup 0) (match_dup 2))]
16498 "")
16499
16500 (define_peephole2
16501 [(set (match_operand:QI 0 "push_operand" "")
16502 (match_operand:QI 1 "memory_operand" ""))
16503 (match_scratch:QI 2 "q")]
16504 "! optimize_size && ! TARGET_PUSH_MEMORY"
16505 [(set (match_dup 2) (match_dup 1))
16506 (set (match_dup 0) (match_dup 2))]
16507 "")
16508
16509 ;; Don't move an immediate directly to memory when the instruction
16510 ;; gets too big.
16511 (define_peephole2
16512 [(match_scratch:SI 1 "r")
16513 (set (match_operand:SI 0 "memory_operand" "")
16514 (const_int 0))]
16515 "! optimize_size
16516 && ! TARGET_USE_MOV0
16517 && TARGET_SPLIT_LONG_MOVES
16518 && get_attr_length (insn) >= ix86_cost->large_insn
16519 && peep2_regno_dead_p (0, FLAGS_REG)"
16520 [(parallel [(set (match_dup 1) (const_int 0))
16521 (clobber (reg:CC 17))])
16522 (set (match_dup 0) (match_dup 1))]
16523 "")
16524
16525 (define_peephole2
16526 [(match_scratch:HI 1 "r")
16527 (set (match_operand:HI 0 "memory_operand" "")
16528 (const_int 0))]
16529 "! optimize_size
16530 && ! TARGET_USE_MOV0
16531 && TARGET_SPLIT_LONG_MOVES
16532 && get_attr_length (insn) >= ix86_cost->large_insn
16533 && peep2_regno_dead_p (0, FLAGS_REG)"
16534 [(parallel [(set (match_dup 2) (const_int 0))
16535 (clobber (reg:CC 17))])
16536 (set (match_dup 0) (match_dup 1))]
16537 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16538
16539 (define_peephole2
16540 [(match_scratch:QI 1 "q")
16541 (set (match_operand:QI 0 "memory_operand" "")
16542 (const_int 0))]
16543 "! optimize_size
16544 && ! TARGET_USE_MOV0
16545 && TARGET_SPLIT_LONG_MOVES
16546 && get_attr_length (insn) >= ix86_cost->large_insn
16547 && peep2_regno_dead_p (0, FLAGS_REG)"
16548 [(parallel [(set (match_dup 2) (const_int 0))
16549 (clobber (reg:CC 17))])
16550 (set (match_dup 0) (match_dup 1))]
16551 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16552
16553 (define_peephole2
16554 [(match_scratch:SI 2 "r")
16555 (set (match_operand:SI 0 "memory_operand" "")
16556 (match_operand:SI 1 "immediate_operand" ""))]
16557 "! optimize_size
16558 && get_attr_length (insn) >= ix86_cost->large_insn
16559 && TARGET_SPLIT_LONG_MOVES"
16560 [(set (match_dup 2) (match_dup 1))
16561 (set (match_dup 0) (match_dup 2))]
16562 "")
16563
16564 (define_peephole2
16565 [(match_scratch:HI 2 "r")
16566 (set (match_operand:HI 0 "memory_operand" "")
16567 (match_operand:HI 1 "immediate_operand" ""))]
16568 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16569 && TARGET_SPLIT_LONG_MOVES"
16570 [(set (match_dup 2) (match_dup 1))
16571 (set (match_dup 0) (match_dup 2))]
16572 "")
16573
16574 (define_peephole2
16575 [(match_scratch:QI 2 "q")
16576 (set (match_operand:QI 0 "memory_operand" "")
16577 (match_operand:QI 1 "immediate_operand" ""))]
16578 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16579 && TARGET_SPLIT_LONG_MOVES"
16580 [(set (match_dup 2) (match_dup 1))
16581 (set (match_dup 0) (match_dup 2))]
16582 "")
16583
16584 ;; Don't compare memory with zero, load and use a test instead.
16585 (define_peephole2
16586 [(set (reg 17)
16587 (compare (match_operand:SI 0 "memory_operand" "")
16588 (const_int 0)))
16589 (match_scratch:SI 3 "r")]
16590 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
16591 [(set (match_dup 3) (match_dup 0))
16592 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
16593 "")
16594
16595 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16596 ;; Don't split NOTs with a displacement operand, because resulting XOR
16597 ;; will not be pariable anyway.
16598 ;;
16599 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
16600 ;; represented using a modRM byte. The XOR replacement is long decoded,
16601 ;; so this split helps here as well.
16602 ;;
16603 ;; Note: Can't do this as a regular split because we can't get proper
16604 ;; lifetime information then.
16605
16606 (define_peephole2
16607 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16608 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16609 "!optimize_size
16610 && peep2_regno_dead_p (0, FLAGS_REG)
16611 && ((TARGET_PENTIUM
16612 && (GET_CODE (operands[0]) != MEM
16613 || !memory_displacement_operand (operands[0], SImode)))
16614 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
16615 [(parallel [(set (match_dup 0)
16616 (xor:SI (match_dup 1) (const_int -1)))
16617 (clobber (reg:CC 17))])]
16618 "")
16619
16620 (define_peephole2
16621 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16622 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16623 "!optimize_size
16624 && peep2_regno_dead_p (0, FLAGS_REG)
16625 && ((TARGET_PENTIUM
16626 && (GET_CODE (operands[0]) != MEM
16627 || !memory_displacement_operand (operands[0], HImode)))
16628 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
16629 [(parallel [(set (match_dup 0)
16630 (xor:HI (match_dup 1) (const_int -1)))
16631 (clobber (reg:CC 17))])]
16632 "")
16633
16634 (define_peephole2
16635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16636 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16637 "!optimize_size
16638 && peep2_regno_dead_p (0, FLAGS_REG)
16639 && ((TARGET_PENTIUM
16640 && (GET_CODE (operands[0]) != MEM
16641 || !memory_displacement_operand (operands[0], QImode)))
16642 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
16643 [(parallel [(set (match_dup 0)
16644 (xor:QI (match_dup 1) (const_int -1)))
16645 (clobber (reg:CC 17))])]
16646 "")
16647
16648 ;; Non pairable "test imm, reg" instructions can be translated to
16649 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16650 ;; byte opcode instead of two, have a short form for byte operands),
16651 ;; so do it for other CPUs as well. Given that the value was dead,
16652 ;; this should not create any new dependencies. Pass on the sub-word
16653 ;; versions if we're concerned about partial register stalls.
16654
16655 (define_peephole2
16656 [(set (reg 17)
16657 (compare (and:SI (match_operand:SI 0 "register_operand" "")
16658 (match_operand:SI 1 "immediate_operand" ""))
16659 (const_int 0)))]
16660 "ix86_match_ccmode (insn, CCNOmode)
16661 && (true_regnum (operands[0]) != 0
16662 || (GET_CODE (operands[1]) == CONST_INT
16663 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
16664 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16665 [(parallel
16666 [(set (reg:CCNO 17)
16667 (compare:CCNO (and:SI (match_dup 0)
16668 (match_dup 1))
16669 (const_int 0)))
16670 (set (match_dup 0)
16671 (and:SI (match_dup 0) (match_dup 1)))])]
16672 "")
16673
16674 ;; We don't need to handle HImode case, because it will be promoted to SImode
16675 ;; on ! TARGET_PARTIAL_REG_STALL
16676
16677 (define_peephole2
16678 [(set (reg 17)
16679 (compare (and:QI (match_operand:QI 0 "register_operand" "")
16680 (match_operand:QI 1 "immediate_operand" ""))
16681 (const_int 0)))]
16682 "! TARGET_PARTIAL_REG_STALL
16683 && ix86_match_ccmode (insn, CCNOmode)
16684 && true_regnum (operands[0]) != 0
16685 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16686 [(parallel
16687 [(set (reg:CCNO 17)
16688 (compare:CCNO (and:QI (match_dup 0)
16689 (match_dup 1))
16690 (const_int 0)))
16691 (set (match_dup 0)
16692 (and:QI (match_dup 0) (match_dup 1)))])]
16693 "")
16694
16695 (define_peephole2
16696 [(set (reg 17)
16697 (compare
16698 (and:SI
16699 (zero_extract:SI
16700 (match_operand 0 "ext_register_operand" "")
16701 (const_int 8)
16702 (const_int 8))
16703 (match_operand 1 "const_int_operand" ""))
16704 (const_int 0)))]
16705 "! TARGET_PARTIAL_REG_STALL
16706 && ix86_match_ccmode (insn, CCNOmode)
16707 && true_regnum (operands[0]) != 0
16708 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16709 [(parallel [(set (reg:CCNO 17)
16710 (compare:CCNO
16711 (and:SI
16712 (zero_extract:SI
16713 (match_dup 0)
16714 (const_int 8)
16715 (const_int 8))
16716 (match_dup 1))
16717 (const_int 0)))
16718 (set (zero_extract:SI (match_dup 0)
16719 (const_int 8)
16720 (const_int 8))
16721 (and:SI
16722 (zero_extract:SI
16723 (match_dup 0)
16724 (const_int 8)
16725 (const_int 8))
16726 (match_dup 1)))])]
16727 "")
16728
16729 ;; Don't do logical operations with memory inputs.
16730 (define_peephole2
16731 [(match_scratch:SI 2 "r")
16732 (parallel [(set (match_operand:SI 0 "register_operand" "")
16733 (match_operator:SI 3 "arith_or_logical_operator"
16734 [(match_dup 0)
16735 (match_operand:SI 1 "memory_operand" "")]))
16736 (clobber (reg:CC 17))])]
16737 "! optimize_size && ! TARGET_READ_MODIFY"
16738 [(set (match_dup 2) (match_dup 1))
16739 (parallel [(set (match_dup 0)
16740 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16741 (clobber (reg:CC 17))])]
16742 "")
16743
16744 (define_peephole2
16745 [(match_scratch:SI 2 "r")
16746 (parallel [(set (match_operand:SI 0 "register_operand" "")
16747 (match_operator:SI 3 "arith_or_logical_operator"
16748 [(match_operand:SI 1 "memory_operand" "")
16749 (match_dup 0)]))
16750 (clobber (reg:CC 17))])]
16751 "! optimize_size && ! TARGET_READ_MODIFY"
16752 [(set (match_dup 2) (match_dup 1))
16753 (parallel [(set (match_dup 0)
16754 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16755 (clobber (reg:CC 17))])]
16756 "")
16757
16758 ; Don't do logical operations with memory outputs
16759 ;
16760 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16761 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16762 ; the same decoder scheduling characteristics as the original.
16763
16764 (define_peephole2
16765 [(match_scratch:SI 2 "r")
16766 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16767 (match_operator:SI 3 "arith_or_logical_operator"
16768 [(match_dup 0)
16769 (match_operand:SI 1 "nonmemory_operand" "")]))
16770 (clobber (reg:CC 17))])]
16771 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16772 [(set (match_dup 2) (match_dup 0))
16773 (parallel [(set (match_dup 2)
16774 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16775 (clobber (reg:CC 17))])
16776 (set (match_dup 0) (match_dup 2))]
16777 "")
16778
16779 (define_peephole2
16780 [(match_scratch:SI 2 "r")
16781 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16782 (match_operator:SI 3 "arith_or_logical_operator"
16783 [(match_operand:SI 1 "nonmemory_operand" "")
16784 (match_dup 0)]))
16785 (clobber (reg:CC 17))])]
16786 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16787 [(set (match_dup 2) (match_dup 0))
16788 (parallel [(set (match_dup 2)
16789 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16790 (clobber (reg:CC 17))])
16791 (set (match_dup 0) (match_dup 2))]
16792 "")
16793
16794 ;; Attempt to always use XOR for zeroing registers.
16795 (define_peephole2
16796 [(set (match_operand 0 "register_operand" "")
16797 (const_int 0))]
16798 "(GET_MODE (operands[0]) == QImode
16799 || GET_MODE (operands[0]) == HImode
16800 || GET_MODE (operands[0]) == SImode
16801 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16802 && (! TARGET_USE_MOV0 || optimize_size)
16803 && peep2_regno_dead_p (0, FLAGS_REG)"
16804 [(parallel [(set (match_dup 0) (const_int 0))
16805 (clobber (reg:CC 17))])]
16806 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16807 true_regnum (operands[0]));")
16808
16809 (define_peephole2
16810 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16811 (const_int 0))]
16812 "(GET_MODE (operands[0]) == QImode
16813 || GET_MODE (operands[0]) == HImode)
16814 && (! TARGET_USE_MOV0 || optimize_size)
16815 && peep2_regno_dead_p (0, FLAGS_REG)"
16816 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16817 (clobber (reg:CC 17))])])
16818
16819 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
16820 (define_peephole2
16821 [(set (match_operand 0 "register_operand" "")
16822 (const_int -1))]
16823 "(GET_MODE (operands[0]) == HImode
16824 || GET_MODE (operands[0]) == SImode
16825 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16826 && (optimize_size || TARGET_PENTIUM)
16827 && peep2_regno_dead_p (0, FLAGS_REG)"
16828 [(parallel [(set (match_dup 0) (const_int -1))
16829 (clobber (reg:CC 17))])]
16830 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16831 true_regnum (operands[0]));")
16832
16833 ;; Attempt to convert simple leas to adds. These can be created by
16834 ;; move expanders.
16835 (define_peephole2
16836 [(set (match_operand:SI 0 "register_operand" "")
16837 (plus:SI (match_dup 0)
16838 (match_operand:SI 1 "nonmemory_operand" "")))]
16839 "peep2_regno_dead_p (0, FLAGS_REG)"
16840 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
16841 (clobber (reg:CC 17))])]
16842 "")
16843
16844 (define_peephole2
16845 [(set (match_operand:SI 0 "register_operand" "")
16846 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16847 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16848 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
16849 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16850 (clobber (reg:CC 17))])]
16851 "operands[2] = gen_lowpart (SImode, operands[2]);")
16852
16853 (define_peephole2
16854 [(set (match_operand:DI 0 "register_operand" "")
16855 (plus:DI (match_dup 0)
16856 (match_operand:DI 1 "x86_64_general_operand" "")))]
16857 "peep2_regno_dead_p (0, FLAGS_REG)"
16858 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
16859 (clobber (reg:CC 17))])]
16860 "")
16861
16862 (define_peephole2
16863 [(set (match_operand:SI 0 "register_operand" "")
16864 (mult:SI (match_dup 0)
16865 (match_operand:SI 1 "const_int_operand" "")))]
16866 "exact_log2 (INTVAL (operands[1])) >= 0
16867 && peep2_regno_dead_p (0, FLAGS_REG)"
16868 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16869 (clobber (reg:CC 17))])]
16870 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16871
16872 (define_peephole2
16873 [(set (match_operand:DI 0 "register_operand" "")
16874 (mult:DI (match_dup 0)
16875 (match_operand:DI 1 "const_int_operand" "")))]
16876 "exact_log2 (INTVAL (operands[1])) >= 0
16877 && peep2_regno_dead_p (0, FLAGS_REG)"
16878 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
16879 (clobber (reg:CC 17))])]
16880 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16881
16882 (define_peephole2
16883 [(set (match_operand:SI 0 "register_operand" "")
16884 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16885 (match_operand:DI 2 "const_int_operand" "")) 0))]
16886 "exact_log2 (INTVAL (operands[1])) >= 0
16887 && REGNO (operands[0]) == REGNO (operands[1])
16888 && peep2_regno_dead_p (0, FLAGS_REG)"
16889 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16890 (clobber (reg:CC 17))])]
16891 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16892
16893 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16894 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
16895 ;; many CPUs it is also faster, since special hardware to avoid esp
16896 ;; dependencies is present.
16897
16898 ;; While some of these conversions may be done using splitters, we use peepholes
16899 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
16900
16901 ;; Convert prologue esp subtractions to push.
16902 ;; We need register to push. In order to keep verify_flow_info happy we have
16903 ;; two choices
16904 ;; - use scratch and clobber it in order to avoid dependencies
16905 ;; - use already live register
16906 ;; We can't use the second way right now, since there is no reliable way how to
16907 ;; verify that given register is live. First choice will also most likely in
16908 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16909 ;; call clobbered registers are dead. We may want to use base pointer as an
16910 ;; alternative when no register is available later.
16911
16912 (define_peephole2
16913 [(match_scratch:SI 0 "r")
16914 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
16915 (clobber (reg:CC 17))
16916 (clobber (mem:BLK (scratch)))])]
16917 "optimize_size || !TARGET_SUB_ESP_4"
16918 [(clobber (match_dup 0))
16919 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16920 (clobber (mem:BLK (scratch)))])])
16921
16922 (define_peephole2
16923 [(match_scratch:SI 0 "r")
16924 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
16925 (clobber (reg:CC 17))
16926 (clobber (mem:BLK (scratch)))])]
16927 "optimize_size || !TARGET_SUB_ESP_8"
16928 [(clobber (match_dup 0))
16929 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16930 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16931 (clobber (mem:BLK (scratch)))])])
16932
16933 ;; Convert esp subtractions to push.
16934 (define_peephole2
16935 [(match_scratch:SI 0 "r")
16936 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
16937 (clobber (reg:CC 17))])]
16938 "optimize_size || !TARGET_SUB_ESP_4"
16939 [(clobber (match_dup 0))
16940 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
16941
16942 (define_peephole2
16943 [(match_scratch:SI 0 "r")
16944 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
16945 (clobber (reg:CC 17))])]
16946 "optimize_size || !TARGET_SUB_ESP_8"
16947 [(clobber (match_dup 0))
16948 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16949 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
16950
16951 ;; Convert epilogue deallocator to pop.
16952 (define_peephole2
16953 [(match_scratch:SI 0 "r")
16954 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16955 (clobber (reg:CC 17))
16956 (clobber (mem:BLK (scratch)))])]
16957 "optimize_size || !TARGET_ADD_ESP_4"
16958 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16959 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16960 (clobber (mem:BLK (scratch)))])]
16961 "")
16962
16963 ;; Two pops case is tricky, since pop causes dependency on destination register.
16964 ;; We use two registers if available.
16965 (define_peephole2
16966 [(match_scratch:SI 0 "r")
16967 (match_scratch:SI 1 "r")
16968 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16969 (clobber (reg:CC 17))
16970 (clobber (mem:BLK (scratch)))])]
16971 "optimize_size || !TARGET_ADD_ESP_8"
16972 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16973 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16974 (clobber (mem:BLK (scratch)))])
16975 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
16976 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16977 "")
16978
16979 (define_peephole2
16980 [(match_scratch:SI 0 "r")
16981 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16982 (clobber (reg:CC 17))
16983 (clobber (mem:BLK (scratch)))])]
16984 "optimize_size"
16985 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16986 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16987 (clobber (mem:BLK (scratch)))])
16988 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16989 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16990 "")
16991
16992 ;; Convert esp additions to pop.
16993 (define_peephole2
16994 [(match_scratch:SI 0 "r")
16995 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16996 (clobber (reg:CC 17))])]
16997 ""
16998 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16999 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17000 "")
17001
17002 ;; Two pops case is tricky, since pop causes dependency on destination register.
17003 ;; We use two registers if available.
17004 (define_peephole2
17005 [(match_scratch:SI 0 "r")
17006 (match_scratch:SI 1 "r")
17007 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17008 (clobber (reg:CC 17))])]
17009 ""
17010 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17011 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17012 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17013 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17014 "")
17015
17016 (define_peephole2
17017 [(match_scratch:SI 0 "r")
17018 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17019 (clobber (reg:CC 17))])]
17020 "optimize_size"
17021 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17022 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17023 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17024 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17025 "")
17026 \f
17027 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17028 ;; required and register dies.
17029 (define_peephole2
17030 [(set (reg 17)
17031 (compare (match_operand:SI 0 "register_operand" "")
17032 (match_operand:SI 1 "incdec_operand" "")))]
17033 "ix86_match_ccmode (insn, CCGCmode)
17034 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17035 [(parallel [(set (reg:CCGC 17)
17036 (compare:CCGC (match_dup 0)
17037 (match_dup 1)))
17038 (clobber (match_dup 0))])]
17039 "")
17040
17041 (define_peephole2
17042 [(set (reg 17)
17043 (compare (match_operand:HI 0 "register_operand" "")
17044 (match_operand:HI 1 "incdec_operand" "")))]
17045 "ix86_match_ccmode (insn, CCGCmode)
17046 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17047 [(parallel [(set (reg:CCGC 17)
17048 (compare:CCGC (match_dup 0)
17049 (match_dup 1)))
17050 (clobber (match_dup 0))])]
17051 "")
17052
17053 (define_peephole2
17054 [(set (reg 17)
17055 (compare (match_operand:QI 0 "register_operand" "")
17056 (match_operand:QI 1 "incdec_operand" "")))]
17057 "ix86_match_ccmode (insn, CCGCmode)
17058 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17059 [(parallel [(set (reg:CCGC 17)
17060 (compare:CCGC (match_dup 0)
17061 (match_dup 1)))
17062 (clobber (match_dup 0))])]
17063 "")
17064
17065 ;; Convert compares with 128 to shorter add -128
17066 (define_peephole2
17067 [(set (reg 17)
17068 (compare (match_operand:SI 0 "register_operand" "")
17069 (const_int 128)))]
17070 "ix86_match_ccmode (insn, CCGCmode)
17071 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17072 [(parallel [(set (reg:CCGC 17)
17073 (compare:CCGC (match_dup 0)
17074 (const_int 128)))
17075 (clobber (match_dup 0))])]
17076 "")
17077
17078 (define_peephole2
17079 [(set (reg 17)
17080 (compare (match_operand:HI 0 "register_operand" "")
17081 (const_int 128)))]
17082 "ix86_match_ccmode (insn, CCGCmode)
17083 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17084 [(parallel [(set (reg:CCGC 17)
17085 (compare:CCGC (match_dup 0)
17086 (const_int 128)))
17087 (clobber (match_dup 0))])]
17088 "")
17089 \f
17090 (define_peephole2
17091 [(match_scratch:DI 0 "r")
17092 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17093 (clobber (reg:CC 17))
17094 (clobber (mem:BLK (scratch)))])]
17095 "optimize_size || !TARGET_SUB_ESP_4"
17096 [(clobber (match_dup 0))
17097 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17098 (clobber (mem:BLK (scratch)))])])
17099
17100 (define_peephole2
17101 [(match_scratch:DI 0 "r")
17102 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17103 (clobber (reg:CC 17))
17104 (clobber (mem:BLK (scratch)))])]
17105 "optimize_size || !TARGET_SUB_ESP_8"
17106 [(clobber (match_dup 0))
17107 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17108 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17109 (clobber (mem:BLK (scratch)))])])
17110
17111 ;; Convert esp subtractions to push.
17112 (define_peephole2
17113 [(match_scratch:DI 0 "r")
17114 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17115 (clobber (reg:CC 17))])]
17116 "optimize_size || !TARGET_SUB_ESP_4"
17117 [(clobber (match_dup 0))
17118 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17119
17120 (define_peephole2
17121 [(match_scratch:DI 0 "r")
17122 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17123 (clobber (reg:CC 17))])]
17124 "optimize_size || !TARGET_SUB_ESP_8"
17125 [(clobber (match_dup 0))
17126 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17127 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17128
17129 ;; Convert epilogue deallocator to pop.
17130 (define_peephole2
17131 [(match_scratch:DI 0 "r")
17132 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17133 (clobber (reg:CC 17))
17134 (clobber (mem:BLK (scratch)))])]
17135 "optimize_size || !TARGET_ADD_ESP_4"
17136 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17137 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17138 (clobber (mem:BLK (scratch)))])]
17139 "")
17140
17141 ;; Two pops case is tricky, since pop causes dependency on destination register.
17142 ;; We use two registers if available.
17143 (define_peephole2
17144 [(match_scratch:DI 0 "r")
17145 (match_scratch:DI 1 "r")
17146 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17147 (clobber (reg:CC 17))
17148 (clobber (mem:BLK (scratch)))])]
17149 "optimize_size || !TARGET_ADD_ESP_8"
17150 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17151 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17152 (clobber (mem:BLK (scratch)))])
17153 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17154 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17155 "")
17156
17157 (define_peephole2
17158 [(match_scratch:DI 0 "r")
17159 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17160 (clobber (reg:CC 17))
17161 (clobber (mem:BLK (scratch)))])]
17162 "optimize_size"
17163 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17164 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17165 (clobber (mem:BLK (scratch)))])
17166 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17167 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17168 "")
17169
17170 ;; Convert esp additions to pop.
17171 (define_peephole2
17172 [(match_scratch:DI 0 "r")
17173 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17174 (clobber (reg:CC 17))])]
17175 ""
17176 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17177 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17178 "")
17179
17180 ;; Two pops case is tricky, since pop causes dependency on destination register.
17181 ;; We use two registers if available.
17182 (define_peephole2
17183 [(match_scratch:DI 0 "r")
17184 (match_scratch:DI 1 "r")
17185 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17186 (clobber (reg:CC 17))])]
17187 ""
17188 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17189 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17190 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17191 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17192 "")
17193
17194 (define_peephole2
17195 [(match_scratch:DI 0 "r")
17196 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17197 (clobber (reg:CC 17))])]
17198 "optimize_size"
17199 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17200 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17201 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17202 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17203 "")
17204 \f
17205 ;; Call-value patterns last so that the wildcard operand does not
17206 ;; disrupt insn-recog's switch tables.
17207
17208 (define_insn "*call_value_pop_0"
17209 [(set (match_operand 0 "" "")
17210 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17211 (match_operand:SI 2 "" "")))
17212 (set (reg:SI 7) (plus:SI (reg:SI 7)
17213 (match_operand:SI 3 "immediate_operand" "")))]
17214 "!TARGET_64BIT"
17215 {
17216 if (SIBLING_CALL_P (insn))
17217 return "jmp\t%P1";
17218 else
17219 return "call\t%P1";
17220 }
17221 [(set_attr "type" "callv")])
17222
17223 (define_insn "*call_value_pop_1"
17224 [(set (match_operand 0 "" "")
17225 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17226 (match_operand:SI 2 "" "")))
17227 (set (reg:SI 7) (plus:SI (reg:SI 7)
17228 (match_operand:SI 3 "immediate_operand" "i")))]
17229 "!TARGET_64BIT"
17230 {
17231 if (constant_call_address_operand (operands[1], QImode))
17232 {
17233 if (SIBLING_CALL_P (insn))
17234 return "jmp\t%P1";
17235 else
17236 return "call\t%P1";
17237 }
17238 if (SIBLING_CALL_P (insn))
17239 return "jmp\t%A1";
17240 else
17241 return "call\t%A1";
17242 }
17243 [(set_attr "type" "callv")])
17244
17245 (define_insn "*call_value_0"
17246 [(set (match_operand 0 "" "")
17247 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17248 (match_operand:SI 2 "" "")))]
17249 "!TARGET_64BIT"
17250 {
17251 if (SIBLING_CALL_P (insn))
17252 return "jmp\t%P1";
17253 else
17254 return "call\t%P1";
17255 }
17256 [(set_attr "type" "callv")])
17257
17258 (define_insn "*call_value_0_rex64"
17259 [(set (match_operand 0 "" "")
17260 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17261 (match_operand:DI 2 "const_int_operand" "")))]
17262 "TARGET_64BIT"
17263 {
17264 if (SIBLING_CALL_P (insn))
17265 return "jmp\t%P1";
17266 else
17267 return "call\t%P1";
17268 }
17269 [(set_attr "type" "callv")])
17270
17271 (define_insn "*call_value_1"
17272 [(set (match_operand 0 "" "")
17273 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17274 (match_operand:SI 2 "" "")))]
17275 "!TARGET_64BIT"
17276 {
17277 if (constant_call_address_operand (operands[1], QImode))
17278 {
17279 if (SIBLING_CALL_P (insn))
17280 return "jmp\t%P1";
17281 else
17282 return "call\t%P1";
17283 }
17284 if (SIBLING_CALL_P (insn))
17285 return "jmp\t%*%1";
17286 else
17287 return "call\t%*%1";
17288 }
17289 [(set_attr "type" "callv")])
17290
17291 (define_insn "*call_value_1_rex64"
17292 [(set (match_operand 0 "" "")
17293 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17294 (match_operand:DI 2 "" "")))]
17295 "TARGET_64BIT"
17296 {
17297 if (constant_call_address_operand (operands[1], QImode))
17298 {
17299 if (SIBLING_CALL_P (insn))
17300 return "jmp\t%P1";
17301 else
17302 return "call\t%P1";
17303 }
17304 if (SIBLING_CALL_P (insn))
17305 return "jmp\t%A1";
17306 else
17307 return "call\t%A1";
17308 }
17309 [(set_attr "type" "callv")])
17310 \f
17311 (define_insn "trap"
17312 [(trap_if (const_int 1) (const_int 5))]
17313 ""
17314 "int\t$5")
17315
17316 ;;; ix86 doesn't have conditional trap instructions, but we fake them
17317 ;;; for the sake of bounds checking. By emitting bounds checks as
17318 ;;; conditional traps rather than as conditional jumps around
17319 ;;; unconditional traps we avoid introducing spurious basic-block
17320 ;;; boundaries and facilitate elimination of redundant checks. In
17321 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17322 ;;; interrupt 5.
17323 ;;;
17324 ;;; FIXME: Static branch prediction rules for ix86 are such that
17325 ;;; forward conditional branches predict as untaken. As implemented
17326 ;;; below, pseudo conditional traps violate that rule. We should use
17327 ;;; .pushsection/.popsection to place all of the `int 5's in a special
17328 ;;; section loaded at the end of the text segment and branch forward
17329 ;;; there on bounds-failure, and then jump back immediately (in case
17330 ;;; the system chooses to ignore bounds violations, or to report
17331 ;;; violations and continue execution).
17332
17333 (define_expand "conditional_trap"
17334 [(trap_if (match_operator 0 "comparison_operator"
17335 [(match_dup 2) (const_int 0)])
17336 (match_operand 1 "const_int_operand" ""))]
17337 ""
17338 {
17339 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
17340 ix86_expand_compare (GET_CODE (operands[0]),
17341 NULL, NULL),
17342 operands[1]));
17343 DONE;
17344 })
17345
17346 (define_insn "*conditional_trap_1"
17347 [(trap_if (match_operator 0 "comparison_operator"
17348 [(reg 17) (const_int 0)])
17349 (match_operand 1 "const_int_operand" ""))]
17350 ""
17351 {
17352 operands[2] = gen_label_rtx ();
17353 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
17354 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
17355 CODE_LABEL_NUMBER (operands[2]));
17356 RET;
17357 })
17358
17359 ;; Pentium III SIMD instructions.
17360
17361 ;; Moves for SSE/MMX regs.
17362
17363 (define_insn "movv4sf_internal"
17364 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17365 (match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
17366 "TARGET_SSE"
17367 ;; @@@ let's try to use movaps here.
17368 "movaps\t{%1, %0|%0, %1}"
17369 [(set_attr "type" "ssemov")
17370 (set_attr "mode" "V4SF")])
17371
17372 (define_insn "movv4si_internal"
17373 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17374 (match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
17375 "TARGET_SSE"
17376 ;; @@@ let's try to use movaps here.
17377 "movaps\t{%1, %0|%0, %1}"
17378 [(set_attr "type" "ssemov")
17379 (set_attr "mode" "V4SF")])
17380
17381 (define_insn "movv8qi_internal"
17382 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17383 (match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
17384 "TARGET_MMX"
17385 "movq\t{%1, %0|%0, %1}"
17386 [(set_attr "type" "mmxmov")
17387 (set_attr "mode" "DI")])
17388
17389 (define_insn "movv4hi_internal"
17390 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17391 (match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
17392 "TARGET_MMX"
17393 "movq\t{%1, %0|%0, %1}"
17394 [(set_attr "type" "mmxmov")
17395 (set_attr "mode" "DI")])
17396
17397 (define_insn "movv2si_internal"
17398 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17399 (match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
17400 "TARGET_MMX"
17401 "movq\t{%1, %0|%0, %1}"
17402 [(set_attr "type" "mmxcvt")
17403 (set_attr "mode" "DI")])
17404
17405 (define_insn "movv2sf_internal"
17406 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
17407 (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
17408 "TARGET_3DNOW"
17409 "movq\\t{%1, %0|%0, %1}"
17410 [(set_attr "type" "mmxcvt")
17411 (set_attr "mode" "DI")])
17412
17413 (define_expand "movti"
17414 [(set (match_operand:TI 0 "general_operand" "")
17415 (match_operand:TI 1 "general_operand" ""))]
17416 "TARGET_SSE || TARGET_64BIT"
17417 {
17418 if (TARGET_64BIT)
17419 ix86_expand_move (TImode, operands);
17420 else
17421 ix86_expand_vector_move (TImode, operands);
17422 DONE;
17423 })
17424
17425 (define_insn "movv2df_internal"
17426 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
17427 (match_operand:V2DF 1 "general_operand" "xm,x"))]
17428 "TARGET_SSE2"
17429 ;; @@@ let's try to use movaps here.
17430 "movapd\t{%1, %0|%0, %1}"
17431 [(set_attr "type" "ssemov")
17432 (set_attr "mode" "V2DF")])
17433
17434 (define_insn "movv8hi_internal"
17435 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
17436 (match_operand:V8HI 1 "general_operand" "xm,x"))]
17437 "TARGET_SSE2"
17438 ;; @@@ let's try to use movaps here.
17439 "movaps\t{%1, %0|%0, %1}"
17440 [(set_attr "type" "ssemov")
17441 (set_attr "mode" "V4SF")])
17442
17443 (define_insn "movv16qi_internal"
17444 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
17445 (match_operand:V16QI 1 "general_operand" "xm,x"))]
17446 "TARGET_SSE2"
17447 ;; @@@ let's try to use movaps here.
17448 "movaps\t{%1, %0|%0, %1}"
17449 [(set_attr "type" "ssemov")
17450 (set_attr "mode" "V4SF")])
17451
17452 (define_expand "movv2df"
17453 [(set (match_operand:V2DF 0 "general_operand" "")
17454 (match_operand:V2DF 1 "general_operand" ""))]
17455 "TARGET_SSE2"
17456 {
17457 ix86_expand_vector_move (V2DFmode, operands);
17458 DONE;
17459 })
17460
17461 (define_expand "movv8hi"
17462 [(set (match_operand:V8HI 0 "general_operand" "")
17463 (match_operand:V8HI 1 "general_operand" ""))]
17464 "TARGET_SSE2"
17465 {
17466 ix86_expand_vector_move (V8HImode, operands);
17467 DONE;
17468 })
17469
17470 (define_expand "movv16qi"
17471 [(set (match_operand:V16QI 0 "general_operand" "")
17472 (match_operand:V16QI 1 "general_operand" ""))]
17473 "TARGET_SSE2"
17474 {
17475 ix86_expand_vector_move (V16QImode, operands);
17476 DONE;
17477 })
17478
17479 (define_expand "movv4sf"
17480 [(set (match_operand:V4SF 0 "general_operand" "")
17481 (match_operand:V4SF 1 "general_operand" ""))]
17482 "TARGET_SSE"
17483 {
17484 ix86_expand_vector_move (V4SFmode, operands);
17485 DONE;
17486 })
17487
17488 (define_expand "movv4si"
17489 [(set (match_operand:V4SI 0 "general_operand" "")
17490 (match_operand:V4SI 1 "general_operand" ""))]
17491 "TARGET_MMX"
17492 {
17493 ix86_expand_vector_move (V4SImode, operands);
17494 DONE;
17495 })
17496
17497 (define_expand "movv2si"
17498 [(set (match_operand:V2SI 0 "general_operand" "")
17499 (match_operand:V2SI 1 "general_operand" ""))]
17500 "TARGET_MMX"
17501 {
17502 ix86_expand_vector_move (V2SImode, operands);
17503 DONE;
17504 })
17505
17506 (define_expand "movv4hi"
17507 [(set (match_operand:V4HI 0 "general_operand" "")
17508 (match_operand:V4HI 1 "general_operand" ""))]
17509 "TARGET_MMX"
17510 {
17511 ix86_expand_vector_move (V4HImode, operands);
17512 DONE;
17513 })
17514
17515 (define_expand "movv8qi"
17516 [(set (match_operand:V8QI 0 "general_operand" "")
17517 (match_operand:V8QI 1 "general_operand" ""))]
17518 "TARGET_MMX"
17519 {
17520 ix86_expand_vector_move (V8QImode, operands);
17521 DONE;
17522 })
17523
17524 (define_expand "movv2sf"
17525 [(set (match_operand:V2SF 0 "general_operand" "")
17526 (match_operand:V2SF 1 "general_operand" ""))]
17527 "TARGET_3DNOW"
17528 {
17529 ix86_expand_vector_move (V2SFmode, operands);
17530 DONE;
17531 })
17532
17533 (define_insn_and_split "*pushti"
17534 [(set (match_operand:TI 0 "push_operand" "=<")
17535 (match_operand:TI 1 "nonmemory_operand" "x"))]
17536 "TARGET_SSE"
17537 "#"
17538 ""
17539 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17540 (set (mem:TI (reg:SI 7)) (match_dup 1))]
17541 ""
17542 [(set_attr "type" "multi")])
17543
17544 (define_insn_and_split "*pushv2df"
17545 [(set (match_operand:V2DF 0 "push_operand" "=<")
17546 (match_operand:V2DF 1 "nonmemory_operand" "x"))]
17547 "TARGET_SSE2"
17548 "#"
17549 ""
17550 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17551 (set (mem:V2DF (reg:SI 7)) (match_dup 1))]
17552 ""
17553 [(set_attr "type" "multi")])
17554
17555 (define_insn_and_split "*pushv8hi"
17556 [(set (match_operand:V8HI 0 "push_operand" "=<")
17557 (match_operand:V8HI 1 "nonmemory_operand" "x"))]
17558 "TARGET_SSE2"
17559 "#"
17560 ""
17561 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17562 (set (mem:V8HI (reg:SI 7)) (match_dup 1))]
17563 ""
17564 [(set_attr "type" "multi")])
17565
17566 (define_insn_and_split "*pushv16qi"
17567 [(set (match_operand:V16QI 0 "push_operand" "=<")
17568 (match_operand:V16QI 1 "nonmemory_operand" "x"))]
17569 "TARGET_SSE2"
17570 "#"
17571 ""
17572 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17573 (set (mem:V16QI (reg:SI 7)) (match_dup 1))]
17574 ""
17575 [(set_attr "type" "multi")])
17576
17577 (define_insn_and_split "*pushv4sf"
17578 [(set (match_operand:V4SF 0 "push_operand" "=<")
17579 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
17580 "TARGET_SSE"
17581 "#"
17582 ""
17583 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17584 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17585 ""
17586 [(set_attr "type" "multi")])
17587
17588 (define_insn_and_split "*pushv4si"
17589 [(set (match_operand:V4SI 0 "push_operand" "=<")
17590 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
17591 "TARGET_SSE"
17592 "#"
17593 ""
17594 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17595 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17596 ""
17597 [(set_attr "type" "multi")])
17598
17599 (define_insn_and_split "*pushv2si"
17600 [(set (match_operand:V2SI 0 "push_operand" "=<")
17601 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
17602 "TARGET_MMX"
17603 "#"
17604 ""
17605 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17606 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
17607 ""
17608 [(set_attr "type" "mmx")])
17609
17610 (define_insn_and_split "*pushv4hi"
17611 [(set (match_operand:V4HI 0 "push_operand" "=<")
17612 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
17613 "TARGET_MMX"
17614 "#"
17615 ""
17616 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17617 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
17618 ""
17619 [(set_attr "type" "mmx")])
17620
17621 (define_insn_and_split "*pushv8qi"
17622 [(set (match_operand:V8QI 0 "push_operand" "=<")
17623 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
17624 "TARGET_MMX"
17625 "#"
17626 ""
17627 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17628 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
17629 ""
17630 [(set_attr "type" "mmx")])
17631
17632 (define_insn_and_split "*pushv2sf"
17633 [(set (match_operand:V2SF 0 "push_operand" "=<")
17634 (match_operand:V2SF 1 "nonmemory_operand" "y"))]
17635 "TARGET_3DNOW"
17636 "#"
17637 ""
17638 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17639 (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
17640 ""
17641 [(set_attr "type" "mmx")])
17642
17643 (define_insn "movti_internal"
17644 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
17645 (match_operand:TI 1 "general_operand" "O,xm,x"))]
17646 "TARGET_SSE && !TARGET_64BIT"
17647 "@
17648 xorps\t%0, %0
17649 movaps\t{%1, %0|%0, %1}
17650 movaps\t{%1, %0|%0, %1}"
17651 [(set_attr "type" "ssemov,ssemov,ssemov")
17652 (set_attr "mode" "V4SF")])
17653
17654 (define_insn "*movti_rex64"
17655 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
17656 (match_operand:TI 1 "general_operand" "riFo,riF,O,x,m"))]
17657 "TARGET_64BIT
17658 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
17659 "@
17660 #
17661 #
17662 xorps\t%0, %0
17663 movaps\\t{%1, %0|%0, %1}
17664 movaps\\t{%1, %0|%0, %1}"
17665 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
17666 (set_attr "mode" "V4SF")])
17667
17668 (define_split
17669 [(set (match_operand:TI 0 "nonimmediate_operand" "")
17670 (match_operand:TI 1 "general_operand" ""))]
17671 "reload_completed && !SSE_REG_P (operands[0])
17672 && !SSE_REG_P (operands[1])"
17673 [(const_int 0)]
17674 "ix86_split_long_move (operands); DONE;")
17675
17676 ;; These two patterns are useful for specifying exactly whether to use
17677 ;; movaps or movups
17678 (define_insn "sse_movaps"
17679 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17680 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
17681 UNSPEC_MOVA))]
17682 "TARGET_SSE"
17683 "@
17684 movaps\t{%1, %0|%0, %1}
17685 movaps\t{%1, %0|%0, %1}"
17686 [(set_attr "type" "ssemov,ssemov")
17687 (set_attr "mode" "V4SF")])
17688
17689 (define_insn "sse_movups"
17690 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17691 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
17692 UNSPEC_MOVU))]
17693 "TARGET_SSE"
17694 "@
17695 movups\t{%1, %0|%0, %1}
17696 movups\t{%1, %0|%0, %1}"
17697 [(set_attr "type" "ssecvt,ssecvt")
17698 (set_attr "mode" "V4SF")])
17699
17700
17701 ;; SSE Strange Moves.
17702
17703 (define_insn "sse_movmskps"
17704 [(set (match_operand:SI 0 "register_operand" "=r")
17705 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
17706 UNSPEC_MOVMSK))]
17707 "TARGET_SSE"
17708 "movmskps\t{%1, %0|%0, %1}"
17709 [(set_attr "type" "ssecvt")
17710 (set_attr "mode" "V4SF")])
17711
17712 (define_insn "mmx_pmovmskb"
17713 [(set (match_operand:SI 0 "register_operand" "=r")
17714 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
17715 UNSPEC_MOVMSK))]
17716 "TARGET_SSE || TARGET_3DNOW_A"
17717 "pmovmskb\t{%1, %0|%0, %1}"
17718 [(set_attr "type" "ssecvt")
17719 (set_attr "mode" "V4SF")])
17720
17721
17722 (define_insn "mmx_maskmovq"
17723 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
17724 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
17725 (match_operand:V8QI 2 "register_operand" "y")]
17726 UNSPEC_MASKMOV))]
17727 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
17728 ;; @@@ check ordering of operands in intel/nonintel syntax
17729 "maskmovq\t{%2, %1|%1, %2}"
17730 [(set_attr "type" "mmxcvt")
17731 (set_attr "mode" "DI")])
17732
17733 (define_insn "mmx_maskmovq_rex"
17734 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
17735 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
17736 (match_operand:V8QI 2 "register_operand" "y")]
17737 UNSPEC_MASKMOV))]
17738 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
17739 ;; @@@ check ordering of operands in intel/nonintel syntax
17740 "maskmovq\t{%2, %1|%1, %2}"
17741 [(set_attr "type" "mmxcvt")
17742 (set_attr "mode" "DI")])
17743
17744 (define_insn "sse_movntv4sf"
17745 [(set (match_operand:V4SF 0 "memory_operand" "=m")
17746 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
17747 UNSPEC_MOVNT))]
17748 "TARGET_SSE"
17749 "movntps\t{%1, %0|%0, %1}"
17750 [(set_attr "type" "ssemov")
17751 (set_attr "mode" "V4SF")])
17752
17753 (define_insn "sse_movntdi"
17754 [(set (match_operand:DI 0 "memory_operand" "=m")
17755 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
17756 UNSPEC_MOVNT))]
17757 "TARGET_SSE || TARGET_3DNOW_A"
17758 "movntq\t{%1, %0|%0, %1}"
17759 [(set_attr "type" "mmxmov")
17760 (set_attr "mode" "DI")])
17761
17762 (define_insn "sse_movhlps"
17763 [(set (match_operand:V4SF 0 "register_operand" "=x")
17764 (vec_merge:V4SF
17765 (match_operand:V4SF 1 "register_operand" "0")
17766 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17767 (parallel [(const_int 2)
17768 (const_int 3)
17769 (const_int 0)
17770 (const_int 1)]))
17771 (const_int 3)))]
17772 "TARGET_SSE"
17773 "movhlps\t{%2, %0|%0, %2}"
17774 [(set_attr "type" "ssecvt")
17775 (set_attr "mode" "V4SF")])
17776
17777 (define_insn "sse_movlhps"
17778 [(set (match_operand:V4SF 0 "register_operand" "=x")
17779 (vec_merge:V4SF
17780 (match_operand:V4SF 1 "register_operand" "0")
17781 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17782 (parallel [(const_int 2)
17783 (const_int 3)
17784 (const_int 0)
17785 (const_int 1)]))
17786 (const_int 12)))]
17787 "TARGET_SSE"
17788 "movlhps\t{%2, %0|%0, %2}"
17789 [(set_attr "type" "ssecvt")
17790 (set_attr "mode" "V4SF")])
17791
17792 (define_insn "sse_movhps"
17793 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17794 (vec_merge:V4SF
17795 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17796 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17797 (const_int 12)))]
17798 "TARGET_SSE
17799 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
17800 "movhps\t{%2, %0|%0, %2}"
17801 [(set_attr "type" "ssecvt")
17802 (set_attr "mode" "V4SF")])
17803
17804 (define_insn "sse_movlps"
17805 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17806 (vec_merge:V4SF
17807 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17808 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17809 (const_int 3)))]
17810 "TARGET_SSE
17811 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
17812 "movlps\t{%2, %0|%0, %2}"
17813 [(set_attr "type" "ssecvt")
17814 (set_attr "mode" "V4SF")])
17815
17816 (define_insn "sse_loadss"
17817 [(set (match_operand:V4SF 0 "register_operand" "=x")
17818 (vec_merge:V4SF
17819 (match_operand:V4SF 1 "memory_operand" "m")
17820 (vec_duplicate:V4SF (float:SF (const_int 0)))
17821 (const_int 1)))]
17822 "TARGET_SSE"
17823 "movss\t{%1, %0|%0, %1}"
17824 [(set_attr "type" "ssemov")
17825 (set_attr "mode" "SF")])
17826
17827 (define_insn "sse_movss"
17828 [(set (match_operand:V4SF 0 "register_operand" "=x")
17829 (vec_merge:V4SF
17830 (match_operand:V4SF 1 "register_operand" "0")
17831 (match_operand:V4SF 2 "register_operand" "x")
17832 (const_int 1)))]
17833 "TARGET_SSE"
17834 "movss\t{%2, %0|%0, %2}"
17835 [(set_attr "type" "ssemov")
17836 (set_attr "mode" "SF")])
17837
17838 (define_insn "sse_storess"
17839 [(set (match_operand:SF 0 "memory_operand" "=m")
17840 (vec_select:SF
17841 (match_operand:V4SF 1 "register_operand" "x")
17842 (parallel [(const_int 0)])))]
17843 "TARGET_SSE"
17844 "movss\t{%1, %0|%0, %1}"
17845 [(set_attr "type" "ssemov")
17846 (set_attr "mode" "SF")])
17847
17848 (define_insn "sse_shufps"
17849 [(set (match_operand:V4SF 0 "register_operand" "=x")
17850 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
17851 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
17852 (match_operand:SI 3 "immediate_operand" "i")]
17853 UNSPEC_SHUFFLE))]
17854 "TARGET_SSE"
17855 ;; @@@ check operand order for intel/nonintel syntax
17856 "shufps\t{%3, %2, %0|%0, %2, %3}"
17857 [(set_attr "type" "ssecvt")
17858 (set_attr "mode" "V4SF")])
17859
17860
17861 ;; SSE arithmetic
17862
17863 (define_insn "addv4sf3"
17864 [(set (match_operand:V4SF 0 "register_operand" "=x")
17865 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17866 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17867 "TARGET_SSE"
17868 "addps\t{%2, %0|%0, %2}"
17869 [(set_attr "type" "sseadd")
17870 (set_attr "mode" "V4SF")])
17871
17872 (define_insn "vmaddv4sf3"
17873 [(set (match_operand:V4SF 0 "register_operand" "=x")
17874 (vec_merge:V4SF
17875 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17876 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17877 (match_dup 1)
17878 (const_int 1)))]
17879 "TARGET_SSE"
17880 "addss\t{%2, %0|%0, %2}"
17881 [(set_attr "type" "sseadd")
17882 (set_attr "mode" "SF")])
17883
17884 (define_insn "subv4sf3"
17885 [(set (match_operand:V4SF 0 "register_operand" "=x")
17886 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17887 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17888 "TARGET_SSE"
17889 "subps\t{%2, %0|%0, %2}"
17890 [(set_attr "type" "sseadd")
17891 (set_attr "mode" "V4SF")])
17892
17893 (define_insn "vmsubv4sf3"
17894 [(set (match_operand:V4SF 0 "register_operand" "=x")
17895 (vec_merge:V4SF
17896 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17897 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17898 (match_dup 1)
17899 (const_int 1)))]
17900 "TARGET_SSE"
17901 "subss\t{%2, %0|%0, %2}"
17902 [(set_attr "type" "sseadd")
17903 (set_attr "mode" "SF")])
17904
17905 (define_insn "mulv4sf3"
17906 [(set (match_operand:V4SF 0 "register_operand" "=x")
17907 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17908 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17909 "TARGET_SSE"
17910 "mulps\t{%2, %0|%0, %2}"
17911 [(set_attr "type" "ssemul")
17912 (set_attr "mode" "V4SF")])
17913
17914 (define_insn "vmmulv4sf3"
17915 [(set (match_operand:V4SF 0 "register_operand" "=x")
17916 (vec_merge:V4SF
17917 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17918 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17919 (match_dup 1)
17920 (const_int 1)))]
17921 "TARGET_SSE"
17922 "mulss\t{%2, %0|%0, %2}"
17923 [(set_attr "type" "ssemul")
17924 (set_attr "mode" "SF")])
17925
17926 (define_insn "divv4sf3"
17927 [(set (match_operand:V4SF 0 "register_operand" "=x")
17928 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
17929 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17930 "TARGET_SSE"
17931 "divps\t{%2, %0|%0, %2}"
17932 [(set_attr "type" "ssediv")
17933 (set_attr "mode" "V4SF")])
17934
17935 (define_insn "vmdivv4sf3"
17936 [(set (match_operand:V4SF 0 "register_operand" "=x")
17937 (vec_merge:V4SF
17938 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
17939 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17940 (match_dup 1)
17941 (const_int 1)))]
17942 "TARGET_SSE"
17943 "divss\t{%2, %0|%0, %2}"
17944 [(set_attr "type" "ssediv")
17945 (set_attr "mode" "SF")])
17946
17947
17948 ;; SSE square root/reciprocal
17949
17950 (define_insn "rcpv4sf2"
17951 [(set (match_operand:V4SF 0 "register_operand" "=x")
17952 (unspec:V4SF
17953 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
17954 "TARGET_SSE"
17955 "rcpps\t{%1, %0|%0, %1}"
17956 [(set_attr "type" "sse")
17957 (set_attr "mode" "V4SF")])
17958
17959 (define_insn "vmrcpv4sf2"
17960 [(set (match_operand:V4SF 0 "register_operand" "=x")
17961 (vec_merge:V4SF
17962 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
17963 UNSPEC_RCP)
17964 (match_operand:V4SF 2 "register_operand" "0")
17965 (const_int 1)))]
17966 "TARGET_SSE"
17967 "rcpss\t{%1, %0|%0, %1}"
17968 [(set_attr "type" "sse")
17969 (set_attr "mode" "SF")])
17970
17971 (define_insn "rsqrtv4sf2"
17972 [(set (match_operand:V4SF 0 "register_operand" "=x")
17973 (unspec:V4SF
17974 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
17975 "TARGET_SSE"
17976 "rsqrtps\t{%1, %0|%0, %1}"
17977 [(set_attr "type" "sse")
17978 (set_attr "mode" "V4SF")])
17979
17980 (define_insn "vmrsqrtv4sf2"
17981 [(set (match_operand:V4SF 0 "register_operand" "=x")
17982 (vec_merge:V4SF
17983 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
17984 UNSPEC_RSQRT)
17985 (match_operand:V4SF 2 "register_operand" "0")
17986 (const_int 1)))]
17987 "TARGET_SSE"
17988 "rsqrtss\t{%1, %0|%0, %1}"
17989 [(set_attr "type" "sse")
17990 (set_attr "mode" "SF")])
17991
17992 (define_insn "sqrtv4sf2"
17993 [(set (match_operand:V4SF 0 "register_operand" "=x")
17994 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
17995 "TARGET_SSE"
17996 "sqrtps\t{%1, %0|%0, %1}"
17997 [(set_attr "type" "sse")
17998 (set_attr "mode" "V4SF")])
17999
18000 (define_insn "vmsqrtv4sf2"
18001 [(set (match_operand:V4SF 0 "register_operand" "=x")
18002 (vec_merge:V4SF
18003 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18004 (match_operand:V4SF 2 "register_operand" "0")
18005 (const_int 1)))]
18006 "TARGET_SSE"
18007 "sqrtss\t{%1, %0|%0, %1}"
18008 [(set_attr "type" "sse")
18009 (set_attr "mode" "SF")])
18010
18011 ;; SSE logical operations.
18012
18013 ;; These are not called andti3 etc. because we really really don't want
18014 ;; the compiler to widen DImode ands to TImode ands and then try to move
18015 ;; into DImode subregs of SSE registers, and them together, and move out
18016 ;; of DImode subregs again!
18017
18018 (define_insn "*sse_andti3_df_1"
18019 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18020 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18021 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18022 "TARGET_SSE2"
18023 "andpd\t{%2, %0|%0, %2}"
18024 [(set_attr "type" "sselog")
18025 (set_attr "mode" "V2DF")])
18026
18027 (define_insn "*sse_andti3_df_2"
18028 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18029 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18030 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18031 "TARGET_SSE2"
18032 "andpd\t{%2, %0|%0, %2}"
18033 [(set_attr "type" "sselog")
18034 (set_attr "mode" "V2DF")])
18035
18036 (define_insn "*sse_andti3_sf_1"
18037 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18038 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18039 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18040 "TARGET_SSE"
18041 "andps\t{%2, %0|%0, %2}"
18042 [(set_attr "type" "sselog")
18043 (set_attr "mode" "V4SF")])
18044
18045 (define_insn "*sse_andti3_sf_2"
18046 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18047 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18048 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18049 "TARGET_SSE"
18050 "andps\t{%2, %0|%0, %2}"
18051 [(set_attr "type" "sselog")
18052 (set_attr "mode" "V4SF")])
18053
18054 (define_insn "sse_andti3"
18055 [(set (match_operand:TI 0 "register_operand" "=x")
18056 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18057 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18058 "TARGET_SSE && !TARGET_SSE2
18059 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18060 "andps\t{%2, %0|%0, %2}"
18061 [(set_attr "type" "sselog")
18062 (set_attr "mode" "V4SF")])
18063
18064 (define_insn "sse2_andti3"
18065 [(set (match_operand:TI 0 "register_operand" "=x")
18066 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18067 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18068 "TARGET_SSE2
18069 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18070 "pand\t{%2, %0|%0, %2}"
18071 [(set_attr "type" "sselog")
18072 (set_attr "mode" "TI")])
18073
18074 (define_insn "sse2_andv2di3"
18075 [(set (match_operand:V2DI 0 "register_operand" "=x")
18076 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18077 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18078 "TARGET_SSE2
18079 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18080 "pand\t{%2, %0|%0, %2}"
18081 [(set_attr "type" "sselog")
18082 (set_attr "mode" "TI")])
18083
18084 (define_insn "*sse_nandti3_df"
18085 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18086 (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
18087 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18088 "TARGET_SSE2"
18089 "andnpd\t{%2, %0|%0, %2}"
18090 [(set_attr "type" "sselog")
18091 (set_attr "mode" "V2DF")])
18092
18093 (define_insn "*sse_nandti3_sf"
18094 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18095 (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
18096 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18097 "TARGET_SSE"
18098 "andnps\t{%2, %0|%0, %2}"
18099 [(set_attr "type" "sselog")
18100 (set_attr "mode" "V4SF")])
18101
18102 (define_insn "sse_nandti3"
18103 [(set (match_operand:TI 0 "register_operand" "=x")
18104 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18105 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18106 "TARGET_SSE && !TARGET_SSE2"
18107 "andnps\t{%2, %0|%0, %2}"
18108 [(set_attr "type" "sselog")
18109 (set_attr "mode" "V4SF")])
18110
18111 (define_insn "sse2_nandti3"
18112 [(set (match_operand:TI 0 "register_operand" "=x")
18113 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18114 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18115 "TARGET_SSE2"
18116 "pandn\t{%2, %0|%0, %2}"
18117 [(set_attr "type" "sselog")
18118 (set_attr "mode" "TI")])
18119
18120 (define_insn "sse2_nandv2di3"
18121 [(set (match_operand:V2DI 0 "register_operand" "=x")
18122 (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0"))
18123 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18124 "TARGET_SSE2
18125 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18126 "pandn\t{%2, %0|%0, %2}"
18127 [(set_attr "type" "sselog")
18128 (set_attr "mode" "TI")])
18129
18130 (define_insn "*sse_iorti3_df_1"
18131 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18132 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18133 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18134 "TARGET_SSE2"
18135 "orpd\t{%2, %0|%0, %2}"
18136 [(set_attr "type" "sselog")
18137 (set_attr "mode" "V2DF")])
18138
18139 (define_insn "*sse_iorti3_df_2"
18140 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18141 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18142 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18143 "TARGET_SSE2"
18144 "orpd\t{%2, %0|%0, %2}"
18145 [(set_attr "type" "sselog")
18146 (set_attr "mode" "V2DF")])
18147
18148 (define_insn "*sse_iorti3_sf_1"
18149 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18150 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18151 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18152 "TARGET_SSE"
18153 "orps\t{%2, %0|%0, %2}"
18154 [(set_attr "type" "sselog")
18155 (set_attr "mode" "V4SF")])
18156
18157 (define_insn "*sse_iorti3_sf_2"
18158 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18159 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18160 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18161 "TARGET_SSE"
18162 "orps\t{%2, %0|%0, %2}"
18163 [(set_attr "type" "sselog")
18164 (set_attr "mode" "V4SF")])
18165
18166 (define_insn "sse_iorti3"
18167 [(set (match_operand:TI 0 "register_operand" "=x")
18168 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18169 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18170 "TARGET_SSE && !TARGET_SSE2
18171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18172 "orps\t{%2, %0|%0, %2}"
18173 [(set_attr "type" "sselog")
18174 (set_attr "mode" "V4SF")])
18175
18176 (define_insn "sse2_iorti3"
18177 [(set (match_operand:TI 0 "register_operand" "=x")
18178 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18179 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18180 "TARGET_SSE2
18181 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18182 "por\t{%2, %0|%0, %2}"
18183 [(set_attr "type" "sselog")
18184 (set_attr "mode" "TI")])
18185
18186 (define_insn "sse2_iorv2di3"
18187 [(set (match_operand:V2DI 0 "register_operand" "=x")
18188 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18189 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18190 "TARGET_SSE2
18191 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18192 "por\t{%2, %0|%0, %2}"
18193 [(set_attr "type" "sselog")
18194 (set_attr "mode" "TI")])
18195
18196 (define_insn "*sse_xorti3_df_1"
18197 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18198 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18199 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18200 "TARGET_SSE2"
18201 "xorpd\t{%2, %0|%0, %2}"
18202 [(set_attr "type" "sselog")
18203 (set_attr "mode" "V2DF")])
18204
18205 (define_insn "*sse_xorti3_df_2"
18206 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18207 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18208 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18209 "TARGET_SSE2"
18210 "xorpd\t{%2, %0|%0, %2}"
18211 [(set_attr "type" "sselog")
18212 (set_attr "mode" "V2DF")])
18213
18214 (define_insn "*sse_xorti3_sf_1"
18215 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18216 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18217 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18218 "TARGET_SSE"
18219 "xorps\t{%2, %0|%0, %2}"
18220 [(set_attr "type" "sselog")
18221 (set_attr "mode" "V4SF")])
18222
18223 (define_insn "*sse_xorti3_sf_2"
18224 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18225 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18226 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18227 "TARGET_SSE"
18228 "xorps\t{%2, %0|%0, %2}"
18229 [(set_attr "type" "sselog")
18230 (set_attr "mode" "V4SF")])
18231
18232 (define_insn "sse_xorti3"
18233 [(set (match_operand:TI 0 "register_operand" "=x")
18234 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18235 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18236 "TARGET_SSE && !TARGET_SSE2
18237 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18238 "xorps\t{%2, %0|%0, %2}"
18239 [(set_attr "type" "sselog")
18240 (set_attr "mode" "V4SF")])
18241
18242 (define_insn "sse2_xorti3"
18243 [(set (match_operand:TI 0 "register_operand" "=x")
18244 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
18245 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18246 "TARGET_SSE2
18247 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18248 "pxor\t{%2, %0|%0, %2}"
18249 [(set_attr "type" "sselog")
18250 (set_attr "mode" "TI")])
18251
18252 (define_insn "sse2_xorv2di3"
18253 [(set (match_operand:V2DI 0 "register_operand" "=x")
18254 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
18255 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
18256 "TARGET_SSE2
18257 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18258 "pxor\t{%2, %0|%0, %2}"
18259 [(set_attr "type" "sselog")
18260 (set_attr "mode" "TI")])
18261
18262 ;; Use xor, but don't show input operands so they aren't live before
18263 ;; this insn.
18264 (define_insn "sse_clrv4sf"
18265 [(set (match_operand:V4SF 0 "register_operand" "=x")
18266 (unspec:V4SF [(const_int 0)] UNSPEC_NOP))]
18267 "TARGET_SSE"
18268 "xorps\t{%0, %0|%0, %0}"
18269 [(set_attr "type" "sselog")
18270 (set_attr "memory" "none")
18271 (set_attr "mode" "V4SF")])
18272
18273 ;; SSE mask-generating compares
18274
18275 (define_insn "maskcmpv4sf3"
18276 [(set (match_operand:V4SI 0 "register_operand" "=x")
18277 (match_operator:V4SI 3 "sse_comparison_operator"
18278 [(match_operand:V4SF 1 "register_operand" "0")
18279 (match_operand:V4SF 2 "register_operand" "x")]))]
18280 "TARGET_SSE"
18281 "cmp%D3ps\t{%2, %0|%0, %2}"
18282 [(set_attr "type" "ssecmp")
18283 (set_attr "mode" "V4SF")])
18284
18285 (define_insn "maskncmpv4sf3"
18286 [(set (match_operand:V4SI 0 "register_operand" "=x")
18287 (not:V4SI
18288 (match_operator:V4SI 3 "sse_comparison_operator"
18289 [(match_operand:V4SF 1 "register_operand" "0")
18290 (match_operand:V4SF 2 "register_operand" "x")])))]
18291 "TARGET_SSE"
18292 {
18293 if (GET_CODE (operands[3]) == UNORDERED)
18294 return "cmpordps\t{%2, %0|%0, %2}";
18295 else
18296 return "cmpn%D3ps\t{%2, %0|%0, %2}";
18297 }
18298 [(set_attr "type" "ssecmp")
18299 (set_attr "mode" "V4SF")])
18300
18301 (define_insn "vmmaskcmpv4sf3"
18302 [(set (match_operand:V4SI 0 "register_operand" "=x")
18303 (vec_merge:V4SI
18304 (match_operator:V4SI 3 "sse_comparison_operator"
18305 [(match_operand:V4SF 1 "register_operand" "0")
18306 (match_operand:V4SF 2 "register_operand" "x")])
18307 (match_dup 1)
18308 (const_int 1)))]
18309 "TARGET_SSE"
18310 "cmp%D3ss\t{%2, %0|%0, %2}"
18311 [(set_attr "type" "ssecmp")
18312 (set_attr "mode" "SF")])
18313
18314 (define_insn "vmmaskncmpv4sf3"
18315 [(set (match_operand:V4SI 0 "register_operand" "=x")
18316 (vec_merge:V4SI
18317 (not:V4SI
18318 (match_operator:V4SI 3 "sse_comparison_operator"
18319 [(match_operand:V4SF 1 "register_operand" "0")
18320 (match_operand:V4SF 2 "register_operand" "x")]))
18321 (subreg:V4SI (match_dup 1) 0)
18322 (const_int 1)))]
18323 "TARGET_SSE"
18324 {
18325 if (GET_CODE (operands[3]) == UNORDERED)
18326 return "cmpordss\t{%2, %0|%0, %2}";
18327 else
18328 return "cmpn%D3ss\t{%2, %0|%0, %2}";
18329 }
18330 [(set_attr "type" "ssecmp")
18331 (set_attr "mode" "SF")])
18332
18333 (define_insn "sse_comi"
18334 [(set (reg:CCFP 17)
18335 (match_operator:CCFP 2 "sse_comparison_operator"
18336 [(vec_select:SF
18337 (match_operand:V4SF 0 "register_operand" "x")
18338 (parallel [(const_int 0)]))
18339 (vec_select:SF
18340 (match_operand:V4SF 1 "register_operand" "x")
18341 (parallel [(const_int 0)]))]))]
18342 "TARGET_SSE"
18343 "comiss\t{%1, %0|%0, %1}"
18344 [(set_attr "type" "ssecmp")
18345 (set_attr "mode" "SF")])
18346
18347 (define_insn "sse_ucomi"
18348 [(set (reg:CCFPU 17)
18349 (match_operator:CCFPU 2 "sse_comparison_operator"
18350 [(vec_select:SF
18351 (match_operand:V4SF 0 "register_operand" "x")
18352 (parallel [(const_int 0)]))
18353 (vec_select:SF
18354 (match_operand:V4SF 1 "register_operand" "x")
18355 (parallel [(const_int 0)]))]))]
18356 "TARGET_SSE"
18357 "ucomiss\t{%1, %0|%0, %1}"
18358 [(set_attr "type" "ssecmp")
18359 (set_attr "mode" "SF")])
18360
18361
18362 ;; SSE unpack
18363
18364 (define_insn "sse_unpckhps"
18365 [(set (match_operand:V4SF 0 "register_operand" "=x")
18366 (vec_merge:V4SF
18367 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18368 (parallel [(const_int 2)
18369 (const_int 0)
18370 (const_int 3)
18371 (const_int 1)]))
18372 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18373 (parallel [(const_int 0)
18374 (const_int 2)
18375 (const_int 1)
18376 (const_int 3)]))
18377 (const_int 5)))]
18378 "TARGET_SSE"
18379 "unpckhps\t{%2, %0|%0, %2}"
18380 [(set_attr "type" "ssecvt")
18381 (set_attr "mode" "V4SF")])
18382
18383 (define_insn "sse_unpcklps"
18384 [(set (match_operand:V4SF 0 "register_operand" "=x")
18385 (vec_merge:V4SF
18386 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18387 (parallel [(const_int 0)
18388 (const_int 2)
18389 (const_int 1)
18390 (const_int 3)]))
18391 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18392 (parallel [(const_int 2)
18393 (const_int 0)
18394 (const_int 3)
18395 (const_int 1)]))
18396 (const_int 5)))]
18397 "TARGET_SSE"
18398 "unpcklps\t{%2, %0|%0, %2}"
18399 [(set_attr "type" "ssecvt")
18400 (set_attr "mode" "V4SF")])
18401
18402
18403 ;; SSE min/max
18404
18405 (define_insn "smaxv4sf3"
18406 [(set (match_operand:V4SF 0 "register_operand" "=x")
18407 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18408 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18409 "TARGET_SSE"
18410 "maxps\t{%2, %0|%0, %2}"
18411 [(set_attr "type" "sse")
18412 (set_attr "mode" "V4SF")])
18413
18414 (define_insn "vmsmaxv4sf3"
18415 [(set (match_operand:V4SF 0 "register_operand" "=x")
18416 (vec_merge:V4SF
18417 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18418 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18419 (match_dup 1)
18420 (const_int 1)))]
18421 "TARGET_SSE"
18422 "maxss\t{%2, %0|%0, %2}"
18423 [(set_attr "type" "sse")
18424 (set_attr "mode" "SF")])
18425
18426 (define_insn "sminv4sf3"
18427 [(set (match_operand:V4SF 0 "register_operand" "=x")
18428 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18429 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18430 "TARGET_SSE"
18431 "minps\t{%2, %0|%0, %2}"
18432 [(set_attr "type" "sse")
18433 (set_attr "mode" "V4SF")])
18434
18435 (define_insn "vmsminv4sf3"
18436 [(set (match_operand:V4SF 0 "register_operand" "=x")
18437 (vec_merge:V4SF
18438 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18439 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18440 (match_dup 1)
18441 (const_int 1)))]
18442 "TARGET_SSE"
18443 "minss\t{%2, %0|%0, %2}"
18444 [(set_attr "type" "sse")
18445 (set_attr "mode" "SF")])
18446
18447
18448 ;; SSE <-> integer/MMX conversions
18449
18450 (define_insn "cvtpi2ps"
18451 [(set (match_operand:V4SF 0 "register_operand" "=x")
18452 (vec_merge:V4SF
18453 (match_operand:V4SF 1 "register_operand" "0")
18454 (vec_duplicate:V4SF
18455 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
18456 (const_int 12)))]
18457 "TARGET_SSE"
18458 "cvtpi2ps\t{%2, %0|%0, %2}"
18459 [(set_attr "type" "ssecvt")
18460 (set_attr "mode" "V4SF")])
18461
18462 (define_insn "cvtps2pi"
18463 [(set (match_operand:V2SI 0 "register_operand" "=y")
18464 (vec_select:V2SI
18465 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18466 (parallel [(const_int 0) (const_int 1)])))]
18467 "TARGET_SSE"
18468 "cvtps2pi\t{%1, %0|%0, %1}"
18469 [(set_attr "type" "ssecvt")
18470 (set_attr "mode" "V4SF")])
18471
18472 (define_insn "cvttps2pi"
18473 [(set (match_operand:V2SI 0 "register_operand" "=y")
18474 (vec_select:V2SI
18475 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
18476 UNSPEC_FIX)
18477 (parallel [(const_int 0) (const_int 1)])))]
18478 "TARGET_SSE"
18479 "cvttps2pi\t{%1, %0|%0, %1}"
18480 [(set_attr "type" "ssecvt")
18481 (set_attr "mode" "SF")])
18482
18483 (define_insn "cvtsi2ss"
18484 [(set (match_operand:V4SF 0 "register_operand" "=x")
18485 (vec_merge:V4SF
18486 (match_operand:V4SF 1 "register_operand" "0")
18487 (vec_duplicate:V4SF
18488 (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
18489 (const_int 14)))]
18490 "TARGET_SSE"
18491 "cvtsi2ss\t{%2, %0|%0, %2}"
18492 [(set_attr "type" "ssecvt")
18493 (set_attr "mode" "SF")])
18494
18495 (define_insn "cvtss2si"
18496 [(set (match_operand:SI 0 "register_operand" "=r")
18497 (vec_select:SI
18498 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
18499 (parallel [(const_int 0)])))]
18500 "TARGET_SSE"
18501 "cvtss2si\t{%1, %0|%0, %1}"
18502 [(set_attr "type" "ssecvt")
18503 (set_attr "mode" "SF")])
18504
18505 (define_insn "cvttss2si"
18506 [(set (match_operand:SI 0 "register_operand" "=r")
18507 (vec_select:SI
18508 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
18509 UNSPEC_FIX)
18510 (parallel [(const_int 0)])))]
18511 "TARGET_SSE"
18512 "cvttss2si\t{%1, %0|%0, %1}"
18513 [(set_attr "type" "ssecvt")
18514 (set_attr "mode" "SF")])
18515
18516
18517 ;; MMX insns
18518
18519 ;; MMX arithmetic
18520
18521 (define_insn "addv8qi3"
18522 [(set (match_operand:V8QI 0 "register_operand" "=y")
18523 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18524 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18525 "TARGET_MMX"
18526 "paddb\t{%2, %0|%0, %2}"
18527 [(set_attr "type" "mmxadd")
18528 (set_attr "mode" "DI")])
18529
18530 (define_insn "addv4hi3"
18531 [(set (match_operand:V4HI 0 "register_operand" "=y")
18532 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18533 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18534 "TARGET_MMX"
18535 "paddw\t{%2, %0|%0, %2}"
18536 [(set_attr "type" "mmxadd")
18537 (set_attr "mode" "DI")])
18538
18539 (define_insn "addv2si3"
18540 [(set (match_operand:V2SI 0 "register_operand" "=y")
18541 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18542 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18543 "TARGET_MMX"
18544 "paddd\t{%2, %0|%0, %2}"
18545 [(set_attr "type" "mmxadd")
18546 (set_attr "mode" "DI")])
18547
18548 (define_insn "ssaddv8qi3"
18549 [(set (match_operand:V8QI 0 "register_operand" "=y")
18550 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18551 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18552 "TARGET_MMX"
18553 "paddsb\t{%2, %0|%0, %2}"
18554 [(set_attr "type" "mmxadd")
18555 (set_attr "mode" "DI")])
18556
18557 (define_insn "ssaddv4hi3"
18558 [(set (match_operand:V4HI 0 "register_operand" "=y")
18559 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18560 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18561 "TARGET_MMX"
18562 "paddsw\t{%2, %0|%0, %2}"
18563 [(set_attr "type" "mmxadd")
18564 (set_attr "mode" "DI")])
18565
18566 (define_insn "usaddv8qi3"
18567 [(set (match_operand:V8QI 0 "register_operand" "=y")
18568 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18569 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18570 "TARGET_MMX"
18571 "paddusb\t{%2, %0|%0, %2}"
18572 [(set_attr "type" "mmxadd")
18573 (set_attr "mode" "DI")])
18574
18575 (define_insn "usaddv4hi3"
18576 [(set (match_operand:V4HI 0 "register_operand" "=y")
18577 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18578 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18579 "TARGET_MMX"
18580 "paddusw\t{%2, %0|%0, %2}"
18581 [(set_attr "type" "mmxadd")
18582 (set_attr "mode" "DI")])
18583
18584 (define_insn "subv8qi3"
18585 [(set (match_operand:V8QI 0 "register_operand" "=y")
18586 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18587 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18588 "TARGET_MMX"
18589 "psubb\t{%2, %0|%0, %2}"
18590 [(set_attr "type" "mmxadd")
18591 (set_attr "mode" "DI")])
18592
18593 (define_insn "subv4hi3"
18594 [(set (match_operand:V4HI 0 "register_operand" "=y")
18595 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18596 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18597 "TARGET_MMX"
18598 "psubw\t{%2, %0|%0, %2}"
18599 [(set_attr "type" "mmxadd")
18600 (set_attr "mode" "DI")])
18601
18602 (define_insn "subv2si3"
18603 [(set (match_operand:V2SI 0 "register_operand" "=y")
18604 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18605 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18606 "TARGET_MMX"
18607 "psubd\t{%2, %0|%0, %2}"
18608 [(set_attr "type" "mmxadd")
18609 (set_attr "mode" "DI")])
18610
18611 (define_insn "sssubv8qi3"
18612 [(set (match_operand:V8QI 0 "register_operand" "=y")
18613 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18614 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18615 "TARGET_MMX"
18616 "psubsb\t{%2, %0|%0, %2}"
18617 [(set_attr "type" "mmxadd")
18618 (set_attr "mode" "DI")])
18619
18620 (define_insn "sssubv4hi3"
18621 [(set (match_operand:V4HI 0 "register_operand" "=y")
18622 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18623 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18624 "TARGET_MMX"
18625 "psubsw\t{%2, %0|%0, %2}"
18626 [(set_attr "type" "mmxadd")
18627 (set_attr "mode" "DI")])
18628
18629 (define_insn "ussubv8qi3"
18630 [(set (match_operand:V8QI 0 "register_operand" "=y")
18631 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18632 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18633 "TARGET_MMX"
18634 "psubusb\t{%2, %0|%0, %2}"
18635 [(set_attr "type" "mmxadd")
18636 (set_attr "mode" "DI")])
18637
18638 (define_insn "ussubv4hi3"
18639 [(set (match_operand:V4HI 0 "register_operand" "=y")
18640 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18641 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18642 "TARGET_MMX"
18643 "psubusw\t{%2, %0|%0, %2}"
18644 [(set_attr "type" "mmxadd")
18645 (set_attr "mode" "DI")])
18646
18647 (define_insn "mulv4hi3"
18648 [(set (match_operand:V4HI 0 "register_operand" "=y")
18649 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18650 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18651 "TARGET_MMX"
18652 "pmullw\t{%2, %0|%0, %2}"
18653 [(set_attr "type" "mmxmul")
18654 (set_attr "mode" "DI")])
18655
18656 (define_insn "smulv4hi3_highpart"
18657 [(set (match_operand:V4HI 0 "register_operand" "=y")
18658 (truncate:V4HI
18659 (lshiftrt:V4SI
18660 (mult:V4SI (sign_extend:V4SI
18661 (match_operand:V4HI 1 "register_operand" "0"))
18662 (sign_extend:V4SI
18663 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18664 (const_int 16))))]
18665 "TARGET_MMX"
18666 "pmulhw\t{%2, %0|%0, %2}"
18667 [(set_attr "type" "mmxmul")
18668 (set_attr "mode" "DI")])
18669
18670 (define_insn "umulv4hi3_highpart"
18671 [(set (match_operand:V4HI 0 "register_operand" "=y")
18672 (truncate:V4HI
18673 (lshiftrt:V4SI
18674 (mult:V4SI (zero_extend:V4SI
18675 (match_operand:V4HI 1 "register_operand" "0"))
18676 (zero_extend:V4SI
18677 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18678 (const_int 16))))]
18679 "TARGET_SSE || TARGET_3DNOW_A"
18680 "pmulhuw\t{%2, %0|%0, %2}"
18681 [(set_attr "type" "mmxmul")
18682 (set_attr "mode" "DI")])
18683
18684 (define_insn "mmx_pmaddwd"
18685 [(set (match_operand:V2SI 0 "register_operand" "=y")
18686 (plus:V2SI
18687 (mult:V2SI
18688 (sign_extend:V2SI
18689 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18690 (parallel [(const_int 0) (const_int 2)])))
18691 (sign_extend:V2SI
18692 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18693 (parallel [(const_int 0) (const_int 2)]))))
18694 (mult:V2SI
18695 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18696 (parallel [(const_int 1)
18697 (const_int 3)])))
18698 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18699 (parallel [(const_int 1)
18700 (const_int 3)]))))))]
18701 "TARGET_MMX"
18702 "pmaddwd\t{%2, %0|%0, %2}"
18703 [(set_attr "type" "mmxmul")
18704 (set_attr "mode" "DI")])
18705
18706
18707 ;; MMX logical operations
18708 ;; Note we don't want to declare these as regular iordi3 insns to prevent
18709 ;; normal code that also wants to use the FPU from getting broken.
18710 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
18711 (define_insn "mmx_iordi3"
18712 [(set (match_operand:DI 0 "register_operand" "=y")
18713 (unspec:DI
18714 [(ior:DI (match_operand:DI 1 "register_operand" "0")
18715 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
18716 UNSPEC_NOP))]
18717 "TARGET_MMX"
18718 "por\t{%2, %0|%0, %2}"
18719 [(set_attr "type" "mmxadd")
18720 (set_attr "mode" "DI")])
18721
18722 (define_insn "mmx_xordi3"
18723 [(set (match_operand:DI 0 "register_operand" "=y")
18724 (unspec:DI
18725 [(xor:DI (match_operand:DI 1 "register_operand" "0")
18726 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
18727 UNSPEC_NOP))]
18728 "TARGET_MMX"
18729 "pxor\t{%2, %0|%0, %2}"
18730 [(set_attr "type" "mmxadd")
18731 (set_attr "mode" "DI")
18732 (set_attr "memory" "none")])
18733
18734 ;; Same as pxor, but don't show input operands so that we don't think
18735 ;; they are live.
18736 (define_insn "mmx_clrdi"
18737 [(set (match_operand:DI 0 "register_operand" "=y")
18738 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
18739 "TARGET_MMX"
18740 "pxor\t{%0, %0|%0, %0}"
18741 [(set_attr "type" "mmxadd")
18742 (set_attr "mode" "DI")
18743 (set_attr "memory" "none")])
18744
18745 (define_insn "mmx_anddi3"
18746 [(set (match_operand:DI 0 "register_operand" "=y")
18747 (unspec:DI
18748 [(and:DI (match_operand:DI 1 "register_operand" "0")
18749 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
18750 UNSPEC_NOP))]
18751 "TARGET_MMX"
18752 "pand\t{%2, %0|%0, %2}"
18753 [(set_attr "type" "mmxadd")
18754 (set_attr "mode" "DI")])
18755
18756 (define_insn "mmx_nanddi3"
18757 [(set (match_operand:DI 0 "register_operand" "=y")
18758 (unspec:DI
18759 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
18760 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
18761 UNSPEC_NOP))]
18762 "TARGET_MMX"
18763 "pandn\t{%2, %0|%0, %2}"
18764 [(set_attr "type" "mmxadd")
18765 (set_attr "mode" "DI")])
18766
18767
18768 ;; MMX unsigned averages/sum of absolute differences
18769
18770 (define_insn "mmx_uavgv8qi3"
18771 [(set (match_operand:V8QI 0 "register_operand" "=y")
18772 (ashiftrt:V8QI
18773 (plus:V8QI (plus:V8QI
18774 (match_operand:V8QI 1 "register_operand" "0")
18775 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
18776 (const_vector:V8QI [(const_int 1)
18777 (const_int 1)
18778 (const_int 1)
18779 (const_int 1)
18780 (const_int 1)
18781 (const_int 1)
18782 (const_int 1)
18783 (const_int 1)]))
18784 (const_int 1)))]
18785 "TARGET_SSE || TARGET_3DNOW_A"
18786 "pavgb\t{%2, %0|%0, %2}"
18787 [(set_attr "type" "mmxshft")
18788 (set_attr "mode" "DI")])
18789
18790 (define_insn "mmx_uavgv4hi3"
18791 [(set (match_operand:V4HI 0 "register_operand" "=y")
18792 (ashiftrt:V4HI
18793 (plus:V4HI (plus:V4HI
18794 (match_operand:V4HI 1 "register_operand" "0")
18795 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
18796 (const_vector:V4HI [(const_int 1)
18797 (const_int 1)
18798 (const_int 1)
18799 (const_int 1)]))
18800 (const_int 1)))]
18801 "TARGET_SSE || TARGET_3DNOW_A"
18802 "pavgw\t{%2, %0|%0, %2}"
18803 [(set_attr "type" "mmxshft")
18804 (set_attr "mode" "DI")])
18805
18806 (define_insn "mmx_psadbw"
18807 [(set (match_operand:DI 0 "register_operand" "=y")
18808 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
18809 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
18810 UNSPEC_PSADBW))]
18811 "TARGET_SSE || TARGET_3DNOW_A"
18812 "psadbw\t{%2, %0|%0, %2}"
18813 [(set_attr "type" "mmxshft")
18814 (set_attr "mode" "DI")])
18815
18816
18817 ;; MMX insert/extract/shuffle
18818
18819 (define_insn "mmx_pinsrw"
18820 [(set (match_operand:V4HI 0 "register_operand" "=y")
18821 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
18822 (vec_duplicate:V4HI
18823 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
18824 (match_operand:SI 3 "immediate_operand" "i")))]
18825 "TARGET_SSE || TARGET_3DNOW_A"
18826 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
18827 [(set_attr "type" "mmxcvt")
18828 (set_attr "mode" "DI")])
18829
18830 (define_insn "mmx_pextrw"
18831 [(set (match_operand:SI 0 "register_operand" "=r")
18832 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
18833 (parallel
18834 [(match_operand:SI 2 "immediate_operand" "i")]))))]
18835 "TARGET_SSE || TARGET_3DNOW_A"
18836 "pextrw\t{%2, %1, %0|%0, %1, %2}"
18837 [(set_attr "type" "mmxcvt")
18838 (set_attr "mode" "DI")])
18839
18840 (define_insn "mmx_pshufw"
18841 [(set (match_operand:V4HI 0 "register_operand" "=y")
18842 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
18843 (match_operand:SI 2 "immediate_operand" "i")]
18844 UNSPEC_SHUFFLE))]
18845 "TARGET_SSE || TARGET_3DNOW_A"
18846 "pshufw\t{%2, %1, %0|%0, %1, %2}"
18847 [(set_attr "type" "mmxcvt")
18848 (set_attr "mode" "DI")])
18849
18850
18851 ;; MMX mask-generating comparisons
18852
18853 (define_insn "eqv8qi3"
18854 [(set (match_operand:V8QI 0 "register_operand" "=y")
18855 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
18856 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18857 "TARGET_MMX"
18858 "pcmpeqb\t{%2, %0|%0, %2}"
18859 [(set_attr "type" "mmxcmp")
18860 (set_attr "mode" "DI")])
18861
18862 (define_insn "eqv4hi3"
18863 [(set (match_operand:V4HI 0 "register_operand" "=y")
18864 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
18865 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18866 "TARGET_MMX"
18867 "pcmpeqw\t{%2, %0|%0, %2}"
18868 [(set_attr "type" "mmxcmp")
18869 (set_attr "mode" "DI")])
18870
18871 (define_insn "eqv2si3"
18872 [(set (match_operand:V2SI 0 "register_operand" "=y")
18873 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
18874 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18875 "TARGET_MMX"
18876 "pcmpeqd\t{%2, %0|%0, %2}"
18877 [(set_attr "type" "mmxcmp")
18878 (set_attr "mode" "DI")])
18879
18880 (define_insn "gtv8qi3"
18881 [(set (match_operand:V8QI 0 "register_operand" "=y")
18882 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
18883 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18884 "TARGET_MMX"
18885 "pcmpgtb\t{%2, %0|%0, %2}"
18886 [(set_attr "type" "mmxcmp")
18887 (set_attr "mode" "DI")])
18888
18889 (define_insn "gtv4hi3"
18890 [(set (match_operand:V4HI 0 "register_operand" "=y")
18891 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18892 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18893 "TARGET_MMX"
18894 "pcmpgtw\t{%2, %0|%0, %2}"
18895 [(set_attr "type" "mmxcmp")
18896 (set_attr "mode" "DI")])
18897
18898 (define_insn "gtv2si3"
18899 [(set (match_operand:V2SI 0 "register_operand" "=y")
18900 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18901 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18902 "TARGET_MMX"
18903 "pcmpgtd\t{%2, %0|%0, %2}"
18904 [(set_attr "type" "mmxcmp")
18905 (set_attr "mode" "DI")])
18906
18907
18908 ;; MMX max/min insns
18909
18910 (define_insn "umaxv8qi3"
18911 [(set (match_operand:V8QI 0 "register_operand" "=y")
18912 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
18913 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18914 "TARGET_SSE || TARGET_3DNOW_A"
18915 "pmaxub\t{%2, %0|%0, %2}"
18916 [(set_attr "type" "mmxadd")
18917 (set_attr "mode" "DI")])
18918
18919 (define_insn "smaxv4hi3"
18920 [(set (match_operand:V4HI 0 "register_operand" "=y")
18921 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
18922 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18923 "TARGET_SSE || TARGET_3DNOW_A"
18924 "pmaxsw\t{%2, %0|%0, %2}"
18925 [(set_attr "type" "mmxadd")
18926 (set_attr "mode" "DI")])
18927
18928 (define_insn "uminv8qi3"
18929 [(set (match_operand:V8QI 0 "register_operand" "=y")
18930 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
18931 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18932 "TARGET_SSE || TARGET_3DNOW_A"
18933 "pminub\t{%2, %0|%0, %2}"
18934 [(set_attr "type" "mmxadd")
18935 (set_attr "mode" "DI")])
18936
18937 (define_insn "sminv4hi3"
18938 [(set (match_operand:V4HI 0 "register_operand" "=y")
18939 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
18940 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18941 "TARGET_SSE || TARGET_3DNOW_A"
18942 "pminsw\t{%2, %0|%0, %2}"
18943 [(set_attr "type" "mmxadd")
18944 (set_attr "mode" "DI")])
18945
18946
18947 ;; MMX shifts
18948
18949 (define_insn "ashrv4hi3"
18950 [(set (match_operand:V4HI 0 "register_operand" "=y")
18951 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18952 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18953 "TARGET_MMX"
18954 "psraw\t{%2, %0|%0, %2}"
18955 [(set_attr "type" "mmxshft")
18956 (set_attr "mode" "DI")])
18957
18958 (define_insn "ashrv2si3"
18959 [(set (match_operand:V2SI 0 "register_operand" "=y")
18960 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18961 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18962 "TARGET_MMX"
18963 "psrad\t{%2, %0|%0, %2}"
18964 [(set_attr "type" "mmxshft")
18965 (set_attr "mode" "DI")])
18966
18967 (define_insn "lshrv4hi3"
18968 [(set (match_operand:V4HI 0 "register_operand" "=y")
18969 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18970 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18971 "TARGET_MMX"
18972 "psrlw\t{%2, %0|%0, %2}"
18973 [(set_attr "type" "mmxshft")
18974 (set_attr "mode" "DI")])
18975
18976 (define_insn "lshrv2si3"
18977 [(set (match_operand:V2SI 0 "register_operand" "=y")
18978 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18979 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18980 "TARGET_MMX"
18981 "psrld\t{%2, %0|%0, %2}"
18982 [(set_attr "type" "mmxshft")
18983 (set_attr "mode" "DI")])
18984
18985 ;; See logical MMX insns.
18986 (define_insn "mmx_lshrdi3"
18987 [(set (match_operand:DI 0 "register_operand" "=y")
18988 (unspec:DI
18989 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
18990 (match_operand:DI 2 "nonmemory_operand" "yi"))]
18991 UNSPEC_NOP))]
18992 "TARGET_MMX"
18993 "psrlq\t{%2, %0|%0, %2}"
18994 [(set_attr "type" "mmxshft")
18995 (set_attr "mode" "DI")])
18996
18997 (define_insn "ashlv4hi3"
18998 [(set (match_operand:V4HI 0 "register_operand" "=y")
18999 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
19000 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19001 "TARGET_MMX"
19002 "psllw\t{%2, %0|%0, %2}"
19003 [(set_attr "type" "mmxshft")
19004 (set_attr "mode" "DI")])
19005
19006 (define_insn "ashlv2si3"
19007 [(set (match_operand:V2SI 0 "register_operand" "=y")
19008 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
19009 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19010 "TARGET_MMX"
19011 "pslld\t{%2, %0|%0, %2}"
19012 [(set_attr "type" "mmxshft")
19013 (set_attr "mode" "DI")])
19014
19015 ;; See logical MMX insns.
19016 (define_insn "mmx_ashldi3"
19017 [(set (match_operand:DI 0 "register_operand" "=y")
19018 (unspec:DI
19019 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
19020 (match_operand:DI 2 "nonmemory_operand" "yi"))]
19021 UNSPEC_NOP))]
19022 "TARGET_MMX"
19023 "psllq\t{%2, %0|%0, %2}"
19024 [(set_attr "type" "mmxshft")
19025 (set_attr "mode" "DI")])
19026
19027
19028 ;; MMX pack/unpack insns.
19029
19030 (define_insn "mmx_packsswb"
19031 [(set (match_operand:V8QI 0 "register_operand" "=y")
19032 (vec_concat:V8QI
19033 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19034 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19035 "TARGET_MMX"
19036 "packsswb\t{%2, %0|%0, %2}"
19037 [(set_attr "type" "mmxshft")
19038 (set_attr "mode" "DI")])
19039
19040 (define_insn "mmx_packssdw"
19041 [(set (match_operand:V4HI 0 "register_operand" "=y")
19042 (vec_concat:V4HI
19043 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
19044 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
19045 "TARGET_MMX"
19046 "packssdw\t{%2, %0|%0, %2}"
19047 [(set_attr "type" "mmxshft")
19048 (set_attr "mode" "DI")])
19049
19050 (define_insn "mmx_packuswb"
19051 [(set (match_operand:V8QI 0 "register_operand" "=y")
19052 (vec_concat:V8QI
19053 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19054 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19055 "TARGET_MMX"
19056 "packuswb\t{%2, %0|%0, %2}"
19057 [(set_attr "type" "mmxshft")
19058 (set_attr "mode" "DI")])
19059
19060 (define_insn "mmx_punpckhbw"
19061 [(set (match_operand:V8QI 0 "register_operand" "=y")
19062 (vec_merge:V8QI
19063 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19064 (parallel [(const_int 4)
19065 (const_int 0)
19066 (const_int 5)
19067 (const_int 1)
19068 (const_int 6)
19069 (const_int 2)
19070 (const_int 7)
19071 (const_int 3)]))
19072 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19073 (parallel [(const_int 0)
19074 (const_int 4)
19075 (const_int 1)
19076 (const_int 5)
19077 (const_int 2)
19078 (const_int 6)
19079 (const_int 3)
19080 (const_int 7)]))
19081 (const_int 85)))]
19082 "TARGET_MMX"
19083 "punpckhbw\t{%2, %0|%0, %2}"
19084 [(set_attr "type" "mmxcvt")
19085 (set_attr "mode" "DI")])
19086
19087 (define_insn "mmx_punpckhwd"
19088 [(set (match_operand:V4HI 0 "register_operand" "=y")
19089 (vec_merge:V4HI
19090 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19091 (parallel [(const_int 0)
19092 (const_int 2)
19093 (const_int 1)
19094 (const_int 3)]))
19095 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19096 (parallel [(const_int 2)
19097 (const_int 0)
19098 (const_int 3)
19099 (const_int 1)]))
19100 (const_int 5)))]
19101 "TARGET_MMX"
19102 "punpckhwd\t{%2, %0|%0, %2}"
19103 [(set_attr "type" "mmxcvt")
19104 (set_attr "mode" "DI")])
19105
19106 (define_insn "mmx_punpckhdq"
19107 [(set (match_operand:V2SI 0 "register_operand" "=y")
19108 (vec_merge:V2SI
19109 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19110 (parallel [(const_int 0)
19111 (const_int 1)]))
19112 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19113 (parallel [(const_int 1)
19114 (const_int 0)]))
19115 (const_int 1)))]
19116 "TARGET_MMX"
19117 "punpckhdq\t{%2, %0|%0, %2}"
19118 [(set_attr "type" "mmxcvt")
19119 (set_attr "mode" "DI")])
19120
19121 (define_insn "mmx_punpcklbw"
19122 [(set (match_operand:V8QI 0 "register_operand" "=y")
19123 (vec_merge:V8QI
19124 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19125 (parallel [(const_int 0)
19126 (const_int 4)
19127 (const_int 1)
19128 (const_int 5)
19129 (const_int 2)
19130 (const_int 6)
19131 (const_int 3)
19132 (const_int 7)]))
19133 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19134 (parallel [(const_int 4)
19135 (const_int 0)
19136 (const_int 5)
19137 (const_int 1)
19138 (const_int 6)
19139 (const_int 2)
19140 (const_int 7)
19141 (const_int 3)]))
19142 (const_int 85)))]
19143 "TARGET_MMX"
19144 "punpcklbw\t{%2, %0|%0, %2}"
19145 [(set_attr "type" "mmxcvt")
19146 (set_attr "mode" "DI")])
19147
19148 (define_insn "mmx_punpcklwd"
19149 [(set (match_operand:V4HI 0 "register_operand" "=y")
19150 (vec_merge:V4HI
19151 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19152 (parallel [(const_int 2)
19153 (const_int 0)
19154 (const_int 3)
19155 (const_int 1)]))
19156 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19157 (parallel [(const_int 0)
19158 (const_int 2)
19159 (const_int 1)
19160 (const_int 3)]))
19161 (const_int 5)))]
19162 "TARGET_MMX"
19163 "punpcklwd\t{%2, %0|%0, %2}"
19164 [(set_attr "type" "mmxcvt")
19165 (set_attr "mode" "DI")])
19166
19167 (define_insn "mmx_punpckldq"
19168 [(set (match_operand:V2SI 0 "register_operand" "=y")
19169 (vec_merge:V2SI
19170 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19171 (parallel [(const_int 1)
19172 (const_int 0)]))
19173 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19174 (parallel [(const_int 0)
19175 (const_int 1)]))
19176 (const_int 1)))]
19177 "TARGET_MMX"
19178 "punpckldq\t{%2, %0|%0, %2}"
19179 [(set_attr "type" "mmxcvt")
19180 (set_attr "mode" "DI")])
19181
19182
19183 ;; Miscellaneous stuff
19184
19185 (define_insn "emms"
19186 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
19187 (clobber (reg:XF 8))
19188 (clobber (reg:XF 9))
19189 (clobber (reg:XF 10))
19190 (clobber (reg:XF 11))
19191 (clobber (reg:XF 12))
19192 (clobber (reg:XF 13))
19193 (clobber (reg:XF 14))
19194 (clobber (reg:XF 15))
19195 (clobber (reg:DI 29))
19196 (clobber (reg:DI 30))
19197 (clobber (reg:DI 31))
19198 (clobber (reg:DI 32))
19199 (clobber (reg:DI 33))
19200 (clobber (reg:DI 34))
19201 (clobber (reg:DI 35))
19202 (clobber (reg:DI 36))]
19203 "TARGET_MMX"
19204 "emms"
19205 [(set_attr "type" "mmx")
19206 (set_attr "memory" "unknown")])
19207
19208 (define_insn "ldmxcsr"
19209 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
19210 UNSPECV_LDMXCSR)]
19211 "TARGET_MMX"
19212 "ldmxcsr\t%0"
19213 [(set_attr "type" "mmx")
19214 (set_attr "memory" "load")])
19215
19216 (define_insn "stmxcsr"
19217 [(set (match_operand:SI 0 "memory_operand" "=m")
19218 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
19219 "TARGET_MMX"
19220 "stmxcsr\t%0"
19221 [(set_attr "type" "mmx")
19222 (set_attr "memory" "store")])
19223
19224 (define_expand "sfence"
19225 [(set (match_dup 0)
19226 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
19227 "TARGET_SSE || TARGET_3DNOW_A"
19228 {
19229 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19230 MEM_VOLATILE_P (operands[0]) = 1;
19231 })
19232
19233 (define_insn "*sfence_insn"
19234 [(set (match_operand:BLK 0 "" "")
19235 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
19236 "TARGET_SSE || TARGET_3DNOW_A"
19237 "sfence"
19238 [(set_attr "type" "sse")
19239 (set_attr "memory" "unknown")])
19240
19241 (define_expand "sse_prologue_save"
19242 [(parallel [(set (match_operand:BLK 0 "" "")
19243 (unspec:BLK [(reg:DI 21)
19244 (reg:DI 22)
19245 (reg:DI 23)
19246 (reg:DI 24)
19247 (reg:DI 25)
19248 (reg:DI 26)
19249 (reg:DI 27)
19250 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19251 (use (match_operand:DI 1 "register_operand" ""))
19252 (use (match_operand:DI 2 "immediate_operand" ""))
19253 (use (label_ref:DI (match_operand 3 "" "")))])]
19254 "TARGET_64BIT"
19255 "")
19256
19257 (define_insn "*sse_prologue_save_insn"
19258 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19259 (match_operand:DI 4 "const_int_operand" "n")))
19260 (unspec:BLK [(reg:DI 21)
19261 (reg:DI 22)
19262 (reg:DI 23)
19263 (reg:DI 24)
19264 (reg:DI 25)
19265 (reg:DI 26)
19266 (reg:DI 27)
19267 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19268 (use (match_operand:DI 1 "register_operand" "r"))
19269 (use (match_operand:DI 2 "const_int_operand" "i"))
19270 (use (label_ref:DI (match_operand 3 "" "X")))]
19271 "TARGET_64BIT
19272 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19273 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19274 "*
19275 {
19276 int i;
19277 operands[0] = gen_rtx_MEM (Pmode,
19278 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19279 output_asm_insn (\"jmp\\t%A1\", operands);
19280 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19281 {
19282 operands[4] = adjust_address (operands[0], DImode, i*16);
19283 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19284 PUT_MODE (operands[4], TImode);
19285 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19286 output_asm_insn (\"rex\", operands);
19287 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19288 }
19289 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
19290 CODE_LABEL_NUMBER (operands[3]));
19291 RET;
19292 }
19293 "
19294 [(set_attr "type" "other")
19295 (set_attr "length_immediate" "0")
19296 (set_attr "length_address" "0")
19297 (set_attr "length" "135")
19298 (set_attr "memory" "store")
19299 (set_attr "modrm" "0")
19300 (set_attr "mode" "DI")])
19301
19302 ;; 3Dnow! instructions
19303
19304 (define_insn "addv2sf3"
19305 [(set (match_operand:V2SF 0 "register_operand" "=y")
19306 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19307 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19308 "TARGET_3DNOW"
19309 "pfadd\\t{%2, %0|%0, %2}"
19310 [(set_attr "type" "mmxadd")
19311 (set_attr "mode" "V2SF")])
19312
19313 (define_insn "subv2sf3"
19314 [(set (match_operand:V2SF 0 "register_operand" "=y")
19315 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19316 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19317 "TARGET_3DNOW"
19318 "pfsub\\t{%2, %0|%0, %2}"
19319 [(set_attr "type" "mmxadd")
19320 (set_attr "mode" "V2SF")])
19321
19322 (define_insn "subrv2sf3"
19323 [(set (match_operand:V2SF 0 "register_operand" "=y")
19324 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
19325 (match_operand:V2SF 1 "register_operand" "0")))]
19326 "TARGET_3DNOW"
19327 "pfsubr\\t{%2, %0|%0, %2}"
19328 [(set_attr "type" "mmxadd")
19329 (set_attr "mode" "V2SF")])
19330
19331 (define_insn "gtv2sf3"
19332 [(set (match_operand:V2SI 0 "register_operand" "=y")
19333 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
19334 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19335 "TARGET_3DNOW"
19336 "pfcmpgt\\t{%2, %0|%0, %2}"
19337 [(set_attr "type" "mmxcmp")
19338 (set_attr "mode" "V2SF")])
19339
19340 (define_insn "gev2sf3"
19341 [(set (match_operand:V2SI 0 "register_operand" "=y")
19342 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
19343 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19344 "TARGET_3DNOW"
19345 "pfcmpge\\t{%2, %0|%0, %2}"
19346 [(set_attr "type" "mmxcmp")
19347 (set_attr "mode" "V2SF")])
19348
19349 (define_insn "eqv2sf3"
19350 [(set (match_operand:V2SI 0 "register_operand" "=y")
19351 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
19352 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19353 "TARGET_3DNOW"
19354 "pfcmpeq\\t{%2, %0|%0, %2}"
19355 [(set_attr "type" "mmxcmp")
19356 (set_attr "mode" "V2SF")])
19357
19358 (define_insn "pfmaxv2sf3"
19359 [(set (match_operand:V2SF 0 "register_operand" "=y")
19360 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
19361 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19362 "TARGET_3DNOW"
19363 "pfmax\\t{%2, %0|%0, %2}"
19364 [(set_attr "type" "mmxadd")
19365 (set_attr "mode" "V2SF")])
19366
19367 (define_insn "pfminv2sf3"
19368 [(set (match_operand:V2SF 0 "register_operand" "=y")
19369 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
19370 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19371 "TARGET_3DNOW"
19372 "pfmin\\t{%2, %0|%0, %2}"
19373 [(set_attr "type" "mmxadd")
19374 (set_attr "mode" "V2SF")])
19375
19376 (define_insn "mulv2sf3"
19377 [(set (match_operand:V2SF 0 "register_operand" "=y")
19378 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
19379 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19380 "TARGET_3DNOW"
19381 "pfmul\\t{%2, %0|%0, %2}"
19382 [(set_attr "type" "mmxmul")
19383 (set_attr "mode" "V2SF")])
19384
19385 (define_insn "femms"
19386 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
19387 (clobber (reg:XF 8))
19388 (clobber (reg:XF 9))
19389 (clobber (reg:XF 10))
19390 (clobber (reg:XF 11))
19391 (clobber (reg:XF 12))
19392 (clobber (reg:XF 13))
19393 (clobber (reg:XF 14))
19394 (clobber (reg:XF 15))
19395 (clobber (reg:DI 29))
19396 (clobber (reg:DI 30))
19397 (clobber (reg:DI 31))
19398 (clobber (reg:DI 32))
19399 (clobber (reg:DI 33))
19400 (clobber (reg:DI 34))
19401 (clobber (reg:DI 35))
19402 (clobber (reg:DI 36))]
19403 "TARGET_3DNOW"
19404 "femms"
19405 [(set_attr "type" "mmx")])
19406
19407 (define_insn "pf2id"
19408 [(set (match_operand:V2SI 0 "register_operand" "=y")
19409 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
19410 "TARGET_3DNOW"
19411 "pf2id\\t{%1, %0|%0, %1}"
19412 [(set_attr "type" "mmxcvt")
19413 (set_attr "mode" "V2SF")])
19414
19415 (define_insn "pf2iw"
19416 [(set (match_operand:V2SI 0 "register_operand" "=y")
19417 (sign_extend:V2SI
19418 (ss_truncate:V2HI
19419 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
19420 "TARGET_3DNOW_A"
19421 "pf2iw\\t{%1, %0|%0, %1}"
19422 [(set_attr "type" "mmxcvt")
19423 (set_attr "mode" "V2SF")])
19424
19425 (define_insn "pfacc"
19426 [(set (match_operand:V2SF 0 "register_operand" "=y")
19427 (vec_concat:V2SF
19428 (plus:SF
19429 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19430 (parallel [(const_int 0)]))
19431 (vec_select:SF (match_dup 1)
19432 (parallel [(const_int 1)])))
19433 (plus:SF
19434 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19435 (parallel [(const_int 0)]))
19436 (vec_select:SF (match_dup 2)
19437 (parallel [(const_int 1)])))))]
19438 "TARGET_3DNOW"
19439 "pfacc\\t{%2, %0|%0, %2}"
19440 [(set_attr "type" "mmxadd")
19441 (set_attr "mode" "V2SF")])
19442
19443 (define_insn "pfnacc"
19444 [(set (match_operand:V2SF 0 "register_operand" "=y")
19445 (vec_concat:V2SF
19446 (minus:SF
19447 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19448 (parallel [(const_int 0)]))
19449 (vec_select:SF (match_dup 1)
19450 (parallel [(const_int 1)])))
19451 (minus:SF
19452 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19453 (parallel [(const_int 0)]))
19454 (vec_select:SF (match_dup 2)
19455 (parallel [(const_int 1)])))))]
19456 "TARGET_3DNOW_A"
19457 "pfnacc\\t{%2, %0|%0, %2}"
19458 [(set_attr "type" "mmxadd")
19459 (set_attr "mode" "V2SF")])
19460
19461 (define_insn "pfpnacc"
19462 [(set (match_operand:V2SF 0 "register_operand" "=y")
19463 (vec_concat:V2SF
19464 (minus:SF
19465 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19466 (parallel [(const_int 0)]))
19467 (vec_select:SF (match_dup 1)
19468 (parallel [(const_int 1)])))
19469 (plus:SF
19470 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19471 (parallel [(const_int 0)]))
19472 (vec_select:SF (match_dup 2)
19473 (parallel [(const_int 1)])))))]
19474 "TARGET_3DNOW_A"
19475 "pfpnacc\\t{%2, %0|%0, %2}"
19476 [(set_attr "type" "mmxadd")
19477 (set_attr "mode" "V2SF")])
19478
19479 (define_insn "pi2fw"
19480 [(set (match_operand:V2SF 0 "register_operand" "=y")
19481 (float:V2SF
19482 (vec_concat:V2SI
19483 (sign_extend:SI
19484 (truncate:HI
19485 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19486 (parallel [(const_int 0)]))))
19487 (sign_extend:SI
19488 (truncate:HI
19489 (vec_select:SI (match_dup 1)
19490 (parallel [(const_int 1)])))))))]
19491 "TARGET_3DNOW_A"
19492 "pi2fw\\t{%1, %0|%0, %1}"
19493 [(set_attr "type" "mmxcvt")
19494 (set_attr "mode" "V2SF")])
19495
19496 (define_insn "floatv2si2"
19497 [(set (match_operand:V2SF 0 "register_operand" "=y")
19498 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
19499 "TARGET_3DNOW"
19500 "pi2fd\\t{%1, %0|%0, %1}"
19501 [(set_attr "type" "mmxcvt")
19502 (set_attr "mode" "V2SF")])
19503
19504 ;; This insn is identical to pavgb in operation, but the opcode is
19505 ;; different. To avoid accidentally matching pavgb, use an unspec.
19506
19507 (define_insn "pavgusb"
19508 [(set (match_operand:V8QI 0 "register_operand" "=y")
19509 (unspec:V8QI
19510 [(match_operand:V8QI 1 "register_operand" "0")
19511 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
19512 UNSPEC_PAVGUSB))]
19513 "TARGET_3DNOW"
19514 "pavgusb\\t{%2, %0|%0, %2}"
19515 [(set_attr "type" "mmxshft")
19516 (set_attr "mode" "TI")])
19517
19518 ;; 3DNow reciprical and sqrt
19519
19520 (define_insn "pfrcpv2sf2"
19521 [(set (match_operand:V2SF 0 "register_operand" "=y")
19522 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
19523 UNSPEC_PFRCP))]
19524 "TARGET_3DNOW"
19525 "pfrcp\\t{%1, %0|%0, %1}"
19526 [(set_attr "type" "mmx")
19527 (set_attr "mode" "TI")])
19528
19529 (define_insn "pfrcpit1v2sf3"
19530 [(set (match_operand:V2SF 0 "register_operand" "=y")
19531 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19532 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
19533 UNSPEC_PFRCPIT1))]
19534 "TARGET_3DNOW"
19535 "pfrcpit1\\t{%2, %0|%0, %2}"
19536 [(set_attr "type" "mmx")
19537 (set_attr "mode" "TI")])
19538
19539 (define_insn "pfrcpit2v2sf3"
19540 [(set (match_operand:V2SF 0 "register_operand" "=y")
19541 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19542 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
19543 UNSPEC_PFRCPIT2))]
19544 "TARGET_3DNOW"
19545 "pfrcpit2\\t{%2, %0|%0, %2}"
19546 [(set_attr "type" "mmx")
19547 (set_attr "mode" "TI")])
19548
19549 (define_insn "pfrsqrtv2sf2"
19550 [(set (match_operand:V2SF 0 "register_operand" "=y")
19551 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
19552 UNSPEC_PFRSQRT))]
19553 "TARGET_3DNOW"
19554 "pfrsqrt\\t{%1, %0|%0, %1}"
19555 [(set_attr "type" "mmx")
19556 (set_attr "mode" "TI")])
19557
19558 (define_insn "pfrsqit1v2sf3"
19559 [(set (match_operand:V2SF 0 "register_operand" "=y")
19560 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19561 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
19562 UNSPEC_PFRSQIT1))]
19563 "TARGET_3DNOW"
19564 "pfrsqit1\\t{%2, %0|%0, %2}"
19565 [(set_attr "type" "mmx")
19566 (set_attr "mode" "TI")])
19567
19568 (define_insn "pmulhrwv4hi3"
19569 [(set (match_operand:V4HI 0 "register_operand" "=y")
19570 (truncate:V4HI
19571 (lshiftrt:V4SI
19572 (plus:V4SI
19573 (mult:V4SI
19574 (sign_extend:V4SI
19575 (match_operand:V4HI 1 "register_operand" "0"))
19576 (sign_extend:V4SI
19577 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19578 (const_vector:V4SI [(const_int 32768)
19579 (const_int 32768)
19580 (const_int 32768)
19581 (const_int 32768)]))
19582 (const_int 16))))]
19583 "TARGET_3DNOW"
19584 "pmulhrw\\t{%2, %0|%0, %2}"
19585 [(set_attr "type" "mmxmul")
19586 (set_attr "mode" "TI")])
19587
19588 (define_insn "pswapdv2si2"
19589 [(set (match_operand:V2SI 0 "register_operand" "=y")
19590 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19591 (parallel [(const_int 1) (const_int 0)])))]
19592 "TARGET_3DNOW_A"
19593 "pswapd\\t{%1, %0|%0, %1}"
19594 [(set_attr "type" "mmxcvt")
19595 (set_attr "mode" "TI")])
19596
19597 (define_insn "pswapdv2sf2"
19598 [(set (match_operand:V2SF 0 "register_operand" "=y")
19599 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
19600 (parallel [(const_int 1) (const_int 0)])))]
19601 "TARGET_3DNOW_A"
19602 "pswapd\\t{%1, %0|%0, %1}"
19603 [(set_attr "type" "mmxcvt")
19604 (set_attr "mode" "TI")])
19605
19606 (define_expand "prefetch"
19607 [(prefetch (match_operand:SI 0 "address_operand" "")
19608 (match_operand:SI 1 "const_int_operand" "")
19609 (match_operand:SI 2 "const_int_operand" ""))]
19610 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19611 {
19612 int rw = INTVAL (operands[1]);
19613 int locality = INTVAL (operands[2]);
19614
19615 if (rw != 0 && rw != 1)
19616 abort ();
19617 if (locality < 0 || locality > 3)
19618 abort ();
19619
19620 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19621 suported by SSE counterpart or the SSE prefetch is not available
19622 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19623 of locality. */
19624 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19625 operands[2] = GEN_INT (3);
19626 else
19627 operands[1] = const0_rtx;
19628 })
19629
19630 (define_insn "*prefetch_sse"
19631 [(prefetch (match_operand:SI 0 "address_operand" "p")
19632 (const_int 0)
19633 (match_operand:SI 1 "const_int_operand" ""))]
19634 "TARGET_PREFETCH_SSE"
19635 {
19636 static const char * const patterns[4] = {
19637 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19638 };
19639
19640 int locality = INTVAL (operands[1]);
19641 if (locality < 0 || locality > 3)
19642 abort ();
19643
19644 return patterns[locality];
19645 }
19646 [(set_attr "type" "sse")
19647 (set_attr "memory" "none")])
19648
19649 (define_insn "*prefetch_3dnow"
19650 [(prefetch (match_operand:SI 0 "address_operand" "p")
19651 (match_operand:SI 1 "const_int_operand" "n")
19652 (const_int 3))]
19653 "TARGET_3DNOW"
19654 {
19655 if (INTVAL (operands[1]) == 0)
19656 return "prefetch\t%a0";
19657 else
19658 return "prefetchw\t%a0";
19659 }
19660 [(set_attr "type" "mmx")
19661 (set_attr "memory" "none")])
19662
19663 ;; SSE2 support
19664
19665 (define_insn "addv2df3"
19666 [(set (match_operand:V2DF 0 "register_operand" "=x")
19667 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
19668 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19669 "TARGET_SSE2"
19670 "addpd\t{%2, %0|%0, %2}"
19671 [(set_attr "type" "sseadd")
19672 (set_attr "mode" "V2DF")])
19673
19674 (define_insn "vmaddv2df3"
19675 [(set (match_operand:V2DF 0 "register_operand" "=x")
19676 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
19677 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19678 (match_dup 1)
19679 (const_int 1)))]
19680 "TARGET_SSE2"
19681 "addsd\t{%2, %0|%0, %2}"
19682 [(set_attr "type" "sseadd")
19683 (set_attr "mode" "DF")])
19684
19685 (define_insn "subv2df3"
19686 [(set (match_operand:V2DF 0 "register_operand" "=x")
19687 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
19688 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19689 "TARGET_SSE2"
19690 "subpd\t{%2, %0|%0, %2}"
19691 [(set_attr "type" "sseadd")
19692 (set_attr "mode" "V2DF")])
19693
19694 (define_insn "vmsubv2df3"
19695 [(set (match_operand:V2DF 0 "register_operand" "=x")
19696 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
19697 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19698 (match_dup 1)
19699 (const_int 1)))]
19700 "TARGET_SSE2"
19701 "subsd\t{%2, %0|%0, %2}"
19702 [(set_attr "type" "sseadd")
19703 (set_attr "mode" "DF")])
19704
19705 (define_insn "mulv2df3"
19706 [(set (match_operand:V2DF 0 "register_operand" "=x")
19707 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
19708 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19709 "TARGET_SSE2"
19710 "mulpd\t{%2, %0|%0, %2}"
19711 [(set_attr "type" "ssemul")
19712 (set_attr "mode" "V2DF")])
19713
19714 (define_insn "vmmulv2df3"
19715 [(set (match_operand:V2DF 0 "register_operand" "=x")
19716 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
19717 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19718 (match_dup 1)
19719 (const_int 1)))]
19720 "TARGET_SSE2"
19721 "mulsd\t{%2, %0|%0, %2}"
19722 [(set_attr "type" "ssemul")
19723 (set_attr "mode" "DF")])
19724
19725 (define_insn "divv2df3"
19726 [(set (match_operand:V2DF 0 "register_operand" "=x")
19727 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
19728 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19729 "TARGET_SSE2"
19730 "divpd\t{%2, %0|%0, %2}"
19731 [(set_attr "type" "ssediv")
19732 (set_attr "mode" "V2DF")])
19733
19734 (define_insn "vmdivv2df3"
19735 [(set (match_operand:V2DF 0 "register_operand" "=x")
19736 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
19737 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19738 (match_dup 1)
19739 (const_int 1)))]
19740 "TARGET_SSE2"
19741 "divsd\t{%2, %0|%0, %2}"
19742 [(set_attr "type" "ssediv")
19743 (set_attr "mode" "DF")])
19744
19745 ;; SSE min/max
19746
19747 (define_insn "smaxv2df3"
19748 [(set (match_operand:V2DF 0 "register_operand" "=x")
19749 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
19750 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19751 "TARGET_SSE2"
19752 "maxpd\t{%2, %0|%0, %2}"
19753 [(set_attr "type" "sseadd")
19754 (set_attr "mode" "V2DF")])
19755
19756 (define_insn "vmsmaxv2df3"
19757 [(set (match_operand:V2DF 0 "register_operand" "=x")
19758 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
19759 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19760 (match_dup 1)
19761 (const_int 1)))]
19762 "TARGET_SSE2"
19763 "maxsd\t{%2, %0|%0, %2}"
19764 [(set_attr "type" "sseadd")
19765 (set_attr "mode" "DF")])
19766
19767 (define_insn "sminv2df3"
19768 [(set (match_operand:V2DF 0 "register_operand" "=x")
19769 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
19770 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19771 "TARGET_SSE2"
19772 "minpd\t{%2, %0|%0, %2}"
19773 [(set_attr "type" "sseadd")
19774 (set_attr "mode" "V2DF")])
19775
19776 (define_insn "vmsminv2df3"
19777 [(set (match_operand:V2DF 0 "register_operand" "=x")
19778 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
19779 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
19780 (match_dup 1)
19781 (const_int 1)))]
19782 "TARGET_SSE2"
19783 "minsd\t{%2, %0|%0, %2}"
19784 [(set_attr "type" "sseadd")
19785 (set_attr "mode" "DF")])
19786
19787 (define_insn "sse2_anddf3"
19788 [(set (match_operand:V2DF 0 "register_operand" "=x")
19789 (subreg:V2DF (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "%0") 0)
19790 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "xm") 0)) 0))]
19791 "TARGET_SSE2"
19792 "andpd\t{%2, %0|%0, %2}"
19793 [(set_attr "type" "sselog")
19794 (set_attr "mode" "V2DF")])
19795
19796 (define_insn "sse2_nanddf3"
19797 [(set (match_operand:V2DF 0 "register_operand" "=x")
19798 (subreg:V2DF (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "0") 0))
19799 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "xm") 0)) 0))]
19800 "TARGET_SSE2"
19801 "andnpd\t{%2, %0|%0, %2}"
19802 [(set_attr "type" "sselog")
19803 (set_attr "mode" "V2DF")])
19804
19805 (define_insn "sse2_iordf3"
19806 [(set (match_operand:V2DF 0 "register_operand" "=x")
19807 (subreg:V2DF (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "%0") 0)
19808 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "xm") 0)) 0))]
19809 "TARGET_SSE2"
19810 "orpd\t{%2, %0|%0, %2}"
19811 [(set_attr "type" "sselog")
19812 (set_attr "mode" "V2DF")])
19813
19814 (define_insn "sse2_xordf3"
19815 [(set (match_operand:V2DF 0 "register_operand" "=x")
19816 (subreg:V2DF (xor:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "%0") 0)
19817 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "xm") 0)) 0))]
19818 "TARGET_SSE2"
19819 "xorpd\t{%2, %0|%0, %2}"
19820 [(set_attr "type" "sselog")
19821 (set_attr "mode" "V2DF")])
19822 ;; SSE2 square root. There doesn't appear to be an extension for the
19823 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
19824
19825 (define_insn "sqrtv2df2"
19826 [(set (match_operand:V2DF 0 "register_operand" "=x")
19827 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
19828 "TARGET_SSE2"
19829 "sqrtpd\t{%1, %0|%0, %1}"
19830 [(set_attr "type" "sse")
19831 (set_attr "mode" "V2DF")])
19832
19833 (define_insn "vmsqrtv2df2"
19834 [(set (match_operand:V2DF 0 "register_operand" "=x")
19835 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
19836 (match_operand:V2DF 2 "register_operand" "0")
19837 (const_int 1)))]
19838 "TARGET_SSE2"
19839 "sqrtsd\t{%1, %0|%0, %1}"
19840 [(set_attr "type" "sse")
19841 (set_attr "mode" "SF")])
19842
19843 ;; SSE mask-generating compares
19844
19845 (define_insn "maskcmpv2df3"
19846 [(set (match_operand:V2DI 0 "register_operand" "=x")
19847 (match_operator:V2DI 3 "sse_comparison_operator"
19848 [(match_operand:V2DF 1 "register_operand" "0")
19849 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
19850 "TARGET_SSE2"
19851 "cmp%D3pd\t{%2, %0|%0, %2}"
19852 [(set_attr "type" "ssecmp")
19853 (set_attr "mode" "V2DF")])
19854
19855 (define_insn "maskncmpv2df3"
19856 [(set (match_operand:V2DI 0 "register_operand" "=x")
19857 (not:V2DI
19858 (match_operator:V2DI 3 "sse_comparison_operator"
19859 [(match_operand:V2DF 1 "register_operand" "0")
19860 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
19861 "TARGET_SSE2"
19862 "cmpn%D3pd\t{%2, %0|%0, %2}"
19863 [(set_attr "type" "ssecmp")
19864 (set_attr "mode" "V2DF")])
19865
19866 (define_insn "vmmaskcmpv2df3"
19867 [(set (match_operand:V2DI 0 "register_operand" "=x")
19868 (vec_merge:V2DI
19869 (match_operator:V2DI 3 "sse_comparison_operator"
19870 [(match_operand:V2DF 1 "register_operand" "0")
19871 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
19872 (match_dup 1)
19873 (const_int 1)))]
19874 "TARGET_SSE2"
19875 "cmp%D3sd\t{%2, %0|%0, %2}"
19876 [(set_attr "type" "ssecmp")
19877 (set_attr "mode" "DF")])
19878
19879 (define_insn "vmmaskncmpv2df3"
19880 [(set (match_operand:V2DI 0 "register_operand" "=x")
19881 (vec_merge:V2DI
19882 (not:V2DI
19883 (match_operator:V2DI 3 "sse_comparison_operator"
19884 [(match_operand:V2DF 1 "register_operand" "0")
19885 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
19886 (subreg:V2DI (match_dup 1) 0)
19887 (const_int 1)))]
19888 "TARGET_SSE2"
19889 "cmp%D3sd\t{%2, %0|%0, %2}"
19890 [(set_attr "type" "ssecmp")
19891 (set_attr "mode" "DF")])
19892
19893 (define_insn "sse2_comi"
19894 [(set (reg:CCFP 17)
19895 (match_operator:CCFP 2 "sse_comparison_operator"
19896 [(vec_select:DF
19897 (match_operand:V2DF 0 "register_operand" "x")
19898 (parallel [(const_int 0)]))
19899 (vec_select:DF
19900 (match_operand:V2DF 1 "register_operand" "x")
19901 (parallel [(const_int 0)]))]))]
19902 "TARGET_SSE2"
19903 "comisd\t{%1, %0|%0, %1}"
19904 [(set_attr "type" "ssecmp")
19905 (set_attr "mode" "DF")])
19906
19907 (define_insn "sse2_ucomi"
19908 [(set (reg:CCFPU 17)
19909 (match_operator:CCFPU 2 "sse_comparison_operator"
19910 [(vec_select:DF
19911 (match_operand:V2DF 0 "register_operand" "x")
19912 (parallel [(const_int 0)]))
19913 (vec_select:DF
19914 (match_operand:V2DF 1 "register_operand" "x")
19915 (parallel [(const_int 0)]))]))]
19916 "TARGET_SSE2"
19917 "ucomisd\t{%1, %0|%0, %1}"
19918 [(set_attr "type" "ssecmp")
19919 (set_attr "mode" "DF")])
19920
19921 ;; SSE Strange Moves.
19922
19923 (define_insn "sse2_movmskpd"
19924 [(set (match_operand:SI 0 "register_operand" "=r")
19925 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
19926 UNSPEC_MOVMSK))]
19927 "TARGET_SSE2"
19928 "movmskpd\t{%1, %0|%0, %1}"
19929 [(set_attr "type" "ssecvt")
19930 (set_attr "mode" "V2DF")])
19931
19932 (define_insn "sse2_pmovmskb"
19933 [(set (match_operand:SI 0 "register_operand" "=r")
19934 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
19935 UNSPEC_MOVMSK))]
19936 "TARGET_SSE2"
19937 "pmovmskb\t{%1, %0|%0, %1}"
19938 [(set_attr "type" "ssecvt")
19939 (set_attr "mode" "V2DF")])
19940
19941 (define_insn "sse2_maskmovdqu"
19942 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
19943 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
19944 (match_operand:V16QI 2 "register_operand" "x")]
19945 UNSPEC_MASKMOV))]
19946 "TARGET_SSE2"
19947 ;; @@@ check ordering of operands in intel/nonintel syntax
19948 "maskmovdqu\t{%2, %1|%1, %2}"
19949 [(set_attr "type" "ssecvt")
19950 (set_attr "mode" "TI")])
19951
19952 (define_insn "sse2_movntv2df"
19953 [(set (match_operand:V2DF 0 "memory_operand" "=m")
19954 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
19955 UNSPEC_MOVNT))]
19956 "TARGET_SSE2"
19957 "movntpd\t{%1, %0|%0, %1}"
19958 [(set_attr "type" "ssecvt")
19959 (set_attr "mode" "V2DF")])
19960
19961 (define_insn "sse2_movntv2di"
19962 [(set (match_operand:V2DI 0 "memory_operand" "=m")
19963 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
19964 UNSPEC_MOVNT))]
19965 "TARGET_SSE2"
19966 "movntdq\t{%1, %0|%0, %1}"
19967 [(set_attr "type" "ssecvt")
19968 (set_attr "mode" "TI")])
19969
19970 (define_insn "sse2_movntsi"
19971 [(set (match_operand:SI 0 "memory_operand" "=m")
19972 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
19973 UNSPEC_MOVNT))]
19974 "TARGET_SSE2"
19975 "movnti\t{%1, %0|%0, %1}"
19976 [(set_attr "type" "ssecvt")
19977 (set_attr "mode" "V2DF")])
19978
19979 ;; SSE <-> integer/MMX conversions
19980
19981 ;; Conversions between SI and SF
19982
19983 (define_insn "cvtdq2ps"
19984 [(set (match_operand:V4SF 0 "register_operand" "=x")
19985 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
19986 "TARGET_SSE2"
19987 "cvtdq2ps\t{%1, %0|%0, %1}"
19988 [(set_attr "type" "ssecvt")
19989 (set_attr "mode" "V2DF")])
19990
19991 (define_insn "cvtps2dq"
19992 [(set (match_operand:V4SI 0 "register_operand" "=x")
19993 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19994 "TARGET_SSE2"
19995 "cvtps2dq\t{%1, %0|%0, %1}"
19996 [(set_attr "type" "ssecvt")
19997 (set_attr "mode" "TI")])
19998
19999 (define_insn "cvttps2dq"
20000 [(set (match_operand:V4SI 0 "register_operand" "=x")
20001 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20002 UNSPEC_FIX))]
20003 "TARGET_SSE2"
20004 "cvttps2dq\t{%1, %0|%0, %1}"
20005 [(set_attr "type" "ssecvt")
20006 (set_attr "mode" "TI")])
20007
20008 ;; Conversions between SI and DF
20009
20010 (define_insn "cvtdq2pd"
20011 [(set (match_operand:V2DF 0 "register_operand" "=x")
20012 (float:V2DF (vec_select:V2SI
20013 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
20014 (parallel
20015 [(const_int 0)
20016 (const_int 1)]))))]
20017 "TARGET_SSE2"
20018 "cvtdq2pd\t{%1, %0|%0, %1}"
20019 [(set_attr "type" "ssecvt")
20020 (set_attr "mode" "V2DF")])
20021
20022 (define_insn "cvtpd2dq"
20023 [(set (match_operand:V4SI 0 "register_operand" "=x")
20024 (vec_concat:V4SI
20025 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
20026 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
20027 "TARGET_SSE2"
20028 "cvtpd2dq\t{%1, %0|%0, %1}"
20029 [(set_attr "type" "ssecvt")
20030 (set_attr "mode" "TI")])
20031
20032 (define_insn "cvttpd2dq"
20033 [(set (match_operand:V4SI 0 "register_operand" "=x")
20034 (vec_concat:V4SI
20035 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
20036 UNSPEC_FIX)
20037 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
20038 "TARGET_SSE2"
20039 "cvttpd2dq\t{%1, %0|%0, %1}"
20040 [(set_attr "type" "ssecvt")
20041 (set_attr "mode" "TI")])
20042
20043 (define_insn "cvtpd2pi"
20044 [(set (match_operand:V2SI 0 "register_operand" "=y")
20045 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
20046 "TARGET_SSE2"
20047 "cvtpd2pi\t{%1, %0|%0, %1}"
20048 [(set_attr "type" "ssecvt")
20049 (set_attr "mode" "TI")])
20050
20051 (define_insn "cvttpd2pi"
20052 [(set (match_operand:V2SI 0 "register_operand" "=y")
20053 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
20054 UNSPEC_FIX))]
20055 "TARGET_SSE2"
20056 "cvttpd2pi\t{%1, %0|%0, %1}"
20057 [(set_attr "type" "ssecvt")
20058 (set_attr "mode" "TI")])
20059
20060 (define_insn "cvtpi2pd"
20061 [(set (match_operand:V2DF 0 "register_operand" "=x")
20062 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
20063 "TARGET_SSE2"
20064 "cvtpi2pd\t{%1, %0|%0, %1}"
20065 [(set_attr "type" "ssecvt")
20066 (set_attr "mode" "TI")])
20067
20068 ;; Conversions between SI and DF
20069
20070 (define_insn "cvtsd2si"
20071 [(set (match_operand:SI 0 "register_operand" "=r")
20072 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
20073 (parallel [(const_int 0)]))))]
20074 "TARGET_SSE2"
20075 "cvtsd2si\t{%1, %0|%0, %1}"
20076 [(set_attr "type" "ssecvt")
20077 (set_attr "mode" "SI")])
20078
20079 (define_insn "cvttsd2si"
20080 [(set (match_operand:SI 0 "register_operand" "=r")
20081 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
20082 (parallel [(const_int 0)]))] UNSPEC_FIX))]
20083 "TARGET_SSE2"
20084 "cvttsd2si\t{%1, %0|%0, %1}"
20085 [(set_attr "type" "ssecvt")
20086 (set_attr "mode" "SI")])
20087
20088 (define_insn "cvtsi2sd"
20089 [(set (match_operand:V2DF 0 "register_operand" "=x")
20090 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
20091 (vec_duplicate:V2DF
20092 (float:DF
20093 (match_operand:SI 2 "nonimmediate_operand" "rm")))
20094 (const_int 2)))]
20095 "TARGET_SSE2"
20096 "cvtsd2si\t{%2, %0|%0, %2}"
20097 [(set_attr "type" "ssecvt")
20098 (set_attr "mode" "DF")])
20099
20100 ;; Conversions between SF and DF
20101
20102 (define_insn "cvtsd2ss"
20103 [(set (match_operand:V4SF 0 "register_operand" "=x")
20104 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
20105 (vec_duplicate:V4SF
20106 (float_truncate:V2SF
20107 (match_operand:V2DF 2 "register_operand" "xm")))
20108 (const_int 14)))]
20109 "TARGET_SSE2"
20110 "cvtsd2ss\t{%2, %0|%0, %2}"
20111 [(set_attr "type" "ssecvt")
20112 (set_attr "mode" "SF")])
20113
20114 (define_insn "cvtss2sd"
20115 [(set (match_operand:V2DF 0 "register_operand" "=x")
20116 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
20117 (float_extend:V2DF
20118 (vec_select:V2SF
20119 (match_operand:V4SF 2 "register_operand" "xm")
20120 (parallel [(const_int 0)
20121 (const_int 1)])))
20122 (const_int 2)))]
20123 "TARGET_SSE2"
20124 "cvtss2sd\t{%2, %0|%0, %2}"
20125 [(set_attr "type" "ssecvt")
20126 (set_attr "mode" "DF")])
20127
20128 (define_insn "cvtpd2ps"
20129 [(set (match_operand:V4SF 0 "register_operand" "=x")
20130 (subreg:V4SF
20131 (vec_concat:V4SI
20132 (subreg:V2SI (float_truncate:V2SF
20133 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
20134 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
20135 "TARGET_SSE2"
20136 "cvtpd2ps\t{%1, %0|%0, %1}"
20137 [(set_attr "type" "ssecvt")
20138 (set_attr "mode" "V4SF")])
20139
20140 (define_insn "cvtps2pd"
20141 [(set (match_operand:V2DF 0 "register_operand" "=x")
20142 (float_extend:V2DF
20143 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
20144 (parallel [(const_int 0)
20145 (const_int 1)]))))]
20146 "TARGET_SSE2"
20147 "cvtps2pd\t{%1, %0|%0, %1}"
20148 [(set_attr "type" "ssecvt")
20149 (set_attr "mode" "V2DF")])
20150
20151 ;; SSE2 variants of MMX insns
20152
20153 ;; MMX arithmetic
20154
20155 (define_insn "addv16qi3"
20156 [(set (match_operand:V16QI 0 "register_operand" "=x")
20157 (plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20158 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20159 "TARGET_SSE2"
20160 "paddb\t{%2, %0|%0, %2}"
20161 [(set_attr "type" "sseiadd")
20162 (set_attr "mode" "TI")])
20163
20164 (define_insn "addv8hi3"
20165 [(set (match_operand:V8HI 0 "register_operand" "=x")
20166 (plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20167 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20168 "TARGET_SSE2"
20169 "paddw\t{%2, %0|%0, %2}"
20170 [(set_attr "type" "sseiadd")
20171 (set_attr "mode" "TI")])
20172
20173 (define_insn "addv4si3"
20174 [(set (match_operand:V4SI 0 "register_operand" "=x")
20175 (plus:V4SI (match_operand:V4SI 1 "register_operand" "0")
20176 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
20177 "TARGET_SSE2"
20178 "paddd\t{%2, %0|%0, %2}"
20179 [(set_attr "type" "sseiadd")
20180 (set_attr "mode" "TI")])
20181
20182 (define_insn "addv2di3"
20183 [(set (match_operand:V2DI 0 "register_operand" "=x")
20184 (plus:V2DI (match_operand:V2DI 1 "register_operand" "0")
20185 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20186 "TARGET_SSE2"
20187 "paddq\t{%2, %0|%0, %2}"
20188 [(set_attr "type" "sseiadd")
20189 (set_attr "mode" "TI")])
20190
20191 (define_insn "ssaddv16qi3"
20192 [(set (match_operand:V16QI 0 "register_operand" "=x")
20193 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20194 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20195 "TARGET_SSE2"
20196 "paddsb\t{%2, %0|%0, %2}"
20197 [(set_attr "type" "sseiadd")
20198 (set_attr "mode" "TI")])
20199
20200 (define_insn "ssaddv8hi3"
20201 [(set (match_operand:V8HI 0 "register_operand" "=x")
20202 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20203 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20204 "TARGET_SSE2"
20205 "paddsw\t{%2, %0|%0, %2}"
20206 [(set_attr "type" "sseiadd")
20207 (set_attr "mode" "TI")])
20208
20209 (define_insn "usaddv16qi3"
20210 [(set (match_operand:V16QI 0 "register_operand" "=x")
20211 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20212 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20213 "TARGET_SSE2"
20214 "paddusb\t{%2, %0|%0, %2}"
20215 [(set_attr "type" "sseiadd")
20216 (set_attr "mode" "TI")])
20217
20218 (define_insn "usaddv8hi3"
20219 [(set (match_operand:V8HI 0 "register_operand" "=x")
20220 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20221 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20222 "TARGET_SSE2"
20223 "paddusw\t{%2, %0|%0, %2}"
20224 [(set_attr "type" "sseiadd")
20225 (set_attr "mode" "TI")])
20226
20227 (define_insn "subv16qi3"
20228 [(set (match_operand:V16QI 0 "register_operand" "=x")
20229 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20230 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20231 "TARGET_SSE2"
20232 "psubb\t{%2, %0|%0, %2}"
20233 [(set_attr "type" "sseiadd")
20234 (set_attr "mode" "TI")])
20235
20236 (define_insn "subv8hi3"
20237 [(set (match_operand:V8HI 0 "register_operand" "=x")
20238 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20239 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20240 "TARGET_SSE2"
20241 "psubw\t{%2, %0|%0, %2}"
20242 [(set_attr "type" "sseiadd")
20243 (set_attr "mode" "TI")])
20244
20245 (define_insn "subv4si3"
20246 [(set (match_operand:V4SI 0 "register_operand" "=x")
20247 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
20248 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
20249 "TARGET_SSE2"
20250 "psubd\t{%2, %0|%0, %2}"
20251 [(set_attr "type" "sseiadd")
20252 (set_attr "mode" "TI")])
20253
20254 (define_insn "subv2di3"
20255 [(set (match_operand:V2DI 0 "register_operand" "=x")
20256 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
20257 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20258 "TARGET_SSE2"
20259 "psubq\t{%2, %0|%0, %2}"
20260 [(set_attr "type" "sseiadd")
20261 (set_attr "mode" "TI")])
20262
20263 (define_insn "sssubv16qi3"
20264 [(set (match_operand:V16QI 0 "register_operand" "=x")
20265 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20266 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20267 "TARGET_SSE2"
20268 "psubsb\t{%2, %0|%0, %2}"
20269 [(set_attr "type" "sseiadd")
20270 (set_attr "mode" "TI")])
20271
20272 (define_insn "sssubv8hi3"
20273 [(set (match_operand:V8HI 0 "register_operand" "=x")
20274 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20275 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20276 "TARGET_SSE2"
20277 "psubsw\t{%2, %0|%0, %2}"
20278 [(set_attr "type" "sseiadd")
20279 (set_attr "mode" "TI")])
20280
20281 (define_insn "ussubv16qi3"
20282 [(set (match_operand:V16QI 0 "register_operand" "=x")
20283 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
20284 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20285 "TARGET_SSE2"
20286 "psubusb\t{%2, %0|%0, %2}"
20287 [(set_attr "type" "sseiadd")
20288 (set_attr "mode" "TI")])
20289
20290 (define_insn "ussubv8hi3"
20291 [(set (match_operand:V8HI 0 "register_operand" "=x")
20292 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
20293 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20294 "TARGET_SSE2"
20295 "psubusw\t{%2, %0|%0, %2}"
20296 [(set_attr "type" "sseiadd")
20297 (set_attr "mode" "TI")])
20298
20299 (define_insn "mulv8hi3"
20300 [(set (match_operand:V8HI 0 "register_operand" "=x")
20301 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
20302 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20303 "TARGET_SSE2"
20304 "pmullw\t{%2, %0|%0, %2}"
20305 [(set_attr "type" "sseimul")
20306 (set_attr "mode" "TI")])
20307
20308 (define_insn "smulv8hi3_highpart"
20309 [(set (match_operand:V8HI 0 "register_operand" "=x")
20310 (truncate:V8HI
20311 (lshiftrt:V8SI
20312 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
20313 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
20314 (const_int 16))))]
20315 "TARGET_SSE2"
20316 "pmulhw\t{%2, %0|%0, %2}"
20317 [(set_attr "type" "sseimul")
20318 (set_attr "mode" "TI")])
20319
20320 (define_insn "umulv8hi3_highpart"
20321 [(set (match_operand:V8HI 0 "register_operand" "=x")
20322 (truncate:V8HI
20323 (lshiftrt:V8SI
20324 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
20325 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
20326 (const_int 16))))]
20327 "TARGET_SSE2"
20328 "pmulhuw\t{%2, %0|%0, %2}"
20329 [(set_attr "type" "sseimul")
20330 (set_attr "mode" "TI")])
20331
20332 (define_insn "sse2_umulsidi3"
20333 [(set (match_operand:DI 0 "register_operand" "=y")
20334 (mult:DI (zero_extend:DI (vec_select:SI
20335 (match_operand:V2SI 1 "register_operand" "0")
20336 (parallel [(const_int 0)])))
20337 (zero_extend:DI (vec_select:SI
20338 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
20339 (parallel [(const_int 0)])))))]
20340 "TARGET_SSE2"
20341 "pmuludq\t{%2, %0|%0, %2}"
20342 [(set_attr "type" "sseimul")
20343 (set_attr "mode" "TI")])
20344
20345 (define_insn "sse2_umulv2siv2di3"
20346 [(set (match_operand:V2DI 0 "register_operand" "=y")
20347 (mult:V2DI (zero_extend:V2DI
20348 (vec_select:V2SI
20349 (match_operand:V4SI 1 "register_operand" "0")
20350 (parallel [(const_int 0) (const_int 2)])))
20351 (zero_extend:V2DI
20352 (vec_select:V2SI
20353 (match_operand:V4SI 2 "nonimmediate_operand" "ym")
20354 (parallel [(const_int 0) (const_int 2)])))))]
20355 "TARGET_SSE2"
20356 "pmuludq\t{%2, %0|%0, %2}"
20357 [(set_attr "type" "sseimul")
20358 (set_attr "mode" "TI")])
20359
20360 (define_insn "sse2_pmaddwd"
20361 [(set (match_operand:V4SI 0 "register_operand" "=x")
20362 (plus:V4SI
20363 (mult:V4SI
20364 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
20365 (parallel [(const_int 0)
20366 (const_int 2)
20367 (const_int 4)
20368 (const_int 6)])))
20369 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
20370 (parallel [(const_int 0)
20371 (const_int 2)
20372 (const_int 4)
20373 (const_int 6)]))))
20374 (mult:V4SI
20375 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
20376 (parallel [(const_int 1)
20377 (const_int 3)
20378 (const_int 5)
20379 (const_int 7)])))
20380 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
20381 (parallel [(const_int 1)
20382 (const_int 3)
20383 (const_int 5)
20384 (const_int 7)]))))))]
20385 "TARGET_SSE2"
20386 "pmaddwd\t{%2, %0|%0, %2}"
20387 [(set_attr "type" "sseiadd")
20388 (set_attr "mode" "TI")])
20389
20390 ;; Same as pxor, but don't show input operands so that we don't think
20391 ;; they are live.
20392 (define_insn "sse2_clrti"
20393 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
20394 "TARGET_SSE2"
20395 "pxor\t{%0, %0|%0, %0}"
20396 [(set_attr "type" "sseiadd")
20397 (set_attr "memory" "none")
20398 (set_attr "mode" "TI")])
20399
20400 ;; MMX unsigned averages/sum of absolute differences
20401
20402 (define_insn "sse2_uavgv16qi3"
20403 [(set (match_operand:V16QI 0 "register_operand" "=x")
20404 (ashiftrt:V16QI
20405 (plus:V16QI (plus:V16QI
20406 (match_operand:V16QI 1 "register_operand" "0")
20407 (match_operand:V16QI 2 "nonimmediate_operand" "ym"))
20408 (const_vector:V16QI [(const_int 1) (const_int 1)
20409 (const_int 1) (const_int 1)
20410 (const_int 1) (const_int 1)
20411 (const_int 1) (const_int 1)
20412 (const_int 1) (const_int 1)
20413 (const_int 1) (const_int 1)
20414 (const_int 1) (const_int 1)
20415 (const_int 1) (const_int 1)]))
20416 (const_int 1)))]
20417 "TARGET_SSE2"
20418 "pavgb\t{%2, %0|%0, %2}"
20419 [(set_attr "type" "sseiadd")
20420 (set_attr "mode" "TI")])
20421
20422 (define_insn "sse2_uavgv8hi3"
20423 [(set (match_operand:V8HI 0 "register_operand" "=x")
20424 (ashiftrt:V8HI
20425 (plus:V8HI (plus:V8HI
20426 (match_operand:V8HI 1 "register_operand" "0")
20427 (match_operand:V8HI 2 "nonimmediate_operand" "ym"))
20428 (const_vector:V8HI [(const_int 1) (const_int 1)
20429 (const_int 1) (const_int 1)
20430 (const_int 1) (const_int 1)
20431 (const_int 1) (const_int 1)]))
20432 (const_int 1)))]
20433 "TARGET_SSE2"
20434 "pavgw\t{%2, %0|%0, %2}"
20435 [(set_attr "type" "sseiadd")
20436 (set_attr "mode" "TI")])
20437
20438 ;; @@@ this isn't the right representation.
20439 (define_insn "sse2_psadbw"
20440 [(set (match_operand:V2DI 0 "register_operand" "=x")
20441 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
20442 (match_operand:V16QI 2 "nonimmediate_operand" "ym")]
20443 UNSPEC_PSADBW))]
20444 "TARGET_SSE2"
20445 "psadbw\t{%2, %0|%0, %2}"
20446 [(set_attr "type" "sseiadd")
20447 (set_attr "mode" "TI")])
20448
20449
20450 ;; MMX insert/extract/shuffle
20451
20452 (define_insn "sse2_pinsrw"
20453 [(set (match_operand:V8HI 0 "register_operand" "=x")
20454 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
20455 (vec_duplicate:V8HI
20456 (match_operand:SI 2 "nonimmediate_operand" "rm"))
20457 (match_operand:SI 3 "immediate_operand" "i")))]
20458 "TARGET_SSE2"
20459 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20460 [(set_attr "type" "ssecvt")
20461 (set_attr "mode" "TI")])
20462
20463 (define_insn "sse2_pextrw"
20464 [(set (match_operand:SI 0 "register_operand" "=r")
20465 (zero_extend:SI
20466 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
20467 (parallel
20468 [(match_operand:SI 2 "immediate_operand" "i")]))))]
20469 "TARGET_SSE2"
20470 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20471 [(set_attr "type" "ssecvt")
20472 (set_attr "mode" "TI")])
20473
20474 (define_insn "sse2_pshufd"
20475 [(set (match_operand:V4SI 0 "register_operand" "=x")
20476 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
20477 (match_operand:SI 2 "immediate_operand" "i")]
20478 UNSPEC_SHUFFLE))]
20479 "TARGET_SSE2"
20480 "pshufd\t{%2, %1, %0|%0, %1, %2}"
20481 [(set_attr "type" "ssecvt")
20482 (set_attr "mode" "TI")])
20483
20484 (define_insn "sse2_pshuflw"
20485 [(set (match_operand:V8HI 0 "register_operand" "=x")
20486 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
20487 (match_operand:SI 2 "immediate_operand" "i")]
20488 UNSPEC_PSHUFLW))]
20489 "TARGET_SSE2"
20490 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
20491 [(set_attr "type" "ssecvt")
20492 (set_attr "mode" "TI")])
20493
20494 (define_insn "sse2_pshufhw"
20495 [(set (match_operand:V8HI 0 "register_operand" "=x")
20496 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
20497 (match_operand:SI 2 "immediate_operand" "i")]
20498 UNSPEC_PSHUFHW))]
20499 "TARGET_SSE2"
20500 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
20501 [(set_attr "type" "ssecvt")
20502 (set_attr "mode" "TI")])
20503
20504 ;; MMX mask-generating comparisons
20505
20506 (define_insn "eqv16qi3"
20507 [(set (match_operand:V16QI 0 "register_operand" "=x")
20508 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
20509 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20510 "TARGET_SSE2"
20511 "pcmpeqb\t{%2, %0|%0, %2}"
20512 [(set_attr "type" "ssecmp")
20513 (set_attr "mode" "TI")])
20514
20515 (define_insn "eqv8hi3"
20516 [(set (match_operand:V8HI 0 "register_operand" "=x")
20517 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
20518 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20519 "TARGET_SSE2"
20520 "pcmpeqw\t{%2, %0|%0, %2}"
20521 [(set_attr "type" "ssecmp")
20522 (set_attr "mode" "TI")])
20523
20524 (define_insn "eqv4si3"
20525 [(set (match_operand:V4SI 0 "register_operand" "=x")
20526 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
20527 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
20528 "TARGET_SSE2"
20529 "pcmpeqd\t{%2, %0|%0, %2}"
20530 [(set_attr "type" "ssecmp")
20531 (set_attr "mode" "TI")])
20532
20533 (define_insn "gtv16qi3"
20534 [(set (match_operand:V16QI 0 "register_operand" "=x")
20535 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
20536 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20537 "TARGET_SSE2"
20538 "pcmpgtb\t{%2, %0|%0, %2}"
20539 [(set_attr "type" "ssecmp")
20540 (set_attr "mode" "TI")])
20541
20542 (define_insn "gtv8hi3"
20543 [(set (match_operand:V8HI 0 "register_operand" "=x")
20544 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20545 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20546 "TARGET_SSE2"
20547 "pcmpgtw\t{%2, %0|%0, %2}"
20548 [(set_attr "type" "ssecmp")
20549 (set_attr "mode" "TI")])
20550
20551 (define_insn "gtv4si3"
20552 [(set (match_operand:V4SI 0 "register_operand" "=x")
20553 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20554 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
20555 "TARGET_SSE2"
20556 "pcmpgtd\t{%2, %0|%0, %2}"
20557 [(set_attr "type" "ssecmp")
20558 (set_attr "mode" "TI")])
20559
20560
20561 ;; MMX max/min insns
20562
20563 (define_insn "umaxv16qi3"
20564 [(set (match_operand:V16QI 0 "register_operand" "=x")
20565 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
20566 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20567 "TARGET_SSE2"
20568 "pmaxub\t{%2, %0|%0, %2}"
20569 [(set_attr "type" "sseiadd")
20570 (set_attr "mode" "TI")])
20571
20572 (define_insn "smaxv8hi3"
20573 [(set (match_operand:V8HI 0 "register_operand" "=x")
20574 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
20575 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20576 "TARGET_SSE2"
20577 "pmaxsw\t{%2, %0|%0, %2}"
20578 [(set_attr "type" "sseiadd")
20579 (set_attr "mode" "TI")])
20580
20581 (define_insn "uminv16qi3"
20582 [(set (match_operand:V16QI 0 "register_operand" "=x")
20583 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
20584 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
20585 "TARGET_SSE2"
20586 "pminub\t{%2, %0|%0, %2}"
20587 [(set_attr "type" "sseiadd")
20588 (set_attr "mode" "TI")])
20589
20590 (define_insn "sminv8hi3"
20591 [(set (match_operand:V8HI 0 "register_operand" "=x")
20592 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
20593 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
20594 "TARGET_SSE2"
20595 "pminsw\t{%2, %0|%0, %2}"
20596 [(set_attr "type" "sseiadd")
20597 (set_attr "mode" "TI")])
20598
20599
20600 ;; MMX shifts
20601
20602 (define_insn "ashrv8hi3"
20603 [(set (match_operand:V8HI 0 "register_operand" "=x")
20604 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20605 (match_operand:SI 2 "nonmemory_operand" "ri")))]
20606 "TARGET_SSE2"
20607 "psraw\t{%2, %0|%0, %2}"
20608 [(set_attr "type" "sseishft")
20609 (set_attr "mode" "TI")])
20610
20611 (define_insn "ashrv4si3"
20612 [(set (match_operand:V4SI 0 "register_operand" "=x")
20613 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20614 (match_operand:SI 2 "nonmemory_operand" "ri")))]
20615 "TARGET_SSE2"
20616 "psrad\t{%2, %0|%0, %2}"
20617 [(set_attr "type" "sseishft")
20618 (set_attr "mode" "TI")])
20619
20620 (define_insn "lshrv8hi3"
20621 [(set (match_operand:V8HI 0 "register_operand" "=x")
20622 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20623 (match_operand:SI 2 "nonmemory_operand" "ri")))]
20624 "TARGET_SSE2"
20625 "psrlw\t{%2, %0|%0, %2}"
20626 [(set_attr "type" "sseishft")
20627 (set_attr "mode" "TI")])
20628
20629 (define_insn "lshrv4si3"
20630 [(set (match_operand:V4SI 0 "register_operand" "=x")
20631 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20632 (match_operand:SI 2 "nonmemory_operand" "ri")))]
20633 "TARGET_SSE2"
20634 "psrld\t{%2, %0|%0, %2}"
20635 [(set_attr "type" "sseishft")
20636 (set_attr "mode" "TI")])
20637
20638 (define_insn "lshrv2di3"
20639 [(set (match_operand:V2DI 0 "register_operand" "=x")
20640 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
20641 (match_operand:SI 2 "nonmemory_operand" "ri")))]
20642 "TARGET_SSE2"
20643 "psrlq\t{%2, %0|%0, %2}"
20644 [(set_attr "type" "sseishft")
20645 (set_attr "mode" "TI")])
20646
20647 (define_insn "ashlv8hi3"
20648 [(set (match_operand:V8HI 0 "register_operand" "=x")
20649 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
20650 (match_operand:SI 2 "nonmemory_operand" "ri")))]
20651 "TARGET_SSE2"
20652 "psllw\t{%2, %0|%0, %2}"
20653 [(set_attr "type" "sseishft")
20654 (set_attr "mode" "TI")])
20655
20656 (define_insn "ashlv4si3"
20657 [(set (match_operand:V4SI 0 "register_operand" "=x")
20658 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
20659 (match_operand:SI 2 "nonmemory_operand" "ri")))]
20660 "TARGET_SSE2"
20661 "pslld\t{%2, %0|%0, %2}"
20662 [(set_attr "type" "sseishft")
20663 (set_attr "mode" "TI")])
20664
20665 (define_insn "ashlv2di3"
20666 [(set (match_operand:V2DI 0 "register_operand" "=x")
20667 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
20668 (match_operand:SI 2 "nonmemory_operand" "ri")))]
20669 "TARGET_SSE2"
20670 "psllq\t{%2, %0|%0, %2}"
20671 [(set_attr "type" "sseishft")
20672 (set_attr "mode" "TI")])
20673
20674 (define_insn "ashrv8hi3_ti"
20675 [(set (match_operand:V8HI 0 "register_operand" "=x")
20676 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20677 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20678 "TARGET_SSE2"
20679 "psraw\t{%2, %0|%0, %2}"
20680 [(set_attr "type" "sseishft")
20681 (set_attr "mode" "TI")])
20682
20683 (define_insn "ashrv4si3_ti"
20684 [(set (match_operand:V4SI 0 "register_operand" "=x")
20685 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20686 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20687 "TARGET_SSE2"
20688 "psrad\t{%2, %0|%0, %2}"
20689 [(set_attr "type" "sseishft")
20690 (set_attr "mode" "TI")])
20691
20692 (define_insn "lshrv8hi3_ti"
20693 [(set (match_operand:V8HI 0 "register_operand" "=x")
20694 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
20695 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20696 "TARGET_SSE2"
20697 "psrlw\t{%2, %0|%0, %2}"
20698 [(set_attr "type" "sseishft")
20699 (set_attr "mode" "TI")])
20700
20701 (define_insn "lshrv4si3_ti"
20702 [(set (match_operand:V4SI 0 "register_operand" "=x")
20703 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
20704 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20705 "TARGET_SSE2"
20706 "psrld\t{%2, %0|%0, %2}"
20707 [(set_attr "type" "sseishft")
20708 (set_attr "mode" "TI")])
20709
20710 (define_insn "lshrv2di3_ti"
20711 [(set (match_operand:V2DI 0 "register_operand" "=x")
20712 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
20713 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20714 "TARGET_SSE2"
20715 "psrlq\t{%2, %0|%0, %2}"
20716 [(set_attr "type" "sseishft")
20717 (set_attr "mode" "TI")])
20718
20719 (define_insn "ashlv8hi3_ti"
20720 [(set (match_operand:V8HI 0 "register_operand" "=x")
20721 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
20722 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20723 "TARGET_SSE2"
20724 "psllw\t{%2, %0|%0, %2}"
20725 [(set_attr "type" "sseishft")
20726 (set_attr "mode" "TI")])
20727
20728 (define_insn "ashlv4si3_ti"
20729 [(set (match_operand:V4SI 0 "register_operand" "=x")
20730 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
20731 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20732 "TARGET_SSE2"
20733 "pslld\t{%2, %0|%0, %2}"
20734 [(set_attr "type" "sseishft")
20735 (set_attr "mode" "TI")])
20736
20737 (define_insn "ashlv2di3_ti"
20738 [(set (match_operand:V2DI 0 "register_operand" "=x")
20739 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
20740 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
20741 "TARGET_SSE2"
20742 "psllq\t{%2, %0|%0, %2}"
20743 [(set_attr "type" "sseishft")
20744 (set_attr "mode" "TI")])
20745
20746 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
20747 ;; we wouldn't need here it since we never generate TImode arithmetic.
20748
20749 ;; There has to be some kind of prize for the weirdest new instruction...
20750 (define_insn "sse2_ashlti3"
20751 [(set (match_operand:TI 0 "register_operand" "=x")
20752 (unspec:TI
20753 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
20754 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
20755 (const_int 8)))] UNSPEC_NOP))]
20756 "TARGET_SSE2"
20757 "pslldq\t{%2, %0|%0, %2}"
20758 [(set_attr "type" "sseishft")
20759 (set_attr "mode" "TI")])
20760
20761 (define_insn "sse2_lshrti3"
20762 [(set (match_operand:TI 0 "register_operand" "=x")
20763 (unspec:TI
20764 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
20765 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
20766 (const_int 8)))] UNSPEC_NOP))]
20767 "TARGET_SSE2"
20768 "pslrdq\t{%2, %0|%0, %2}"
20769 [(set_attr "type" "sseishft")
20770 (set_attr "mode" "TI")])
20771
20772 ;; SSE unpack
20773
20774 (define_insn "sse2_unpckhpd"
20775 [(set (match_operand:V2DF 0 "register_operand" "=x")
20776 (vec_concat:V2DF
20777 (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
20778 (parallel [(const_int 1)]))
20779 (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
20780 (parallel [(const_int 0)]))))]
20781 "TARGET_SSE2"
20782 "unpckhpd\t{%2, %0|%0, %2}"
20783 [(set_attr "type" "ssecvt")
20784 (set_attr "mode" "TI")])
20785
20786 (define_insn "sse2_unpcklpd"
20787 [(set (match_operand:V2DF 0 "register_operand" "=x")
20788 (vec_concat:V2DF
20789 (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
20790 (parallel [(const_int 0)]))
20791 (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
20792 (parallel [(const_int 1)]))))]
20793 "TARGET_SSE2"
20794 "unpcklpd\t{%2, %0|%0, %2}"
20795 [(set_attr "type" "ssecvt")
20796 (set_attr "mode" "TI")])
20797
20798 ;; MMX pack/unpack insns.
20799
20800 (define_insn "sse2_packsswb"
20801 [(set (match_operand:V16QI 0 "register_operand" "=x")
20802 (vec_concat:V16QI
20803 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
20804 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
20805 "TARGET_SSE2"
20806 "packsswb\t{%2, %0|%0, %2}"
20807 [(set_attr "type" "ssecvt")
20808 (set_attr "mode" "TI")])
20809
20810 (define_insn "sse2_packssdw"
20811 [(set (match_operand:V8HI 0 "register_operand" "=x")
20812 (vec_concat:V8HI
20813 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
20814 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
20815 "TARGET_SSE2"
20816 "packssdw\t{%2, %0|%0, %2}"
20817 [(set_attr "type" "ssecvt")
20818 (set_attr "mode" "TI")])
20819
20820 (define_insn "sse2_packuswb"
20821 [(set (match_operand:V16QI 0 "register_operand" "=x")
20822 (vec_concat:V16QI
20823 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
20824 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
20825 "TARGET_SSE2"
20826 "packuswb\t{%2, %0|%0, %2}"
20827 [(set_attr "type" "ssecvt")
20828 (set_attr "mode" "TI")])
20829
20830 (define_insn "sse2_punpckhbw"
20831 [(set (match_operand:V16QI 0 "register_operand" "=x")
20832 (vec_merge:V16QI
20833 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
20834 (parallel [(const_int 8) (const_int 0)
20835 (const_int 9) (const_int 1)
20836 (const_int 10) (const_int 2)
20837 (const_int 11) (const_int 3)
20838 (const_int 12) (const_int 4)
20839 (const_int 13) (const_int 5)
20840 (const_int 14) (const_int 6)
20841 (const_int 15) (const_int 7)]))
20842 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
20843 (parallel [(const_int 0) (const_int 8)
20844 (const_int 1) (const_int 9)
20845 (const_int 2) (const_int 10)
20846 (const_int 3) (const_int 11)
20847 (const_int 4) (const_int 12)
20848 (const_int 5) (const_int 13)
20849 (const_int 6) (const_int 14)
20850 (const_int 7) (const_int 15)]))
20851 (const_int 21845)))]
20852 "TARGET_SSE2"
20853 "punpckhbw\t{%2, %0|%0, %2}"
20854 [(set_attr "type" "ssecvt")
20855 (set_attr "mode" "TI")])
20856
20857 (define_insn "sse2_punpckhwd"
20858 [(set (match_operand:V8HI 0 "register_operand" "=x")
20859 (vec_merge:V8HI
20860 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
20861 (parallel [(const_int 4) (const_int 0)
20862 (const_int 5) (const_int 1)
20863 (const_int 6) (const_int 2)
20864 (const_int 7) (const_int 3)]))
20865 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
20866 (parallel [(const_int 0) (const_int 4)
20867 (const_int 1) (const_int 5)
20868 (const_int 2) (const_int 6)
20869 (const_int 3) (const_int 7)]))
20870 (const_int 85)))]
20871 "TARGET_SSE2"
20872 "punpckhwd\t{%2, %0|%0, %2}"
20873 [(set_attr "type" "ssecvt")
20874 (set_attr "mode" "TI")])
20875
20876 (define_insn "sse2_punpckhdq"
20877 [(set (match_operand:V4SI 0 "register_operand" "=x")
20878 (vec_merge:V4SI
20879 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
20880 (parallel [(const_int 2) (const_int 0)
20881 (const_int 3) (const_int 1)]))
20882 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
20883 (parallel [(const_int 0) (const_int 2)
20884 (const_int 1) (const_int 3)]))
20885 (const_int 5)))]
20886 "TARGET_SSE2"
20887 "punpckhdq\t{%2, %0|%0, %2}"
20888 [(set_attr "type" "ssecvt")
20889 (set_attr "mode" "TI")])
20890
20891 (define_insn "sse2_punpcklbw"
20892 [(set (match_operand:V16QI 0 "register_operand" "=x")
20893 (vec_merge:V16QI
20894 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
20895 (parallel [(const_int 0) (const_int 8)
20896 (const_int 1) (const_int 9)
20897 (const_int 2) (const_int 10)
20898 (const_int 3) (const_int 11)
20899 (const_int 4) (const_int 12)
20900 (const_int 5) (const_int 13)
20901 (const_int 6) (const_int 14)
20902 (const_int 7) (const_int 15)]))
20903 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
20904 (parallel [(const_int 8) (const_int 0)
20905 (const_int 9) (const_int 1)
20906 (const_int 10) (const_int 2)
20907 (const_int 11) (const_int 3)
20908 (const_int 12) (const_int 4)
20909 (const_int 13) (const_int 5)
20910 (const_int 14) (const_int 6)
20911 (const_int 15) (const_int 7)]))
20912 (const_int 21845)))]
20913 "TARGET_SSE2"
20914 "punpcklbw\t{%2, %0|%0, %2}"
20915 [(set_attr "type" "ssecvt")
20916 (set_attr "mode" "TI")])
20917
20918 (define_insn "sse2_punpcklwd"
20919 [(set (match_operand:V8HI 0 "register_operand" "=x")
20920 (vec_merge:V8HI
20921 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
20922 (parallel [(const_int 0) (const_int 4)
20923 (const_int 1) (const_int 5)
20924 (const_int 2) (const_int 6)
20925 (const_int 3) (const_int 7)]))
20926 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
20927 (parallel [(const_int 4) (const_int 0)
20928 (const_int 5) (const_int 1)
20929 (const_int 6) (const_int 2)
20930 (const_int 7) (const_int 3)]))
20931 (const_int 85)))]
20932 "TARGET_SSE2"
20933 "punpcklwd\t{%2, %0|%0, %2}"
20934 [(set_attr "type" "ssecvt")
20935 (set_attr "mode" "TI")])
20936
20937 (define_insn "sse2_punpckldq"
20938 [(set (match_operand:V4SI 0 "register_operand" "=x")
20939 (vec_merge:V4SI
20940 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
20941 (parallel [(const_int 0) (const_int 2)
20942 (const_int 1) (const_int 3)]))
20943 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
20944 (parallel [(const_int 2) (const_int 0)
20945 (const_int 3) (const_int 1)]))
20946 (const_int 5)))]
20947 "TARGET_SSE2"
20948 "punpckldq\t{%2, %0|%0, %2}"
20949 [(set_attr "type" "ssecvt")
20950 (set_attr "mode" "TI")])
20951
20952 ;; SSE2 moves
20953
20954 (define_insn "sse2_movapd"
20955 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
20956 (unspec:V2DF [(match_operand:V2DF 1 "general_operand" "xm,x")]
20957 UNSPEC_MOVA))]
20958 "TARGET_SSE2"
20959 "@
20960 movapd\t{%1, %0|%0, %1}
20961 movapd\t{%1, %0|%0, %1}"
20962 [(set_attr "type" "ssemov")
20963 (set_attr "mode" "V2DF")])
20964
20965 (define_insn "sse2_movupd"
20966 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
20967 (unspec:V2DF [(match_operand:V2DF 1 "general_operand" "xm,x")]
20968 UNSPEC_MOVU))]
20969 "TARGET_SSE2"
20970 "@
20971 movupd\t{%1, %0|%0, %1}
20972 movupd\t{%1, %0|%0, %1}"
20973 [(set_attr "type" "ssecvt")
20974 (set_attr "mode" "V2DF")])
20975
20976 (define_insn "sse2_movdqa"
20977 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
20978 (unspec:TI [(match_operand:TI 1 "general_operand" "xm,x")]
20979 UNSPEC_MOVA))]
20980 "TARGET_SSE2"
20981 "@
20982 movdqa\t{%1, %0|%0, %1}
20983 movdqa\t{%1, %0|%0, %1}"
20984 [(set_attr "type" "ssemov")
20985 (set_attr "mode" "TI")])
20986
20987 (define_insn "sse2_movdqu"
20988 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
20989 (unspec:TI [(match_operand:TI 1 "general_operand" "xm,x")]
20990 UNSPEC_MOVU))]
20991 "TARGET_SSE2"
20992 "@
20993 movdqu\t{%1, %0|%0, %1}
20994 movdqu\t{%1, %0|%0, %1}"
20995 [(set_attr "type" "ssecvt")
20996 (set_attr "mode" "TI")])
20997
20998 (define_insn "sse2_movdq2q"
20999 [(set (match_operand:DI 0 "nonimmediate_operand" "=y")
21000 (vec_select:DI (match_operand:V2DI 1 "general_operand" "x")
21001 (parallel [(const_int 0)])))]
21002 "TARGET_SSE2"
21003 "movdq2q\t{%1, %0|%0, %1}"
21004 [(set_attr "type" "ssecvt")
21005 (set_attr "mode" "TI")])
21006
21007 (define_insn "sse2_movq2dq"
21008 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x")
21009 (vec_concat:V2DI (match_operand:DI 1 "general_operand" "y")
21010 (const_vector:DI [(const_int 0)])))]
21011 "TARGET_SSE2"
21012 "movq2dq\t{%1, %0|%0, %1}"
21013 [(set_attr "type" "ssecvt")
21014 (set_attr "mode" "TI")])
21015
21016 (define_insn "sse2_movhpd"
21017 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
21018 (vec_merge:V2DF
21019 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
21020 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
21021 (const_int 2)))]
21022 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
21023 "movhpd\t{%2, %0|%0, %2}"
21024 [(set_attr "type" "ssecvt")
21025 (set_attr "mode" "V2DF")])
21026
21027 (define_insn "sse2_movlpd"
21028 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
21029 (vec_merge:V2DF
21030 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
21031 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
21032 (const_int 1)))]
21033 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
21034 "movlpd\t{%2, %0|%0, %2}"
21035 [(set_attr "type" "ssecvt")
21036 (set_attr "mode" "V2DF")])
21037
21038 (define_insn "sse2_loadsd"
21039 [(set (match_operand:V2DF 0 "register_operand" "=x")
21040 (vec_merge:V2DF
21041 (match_operand:DF 1 "memory_operand" "m")
21042 (vec_duplicate:DF (float:DF (const_int 0)))
21043 (const_int 1)))]
21044 "TARGET_SSE2"
21045 "movsd\t{%1, %0|%0, %1}"
21046 [(set_attr "type" "ssecvt")
21047 (set_attr "mode" "DF")])
21048
21049 (define_insn "sse2_movsd"
21050 [(set (match_operand:V2DF 0 "register_operand" "=x")
21051 (vec_merge:V2DF
21052 (match_operand:V2DF 1 "register_operand" "0")
21053 (match_operand:V2DF 2 "register_operand" "x")
21054 (const_int 1)))]
21055 "TARGET_SSE2"
21056 "movsd\t{%2, %0|%0, %2}"
21057 [(set_attr "type" "ssecvt")
21058 (set_attr "mode" "DF")])
21059
21060 (define_insn "sse2_storesd"
21061 [(set (match_operand:DF 0 "memory_operand" "=m")
21062 (vec_select:DF
21063 (match_operand:V2DF 1 "register_operand" "x")
21064 (parallel [(const_int 0)])))]
21065 "TARGET_SSE2"
21066 "movsd\t{%1, %0|%0, %1}"
21067 [(set_attr "type" "ssecvt")
21068 (set_attr "mode" "DF")])
21069
21070 (define_insn "sse2_shufpd"
21071 [(set (match_operand:V2DF 0 "register_operand" "=x")
21072 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
21073 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
21074 (match_operand:SI 3 "immediate_operand" "i")]
21075 UNSPEC_SHUFFLE))]
21076 "TARGET_SSE2"
21077 ;; @@@ check operand order for intel/nonintel syntax
21078 "shufpd\t{%3, %2, %0|%0, %2, %3}"
21079 [(set_attr "type" "ssecvt")
21080 (set_attr "mode" "V2DF")])
21081
21082 (define_insn "sse2_clflush"
21083 [(unspec_volatile [(match_operand:SI 0 "address_operand" "p")]
21084 UNSPECV_CLFLUSH)]
21085 "TARGET_SSE2"
21086 "clflush %0"
21087 [(set_attr "type" "sse")
21088 (set_attr "memory" "unknown")])
21089
21090 (define_expand "sse2_mfence"
21091 [(set (match_dup 0)
21092 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
21093 "TARGET_SSE2"
21094 {
21095 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21096 MEM_VOLATILE_P (operands[0]) = 1;
21097 })
21098
21099 (define_insn "*mfence_insn"
21100 [(set (match_operand:BLK 0 "" "")
21101 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
21102 "TARGET_SSE2"
21103 "mfence"
21104 [(set_attr "type" "sse")
21105 (set_attr "memory" "unknown")])
21106
21107 (define_expand "sse2_lfence"
21108 [(set (match_dup 0)
21109 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
21110 "TARGET_SSE2"
21111 {
21112 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21113 MEM_VOLATILE_P (operands[0]) = 1;
21114 })
21115
21116 (define_insn "*lfence_insn"
21117 [(set (match_operand:BLK 0 "" "")
21118 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
21119 "TARGET_SSE2"
21120 "lfence"
21121 [(set_attr "type" "sse")
21122 (set_attr "memory" "unknown")])