i386.md (movstrictqi, [...]): Check optimize_size as well.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GNU CC.
9 ;;
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
31 ;; updates for most instructions.
32 ;;
33 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
34 ;; constraint letters.
35 ;;
36 ;; The special asm out single letter directives following a '%' are:
37 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
38 ;; operands[1].
39 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
40 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
41 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
42 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
43 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
44 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
45 ;; 'J' Print the appropriate jump operand.
46 ;;
47 ;; 'b' Print the QImode name of the register for the indicated operand.
48 ;; %b0 would print %al if operands[0] is reg 0.
49 ;; 'w' Likewise, print the HImode name of the register.
50 ;; 'k' Likewise, print the SImode name of the register.
51 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; 'y' Print "st(0)" instead of "st" as a register.
53
54 ;; UNSPEC usage:
55
56 (define_constants
57 [; Relocation specifiers
58 (UNSPEC_GOT 0)
59 (UNSPEC_GOTOFF 1)
60 (UNSPEC_GOTPCREL 2)
61 (UNSPEC_GOTTPOFF 3)
62 (UNSPEC_TPOFF 4)
63 (UNSPEC_NTPOFF 5)
64 (UNSPEC_DTPOFF 6)
65 (UNSPEC_GOTNTPOFF 7)
66 (UNSPEC_INDNTPOFF 8)
67
68 ; Prologue support
69 (UNSPEC_STACK_PROBE 10)
70 (UNSPEC_STACK_ALLOC 11)
71 (UNSPEC_SET_GOT 12)
72 (UNSPEC_SSE_PROLOGUE_SAVE 13)
73
74 ; TLS support
75 (UNSPEC_TP 15)
76 (UNSPEC_TLS_GD 16)
77 (UNSPEC_TLS_LD_BASE 17)
78
79 ; Other random patterns
80 (UNSPEC_SCAS 20)
81 (UNSPEC_SIN 21)
82 (UNSPEC_COS 22)
83 (UNSPEC_FNSTSW 24)
84 (UNSPEC_SAHF 25)
85 (UNSPEC_FSTCW 26)
86 (UNSPEC_ADD_CARRY 27)
87 (UNSPEC_FLDCW 28)
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX 30)
91 (UNSPEC_MASKMOV 32)
92 (UNSPEC_MOVMSK 33)
93 (UNSPEC_MOVNT 34)
94 (UNSPEC_MOVA 38)
95 (UNSPEC_MOVU 39)
96 (UNSPEC_SHUFFLE 41)
97 (UNSPEC_RCP 42)
98 (UNSPEC_RSQRT 43)
99 (UNSPEC_SFENCE 44)
100 (UNSPEC_NOP 45) ; prevents combiner cleverness
101 (UNSPEC_PAVGUSB 49)
102 (UNSPEC_PFRCP 50)
103 (UNSPEC_PFRCPIT1 51)
104 (UNSPEC_PFRCPIT2 52)
105 (UNSPEC_PFRSQRT 53)
106 (UNSPEC_PFRSQIT1 54)
107 (UNSPEC_PSHUFLW 55)
108 (UNSPEC_PSHUFHW 56)
109 (UNSPEC_MFENCE 59)
110 (UNSPEC_LFENCE 60)
111 (UNSPEC_PSADBW 61)
112
113 ; x87 Floating point
114 (UNSPEC_FPATAN 65)
115 ])
116
117 (define_constants
118 [(UNSPECV_BLOCKAGE 0)
119 (UNSPECV_EH_RETURN 13)
120 (UNSPECV_EMMS 31)
121 (UNSPECV_LDMXCSR 37)
122 (UNSPECV_STMXCSR 40)
123 (UNSPECV_FEMMS 46)
124 (UNSPECV_CLFLUSH 57)
125 ])
126
127 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
128 ;; from i386.c.
129
130 ;; In C guard expressions, put expressions which may be compile-time
131 ;; constants first. This allows for better optimization. For
132 ;; example, write "TARGET_64BIT && reload_completed", not
133 ;; "reload_completed && TARGET_64BIT".
134
135 \f
136 ;; Processor type. This attribute must exactly match the processor_type
137 ;; enumeration in i386.h.
138 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
139 (const (symbol_ref "ix86_tune")))
140
141 ;; A basic instruction type. Refinements due to arguments to be
142 ;; provided in other attributes.
143 (define_attr "type"
144 "other,multi,
145 alu,alu1,negnot,imov,imovx,lea,
146 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
147 icmp,test,ibr,setcc,icmov,
148 push,pop,call,callv,leave,
149 str,cld,
150 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
151 sselog,sseiadd,sseishft,sseimul,
152 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
153 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
154 (const_string "other"))
155
156 ;; Main data type used by the insn
157 (define_attr "mode"
158 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
159 (const_string "unknown"))
160
161 ;; The CPU unit operations uses.
162 (define_attr "unit" "integer,i387,sse,mmx,unknown"
163 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
164 (const_string "i387")
165 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
166 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
167 (const_string "sse")
168 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
169 (const_string "mmx")
170 (eq_attr "type" "other")
171 (const_string "unknown")]
172 (const_string "integer")))
173
174 ;; The (bounding maximum) length of an instruction immediate.
175 (define_attr "length_immediate" ""
176 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
177 (const_int 0)
178 (eq_attr "unit" "i387,sse,mmx")
179 (const_int 0)
180 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
181 imul,icmp,push,pop")
182 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
183 (eq_attr "type" "imov,test")
184 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
185 (eq_attr "type" "call")
186 (if_then_else (match_operand 0 "constant_call_address_operand" "")
187 (const_int 4)
188 (const_int 0))
189 (eq_attr "type" "callv")
190 (if_then_else (match_operand 1 "constant_call_address_operand" "")
191 (const_int 4)
192 (const_int 0))
193 ;; We don't know the size before shorten_branches. Expect
194 ;; the instruction to fit for better scheduling.
195 (eq_attr "type" "ibr")
196 (const_int 1)
197 ]
198 (symbol_ref "/* Update immediate_length and other attributes! */
199 abort(),1")))
200
201 ;; The (bounding maximum) length of an instruction address.
202 (define_attr "length_address" ""
203 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
204 (const_int 0)
205 (and (eq_attr "type" "call")
206 (match_operand 0 "constant_call_address_operand" ""))
207 (const_int 0)
208 (and (eq_attr "type" "callv")
209 (match_operand 1 "constant_call_address_operand" ""))
210 (const_int 0)
211 ]
212 (symbol_ref "ix86_attr_length_address_default (insn)")))
213
214 ;; Set when length prefix is used.
215 (define_attr "prefix_data16" ""
216 (if_then_else (ior (eq_attr "mode" "HI")
217 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
218 (const_int 1)
219 (const_int 0)))
220
221 ;; Set when string REP prefix is used.
222 (define_attr "prefix_rep" ""
223 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
224 (const_int 1)
225 (const_int 0)))
226
227 ;; Set when 0f opcode prefix is used.
228 (define_attr "prefix_0f" ""
229 (if_then_else
230 (ior (eq_attr "type" "imovx,setcc,icmov")
231 (eq_attr "unit" "sse,mmx"))
232 (const_int 1)
233 (const_int 0)))
234
235 ;; Set when 0f opcode prefix is used.
236 (define_attr "prefix_rex" ""
237 (cond [(and (eq_attr "mode" "DI")
238 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
239 (const_int 1)
240 (and (eq_attr "mode" "QI")
241 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
242 (const_int 0)))
243 (const_int 1)
244 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
245 (const_int 0))
246 (const_int 1)
247 ]
248 (const_int 0)))
249
250 ;; Set when modrm byte is used.
251 (define_attr "modrm" ""
252 (cond [(eq_attr "type" "str,cld,leave")
253 (const_int 0)
254 (eq_attr "unit" "i387")
255 (const_int 0)
256 (and (eq_attr "type" "incdec")
257 (ior (match_operand:SI 1 "register_operand" "")
258 (match_operand:HI 1 "register_operand" "")))
259 (const_int 0)
260 (and (eq_attr "type" "push")
261 (not (match_operand 1 "memory_operand" "")))
262 (const_int 0)
263 (and (eq_attr "type" "pop")
264 (not (match_operand 0 "memory_operand" "")))
265 (const_int 0)
266 (and (eq_attr "type" "imov")
267 (and (match_operand 0 "register_operand" "")
268 (match_operand 1 "immediate_operand" "")))
269 (const_int 0)
270 (and (eq_attr "type" "call")
271 (match_operand 0 "constant_call_address_operand" ""))
272 (const_int 0)
273 (and (eq_attr "type" "callv")
274 (match_operand 1 "constant_call_address_operand" ""))
275 (const_int 0)
276 ]
277 (const_int 1)))
278
279 ;; The (bounding maximum) length of an instruction in bytes.
280 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
281 ;; to split it and compute proper length as for other insns.
282 (define_attr "length" ""
283 (cond [(eq_attr "type" "other,multi,fistp")
284 (const_int 16)
285 (eq_attr "unit" "i387")
286 (plus (const_int 2)
287 (plus (attr "prefix_data16")
288 (attr "length_address")))]
289 (plus (plus (attr "modrm")
290 (plus (attr "prefix_0f")
291 (plus (attr "prefix_rex")
292 (const_int 1))))
293 (plus (attr "prefix_rep")
294 (plus (attr "prefix_data16")
295 (plus (attr "length_immediate")
296 (attr "length_address")))))))
297
298 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
299 ;; `store' if there is a simple memory reference therein, or `unknown'
300 ;; if the instruction is complex.
301
302 (define_attr "memory" "none,load,store,both,unknown"
303 (cond [(eq_attr "type" "other,multi,str")
304 (const_string "unknown")
305 (eq_attr "type" "lea,fcmov,fpspc,cld")
306 (const_string "none")
307 (eq_attr "type" "fistp,leave")
308 (const_string "both")
309 (eq_attr "type" "push")
310 (if_then_else (match_operand 1 "memory_operand" "")
311 (const_string "both")
312 (const_string "store"))
313 (eq_attr "type" "pop")
314 (if_then_else (match_operand 0 "memory_operand" "")
315 (const_string "both")
316 (const_string "load"))
317 (eq_attr "type" "setcc")
318 (if_then_else (match_operand 0 "memory_operand" "")
319 (const_string "store")
320 (const_string "none"))
321 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
322 (if_then_else (ior (match_operand 0 "memory_operand" "")
323 (match_operand 1 "memory_operand" ""))
324 (const_string "load")
325 (const_string "none"))
326 (eq_attr "type" "ibr")
327 (if_then_else (match_operand 0 "memory_operand" "")
328 (const_string "load")
329 (const_string "none"))
330 (eq_attr "type" "call")
331 (if_then_else (match_operand 0 "constant_call_address_operand" "")
332 (const_string "none")
333 (const_string "load"))
334 (eq_attr "type" "callv")
335 (if_then_else (match_operand 1 "constant_call_address_operand" "")
336 (const_string "none")
337 (const_string "load"))
338 (and (eq_attr "type" "alu1,negnot")
339 (match_operand 1 "memory_operand" ""))
340 (const_string "both")
341 (and (match_operand 0 "memory_operand" "")
342 (match_operand 1 "memory_operand" ""))
343 (const_string "both")
344 (match_operand 0 "memory_operand" "")
345 (const_string "store")
346 (match_operand 1 "memory_operand" "")
347 (const_string "load")
348 (and (eq_attr "type"
349 "!alu1,negnot,
350 imov,imovx,icmp,test,
351 fmov,fcmp,fsgn,
352 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
353 mmx,mmxmov,mmxcmp,mmxcvt")
354 (match_operand 2 "memory_operand" ""))
355 (const_string "load")
356 (and (eq_attr "type" "icmov")
357 (match_operand 3 "memory_operand" ""))
358 (const_string "load")
359 ]
360 (const_string "none")))
361
362 ;; Indicates if an instruction has both an immediate and a displacement.
363
364 (define_attr "imm_disp" "false,true,unknown"
365 (cond [(eq_attr "type" "other,multi")
366 (const_string "unknown")
367 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
368 (and (match_operand 0 "memory_displacement_operand" "")
369 (match_operand 1 "immediate_operand" "")))
370 (const_string "true")
371 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
372 (and (match_operand 0 "memory_displacement_operand" "")
373 (match_operand 2 "immediate_operand" "")))
374 (const_string "true")
375 ]
376 (const_string "false")))
377
378 ;; Indicates if an FP operation has an integer source.
379
380 (define_attr "fp_int_src" "false,true"
381 (const_string "false"))
382
383 ;; Describe a user's asm statement.
384 (define_asm_attributes
385 [(set_attr "length" "128")
386 (set_attr "type" "multi")])
387 \f
388 (include "pentium.md")
389 (include "ppro.md")
390 (include "k6.md")
391 (include "athlon.md")
392 \f
393 ;; Compare instructions.
394
395 ;; All compare insns have expanders that save the operands away without
396 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
397 ;; after the cmp) will actually emit the cmpM.
398
399 (define_expand "cmpdi"
400 [(set (reg:CC 17)
401 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
402 (match_operand:DI 1 "x86_64_general_operand" "")))]
403 ""
404 {
405 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
406 operands[0] = force_reg (DImode, operands[0]);
407 ix86_compare_op0 = operands[0];
408 ix86_compare_op1 = operands[1];
409 DONE;
410 })
411
412 (define_expand "cmpsi"
413 [(set (reg:CC 17)
414 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
415 (match_operand:SI 1 "general_operand" "")))]
416 ""
417 {
418 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
419 operands[0] = force_reg (SImode, operands[0]);
420 ix86_compare_op0 = operands[0];
421 ix86_compare_op1 = operands[1];
422 DONE;
423 })
424
425 (define_expand "cmphi"
426 [(set (reg:CC 17)
427 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
428 (match_operand:HI 1 "general_operand" "")))]
429 ""
430 {
431 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
432 operands[0] = force_reg (HImode, operands[0]);
433 ix86_compare_op0 = operands[0];
434 ix86_compare_op1 = operands[1];
435 DONE;
436 })
437
438 (define_expand "cmpqi"
439 [(set (reg:CC 17)
440 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
441 (match_operand:QI 1 "general_operand" "")))]
442 "TARGET_QIMODE_MATH"
443 {
444 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
445 operands[0] = force_reg (QImode, operands[0]);
446 ix86_compare_op0 = operands[0];
447 ix86_compare_op1 = operands[1];
448 DONE;
449 })
450
451 (define_insn "cmpdi_ccno_1_rex64"
452 [(set (reg 17)
453 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
454 (match_operand:DI 1 "const0_operand" "n,n")))]
455 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
456 "@
457 test{q}\t{%0, %0|%0, %0}
458 cmp{q}\t{%1, %0|%0, %1}"
459 [(set_attr "type" "test,icmp")
460 (set_attr "length_immediate" "0,1")
461 (set_attr "mode" "DI")])
462
463 (define_insn "*cmpdi_minus_1_rex64"
464 [(set (reg 17)
465 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
466 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
467 (const_int 0)))]
468 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
469 "cmp{q}\t{%1, %0|%0, %1}"
470 [(set_attr "type" "icmp")
471 (set_attr "mode" "DI")])
472
473 (define_expand "cmpdi_1_rex64"
474 [(set (reg:CC 17)
475 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
476 (match_operand:DI 1 "general_operand" "")))]
477 "TARGET_64BIT"
478 "")
479
480 (define_insn "cmpdi_1_insn_rex64"
481 [(set (reg 17)
482 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
483 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
484 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
485 "cmp{q}\t{%1, %0|%0, %1}"
486 [(set_attr "type" "icmp")
487 (set_attr "mode" "DI")])
488
489
490 (define_insn "*cmpsi_ccno_1"
491 [(set (reg 17)
492 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
493 (match_operand:SI 1 "const0_operand" "n,n")))]
494 "ix86_match_ccmode (insn, CCNOmode)"
495 "@
496 test{l}\t{%0, %0|%0, %0}
497 cmp{l}\t{%1, %0|%0, %1}"
498 [(set_attr "type" "test,icmp")
499 (set_attr "length_immediate" "0,1")
500 (set_attr "mode" "SI")])
501
502 (define_insn "*cmpsi_minus_1"
503 [(set (reg 17)
504 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
505 (match_operand:SI 1 "general_operand" "ri,mr"))
506 (const_int 0)))]
507 "ix86_match_ccmode (insn, CCGOCmode)"
508 "cmp{l}\t{%1, %0|%0, %1}"
509 [(set_attr "type" "icmp")
510 (set_attr "mode" "SI")])
511
512 (define_expand "cmpsi_1"
513 [(set (reg:CC 17)
514 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
515 (match_operand:SI 1 "general_operand" "ri,mr")))]
516 ""
517 "")
518
519 (define_insn "*cmpsi_1_insn"
520 [(set (reg 17)
521 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
522 (match_operand:SI 1 "general_operand" "ri,mr")))]
523 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
524 && ix86_match_ccmode (insn, CCmode)"
525 "cmp{l}\t{%1, %0|%0, %1}"
526 [(set_attr "type" "icmp")
527 (set_attr "mode" "SI")])
528
529 (define_insn "*cmphi_ccno_1"
530 [(set (reg 17)
531 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
532 (match_operand:HI 1 "const0_operand" "n,n")))]
533 "ix86_match_ccmode (insn, CCNOmode)"
534 "@
535 test{w}\t{%0, %0|%0, %0}
536 cmp{w}\t{%1, %0|%0, %1}"
537 [(set_attr "type" "test,icmp")
538 (set_attr "length_immediate" "0,1")
539 (set_attr "mode" "HI")])
540
541 (define_insn "*cmphi_minus_1"
542 [(set (reg 17)
543 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
544 (match_operand:HI 1 "general_operand" "ri,mr"))
545 (const_int 0)))]
546 "ix86_match_ccmode (insn, CCGOCmode)"
547 "cmp{w}\t{%1, %0|%0, %1}"
548 [(set_attr "type" "icmp")
549 (set_attr "mode" "HI")])
550
551 (define_insn "*cmphi_1"
552 [(set (reg 17)
553 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
554 (match_operand:HI 1 "general_operand" "ri,mr")))]
555 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
556 && ix86_match_ccmode (insn, CCmode)"
557 "cmp{w}\t{%1, %0|%0, %1}"
558 [(set_attr "type" "icmp")
559 (set_attr "mode" "HI")])
560
561 (define_insn "*cmpqi_ccno_1"
562 [(set (reg 17)
563 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
564 (match_operand:QI 1 "const0_operand" "n,n")))]
565 "ix86_match_ccmode (insn, CCNOmode)"
566 "@
567 test{b}\t{%0, %0|%0, %0}
568 cmp{b}\t{$0, %0|%0, 0}"
569 [(set_attr "type" "test,icmp")
570 (set_attr "length_immediate" "0,1")
571 (set_attr "mode" "QI")])
572
573 (define_insn "*cmpqi_1"
574 [(set (reg 17)
575 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
576 (match_operand:QI 1 "general_operand" "qi,mq")))]
577 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
578 && ix86_match_ccmode (insn, CCmode)"
579 "cmp{b}\t{%1, %0|%0, %1}"
580 [(set_attr "type" "icmp")
581 (set_attr "mode" "QI")])
582
583 (define_insn "*cmpqi_minus_1"
584 [(set (reg 17)
585 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
586 (match_operand:QI 1 "general_operand" "qi,mq"))
587 (const_int 0)))]
588 "ix86_match_ccmode (insn, CCGOCmode)"
589 "cmp{b}\t{%1, %0|%0, %1}"
590 [(set_attr "type" "icmp")
591 (set_attr "mode" "QI")])
592
593 (define_insn "*cmpqi_ext_1"
594 [(set (reg 17)
595 (compare
596 (match_operand:QI 0 "general_operand" "Qm")
597 (subreg:QI
598 (zero_extract:SI
599 (match_operand 1 "ext_register_operand" "Q")
600 (const_int 8)
601 (const_int 8)) 0)))]
602 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603 "cmp{b}\t{%h1, %0|%0, %h1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "QI")])
606
607 (define_insn "*cmpqi_ext_1_rex64"
608 [(set (reg 17)
609 (compare
610 (match_operand:QI 0 "register_operand" "Q")
611 (subreg:QI
612 (zero_extract:SI
613 (match_operand 1 "ext_register_operand" "Q")
614 (const_int 8)
615 (const_int 8)) 0)))]
616 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
617 "cmp{b}\t{%h1, %0|%0, %h1}"
618 [(set_attr "type" "icmp")
619 (set_attr "mode" "QI")])
620
621 (define_insn "*cmpqi_ext_2"
622 [(set (reg 17)
623 (compare
624 (subreg:QI
625 (zero_extract:SI
626 (match_operand 0 "ext_register_operand" "Q")
627 (const_int 8)
628 (const_int 8)) 0)
629 (match_operand:QI 1 "const0_operand" "n")))]
630 "ix86_match_ccmode (insn, CCNOmode)"
631 "test{b}\t%h0, %h0"
632 [(set_attr "type" "test")
633 (set_attr "length_immediate" "0")
634 (set_attr "mode" "QI")])
635
636 (define_expand "cmpqi_ext_3"
637 [(set (reg:CC 17)
638 (compare:CC
639 (subreg:QI
640 (zero_extract:SI
641 (match_operand 0 "ext_register_operand" "")
642 (const_int 8)
643 (const_int 8)) 0)
644 (match_operand:QI 1 "general_operand" "")))]
645 ""
646 "")
647
648 (define_insn "cmpqi_ext_3_insn"
649 [(set (reg 17)
650 (compare
651 (subreg:QI
652 (zero_extract:SI
653 (match_operand 0 "ext_register_operand" "Q")
654 (const_int 8)
655 (const_int 8)) 0)
656 (match_operand:QI 1 "general_operand" "Qmn")))]
657 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
658 "cmp{b}\t{%1, %h0|%h0, %1}"
659 [(set_attr "type" "icmp")
660 (set_attr "mode" "QI")])
661
662 (define_insn "cmpqi_ext_3_insn_rex64"
663 [(set (reg 17)
664 (compare
665 (subreg:QI
666 (zero_extract:SI
667 (match_operand 0 "ext_register_operand" "Q")
668 (const_int 8)
669 (const_int 8)) 0)
670 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
671 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
672 "cmp{b}\t{%1, %h0|%h0, %1}"
673 [(set_attr "type" "icmp")
674 (set_attr "mode" "QI")])
675
676 (define_insn "*cmpqi_ext_4"
677 [(set (reg 17)
678 (compare
679 (subreg:QI
680 (zero_extract:SI
681 (match_operand 0 "ext_register_operand" "Q")
682 (const_int 8)
683 (const_int 8)) 0)
684 (subreg:QI
685 (zero_extract:SI
686 (match_operand 1 "ext_register_operand" "Q")
687 (const_int 8)
688 (const_int 8)) 0)))]
689 "ix86_match_ccmode (insn, CCmode)"
690 "cmp{b}\t{%h1, %h0|%h0, %h1}"
691 [(set_attr "type" "icmp")
692 (set_attr "mode" "QI")])
693
694 ;; These implement float point compares.
695 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
696 ;; which would allow mix and match FP modes on the compares. Which is what
697 ;; the old patterns did, but with many more of them.
698
699 (define_expand "cmpxf"
700 [(set (reg:CC 17)
701 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
702 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
703 "!TARGET_64BIT && TARGET_80387"
704 {
705 ix86_compare_op0 = operands[0];
706 ix86_compare_op1 = operands[1];
707 DONE;
708 })
709
710 (define_expand "cmptf"
711 [(set (reg:CC 17)
712 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
713 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
714 "TARGET_80387"
715 {
716 ix86_compare_op0 = operands[0];
717 ix86_compare_op1 = operands[1];
718 DONE;
719 })
720
721 (define_expand "cmpdf"
722 [(set (reg:CC 17)
723 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
724 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
725 "TARGET_80387 || TARGET_SSE2"
726 {
727 ix86_compare_op0 = operands[0];
728 ix86_compare_op1 = operands[1];
729 DONE;
730 })
731
732 (define_expand "cmpsf"
733 [(set (reg:CC 17)
734 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
735 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
736 "TARGET_80387 || TARGET_SSE"
737 {
738 ix86_compare_op0 = operands[0];
739 ix86_compare_op1 = operands[1];
740 DONE;
741 })
742
743 ;; FP compares, step 1:
744 ;; Set the FP condition codes.
745 ;;
746 ;; CCFPmode compare with exceptions
747 ;; CCFPUmode compare with no exceptions
748
749 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
750 ;; and that fp moves clobber the condition codes, and that there is
751 ;; currently no way to describe this fact to reg-stack. So there are
752 ;; no splitters yet for this.
753
754 ;; %%% YIKES! This scheme does not retain a strong connection between
755 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
756 ;; work! Only allow tos/mem with tos in op 0.
757 ;;
758 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
759 ;; things aren't as bad as they sound...
760
761 (define_insn "*cmpfp_0"
762 [(set (match_operand:HI 0 "register_operand" "=a")
763 (unspec:HI
764 [(compare:CCFP (match_operand 1 "register_operand" "f")
765 (match_operand 2 "const0_operand" "X"))]
766 UNSPEC_FNSTSW))]
767 "TARGET_80387
768 && FLOAT_MODE_P (GET_MODE (operands[1]))
769 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
770 {
771 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
772 return "ftst\;fnstsw\t%0\;fstp\t%y0";
773 else
774 return "ftst\;fnstsw\t%0";
775 }
776 [(set_attr "type" "multi")
777 (set (attr "mode")
778 (cond [(match_operand:SF 1 "" "")
779 (const_string "SF")
780 (match_operand:DF 1 "" "")
781 (const_string "DF")
782 ]
783 (const_string "XF")))])
784
785 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
786 ;; used to manage the reg stack popping would not be preserved.
787
788 (define_insn "*cmpfp_2_sf"
789 [(set (reg:CCFP 18)
790 (compare:CCFP
791 (match_operand:SF 0 "register_operand" "f")
792 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
793 "TARGET_80387"
794 "* return output_fp_compare (insn, operands, 0, 0);"
795 [(set_attr "type" "fcmp")
796 (set_attr "mode" "SF")])
797
798 (define_insn "*cmpfp_2_sf_1"
799 [(set (match_operand:HI 0 "register_operand" "=a")
800 (unspec:HI
801 [(compare:CCFP
802 (match_operand:SF 1 "register_operand" "f")
803 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
804 UNSPEC_FNSTSW))]
805 "TARGET_80387"
806 "* return output_fp_compare (insn, operands, 2, 0);"
807 [(set_attr "type" "fcmp")
808 (set_attr "mode" "SF")])
809
810 (define_insn "*cmpfp_2_df"
811 [(set (reg:CCFP 18)
812 (compare:CCFP
813 (match_operand:DF 0 "register_operand" "f")
814 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
815 "TARGET_80387"
816 "* return output_fp_compare (insn, operands, 0, 0);"
817 [(set_attr "type" "fcmp")
818 (set_attr "mode" "DF")])
819
820 (define_insn "*cmpfp_2_df_1"
821 [(set (match_operand:HI 0 "register_operand" "=a")
822 (unspec:HI
823 [(compare:CCFP
824 (match_operand:DF 1 "register_operand" "f")
825 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
826 UNSPEC_FNSTSW))]
827 "TARGET_80387"
828 "* return output_fp_compare (insn, operands, 2, 0);"
829 [(set_attr "type" "multi")
830 (set_attr "mode" "DF")])
831
832 (define_insn "*cmpfp_2_xf"
833 [(set (reg:CCFP 18)
834 (compare:CCFP
835 (match_operand:XF 0 "register_operand" "f")
836 (match_operand:XF 1 "register_operand" "f")))]
837 "!TARGET_64BIT && TARGET_80387"
838 "* return output_fp_compare (insn, operands, 0, 0);"
839 [(set_attr "type" "fcmp")
840 (set_attr "mode" "XF")])
841
842 (define_insn "*cmpfp_2_tf"
843 [(set (reg:CCFP 18)
844 (compare:CCFP
845 (match_operand:TF 0 "register_operand" "f")
846 (match_operand:TF 1 "register_operand" "f")))]
847 "TARGET_80387"
848 "* return output_fp_compare (insn, operands, 0, 0);"
849 [(set_attr "type" "fcmp")
850 (set_attr "mode" "XF")])
851
852 (define_insn "*cmpfp_2_xf_1"
853 [(set (match_operand:HI 0 "register_operand" "=a")
854 (unspec:HI
855 [(compare:CCFP
856 (match_operand:XF 1 "register_operand" "f")
857 (match_operand:XF 2 "register_operand" "f"))]
858 UNSPEC_FNSTSW))]
859 "!TARGET_64BIT && TARGET_80387"
860 "* return output_fp_compare (insn, operands, 2, 0);"
861 [(set_attr "type" "multi")
862 (set_attr "mode" "XF")])
863
864 (define_insn "*cmpfp_2_tf_1"
865 [(set (match_operand:HI 0 "register_operand" "=a")
866 (unspec:HI
867 [(compare:CCFP
868 (match_operand:TF 1 "register_operand" "f")
869 (match_operand:TF 2 "register_operand" "f"))]
870 UNSPEC_FNSTSW))]
871 "TARGET_80387"
872 "* return output_fp_compare (insn, operands, 2, 0);"
873 [(set_attr "type" "multi")
874 (set_attr "mode" "XF")])
875
876 (define_insn "*cmpfp_2u"
877 [(set (reg:CCFPU 18)
878 (compare:CCFPU
879 (match_operand 0 "register_operand" "f")
880 (match_operand 1 "register_operand" "f")))]
881 "TARGET_80387
882 && FLOAT_MODE_P (GET_MODE (operands[0]))
883 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
884 "* return output_fp_compare (insn, operands, 0, 1);"
885 [(set_attr "type" "fcmp")
886 (set (attr "mode")
887 (cond [(match_operand:SF 1 "" "")
888 (const_string "SF")
889 (match_operand:DF 1 "" "")
890 (const_string "DF")
891 ]
892 (const_string "XF")))])
893
894 (define_insn "*cmpfp_2u_1"
895 [(set (match_operand:HI 0 "register_operand" "=a")
896 (unspec:HI
897 [(compare:CCFPU
898 (match_operand 1 "register_operand" "f")
899 (match_operand 2 "register_operand" "f"))]
900 UNSPEC_FNSTSW))]
901 "TARGET_80387
902 && FLOAT_MODE_P (GET_MODE (operands[1]))
903 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
904 "* return output_fp_compare (insn, operands, 2, 1);"
905 [(set_attr "type" "multi")
906 (set (attr "mode")
907 (cond [(match_operand:SF 1 "" "")
908 (const_string "SF")
909 (match_operand:DF 1 "" "")
910 (const_string "DF")
911 ]
912 (const_string "XF")))])
913
914 ;; Patterns to match the SImode-in-memory ficom instructions.
915 ;;
916 ;; %%% Play games with accepting gp registers, as otherwise we have to
917 ;; force them to memory during rtl generation, which is no good. We
918 ;; can get rid of this once we teach reload to do memory input reloads
919 ;; via pushes.
920
921 (define_insn "*ficom_1"
922 [(set (reg:CCFP 18)
923 (compare:CCFP
924 (match_operand 0 "register_operand" "f,f")
925 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
926 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
927 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
928 "#")
929
930 ;; Split the not-really-implemented gp register case into a
931 ;; push-op-pop sequence.
932 ;;
933 ;; %%% This is most efficient, but am I gonna get in trouble
934 ;; for separating cc0_setter and cc0_user?
935
936 (define_split
937 [(set (reg:CCFP 18)
938 (compare:CCFP
939 (match_operand:SF 0 "register_operand" "")
940 (float (match_operand:SI 1 "register_operand" ""))))]
941 "0 && TARGET_80387 && reload_completed"
942 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
943 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
944 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
945 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
946 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
947 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
948
949 ;; FP compares, step 2
950 ;; Move the fpsw to ax.
951
952 (define_insn "*x86_fnstsw_1"
953 [(set (match_operand:HI 0 "register_operand" "=a")
954 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
955 "TARGET_80387"
956 "fnstsw\t%0"
957 [(set_attr "length" "2")
958 (set_attr "mode" "SI")
959 (set_attr "unit" "i387")
960 (set_attr "ppro_uops" "few")])
961
962 ;; FP compares, step 3
963 ;; Get ax into flags, general case.
964
965 (define_insn "x86_sahf_1"
966 [(set (reg:CC 17)
967 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
968 "!TARGET_64BIT"
969 "sahf"
970 [(set_attr "length" "1")
971 (set_attr "athlon_decode" "vector")
972 (set_attr "mode" "SI")
973 (set_attr "ppro_uops" "one")])
974
975 ;; Pentium Pro can do steps 1 through 3 in one go.
976
977 (define_insn "*cmpfp_i"
978 [(set (reg:CCFP 17)
979 (compare:CCFP (match_operand 0 "register_operand" "f")
980 (match_operand 1 "register_operand" "f")))]
981 "TARGET_80387 && TARGET_CMOVE
982 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983 && FLOAT_MODE_P (GET_MODE (operands[0]))
984 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
985 "* return output_fp_compare (insn, operands, 1, 0);"
986 [(set_attr "type" "fcmp")
987 (set (attr "mode")
988 (cond [(match_operand:SF 1 "" "")
989 (const_string "SF")
990 (match_operand:DF 1 "" "")
991 (const_string "DF")
992 ]
993 (const_string "XF")))
994 (set_attr "athlon_decode" "vector")])
995
996 (define_insn "*cmpfp_i_sse"
997 [(set (reg:CCFP 17)
998 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
999 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1000 "TARGET_80387
1001 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1003 "* return output_fp_compare (insn, operands, 1, 0);"
1004 [(set_attr "type" "fcmp,ssecomi")
1005 (set (attr "mode")
1006 (if_then_else (match_operand:SF 1 "" "")
1007 (const_string "SF")
1008 (const_string "DF")))
1009 (set_attr "athlon_decode" "vector")])
1010
1011 (define_insn "*cmpfp_i_sse_only"
1012 [(set (reg:CCFP 17)
1013 (compare:CCFP (match_operand 0 "register_operand" "x")
1014 (match_operand 1 "nonimmediate_operand" "xm")))]
1015 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1016 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1017 "* return output_fp_compare (insn, operands, 1, 0);"
1018 [(set_attr "type" "ssecomi")
1019 (set (attr "mode")
1020 (if_then_else (match_operand:SF 1 "" "")
1021 (const_string "SF")
1022 (const_string "DF")))
1023 (set_attr "athlon_decode" "vector")])
1024
1025 (define_insn "*cmpfp_iu"
1026 [(set (reg:CCFPU 17)
1027 (compare:CCFPU (match_operand 0 "register_operand" "f")
1028 (match_operand 1 "register_operand" "f")))]
1029 "TARGET_80387 && TARGET_CMOVE
1030 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1031 && FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 1);"
1034 [(set_attr "type" "fcmp")
1035 (set (attr "mode")
1036 (cond [(match_operand:SF 1 "" "")
1037 (const_string "SF")
1038 (match_operand:DF 1 "" "")
1039 (const_string "DF")
1040 ]
1041 (const_string "XF")))
1042 (set_attr "athlon_decode" "vector")])
1043
1044 (define_insn "*cmpfp_iu_sse"
1045 [(set (reg:CCFPU 17)
1046 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1047 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1048 "TARGET_80387
1049 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1050 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1051 "* return output_fp_compare (insn, operands, 1, 1);"
1052 [(set_attr "type" "fcmp,ssecomi")
1053 (set (attr "mode")
1054 (if_then_else (match_operand:SF 1 "" "")
1055 (const_string "SF")
1056 (const_string "DF")))
1057 (set_attr "athlon_decode" "vector")])
1058
1059 (define_insn "*cmpfp_iu_sse_only"
1060 [(set (reg:CCFPU 17)
1061 (compare:CCFPU (match_operand 0 "register_operand" "x")
1062 (match_operand 1 "nonimmediate_operand" "xm")))]
1063 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1064 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1065 "* return output_fp_compare (insn, operands, 1, 1);"
1066 [(set_attr "type" "ssecomi")
1067 (set (attr "mode")
1068 (if_then_else (match_operand:SF 1 "" "")
1069 (const_string "SF")
1070 (const_string "DF")))
1071 (set_attr "athlon_decode" "vector")])
1072 \f
1073 ;; Move instructions.
1074
1075 ;; General case of fullword move.
1076
1077 (define_expand "movsi"
1078 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1079 (match_operand:SI 1 "general_operand" ""))]
1080 ""
1081 "ix86_expand_move (SImode, operands); DONE;")
1082
1083 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1084 ;; general_operand.
1085 ;;
1086 ;; %%% We don't use a post-inc memory reference because x86 is not a
1087 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1088 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1089 ;; targets without our curiosities, and it is just as easy to represent
1090 ;; this differently.
1091
1092 (define_insn "*pushsi2"
1093 [(set (match_operand:SI 0 "push_operand" "=<")
1094 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1095 "!TARGET_64BIT"
1096 "push{l}\t%1"
1097 [(set_attr "type" "push")
1098 (set_attr "mode" "SI")])
1099
1100 ;; For 64BIT abi we always round up to 8 bytes.
1101 (define_insn "*pushsi2_rex64"
1102 [(set (match_operand:SI 0 "push_operand" "=X")
1103 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1104 "TARGET_64BIT"
1105 "push{q}\t%q1"
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1108
1109 (define_insn "*pushsi2_prologue"
1110 [(set (match_operand:SI 0 "push_operand" "=<")
1111 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1112 (clobber (mem:BLK (scratch)))]
1113 "!TARGET_64BIT"
1114 "push{l}\t%1"
1115 [(set_attr "type" "push")
1116 (set_attr "mode" "SI")])
1117
1118 (define_insn "*popsi1_epilogue"
1119 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1120 (mem:SI (reg:SI 7)))
1121 (set (reg:SI 7)
1122 (plus:SI (reg:SI 7) (const_int 4)))
1123 (clobber (mem:BLK (scratch)))]
1124 "!TARGET_64BIT"
1125 "pop{l}\t%0"
1126 [(set_attr "type" "pop")
1127 (set_attr "mode" "SI")])
1128
1129 (define_insn "popsi1"
1130 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1131 (mem:SI (reg:SI 7)))
1132 (set (reg:SI 7)
1133 (plus:SI (reg:SI 7) (const_int 4)))]
1134 "!TARGET_64BIT"
1135 "pop{l}\t%0"
1136 [(set_attr "type" "pop")
1137 (set_attr "mode" "SI")])
1138
1139 (define_insn "*movsi_xor"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (match_operand:SI 1 "const0_operand" "i"))
1142 (clobber (reg:CC 17))]
1143 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1144 "xor{l}\t{%0, %0|%0, %0}"
1145 [(set_attr "type" "alu1")
1146 (set_attr "mode" "SI")
1147 (set_attr "length_immediate" "0")])
1148
1149 (define_insn "*movsi_or"
1150 [(set (match_operand:SI 0 "register_operand" "=r")
1151 (match_operand:SI 1 "immediate_operand" "i"))
1152 (clobber (reg:CC 17))]
1153 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1154 && INTVAL (operands[1]) == -1
1155 && (TARGET_PENTIUM || optimize_size)"
1156 {
1157 operands[1] = constm1_rtx;
1158 return "or{l}\t{%1, %0|%0, %1}";
1159 }
1160 [(set_attr "type" "alu1")
1161 (set_attr "mode" "SI")
1162 (set_attr "length_immediate" "1")])
1163
1164 (define_insn "*movsi_1"
1165 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1166 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1167 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1168 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1169 {
1170 switch (get_attr_type (insn))
1171 {
1172 case TYPE_SSEMOV:
1173 if (get_attr_mode (insn) == TImode)
1174 return "movdqa\t{%1, %0|%0, %1}";
1175 return "movd\t{%1, %0|%0, %1}";
1176
1177 case TYPE_MMXMOV:
1178 if (get_attr_mode (insn) == DImode)
1179 return "movq\t{%1, %0|%0, %1}";
1180 return "movd\t{%1, %0|%0, %1}";
1181
1182 case TYPE_LEA:
1183 return "lea{l}\t{%1, %0|%0, %1}";
1184
1185 default:
1186 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1187 abort();
1188 return "mov{l}\t{%1, %0|%0, %1}";
1189 }
1190 }
1191 [(set (attr "type")
1192 (cond [(eq_attr "alternative" "2,3,4")
1193 (const_string "mmxmov")
1194 (eq_attr "alternative" "5,6,7")
1195 (const_string "ssemov")
1196 (and (ne (symbol_ref "flag_pic") (const_int 0))
1197 (match_operand:SI 1 "symbolic_operand" ""))
1198 (const_string "lea")
1199 ]
1200 (const_string "imov")))
1201 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1202
1203 (define_insn "*movsi_1_nointernunit"
1204 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1205 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1206 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1207 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1208 {
1209 switch (get_attr_type (insn))
1210 {
1211 case TYPE_SSEMOV:
1212 if (get_attr_mode (insn) == TImode || which_alternative == 9)
1213 return "movdqa\t{%1, %0|%0, %1}";
1214 return "movd\t{%1, %0|%0, %1}";
1215
1216 case TYPE_MMXMOV:
1217 if (get_attr_mode (insn) == DImode)
1218 return "movq\t{%1, %0|%0, %1}";
1219 return "movd\t{%1, %0|%0, %1}";
1220
1221 case TYPE_LEA:
1222 return "lea{l}\t{%1, %0|%0, %1}";
1223
1224 default:
1225 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1226 abort();
1227 return "mov{l}\t{%1, %0|%0, %1}";
1228 }
1229 }
1230 [(set (attr "type")
1231 (cond [(eq_attr "alternative" "2,3,4")
1232 (const_string "mmxmov")
1233 (eq_attr "alternative" "5,6,7")
1234 (const_string "ssemov")
1235 (and (ne (symbol_ref "flag_pic") (const_int 0))
1236 (match_operand:SI 1 "symbolic_operand" ""))
1237 (const_string "lea")
1238 ]
1239 (const_string "imov")))
1240 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1241
1242 ;; Stores and loads of ax to arbitrary constant address.
1243 ;; We fake an second form of instruction to force reload to load address
1244 ;; into register when rax is not available
1245 (define_insn "*movabssi_1_rex64"
1246 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1247 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1248 "TARGET_64BIT"
1249 "@
1250 movabs{l}\t{%1, %P0|%P0, %1}
1251 mov{l}\t{%1, %a0|%a0, %1}
1252 movabs{l}\t{%1, %a0|%a0, %1}"
1253 [(set_attr "type" "imov")
1254 (set_attr "modrm" "0,*,*")
1255 (set_attr "length_address" "8,0,0")
1256 (set_attr "length_immediate" "0,*,*")
1257 (set_attr "memory" "store")
1258 (set_attr "mode" "SI")])
1259
1260 (define_insn "*movabssi_2_rex64"
1261 [(set (match_operand:SI 0 "register_operand" "=a,r")
1262 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1263 "TARGET_64BIT"
1264 "@
1265 movabs{l}\t{%P1, %0|%0, %P1}
1266 mov{l}\t{%a1, %0|%0, %a1}"
1267 [(set_attr "type" "imov")
1268 (set_attr "modrm" "0,*")
1269 (set_attr "length_address" "8,0")
1270 (set_attr "length_immediate" "0")
1271 (set_attr "memory" "load")
1272 (set_attr "mode" "SI")])
1273
1274 (define_insn "*swapsi"
1275 [(set (match_operand:SI 0 "register_operand" "+r")
1276 (match_operand:SI 1 "register_operand" "+r"))
1277 (set (match_dup 1)
1278 (match_dup 0))]
1279 ""
1280 "xchg{l}\t%1, %0"
1281 [(set_attr "type" "imov")
1282 (set_attr "pent_pair" "np")
1283 (set_attr "athlon_decode" "vector")
1284 (set_attr "mode" "SI")
1285 (set_attr "modrm" "0")
1286 (set_attr "ppro_uops" "few")])
1287
1288 (define_expand "movhi"
1289 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1290 (match_operand:HI 1 "general_operand" ""))]
1291 ""
1292 "ix86_expand_move (HImode, operands); DONE;")
1293
1294 (define_insn "*pushhi2"
1295 [(set (match_operand:HI 0 "push_operand" "=<,<")
1296 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1297 "!TARGET_64BIT"
1298 "@
1299 push{w}\t{|WORD PTR }%1
1300 push{w}\t%1"
1301 [(set_attr "type" "push")
1302 (set_attr "mode" "HI")])
1303
1304 ;; For 64BIT abi we always round up to 8 bytes.
1305 (define_insn "*pushhi2_rex64"
1306 [(set (match_operand:HI 0 "push_operand" "=X")
1307 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1308 "TARGET_64BIT"
1309 "push{q}\t%q1"
1310 [(set_attr "type" "push")
1311 (set_attr "mode" "QI")])
1312
1313 (define_insn "*movhi_1"
1314 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1315 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1316 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1317 {
1318 switch (get_attr_type (insn))
1319 {
1320 case TYPE_IMOVX:
1321 /* movzwl is faster than movw on p2 due to partial word stalls,
1322 though not as fast as an aligned movl. */
1323 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1324 default:
1325 if (get_attr_mode (insn) == MODE_SI)
1326 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1327 else
1328 return "mov{w}\t{%1, %0|%0, %1}";
1329 }
1330 }
1331 [(set (attr "type")
1332 (cond [(and (eq_attr "alternative" "0")
1333 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1334 (const_int 0))
1335 (eq (symbol_ref "TARGET_HIMODE_MATH")
1336 (const_int 0))))
1337 (const_string "imov")
1338 (and (eq_attr "alternative" "1,2")
1339 (match_operand:HI 1 "aligned_operand" ""))
1340 (const_string "imov")
1341 (and (ne (symbol_ref "TARGET_MOVX")
1342 (const_int 0))
1343 (eq_attr "alternative" "0,2"))
1344 (const_string "imovx")
1345 ]
1346 (const_string "imov")))
1347 (set (attr "mode")
1348 (cond [(eq_attr "type" "imovx")
1349 (const_string "SI")
1350 (and (eq_attr "alternative" "1,2")
1351 (match_operand:HI 1 "aligned_operand" ""))
1352 (const_string "SI")
1353 (and (eq_attr "alternative" "0")
1354 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1355 (const_int 0))
1356 (eq (symbol_ref "TARGET_HIMODE_MATH")
1357 (const_int 0))))
1358 (const_string "SI")
1359 ]
1360 (const_string "HI")))])
1361
1362 ;; Stores and loads of ax to arbitrary constant address.
1363 ;; We fake an second form of instruction to force reload to load address
1364 ;; into register when rax is not available
1365 (define_insn "*movabshi_1_rex64"
1366 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1367 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1368 "TARGET_64BIT"
1369 "@
1370 movabs{w}\t{%1, %P0|%P0, %1}
1371 mov{w}\t{%1, %a0|%a0, %1}
1372 movabs{w}\t{%1, %a0|%a0, %1}"
1373 [(set_attr "type" "imov")
1374 (set_attr "modrm" "0,*,*")
1375 (set_attr "length_address" "8,0,0")
1376 (set_attr "length_immediate" "0,*,*")
1377 (set_attr "memory" "store")
1378 (set_attr "mode" "HI")])
1379
1380 (define_insn "*movabshi_2_rex64"
1381 [(set (match_operand:HI 0 "register_operand" "=a,r")
1382 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1383 "TARGET_64BIT"
1384 "@
1385 movabs{w}\t{%P1, %0|%0, %P1}
1386 mov{w}\t{%a1, %0|%0, %a1}"
1387 [(set_attr "type" "imov")
1388 (set_attr "modrm" "0,*")
1389 (set_attr "length_address" "8,0")
1390 (set_attr "length_immediate" "0")
1391 (set_attr "memory" "load")
1392 (set_attr "mode" "HI")])
1393
1394 (define_insn "*swaphi_1"
1395 [(set (match_operand:HI 0 "register_operand" "+r")
1396 (match_operand:HI 1 "register_operand" "+r"))
1397 (set (match_dup 1)
1398 (match_dup 0))]
1399 "TARGET_PARTIAL_REG_STALL"
1400 "xchg{w}\t%1, %0"
1401 [(set_attr "type" "imov")
1402 (set_attr "pent_pair" "np")
1403 (set_attr "mode" "HI")
1404 (set_attr "modrm" "0")
1405 (set_attr "ppro_uops" "few")])
1406
1407 (define_insn "*swaphi_2"
1408 [(set (match_operand:HI 0 "register_operand" "+r")
1409 (match_operand:HI 1 "register_operand" "+r"))
1410 (set (match_dup 1)
1411 (match_dup 0))]
1412 "! TARGET_PARTIAL_REG_STALL"
1413 "xchg{l}\t%k1, %k0"
1414 [(set_attr "type" "imov")
1415 (set_attr "pent_pair" "np")
1416 (set_attr "mode" "SI")
1417 (set_attr "modrm" "0")
1418 (set_attr "ppro_uops" "few")])
1419
1420 (define_expand "movstricthi"
1421 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1422 (match_operand:HI 1 "general_operand" ""))]
1423 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1424 {
1425 /* Don't generate memory->memory moves, go through a register */
1426 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1427 operands[1] = force_reg (HImode, operands[1]);
1428 })
1429
1430 (define_insn "*movstricthi_1"
1431 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1432 (match_operand:HI 1 "general_operand" "rn,m"))]
1433 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1434 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1435 "mov{w}\t{%1, %0|%0, %1}"
1436 [(set_attr "type" "imov")
1437 (set_attr "mode" "HI")])
1438
1439 (define_insn "*movstricthi_xor"
1440 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1441 (match_operand:HI 1 "const0_operand" "i"))
1442 (clobber (reg:CC 17))]
1443 "reload_completed
1444 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1445 "xor{w}\t{%0, %0|%0, %0}"
1446 [(set_attr "type" "alu1")
1447 (set_attr "mode" "HI")
1448 (set_attr "length_immediate" "0")])
1449
1450 (define_expand "movqi"
1451 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1452 (match_operand:QI 1 "general_operand" ""))]
1453 ""
1454 "ix86_expand_move (QImode, operands); DONE;")
1455
1456 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1457 ;; "push a byte". But actually we use pushw, which has the effect
1458 ;; of rounding the amount pushed up to a halfword.
1459
1460 (define_insn "*pushqi2"
1461 [(set (match_operand:QI 0 "push_operand" "=X,X")
1462 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1463 "!TARGET_64BIT"
1464 "@
1465 push{w}\t{|word ptr }%1
1466 push{w}\t%w1"
1467 [(set_attr "type" "push")
1468 (set_attr "mode" "HI")])
1469
1470 ;; For 64BIT abi we always round up to 8 bytes.
1471 (define_insn "*pushqi2_rex64"
1472 [(set (match_operand:QI 0 "push_operand" "=X")
1473 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1474 "TARGET_64BIT"
1475 "push{q}\t%q1"
1476 [(set_attr "type" "push")
1477 (set_attr "mode" "QI")])
1478
1479 ;; Situation is quite tricky about when to choose full sized (SImode) move
1480 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1481 ;; partial register dependency machines (such as AMD Athlon), where QImode
1482 ;; moves issue extra dependency and for partial register stalls machines
1483 ;; that don't use QImode patterns (and QImode move cause stall on the next
1484 ;; instruction).
1485 ;;
1486 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1487 ;; register stall machines with, where we use QImode instructions, since
1488 ;; partial register stall can be caused there. Then we use movzx.
1489 (define_insn "*movqi_1"
1490 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1491 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1492 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1493 {
1494 switch (get_attr_type (insn))
1495 {
1496 case TYPE_IMOVX:
1497 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1498 abort ();
1499 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1500 default:
1501 if (get_attr_mode (insn) == MODE_SI)
1502 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1503 else
1504 return "mov{b}\t{%1, %0|%0, %1}";
1505 }
1506 }
1507 [(set (attr "type")
1508 (cond [(and (eq_attr "alternative" "3")
1509 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1510 (const_int 0))
1511 (eq (symbol_ref "TARGET_QIMODE_MATH")
1512 (const_int 0))))
1513 (const_string "imov")
1514 (eq_attr "alternative" "3,5")
1515 (const_string "imovx")
1516 (and (ne (symbol_ref "TARGET_MOVX")
1517 (const_int 0))
1518 (eq_attr "alternative" "2"))
1519 (const_string "imovx")
1520 ]
1521 (const_string "imov")))
1522 (set (attr "mode")
1523 (cond [(eq_attr "alternative" "3,4,5")
1524 (const_string "SI")
1525 (eq_attr "alternative" "6")
1526 (const_string "QI")
1527 (eq_attr "type" "imovx")
1528 (const_string "SI")
1529 (and (eq_attr "type" "imov")
1530 (and (eq_attr "alternative" "0,1,2")
1531 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1532 (const_int 0))))
1533 (const_string "SI")
1534 ;; Avoid partial register stalls when not using QImode arithmetic
1535 (and (eq_attr "type" "imov")
1536 (and (eq_attr "alternative" "0,1,2")
1537 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1538 (const_int 0))
1539 (eq (symbol_ref "TARGET_QIMODE_MATH")
1540 (const_int 0)))))
1541 (const_string "SI")
1542 ]
1543 (const_string "QI")))])
1544
1545 (define_expand "reload_outqi"
1546 [(parallel [(match_operand:QI 0 "" "=m")
1547 (match_operand:QI 1 "register_operand" "r")
1548 (match_operand:QI 2 "register_operand" "=&q")])]
1549 ""
1550 {
1551 rtx op0, op1, op2;
1552 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1553
1554 if (reg_overlap_mentioned_p (op2, op0))
1555 abort ();
1556 if (! q_regs_operand (op1, QImode))
1557 {
1558 emit_insn (gen_movqi (op2, op1));
1559 op1 = op2;
1560 }
1561 emit_insn (gen_movqi (op0, op1));
1562 DONE;
1563 })
1564
1565 (define_insn "*swapqi"
1566 [(set (match_operand:QI 0 "register_operand" "+r")
1567 (match_operand:QI 1 "register_operand" "+r"))
1568 (set (match_dup 1)
1569 (match_dup 0))]
1570 ""
1571 "xchg{b}\t%1, %0"
1572 [(set_attr "type" "imov")
1573 (set_attr "pent_pair" "np")
1574 (set_attr "mode" "QI")
1575 (set_attr "modrm" "0")
1576 (set_attr "ppro_uops" "few")])
1577
1578 (define_expand "movstrictqi"
1579 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1580 (match_operand:QI 1 "general_operand" ""))]
1581 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1582 {
1583 /* Don't generate memory->memory moves, go through a register. */
1584 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1585 operands[1] = force_reg (QImode, operands[1]);
1586 })
1587
1588 (define_insn "*movstrictqi_1"
1589 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1590 (match_operand:QI 1 "general_operand" "*qn,m"))]
1591 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1592 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1593 "mov{b}\t{%1, %0|%0, %1}"
1594 [(set_attr "type" "imov")
1595 (set_attr "mode" "QI")])
1596
1597 (define_insn "*movstrictqi_xor"
1598 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1599 (match_operand:QI 1 "const0_operand" "i"))
1600 (clobber (reg:CC 17))]
1601 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1602 "xor{b}\t{%0, %0|%0, %0}"
1603 [(set_attr "type" "alu1")
1604 (set_attr "mode" "QI")
1605 (set_attr "length_immediate" "0")])
1606
1607 (define_insn "*movsi_extv_1"
1608 [(set (match_operand:SI 0 "register_operand" "=R")
1609 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1610 (const_int 8)
1611 (const_int 8)))]
1612 ""
1613 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1614 [(set_attr "type" "imovx")
1615 (set_attr "mode" "SI")])
1616
1617 (define_insn "*movhi_extv_1"
1618 [(set (match_operand:HI 0 "register_operand" "=R")
1619 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1620 (const_int 8)
1621 (const_int 8)))]
1622 ""
1623 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1624 [(set_attr "type" "imovx")
1625 (set_attr "mode" "SI")])
1626
1627 (define_insn "*movqi_extv_1"
1628 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1629 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1630 (const_int 8)
1631 (const_int 8)))]
1632 "!TARGET_64BIT"
1633 {
1634 switch (get_attr_type (insn))
1635 {
1636 case TYPE_IMOVX:
1637 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1638 default:
1639 return "mov{b}\t{%h1, %0|%0, %h1}";
1640 }
1641 }
1642 [(set (attr "type")
1643 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1644 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1645 (ne (symbol_ref "TARGET_MOVX")
1646 (const_int 0))))
1647 (const_string "imovx")
1648 (const_string "imov")))
1649 (set (attr "mode")
1650 (if_then_else (eq_attr "type" "imovx")
1651 (const_string "SI")
1652 (const_string "QI")))])
1653
1654 (define_insn "*movqi_extv_1_rex64"
1655 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1656 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1657 (const_int 8)
1658 (const_int 8)))]
1659 "TARGET_64BIT"
1660 {
1661 switch (get_attr_type (insn))
1662 {
1663 case TYPE_IMOVX:
1664 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1665 default:
1666 return "mov{b}\t{%h1, %0|%0, %h1}";
1667 }
1668 }
1669 [(set (attr "type")
1670 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1671 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1672 (ne (symbol_ref "TARGET_MOVX")
1673 (const_int 0))))
1674 (const_string "imovx")
1675 (const_string "imov")))
1676 (set (attr "mode")
1677 (if_then_else (eq_attr "type" "imovx")
1678 (const_string "SI")
1679 (const_string "QI")))])
1680
1681 ;; Stores and loads of ax to arbitrary constant address.
1682 ;; We fake an second form of instruction to force reload to load address
1683 ;; into register when rax is not available
1684 (define_insn "*movabsqi_1_rex64"
1685 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1686 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1687 "TARGET_64BIT"
1688 "@
1689 movabs{b}\t{%1, %P0|%P0, %1}
1690 mov{b}\t{%1, %a0|%a0, %1}
1691 movabs{b}\t{%1, %a0|%a0, %1}"
1692 [(set_attr "type" "imov")
1693 (set_attr "modrm" "0,*,*")
1694 (set_attr "length_address" "8,0,0")
1695 (set_attr "length_immediate" "0,*,*")
1696 (set_attr "memory" "store")
1697 (set_attr "mode" "QI")])
1698
1699 (define_insn "*movabsqi_2_rex64"
1700 [(set (match_operand:QI 0 "register_operand" "=a,r")
1701 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1702 "TARGET_64BIT"
1703 "@
1704 movabs{b}\t{%P1, %0|%0, %P1}
1705 mov{b}\t{%a1, %0|%0, %a1}"
1706 [(set_attr "type" "imov")
1707 (set_attr "modrm" "0,*")
1708 (set_attr "length_address" "8,0")
1709 (set_attr "length_immediate" "0")
1710 (set_attr "memory" "load")
1711 (set_attr "mode" "QI")])
1712
1713 (define_insn "*movsi_extzv_1"
1714 [(set (match_operand:SI 0 "register_operand" "=R")
1715 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1716 (const_int 8)
1717 (const_int 8)))]
1718 ""
1719 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1720 [(set_attr "type" "imovx")
1721 (set_attr "mode" "SI")])
1722
1723 (define_insn "*movqi_extzv_2"
1724 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1725 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1726 (const_int 8)
1727 (const_int 8)) 0))]
1728 "!TARGET_64BIT"
1729 {
1730 switch (get_attr_type (insn))
1731 {
1732 case TYPE_IMOVX:
1733 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1734 default:
1735 return "mov{b}\t{%h1, %0|%0, %h1}";
1736 }
1737 }
1738 [(set (attr "type")
1739 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1740 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1741 (ne (symbol_ref "TARGET_MOVX")
1742 (const_int 0))))
1743 (const_string "imovx")
1744 (const_string "imov")))
1745 (set (attr "mode")
1746 (if_then_else (eq_attr "type" "imovx")
1747 (const_string "SI")
1748 (const_string "QI")))])
1749
1750 (define_insn "*movqi_extzv_2_rex64"
1751 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1752 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1753 (const_int 8)
1754 (const_int 8)) 0))]
1755 "TARGET_64BIT"
1756 {
1757 switch (get_attr_type (insn))
1758 {
1759 case TYPE_IMOVX:
1760 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1761 default:
1762 return "mov{b}\t{%h1, %0|%0, %h1}";
1763 }
1764 }
1765 [(set (attr "type")
1766 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1767 (ne (symbol_ref "TARGET_MOVX")
1768 (const_int 0)))
1769 (const_string "imovx")
1770 (const_string "imov")))
1771 (set (attr "mode")
1772 (if_then_else (eq_attr "type" "imovx")
1773 (const_string "SI")
1774 (const_string "QI")))])
1775
1776 (define_insn "movsi_insv_1"
1777 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1778 (const_int 8)
1779 (const_int 8))
1780 (match_operand:SI 1 "general_operand" "Qmn"))]
1781 "!TARGET_64BIT"
1782 "mov{b}\t{%b1, %h0|%h0, %b1}"
1783 [(set_attr "type" "imov")
1784 (set_attr "mode" "QI")])
1785
1786 (define_insn "*movsi_insv_1_rex64"
1787 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1788 (const_int 8)
1789 (const_int 8))
1790 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1791 "TARGET_64BIT"
1792 "mov{b}\t{%b1, %h0|%h0, %b1}"
1793 [(set_attr "type" "imov")
1794 (set_attr "mode" "QI")])
1795
1796 (define_insn "*movqi_insv_2"
1797 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1798 (const_int 8)
1799 (const_int 8))
1800 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1801 (const_int 8))
1802 (const_int 255)))]
1803 ""
1804 "mov{b}\t{%h1, %h0|%h0, %h1}"
1805 [(set_attr "type" "imov")
1806 (set_attr "mode" "QI")])
1807
1808 (define_expand "movdi"
1809 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1810 (match_operand:DI 1 "general_operand" ""))]
1811 ""
1812 "ix86_expand_move (DImode, operands); DONE;")
1813
1814 (define_insn "*pushdi"
1815 [(set (match_operand:DI 0 "push_operand" "=<")
1816 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1817 "!TARGET_64BIT"
1818 "#")
1819
1820 (define_insn "pushdi2_rex64"
1821 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1822 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1823 "TARGET_64BIT"
1824 "@
1825 push{q}\t%1
1826 #"
1827 [(set_attr "type" "push,multi")
1828 (set_attr "mode" "DI")])
1829
1830 ;; Convert impossible pushes of immediate to existing instructions.
1831 ;; First try to get scratch register and go through it. In case this
1832 ;; fails, push sign extended lower part first and then overwrite
1833 ;; upper part by 32bit move.
1834 (define_peephole2
1835 [(match_scratch:DI 2 "r")
1836 (set (match_operand:DI 0 "push_operand" "")
1837 (match_operand:DI 1 "immediate_operand" ""))]
1838 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1839 && !x86_64_immediate_operand (operands[1], DImode)"
1840 [(set (match_dup 2) (match_dup 1))
1841 (set (match_dup 0) (match_dup 2))]
1842 "")
1843
1844 ;; We need to define this as both peepholer and splitter for case
1845 ;; peephole2 pass is not run.
1846 (define_peephole2
1847 [(set (match_operand:DI 0 "push_operand" "")
1848 (match_operand:DI 1 "immediate_operand" ""))]
1849 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1850 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1851 [(set (match_dup 0) (match_dup 1))
1852 (set (match_dup 2) (match_dup 3))]
1853 "split_di (operands + 1, 1, operands + 2, operands + 3);
1854 operands[1] = gen_lowpart (DImode, operands[2]);
1855 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1856 GEN_INT (4)));
1857 ")
1858
1859 (define_split
1860 [(set (match_operand:DI 0 "push_operand" "")
1861 (match_operand:DI 1 "immediate_operand" ""))]
1862 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1863 && !symbolic_operand (operands[1], DImode)
1864 && !x86_64_immediate_operand (operands[1], DImode)"
1865 [(set (match_dup 0) (match_dup 1))
1866 (set (match_dup 2) (match_dup 3))]
1867 "split_di (operands + 1, 1, operands + 2, operands + 3);
1868 operands[1] = gen_lowpart (DImode, operands[2]);
1869 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1870 GEN_INT (4)));
1871 ")
1872
1873 (define_insn "*pushdi2_prologue_rex64"
1874 [(set (match_operand:DI 0 "push_operand" "=<")
1875 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1876 (clobber (mem:BLK (scratch)))]
1877 "TARGET_64BIT"
1878 "push{q}\t%1"
1879 [(set_attr "type" "push")
1880 (set_attr "mode" "DI")])
1881
1882 (define_insn "*popdi1_epilogue_rex64"
1883 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1884 (mem:DI (reg:DI 7)))
1885 (set (reg:DI 7)
1886 (plus:DI (reg:DI 7) (const_int 8)))
1887 (clobber (mem:BLK (scratch)))]
1888 "TARGET_64BIT"
1889 "pop{q}\t%0"
1890 [(set_attr "type" "pop")
1891 (set_attr "mode" "DI")])
1892
1893 (define_insn "popdi1"
1894 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1895 (mem:DI (reg:DI 7)))
1896 (set (reg:DI 7)
1897 (plus:DI (reg:DI 7) (const_int 8)))]
1898 "TARGET_64BIT"
1899 "pop{q}\t%0"
1900 [(set_attr "type" "pop")
1901 (set_attr "mode" "DI")])
1902
1903 (define_insn "*movdi_xor_rex64"
1904 [(set (match_operand:DI 0 "register_operand" "=r")
1905 (match_operand:DI 1 "const0_operand" "i"))
1906 (clobber (reg:CC 17))]
1907 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1908 && reload_completed"
1909 "xor{l}\t{%k0, %k0|%k0, %k0}"
1910 [(set_attr "type" "alu1")
1911 (set_attr "mode" "SI")
1912 (set_attr "length_immediate" "0")])
1913
1914 (define_insn "*movdi_or_rex64"
1915 [(set (match_operand:DI 0 "register_operand" "=r")
1916 (match_operand:DI 1 "const_int_operand" "i"))
1917 (clobber (reg:CC 17))]
1918 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1919 && reload_completed
1920 && GET_CODE (operands[1]) == CONST_INT
1921 && INTVAL (operands[1]) == -1"
1922 {
1923 operands[1] = constm1_rtx;
1924 return "or{q}\t{%1, %0|%0, %1}";
1925 }
1926 [(set_attr "type" "alu1")
1927 (set_attr "mode" "DI")
1928 (set_attr "length_immediate" "1")])
1929
1930 (define_insn "*movdi_2"
1931 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1932 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1933 "!TARGET_64BIT
1934 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1935 "@
1936 #
1937 #
1938 movq\t{%1, %0|%0, %1}
1939 movq\t{%1, %0|%0, %1}
1940 movq\t{%1, %0|%0, %1}
1941 movdqa\t{%1, %0|%0, %1}
1942 movq\t{%1, %0|%0, %1}"
1943 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1944 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1945
1946 (define_split
1947 [(set (match_operand:DI 0 "push_operand" "")
1948 (match_operand:DI 1 "general_operand" ""))]
1949 "!TARGET_64BIT && reload_completed
1950 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1951 [(const_int 0)]
1952 "ix86_split_long_move (operands); DONE;")
1953
1954 ;; %%% This multiword shite has got to go.
1955 (define_split
1956 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1957 (match_operand:DI 1 "general_operand" ""))]
1958 "!TARGET_64BIT && reload_completed
1959 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1960 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1961 [(const_int 0)]
1962 "ix86_split_long_move (operands); DONE;")
1963
1964 (define_insn "*movdi_1_rex64"
1965 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1966 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1967 "TARGET_64BIT
1968 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1969 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1970 {
1971 switch (get_attr_type (insn))
1972 {
1973 case TYPE_SSEMOV:
1974 if (get_attr_mode (insn) == MODE_TI)
1975 return "movdqa\t{%1, %0|%0, %1}";
1976 /* FALLTHRU */
1977 case TYPE_MMXMOV:
1978 /* Moves from and into integer register is done using movd opcode with
1979 REX prefix. */
1980 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1981 return "movd\t{%1, %0|%0, %1}";
1982 return "movq\t{%1, %0|%0, %1}";
1983 case TYPE_MULTI:
1984 return "#";
1985 case TYPE_LEA:
1986 return "lea{q}\t{%a1, %0|%0, %a1}";
1987 default:
1988 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1989 abort ();
1990 if (get_attr_mode (insn) == MODE_SI)
1991 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1992 else if (which_alternative == 2)
1993 return "movabs{q}\t{%1, %0|%0, %1}";
1994 else
1995 return "mov{q}\t{%1, %0|%0, %1}";
1996 }
1997 }
1998 [(set (attr "type")
1999 (cond [(eq_attr "alternative" "5,6,7")
2000 (const_string "mmxmov")
2001 (eq_attr "alternative" "8,9,10")
2002 (const_string "ssemov")
2003 (eq_attr "alternative" "4")
2004 (const_string "multi")
2005 (and (ne (symbol_ref "flag_pic") (const_int 0))
2006 (match_operand:DI 1 "symbolic_operand" ""))
2007 (const_string "lea")
2008 ]
2009 (const_string "imov")))
2010 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2011 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2012 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2013
2014 (define_insn "*movdi_1_rex64_nointerunit"
2015 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2016 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2017 "TARGET_64BIT
2018 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2019 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2020 {
2021 switch (get_attr_type (insn))
2022 {
2023 case TYPE_SSEMOV:
2024 if (get_attr_mode (insn) == MODE_TI)
2025 return "movdqa\t{%1, %0|%0, %1}";
2026 /* FALLTHRU */
2027 case TYPE_MMXMOV:
2028 return "movq\t{%1, %0|%0, %1}";
2029 case TYPE_MULTI:
2030 return "#";
2031 case TYPE_LEA:
2032 return "lea{q}\t{%a1, %0|%0, %a1}";
2033 default:
2034 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2035 abort ();
2036 if (get_attr_mode (insn) == MODE_SI)
2037 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2038 else if (which_alternative == 2)
2039 return "movabs{q}\t{%1, %0|%0, %1}";
2040 else
2041 return "mov{q}\t{%1, %0|%0, %1}";
2042 }
2043 }
2044 [(set (attr "type")
2045 (cond [(eq_attr "alternative" "5,6,7")
2046 (const_string "mmxmov")
2047 (eq_attr "alternative" "8,9,10")
2048 (const_string "ssemov")
2049 (eq_attr "alternative" "4")
2050 (const_string "multi")
2051 (and (ne (symbol_ref "flag_pic") (const_int 0))
2052 (match_operand:DI 1 "symbolic_operand" ""))
2053 (const_string "lea")
2054 ]
2055 (const_string "imov")))
2056 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2057 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2058 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2059
2060 ;; Stores and loads of ax to arbitrary constant address.
2061 ;; We fake an second form of instruction to force reload to load address
2062 ;; into register when rax is not available
2063 (define_insn "*movabsdi_1_rex64"
2064 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2065 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2066 "TARGET_64BIT"
2067 "@
2068 movabs{q}\t{%1, %P0|%P0, %1}
2069 mov{q}\t{%1, %a0|%a0, %1}
2070 movabs{q}\t{%1, %a0|%a0, %1}"
2071 [(set_attr "type" "imov")
2072 (set_attr "modrm" "0,*,*")
2073 (set_attr "length_address" "8,0,0")
2074 (set_attr "length_immediate" "0,*,*")
2075 (set_attr "memory" "store")
2076 (set_attr "mode" "DI")])
2077
2078 (define_insn "*movabsdi_2_rex64"
2079 [(set (match_operand:DI 0 "register_operand" "=a,r")
2080 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2081 "TARGET_64BIT"
2082 "@
2083 movabs{q}\t{%P1, %0|%0, %P1}
2084 mov{q}\t{%a1, %0|%0, %a1}"
2085 [(set_attr "type" "imov")
2086 (set_attr "modrm" "0,*")
2087 (set_attr "length_address" "8,0")
2088 (set_attr "length_immediate" "0")
2089 (set_attr "memory" "load")
2090 (set_attr "mode" "DI")])
2091
2092 ;; Convert impossible stores of immediate to existing instructions.
2093 ;; First try to get scratch register and go through it. In case this
2094 ;; fails, move by 32bit parts.
2095 (define_peephole2
2096 [(match_scratch:DI 2 "r")
2097 (set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2100 && !x86_64_immediate_operand (operands[1], DImode)"
2101 [(set (match_dup 2) (match_dup 1))
2102 (set (match_dup 0) (match_dup 2))]
2103 "")
2104
2105 ;; We need to define this as both peepholer and splitter for case
2106 ;; peephole2 pass is not run.
2107 (define_peephole2
2108 [(set (match_operand:DI 0 "memory_operand" "")
2109 (match_operand:DI 1 "immediate_operand" ""))]
2110 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2111 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2112 [(set (match_dup 2) (match_dup 3))
2113 (set (match_dup 4) (match_dup 5))]
2114 "split_di (operands, 2, operands + 2, operands + 4);")
2115
2116 (define_split
2117 [(set (match_operand:DI 0 "memory_operand" "")
2118 (match_operand:DI 1 "immediate_operand" ""))]
2119 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2120 && !symbolic_operand (operands[1], DImode)
2121 && !x86_64_immediate_operand (operands[1], DImode)"
2122 [(set (match_dup 2) (match_dup 3))
2123 (set (match_dup 4) (match_dup 5))]
2124 "split_di (operands, 2, operands + 2, operands + 4);")
2125
2126 (define_insn "*swapdi_rex64"
2127 [(set (match_operand:DI 0 "register_operand" "+r")
2128 (match_operand:DI 1 "register_operand" "+r"))
2129 (set (match_dup 1)
2130 (match_dup 0))]
2131 "TARGET_64BIT"
2132 "xchg{q}\t%1, %0"
2133 [(set_attr "type" "imov")
2134 (set_attr "pent_pair" "np")
2135 (set_attr "athlon_decode" "vector")
2136 (set_attr "mode" "DI")
2137 (set_attr "modrm" "0")
2138 (set_attr "ppro_uops" "few")])
2139
2140
2141 (define_expand "movsf"
2142 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2143 (match_operand:SF 1 "general_operand" ""))]
2144 ""
2145 "ix86_expand_move (SFmode, operands); DONE;")
2146
2147 (define_insn "*pushsf"
2148 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2149 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2150 "!TARGET_64BIT"
2151 {
2152 switch (which_alternative)
2153 {
2154 case 1:
2155 return "push{l}\t%1";
2156
2157 default:
2158 /* This insn should be already splitted before reg-stack. */
2159 abort ();
2160 }
2161 }
2162 [(set_attr "type" "multi,push,multi")
2163 (set_attr "mode" "SF,SI,SF")])
2164
2165 (define_insn "*pushsf_rex64"
2166 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2167 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2168 "TARGET_64BIT"
2169 {
2170 switch (which_alternative)
2171 {
2172 case 1:
2173 return "push{q}\t%q1";
2174
2175 default:
2176 /* This insn should be already splitted before reg-stack. */
2177 abort ();
2178 }
2179 }
2180 [(set_attr "type" "multi,push,multi")
2181 (set_attr "mode" "SF,DI,SF")])
2182
2183 (define_split
2184 [(set (match_operand:SF 0 "push_operand" "")
2185 (match_operand:SF 1 "memory_operand" ""))]
2186 "reload_completed
2187 && GET_CODE (operands[1]) == MEM
2188 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2189 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2190 [(set (match_dup 0)
2191 (match_dup 1))]
2192 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2193
2194
2195 ;; %%% Kill this when call knows how to work this out.
2196 (define_split
2197 [(set (match_operand:SF 0 "push_operand" "")
2198 (match_operand:SF 1 "any_fp_register_operand" ""))]
2199 "!TARGET_64BIT"
2200 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2201 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2202
2203 (define_split
2204 [(set (match_operand:SF 0 "push_operand" "")
2205 (match_operand:SF 1 "any_fp_register_operand" ""))]
2206 "TARGET_64BIT"
2207 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2208 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2209
2210 (define_insn "*movsf_1"
2211 [(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")
2212 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2213 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2214 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2215 && (reload_in_progress || reload_completed
2216 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2217 || GET_CODE (operands[1]) != CONST_DOUBLE
2218 || memory_operand (operands[0], SFmode))"
2219 {
2220 switch (which_alternative)
2221 {
2222 case 0:
2223 if (REG_P (operands[1])
2224 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2225 return "fstp\t%y0";
2226 else if (STACK_TOP_P (operands[0]))
2227 return "fld%z1\t%y1";
2228 else
2229 return "fst\t%y0";
2230
2231 case 1:
2232 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2233 return "fstp%z0\t%y0";
2234 else
2235 return "fst%z0\t%y0";
2236
2237 case 2:
2238 return standard_80387_constant_opcode (operands[1]);
2239
2240 case 3:
2241 case 4:
2242 return "mov{l}\t{%1, %0|%0, %1}";
2243 case 5:
2244 if (get_attr_mode (insn) == MODE_TI)
2245 return "pxor\t%0, %0";
2246 else
2247 return "xorps\t%0, %0";
2248 case 6:
2249 if (get_attr_mode (insn) == MODE_V4SF)
2250 return "movaps\t{%1, %0|%0, %1}";
2251 else
2252 return "movss\t{%1, %0|%0, %1}";
2253 case 7:
2254 case 8:
2255 return "movss\t{%1, %0|%0, %1}";
2256
2257 case 9:
2258 case 10:
2259 return "movd\t{%1, %0|%0, %1}";
2260
2261 case 11:
2262 return "movq\t{%1, %0|%0, %1}";
2263
2264 default:
2265 abort();
2266 }
2267 }
2268 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2269 (set (attr "mode")
2270 (cond [(eq_attr "alternative" "3,4,9,10")
2271 (const_string "SI")
2272 (eq_attr "alternative" "5")
2273 (if_then_else
2274 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2275 (const_int 0))
2276 (ne (symbol_ref "TARGET_SSE2")
2277 (const_int 0)))
2278 (eq (symbol_ref "optimize_size")
2279 (const_int 0)))
2280 (const_string "TI")
2281 (const_string "V4SF"))
2282 /* For architectures resolving dependencies on
2283 whole SSE registers use APS move to break dependency
2284 chains, otherwise use short move to avoid extra work.
2285
2286 Do the same for architectures resolving dependencies on
2287 the parts. While in DF mode it is better to always handle
2288 just register parts, the SF mode is different due to lack
2289 of instructions to load just part of the register. It is
2290 better to maintain the whole registers in single format
2291 to avoid problems on using packed logical operations. */
2292 (eq_attr "alternative" "6")
2293 (if_then_else
2294 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2295 (const_int 0))
2296 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2297 (const_int 0)))
2298 (const_string "V4SF")
2299 (const_string "SF"))
2300 (eq_attr "alternative" "11")
2301 (const_string "DI")]
2302 (const_string "SF")))])
2303
2304 (define_insn "*movsf_1_nointerunit"
2305 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2306 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2307 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2308 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2309 && (reload_in_progress || reload_completed
2310 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2311 || GET_CODE (operands[1]) != CONST_DOUBLE
2312 || memory_operand (operands[0], SFmode))"
2313 {
2314 switch (which_alternative)
2315 {
2316 case 0:
2317 if (REG_P (operands[1])
2318 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319 {
2320 if (REGNO (operands[0]) == FIRST_STACK_REG
2321 && TARGET_USE_FFREEP)
2322 return "ffreep\t%y0";
2323 return "fstp\t%y0";
2324 }
2325 else if (STACK_TOP_P (operands[0]))
2326 return "fld%z1\t%y1";
2327 else
2328 return "fst\t%y0";
2329
2330 case 1:
2331 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2332 return "fstp%z0\t%y0";
2333 else
2334 return "fst%z0\t%y0";
2335
2336 case 2:
2337 return standard_80387_constant_opcode (operands[1]);
2338
2339 case 3:
2340 case 4:
2341 return "mov{l}\t{%1, %0|%0, %1}";
2342 case 5:
2343 if (get_attr_mode (insn) == MODE_TI)
2344 return "pxor\t%0, %0";
2345 else
2346 return "xorps\t%0, %0";
2347 case 6:
2348 if (get_attr_mode (insn) == MODE_V4SF)
2349 return "movaps\t{%1, %0|%0, %1}";
2350 else
2351 return "movss\t{%1, %0|%0, %1}";
2352 case 7:
2353 case 8:
2354 return "movss\t{%1, %0|%0, %1}";
2355
2356 case 9:
2357 case 10:
2358 return "movd\t{%1, %0|%0, %1}";
2359
2360 case 11:
2361 return "movq\t{%1, %0|%0, %1}";
2362
2363 default:
2364 abort();
2365 }
2366 }
2367 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2368 (set (attr "mode")
2369 (cond [(eq_attr "alternative" "3,4,9,10")
2370 (const_string "SI")
2371 (eq_attr "alternative" "5")
2372 (if_then_else
2373 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2374 (const_int 0))
2375 (ne (symbol_ref "TARGET_SSE2")
2376 (const_int 0)))
2377 (eq (symbol_ref "optimize_size")
2378 (const_int 0)))
2379 (const_string "TI")
2380 (const_string "V4SF"))
2381 /* For architectures resolving dependencies on
2382 whole SSE registers use APS move to break dependency
2383 chains, otherwise use short move to avoid extra work.
2384
2385 Do the same for architectures resolving dependencies on
2386 the parts. While in DF mode it is better to always handle
2387 just register parts, the SF mode is different due to lack
2388 of instructions to load just part of the register. It is
2389 better to maintain the whole registers in single format
2390 to avoid problems on using packed logical operations. */
2391 (eq_attr "alternative" "6")
2392 (if_then_else
2393 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2394 (const_int 0))
2395 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2396 (const_int 0)))
2397 (const_string "V4SF")
2398 (const_string "SF"))
2399 (eq_attr "alternative" "11")
2400 (const_string "DI")]
2401 (const_string "SF")))])
2402
2403 (define_insn "*swapsf"
2404 [(set (match_operand:SF 0 "register_operand" "+f")
2405 (match_operand:SF 1 "register_operand" "+f"))
2406 (set (match_dup 1)
2407 (match_dup 0))]
2408 "reload_completed || !TARGET_SSE"
2409 {
2410 if (STACK_TOP_P (operands[0]))
2411 return "fxch\t%1";
2412 else
2413 return "fxch\t%0";
2414 }
2415 [(set_attr "type" "fxch")
2416 (set_attr "mode" "SF")])
2417
2418 (define_expand "movdf"
2419 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2420 (match_operand:DF 1 "general_operand" ""))]
2421 ""
2422 "ix86_expand_move (DFmode, operands); DONE;")
2423
2424 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2425 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2426 ;; On the average, pushdf using integers can be still shorter. Allow this
2427 ;; pattern for optimize_size too.
2428
2429 (define_insn "*pushdf_nointeger"
2430 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2431 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2432 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2433 {
2434 /* This insn should be already splitted before reg-stack. */
2435 abort ();
2436 }
2437 [(set_attr "type" "multi")
2438 (set_attr "mode" "DF,SI,SI,DF")])
2439
2440 (define_insn "*pushdf_integer"
2441 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2442 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2443 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2444 {
2445 /* This insn should be already splitted before reg-stack. */
2446 abort ();
2447 }
2448 [(set_attr "type" "multi")
2449 (set_attr "mode" "DF,SI,DF")])
2450
2451 ;; %%% Kill this when call knows how to work this out.
2452 (define_split
2453 [(set (match_operand:DF 0 "push_operand" "")
2454 (match_operand:DF 1 "any_fp_register_operand" ""))]
2455 "!TARGET_64BIT && reload_completed"
2456 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2457 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2458 "")
2459
2460 (define_split
2461 [(set (match_operand:DF 0 "push_operand" "")
2462 (match_operand:DF 1 "any_fp_register_operand" ""))]
2463 "TARGET_64BIT && reload_completed"
2464 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2465 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2466 "")
2467
2468 (define_split
2469 [(set (match_operand:DF 0 "push_operand" "")
2470 (match_operand:DF 1 "general_operand" ""))]
2471 "reload_completed"
2472 [(const_int 0)]
2473 "ix86_split_long_move (operands); DONE;")
2474
2475 ;; Moving is usually shorter when only FP registers are used. This separate
2476 ;; movdf pattern avoids the use of integer registers for FP operations
2477 ;; when optimizing for size.
2478
2479 (define_insn "*movdf_nointeger"
2480 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2481 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2482 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2483 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2484 && (reload_in_progress || reload_completed
2485 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2486 || GET_CODE (operands[1]) != CONST_DOUBLE
2487 || memory_operand (operands[0], DFmode))"
2488 {
2489 switch (which_alternative)
2490 {
2491 case 0:
2492 if (REG_P (operands[1])
2493 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2494 {
2495 if (REGNO (operands[0]) == FIRST_STACK_REG
2496 && TARGET_USE_FFREEP)
2497 return "ffreep\t%y0";
2498 return "fstp\t%y0";
2499 }
2500 else if (STACK_TOP_P (operands[0]))
2501 return "fld%z1\t%y1";
2502 else
2503 return "fst\t%y0";
2504
2505 case 1:
2506 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2507 return "fstp%z0\t%y0";
2508 else
2509 return "fst%z0\t%y0";
2510
2511 case 2:
2512 return standard_80387_constant_opcode (operands[1]);
2513
2514 case 3:
2515 case 4:
2516 return "#";
2517 case 5:
2518 switch (get_attr_mode (insn))
2519 {
2520 case MODE_V4SF:
2521 return "xorps\t%0, %0";
2522 case MODE_V2DF:
2523 return "xorpd\t%0, %0";
2524 case MODE_TI:
2525 return "pxor\t%0, %0";
2526 default:
2527 abort ();
2528 }
2529 case 6:
2530 switch (get_attr_mode (insn))
2531 {
2532 case MODE_V4SF:
2533 return "movaps\t{%1, %0|%0, %1}";
2534 case MODE_V2DF:
2535 return "movapd\t{%1, %0|%0, %1}";
2536 case MODE_DF:
2537 return "movsd\t{%1, %0|%0, %1}";
2538 default:
2539 abort ();
2540 }
2541 case 7:
2542 if (get_attr_mode (insn) == MODE_V2DF)
2543 return "movlpd\t{%1, %0|%0, %1}";
2544 else
2545 return "movsd\t{%1, %0|%0, %1}";
2546 case 8:
2547 return "movsd\t{%1, %0|%0, %1}";
2548
2549 default:
2550 abort();
2551 }
2552 }
2553 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2554 (set (attr "mode")
2555 (cond [(eq_attr "alternative" "3,4")
2556 (const_string "SI")
2557 /* xorps is one byte shorter. */
2558 (eq_attr "alternative" "5")
2559 (cond [(ne (symbol_ref "optimize_size")
2560 (const_int 0))
2561 (const_string "V4SF")
2562 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2563 (const_int 0))
2564 (const_string "TI")]
2565 (const_string "V2DF"))
2566 /* For architectures resolving dependencies on
2567 whole SSE registers use APD move to break dependency
2568 chains, otherwise use short move to avoid extra work.
2569
2570 movaps encodes one byte shorter. */
2571 (eq_attr "alternative" "6")
2572 (cond
2573 [(ne (symbol_ref "optimize_size")
2574 (const_int 0))
2575 (const_string "V4SF")
2576 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2577 (const_int 0))
2578 (const_string "V2DF")]
2579 (const_string "DF"))
2580 /* For architectures resolving dependencies on register
2581 parts we may avoid extra work to zero out upper part
2582 of register. */
2583 (eq_attr "alternative" "7")
2584 (if_then_else
2585 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2586 (const_int 0))
2587 (const_string "V2DF")
2588 (const_string "DF"))]
2589 (const_string "DF")))])
2590
2591 (define_insn "*movdf_integer"
2592 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2593 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2594 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2595 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2596 && (reload_in_progress || reload_completed
2597 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2598 || GET_CODE (operands[1]) != CONST_DOUBLE
2599 || memory_operand (operands[0], DFmode))"
2600 {
2601 switch (which_alternative)
2602 {
2603 case 0:
2604 if (REG_P (operands[1])
2605 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2606 {
2607 if (REGNO (operands[0]) == FIRST_STACK_REG
2608 && TARGET_USE_FFREEP)
2609 return "ffreep\t%y0";
2610 return "fstp\t%y0";
2611 }
2612 else if (STACK_TOP_P (operands[0]))
2613 return "fld%z1\t%y1";
2614 else
2615 return "fst\t%y0";
2616
2617 case 1:
2618 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2619 return "fstp%z0\t%y0";
2620 else
2621 return "fst%z0\t%y0";
2622
2623 case 2:
2624 return standard_80387_constant_opcode (operands[1]);
2625
2626 case 3:
2627 case 4:
2628 return "#";
2629
2630 case 5:
2631 switch (get_attr_mode (insn))
2632 {
2633 case MODE_V4SF:
2634 return "xorps\t%0, %0";
2635 case MODE_V2DF:
2636 return "xorpd\t%0, %0";
2637 case MODE_TI:
2638 return "pxor\t%0, %0";
2639 default:
2640 abort ();
2641 }
2642 case 6:
2643 switch (get_attr_mode (insn))
2644 {
2645 case MODE_V4SF:
2646 return "movaps\t{%1, %0|%0, %1}";
2647 case MODE_V2DF:
2648 return "movapd\t{%1, %0|%0, %1}";
2649 case MODE_DF:
2650 return "movsd\t{%1, %0|%0, %1}";
2651 default:
2652 abort ();
2653 }
2654 case 7:
2655 if (get_attr_mode (insn) == MODE_V2DF)
2656 return "movlpd\t{%1, %0|%0, %1}";
2657 else
2658 return "movsd\t{%1, %0|%0, %1}";
2659 case 8:
2660 return "movsd\t{%1, %0|%0, %1}";
2661
2662 default:
2663 abort();
2664 }
2665 }
2666 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2667 (set (attr "mode")
2668 (cond [(eq_attr "alternative" "3,4")
2669 (const_string "SI")
2670 /* xorps is one byte shorter. */
2671 (eq_attr "alternative" "5")
2672 (cond [(ne (symbol_ref "optimize_size")
2673 (const_int 0))
2674 (const_string "V4SF")
2675 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2676 (const_int 0))
2677 (const_string "TI")]
2678 (const_string "V2DF"))
2679 /* For architectures resolving dependencies on
2680 whole SSE registers use APD move to break dependency
2681 chains, otherwise use short move to avoid extra work.
2682
2683 movaps encodes one byte shorter. */
2684 (eq_attr "alternative" "6")
2685 (cond
2686 [(ne (symbol_ref "optimize_size")
2687 (const_int 0))
2688 (const_string "V4SF")
2689 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2690 (const_int 0))
2691 (const_string "V2DF")]
2692 (const_string "DF"))
2693 /* For architectures resolving dependencies on register
2694 parts we may avoid extra work to zero out upper part
2695 of register. */
2696 (eq_attr "alternative" "7")
2697 (if_then_else
2698 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2699 (const_int 0))
2700 (const_string "V2DF")
2701 (const_string "DF"))]
2702 (const_string "DF")))])
2703
2704 (define_split
2705 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2706 (match_operand:DF 1 "general_operand" ""))]
2707 "reload_completed
2708 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2709 && ! (ANY_FP_REG_P (operands[0]) ||
2710 (GET_CODE (operands[0]) == SUBREG
2711 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2712 && ! (ANY_FP_REG_P (operands[1]) ||
2713 (GET_CODE (operands[1]) == SUBREG
2714 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2715 [(const_int 0)]
2716 "ix86_split_long_move (operands); DONE;")
2717
2718 (define_insn "*swapdf"
2719 [(set (match_operand:DF 0 "register_operand" "+f")
2720 (match_operand:DF 1 "register_operand" "+f"))
2721 (set (match_dup 1)
2722 (match_dup 0))]
2723 "reload_completed || !TARGET_SSE2"
2724 {
2725 if (STACK_TOP_P (operands[0]))
2726 return "fxch\t%1";
2727 else
2728 return "fxch\t%0";
2729 }
2730 [(set_attr "type" "fxch")
2731 (set_attr "mode" "DF")])
2732
2733 (define_expand "movxf"
2734 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2735 (match_operand:XF 1 "general_operand" ""))]
2736 "!TARGET_64BIT"
2737 "ix86_expand_move (XFmode, operands); DONE;")
2738
2739 (define_expand "movtf"
2740 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2741 (match_operand:TF 1 "general_operand" ""))]
2742 ""
2743 "ix86_expand_move (TFmode, operands); DONE;")
2744
2745 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2746 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2747 ;; Pushing using integer instructions is longer except for constants
2748 ;; and direct memory references.
2749 ;; (assuming that any given constant is pushed only once, but this ought to be
2750 ;; handled elsewhere).
2751
2752 (define_insn "*pushxf_nointeger"
2753 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2754 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2755 "!TARGET_64BIT && optimize_size"
2756 {
2757 /* This insn should be already splitted before reg-stack. */
2758 abort ();
2759 }
2760 [(set_attr "type" "multi")
2761 (set_attr "mode" "XF,SI,SI")])
2762
2763 (define_insn "*pushtf_nointeger"
2764 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2765 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2766 "optimize_size"
2767 {
2768 /* This insn should be already splitted before reg-stack. */
2769 abort ();
2770 }
2771 [(set_attr "type" "multi")
2772 (set_attr "mode" "XF,SI,SI")])
2773
2774 (define_insn "*pushxf_integer"
2775 [(set (match_operand:XF 0 "push_operand" "=<,<")
2776 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2777 "!TARGET_64BIT && !optimize_size"
2778 {
2779 /* This insn should be already splitted before reg-stack. */
2780 abort ();
2781 }
2782 [(set_attr "type" "multi")
2783 (set_attr "mode" "XF,SI")])
2784
2785 (define_insn "*pushtf_integer"
2786 [(set (match_operand:TF 0 "push_operand" "=<,<")
2787 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2788 "!optimize_size"
2789 {
2790 /* This insn should be already splitted before reg-stack. */
2791 abort ();
2792 }
2793 [(set_attr "type" "multi")
2794 (set_attr "mode" "XF,SI")])
2795
2796 (define_split
2797 [(set (match_operand 0 "push_operand" "")
2798 (match_operand 1 "general_operand" ""))]
2799 "reload_completed
2800 && (GET_MODE (operands[0]) == XFmode
2801 || GET_MODE (operands[0]) == TFmode
2802 || GET_MODE (operands[0]) == DFmode)
2803 && !ANY_FP_REG_P (operands[1])"
2804 [(const_int 0)]
2805 "ix86_split_long_move (operands); DONE;")
2806
2807 (define_split
2808 [(set (match_operand:XF 0 "push_operand" "")
2809 (match_operand:XF 1 "any_fp_register_operand" ""))]
2810 "!TARGET_64BIT"
2811 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2812 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2813
2814 (define_split
2815 [(set (match_operand:TF 0 "push_operand" "")
2816 (match_operand:TF 1 "any_fp_register_operand" ""))]
2817 "!TARGET_64BIT"
2818 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2819 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2820
2821 (define_split
2822 [(set (match_operand:TF 0 "push_operand" "")
2823 (match_operand:TF 1 "any_fp_register_operand" ""))]
2824 "TARGET_64BIT"
2825 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2826 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2827
2828 ;; Do not use integer registers when optimizing for size
2829 (define_insn "*movxf_nointeger"
2830 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2831 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2832 "!TARGET_64BIT
2833 && optimize_size
2834 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2835 && (reload_in_progress || reload_completed
2836 || GET_CODE (operands[1]) != CONST_DOUBLE
2837 || memory_operand (operands[0], XFmode))"
2838 {
2839 switch (which_alternative)
2840 {
2841 case 0:
2842 if (REG_P (operands[1])
2843 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2844 {
2845 if (REGNO (operands[0]) == FIRST_STACK_REG
2846 && TARGET_USE_FFREEP)
2847 return "ffreep\t%y0";
2848 return "fstp\t%y0";
2849 }
2850 else if (STACK_TOP_P (operands[0]))
2851 return "fld%z1\t%y1";
2852 else
2853 return "fst\t%y0";
2854
2855 case 1:
2856 /* There is no non-popping store to memory for XFmode. So if
2857 we need one, follow the store with a load. */
2858 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2859 return "fstp%z0\t%y0\;fld%z0\t%y0";
2860 else
2861 return "fstp%z0\t%y0";
2862
2863 case 2:
2864 return standard_80387_constant_opcode (operands[1]);
2865
2866 case 3: case 4:
2867 return "#";
2868 }
2869 abort();
2870 }
2871 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2872 (set_attr "mode" "XF,XF,XF,SI,SI")])
2873
2874 (define_insn "*movtf_nointeger"
2875 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2876 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2877 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2878 && optimize_size
2879 && (reload_in_progress || reload_completed
2880 || GET_CODE (operands[1]) != CONST_DOUBLE
2881 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2882 || memory_operand (operands[0], TFmode))"
2883 {
2884 switch (which_alternative)
2885 {
2886 case 0:
2887 if (REG_P (operands[1])
2888 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2889 {
2890 if (REGNO (operands[0]) == FIRST_STACK_REG
2891 && TARGET_USE_FFREEP)
2892 return "ffreep\t%y0";
2893 return "fstp\t%y0";
2894 }
2895 else if (STACK_TOP_P (operands[0]))
2896 return "fld%z1\t%y1";
2897 else
2898 return "fst\t%y0";
2899
2900 case 1:
2901 /* There is no non-popping store to memory for XFmode. So if
2902 we need one, follow the store with a load. */
2903 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2904 return "fstp%z0\t%y0\;fld%z0\t%y0";
2905 else
2906 return "fstp%z0\t%y0";
2907
2908 case 2:
2909 return standard_80387_constant_opcode (operands[1]);
2910
2911 case 3: case 4:
2912 return "#";
2913 }
2914 abort();
2915 }
2916 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2917 (set_attr "mode" "XF,XF,XF,SI,SI")])
2918
2919 (define_insn "*movxf_integer"
2920 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2921 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2922 "!TARGET_64BIT
2923 && !optimize_size
2924 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2925 && (reload_in_progress || reload_completed
2926 || GET_CODE (operands[1]) != CONST_DOUBLE
2927 || memory_operand (operands[0], XFmode))"
2928 {
2929 switch (which_alternative)
2930 {
2931 case 0:
2932 if (REG_P (operands[1])
2933 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2934 {
2935 if (REGNO (operands[0]) == FIRST_STACK_REG
2936 && TARGET_USE_FFREEP)
2937 return "ffreep\t%y0";
2938 return "fstp\t%y0";
2939 }
2940 else if (STACK_TOP_P (operands[0]))
2941 return "fld%z1\t%y1";
2942 else
2943 return "fst\t%y0";
2944
2945 case 1:
2946 /* There is no non-popping store to memory for XFmode. So if
2947 we need one, follow the store with a load. */
2948 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2949 return "fstp%z0\t%y0\;fld%z0\t%y0";
2950 else
2951 return "fstp%z0\t%y0";
2952
2953 case 2:
2954 return standard_80387_constant_opcode (operands[1]);
2955
2956 case 3: case 4:
2957 return "#";
2958 }
2959 abort();
2960 }
2961 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2962 (set_attr "mode" "XF,XF,XF,SI,SI")])
2963
2964 (define_insn "*movtf_integer"
2965 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2966 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2967 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2968 && !optimize_size
2969 && (reload_in_progress || reload_completed
2970 || GET_CODE (operands[1]) != CONST_DOUBLE
2971 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2972 || memory_operand (operands[0], TFmode))"
2973 {
2974 switch (which_alternative)
2975 {
2976 case 0:
2977 if (REG_P (operands[1])
2978 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2979 {
2980 if (REGNO (operands[0]) == FIRST_STACK_REG
2981 && TARGET_USE_FFREEP)
2982 return "ffreep\t%y0";
2983 return "fstp\t%y0";
2984 }
2985 else if (STACK_TOP_P (operands[0]))
2986 return "fld%z1\t%y1";
2987 else
2988 return "fst\t%y0";
2989
2990 case 1:
2991 /* There is no non-popping store to memory for XFmode. So if
2992 we need one, follow the store with a load. */
2993 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2994 return "fstp%z0\t%y0\;fld%z0\t%y0";
2995 else
2996 return "fstp%z0\t%y0";
2997
2998 case 2:
2999 return standard_80387_constant_opcode (operands[1]);
3000
3001 case 3: case 4:
3002 return "#";
3003 }
3004 abort();
3005 }
3006 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3007 (set_attr "mode" "XF,XF,XF,SI,SI")])
3008
3009 (define_split
3010 [(set (match_operand 0 "nonimmediate_operand" "")
3011 (match_operand 1 "general_operand" ""))]
3012 "reload_completed
3013 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3014 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3015 && ! (ANY_FP_REG_P (operands[0]) ||
3016 (GET_CODE (operands[0]) == SUBREG
3017 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3018 && ! (ANY_FP_REG_P (operands[1]) ||
3019 (GET_CODE (operands[1]) == SUBREG
3020 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3021 [(const_int 0)]
3022 "ix86_split_long_move (operands); DONE;")
3023
3024 (define_split
3025 [(set (match_operand 0 "register_operand" "")
3026 (match_operand 1 "memory_operand" ""))]
3027 "reload_completed
3028 && GET_CODE (operands[1]) == MEM
3029 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3030 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3031 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3032 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3033 && (!(SSE_REG_P (operands[0]) ||
3034 (GET_CODE (operands[0]) == SUBREG
3035 && SSE_REG_P (SUBREG_REG (operands[0]))))
3036 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3037 && (!(FP_REG_P (operands[0]) ||
3038 (GET_CODE (operands[0]) == SUBREG
3039 && FP_REG_P (SUBREG_REG (operands[0]))))
3040 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3041 [(set (match_dup 0)
3042 (match_dup 1))]
3043 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3044
3045 (define_insn "swapxf"
3046 [(set (match_operand:XF 0 "register_operand" "+f")
3047 (match_operand:XF 1 "register_operand" "+f"))
3048 (set (match_dup 1)
3049 (match_dup 0))]
3050 ""
3051 {
3052 if (STACK_TOP_P (operands[0]))
3053 return "fxch\t%1";
3054 else
3055 return "fxch\t%0";
3056 }
3057 [(set_attr "type" "fxch")
3058 (set_attr "mode" "XF")])
3059
3060 (define_insn "swaptf"
3061 [(set (match_operand:TF 0 "register_operand" "+f")
3062 (match_operand:TF 1 "register_operand" "+f"))
3063 (set (match_dup 1)
3064 (match_dup 0))]
3065 ""
3066 {
3067 if (STACK_TOP_P (operands[0]))
3068 return "fxch\t%1";
3069 else
3070 return "fxch\t%0";
3071 }
3072 [(set_attr "type" "fxch")
3073 (set_attr "mode" "XF")])
3074 \f
3075 ;; Zero extension instructions
3076
3077 (define_expand "zero_extendhisi2"
3078 [(set (match_operand:SI 0 "register_operand" "")
3079 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3080 ""
3081 {
3082 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3083 {
3084 operands[1] = force_reg (HImode, operands[1]);
3085 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3086 DONE;
3087 }
3088 })
3089
3090 (define_insn "zero_extendhisi2_and"
3091 [(set (match_operand:SI 0 "register_operand" "=r")
3092 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3093 (clobber (reg:CC 17))]
3094 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3095 "#"
3096 [(set_attr "type" "alu1")
3097 (set_attr "mode" "SI")])
3098
3099 (define_split
3100 [(set (match_operand:SI 0 "register_operand" "")
3101 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3102 (clobber (reg:CC 17))]
3103 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3104 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3105 (clobber (reg:CC 17))])]
3106 "")
3107
3108 (define_insn "*zero_extendhisi2_movzwl"
3109 [(set (match_operand:SI 0 "register_operand" "=r")
3110 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3111 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3112 "movz{wl|x}\t{%1, %0|%0, %1}"
3113 [(set_attr "type" "imovx")
3114 (set_attr "mode" "SI")])
3115
3116 (define_expand "zero_extendqihi2"
3117 [(parallel
3118 [(set (match_operand:HI 0 "register_operand" "")
3119 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3120 (clobber (reg:CC 17))])]
3121 ""
3122 "")
3123
3124 (define_insn "*zero_extendqihi2_and"
3125 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3126 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3127 (clobber (reg:CC 17))]
3128 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3129 "#"
3130 [(set_attr "type" "alu1")
3131 (set_attr "mode" "HI")])
3132
3133 (define_insn "*zero_extendqihi2_movzbw_and"
3134 [(set (match_operand:HI 0 "register_operand" "=r,r")
3135 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3136 (clobber (reg:CC 17))]
3137 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3138 "#"
3139 [(set_attr "type" "imovx,alu1")
3140 (set_attr "mode" "HI")])
3141
3142 (define_insn "*zero_extendqihi2_movzbw"
3143 [(set (match_operand:HI 0 "register_operand" "=r")
3144 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3145 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3146 "movz{bw|x}\t{%1, %0|%0, %1}"
3147 [(set_attr "type" "imovx")
3148 (set_attr "mode" "HI")])
3149
3150 ;; For the movzbw case strip only the clobber
3151 (define_split
3152 [(set (match_operand:HI 0 "register_operand" "")
3153 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3154 (clobber (reg:CC 17))]
3155 "reload_completed
3156 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3157 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3158 [(set (match_operand:HI 0 "register_operand" "")
3159 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3160
3161 ;; When source and destination does not overlap, clear destination
3162 ;; first and then do the movb
3163 (define_split
3164 [(set (match_operand:HI 0 "register_operand" "")
3165 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3166 (clobber (reg:CC 17))]
3167 "reload_completed
3168 && ANY_QI_REG_P (operands[0])
3169 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3170 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3171 [(set (match_dup 0) (const_int 0))
3172 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3173 "operands[2] = gen_lowpart (QImode, operands[0]);")
3174
3175 ;; Rest is handled by single and.
3176 (define_split
3177 [(set (match_operand:HI 0 "register_operand" "")
3178 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3179 (clobber (reg:CC 17))]
3180 "reload_completed
3181 && true_regnum (operands[0]) == true_regnum (operands[1])"
3182 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3183 (clobber (reg:CC 17))])]
3184 "")
3185
3186 (define_expand "zero_extendqisi2"
3187 [(parallel
3188 [(set (match_operand:SI 0 "register_operand" "")
3189 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3190 (clobber (reg:CC 17))])]
3191 ""
3192 "")
3193
3194 (define_insn "*zero_extendqisi2_and"
3195 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3196 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3197 (clobber (reg:CC 17))]
3198 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3199 "#"
3200 [(set_attr "type" "alu1")
3201 (set_attr "mode" "SI")])
3202
3203 (define_insn "*zero_extendqisi2_movzbw_and"
3204 [(set (match_operand:SI 0 "register_operand" "=r,r")
3205 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3206 (clobber (reg:CC 17))]
3207 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3208 "#"
3209 [(set_attr "type" "imovx,alu1")
3210 (set_attr "mode" "SI")])
3211
3212 (define_insn "*zero_extendqisi2_movzbw"
3213 [(set (match_operand:SI 0 "register_operand" "=r")
3214 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3215 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3216 "movz{bl|x}\t{%1, %0|%0, %1}"
3217 [(set_attr "type" "imovx")
3218 (set_attr "mode" "SI")])
3219
3220 ;; For the movzbl case strip only the clobber
3221 (define_split
3222 [(set (match_operand:SI 0 "register_operand" "")
3223 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3224 (clobber (reg:CC 17))]
3225 "reload_completed
3226 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3227 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3228 [(set (match_dup 0)
3229 (zero_extend:SI (match_dup 1)))])
3230
3231 ;; When source and destination does not overlap, clear destination
3232 ;; first and then do the movb
3233 (define_split
3234 [(set (match_operand:SI 0 "register_operand" "")
3235 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3236 (clobber (reg:CC 17))]
3237 "reload_completed
3238 && ANY_QI_REG_P (operands[0])
3239 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3240 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3241 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3242 [(set (match_dup 0) (const_int 0))
3243 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3244 "operands[2] = gen_lowpart (QImode, operands[0]);")
3245
3246 ;; Rest is handled by single and.
3247 (define_split
3248 [(set (match_operand:SI 0 "register_operand" "")
3249 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3250 (clobber (reg:CC 17))]
3251 "reload_completed
3252 && true_regnum (operands[0]) == true_regnum (operands[1])"
3253 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3254 (clobber (reg:CC 17))])]
3255 "")
3256
3257 ;; %%% Kill me once multi-word ops are sane.
3258 (define_expand "zero_extendsidi2"
3259 [(set (match_operand:DI 0 "register_operand" "=r")
3260 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3261 ""
3262 "if (!TARGET_64BIT)
3263 {
3264 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3265 DONE;
3266 }
3267 ")
3268
3269 (define_insn "zero_extendsidi2_32"
3270 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3271 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3272 (clobber (reg:CC 17))]
3273 "!TARGET_64BIT"
3274 "#"
3275 [(set_attr "mode" "SI")])
3276
3277 (define_insn "zero_extendsidi2_rex64"
3278 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3279 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3280 "TARGET_64BIT"
3281 "@
3282 mov\t{%k1, %k0|%k0, %k1}
3283 #"
3284 [(set_attr "type" "imovx,imov")
3285 (set_attr "mode" "SI,DI")])
3286
3287 (define_split
3288 [(set (match_operand:DI 0 "memory_operand" "")
3289 (zero_extend:DI (match_dup 0)))]
3290 "TARGET_64BIT"
3291 [(set (match_dup 4) (const_int 0))]
3292 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3293
3294 (define_split
3295 [(set (match_operand:DI 0 "register_operand" "")
3296 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3297 (clobber (reg:CC 17))]
3298 "!TARGET_64BIT && reload_completed
3299 && true_regnum (operands[0]) == true_regnum (operands[1])"
3300 [(set (match_dup 4) (const_int 0))]
3301 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3302
3303 (define_split
3304 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3305 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3306 (clobber (reg:CC 17))]
3307 "!TARGET_64BIT && reload_completed"
3308 [(set (match_dup 3) (match_dup 1))
3309 (set (match_dup 4) (const_int 0))]
3310 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3311
3312 (define_insn "zero_extendhidi2"
3313 [(set (match_operand:DI 0 "register_operand" "=r,r")
3314 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3315 "TARGET_64BIT"
3316 "@
3317 movz{wl|x}\t{%1, %k0|%k0, %1}
3318 movz{wq|x}\t{%1, %0|%0, %1}"
3319 [(set_attr "type" "imovx")
3320 (set_attr "mode" "SI,DI")])
3321
3322 (define_insn "zero_extendqidi2"
3323 [(set (match_operand:DI 0 "register_operand" "=r,r")
3324 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3325 "TARGET_64BIT"
3326 "@
3327 movz{bl|x}\t{%1, %k0|%k0, %1}
3328 movz{bq|x}\t{%1, %0|%0, %1}"
3329 [(set_attr "type" "imovx")
3330 (set_attr "mode" "SI,DI")])
3331 \f
3332 ;; Sign extension instructions
3333
3334 (define_expand "extendsidi2"
3335 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3336 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3337 (clobber (reg:CC 17))
3338 (clobber (match_scratch:SI 2 ""))])]
3339 ""
3340 {
3341 if (TARGET_64BIT)
3342 {
3343 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3344 DONE;
3345 }
3346 })
3347
3348 (define_insn "*extendsidi2_1"
3349 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3350 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3351 (clobber (reg:CC 17))
3352 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3353 "!TARGET_64BIT"
3354 "#")
3355
3356 (define_insn "extendsidi2_rex64"
3357 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3358 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3359 "TARGET_64BIT"
3360 "@
3361 {cltq|cdqe}
3362 movs{lq|x}\t{%1,%0|%0, %1}"
3363 [(set_attr "type" "imovx")
3364 (set_attr "mode" "DI")
3365 (set_attr "prefix_0f" "0")
3366 (set_attr "modrm" "0,1")])
3367
3368 (define_insn "extendhidi2"
3369 [(set (match_operand:DI 0 "register_operand" "=r")
3370 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3371 "TARGET_64BIT"
3372 "movs{wq|x}\t{%1,%0|%0, %1}"
3373 [(set_attr "type" "imovx")
3374 (set_attr "mode" "DI")])
3375
3376 (define_insn "extendqidi2"
3377 [(set (match_operand:DI 0 "register_operand" "=r")
3378 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3379 "TARGET_64BIT"
3380 "movs{bq|x}\t{%1,%0|%0, %1}"
3381 [(set_attr "type" "imovx")
3382 (set_attr "mode" "DI")])
3383
3384 ;; Extend to memory case when source register does die.
3385 (define_split
3386 [(set (match_operand:DI 0 "memory_operand" "")
3387 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3388 (clobber (reg:CC 17))
3389 (clobber (match_operand:SI 2 "register_operand" ""))]
3390 "(reload_completed
3391 && dead_or_set_p (insn, operands[1])
3392 && !reg_mentioned_p (operands[1], operands[0]))"
3393 [(set (match_dup 3) (match_dup 1))
3394 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3395 (clobber (reg:CC 17))])
3396 (set (match_dup 4) (match_dup 1))]
3397 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3398
3399 ;; Extend to memory case when source register does not die.
3400 (define_split
3401 [(set (match_operand:DI 0 "memory_operand" "")
3402 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3403 (clobber (reg:CC 17))
3404 (clobber (match_operand:SI 2 "register_operand" ""))]
3405 "reload_completed"
3406 [(const_int 0)]
3407 {
3408 split_di (&operands[0], 1, &operands[3], &operands[4]);
3409
3410 emit_move_insn (operands[3], operands[1]);
3411
3412 /* Generate a cltd if possible and doing so it profitable. */
3413 if (true_regnum (operands[1]) == 0
3414 && true_regnum (operands[2]) == 1
3415 && (optimize_size || TARGET_USE_CLTD))
3416 {
3417 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3418 }
3419 else
3420 {
3421 emit_move_insn (operands[2], operands[1]);
3422 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3423 }
3424 emit_move_insn (operands[4], operands[2]);
3425 DONE;
3426 })
3427
3428 ;; Extend to register case. Optimize case where source and destination
3429 ;; registers match and cases where we can use cltd.
3430 (define_split
3431 [(set (match_operand:DI 0 "register_operand" "")
3432 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3433 (clobber (reg:CC 17))
3434 (clobber (match_scratch:SI 2 ""))]
3435 "reload_completed"
3436 [(const_int 0)]
3437 {
3438 split_di (&operands[0], 1, &operands[3], &operands[4]);
3439
3440 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3441 emit_move_insn (operands[3], operands[1]);
3442
3443 /* Generate a cltd if possible and doing so it profitable. */
3444 if (true_regnum (operands[3]) == 0
3445 && (optimize_size || TARGET_USE_CLTD))
3446 {
3447 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3448 DONE;
3449 }
3450
3451 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3452 emit_move_insn (operands[4], operands[1]);
3453
3454 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3455 DONE;
3456 })
3457
3458 (define_insn "extendhisi2"
3459 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3460 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3461 ""
3462 {
3463 switch (get_attr_prefix_0f (insn))
3464 {
3465 case 0:
3466 return "{cwtl|cwde}";
3467 default:
3468 return "movs{wl|x}\t{%1,%0|%0, %1}";
3469 }
3470 }
3471 [(set_attr "type" "imovx")
3472 (set_attr "mode" "SI")
3473 (set (attr "prefix_0f")
3474 ;; movsx is short decodable while cwtl is vector decoded.
3475 (if_then_else (and (eq_attr "cpu" "!k6")
3476 (eq_attr "alternative" "0"))
3477 (const_string "0")
3478 (const_string "1")))
3479 (set (attr "modrm")
3480 (if_then_else (eq_attr "prefix_0f" "0")
3481 (const_string "0")
3482 (const_string "1")))])
3483
3484 (define_insn "*extendhisi2_zext"
3485 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3486 (zero_extend:DI
3487 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3488 "TARGET_64BIT"
3489 {
3490 switch (get_attr_prefix_0f (insn))
3491 {
3492 case 0:
3493 return "{cwtl|cwde}";
3494 default:
3495 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3496 }
3497 }
3498 [(set_attr "type" "imovx")
3499 (set_attr "mode" "SI")
3500 (set (attr "prefix_0f")
3501 ;; movsx is short decodable while cwtl is vector decoded.
3502 (if_then_else (and (eq_attr "cpu" "!k6")
3503 (eq_attr "alternative" "0"))
3504 (const_string "0")
3505 (const_string "1")))
3506 (set (attr "modrm")
3507 (if_then_else (eq_attr "prefix_0f" "0")
3508 (const_string "0")
3509 (const_string "1")))])
3510
3511 (define_insn "extendqihi2"
3512 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3513 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3514 ""
3515 {
3516 switch (get_attr_prefix_0f (insn))
3517 {
3518 case 0:
3519 return "{cbtw|cbw}";
3520 default:
3521 return "movs{bw|x}\t{%1,%0|%0, %1}";
3522 }
3523 }
3524 [(set_attr "type" "imovx")
3525 (set_attr "mode" "HI")
3526 (set (attr "prefix_0f")
3527 ;; movsx is short decodable while cwtl is vector decoded.
3528 (if_then_else (and (eq_attr "cpu" "!k6")
3529 (eq_attr "alternative" "0"))
3530 (const_string "0")
3531 (const_string "1")))
3532 (set (attr "modrm")
3533 (if_then_else (eq_attr "prefix_0f" "0")
3534 (const_string "0")
3535 (const_string "1")))])
3536
3537 (define_insn "extendqisi2"
3538 [(set (match_operand:SI 0 "register_operand" "=r")
3539 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3540 ""
3541 "movs{bl|x}\t{%1,%0|%0, %1}"
3542 [(set_attr "type" "imovx")
3543 (set_attr "mode" "SI")])
3544
3545 (define_insn "*extendqisi2_zext"
3546 [(set (match_operand:DI 0 "register_operand" "=r")
3547 (zero_extend:DI
3548 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3549 "TARGET_64BIT"
3550 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3551 [(set_attr "type" "imovx")
3552 (set_attr "mode" "SI")])
3553 \f
3554 ;; Conversions between float and double.
3555
3556 ;; These are all no-ops in the model used for the 80387. So just
3557 ;; emit moves.
3558
3559 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3560 (define_insn "*dummy_extendsfdf2"
3561 [(set (match_operand:DF 0 "push_operand" "=<")
3562 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3563 "0"
3564 "#")
3565
3566 (define_split
3567 [(set (match_operand:DF 0 "push_operand" "")
3568 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3569 "!TARGET_64BIT"
3570 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3571 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3572
3573 (define_split
3574 [(set (match_operand:DF 0 "push_operand" "")
3575 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3576 "TARGET_64BIT"
3577 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3578 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3579
3580 (define_insn "*dummy_extendsfxf2"
3581 [(set (match_operand:XF 0 "push_operand" "=<")
3582 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3583 "0"
3584 "#")
3585
3586 (define_split
3587 [(set (match_operand:XF 0 "push_operand" "")
3588 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3589 "!TARGET_64BIT"
3590 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3591 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3592
3593 (define_insn "*dummy_extendsftf2"
3594 [(set (match_operand:TF 0 "push_operand" "=<")
3595 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3596 "0"
3597 "#")
3598
3599 (define_split
3600 [(set (match_operand:TF 0 "push_operand" "")
3601 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3602 "!TARGET_64BIT"
3603 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3604 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3605
3606 (define_split
3607 [(set (match_operand:TF 0 "push_operand" "")
3608 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3609 "TARGET_64BIT"
3610 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3611 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3612
3613 (define_insn "*dummy_extenddfxf2"
3614 [(set (match_operand:XF 0 "push_operand" "=<")
3615 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3616 "0"
3617 "#")
3618
3619 (define_split
3620 [(set (match_operand:XF 0 "push_operand" "")
3621 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3622 "!TARGET_64BIT"
3623 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3624 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3625
3626 (define_insn "*dummy_extenddftf2"
3627 [(set (match_operand:TF 0 "push_operand" "=<")
3628 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3629 "0"
3630 "#")
3631
3632 (define_split
3633 [(set (match_operand:TF 0 "push_operand" "")
3634 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3635 "!TARGET_64BIT"
3636 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3637 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3638
3639 (define_split
3640 [(set (match_operand:TF 0 "push_operand" "")
3641 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3642 "TARGET_64BIT"
3643 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3644 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3645
3646 (define_expand "extendsfdf2"
3647 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3648 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3649 "TARGET_80387 || TARGET_SSE2"
3650 {
3651 /* ??? Needed for compress_float_constant since all fp constants
3652 are LEGITIMATE_CONSTANT_P. */
3653 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3654 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3655 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3656 operands[1] = force_reg (SFmode, operands[1]);
3657 })
3658
3659 (define_insn "*extendsfdf2_1"
3660 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3661 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3662 "(TARGET_80387 || TARGET_SSE2)
3663 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3664 {
3665 switch (which_alternative)
3666 {
3667 case 0:
3668 if (REG_P (operands[1])
3669 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3670 return "fstp\t%y0";
3671 else if (STACK_TOP_P (operands[0]))
3672 return "fld%z1\t%y1";
3673 else
3674 return "fst\t%y0";
3675
3676 case 1:
3677 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3678 return "fstp%z0\t%y0";
3679
3680 else
3681 return "fst%z0\t%y0";
3682 case 2:
3683 return "cvtss2sd\t{%1, %0|%0, %1}";
3684
3685 default:
3686 abort ();
3687 }
3688 }
3689 [(set_attr "type" "fmov,fmov,ssecvt")
3690 (set_attr "mode" "SF,XF,DF")])
3691
3692 (define_insn "*extendsfdf2_1_sse_only"
3693 [(set (match_operand:DF 0 "register_operand" "=Y")
3694 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3695 "!TARGET_80387 && TARGET_SSE2
3696 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3697 "cvtss2sd\t{%1, %0|%0, %1}"
3698 [(set_attr "type" "ssecvt")
3699 (set_attr "mode" "DF")])
3700
3701 (define_expand "extendsfxf2"
3702 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3703 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3704 "!TARGET_64BIT && TARGET_80387"
3705 {
3706 /* ??? Needed for compress_float_constant since all fp constants
3707 are LEGITIMATE_CONSTANT_P. */
3708 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3709 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3710 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3711 operands[1] = force_reg (SFmode, operands[1]);
3712 })
3713
3714 (define_insn "*extendsfxf2_1"
3715 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3716 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3717 "!TARGET_64BIT && TARGET_80387
3718 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3719 {
3720 switch (which_alternative)
3721 {
3722 case 0:
3723 if (REG_P (operands[1])
3724 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3725 return "fstp\t%y0";
3726 else if (STACK_TOP_P (operands[0]))
3727 return "fld%z1\t%y1";
3728 else
3729 return "fst\t%y0";
3730
3731 case 1:
3732 /* There is no non-popping store to memory for XFmode. So if
3733 we need one, follow the store with a load. */
3734 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3735 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3736 else
3737 return "fstp%z0\t%y0";
3738
3739 default:
3740 abort ();
3741 }
3742 }
3743 [(set_attr "type" "fmov")
3744 (set_attr "mode" "SF,XF")])
3745
3746 (define_expand "extendsftf2"
3747 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3748 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3749 "TARGET_80387"
3750 {
3751 /* ??? Needed for compress_float_constant since all fp constants
3752 are LEGITIMATE_CONSTANT_P. */
3753 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3754 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3755 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3756 operands[1] = force_reg (SFmode, operands[1]);
3757 })
3758
3759 (define_insn "*extendsftf2_1"
3760 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3761 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3762 "TARGET_80387
3763 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3764 {
3765 switch (which_alternative)
3766 {
3767 case 0:
3768 if (REG_P (operands[1])
3769 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3770 return "fstp\t%y0";
3771 else if (STACK_TOP_P (operands[0]))
3772 return "fld%z1\t%y1";
3773 else
3774 return "fst\t%y0";
3775
3776 case 1:
3777 /* There is no non-popping store to memory for XFmode. So if
3778 we need one, follow the store with a load. */
3779 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3781 else
3782 return "fstp%z0\t%y0";
3783
3784 default:
3785 abort ();
3786 }
3787 }
3788 [(set_attr "type" "fmov")
3789 (set_attr "mode" "SF,XF")])
3790
3791 (define_expand "extenddfxf2"
3792 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3793 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3794 "!TARGET_64BIT && TARGET_80387"
3795 {
3796 /* ??? Needed for compress_float_constant since all fp constants
3797 are LEGITIMATE_CONSTANT_P. */
3798 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3799 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3800 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3801 operands[1] = force_reg (DFmode, operands[1]);
3802 })
3803
3804 (define_insn "*extenddfxf2_1"
3805 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3806 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3807 "!TARGET_64BIT && TARGET_80387
3808 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3809 {
3810 switch (which_alternative)
3811 {
3812 case 0:
3813 if (REG_P (operands[1])
3814 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3815 return "fstp\t%y0";
3816 else if (STACK_TOP_P (operands[0]))
3817 return "fld%z1\t%y1";
3818 else
3819 return "fst\t%y0";
3820
3821 case 1:
3822 /* There is no non-popping store to memory for XFmode. So if
3823 we need one, follow the store with a load. */
3824 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3825 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3826 else
3827 return "fstp%z0\t%y0";
3828
3829 default:
3830 abort ();
3831 }
3832 }
3833 [(set_attr "type" "fmov")
3834 (set_attr "mode" "DF,XF")])
3835
3836 (define_expand "extenddftf2"
3837 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3838 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3839 "TARGET_80387"
3840 {
3841 /* ??? Needed for compress_float_constant since all fp constants
3842 are LEGITIMATE_CONSTANT_P. */
3843 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3844 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3845 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3846 operands[1] = force_reg (DFmode, operands[1]);
3847 })
3848
3849 (define_insn "*extenddftf2_1"
3850 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3851 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3852 "TARGET_80387
3853 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3854 {
3855 switch (which_alternative)
3856 {
3857 case 0:
3858 if (REG_P (operands[1])
3859 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3860 return "fstp\t%y0";
3861 else if (STACK_TOP_P (operands[0]))
3862 return "fld%z1\t%y1";
3863 else
3864 return "fst\t%y0";
3865
3866 case 1:
3867 /* There is no non-popping store to memory for XFmode. So if
3868 we need one, follow the store with a load. */
3869 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3870 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3871 else
3872 return "fstp%z0\t%y0";
3873
3874 default:
3875 abort ();
3876 }
3877 }
3878 [(set_attr "type" "fmov")
3879 (set_attr "mode" "DF,XF")])
3880
3881 ;; %%% This seems bad bad news.
3882 ;; This cannot output into an f-reg because there is no way to be sure
3883 ;; of truncating in that case. Otherwise this is just like a simple move
3884 ;; insn. So we pretend we can output to a reg in order to get better
3885 ;; register preferencing, but we really use a stack slot.
3886
3887 (define_expand "truncdfsf2"
3888 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3889 (float_truncate:SF
3890 (match_operand:DF 1 "register_operand" "")))
3891 (clobber (match_dup 2))])]
3892 "TARGET_80387 || TARGET_SSE2"
3893 "
3894 if (TARGET_80387)
3895 operands[2] = assign_386_stack_local (SFmode, 0);
3896 else
3897 {
3898 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3899 DONE;
3900 }
3901 ")
3902
3903 (define_insn "*truncdfsf2_1"
3904 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3905 (float_truncate:SF
3906 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3907 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3908 "TARGET_80387 && !TARGET_SSE2"
3909 {
3910 switch (which_alternative)
3911 {
3912 case 0:
3913 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3914 return "fstp%z0\t%y0";
3915 else
3916 return "fst%z0\t%y0";
3917 default:
3918 abort ();
3919 }
3920 }
3921 [(set_attr "type" "fmov,multi,multi,multi")
3922 (set_attr "mode" "SF,SF,SF,SF")])
3923
3924 (define_insn "*truncdfsf2_1_sse"
3925 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3926 (float_truncate:SF
3927 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3928 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3929 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3930 {
3931 switch (which_alternative)
3932 {
3933 case 0:
3934 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3935 return "fstp%z0\t%y0";
3936 else
3937 return "fst%z0\t%y0";
3938 case 4:
3939 return "#";
3940 default:
3941 abort ();
3942 }
3943 }
3944 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3945 (set_attr "mode" "SF,SF,SF,SF,DF")])
3946
3947 (define_insn "*truncdfsf2_1_sse_nooverlap"
3948 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3949 (float_truncate:SF
3950 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3951 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3952 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3953 {
3954 switch (which_alternative)
3955 {
3956 case 0:
3957 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3958 return "fstp%z0\t%y0";
3959 else
3960 return "fst%z0\t%y0";
3961 case 4:
3962 return "#";
3963 default:
3964 abort ();
3965 }
3966 }
3967 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3968 (set_attr "mode" "SF,SF,SF,SF,DF")])
3969
3970 (define_insn "*truncdfsf2_2"
3971 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3972 (float_truncate:SF
3973 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3974 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3975 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3976 {
3977 switch (which_alternative)
3978 {
3979 case 0:
3980 case 1:
3981 return "cvtsd2ss\t{%1, %0|%0, %1}";
3982 case 2:
3983 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3984 return "fstp%z0\t%y0";
3985 else
3986 return "fst%z0\t%y0";
3987 default:
3988 abort ();
3989 }
3990 }
3991 [(set_attr "type" "ssecvt,ssecvt,fmov")
3992 (set_attr "athlon_decode" "vector,double,*")
3993 (set_attr "mode" "DF,DF,SF")])
3994
3995 (define_insn "*truncdfsf2_2_nooverlap"
3996 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3997 (float_truncate:SF
3998 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3999 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4000 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4001 {
4002 switch (which_alternative)
4003 {
4004 case 0:
4005 return "#";
4006 case 1:
4007 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008 return "fstp%z0\t%y0";
4009 else
4010 return "fst%z0\t%y0";
4011 default:
4012 abort ();
4013 }
4014 }
4015 [(set_attr "type" "ssecvt,fmov")
4016 (set_attr "mode" "DF,SF")])
4017
4018 (define_insn "*truncdfsf2_3"
4019 [(set (match_operand:SF 0 "memory_operand" "=m")
4020 (float_truncate:SF
4021 (match_operand:DF 1 "register_operand" "f")))]
4022 "TARGET_80387"
4023 {
4024 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4025 return "fstp%z0\t%y0";
4026 else
4027 return "fst%z0\t%y0";
4028 }
4029 [(set_attr "type" "fmov")
4030 (set_attr "mode" "SF")])
4031
4032 (define_insn "truncdfsf2_sse_only"
4033 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4034 (float_truncate:SF
4035 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4036 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4037 "cvtsd2ss\t{%1, %0|%0, %1}"
4038 [(set_attr "type" "ssecvt")
4039 (set_attr "athlon_decode" "vector,double")
4040 (set_attr "mode" "DF")])
4041
4042 (define_insn "*truncdfsf2_sse_only_nooverlap"
4043 [(set (match_operand:SF 0 "register_operand" "=&Y")
4044 (float_truncate:SF
4045 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4046 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4047 "#"
4048 [(set_attr "type" "ssecvt")
4049 (set_attr "mode" "DF")])
4050
4051 (define_split
4052 [(set (match_operand:SF 0 "memory_operand" "")
4053 (float_truncate:SF
4054 (match_operand:DF 1 "register_operand" "")))
4055 (clobber (match_operand:SF 2 "memory_operand" ""))]
4056 "TARGET_80387"
4057 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4058 "")
4059
4060 ; Avoid possible reformatting penalty on the destination by first
4061 ; zeroing it out
4062 (define_split
4063 [(set (match_operand:SF 0 "register_operand" "")
4064 (float_truncate:SF
4065 (match_operand:DF 1 "nonimmediate_operand" "")))
4066 (clobber (match_operand 2 "" ""))]
4067 "TARGET_80387 && reload_completed
4068 && SSE_REG_P (operands[0])
4069 && !STACK_REG_P (operands[1])"
4070 [(const_int 0)]
4071 {
4072 rtx src, dest;
4073 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4074 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4075 else
4076 {
4077 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4078 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4079 /* simplify_gen_subreg refuses to widen memory references. */
4080 if (GET_CODE (src) == SUBREG)
4081 alter_subreg (&src);
4082 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4083 abort ();
4084 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4085 emit_insn (gen_cvtsd2ss (dest, dest, src));
4086 }
4087 DONE;
4088 })
4089
4090 (define_split
4091 [(set (match_operand:SF 0 "register_operand" "")
4092 (float_truncate:SF
4093 (match_operand:DF 1 "nonimmediate_operand" "")))]
4094 "TARGET_80387 && reload_completed
4095 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4096 [(const_int 0)]
4097 {
4098 rtx src, dest;
4099 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4100 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4101 /* simplify_gen_subreg refuses to widen memory references. */
4102 if (GET_CODE (src) == SUBREG)
4103 alter_subreg (&src);
4104 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4105 abort ();
4106 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4107 emit_insn (gen_cvtsd2ss (dest, dest, src));
4108 DONE;
4109 })
4110
4111 (define_split
4112 [(set (match_operand:SF 0 "register_operand" "")
4113 (float_truncate:SF
4114 (match_operand:DF 1 "fp_register_operand" "")))
4115 (clobber (match_operand:SF 2 "memory_operand" ""))]
4116 "TARGET_80387 && reload_completed"
4117 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4118 (set (match_dup 0) (match_dup 2))]
4119 "")
4120
4121 (define_expand "truncxfsf2"
4122 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4123 (float_truncate:SF
4124 (match_operand:XF 1 "register_operand" "")))
4125 (clobber (match_dup 2))])]
4126 "!TARGET_64BIT && TARGET_80387"
4127 "operands[2] = assign_386_stack_local (SFmode, 0);")
4128
4129 (define_insn "*truncxfsf2_1"
4130 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4131 (float_truncate:SF
4132 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4133 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4134 "!TARGET_64BIT && TARGET_80387"
4135 {
4136 switch (which_alternative)
4137 {
4138 case 0:
4139 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4140 return "fstp%z0\t%y0";
4141 else
4142 return "fst%z0\t%y0";
4143 default:
4144 abort();
4145 }
4146 }
4147 [(set_attr "type" "fmov,multi,multi,multi")
4148 (set_attr "mode" "SF")])
4149
4150 (define_insn "*truncxfsf2_2"
4151 [(set (match_operand:SF 0 "memory_operand" "=m")
4152 (float_truncate:SF
4153 (match_operand:XF 1 "register_operand" "f")))]
4154 "!TARGET_64BIT && TARGET_80387"
4155 {
4156 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4157 return "fstp%z0\t%y0";
4158 else
4159 return "fst%z0\t%y0";
4160 }
4161 [(set_attr "type" "fmov")
4162 (set_attr "mode" "SF")])
4163
4164 (define_split
4165 [(set (match_operand:SF 0 "memory_operand" "")
4166 (float_truncate:SF
4167 (match_operand:XF 1 "register_operand" "")))
4168 (clobber (match_operand:SF 2 "memory_operand" ""))]
4169 "TARGET_80387"
4170 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4171 "")
4172
4173 (define_split
4174 [(set (match_operand:SF 0 "register_operand" "")
4175 (float_truncate:SF
4176 (match_operand:XF 1 "register_operand" "")))
4177 (clobber (match_operand:SF 2 "memory_operand" ""))]
4178 "TARGET_80387 && reload_completed"
4179 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4180 (set (match_dup 0) (match_dup 2))]
4181 "")
4182
4183 (define_expand "trunctfsf2"
4184 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4185 (float_truncate:SF
4186 (match_operand:TF 1 "register_operand" "")))
4187 (clobber (match_dup 2))])]
4188 "TARGET_80387"
4189 "operands[2] = assign_386_stack_local (SFmode, 0);")
4190
4191 (define_insn "*trunctfsf2_1"
4192 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4193 (float_truncate:SF
4194 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4195 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4196 "TARGET_80387"
4197 {
4198 switch (which_alternative)
4199 {
4200 case 0:
4201 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4202 return "fstp%z0\t%y0";
4203 else
4204 return "fst%z0\t%y0";
4205 default:
4206 abort();
4207 }
4208 }
4209 [(set_attr "type" "fmov,multi,multi,multi")
4210 (set_attr "mode" "SF")])
4211
4212 (define_insn "*trunctfsf2_2"
4213 [(set (match_operand:SF 0 "memory_operand" "=m")
4214 (float_truncate:SF
4215 (match_operand:TF 1 "register_operand" "f")))]
4216 "TARGET_80387"
4217 {
4218 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4219 return "fstp%z0\t%y0";
4220 else
4221 return "fst%z0\t%y0";
4222 }
4223 [(set_attr "type" "fmov")
4224 (set_attr "mode" "SF")])
4225
4226 (define_split
4227 [(set (match_operand:SF 0 "memory_operand" "")
4228 (float_truncate:SF
4229 (match_operand:TF 1 "register_operand" "")))
4230 (clobber (match_operand:SF 2 "memory_operand" ""))]
4231 "TARGET_80387"
4232 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4233 "")
4234
4235 (define_split
4236 [(set (match_operand:SF 0 "register_operand" "")
4237 (float_truncate:SF
4238 (match_operand:TF 1 "register_operand" "")))
4239 (clobber (match_operand:SF 2 "memory_operand" ""))]
4240 "TARGET_80387 && reload_completed"
4241 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4242 (set (match_dup 0) (match_dup 2))]
4243 "")
4244
4245
4246 (define_expand "truncxfdf2"
4247 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4248 (float_truncate:DF
4249 (match_operand:XF 1 "register_operand" "")))
4250 (clobber (match_dup 2))])]
4251 "!TARGET_64BIT && TARGET_80387"
4252 "operands[2] = assign_386_stack_local (DFmode, 0);")
4253
4254 (define_insn "*truncxfdf2_1"
4255 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4256 (float_truncate:DF
4257 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4258 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4259 "!TARGET_64BIT && TARGET_80387"
4260 {
4261 switch (which_alternative)
4262 {
4263 case 0:
4264 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4265 return "fstp%z0\t%y0";
4266 else
4267 return "fst%z0\t%y0";
4268 default:
4269 abort();
4270 }
4271 abort ();
4272 }
4273 [(set_attr "type" "fmov,multi,multi,multi")
4274 (set_attr "mode" "DF")])
4275
4276 (define_insn "*truncxfdf2_2"
4277 [(set (match_operand:DF 0 "memory_operand" "=m")
4278 (float_truncate:DF
4279 (match_operand:XF 1 "register_operand" "f")))]
4280 "!TARGET_64BIT && TARGET_80387"
4281 {
4282 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4283 return "fstp%z0\t%y0";
4284 else
4285 return "fst%z0\t%y0";
4286 }
4287 [(set_attr "type" "fmov")
4288 (set_attr "mode" "DF")])
4289
4290 (define_split
4291 [(set (match_operand:DF 0 "memory_operand" "")
4292 (float_truncate:DF
4293 (match_operand:XF 1 "register_operand" "")))
4294 (clobber (match_operand:DF 2 "memory_operand" ""))]
4295 "TARGET_80387"
4296 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4297 "")
4298
4299 (define_split
4300 [(set (match_operand:DF 0 "register_operand" "")
4301 (float_truncate:DF
4302 (match_operand:XF 1 "register_operand" "")))
4303 (clobber (match_operand:DF 2 "memory_operand" ""))]
4304 "TARGET_80387 && reload_completed"
4305 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4306 (set (match_dup 0) (match_dup 2))]
4307 "")
4308
4309 (define_expand "trunctfdf2"
4310 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4311 (float_truncate:DF
4312 (match_operand:TF 1 "register_operand" "")))
4313 (clobber (match_dup 2))])]
4314 "TARGET_80387"
4315 "operands[2] = assign_386_stack_local (DFmode, 0);")
4316
4317 (define_insn "*trunctfdf2_1"
4318 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4319 (float_truncate:DF
4320 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4321 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4322 "TARGET_80387"
4323 {
4324 switch (which_alternative)
4325 {
4326 case 0:
4327 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4328 return "fstp%z0\t%y0";
4329 else
4330 return "fst%z0\t%y0";
4331 default:
4332 abort();
4333 }
4334 abort ();
4335 }
4336 [(set_attr "type" "fmov,multi,multi,multi")
4337 (set_attr "mode" "DF")])
4338
4339 (define_insn "*trunctfdf2_2"
4340 [(set (match_operand:DF 0 "memory_operand" "=m")
4341 (float_truncate:DF
4342 (match_operand:TF 1 "register_operand" "f")))]
4343 "TARGET_80387"
4344 {
4345 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4346 return "fstp%z0\t%y0";
4347 else
4348 return "fst%z0\t%y0";
4349 }
4350 [(set_attr "type" "fmov")
4351 (set_attr "mode" "DF")])
4352
4353 (define_split
4354 [(set (match_operand:DF 0 "memory_operand" "")
4355 (float_truncate:DF
4356 (match_operand:TF 1 "register_operand" "")))
4357 (clobber (match_operand:DF 2 "memory_operand" ""))]
4358 "TARGET_80387"
4359 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4360 "")
4361
4362 (define_split
4363 [(set (match_operand:DF 0 "register_operand" "")
4364 (float_truncate:DF
4365 (match_operand:TF 1 "register_operand" "")))
4366 (clobber (match_operand:DF 2 "memory_operand" ""))]
4367 "TARGET_80387 && reload_completed"
4368 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4369 (set (match_dup 0) (match_dup 2))]
4370 "")
4371
4372 \f
4373 ;; %%% Break up all these bad boys.
4374
4375 ;; Signed conversion to DImode.
4376
4377 (define_expand "fix_truncxfdi2"
4378 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4379 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4380 "!TARGET_64BIT && TARGET_80387"
4381 "")
4382
4383 (define_expand "fix_trunctfdi2"
4384 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4385 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4386 "TARGET_80387"
4387 "")
4388
4389 (define_expand "fix_truncdfdi2"
4390 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4391 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4392 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4393 {
4394 if (TARGET_64BIT && TARGET_SSE2)
4395 {
4396 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4397 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4398 if (out != operands[0])
4399 emit_move_insn (operands[0], out);
4400 DONE;
4401 }
4402 })
4403
4404 (define_expand "fix_truncsfdi2"
4405 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4406 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4407 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4408 {
4409 if (TARGET_SSE && TARGET_64BIT)
4410 {
4411 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4412 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4413 if (out != operands[0])
4414 emit_move_insn (operands[0], out);
4415 DONE;
4416 }
4417 })
4418
4419 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4420 ;; of the machinery.
4421 (define_insn_and_split "*fix_truncdi_1"
4422 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4423 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4424 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4425 && !reload_completed && !reload_in_progress
4426 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4427 "#"
4428 "&& 1"
4429 [(const_int 0)]
4430 {
4431 ix86_optimize_mode_switching = 1;
4432 operands[2] = assign_386_stack_local (HImode, 1);
4433 operands[3] = assign_386_stack_local (HImode, 2);
4434 if (memory_operand (operands[0], VOIDmode))
4435 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4436 operands[2], operands[3]));
4437 else
4438 {
4439 operands[4] = assign_386_stack_local (DImode, 0);
4440 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4441 operands[2], operands[3],
4442 operands[4]));
4443 }
4444 DONE;
4445 }
4446 [(set_attr "type" "fistp")])
4447
4448 (define_insn "fix_truncdi_nomemory"
4449 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4450 (fix:DI (match_operand 1 "register_operand" "f,f")))
4451 (use (match_operand:HI 2 "memory_operand" "m,m"))
4452 (use (match_operand:HI 3 "memory_operand" "m,m"))
4453 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4454 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4455 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4456 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4457 "#"
4458 [(set_attr "type" "fistp")])
4459
4460 (define_insn "fix_truncdi_memory"
4461 [(set (match_operand:DI 0 "memory_operand" "=m")
4462 (fix:DI (match_operand 1 "register_operand" "f")))
4463 (use (match_operand:HI 2 "memory_operand" "m"))
4464 (use (match_operand:HI 3 "memory_operand" "m"))
4465 (clobber (match_scratch:DF 4 "=&1f"))]
4466 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4467 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4468 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4469 [(set_attr "type" "fistp")])
4470
4471 (define_split
4472 [(set (match_operand:DI 0 "register_operand" "")
4473 (fix:DI (match_operand 1 "register_operand" "")))
4474 (use (match_operand:HI 2 "memory_operand" ""))
4475 (use (match_operand:HI 3 "memory_operand" ""))
4476 (clobber (match_operand:DI 4 "memory_operand" ""))
4477 (clobber (match_scratch 5 ""))]
4478 "reload_completed"
4479 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4480 (use (match_dup 2))
4481 (use (match_dup 3))
4482 (clobber (match_dup 5))])
4483 (set (match_dup 0) (match_dup 4))]
4484 "")
4485
4486 (define_split
4487 [(set (match_operand:DI 0 "memory_operand" "")
4488 (fix:DI (match_operand 1 "register_operand" "")))
4489 (use (match_operand:HI 2 "memory_operand" ""))
4490 (use (match_operand:HI 3 "memory_operand" ""))
4491 (clobber (match_operand:DI 4 "memory_operand" ""))
4492 (clobber (match_scratch 5 ""))]
4493 "reload_completed"
4494 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4495 (use (match_dup 2))
4496 (use (match_dup 3))
4497 (clobber (match_dup 5))])]
4498 "")
4499
4500 ;; When SSE available, it is always faster to use it!
4501 (define_insn "fix_truncsfdi_sse"
4502 [(set (match_operand:DI 0 "register_operand" "=r,r")
4503 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4504 "TARGET_64BIT && TARGET_SSE"
4505 "cvttss2si{q}\t{%1, %0|%0, %1}"
4506 [(set_attr "type" "sseicvt")
4507 (set_attr "athlon_decode" "double,vector")])
4508
4509 ;; Avoid vector decoded form of the instruction.
4510 (define_peephole2
4511 [(match_scratch:SF 2 "x")
4512 (set (match_operand:DI 0 "register_operand" "")
4513 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "")))]
4514 "TARGET_K8 && !optimize_size"
4515 [(set (match_dup 2) (match_dup 1))
4516 (set (match_dup 0) (fix:DI (match_dup 2)))]
4517 "")
4518
4519 (define_insn "fix_truncdfdi_sse"
4520 [(set (match_operand:DI 0 "register_operand" "=r,r")
4521 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4522 "TARGET_64BIT && TARGET_SSE2"
4523 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4524 [(set_attr "type" "sseicvt,sseicvt")
4525 (set_attr "athlon_decode" "double,vector")])
4526
4527 ;; Avoid vector decoded form of the instruction.
4528 (define_peephole2
4529 [(match_scratch:DF 2 "Y")
4530 (set (match_operand:DI 0 "register_operand" "")
4531 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "")))]
4532 "TARGET_K8 && !optimize_size"
4533 [(set (match_dup 2) (match_dup 1))
4534 (set (match_dup 0) (fix:DI (match_dup 2)))]
4535 "")
4536
4537 ;; Signed conversion to SImode.
4538
4539 (define_expand "fix_truncxfsi2"
4540 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4541 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4542 "!TARGET_64BIT && TARGET_80387"
4543 "")
4544
4545 (define_expand "fix_trunctfsi2"
4546 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4547 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4548 "TARGET_80387"
4549 "")
4550
4551 (define_expand "fix_truncdfsi2"
4552 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4553 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4554 "TARGET_80387 || TARGET_SSE2"
4555 {
4556 if (TARGET_SSE2)
4557 {
4558 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4559 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4560 if (out != operands[0])
4561 emit_move_insn (operands[0], out);
4562 DONE;
4563 }
4564 })
4565
4566 (define_expand "fix_truncsfsi2"
4567 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4568 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4569 "TARGET_80387 || TARGET_SSE"
4570 {
4571 if (TARGET_SSE)
4572 {
4573 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4574 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4575 if (out != operands[0])
4576 emit_move_insn (operands[0], out);
4577 DONE;
4578 }
4579 })
4580
4581 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4582 ;; of the machinery.
4583 (define_insn_and_split "*fix_truncsi_1"
4584 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4585 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4586 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4587 && !reload_completed && !reload_in_progress
4588 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4589 "#"
4590 "&& 1"
4591 [(const_int 0)]
4592 {
4593 ix86_optimize_mode_switching = 1;
4594 operands[2] = assign_386_stack_local (HImode, 1);
4595 operands[3] = assign_386_stack_local (HImode, 2);
4596 if (memory_operand (operands[0], VOIDmode))
4597 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4598 operands[2], operands[3]));
4599 else
4600 {
4601 operands[4] = assign_386_stack_local (SImode, 0);
4602 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4603 operands[2], operands[3],
4604 operands[4]));
4605 }
4606 DONE;
4607 }
4608 [(set_attr "type" "fistp")])
4609
4610 (define_insn "fix_truncsi_nomemory"
4611 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4612 (fix:SI (match_operand 1 "register_operand" "f,f")))
4613 (use (match_operand:HI 2 "memory_operand" "m,m"))
4614 (use (match_operand:HI 3 "memory_operand" "m,m"))
4615 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4616 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4617 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4618 "#"
4619 [(set_attr "type" "fistp")])
4620
4621 (define_insn "fix_truncsi_memory"
4622 [(set (match_operand:SI 0 "memory_operand" "=m")
4623 (fix:SI (match_operand 1 "register_operand" "f")))
4624 (use (match_operand:HI 2 "memory_operand" "m"))
4625 (use (match_operand:HI 3 "memory_operand" "m"))]
4626 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4627 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4628 "* return output_fix_trunc (insn, operands);"
4629 [(set_attr "type" "fistp")])
4630
4631 ;; When SSE available, it is always faster to use it!
4632 (define_insn "fix_truncsfsi_sse"
4633 [(set (match_operand:SI 0 "register_operand" "=r,r")
4634 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4635 "TARGET_SSE"
4636 "cvttss2si\t{%1, %0|%0, %1}"
4637 [(set_attr "type" "sseicvt")
4638 (set_attr "athlon_decode" "double,vector")])
4639
4640 ;; Avoid vector decoded form of the instruction.
4641 (define_peephole2
4642 [(match_scratch:SF 2 "x")
4643 (set (match_operand:SI 0 "register_operand" "")
4644 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
4645 "TARGET_K8 && !optimize_size"
4646 [(set (match_dup 2) (match_dup 1))
4647 (set (match_dup 0) (fix:SI (match_dup 2)))]
4648 "")
4649
4650 (define_insn "fix_truncdfsi_sse"
4651 [(set (match_operand:SI 0 "register_operand" "=r,r")
4652 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4653 "TARGET_SSE2"
4654 "cvttsd2si\t{%1, %0|%0, %1}"
4655 [(set_attr "type" "sseicvt")
4656 (set_attr "athlon_decode" "double,vector")])
4657
4658 ;; Avoid vector decoded form of the instruction.
4659 (define_peephole2
4660 [(match_scratch:DF 2 "Y")
4661 (set (match_operand:SI 0 "register_operand" "")
4662 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
4663 "TARGET_K8 && !optimize_size"
4664 [(set (match_dup 2) (match_dup 1))
4665 (set (match_dup 0) (fix:SI (match_dup 2)))]
4666 "")
4667
4668 (define_split
4669 [(set (match_operand:SI 0 "register_operand" "")
4670 (fix:SI (match_operand 1 "register_operand" "")))
4671 (use (match_operand:HI 2 "memory_operand" ""))
4672 (use (match_operand:HI 3 "memory_operand" ""))
4673 (clobber (match_operand:SI 4 "memory_operand" ""))]
4674 "reload_completed"
4675 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4676 (use (match_dup 2))
4677 (use (match_dup 3))])
4678 (set (match_dup 0) (match_dup 4))]
4679 "")
4680
4681 (define_split
4682 [(set (match_operand:SI 0 "memory_operand" "")
4683 (fix:SI (match_operand 1 "register_operand" "")))
4684 (use (match_operand:HI 2 "memory_operand" ""))
4685 (use (match_operand:HI 3 "memory_operand" ""))
4686 (clobber (match_operand:SI 4 "memory_operand" ""))]
4687 "reload_completed"
4688 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4689 (use (match_dup 2))
4690 (use (match_dup 3))])]
4691 "")
4692
4693 ;; Signed conversion to HImode.
4694
4695 (define_expand "fix_truncxfhi2"
4696 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4697 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4698 "!TARGET_64BIT && TARGET_80387"
4699 "")
4700
4701 (define_expand "fix_trunctfhi2"
4702 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4703 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4704 "TARGET_80387"
4705 "")
4706
4707 (define_expand "fix_truncdfhi2"
4708 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4709 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4710 "TARGET_80387 && !TARGET_SSE2"
4711 "")
4712
4713 (define_expand "fix_truncsfhi2"
4714 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4715 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4716 "TARGET_80387 && !TARGET_SSE"
4717 "")
4718
4719 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4720 ;; of the machinery.
4721 (define_insn_and_split "*fix_trunchi_1"
4722 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4723 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4724 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4725 && !reload_completed && !reload_in_progress
4726 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4727 "#"
4728 ""
4729 [(const_int 0)]
4730 {
4731 ix86_optimize_mode_switching = 1;
4732 operands[2] = assign_386_stack_local (HImode, 1);
4733 operands[3] = assign_386_stack_local (HImode, 2);
4734 if (memory_operand (operands[0], VOIDmode))
4735 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4736 operands[2], operands[3]));
4737 else
4738 {
4739 operands[4] = assign_386_stack_local (HImode, 0);
4740 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4741 operands[2], operands[3],
4742 operands[4]));
4743 }
4744 DONE;
4745 }
4746 [(set_attr "type" "fistp")])
4747
4748 (define_insn "fix_trunchi_nomemory"
4749 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4750 (fix:HI (match_operand 1 "register_operand" "f,f")))
4751 (use (match_operand:HI 2 "memory_operand" "m,m"))
4752 (use (match_operand:HI 3 "memory_operand" "m,m"))
4753 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4754 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4755 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4756 "#"
4757 [(set_attr "type" "fistp")])
4758
4759 (define_insn "fix_trunchi_memory"
4760 [(set (match_operand:HI 0 "memory_operand" "=m")
4761 (fix:HI (match_operand 1 "register_operand" "f")))
4762 (use (match_operand:HI 2 "memory_operand" "m"))
4763 (use (match_operand:HI 3 "memory_operand" "m"))]
4764 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4765 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4766 "* return output_fix_trunc (insn, operands);"
4767 [(set_attr "type" "fistp")])
4768
4769 (define_split
4770 [(set (match_operand:HI 0 "memory_operand" "")
4771 (fix:HI (match_operand 1 "register_operand" "")))
4772 (use (match_operand:HI 2 "memory_operand" ""))
4773 (use (match_operand:HI 3 "memory_operand" ""))
4774 (clobber (match_operand:HI 4 "memory_operand" ""))]
4775 "reload_completed"
4776 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4777 (use (match_dup 2))
4778 (use (match_dup 3))])]
4779 "")
4780
4781 (define_split
4782 [(set (match_operand:HI 0 "register_operand" "")
4783 (fix:HI (match_operand 1 "register_operand" "")))
4784 (use (match_operand:HI 2 "memory_operand" ""))
4785 (use (match_operand:HI 3 "memory_operand" ""))
4786 (clobber (match_operand:HI 4 "memory_operand" ""))]
4787 "reload_completed"
4788 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4789 (use (match_dup 2))
4790 (use (match_dup 3))
4791 (clobber (match_dup 4))])
4792 (set (match_dup 0) (match_dup 4))]
4793 "")
4794
4795 ;; %% Not used yet.
4796 (define_insn "x86_fnstcw_1"
4797 [(set (match_operand:HI 0 "memory_operand" "=m")
4798 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4799 "TARGET_80387"
4800 "fnstcw\t%0"
4801 [(set_attr "length" "2")
4802 (set_attr "mode" "HI")
4803 (set_attr "unit" "i387")
4804 (set_attr "ppro_uops" "few")])
4805
4806 (define_insn "x86_fldcw_1"
4807 [(set (reg:HI 18)
4808 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4809 "TARGET_80387"
4810 "fldcw\t%0"
4811 [(set_attr "length" "2")
4812 (set_attr "mode" "HI")
4813 (set_attr "unit" "i387")
4814 (set_attr "athlon_decode" "vector")
4815 (set_attr "ppro_uops" "few")])
4816 \f
4817 ;; Conversion between fixed point and floating point.
4818
4819 ;; Even though we only accept memory inputs, the backend _really_
4820 ;; wants to be able to do this between registers.
4821
4822 (define_expand "floathisf2"
4823 [(set (match_operand:SF 0 "register_operand" "")
4824 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4825 "TARGET_SSE || TARGET_80387"
4826 {
4827 if (TARGET_SSE && TARGET_SSE_MATH)
4828 {
4829 emit_insn (gen_floatsisf2 (operands[0],
4830 convert_to_mode (SImode, operands[1], 0)));
4831 DONE;
4832 }
4833 })
4834
4835 (define_insn "*floathisf2_1"
4836 [(set (match_operand:SF 0 "register_operand" "=f,f")
4837 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4838 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4839 "@
4840 fild%z1\t%1
4841 #"
4842 [(set_attr "type" "fmov,multi")
4843 (set_attr "mode" "SF")
4844 (set_attr "fp_int_src" "true")])
4845
4846 (define_expand "floatsisf2"
4847 [(set (match_operand:SF 0 "register_operand" "")
4848 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4849 "TARGET_SSE || TARGET_80387"
4850 "")
4851
4852 (define_insn "*floatsisf2_i387"
4853 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4854 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4855 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4856 "@
4857 fild%z1\t%1
4858 #
4859 cvtsi2ss\t{%1, %0|%0, %1}
4860 cvtsi2ss\t{%1, %0|%0, %1}"
4861 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4862 (set_attr "mode" "SF")
4863 (set_attr "athlon_decode" "*,*,vector,double")
4864 (set_attr "fp_int_src" "true")])
4865
4866 (define_insn "*floatsisf2_sse"
4867 [(set (match_operand:SF 0 "register_operand" "=x,x")
4868 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4869 "TARGET_SSE"
4870 "cvtsi2ss\t{%1, %0|%0, %1}"
4871 [(set_attr "type" "sseicvt")
4872 (set_attr "mode" "SF")
4873 (set_attr "athlon_decode" "vector,double")
4874 (set_attr "fp_int_src" "true")])
4875
4876 ; Avoid possible reformatting penalty on the destination by first
4877 ; zeroing it out
4878 (define_split
4879 [(set (match_operand:SF 0 "register_operand" "")
4880 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4881 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4882 && SSE_REG_P (operands[0])"
4883 [(const_int 0)]
4884 {
4885 rtx dest;
4886 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4887 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4888 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4889 DONE;
4890 })
4891
4892 (define_expand "floatdisf2"
4893 [(set (match_operand:SF 0 "register_operand" "")
4894 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4895 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4896 "")
4897
4898 (define_insn "*floatdisf2_i387_only"
4899 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4900 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4901 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4902 "@
4903 fild%z1\t%1
4904 #"
4905 [(set_attr "type" "fmov,multi")
4906 (set_attr "mode" "SF")
4907 (set_attr "fp_int_src" "true")])
4908
4909 (define_insn "*floatdisf2_i387"
4910 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4911 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4912 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4913 "@
4914 fild%z1\t%1
4915 #
4916 cvtsi2ss{q}\t{%1, %0|%0, %1}
4917 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4918 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4919 (set_attr "mode" "SF")
4920 (set_attr "athlon_decode" "*,*,vector,double")
4921 (set_attr "fp_int_src" "true")])
4922
4923 (define_insn "*floatdisf2_sse"
4924 [(set (match_operand:SF 0 "register_operand" "=x,x")
4925 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4926 "TARGET_64BIT && TARGET_SSE"
4927 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4928 [(set_attr "type" "sseicvt")
4929 (set_attr "mode" "SF")
4930 (set_attr "athlon_decode" "vector,double")
4931 (set_attr "fp_int_src" "true")])
4932
4933 ; Avoid possible reformatting penalty on the destination by first
4934 ; zeroing it out
4935 (define_split
4936 [(set (match_operand:SF 0 "register_operand" "")
4937 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4938 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4939 && SSE_REG_P (operands[0])"
4940 [(const_int 0)]
4941 {
4942 rtx dest;
4943 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4944 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4945 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4946 DONE;
4947 })
4948
4949 (define_expand "floathidf2"
4950 [(set (match_operand:DF 0 "register_operand" "")
4951 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4952 "TARGET_SSE2 || TARGET_80387"
4953 {
4954 if (TARGET_SSE && TARGET_SSE_MATH)
4955 {
4956 emit_insn (gen_floatsidf2 (operands[0],
4957 convert_to_mode (SImode, operands[1], 0)));
4958 DONE;
4959 }
4960 })
4961
4962 (define_insn "*floathidf2_1"
4963 [(set (match_operand:DF 0 "register_operand" "=f,f")
4964 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4965 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4966 "@
4967 fild%z1\t%1
4968 #"
4969 [(set_attr "type" "fmov,multi")
4970 (set_attr "mode" "DF")
4971 (set_attr "fp_int_src" "true")])
4972
4973 (define_expand "floatsidf2"
4974 [(set (match_operand:DF 0 "register_operand" "")
4975 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4976 "TARGET_80387 || TARGET_SSE2"
4977 "")
4978
4979 (define_insn "*floatsidf2_i387"
4980 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4981 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4982 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4983 "@
4984 fild%z1\t%1
4985 #
4986 cvtsi2sd\t{%1, %0|%0, %1}
4987 cvtsi2sd\t{%1, %0|%0, %1}"
4988 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4989 (set_attr "mode" "DF")
4990 (set_attr "athlon_decode" "*,*,double,direct")
4991 (set_attr "fp_int_src" "true")])
4992
4993 (define_insn "*floatsidf2_sse"
4994 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4995 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4996 "TARGET_SSE2"
4997 "cvtsi2sd\t{%1, %0|%0, %1}"
4998 [(set_attr "type" "sseicvt")
4999 (set_attr "mode" "DF")
5000 (set_attr "athlon_decode" "double,direct")
5001 (set_attr "fp_int_src" "true")])
5002
5003 (define_expand "floatdidf2"
5004 [(set (match_operand:DF 0 "register_operand" "")
5005 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5006 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5007 "")
5008
5009 (define_insn "*floatdidf2_i387_only"
5010 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5011 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5012 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5013 "@
5014 fild%z1\t%1
5015 #"
5016 [(set_attr "type" "fmov,multi")
5017 (set_attr "mode" "DF")
5018 (set_attr "fp_int_src" "true")])
5019
5020 (define_insn "*floatdidf2_i387"
5021 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5022 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5023 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5024 "@
5025 fild%z1\t%1
5026 #
5027 cvtsi2sd{q}\t{%1, %0|%0, %1}
5028 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5029 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5030 (set_attr "mode" "DF")
5031 (set_attr "athlon_decode" "*,*,double,direct")
5032 (set_attr "fp_int_src" "true")])
5033
5034 (define_insn "*floatdidf2_sse"
5035 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5036 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5037 "TARGET_SSE2"
5038 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5039 [(set_attr "type" "sseicvt")
5040 (set_attr "mode" "DF")
5041 (set_attr "athlon_decode" "double,direct")
5042 (set_attr "fp_int_src" "true")])
5043
5044 (define_insn "floathixf2"
5045 [(set (match_operand:XF 0 "register_operand" "=f,f")
5046 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5047 "!TARGET_64BIT && TARGET_80387"
5048 "@
5049 fild%z1\t%1
5050 #"
5051 [(set_attr "type" "fmov,multi")
5052 (set_attr "mode" "XF")
5053 (set_attr "fp_int_src" "true")])
5054
5055 (define_insn "floathitf2"
5056 [(set (match_operand:TF 0 "register_operand" "=f,f")
5057 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5058 "TARGET_80387"
5059 "@
5060 fild%z1\t%1
5061 #"
5062 [(set_attr "type" "fmov,multi")
5063 (set_attr "mode" "XF")
5064 (set_attr "fp_int_src" "true")])
5065
5066 (define_insn "floatsixf2"
5067 [(set (match_operand:XF 0 "register_operand" "=f,f")
5068 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5069 "!TARGET_64BIT && TARGET_80387"
5070 "@
5071 fild%z1\t%1
5072 #"
5073 [(set_attr "type" "fmov,multi")
5074 (set_attr "mode" "XF")
5075 (set_attr "fp_int_src" "true")])
5076
5077 (define_insn "floatsitf2"
5078 [(set (match_operand:TF 0 "register_operand" "=f,f")
5079 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5080 "TARGET_80387"
5081 "@
5082 fild%z1\t%1
5083 #"
5084 [(set_attr "type" "fmov,multi")
5085 (set_attr "mode" "XF")
5086 (set_attr "fp_int_src" "true")])
5087
5088 (define_insn "floatdixf2"
5089 [(set (match_operand:XF 0 "register_operand" "=f,f")
5090 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5091 "!TARGET_64BIT && TARGET_80387"
5092 "@
5093 fild%z1\t%1
5094 #"
5095 [(set_attr "type" "fmov,multi")
5096 (set_attr "mode" "XF")
5097 (set_attr "fp_int_src" "true")])
5098
5099 (define_insn "floatditf2"
5100 [(set (match_operand:TF 0 "register_operand" "=f,f")
5101 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5102 "TARGET_80387"
5103 "@
5104 fild%z1\t%1
5105 #"
5106 [(set_attr "type" "fmov,multi")
5107 (set_attr "mode" "XF")
5108 (set_attr "fp_int_src" "true")])
5109
5110 ;; %%% Kill these when reload knows how to do it.
5111 (define_split
5112 [(set (match_operand 0 "fp_register_operand" "")
5113 (float (match_operand 1 "register_operand" "")))]
5114 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5115 [(const_int 0)]
5116 {
5117 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5118 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5119 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5120 ix86_free_from_memory (GET_MODE (operands[1]));
5121 DONE;
5122 })
5123
5124 (define_expand "floatunssisf2"
5125 [(use (match_operand:SF 0 "register_operand" ""))
5126 (use (match_operand:SI 1 "register_operand" ""))]
5127 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5128 "x86_emit_floatuns (operands); DONE;")
5129
5130 (define_expand "floatunsdisf2"
5131 [(use (match_operand:SF 0 "register_operand" ""))
5132 (use (match_operand:DI 1 "register_operand" ""))]
5133 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5134 "x86_emit_floatuns (operands); DONE;")
5135
5136 (define_expand "floatunsdidf2"
5137 [(use (match_operand:DF 0 "register_operand" ""))
5138 (use (match_operand:DI 1 "register_operand" ""))]
5139 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5140 "x86_emit_floatuns (operands); DONE;")
5141 \f
5142 ;; Add instructions
5143
5144 ;; %%% splits for addsidi3
5145 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5146 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5147 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5148
5149 (define_expand "adddi3"
5150 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5151 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5152 (match_operand:DI 2 "x86_64_general_operand" "")))
5153 (clobber (reg:CC 17))]
5154 ""
5155 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5156
5157 (define_insn "*adddi3_1"
5158 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5159 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5160 (match_operand:DI 2 "general_operand" "roiF,riF")))
5161 (clobber (reg:CC 17))]
5162 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5163 "#")
5164
5165 (define_split
5166 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5167 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5168 (match_operand:DI 2 "general_operand" "")))
5169 (clobber (reg:CC 17))]
5170 "!TARGET_64BIT && reload_completed"
5171 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5172 UNSPEC_ADD_CARRY))
5173 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5174 (parallel [(set (match_dup 3)
5175 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5176 (match_dup 4))
5177 (match_dup 5)))
5178 (clobber (reg:CC 17))])]
5179 "split_di (operands+0, 1, operands+0, operands+3);
5180 split_di (operands+1, 1, operands+1, operands+4);
5181 split_di (operands+2, 1, operands+2, operands+5);")
5182
5183 (define_insn "adddi3_carry_rex64"
5184 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5185 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5186 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5187 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5188 (clobber (reg:CC 17))]
5189 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5190 "adc{q}\t{%2, %0|%0, %2}"
5191 [(set_attr "type" "alu")
5192 (set_attr "pent_pair" "pu")
5193 (set_attr "mode" "DI")
5194 (set_attr "ppro_uops" "few")])
5195
5196 (define_insn "*adddi3_cc_rex64"
5197 [(set (reg:CC 17)
5198 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5199 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5200 UNSPEC_ADD_CARRY))
5201 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5202 (plus:DI (match_dup 1) (match_dup 2)))]
5203 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5204 "add{q}\t{%2, %0|%0, %2}"
5205 [(set_attr "type" "alu")
5206 (set_attr "mode" "DI")])
5207
5208 (define_insn "addqi3_carry"
5209 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5210 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5211 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5212 (match_operand:QI 2 "general_operand" "ri,rm")))
5213 (clobber (reg:CC 17))]
5214 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5215 "adc{b}\t{%2, %0|%0, %2}"
5216 [(set_attr "type" "alu")
5217 (set_attr "pent_pair" "pu")
5218 (set_attr "mode" "QI")
5219 (set_attr "ppro_uops" "few")])
5220
5221 (define_insn "addhi3_carry"
5222 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5223 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5224 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5225 (match_operand:HI 2 "general_operand" "ri,rm")))
5226 (clobber (reg:CC 17))]
5227 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5228 "adc{w}\t{%2, %0|%0, %2}"
5229 [(set_attr "type" "alu")
5230 (set_attr "pent_pair" "pu")
5231 (set_attr "mode" "HI")
5232 (set_attr "ppro_uops" "few")])
5233
5234 (define_insn "addsi3_carry"
5235 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5236 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5237 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5238 (match_operand:SI 2 "general_operand" "ri,rm")))
5239 (clobber (reg:CC 17))]
5240 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5241 "adc{l}\t{%2, %0|%0, %2}"
5242 [(set_attr "type" "alu")
5243 (set_attr "pent_pair" "pu")
5244 (set_attr "mode" "SI")
5245 (set_attr "ppro_uops" "few")])
5246
5247 (define_insn "*addsi3_carry_zext"
5248 [(set (match_operand:DI 0 "register_operand" "=r")
5249 (zero_extend:DI
5250 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5251 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5252 (match_operand:SI 2 "general_operand" "rim"))))
5253 (clobber (reg:CC 17))]
5254 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5255 "adc{l}\t{%2, %k0|%k0, %2}"
5256 [(set_attr "type" "alu")
5257 (set_attr "pent_pair" "pu")
5258 (set_attr "mode" "SI")
5259 (set_attr "ppro_uops" "few")])
5260
5261 (define_insn "*addsi3_cc"
5262 [(set (reg:CC 17)
5263 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5264 (match_operand:SI 2 "general_operand" "ri,rm")]
5265 UNSPEC_ADD_CARRY))
5266 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5267 (plus:SI (match_dup 1) (match_dup 2)))]
5268 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5269 "add{l}\t{%2, %0|%0, %2}"
5270 [(set_attr "type" "alu")
5271 (set_attr "mode" "SI")])
5272
5273 (define_insn "addqi3_cc"
5274 [(set (reg:CC 17)
5275 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5276 (match_operand:QI 2 "general_operand" "qi,qm")]
5277 UNSPEC_ADD_CARRY))
5278 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5279 (plus:QI (match_dup 1) (match_dup 2)))]
5280 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5281 "add{b}\t{%2, %0|%0, %2}"
5282 [(set_attr "type" "alu")
5283 (set_attr "mode" "QI")])
5284
5285 (define_expand "addsi3"
5286 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5287 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5288 (match_operand:SI 2 "general_operand" "")))
5289 (clobber (reg:CC 17))])]
5290 ""
5291 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5292
5293 (define_insn "*lea_1"
5294 [(set (match_operand:SI 0 "register_operand" "=r")
5295 (match_operand:SI 1 "address_operand" "p"))]
5296 "!TARGET_64BIT"
5297 "lea{l}\t{%a1, %0|%0, %a1}"
5298 [(set_attr "type" "lea")
5299 (set_attr "mode" "SI")])
5300
5301 (define_insn "*lea_1_rex64"
5302 [(set (match_operand:SI 0 "register_operand" "=r")
5303 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5304 "TARGET_64BIT"
5305 "lea{l}\t{%a1, %0|%0, %a1}"
5306 [(set_attr "type" "lea")
5307 (set_attr "mode" "SI")])
5308
5309 (define_insn "*lea_1_zext"
5310 [(set (match_operand:DI 0 "register_operand" "=r")
5311 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5312 "TARGET_64BIT"
5313 "lea{l}\t{%a1, %k0|%k0, %a1}"
5314 [(set_attr "type" "lea")
5315 (set_attr "mode" "SI")])
5316
5317 (define_insn "*lea_2_rex64"
5318 [(set (match_operand:DI 0 "register_operand" "=r")
5319 (match_operand:DI 1 "address_operand" "p"))]
5320 "TARGET_64BIT"
5321 "lea{q}\t{%a1, %0|%0, %a1}"
5322 [(set_attr "type" "lea")
5323 (set_attr "mode" "DI")])
5324
5325 ;; The lea patterns for non-Pmodes needs to be matched by several
5326 ;; insns converted to real lea by splitters.
5327
5328 (define_insn_and_split "*lea_general_1"
5329 [(set (match_operand 0 "register_operand" "=r")
5330 (plus (plus (match_operand 1 "index_register_operand" "r")
5331 (match_operand 2 "register_operand" "r"))
5332 (match_operand 3 "immediate_operand" "i")))]
5333 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5334 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5335 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5336 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5337 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5338 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5339 || GET_MODE (operands[3]) == VOIDmode)"
5340 "#"
5341 "&& reload_completed"
5342 [(const_int 0)]
5343 {
5344 rtx pat;
5345 operands[0] = gen_lowpart (SImode, operands[0]);
5346 operands[1] = gen_lowpart (Pmode, operands[1]);
5347 operands[2] = gen_lowpart (Pmode, operands[2]);
5348 operands[3] = gen_lowpart (Pmode, operands[3]);
5349 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5350 operands[3]);
5351 if (Pmode != SImode)
5352 pat = gen_rtx_SUBREG (SImode, pat, 0);
5353 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5354 DONE;
5355 }
5356 [(set_attr "type" "lea")
5357 (set_attr "mode" "SI")])
5358
5359 (define_insn_and_split "*lea_general_1_zext"
5360 [(set (match_operand:DI 0 "register_operand" "=r")
5361 (zero_extend:DI
5362 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5363 (match_operand:SI 2 "register_operand" "r"))
5364 (match_operand:SI 3 "immediate_operand" "i"))))]
5365 "TARGET_64BIT"
5366 "#"
5367 "&& reload_completed"
5368 [(set (match_dup 0)
5369 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5370 (match_dup 2))
5371 (match_dup 3)) 0)))]
5372 {
5373 operands[1] = gen_lowpart (Pmode, operands[1]);
5374 operands[2] = gen_lowpart (Pmode, operands[2]);
5375 operands[3] = gen_lowpart (Pmode, operands[3]);
5376 }
5377 [(set_attr "type" "lea")
5378 (set_attr "mode" "SI")])
5379
5380 (define_insn_and_split "*lea_general_2"
5381 [(set (match_operand 0 "register_operand" "=r")
5382 (plus (mult (match_operand 1 "index_register_operand" "r")
5383 (match_operand 2 "const248_operand" "i"))
5384 (match_operand 3 "nonmemory_operand" "ri")))]
5385 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5386 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5387 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5388 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5389 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5390 || GET_MODE (operands[3]) == VOIDmode)"
5391 "#"
5392 "&& reload_completed"
5393 [(const_int 0)]
5394 {
5395 rtx pat;
5396 operands[0] = gen_lowpart (SImode, operands[0]);
5397 operands[1] = gen_lowpart (Pmode, operands[1]);
5398 operands[3] = gen_lowpart (Pmode, operands[3]);
5399 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5400 operands[3]);
5401 if (Pmode != SImode)
5402 pat = gen_rtx_SUBREG (SImode, pat, 0);
5403 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5404 DONE;
5405 }
5406 [(set_attr "type" "lea")
5407 (set_attr "mode" "SI")])
5408
5409 (define_insn_and_split "*lea_general_2_zext"
5410 [(set (match_operand:DI 0 "register_operand" "=r")
5411 (zero_extend:DI
5412 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5413 (match_operand:SI 2 "const248_operand" "n"))
5414 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5415 "TARGET_64BIT"
5416 "#"
5417 "&& reload_completed"
5418 [(set (match_dup 0)
5419 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5420 (match_dup 2))
5421 (match_dup 3)) 0)))]
5422 {
5423 operands[1] = gen_lowpart (Pmode, operands[1]);
5424 operands[3] = gen_lowpart (Pmode, operands[3]);
5425 }
5426 [(set_attr "type" "lea")
5427 (set_attr "mode" "SI")])
5428
5429 (define_insn_and_split "*lea_general_3"
5430 [(set (match_operand 0 "register_operand" "=r")
5431 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5432 (match_operand 2 "const248_operand" "i"))
5433 (match_operand 3 "register_operand" "r"))
5434 (match_operand 4 "immediate_operand" "i")))]
5435 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5436 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5437 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5438 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5439 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5440 "#"
5441 "&& reload_completed"
5442 [(const_int 0)]
5443 {
5444 rtx pat;
5445 operands[0] = gen_lowpart (SImode, operands[0]);
5446 operands[1] = gen_lowpart (Pmode, operands[1]);
5447 operands[3] = gen_lowpart (Pmode, operands[3]);
5448 operands[4] = gen_lowpart (Pmode, operands[4]);
5449 pat = gen_rtx_PLUS (Pmode,
5450 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5451 operands[2]),
5452 operands[3]),
5453 operands[4]);
5454 if (Pmode != SImode)
5455 pat = gen_rtx_SUBREG (SImode, pat, 0);
5456 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5457 DONE;
5458 }
5459 [(set_attr "type" "lea")
5460 (set_attr "mode" "SI")])
5461
5462 (define_insn_and_split "*lea_general_3_zext"
5463 [(set (match_operand:DI 0 "register_operand" "=r")
5464 (zero_extend:DI
5465 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5466 (match_operand:SI 2 "const248_operand" "n"))
5467 (match_operand:SI 3 "register_operand" "r"))
5468 (match_operand:SI 4 "immediate_operand" "i"))))]
5469 "TARGET_64BIT"
5470 "#"
5471 "&& reload_completed"
5472 [(set (match_dup 0)
5473 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5474 (match_dup 2))
5475 (match_dup 3))
5476 (match_dup 4)) 0)))]
5477 {
5478 operands[1] = gen_lowpart (Pmode, operands[1]);
5479 operands[3] = gen_lowpart (Pmode, operands[3]);
5480 operands[4] = gen_lowpart (Pmode, operands[4]);
5481 }
5482 [(set_attr "type" "lea")
5483 (set_attr "mode" "SI")])
5484
5485 (define_insn "*adddi_1_rex64"
5486 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5487 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5488 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5489 (clobber (reg:CC 17))]
5490 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5491 {
5492 switch (get_attr_type (insn))
5493 {
5494 case TYPE_LEA:
5495 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5496 return "lea{q}\t{%a2, %0|%0, %a2}";
5497
5498 case TYPE_INCDEC:
5499 if (! rtx_equal_p (operands[0], operands[1]))
5500 abort ();
5501 if (operands[2] == const1_rtx)
5502 return "inc{q}\t%0";
5503 else if (operands[2] == constm1_rtx)
5504 return "dec{q}\t%0";
5505 else
5506 abort ();
5507
5508 default:
5509 if (! rtx_equal_p (operands[0], operands[1]))
5510 abort ();
5511
5512 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5513 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5514 if (GET_CODE (operands[2]) == CONST_INT
5515 /* Avoid overflows. */
5516 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5517 && (INTVAL (operands[2]) == 128
5518 || (INTVAL (operands[2]) < 0
5519 && INTVAL (operands[2]) != -128)))
5520 {
5521 operands[2] = GEN_INT (-INTVAL (operands[2]));
5522 return "sub{q}\t{%2, %0|%0, %2}";
5523 }
5524 return "add{q}\t{%2, %0|%0, %2}";
5525 }
5526 }
5527 [(set (attr "type")
5528 (cond [(eq_attr "alternative" "2")
5529 (const_string "lea")
5530 ; Current assemblers are broken and do not allow @GOTOFF in
5531 ; ought but a memory context.
5532 (match_operand:DI 2 "pic_symbolic_operand" "")
5533 (const_string "lea")
5534 (match_operand:DI 2 "incdec_operand" "")
5535 (const_string "incdec")
5536 ]
5537 (const_string "alu")))
5538 (set_attr "mode" "DI")])
5539
5540 ;; Convert lea to the lea pattern to avoid flags dependency.
5541 (define_split
5542 [(set (match_operand:DI 0 "register_operand" "")
5543 (plus:DI (match_operand:DI 1 "register_operand" "")
5544 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5545 (clobber (reg:CC 17))]
5546 "TARGET_64BIT && reload_completed
5547 && true_regnum (operands[0]) != true_regnum (operands[1])"
5548 [(set (match_dup 0)
5549 (plus:DI (match_dup 1)
5550 (match_dup 2)))]
5551 "")
5552
5553 (define_insn "*adddi_2_rex64"
5554 [(set (reg 17)
5555 (compare
5556 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5557 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5558 (const_int 0)))
5559 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5560 (plus:DI (match_dup 1) (match_dup 2)))]
5561 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5562 && ix86_binary_operator_ok (PLUS, DImode, operands)
5563 /* Current assemblers are broken and do not allow @GOTOFF in
5564 ought but a memory context. */
5565 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5566 {
5567 switch (get_attr_type (insn))
5568 {
5569 case TYPE_INCDEC:
5570 if (! rtx_equal_p (operands[0], operands[1]))
5571 abort ();
5572 if (operands[2] == const1_rtx)
5573 return "inc{q}\t%0";
5574 else if (operands[2] == constm1_rtx)
5575 return "dec{q}\t%0";
5576 else
5577 abort ();
5578
5579 default:
5580 if (! rtx_equal_p (operands[0], operands[1]))
5581 abort ();
5582 /* ???? We ought to handle there the 32bit case too
5583 - do we need new constraint? */
5584 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5585 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5586 if (GET_CODE (operands[2]) == CONST_INT
5587 /* Avoid overflows. */
5588 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5589 && (INTVAL (operands[2]) == 128
5590 || (INTVAL (operands[2]) < 0
5591 && INTVAL (operands[2]) != -128)))
5592 {
5593 operands[2] = GEN_INT (-INTVAL (operands[2]));
5594 return "sub{q}\t{%2, %0|%0, %2}";
5595 }
5596 return "add{q}\t{%2, %0|%0, %2}";
5597 }
5598 }
5599 [(set (attr "type")
5600 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5601 (const_string "incdec")
5602 (const_string "alu")))
5603 (set_attr "mode" "DI")])
5604
5605 (define_insn "*adddi_3_rex64"
5606 [(set (reg 17)
5607 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5608 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5609 (clobber (match_scratch:DI 0 "=r"))]
5610 "TARGET_64BIT
5611 && ix86_match_ccmode (insn, CCZmode)
5612 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5613 /* Current assemblers are broken and do not allow @GOTOFF in
5614 ought but a memory context. */
5615 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5616 {
5617 switch (get_attr_type (insn))
5618 {
5619 case TYPE_INCDEC:
5620 if (! rtx_equal_p (operands[0], operands[1]))
5621 abort ();
5622 if (operands[2] == const1_rtx)
5623 return "inc{q}\t%0";
5624 else if (operands[2] == constm1_rtx)
5625 return "dec{q}\t%0";
5626 else
5627 abort ();
5628
5629 default:
5630 if (! rtx_equal_p (operands[0], operands[1]))
5631 abort ();
5632 /* ???? We ought to handle there the 32bit case too
5633 - do we need new constraint? */
5634 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5635 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5636 if (GET_CODE (operands[2]) == CONST_INT
5637 /* Avoid overflows. */
5638 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5639 && (INTVAL (operands[2]) == 128
5640 || (INTVAL (operands[2]) < 0
5641 && INTVAL (operands[2]) != -128)))
5642 {
5643 operands[2] = GEN_INT (-INTVAL (operands[2]));
5644 return "sub{q}\t{%2, %0|%0, %2}";
5645 }
5646 return "add{q}\t{%2, %0|%0, %2}";
5647 }
5648 }
5649 [(set (attr "type")
5650 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5651 (const_string "incdec")
5652 (const_string "alu")))
5653 (set_attr "mode" "DI")])
5654
5655 ; For comparisons against 1, -1 and 128, we may generate better code
5656 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5657 ; is matched then. We can't accept general immediate, because for
5658 ; case of overflows, the result is messed up.
5659 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5660 ; when negated.
5661 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5662 ; only for comparisons not depending on it.
5663 (define_insn "*adddi_4_rex64"
5664 [(set (reg 17)
5665 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5666 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5667 (clobber (match_scratch:DI 0 "=rm"))]
5668 "TARGET_64BIT
5669 && ix86_match_ccmode (insn, CCGCmode)"
5670 {
5671 switch (get_attr_type (insn))
5672 {
5673 case TYPE_INCDEC:
5674 if (operands[2] == constm1_rtx)
5675 return "inc{q}\t%0";
5676 else if (operands[2] == const1_rtx)
5677 return "dec{q}\t%0";
5678 else
5679 abort();
5680
5681 default:
5682 if (! rtx_equal_p (operands[0], operands[1]))
5683 abort ();
5684 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5685 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5686 if ((INTVAL (operands[2]) == -128
5687 || (INTVAL (operands[2]) > 0
5688 && INTVAL (operands[2]) != 128))
5689 /* Avoid overflows. */
5690 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5691 return "sub{q}\t{%2, %0|%0, %2}";
5692 operands[2] = GEN_INT (-INTVAL (operands[2]));
5693 return "add{q}\t{%2, %0|%0, %2}";
5694 }
5695 }
5696 [(set (attr "type")
5697 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5698 (const_string "incdec")
5699 (const_string "alu")))
5700 (set_attr "mode" "DI")])
5701
5702 (define_insn "*adddi_5_rex64"
5703 [(set (reg 17)
5704 (compare
5705 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5706 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5707 (const_int 0)))
5708 (clobber (match_scratch:DI 0 "=r"))]
5709 "TARGET_64BIT
5710 && ix86_match_ccmode (insn, CCGOCmode)
5711 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5712 /* Current assemblers are broken and do not allow @GOTOFF in
5713 ought but a memory context. */
5714 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5715 {
5716 switch (get_attr_type (insn))
5717 {
5718 case TYPE_INCDEC:
5719 if (! rtx_equal_p (operands[0], operands[1]))
5720 abort ();
5721 if (operands[2] == const1_rtx)
5722 return "inc{q}\t%0";
5723 else if (operands[2] == constm1_rtx)
5724 return "dec{q}\t%0";
5725 else
5726 abort();
5727
5728 default:
5729 if (! rtx_equal_p (operands[0], operands[1]))
5730 abort ();
5731 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5732 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5733 if (GET_CODE (operands[2]) == CONST_INT
5734 /* Avoid overflows. */
5735 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5736 && (INTVAL (operands[2]) == 128
5737 || (INTVAL (operands[2]) < 0
5738 && INTVAL (operands[2]) != -128)))
5739 {
5740 operands[2] = GEN_INT (-INTVAL (operands[2]));
5741 return "sub{q}\t{%2, %0|%0, %2}";
5742 }
5743 return "add{q}\t{%2, %0|%0, %2}";
5744 }
5745 }
5746 [(set (attr "type")
5747 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5748 (const_string "incdec")
5749 (const_string "alu")))
5750 (set_attr "mode" "DI")])
5751
5752
5753 (define_insn "*addsi_1"
5754 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5755 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5756 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5757 (clobber (reg:CC 17))]
5758 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5759 {
5760 switch (get_attr_type (insn))
5761 {
5762 case TYPE_LEA:
5763 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5764 return "lea{l}\t{%a2, %0|%0, %a2}";
5765
5766 case TYPE_INCDEC:
5767 if (! rtx_equal_p (operands[0], operands[1]))
5768 abort ();
5769 if (operands[2] == const1_rtx)
5770 return "inc{l}\t%0";
5771 else if (operands[2] == constm1_rtx)
5772 return "dec{l}\t%0";
5773 else
5774 abort();
5775
5776 default:
5777 if (! rtx_equal_p (operands[0], operands[1]))
5778 abort ();
5779
5780 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5782 if (GET_CODE (operands[2]) == CONST_INT
5783 && (INTVAL (operands[2]) == 128
5784 || (INTVAL (operands[2]) < 0
5785 && INTVAL (operands[2]) != -128)))
5786 {
5787 operands[2] = GEN_INT (-INTVAL (operands[2]));
5788 return "sub{l}\t{%2, %0|%0, %2}";
5789 }
5790 return "add{l}\t{%2, %0|%0, %2}";
5791 }
5792 }
5793 [(set (attr "type")
5794 (cond [(eq_attr "alternative" "2")
5795 (const_string "lea")
5796 ; Current assemblers are broken and do not allow @GOTOFF in
5797 ; ought but a memory context.
5798 (match_operand:SI 2 "pic_symbolic_operand" "")
5799 (const_string "lea")
5800 (match_operand:SI 2 "incdec_operand" "")
5801 (const_string "incdec")
5802 ]
5803 (const_string "alu")))
5804 (set_attr "mode" "SI")])
5805
5806 ;; Convert lea to the lea pattern to avoid flags dependency.
5807 (define_split
5808 [(set (match_operand 0 "register_operand" "")
5809 (plus (match_operand 1 "register_operand" "")
5810 (match_operand 2 "nonmemory_operand" "")))
5811 (clobber (reg:CC 17))]
5812 "reload_completed
5813 && true_regnum (operands[0]) != true_regnum (operands[1])"
5814 [(const_int 0)]
5815 {
5816 rtx pat;
5817 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5818 may confuse gen_lowpart. */
5819 if (GET_MODE (operands[0]) != Pmode)
5820 {
5821 operands[1] = gen_lowpart (Pmode, operands[1]);
5822 operands[2] = gen_lowpart (Pmode, operands[2]);
5823 }
5824 operands[0] = gen_lowpart (SImode, operands[0]);
5825 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5826 if (Pmode != SImode)
5827 pat = gen_rtx_SUBREG (SImode, pat, 0);
5828 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5829 DONE;
5830 })
5831
5832 ;; It may seem that nonimmediate operand is proper one for operand 1.
5833 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5834 ;; we take care in ix86_binary_operator_ok to not allow two memory
5835 ;; operands so proper swapping will be done in reload. This allow
5836 ;; patterns constructed from addsi_1 to match.
5837 (define_insn "addsi_1_zext"
5838 [(set (match_operand:DI 0 "register_operand" "=r,r")
5839 (zero_extend:DI
5840 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5841 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5842 (clobber (reg:CC 17))]
5843 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5844 {
5845 switch (get_attr_type (insn))
5846 {
5847 case TYPE_LEA:
5848 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5849 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5850
5851 case TYPE_INCDEC:
5852 if (operands[2] == const1_rtx)
5853 return "inc{l}\t%k0";
5854 else if (operands[2] == constm1_rtx)
5855 return "dec{l}\t%k0";
5856 else
5857 abort();
5858
5859 default:
5860 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5861 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5862 if (GET_CODE (operands[2]) == CONST_INT
5863 && (INTVAL (operands[2]) == 128
5864 || (INTVAL (operands[2]) < 0
5865 && INTVAL (operands[2]) != -128)))
5866 {
5867 operands[2] = GEN_INT (-INTVAL (operands[2]));
5868 return "sub{l}\t{%2, %k0|%k0, %2}";
5869 }
5870 return "add{l}\t{%2, %k0|%k0, %2}";
5871 }
5872 }
5873 [(set (attr "type")
5874 (cond [(eq_attr "alternative" "1")
5875 (const_string "lea")
5876 ; Current assemblers are broken and do not allow @GOTOFF in
5877 ; ought but a memory context.
5878 (match_operand:SI 2 "pic_symbolic_operand" "")
5879 (const_string "lea")
5880 (match_operand:SI 2 "incdec_operand" "")
5881 (const_string "incdec")
5882 ]
5883 (const_string "alu")))
5884 (set_attr "mode" "SI")])
5885
5886 ;; Convert lea to the lea pattern to avoid flags dependency.
5887 (define_split
5888 [(set (match_operand:DI 0 "register_operand" "")
5889 (zero_extend:DI
5890 (plus:SI (match_operand:SI 1 "register_operand" "")
5891 (match_operand:SI 2 "nonmemory_operand" ""))))
5892 (clobber (reg:CC 17))]
5893 "TARGET_64BIT && reload_completed
5894 && true_regnum (operands[0]) != true_regnum (operands[1])"
5895 [(set (match_dup 0)
5896 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5897 {
5898 operands[1] = gen_lowpart (Pmode, operands[1]);
5899 operands[2] = gen_lowpart (Pmode, operands[2]);
5900 })
5901
5902 (define_insn "*addsi_2"
5903 [(set (reg 17)
5904 (compare
5905 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5906 (match_operand:SI 2 "general_operand" "rmni,rni"))
5907 (const_int 0)))
5908 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5909 (plus:SI (match_dup 1) (match_dup 2)))]
5910 "ix86_match_ccmode (insn, CCGOCmode)
5911 && ix86_binary_operator_ok (PLUS, SImode, operands)
5912 /* Current assemblers are broken and do not allow @GOTOFF in
5913 ought but a memory context. */
5914 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5915 {
5916 switch (get_attr_type (insn))
5917 {
5918 case TYPE_INCDEC:
5919 if (! rtx_equal_p (operands[0], operands[1]))
5920 abort ();
5921 if (operands[2] == const1_rtx)
5922 return "inc{l}\t%0";
5923 else if (operands[2] == constm1_rtx)
5924 return "dec{l}\t%0";
5925 else
5926 abort();
5927
5928 default:
5929 if (! rtx_equal_p (operands[0], operands[1]))
5930 abort ();
5931 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5932 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5933 if (GET_CODE (operands[2]) == CONST_INT
5934 && (INTVAL (operands[2]) == 128
5935 || (INTVAL (operands[2]) < 0
5936 && INTVAL (operands[2]) != -128)))
5937 {
5938 operands[2] = GEN_INT (-INTVAL (operands[2]));
5939 return "sub{l}\t{%2, %0|%0, %2}";
5940 }
5941 return "add{l}\t{%2, %0|%0, %2}";
5942 }
5943 }
5944 [(set (attr "type")
5945 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5946 (const_string "incdec")
5947 (const_string "alu")))
5948 (set_attr "mode" "SI")])
5949
5950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5951 (define_insn "*addsi_2_zext"
5952 [(set (reg 17)
5953 (compare
5954 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5955 (match_operand:SI 2 "general_operand" "rmni"))
5956 (const_int 0)))
5957 (set (match_operand:DI 0 "register_operand" "=r")
5958 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5959 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5960 && ix86_binary_operator_ok (PLUS, SImode, operands)
5961 /* Current assemblers are broken and do not allow @GOTOFF in
5962 ought but a memory context. */
5963 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5964 {
5965 switch (get_attr_type (insn))
5966 {
5967 case TYPE_INCDEC:
5968 if (operands[2] == const1_rtx)
5969 return "inc{l}\t%k0";
5970 else if (operands[2] == constm1_rtx)
5971 return "dec{l}\t%k0";
5972 else
5973 abort();
5974
5975 default:
5976 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5977 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5978 if (GET_CODE (operands[2]) == CONST_INT
5979 && (INTVAL (operands[2]) == 128
5980 || (INTVAL (operands[2]) < 0
5981 && INTVAL (operands[2]) != -128)))
5982 {
5983 operands[2] = GEN_INT (-INTVAL (operands[2]));
5984 return "sub{l}\t{%2, %k0|%k0, %2}";
5985 }
5986 return "add{l}\t{%2, %k0|%k0, %2}";
5987 }
5988 }
5989 [(set (attr "type")
5990 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5991 (const_string "incdec")
5992 (const_string "alu")))
5993 (set_attr "mode" "SI")])
5994
5995 (define_insn "*addsi_3"
5996 [(set (reg 17)
5997 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5998 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5999 (clobber (match_scratch:SI 0 "=r"))]
6000 "ix86_match_ccmode (insn, CCZmode)
6001 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6002 /* Current assemblers are broken and do not allow @GOTOFF in
6003 ought but a memory context. */
6004 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6005 {
6006 switch (get_attr_type (insn))
6007 {
6008 case TYPE_INCDEC:
6009 if (! rtx_equal_p (operands[0], operands[1]))
6010 abort ();
6011 if (operands[2] == const1_rtx)
6012 return "inc{l}\t%0";
6013 else if (operands[2] == constm1_rtx)
6014 return "dec{l}\t%0";
6015 else
6016 abort();
6017
6018 default:
6019 if (! rtx_equal_p (operands[0], operands[1]))
6020 abort ();
6021 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6022 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6023 if (GET_CODE (operands[2]) == CONST_INT
6024 && (INTVAL (operands[2]) == 128
6025 || (INTVAL (operands[2]) < 0
6026 && INTVAL (operands[2]) != -128)))
6027 {
6028 operands[2] = GEN_INT (-INTVAL (operands[2]));
6029 return "sub{l}\t{%2, %0|%0, %2}";
6030 }
6031 return "add{l}\t{%2, %0|%0, %2}";
6032 }
6033 }
6034 [(set (attr "type")
6035 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6036 (const_string "incdec")
6037 (const_string "alu")))
6038 (set_attr "mode" "SI")])
6039
6040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6041 (define_insn "*addsi_3_zext"
6042 [(set (reg 17)
6043 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6044 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6045 (set (match_operand:DI 0 "register_operand" "=r")
6046 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6047 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6048 && ix86_binary_operator_ok (PLUS, SImode, operands)
6049 /* Current assemblers are broken and do not allow @GOTOFF in
6050 ought but a memory context. */
6051 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6052 {
6053 switch (get_attr_type (insn))
6054 {
6055 case TYPE_INCDEC:
6056 if (operands[2] == const1_rtx)
6057 return "inc{l}\t%k0";
6058 else if (operands[2] == constm1_rtx)
6059 return "dec{l}\t%k0";
6060 else
6061 abort();
6062
6063 default:
6064 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6065 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6066 if (GET_CODE (operands[2]) == CONST_INT
6067 && (INTVAL (operands[2]) == 128
6068 || (INTVAL (operands[2]) < 0
6069 && INTVAL (operands[2]) != -128)))
6070 {
6071 operands[2] = GEN_INT (-INTVAL (operands[2]));
6072 return "sub{l}\t{%2, %k0|%k0, %2}";
6073 }
6074 return "add{l}\t{%2, %k0|%k0, %2}";
6075 }
6076 }
6077 [(set (attr "type")
6078 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set_attr "mode" "SI")])
6082
6083 ; For comparisons against 1, -1 and 128, we may generate better code
6084 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6085 ; is matched then. We can't accept general immediate, because for
6086 ; case of overflows, the result is messed up.
6087 ; This pattern also don't hold of 0x80000000, since the value overflows
6088 ; when negated.
6089 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6090 ; only for comparisons not depending on it.
6091 (define_insn "*addsi_4"
6092 [(set (reg 17)
6093 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6094 (match_operand:SI 2 "const_int_operand" "n")))
6095 (clobber (match_scratch:SI 0 "=rm"))]
6096 "ix86_match_ccmode (insn, CCGCmode)
6097 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6098 {
6099 switch (get_attr_type (insn))
6100 {
6101 case TYPE_INCDEC:
6102 if (operands[2] == constm1_rtx)
6103 return "inc{l}\t%0";
6104 else if (operands[2] == const1_rtx)
6105 return "dec{l}\t%0";
6106 else
6107 abort();
6108
6109 default:
6110 if (! rtx_equal_p (operands[0], operands[1]))
6111 abort ();
6112 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6113 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6114 if ((INTVAL (operands[2]) == -128
6115 || (INTVAL (operands[2]) > 0
6116 && INTVAL (operands[2]) != 128)))
6117 return "sub{l}\t{%2, %0|%0, %2}";
6118 operands[2] = GEN_INT (-INTVAL (operands[2]));
6119 return "add{l}\t{%2, %0|%0, %2}";
6120 }
6121 }
6122 [(set (attr "type")
6123 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6124 (const_string "incdec")
6125 (const_string "alu")))
6126 (set_attr "mode" "SI")])
6127
6128 (define_insn "*addsi_5"
6129 [(set (reg 17)
6130 (compare
6131 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6132 (match_operand:SI 2 "general_operand" "rmni"))
6133 (const_int 0)))
6134 (clobber (match_scratch:SI 0 "=r"))]
6135 "ix86_match_ccmode (insn, CCGOCmode)
6136 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6137 /* Current assemblers are broken and do not allow @GOTOFF in
6138 ought but a memory context. */
6139 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6140 {
6141 switch (get_attr_type (insn))
6142 {
6143 case TYPE_INCDEC:
6144 if (! rtx_equal_p (operands[0], operands[1]))
6145 abort ();
6146 if (operands[2] == const1_rtx)
6147 return "inc{l}\t%0";
6148 else if (operands[2] == constm1_rtx)
6149 return "dec{l}\t%0";
6150 else
6151 abort();
6152
6153 default:
6154 if (! rtx_equal_p (operands[0], operands[1]))
6155 abort ();
6156 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6157 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6158 if (GET_CODE (operands[2]) == CONST_INT
6159 && (INTVAL (operands[2]) == 128
6160 || (INTVAL (operands[2]) < 0
6161 && INTVAL (operands[2]) != -128)))
6162 {
6163 operands[2] = GEN_INT (-INTVAL (operands[2]));
6164 return "sub{l}\t{%2, %0|%0, %2}";
6165 }
6166 return "add{l}\t{%2, %0|%0, %2}";
6167 }
6168 }
6169 [(set (attr "type")
6170 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6171 (const_string "incdec")
6172 (const_string "alu")))
6173 (set_attr "mode" "SI")])
6174
6175 (define_expand "addhi3"
6176 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6177 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6178 (match_operand:HI 2 "general_operand" "")))
6179 (clobber (reg:CC 17))])]
6180 "TARGET_HIMODE_MATH"
6181 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6182
6183 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6184 ;; type optimizations enabled by define-splits. This is not important
6185 ;; for PII, and in fact harmful because of partial register stalls.
6186
6187 (define_insn "*addhi_1_lea"
6188 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6189 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6190 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6191 (clobber (reg:CC 17))]
6192 "!TARGET_PARTIAL_REG_STALL
6193 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6194 {
6195 switch (get_attr_type (insn))
6196 {
6197 case TYPE_LEA:
6198 return "#";
6199 case TYPE_INCDEC:
6200 if (operands[2] == const1_rtx)
6201 return "inc{w}\t%0";
6202 else if (operands[2] == constm1_rtx)
6203 return "dec{w}\t%0";
6204 abort();
6205
6206 default:
6207 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6208 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6209 if (GET_CODE (operands[2]) == CONST_INT
6210 && (INTVAL (operands[2]) == 128
6211 || (INTVAL (operands[2]) < 0
6212 && INTVAL (operands[2]) != -128)))
6213 {
6214 operands[2] = GEN_INT (-INTVAL (operands[2]));
6215 return "sub{w}\t{%2, %0|%0, %2}";
6216 }
6217 return "add{w}\t{%2, %0|%0, %2}";
6218 }
6219 }
6220 [(set (attr "type")
6221 (if_then_else (eq_attr "alternative" "2")
6222 (const_string "lea")
6223 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6224 (const_string "incdec")
6225 (const_string "alu"))))
6226 (set_attr "mode" "HI,HI,SI")])
6227
6228 (define_insn "*addhi_1"
6229 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6230 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6231 (match_operand:HI 2 "general_operand" "ri,rm")))
6232 (clobber (reg:CC 17))]
6233 "TARGET_PARTIAL_REG_STALL
6234 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6235 {
6236 switch (get_attr_type (insn))
6237 {
6238 case TYPE_INCDEC:
6239 if (operands[2] == const1_rtx)
6240 return "inc{w}\t%0";
6241 else if (operands[2] == constm1_rtx)
6242 return "dec{w}\t%0";
6243 abort();
6244
6245 default:
6246 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6247 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6248 if (GET_CODE (operands[2]) == CONST_INT
6249 && (INTVAL (operands[2]) == 128
6250 || (INTVAL (operands[2]) < 0
6251 && INTVAL (operands[2]) != -128)))
6252 {
6253 operands[2] = GEN_INT (-INTVAL (operands[2]));
6254 return "sub{w}\t{%2, %0|%0, %2}";
6255 }
6256 return "add{w}\t{%2, %0|%0, %2}";
6257 }
6258 }
6259 [(set (attr "type")
6260 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6261 (const_string "incdec")
6262 (const_string "alu")))
6263 (set_attr "mode" "HI")])
6264
6265 (define_insn "*addhi_2"
6266 [(set (reg 17)
6267 (compare
6268 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6269 (match_operand:HI 2 "general_operand" "rmni,rni"))
6270 (const_int 0)))
6271 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6272 (plus:HI (match_dup 1) (match_dup 2)))]
6273 "ix86_match_ccmode (insn, CCGOCmode)
6274 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6275 {
6276 switch (get_attr_type (insn))
6277 {
6278 case TYPE_INCDEC:
6279 if (operands[2] == const1_rtx)
6280 return "inc{w}\t%0";
6281 else if (operands[2] == constm1_rtx)
6282 return "dec{w}\t%0";
6283 abort();
6284
6285 default:
6286 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6287 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6288 if (GET_CODE (operands[2]) == CONST_INT
6289 && (INTVAL (operands[2]) == 128
6290 || (INTVAL (operands[2]) < 0
6291 && INTVAL (operands[2]) != -128)))
6292 {
6293 operands[2] = GEN_INT (-INTVAL (operands[2]));
6294 return "sub{w}\t{%2, %0|%0, %2}";
6295 }
6296 return "add{w}\t{%2, %0|%0, %2}";
6297 }
6298 }
6299 [(set (attr "type")
6300 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6301 (const_string "incdec")
6302 (const_string "alu")))
6303 (set_attr "mode" "HI")])
6304
6305 (define_insn "*addhi_3"
6306 [(set (reg 17)
6307 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6308 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6309 (clobber (match_scratch:HI 0 "=r"))]
6310 "ix86_match_ccmode (insn, CCZmode)
6311 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6312 {
6313 switch (get_attr_type (insn))
6314 {
6315 case TYPE_INCDEC:
6316 if (operands[2] == const1_rtx)
6317 return "inc{w}\t%0";
6318 else if (operands[2] == constm1_rtx)
6319 return "dec{w}\t%0";
6320 abort();
6321
6322 default:
6323 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6324 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6325 if (GET_CODE (operands[2]) == CONST_INT
6326 && (INTVAL (operands[2]) == 128
6327 || (INTVAL (operands[2]) < 0
6328 && INTVAL (operands[2]) != -128)))
6329 {
6330 operands[2] = GEN_INT (-INTVAL (operands[2]));
6331 return "sub{w}\t{%2, %0|%0, %2}";
6332 }
6333 return "add{w}\t{%2, %0|%0, %2}";
6334 }
6335 }
6336 [(set (attr "type")
6337 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6338 (const_string "incdec")
6339 (const_string "alu")))
6340 (set_attr "mode" "HI")])
6341
6342 ; See comments above addsi_3_imm for details.
6343 (define_insn "*addhi_4"
6344 [(set (reg 17)
6345 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6346 (match_operand:HI 2 "const_int_operand" "n")))
6347 (clobber (match_scratch:HI 0 "=rm"))]
6348 "ix86_match_ccmode (insn, CCGCmode)
6349 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6350 {
6351 switch (get_attr_type (insn))
6352 {
6353 case TYPE_INCDEC:
6354 if (operands[2] == constm1_rtx)
6355 return "inc{w}\t%0";
6356 else if (operands[2] == const1_rtx)
6357 return "dec{w}\t%0";
6358 else
6359 abort();
6360
6361 default:
6362 if (! rtx_equal_p (operands[0], operands[1]))
6363 abort ();
6364 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6365 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6366 if ((INTVAL (operands[2]) == -128
6367 || (INTVAL (operands[2]) > 0
6368 && INTVAL (operands[2]) != 128)))
6369 return "sub{w}\t{%2, %0|%0, %2}";
6370 operands[2] = GEN_INT (-INTVAL (operands[2]));
6371 return "add{w}\t{%2, %0|%0, %2}";
6372 }
6373 }
6374 [(set (attr "type")
6375 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6376 (const_string "incdec")
6377 (const_string "alu")))
6378 (set_attr "mode" "SI")])
6379
6380
6381 (define_insn "*addhi_5"
6382 [(set (reg 17)
6383 (compare
6384 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6385 (match_operand:HI 2 "general_operand" "rmni"))
6386 (const_int 0)))
6387 (clobber (match_scratch:HI 0 "=r"))]
6388 "ix86_match_ccmode (insn, CCGOCmode)
6389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6390 {
6391 switch (get_attr_type (insn))
6392 {
6393 case TYPE_INCDEC:
6394 if (operands[2] == const1_rtx)
6395 return "inc{w}\t%0";
6396 else if (operands[2] == constm1_rtx)
6397 return "dec{w}\t%0";
6398 abort();
6399
6400 default:
6401 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6402 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6403 if (GET_CODE (operands[2]) == CONST_INT
6404 && (INTVAL (operands[2]) == 128
6405 || (INTVAL (operands[2]) < 0
6406 && INTVAL (operands[2]) != -128)))
6407 {
6408 operands[2] = GEN_INT (-INTVAL (operands[2]));
6409 return "sub{w}\t{%2, %0|%0, %2}";
6410 }
6411 return "add{w}\t{%2, %0|%0, %2}";
6412 }
6413 }
6414 [(set (attr "type")
6415 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6416 (const_string "incdec")
6417 (const_string "alu")))
6418 (set_attr "mode" "HI")])
6419
6420 (define_expand "addqi3"
6421 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6422 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6423 (match_operand:QI 2 "general_operand" "")))
6424 (clobber (reg:CC 17))])]
6425 "TARGET_QIMODE_MATH"
6426 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6427
6428 ;; %%% Potential partial reg stall on alternative 2. What to do?
6429 (define_insn "*addqi_1_lea"
6430 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6431 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6432 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6433 (clobber (reg:CC 17))]
6434 "!TARGET_PARTIAL_REG_STALL
6435 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6436 {
6437 int widen = (which_alternative == 2);
6438 switch (get_attr_type (insn))
6439 {
6440 case TYPE_LEA:
6441 return "#";
6442 case TYPE_INCDEC:
6443 if (operands[2] == const1_rtx)
6444 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6445 else if (operands[2] == constm1_rtx)
6446 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6447 abort();
6448
6449 default:
6450 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6451 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6452 if (GET_CODE (operands[2]) == CONST_INT
6453 && (INTVAL (operands[2]) == 128
6454 || (INTVAL (operands[2]) < 0
6455 && INTVAL (operands[2]) != -128)))
6456 {
6457 operands[2] = GEN_INT (-INTVAL (operands[2]));
6458 if (widen)
6459 return "sub{l}\t{%2, %k0|%k0, %2}";
6460 else
6461 return "sub{b}\t{%2, %0|%0, %2}";
6462 }
6463 if (widen)
6464 return "add{l}\t{%k2, %k0|%k0, %k2}";
6465 else
6466 return "add{b}\t{%2, %0|%0, %2}";
6467 }
6468 }
6469 [(set (attr "type")
6470 (if_then_else (eq_attr "alternative" "3")
6471 (const_string "lea")
6472 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6473 (const_string "incdec")
6474 (const_string "alu"))))
6475 (set_attr "mode" "QI,QI,SI,SI")])
6476
6477 (define_insn "*addqi_1"
6478 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6479 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6480 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6481 (clobber (reg:CC 17))]
6482 "TARGET_PARTIAL_REG_STALL
6483 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6484 {
6485 int widen = (which_alternative == 2);
6486 switch (get_attr_type (insn))
6487 {
6488 case TYPE_INCDEC:
6489 if (operands[2] == const1_rtx)
6490 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6491 else if (operands[2] == constm1_rtx)
6492 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6493 abort();
6494
6495 default:
6496 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6497 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6498 if (GET_CODE (operands[2]) == CONST_INT
6499 && (INTVAL (operands[2]) == 128
6500 || (INTVAL (operands[2]) < 0
6501 && INTVAL (operands[2]) != -128)))
6502 {
6503 operands[2] = GEN_INT (-INTVAL (operands[2]));
6504 if (widen)
6505 return "sub{l}\t{%2, %k0|%k0, %2}";
6506 else
6507 return "sub{b}\t{%2, %0|%0, %2}";
6508 }
6509 if (widen)
6510 return "add{l}\t{%k2, %k0|%k0, %k2}";
6511 else
6512 return "add{b}\t{%2, %0|%0, %2}";
6513 }
6514 }
6515 [(set (attr "type")
6516 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6517 (const_string "incdec")
6518 (const_string "alu")))
6519 (set_attr "mode" "QI,QI,SI")])
6520
6521 (define_insn "*addqi_1_slp"
6522 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6523 (plus:QI (match_dup 0)
6524 (match_operand:QI 1 "general_operand" "qn,qnm")))
6525 (clobber (reg:CC 17))]
6526 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6527 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6528 {
6529 switch (get_attr_type (insn))
6530 {
6531 case TYPE_INCDEC:
6532 if (operands[1] == const1_rtx)
6533 return "inc{b}\t%0";
6534 else if (operands[1] == constm1_rtx)
6535 return "dec{b}\t%0";
6536 abort();
6537
6538 default:
6539 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6540 if (GET_CODE (operands[1]) == CONST_INT
6541 && INTVAL (operands[1]) < 0)
6542 {
6543 operands[2] = GEN_INT (-INTVAL (operands[2]));
6544 return "sub{b}\t{%1, %0|%0, %1}";
6545 }
6546 return "add{b}\t{%1, %0|%0, %1}";
6547 }
6548 }
6549 [(set (attr "type")
6550 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6551 (const_string "incdec")
6552 (const_string "alu1")))
6553 (set_attr "mode" "QI")])
6554
6555 (define_insn "*addqi_2"
6556 [(set (reg 17)
6557 (compare
6558 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6559 (match_operand:QI 2 "general_operand" "qmni,qni"))
6560 (const_int 0)))
6561 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6562 (plus:QI (match_dup 1) (match_dup 2)))]
6563 "ix86_match_ccmode (insn, CCGOCmode)
6564 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6565 {
6566 switch (get_attr_type (insn))
6567 {
6568 case TYPE_INCDEC:
6569 if (operands[2] == const1_rtx)
6570 return "inc{b}\t%0";
6571 else if (operands[2] == constm1_rtx
6572 || (GET_CODE (operands[2]) == CONST_INT
6573 && INTVAL (operands[2]) == 255))
6574 return "dec{b}\t%0";
6575 abort();
6576
6577 default:
6578 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6579 if (GET_CODE (operands[2]) == CONST_INT
6580 && INTVAL (operands[2]) < 0)
6581 {
6582 operands[2] = GEN_INT (-INTVAL (operands[2]));
6583 return "sub{b}\t{%2, %0|%0, %2}";
6584 }
6585 return "add{b}\t{%2, %0|%0, %2}";
6586 }
6587 }
6588 [(set (attr "type")
6589 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6590 (const_string "incdec")
6591 (const_string "alu")))
6592 (set_attr "mode" "QI")])
6593
6594 (define_insn "*addqi_3"
6595 [(set (reg 17)
6596 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6597 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6598 (clobber (match_scratch:QI 0 "=q"))]
6599 "ix86_match_ccmode (insn, CCZmode)
6600 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6601 {
6602 switch (get_attr_type (insn))
6603 {
6604 case TYPE_INCDEC:
6605 if (operands[2] == const1_rtx)
6606 return "inc{b}\t%0";
6607 else if (operands[2] == constm1_rtx
6608 || (GET_CODE (operands[2]) == CONST_INT
6609 && INTVAL (operands[2]) == 255))
6610 return "dec{b}\t%0";
6611 abort();
6612
6613 default:
6614 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6615 if (GET_CODE (operands[2]) == CONST_INT
6616 && INTVAL (operands[2]) < 0)
6617 {
6618 operands[2] = GEN_INT (-INTVAL (operands[2]));
6619 return "sub{b}\t{%2, %0|%0, %2}";
6620 }
6621 return "add{b}\t{%2, %0|%0, %2}";
6622 }
6623 }
6624 [(set (attr "type")
6625 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6626 (const_string "incdec")
6627 (const_string "alu")))
6628 (set_attr "mode" "QI")])
6629
6630 ; See comments above addsi_3_imm for details.
6631 (define_insn "*addqi_4"
6632 [(set (reg 17)
6633 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6634 (match_operand:QI 2 "const_int_operand" "n")))
6635 (clobber (match_scratch:QI 0 "=qm"))]
6636 "ix86_match_ccmode (insn, CCGCmode)
6637 && (INTVAL (operands[2]) & 0xff) != 0x80"
6638 {
6639 switch (get_attr_type (insn))
6640 {
6641 case TYPE_INCDEC:
6642 if (operands[2] == constm1_rtx
6643 || (GET_CODE (operands[2]) == CONST_INT
6644 && INTVAL (operands[2]) == 255))
6645 return "inc{b}\t%0";
6646 else if (operands[2] == const1_rtx)
6647 return "dec{b}\t%0";
6648 else
6649 abort();
6650
6651 default:
6652 if (! rtx_equal_p (operands[0], operands[1]))
6653 abort ();
6654 if (INTVAL (operands[2]) < 0)
6655 {
6656 operands[2] = GEN_INT (-INTVAL (operands[2]));
6657 return "add{b}\t{%2, %0|%0, %2}";
6658 }
6659 return "sub{b}\t{%2, %0|%0, %2}";
6660 }
6661 }
6662 [(set (attr "type")
6663 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6664 (const_string "incdec")
6665 (const_string "alu")))
6666 (set_attr "mode" "QI")])
6667
6668
6669 (define_insn "*addqi_5"
6670 [(set (reg 17)
6671 (compare
6672 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6673 (match_operand:QI 2 "general_operand" "qmni"))
6674 (const_int 0)))
6675 (clobber (match_scratch:QI 0 "=q"))]
6676 "ix86_match_ccmode (insn, CCGOCmode)
6677 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6678 {
6679 switch (get_attr_type (insn))
6680 {
6681 case TYPE_INCDEC:
6682 if (operands[2] == const1_rtx)
6683 return "inc{b}\t%0";
6684 else if (operands[2] == constm1_rtx
6685 || (GET_CODE (operands[2]) == CONST_INT
6686 && INTVAL (operands[2]) == 255))
6687 return "dec{b}\t%0";
6688 abort();
6689
6690 default:
6691 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6692 if (GET_CODE (operands[2]) == CONST_INT
6693 && INTVAL (operands[2]) < 0)
6694 {
6695 operands[2] = GEN_INT (-INTVAL (operands[2]));
6696 return "sub{b}\t{%2, %0|%0, %2}";
6697 }
6698 return "add{b}\t{%2, %0|%0, %2}";
6699 }
6700 }
6701 [(set (attr "type")
6702 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6703 (const_string "incdec")
6704 (const_string "alu")))
6705 (set_attr "mode" "QI")])
6706
6707
6708 (define_insn "addqi_ext_1"
6709 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6710 (const_int 8)
6711 (const_int 8))
6712 (plus:SI
6713 (zero_extract:SI
6714 (match_operand 1 "ext_register_operand" "0")
6715 (const_int 8)
6716 (const_int 8))
6717 (match_operand:QI 2 "general_operand" "Qmn")))
6718 (clobber (reg:CC 17))]
6719 "!TARGET_64BIT"
6720 {
6721 switch (get_attr_type (insn))
6722 {
6723 case TYPE_INCDEC:
6724 if (operands[2] == const1_rtx)
6725 return "inc{b}\t%h0";
6726 else if (operands[2] == constm1_rtx
6727 || (GET_CODE (operands[2]) == CONST_INT
6728 && INTVAL (operands[2]) == 255))
6729 return "dec{b}\t%h0";
6730 abort();
6731
6732 default:
6733 return "add{b}\t{%2, %h0|%h0, %2}";
6734 }
6735 }
6736 [(set (attr "type")
6737 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6738 (const_string "incdec")
6739 (const_string "alu")))
6740 (set_attr "mode" "QI")])
6741
6742 (define_insn "*addqi_ext_1_rex64"
6743 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6744 (const_int 8)
6745 (const_int 8))
6746 (plus:SI
6747 (zero_extract:SI
6748 (match_operand 1 "ext_register_operand" "0")
6749 (const_int 8)
6750 (const_int 8))
6751 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6752 (clobber (reg:CC 17))]
6753 "TARGET_64BIT"
6754 {
6755 switch (get_attr_type (insn))
6756 {
6757 case TYPE_INCDEC:
6758 if (operands[2] == const1_rtx)
6759 return "inc{b}\t%h0";
6760 else if (operands[2] == constm1_rtx
6761 || (GET_CODE (operands[2]) == CONST_INT
6762 && INTVAL (operands[2]) == 255))
6763 return "dec{b}\t%h0";
6764 abort();
6765
6766 default:
6767 return "add{b}\t{%2, %h0|%h0, %2}";
6768 }
6769 }
6770 [(set (attr "type")
6771 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6772 (const_string "incdec")
6773 (const_string "alu")))
6774 (set_attr "mode" "QI")])
6775
6776 (define_insn "*addqi_ext_2"
6777 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6778 (const_int 8)
6779 (const_int 8))
6780 (plus:SI
6781 (zero_extract:SI
6782 (match_operand 1 "ext_register_operand" "%0")
6783 (const_int 8)
6784 (const_int 8))
6785 (zero_extract:SI
6786 (match_operand 2 "ext_register_operand" "Q")
6787 (const_int 8)
6788 (const_int 8))))
6789 (clobber (reg:CC 17))]
6790 ""
6791 "add{b}\t{%h2, %h0|%h0, %h2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "QI")])
6794
6795 ;; The patterns that match these are at the end of this file.
6796
6797 (define_expand "addxf3"
6798 [(set (match_operand:XF 0 "register_operand" "")
6799 (plus:XF (match_operand:XF 1 "register_operand" "")
6800 (match_operand:XF 2 "register_operand" "")))]
6801 "!TARGET_64BIT && TARGET_80387"
6802 "")
6803
6804 (define_expand "addtf3"
6805 [(set (match_operand:TF 0 "register_operand" "")
6806 (plus:TF (match_operand:TF 1 "register_operand" "")
6807 (match_operand:TF 2 "register_operand" "")))]
6808 "TARGET_80387"
6809 "")
6810
6811 (define_expand "adddf3"
6812 [(set (match_operand:DF 0 "register_operand" "")
6813 (plus:DF (match_operand:DF 1 "register_operand" "")
6814 (match_operand:DF 2 "nonimmediate_operand" "")))]
6815 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6816 "")
6817
6818 (define_expand "addsf3"
6819 [(set (match_operand:SF 0 "register_operand" "")
6820 (plus:SF (match_operand:SF 1 "register_operand" "")
6821 (match_operand:SF 2 "nonimmediate_operand" "")))]
6822 "TARGET_80387 || TARGET_SSE_MATH"
6823 "")
6824 \f
6825 ;; Subtract instructions
6826
6827 ;; %%% splits for subsidi3
6828
6829 (define_expand "subdi3"
6830 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6831 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6832 (match_operand:DI 2 "x86_64_general_operand" "")))
6833 (clobber (reg:CC 17))])]
6834 ""
6835 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6836
6837 (define_insn "*subdi3_1"
6838 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6839 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6840 (match_operand:DI 2 "general_operand" "roiF,riF")))
6841 (clobber (reg:CC 17))]
6842 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6843 "#")
6844
6845 (define_split
6846 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6847 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6848 (match_operand:DI 2 "general_operand" "")))
6849 (clobber (reg:CC 17))]
6850 "!TARGET_64BIT && reload_completed"
6851 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6852 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6853 (parallel [(set (match_dup 3)
6854 (minus:SI (match_dup 4)
6855 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6856 (match_dup 5))))
6857 (clobber (reg:CC 17))])]
6858 "split_di (operands+0, 1, operands+0, operands+3);
6859 split_di (operands+1, 1, operands+1, operands+4);
6860 split_di (operands+2, 1, operands+2, operands+5);")
6861
6862 (define_insn "subdi3_carry_rex64"
6863 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6864 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6865 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6866 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6867 (clobber (reg:CC 17))]
6868 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6869 "sbb{q}\t{%2, %0|%0, %2}"
6870 [(set_attr "type" "alu")
6871 (set_attr "pent_pair" "pu")
6872 (set_attr "ppro_uops" "few")
6873 (set_attr "mode" "DI")])
6874
6875 (define_insn "*subdi_1_rex64"
6876 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6877 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6878 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6879 (clobber (reg:CC 17))]
6880 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6881 "sub{q}\t{%2, %0|%0, %2}"
6882 [(set_attr "type" "alu")
6883 (set_attr "mode" "DI")])
6884
6885 (define_insn "*subdi_2_rex64"
6886 [(set (reg 17)
6887 (compare
6888 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6889 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6890 (const_int 0)))
6891 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6892 (minus:DI (match_dup 1) (match_dup 2)))]
6893 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6894 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6895 "sub{q}\t{%2, %0|%0, %2}"
6896 [(set_attr "type" "alu")
6897 (set_attr "mode" "DI")])
6898
6899 (define_insn "*subdi_3_rex63"
6900 [(set (reg 17)
6901 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6902 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6903 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6904 (minus:DI (match_dup 1) (match_dup 2)))]
6905 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6906 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6907 "sub{q}\t{%2, %0|%0, %2}"
6908 [(set_attr "type" "alu")
6909 (set_attr "mode" "DI")])
6910
6911 (define_insn "subqi3_carry"
6912 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6913 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6914 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6915 (match_operand:QI 2 "general_operand" "ri,rm"))))
6916 (clobber (reg:CC 17))]
6917 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6918 "sbb{b}\t{%2, %0|%0, %2}"
6919 [(set_attr "type" "alu")
6920 (set_attr "pent_pair" "pu")
6921 (set_attr "ppro_uops" "few")
6922 (set_attr "mode" "QI")])
6923
6924 (define_insn "subhi3_carry"
6925 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6926 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6927 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6928 (match_operand:HI 2 "general_operand" "ri,rm"))))
6929 (clobber (reg:CC 17))]
6930 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6931 "sbb{w}\t{%2, %0|%0, %2}"
6932 [(set_attr "type" "alu")
6933 (set_attr "pent_pair" "pu")
6934 (set_attr "ppro_uops" "few")
6935 (set_attr "mode" "HI")])
6936
6937 (define_insn "subsi3_carry"
6938 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6939 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6940 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6941 (match_operand:SI 2 "general_operand" "ri,rm"))))
6942 (clobber (reg:CC 17))]
6943 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6944 "sbb{l}\t{%2, %0|%0, %2}"
6945 [(set_attr "type" "alu")
6946 (set_attr "pent_pair" "pu")
6947 (set_attr "ppro_uops" "few")
6948 (set_attr "mode" "SI")])
6949
6950 (define_insn "subsi3_carry_zext"
6951 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6952 (zero_extend:DI
6953 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6954 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6955 (match_operand:SI 2 "general_operand" "ri,rm")))))
6956 (clobber (reg:CC 17))]
6957 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6958 "sbb{l}\t{%2, %k0|%k0, %2}"
6959 [(set_attr "type" "alu")
6960 (set_attr "pent_pair" "pu")
6961 (set_attr "ppro_uops" "few")
6962 (set_attr "mode" "SI")])
6963
6964 (define_expand "subsi3"
6965 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6966 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6967 (match_operand:SI 2 "general_operand" "")))
6968 (clobber (reg:CC 17))])]
6969 ""
6970 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6971
6972 (define_insn "*subsi_1"
6973 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6974 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6975 (match_operand:SI 2 "general_operand" "ri,rm")))
6976 (clobber (reg:CC 17))]
6977 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6978 "sub{l}\t{%2, %0|%0, %2}"
6979 [(set_attr "type" "alu")
6980 (set_attr "mode" "SI")])
6981
6982 (define_insn "*subsi_1_zext"
6983 [(set (match_operand:DI 0 "register_operand" "=r")
6984 (zero_extend:DI
6985 (minus:SI (match_operand:SI 1 "register_operand" "0")
6986 (match_operand:SI 2 "general_operand" "rim"))))
6987 (clobber (reg:CC 17))]
6988 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6989 "sub{l}\t{%2, %k0|%k0, %2}"
6990 [(set_attr "type" "alu")
6991 (set_attr "mode" "SI")])
6992
6993 (define_insn "*subsi_2"
6994 [(set (reg 17)
6995 (compare
6996 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6997 (match_operand:SI 2 "general_operand" "ri,rm"))
6998 (const_int 0)))
6999 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7000 (minus:SI (match_dup 1) (match_dup 2)))]
7001 "ix86_match_ccmode (insn, CCGOCmode)
7002 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7003 "sub{l}\t{%2, %0|%0, %2}"
7004 [(set_attr "type" "alu")
7005 (set_attr "mode" "SI")])
7006
7007 (define_insn "*subsi_2_zext"
7008 [(set (reg 17)
7009 (compare
7010 (minus:SI (match_operand:SI 1 "register_operand" "0")
7011 (match_operand:SI 2 "general_operand" "rim"))
7012 (const_int 0)))
7013 (set (match_operand:DI 0 "register_operand" "=r")
7014 (zero_extend:DI
7015 (minus:SI (match_dup 1)
7016 (match_dup 2))))]
7017 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7018 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7019 "sub{l}\t{%2, %k0|%k0, %2}"
7020 [(set_attr "type" "alu")
7021 (set_attr "mode" "SI")])
7022
7023 (define_insn "*subsi_3"
7024 [(set (reg 17)
7025 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7026 (match_operand:SI 2 "general_operand" "ri,rm")))
7027 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7028 (minus:SI (match_dup 1) (match_dup 2)))]
7029 "ix86_match_ccmode (insn, CCmode)
7030 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7031 "sub{l}\t{%2, %0|%0, %2}"
7032 [(set_attr "type" "alu")
7033 (set_attr "mode" "SI")])
7034
7035 (define_insn "*subsi_3_zext"
7036 [(set (reg 17)
7037 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7038 (match_operand:SI 2 "general_operand" "rim")))
7039 (set (match_operand:DI 0 "register_operand" "=r")
7040 (zero_extend:DI
7041 (minus:SI (match_dup 1)
7042 (match_dup 2))))]
7043 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7044 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7045 "sub{q}\t{%2, %0|%0, %2}"
7046 [(set_attr "type" "alu")
7047 (set_attr "mode" "DI")])
7048
7049 (define_expand "subhi3"
7050 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7051 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7052 (match_operand:HI 2 "general_operand" "")))
7053 (clobber (reg:CC 17))])]
7054 "TARGET_HIMODE_MATH"
7055 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7056
7057 (define_insn "*subhi_1"
7058 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7059 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7060 (match_operand:HI 2 "general_operand" "ri,rm")))
7061 (clobber (reg:CC 17))]
7062 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7063 "sub{w}\t{%2, %0|%0, %2}"
7064 [(set_attr "type" "alu")
7065 (set_attr "mode" "HI")])
7066
7067 (define_insn "*subhi_2"
7068 [(set (reg 17)
7069 (compare
7070 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7071 (match_operand:HI 2 "general_operand" "ri,rm"))
7072 (const_int 0)))
7073 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7074 (minus:HI (match_dup 1) (match_dup 2)))]
7075 "ix86_match_ccmode (insn, CCGOCmode)
7076 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7077 "sub{w}\t{%2, %0|%0, %2}"
7078 [(set_attr "type" "alu")
7079 (set_attr "mode" "HI")])
7080
7081 (define_insn "*subhi_3"
7082 [(set (reg 17)
7083 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7084 (match_operand:HI 2 "general_operand" "ri,rm")))
7085 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7086 (minus:HI (match_dup 1) (match_dup 2)))]
7087 "ix86_match_ccmode (insn, CCmode)
7088 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7089 "sub{w}\t{%2, %0|%0, %2}"
7090 [(set_attr "type" "alu")
7091 (set_attr "mode" "HI")])
7092
7093 (define_expand "subqi3"
7094 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7095 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7096 (match_operand:QI 2 "general_operand" "")))
7097 (clobber (reg:CC 17))])]
7098 "TARGET_QIMODE_MATH"
7099 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7100
7101 (define_insn "*subqi_1"
7102 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7103 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7104 (match_operand:QI 2 "general_operand" "qn,qmn")))
7105 (clobber (reg:CC 17))]
7106 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7107 "sub{b}\t{%2, %0|%0, %2}"
7108 [(set_attr "type" "alu")
7109 (set_attr "mode" "QI")])
7110
7111 (define_insn "*subqi_1_slp"
7112 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7113 (minus:QI (match_dup 0)
7114 (match_operand:QI 1 "general_operand" "qn,qmn")))
7115 (clobber (reg:CC 17))]
7116 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7117 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7118 "sub{b}\t{%1, %0|%0, %1}"
7119 [(set_attr "type" "alu1")
7120 (set_attr "mode" "QI")])
7121
7122 (define_insn "*subqi_2"
7123 [(set (reg 17)
7124 (compare
7125 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7126 (match_operand:QI 2 "general_operand" "qi,qm"))
7127 (const_int 0)))
7128 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7129 (minus:HI (match_dup 1) (match_dup 2)))]
7130 "ix86_match_ccmode (insn, CCGOCmode)
7131 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7132 "sub{b}\t{%2, %0|%0, %2}"
7133 [(set_attr "type" "alu")
7134 (set_attr "mode" "QI")])
7135
7136 (define_insn "*subqi_3"
7137 [(set (reg 17)
7138 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7139 (match_operand:QI 2 "general_operand" "qi,qm")))
7140 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7141 (minus:HI (match_dup 1) (match_dup 2)))]
7142 "ix86_match_ccmode (insn, CCmode)
7143 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7144 "sub{b}\t{%2, %0|%0, %2}"
7145 [(set_attr "type" "alu")
7146 (set_attr "mode" "QI")])
7147
7148 ;; The patterns that match these are at the end of this file.
7149
7150 (define_expand "subxf3"
7151 [(set (match_operand:XF 0 "register_operand" "")
7152 (minus:XF (match_operand:XF 1 "register_operand" "")
7153 (match_operand:XF 2 "register_operand" "")))]
7154 "!TARGET_64BIT && TARGET_80387"
7155 "")
7156
7157 (define_expand "subtf3"
7158 [(set (match_operand:TF 0 "register_operand" "")
7159 (minus:TF (match_operand:TF 1 "register_operand" "")
7160 (match_operand:TF 2 "register_operand" "")))]
7161 "TARGET_80387"
7162 "")
7163
7164 (define_expand "subdf3"
7165 [(set (match_operand:DF 0 "register_operand" "")
7166 (minus:DF (match_operand:DF 1 "register_operand" "")
7167 (match_operand:DF 2 "nonimmediate_operand" "")))]
7168 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7169 "")
7170
7171 (define_expand "subsf3"
7172 [(set (match_operand:SF 0 "register_operand" "")
7173 (minus:SF (match_operand:SF 1 "register_operand" "")
7174 (match_operand:SF 2 "nonimmediate_operand" "")))]
7175 "TARGET_80387 || TARGET_SSE_MATH"
7176 "")
7177 \f
7178 ;; Multiply instructions
7179
7180 (define_expand "muldi3"
7181 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7182 (mult:DI (match_operand:DI 1 "register_operand" "")
7183 (match_operand:DI 2 "x86_64_general_operand" "")))
7184 (clobber (reg:CC 17))])]
7185 "TARGET_64BIT"
7186 "")
7187
7188 (define_insn "*muldi3_1_rex64"
7189 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7190 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7191 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7192 (clobber (reg:CC 17))]
7193 "TARGET_64BIT
7194 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7195 "@
7196 imul{q}\t{%2, %1, %0|%0, %1, %2}
7197 imul{q}\t{%2, %1, %0|%0, %1, %2}
7198 imul{q}\t{%2, %0|%0, %2}"
7199 [(set_attr "type" "imul")
7200 (set_attr "prefix_0f" "0,0,1")
7201 (set (attr "athlon_decode")
7202 (cond [(eq_attr "cpu" "athlon")
7203 (const_string "vector")
7204 (eq_attr "alternative" "1")
7205 (const_string "vector")
7206 (and (eq_attr "alternative" "2")
7207 (match_operand 1 "memory_operand" ""))
7208 (const_string "vector")]
7209 (const_string "direct")))
7210 (set_attr "mode" "DI")])
7211
7212 (define_expand "mulsi3"
7213 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7214 (mult:SI (match_operand:SI 1 "register_operand" "")
7215 (match_operand:SI 2 "general_operand" "")))
7216 (clobber (reg:CC 17))])]
7217 ""
7218 "")
7219
7220 (define_insn "*mulsi3_1"
7221 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7222 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7223 (match_operand:SI 2 "general_operand" "K,i,mr")))
7224 (clobber (reg:CC 17))]
7225 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7226 "@
7227 imul{l}\t{%2, %1, %0|%0, %1, %2}
7228 imul{l}\t{%2, %1, %0|%0, %1, %2}
7229 imul{l}\t{%2, %0|%0, %2}"
7230 [(set_attr "type" "imul")
7231 (set_attr "prefix_0f" "0,0,1")
7232 (set (attr "athlon_decode")
7233 (cond [(eq_attr "cpu" "athlon")
7234 (const_string "vector")
7235 (eq_attr "alternative" "1")
7236 (const_string "vector")
7237 (and (eq_attr "alternative" "2")
7238 (match_operand 1 "memory_operand" ""))
7239 (const_string "vector")]
7240 (const_string "direct")))
7241 (set_attr "mode" "SI")])
7242
7243 (define_insn "*mulsi3_1_zext"
7244 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7245 (zero_extend:DI
7246 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7247 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7248 (clobber (reg:CC 17))]
7249 "TARGET_64BIT
7250 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7251 "@
7252 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7253 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7254 imul{l}\t{%2, %k0|%k0, %2}"
7255 [(set_attr "type" "imul")
7256 (set_attr "prefix_0f" "0,0,1")
7257 (set (attr "athlon_decode")
7258 (cond [(eq_attr "cpu" "athlon")
7259 (const_string "vector")
7260 (eq_attr "alternative" "1")
7261 (const_string "vector")
7262 (and (eq_attr "alternative" "2")
7263 (match_operand 1 "memory_operand" ""))
7264 (const_string "vector")]
7265 (const_string "direct")))
7266 (set_attr "mode" "SI")])
7267
7268 (define_expand "mulhi3"
7269 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7270 (mult:HI (match_operand:HI 1 "register_operand" "")
7271 (match_operand:HI 2 "general_operand" "")))
7272 (clobber (reg:CC 17))])]
7273 "TARGET_HIMODE_MATH"
7274 "")
7275
7276 (define_insn "*mulhi3_1"
7277 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7278 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7279 (match_operand:HI 2 "general_operand" "K,i,mr")))
7280 (clobber (reg:CC 17))]
7281 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7282 "@
7283 imul{w}\t{%2, %1, %0|%0, %1, %2}
7284 imul{w}\t{%2, %1, %0|%0, %1, %2}
7285 imul{w}\t{%2, %0|%0, %2}"
7286 [(set_attr "type" "imul")
7287 (set_attr "prefix_0f" "0,0,1")
7288 (set (attr "athlon_decode")
7289 (cond [(eq_attr "cpu" "athlon")
7290 (const_string "vector")
7291 (eq_attr "alternative" "1,2")
7292 (const_string "vector")]
7293 (const_string "direct")))
7294 (set_attr "mode" "HI")])
7295
7296 (define_expand "mulqi3"
7297 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7298 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7299 (match_operand:QI 2 "register_operand" "")))
7300 (clobber (reg:CC 17))])]
7301 "TARGET_QIMODE_MATH"
7302 "")
7303
7304 (define_insn "*mulqi3_1"
7305 [(set (match_operand:QI 0 "register_operand" "=a")
7306 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7307 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7308 (clobber (reg:CC 17))]
7309 "TARGET_QIMODE_MATH
7310 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7311 "mul{b}\t%2"
7312 [(set_attr "type" "imul")
7313 (set_attr "length_immediate" "0")
7314 (set (attr "athlon_decode")
7315 (if_then_else (eq_attr "cpu" "athlon")
7316 (const_string "vector")
7317 (const_string "direct")))
7318 (set_attr "mode" "QI")])
7319
7320 (define_expand "umulqihi3"
7321 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7322 (mult:HI (zero_extend:HI
7323 (match_operand:QI 1 "nonimmediate_operand" ""))
7324 (zero_extend:HI
7325 (match_operand:QI 2 "register_operand" ""))))
7326 (clobber (reg:CC 17))])]
7327 "TARGET_QIMODE_MATH"
7328 "")
7329
7330 (define_insn "*umulqihi3_1"
7331 [(set (match_operand:HI 0 "register_operand" "=a")
7332 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7333 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7334 (clobber (reg:CC 17))]
7335 "TARGET_QIMODE_MATH
7336 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7337 "mul{b}\t%2"
7338 [(set_attr "type" "imul")
7339 (set_attr "length_immediate" "0")
7340 (set (attr "athlon_decode")
7341 (if_then_else (eq_attr "cpu" "athlon")
7342 (const_string "vector")
7343 (const_string "direct")))
7344 (set_attr "mode" "QI")])
7345
7346 (define_expand "mulqihi3"
7347 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7348 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7349 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7350 (clobber (reg:CC 17))])]
7351 "TARGET_QIMODE_MATH"
7352 "")
7353
7354 (define_insn "*mulqihi3_insn"
7355 [(set (match_operand:HI 0 "register_operand" "=a")
7356 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7357 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7358 (clobber (reg:CC 17))]
7359 "TARGET_QIMODE_MATH
7360 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7361 "imul{b}\t%2"
7362 [(set_attr "type" "imul")
7363 (set_attr "length_immediate" "0")
7364 (set (attr "athlon_decode")
7365 (if_then_else (eq_attr "cpu" "athlon")
7366 (const_string "vector")
7367 (const_string "direct")))
7368 (set_attr "mode" "QI")])
7369
7370 (define_expand "umulditi3"
7371 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7372 (mult:TI (zero_extend:TI
7373 (match_operand:DI 1 "nonimmediate_operand" ""))
7374 (zero_extend:TI
7375 (match_operand:DI 2 "register_operand" ""))))
7376 (clobber (reg:CC 17))])]
7377 "TARGET_64BIT"
7378 "")
7379
7380 (define_insn "*umulditi3_insn"
7381 [(set (match_operand:TI 0 "register_operand" "=A")
7382 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7383 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7384 (clobber (reg:CC 17))]
7385 "TARGET_64BIT
7386 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7387 "mul{q}\t%2"
7388 [(set_attr "type" "imul")
7389 (set_attr "ppro_uops" "few")
7390 (set_attr "length_immediate" "0")
7391 (set (attr "athlon_decode")
7392 (if_then_else (eq_attr "cpu" "athlon")
7393 (const_string "vector")
7394 (const_string "double")))
7395 (set_attr "mode" "DI")])
7396
7397 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7398 (define_expand "umulsidi3"
7399 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7400 (mult:DI (zero_extend:DI
7401 (match_operand:SI 1 "nonimmediate_operand" ""))
7402 (zero_extend:DI
7403 (match_operand:SI 2 "register_operand" ""))))
7404 (clobber (reg:CC 17))])]
7405 "!TARGET_64BIT"
7406 "")
7407
7408 (define_insn "*umulsidi3_insn"
7409 [(set (match_operand:DI 0 "register_operand" "=A")
7410 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7411 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7412 (clobber (reg:CC 17))]
7413 "!TARGET_64BIT
7414 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7415 "mul{l}\t%2"
7416 [(set_attr "type" "imul")
7417 (set_attr "ppro_uops" "few")
7418 (set_attr "length_immediate" "0")
7419 (set (attr "athlon_decode")
7420 (if_then_else (eq_attr "cpu" "athlon")
7421 (const_string "vector")
7422 (const_string "double")))
7423 (set_attr "mode" "SI")])
7424
7425 (define_expand "mulditi3"
7426 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7427 (mult:TI (sign_extend:TI
7428 (match_operand:DI 1 "nonimmediate_operand" ""))
7429 (sign_extend:TI
7430 (match_operand:DI 2 "register_operand" ""))))
7431 (clobber (reg:CC 17))])]
7432 "TARGET_64BIT"
7433 "")
7434
7435 (define_insn "*mulditi3_insn"
7436 [(set (match_operand:TI 0 "register_operand" "=A")
7437 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7438 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7439 (clobber (reg:CC 17))]
7440 "TARGET_64BIT
7441 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7442 "imul{q}\t%2"
7443 [(set_attr "type" "imul")
7444 (set_attr "length_immediate" "0")
7445 (set (attr "athlon_decode")
7446 (if_then_else (eq_attr "cpu" "athlon")
7447 (const_string "vector")
7448 (const_string "double")))
7449 (set_attr "mode" "DI")])
7450
7451 (define_expand "mulsidi3"
7452 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7453 (mult:DI (sign_extend:DI
7454 (match_operand:SI 1 "nonimmediate_operand" ""))
7455 (sign_extend:DI
7456 (match_operand:SI 2 "register_operand" ""))))
7457 (clobber (reg:CC 17))])]
7458 "!TARGET_64BIT"
7459 "")
7460
7461 (define_insn "*mulsidi3_insn"
7462 [(set (match_operand:DI 0 "register_operand" "=A")
7463 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7464 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7465 (clobber (reg:CC 17))]
7466 "!TARGET_64BIT
7467 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7468 "imul{l}\t%2"
7469 [(set_attr "type" "imul")
7470 (set_attr "length_immediate" "0")
7471 (set (attr "athlon_decode")
7472 (if_then_else (eq_attr "cpu" "athlon")
7473 (const_string "vector")
7474 (const_string "double")))
7475 (set_attr "mode" "SI")])
7476
7477 (define_expand "umuldi3_highpart"
7478 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7479 (truncate:DI
7480 (lshiftrt:TI
7481 (mult:TI (zero_extend:TI
7482 (match_operand:DI 1 "nonimmediate_operand" ""))
7483 (zero_extend:TI
7484 (match_operand:DI 2 "register_operand" "")))
7485 (const_int 64))))
7486 (clobber (match_scratch:DI 3 ""))
7487 (clobber (reg:CC 17))])]
7488 "TARGET_64BIT"
7489 "")
7490
7491 (define_insn "*umuldi3_highpart_rex64"
7492 [(set (match_operand:DI 0 "register_operand" "=d")
7493 (truncate:DI
7494 (lshiftrt:TI
7495 (mult:TI (zero_extend:TI
7496 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7497 (zero_extend:TI
7498 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7499 (const_int 64))))
7500 (clobber (match_scratch:DI 3 "=1"))
7501 (clobber (reg:CC 17))]
7502 "TARGET_64BIT
7503 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7504 "mul{q}\t%2"
7505 [(set_attr "type" "imul")
7506 (set_attr "ppro_uops" "few")
7507 (set_attr "length_immediate" "0")
7508 (set (attr "athlon_decode")
7509 (if_then_else (eq_attr "cpu" "athlon")
7510 (const_string "vector")
7511 (const_string "double")))
7512 (set_attr "mode" "DI")])
7513
7514 (define_expand "umulsi3_highpart"
7515 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7516 (truncate:SI
7517 (lshiftrt:DI
7518 (mult:DI (zero_extend:DI
7519 (match_operand:SI 1 "nonimmediate_operand" ""))
7520 (zero_extend:DI
7521 (match_operand:SI 2 "register_operand" "")))
7522 (const_int 32))))
7523 (clobber (match_scratch:SI 3 ""))
7524 (clobber (reg:CC 17))])]
7525 ""
7526 "")
7527
7528 (define_insn "*umulsi3_highpart_insn"
7529 [(set (match_operand:SI 0 "register_operand" "=d")
7530 (truncate:SI
7531 (lshiftrt:DI
7532 (mult:DI (zero_extend:DI
7533 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7534 (zero_extend:DI
7535 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7536 (const_int 32))))
7537 (clobber (match_scratch:SI 3 "=1"))
7538 (clobber (reg:CC 17))]
7539 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7540 "mul{l}\t%2"
7541 [(set_attr "type" "imul")
7542 (set_attr "ppro_uops" "few")
7543 (set_attr "length_immediate" "0")
7544 (set (attr "athlon_decode")
7545 (if_then_else (eq_attr "cpu" "athlon")
7546 (const_string "vector")
7547 (const_string "double")))
7548 (set_attr "mode" "SI")])
7549
7550 (define_insn "*umulsi3_highpart_zext"
7551 [(set (match_operand:DI 0 "register_operand" "=d")
7552 (zero_extend:DI (truncate:SI
7553 (lshiftrt:DI
7554 (mult:DI (zero_extend:DI
7555 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7556 (zero_extend:DI
7557 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7558 (const_int 32)))))
7559 (clobber (match_scratch:SI 3 "=1"))
7560 (clobber (reg:CC 17))]
7561 "TARGET_64BIT
7562 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7563 "mul{l}\t%2"
7564 [(set_attr "type" "imul")
7565 (set_attr "ppro_uops" "few")
7566 (set_attr "length_immediate" "0")
7567 (set (attr "athlon_decode")
7568 (if_then_else (eq_attr "cpu" "athlon")
7569 (const_string "vector")
7570 (const_string "double")))
7571 (set_attr "mode" "SI")])
7572
7573 (define_expand "smuldi3_highpart"
7574 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7575 (truncate:DI
7576 (lshiftrt:TI
7577 (mult:TI (sign_extend:TI
7578 (match_operand:DI 1 "nonimmediate_operand" ""))
7579 (sign_extend:TI
7580 (match_operand:DI 2 "register_operand" "")))
7581 (const_int 64))))
7582 (clobber (match_scratch:DI 3 ""))
7583 (clobber (reg:CC 17))])]
7584 "TARGET_64BIT"
7585 "")
7586
7587 (define_insn "*smuldi3_highpart_rex64"
7588 [(set (match_operand:DI 0 "register_operand" "=d")
7589 (truncate:DI
7590 (lshiftrt:TI
7591 (mult:TI (sign_extend:TI
7592 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7593 (sign_extend:TI
7594 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7595 (const_int 64))))
7596 (clobber (match_scratch:DI 3 "=1"))
7597 (clobber (reg:CC 17))]
7598 "TARGET_64BIT
7599 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7600 "imul{q}\t%2"
7601 [(set_attr "type" "imul")
7602 (set_attr "ppro_uops" "few")
7603 (set (attr "athlon_decode")
7604 (if_then_else (eq_attr "cpu" "athlon")
7605 (const_string "vector")
7606 (const_string "double")))
7607 (set_attr "mode" "DI")])
7608
7609 (define_expand "smulsi3_highpart"
7610 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7611 (truncate:SI
7612 (lshiftrt:DI
7613 (mult:DI (sign_extend:DI
7614 (match_operand:SI 1 "nonimmediate_operand" ""))
7615 (sign_extend:DI
7616 (match_operand:SI 2 "register_operand" "")))
7617 (const_int 32))))
7618 (clobber (match_scratch:SI 3 ""))
7619 (clobber (reg:CC 17))])]
7620 ""
7621 "")
7622
7623 (define_insn "*smulsi3_highpart_insn"
7624 [(set (match_operand:SI 0 "register_operand" "=d")
7625 (truncate:SI
7626 (lshiftrt:DI
7627 (mult:DI (sign_extend:DI
7628 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7629 (sign_extend:DI
7630 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7631 (const_int 32))))
7632 (clobber (match_scratch:SI 3 "=1"))
7633 (clobber (reg:CC 17))]
7634 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7635 "imul{l}\t%2"
7636 [(set_attr "type" "imul")
7637 (set_attr "ppro_uops" "few")
7638 (set (attr "athlon_decode")
7639 (if_then_else (eq_attr "cpu" "athlon")
7640 (const_string "vector")
7641 (const_string "double")))
7642 (set_attr "mode" "SI")])
7643
7644 (define_insn "*smulsi3_highpart_zext"
7645 [(set (match_operand:DI 0 "register_operand" "=d")
7646 (zero_extend:DI (truncate:SI
7647 (lshiftrt:DI
7648 (mult:DI (sign_extend:DI
7649 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7650 (sign_extend:DI
7651 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7652 (const_int 32)))))
7653 (clobber (match_scratch:SI 3 "=1"))
7654 (clobber (reg:CC 17))]
7655 "TARGET_64BIT
7656 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7657 "imul{l}\t%2"
7658 [(set_attr "type" "imul")
7659 (set_attr "ppro_uops" "few")
7660 (set (attr "athlon_decode")
7661 (if_then_else (eq_attr "cpu" "athlon")
7662 (const_string "vector")
7663 (const_string "double")))
7664 (set_attr "mode" "SI")])
7665
7666 ;; The patterns that match these are at the end of this file.
7667
7668 (define_expand "mulxf3"
7669 [(set (match_operand:XF 0 "register_operand" "")
7670 (mult:XF (match_operand:XF 1 "register_operand" "")
7671 (match_operand:XF 2 "register_operand" "")))]
7672 "!TARGET_64BIT && TARGET_80387"
7673 "")
7674
7675 (define_expand "multf3"
7676 [(set (match_operand:TF 0 "register_operand" "")
7677 (mult:TF (match_operand:TF 1 "register_operand" "")
7678 (match_operand:TF 2 "register_operand" "")))]
7679 "TARGET_80387"
7680 "")
7681
7682 (define_expand "muldf3"
7683 [(set (match_operand:DF 0 "register_operand" "")
7684 (mult:DF (match_operand:DF 1 "register_operand" "")
7685 (match_operand:DF 2 "nonimmediate_operand" "")))]
7686 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7687 "")
7688
7689 (define_expand "mulsf3"
7690 [(set (match_operand:SF 0 "register_operand" "")
7691 (mult:SF (match_operand:SF 1 "register_operand" "")
7692 (match_operand:SF 2 "nonimmediate_operand" "")))]
7693 "TARGET_80387 || TARGET_SSE_MATH"
7694 "")
7695 \f
7696 ;; Divide instructions
7697
7698 (define_insn "divqi3"
7699 [(set (match_operand:QI 0 "register_operand" "=a")
7700 (div:QI (match_operand:HI 1 "register_operand" "0")
7701 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7702 (clobber (reg:CC 17))]
7703 "TARGET_QIMODE_MATH"
7704 "idiv{b}\t%2"
7705 [(set_attr "type" "idiv")
7706 (set_attr "mode" "QI")
7707 (set_attr "ppro_uops" "few")])
7708
7709 (define_insn "udivqi3"
7710 [(set (match_operand:QI 0 "register_operand" "=a")
7711 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7712 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7713 (clobber (reg:CC 17))]
7714 "TARGET_QIMODE_MATH"
7715 "div{b}\t%2"
7716 [(set_attr "type" "idiv")
7717 (set_attr "mode" "QI")
7718 (set_attr "ppro_uops" "few")])
7719
7720 ;; The patterns that match these are at the end of this file.
7721
7722 (define_expand "divxf3"
7723 [(set (match_operand:XF 0 "register_operand" "")
7724 (div:XF (match_operand:XF 1 "register_operand" "")
7725 (match_operand:XF 2 "register_operand" "")))]
7726 "!TARGET_64BIT && TARGET_80387"
7727 "")
7728
7729 (define_expand "divtf3"
7730 [(set (match_operand:TF 0 "register_operand" "")
7731 (div:TF (match_operand:TF 1 "register_operand" "")
7732 (match_operand:TF 2 "register_operand" "")))]
7733 "TARGET_80387"
7734 "")
7735
7736 (define_expand "divdf3"
7737 [(set (match_operand:DF 0 "register_operand" "")
7738 (div:DF (match_operand:DF 1 "register_operand" "")
7739 (match_operand:DF 2 "nonimmediate_operand" "")))]
7740 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7741 "")
7742
7743 (define_expand "divsf3"
7744 [(set (match_operand:SF 0 "register_operand" "")
7745 (div:SF (match_operand:SF 1 "register_operand" "")
7746 (match_operand:SF 2 "nonimmediate_operand" "")))]
7747 "TARGET_80387 || TARGET_SSE_MATH"
7748 "")
7749 \f
7750 ;; Remainder instructions.
7751
7752 (define_expand "divmoddi4"
7753 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7754 (div:DI (match_operand:DI 1 "register_operand" "")
7755 (match_operand:DI 2 "nonimmediate_operand" "")))
7756 (set (match_operand:DI 3 "register_operand" "")
7757 (mod:DI (match_dup 1) (match_dup 2)))
7758 (clobber (reg:CC 17))])]
7759 "TARGET_64BIT"
7760 "")
7761
7762 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7763 ;; Penalize eax case slightly because it results in worse scheduling
7764 ;; of code.
7765 (define_insn "*divmoddi4_nocltd_rex64"
7766 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7767 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7768 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7769 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7770 (mod:DI (match_dup 2) (match_dup 3)))
7771 (clobber (reg:CC 17))]
7772 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7773 "#"
7774 [(set_attr "type" "multi")])
7775
7776 (define_insn "*divmoddi4_cltd_rex64"
7777 [(set (match_operand:DI 0 "register_operand" "=a")
7778 (div:DI (match_operand:DI 2 "register_operand" "a")
7779 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7780 (set (match_operand:DI 1 "register_operand" "=&d")
7781 (mod:DI (match_dup 2) (match_dup 3)))
7782 (clobber (reg:CC 17))]
7783 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7784 "#"
7785 [(set_attr "type" "multi")])
7786
7787 (define_insn "*divmoddi_noext_rex64"
7788 [(set (match_operand:DI 0 "register_operand" "=a")
7789 (div:DI (match_operand:DI 1 "register_operand" "0")
7790 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7791 (set (match_operand:DI 3 "register_operand" "=d")
7792 (mod:DI (match_dup 1) (match_dup 2)))
7793 (use (match_operand:DI 4 "register_operand" "3"))
7794 (clobber (reg:CC 17))]
7795 "TARGET_64BIT"
7796 "idiv{q}\t%2"
7797 [(set_attr "type" "idiv")
7798 (set_attr "mode" "DI")
7799 (set_attr "ppro_uops" "few")])
7800
7801 (define_split
7802 [(set (match_operand:DI 0 "register_operand" "")
7803 (div:DI (match_operand:DI 1 "register_operand" "")
7804 (match_operand:DI 2 "nonimmediate_operand" "")))
7805 (set (match_operand:DI 3 "register_operand" "")
7806 (mod:DI (match_dup 1) (match_dup 2)))
7807 (clobber (reg:CC 17))]
7808 "TARGET_64BIT && reload_completed"
7809 [(parallel [(set (match_dup 3)
7810 (ashiftrt:DI (match_dup 4) (const_int 63)))
7811 (clobber (reg:CC 17))])
7812 (parallel [(set (match_dup 0)
7813 (div:DI (reg:DI 0) (match_dup 2)))
7814 (set (match_dup 3)
7815 (mod:DI (reg:DI 0) (match_dup 2)))
7816 (use (match_dup 3))
7817 (clobber (reg:CC 17))])]
7818 {
7819 /* Avoid use of cltd in favor of a mov+shift. */
7820 if (!TARGET_USE_CLTD && !optimize_size)
7821 {
7822 if (true_regnum (operands[1]))
7823 emit_move_insn (operands[0], operands[1]);
7824 else
7825 emit_move_insn (operands[3], operands[1]);
7826 operands[4] = operands[3];
7827 }
7828 else
7829 {
7830 if (true_regnum (operands[1]))
7831 abort();
7832 operands[4] = operands[1];
7833 }
7834 })
7835
7836
7837 (define_expand "divmodsi4"
7838 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7839 (div:SI (match_operand:SI 1 "register_operand" "")
7840 (match_operand:SI 2 "nonimmediate_operand" "")))
7841 (set (match_operand:SI 3 "register_operand" "")
7842 (mod:SI (match_dup 1) (match_dup 2)))
7843 (clobber (reg:CC 17))])]
7844 ""
7845 "")
7846
7847 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7848 ;; Penalize eax case slightly because it results in worse scheduling
7849 ;; of code.
7850 (define_insn "*divmodsi4_nocltd"
7851 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7852 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7853 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7854 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7855 (mod:SI (match_dup 2) (match_dup 3)))
7856 (clobber (reg:CC 17))]
7857 "!optimize_size && !TARGET_USE_CLTD"
7858 "#"
7859 [(set_attr "type" "multi")])
7860
7861 (define_insn "*divmodsi4_cltd"
7862 [(set (match_operand:SI 0 "register_operand" "=a")
7863 (div:SI (match_operand:SI 2 "register_operand" "a")
7864 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7865 (set (match_operand:SI 1 "register_operand" "=&d")
7866 (mod:SI (match_dup 2) (match_dup 3)))
7867 (clobber (reg:CC 17))]
7868 "optimize_size || TARGET_USE_CLTD"
7869 "#"
7870 [(set_attr "type" "multi")])
7871
7872 (define_insn "*divmodsi_noext"
7873 [(set (match_operand:SI 0 "register_operand" "=a")
7874 (div:SI (match_operand:SI 1 "register_operand" "0")
7875 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7876 (set (match_operand:SI 3 "register_operand" "=d")
7877 (mod:SI (match_dup 1) (match_dup 2)))
7878 (use (match_operand:SI 4 "register_operand" "3"))
7879 (clobber (reg:CC 17))]
7880 ""
7881 "idiv{l}\t%2"
7882 [(set_attr "type" "idiv")
7883 (set_attr "mode" "SI")
7884 (set_attr "ppro_uops" "few")])
7885
7886 (define_split
7887 [(set (match_operand:SI 0 "register_operand" "")
7888 (div:SI (match_operand:SI 1 "register_operand" "")
7889 (match_operand:SI 2 "nonimmediate_operand" "")))
7890 (set (match_operand:SI 3 "register_operand" "")
7891 (mod:SI (match_dup 1) (match_dup 2)))
7892 (clobber (reg:CC 17))]
7893 "reload_completed"
7894 [(parallel [(set (match_dup 3)
7895 (ashiftrt:SI (match_dup 4) (const_int 31)))
7896 (clobber (reg:CC 17))])
7897 (parallel [(set (match_dup 0)
7898 (div:SI (reg:SI 0) (match_dup 2)))
7899 (set (match_dup 3)
7900 (mod:SI (reg:SI 0) (match_dup 2)))
7901 (use (match_dup 3))
7902 (clobber (reg:CC 17))])]
7903 {
7904 /* Avoid use of cltd in favor of a mov+shift. */
7905 if (!TARGET_USE_CLTD && !optimize_size)
7906 {
7907 if (true_regnum (operands[1]))
7908 emit_move_insn (operands[0], operands[1]);
7909 else
7910 emit_move_insn (operands[3], operands[1]);
7911 operands[4] = operands[3];
7912 }
7913 else
7914 {
7915 if (true_regnum (operands[1]))
7916 abort();
7917 operands[4] = operands[1];
7918 }
7919 })
7920 ;; %%% Split me.
7921 (define_insn "divmodhi4"
7922 [(set (match_operand:HI 0 "register_operand" "=a")
7923 (div:HI (match_operand:HI 1 "register_operand" "0")
7924 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7925 (set (match_operand:HI 3 "register_operand" "=&d")
7926 (mod:HI (match_dup 1) (match_dup 2)))
7927 (clobber (reg:CC 17))]
7928 "TARGET_HIMODE_MATH"
7929 "cwtd\;idiv{w}\t%2"
7930 [(set_attr "type" "multi")
7931 (set_attr "length_immediate" "0")
7932 (set_attr "mode" "SI")])
7933
7934 (define_insn "udivmoddi4"
7935 [(set (match_operand:DI 0 "register_operand" "=a")
7936 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7937 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7938 (set (match_operand:DI 3 "register_operand" "=&d")
7939 (umod:DI (match_dup 1) (match_dup 2)))
7940 (clobber (reg:CC 17))]
7941 "TARGET_64BIT"
7942 "xor{q}\t%3, %3\;div{q}\t%2"
7943 [(set_attr "type" "multi")
7944 (set_attr "length_immediate" "0")
7945 (set_attr "mode" "DI")])
7946
7947 (define_insn "*udivmoddi4_noext"
7948 [(set (match_operand:DI 0 "register_operand" "=a")
7949 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7950 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7951 (set (match_operand:DI 3 "register_operand" "=d")
7952 (umod:DI (match_dup 1) (match_dup 2)))
7953 (use (match_dup 3))
7954 (clobber (reg:CC 17))]
7955 "TARGET_64BIT"
7956 "div{q}\t%2"
7957 [(set_attr "type" "idiv")
7958 (set_attr "ppro_uops" "few")
7959 (set_attr "mode" "DI")])
7960
7961 (define_split
7962 [(set (match_operand:DI 0 "register_operand" "")
7963 (udiv:DI (match_operand:DI 1 "register_operand" "")
7964 (match_operand:DI 2 "nonimmediate_operand" "")))
7965 (set (match_operand:DI 3 "register_operand" "")
7966 (umod:DI (match_dup 1) (match_dup 2)))
7967 (clobber (reg:CC 17))]
7968 "TARGET_64BIT && reload_completed"
7969 [(set (match_dup 3) (const_int 0))
7970 (parallel [(set (match_dup 0)
7971 (udiv:DI (match_dup 1) (match_dup 2)))
7972 (set (match_dup 3)
7973 (umod:DI (match_dup 1) (match_dup 2)))
7974 (use (match_dup 3))
7975 (clobber (reg:CC 17))])]
7976 "")
7977
7978 (define_insn "udivmodsi4"
7979 [(set (match_operand:SI 0 "register_operand" "=a")
7980 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7981 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7982 (set (match_operand:SI 3 "register_operand" "=&d")
7983 (umod:SI (match_dup 1) (match_dup 2)))
7984 (clobber (reg:CC 17))]
7985 ""
7986 "xor{l}\t%3, %3\;div{l}\t%2"
7987 [(set_attr "type" "multi")
7988 (set_attr "length_immediate" "0")
7989 (set_attr "mode" "SI")])
7990
7991 (define_insn "*udivmodsi4_noext"
7992 [(set (match_operand:SI 0 "register_operand" "=a")
7993 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7994 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7995 (set (match_operand:SI 3 "register_operand" "=d")
7996 (umod:SI (match_dup 1) (match_dup 2)))
7997 (use (match_dup 3))
7998 (clobber (reg:CC 17))]
7999 ""
8000 "div{l}\t%2"
8001 [(set_attr "type" "idiv")
8002 (set_attr "ppro_uops" "few")
8003 (set_attr "mode" "SI")])
8004
8005 (define_split
8006 [(set (match_operand:SI 0 "register_operand" "")
8007 (udiv:SI (match_operand:SI 1 "register_operand" "")
8008 (match_operand:SI 2 "nonimmediate_operand" "")))
8009 (set (match_operand:SI 3 "register_operand" "")
8010 (umod:SI (match_dup 1) (match_dup 2)))
8011 (clobber (reg:CC 17))]
8012 "reload_completed"
8013 [(set (match_dup 3) (const_int 0))
8014 (parallel [(set (match_dup 0)
8015 (udiv:SI (match_dup 1) (match_dup 2)))
8016 (set (match_dup 3)
8017 (umod:SI (match_dup 1) (match_dup 2)))
8018 (use (match_dup 3))
8019 (clobber (reg:CC 17))])]
8020 "")
8021
8022 (define_expand "udivmodhi4"
8023 [(set (match_dup 4) (const_int 0))
8024 (parallel [(set (match_operand:HI 0 "register_operand" "")
8025 (udiv:HI (match_operand:HI 1 "register_operand" "")
8026 (match_operand:HI 2 "nonimmediate_operand" "")))
8027 (set (match_operand:HI 3 "register_operand" "")
8028 (umod:HI (match_dup 1) (match_dup 2)))
8029 (use (match_dup 4))
8030 (clobber (reg:CC 17))])]
8031 "TARGET_HIMODE_MATH"
8032 "operands[4] = gen_reg_rtx (HImode);")
8033
8034 (define_insn "*udivmodhi_noext"
8035 [(set (match_operand:HI 0 "register_operand" "=a")
8036 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8037 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8038 (set (match_operand:HI 3 "register_operand" "=d")
8039 (umod:HI (match_dup 1) (match_dup 2)))
8040 (use (match_operand:HI 4 "register_operand" "3"))
8041 (clobber (reg:CC 17))]
8042 ""
8043 "div{w}\t%2"
8044 [(set_attr "type" "idiv")
8045 (set_attr "mode" "HI")
8046 (set_attr "ppro_uops" "few")])
8047
8048 ;; We can not use div/idiv for double division, because it causes
8049 ;; "division by zero" on the overflow and that's not what we expect
8050 ;; from truncate. Because true (non truncating) double division is
8051 ;; never generated, we can't create this insn anyway.
8052 ;
8053 ;(define_insn ""
8054 ; [(set (match_operand:SI 0 "register_operand" "=a")
8055 ; (truncate:SI
8056 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8057 ; (zero_extend:DI
8058 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8059 ; (set (match_operand:SI 3 "register_operand" "=d")
8060 ; (truncate:SI
8061 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8062 ; (clobber (reg:CC 17))]
8063 ; ""
8064 ; "div{l}\t{%2, %0|%0, %2}"
8065 ; [(set_attr "type" "idiv")
8066 ; (set_attr "ppro_uops" "few")])
8067 \f
8068 ;;- Logical AND instructions
8069
8070 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8071 ;; Note that this excludes ah.
8072
8073 (define_insn "*testdi_1_rex64"
8074 [(set (reg 17)
8075 (compare
8076 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8077 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
8078 (const_int 0)))]
8079 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8080 "@
8081 test{l}\t{%k1, %k0|%k0, %k1}
8082 test{l}\t{%k1, %k0|%k0, %k1}
8083 test{q}\t{%1, %0|%0, %1}
8084 test{q}\t{%1, %0|%0, %1}
8085 test{q}\t{%1, %0|%0, %1}"
8086 [(set_attr "type" "test")
8087 (set_attr "modrm" "0,1,0,1,1")
8088 (set_attr "mode" "SI,SI,DI,DI,DI")
8089 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8090
8091 (define_insn "testsi_1"
8092 [(set (reg 17)
8093 (compare
8094 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8095 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
8096 (const_int 0)))]
8097 "ix86_match_ccmode (insn, CCNOmode)"
8098 "test{l}\t{%1, %0|%0, %1}"
8099 [(set_attr "type" "test")
8100 (set_attr "modrm" "0,1,1")
8101 (set_attr "mode" "SI")
8102 (set_attr "pent_pair" "uv,np,uv")])
8103
8104 (define_expand "testsi_ccno_1"
8105 [(set (reg:CCNO 17)
8106 (compare:CCNO
8107 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8108 (match_operand:SI 1 "nonmemory_operand" ""))
8109 (const_int 0)))]
8110 ""
8111 "")
8112
8113 (define_insn "*testhi_1"
8114 [(set (reg 17)
8115 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8116 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
8117 (const_int 0)))]
8118 "ix86_match_ccmode (insn, CCNOmode)"
8119 "test{w}\t{%1, %0|%0, %1}"
8120 [(set_attr "type" "test")
8121 (set_attr "modrm" "0,1,1")
8122 (set_attr "mode" "HI")
8123 (set_attr "pent_pair" "uv,np,uv")])
8124
8125 (define_expand "testqi_ccz_1"
8126 [(set (reg:CCZ 17)
8127 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8128 (match_operand:QI 1 "nonmemory_operand" ""))
8129 (const_int 0)))]
8130 ""
8131 "")
8132
8133 (define_insn "*testqi_1"
8134 [(set (reg 17)
8135 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8136 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
8137 (const_int 0)))]
8138 "ix86_match_ccmode (insn, CCNOmode)"
8139 {
8140 if (which_alternative == 3)
8141 {
8142 if (GET_CODE (operands[1]) == CONST_INT
8143 && (INTVAL (operands[1]) & 0xffffff00))
8144 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8145 return "test{l}\t{%1, %k0|%k0, %1}";
8146 }
8147 return "test{b}\t{%1, %0|%0, %1}";
8148 }
8149 [(set_attr "type" "test")
8150 (set_attr "modrm" "0,1,1,1")
8151 (set_attr "mode" "QI,QI,QI,SI")
8152 (set_attr "pent_pair" "uv,np,uv,np")])
8153
8154 (define_expand "testqi_ext_ccno_0"
8155 [(set (reg:CCNO 17)
8156 (compare:CCNO
8157 (and:SI
8158 (zero_extract:SI
8159 (match_operand 0 "ext_register_operand" "")
8160 (const_int 8)
8161 (const_int 8))
8162 (match_operand 1 "const_int_operand" ""))
8163 (const_int 0)))]
8164 ""
8165 "")
8166
8167 (define_insn "*testqi_ext_0"
8168 [(set (reg 17)
8169 (compare
8170 (and:SI
8171 (zero_extract:SI
8172 (match_operand 0 "ext_register_operand" "Q")
8173 (const_int 8)
8174 (const_int 8))
8175 (match_operand 1 "const_int_operand" "n"))
8176 (const_int 0)))]
8177 "ix86_match_ccmode (insn, CCNOmode)"
8178 "test{b}\t{%1, %h0|%h0, %1}"
8179 [(set_attr "type" "test")
8180 (set_attr "mode" "QI")
8181 (set_attr "length_immediate" "1")
8182 (set_attr "pent_pair" "np")])
8183
8184 (define_insn "*testqi_ext_1"
8185 [(set (reg 17)
8186 (compare
8187 (and:SI
8188 (zero_extract:SI
8189 (match_operand 0 "ext_register_operand" "Q")
8190 (const_int 8)
8191 (const_int 8))
8192 (zero_extend:SI
8193 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
8194 (const_int 0)))]
8195 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8196 "test{b}\t{%1, %h0|%h0, %1}"
8197 [(set_attr "type" "test")
8198 (set_attr "mode" "QI")])
8199
8200 (define_insn "*testqi_ext_1_rex64"
8201 [(set (reg 17)
8202 (compare
8203 (and:SI
8204 (zero_extract:SI
8205 (match_operand 0 "ext_register_operand" "Q")
8206 (const_int 8)
8207 (const_int 8))
8208 (zero_extend:SI
8209 (match_operand:QI 1 "register_operand" "Q")))
8210 (const_int 0)))]
8211 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8212 "test{b}\t{%1, %h0|%h0, %1}"
8213 [(set_attr "type" "test")
8214 (set_attr "mode" "QI")])
8215
8216 (define_insn "*testqi_ext_2"
8217 [(set (reg 17)
8218 (compare
8219 (and:SI
8220 (zero_extract:SI
8221 (match_operand 0 "ext_register_operand" "Q")
8222 (const_int 8)
8223 (const_int 8))
8224 (zero_extract:SI
8225 (match_operand 1 "ext_register_operand" "Q")
8226 (const_int 8)
8227 (const_int 8)))
8228 (const_int 0)))]
8229 "ix86_match_ccmode (insn, CCNOmode)"
8230 "test{b}\t{%h1, %h0|%h0, %h1}"
8231 [(set_attr "type" "test")
8232 (set_attr "mode" "QI")])
8233
8234 ;; Combine likes to form bit extractions for some tests. Humor it.
8235 (define_insn "*testqi_ext_3"
8236 [(set (reg 17)
8237 (compare (zero_extract:SI
8238 (match_operand 0 "nonimmediate_operand" "rm")
8239 (match_operand:SI 1 "const_int_operand" "")
8240 (match_operand:SI 2 "const_int_operand" ""))
8241 (const_int 0)))]
8242 "ix86_match_ccmode (insn, CCNOmode)
8243 && (GET_MODE (operands[0]) == SImode
8244 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8245 || GET_MODE (operands[0]) == HImode
8246 || GET_MODE (operands[0]) == QImode)"
8247 "#")
8248
8249 (define_insn "*testqi_ext_3_rex64"
8250 [(set (reg 17)
8251 (compare (zero_extract:DI
8252 (match_operand 0 "nonimmediate_operand" "rm")
8253 (match_operand:DI 1 "const_int_operand" "")
8254 (match_operand:DI 2 "const_int_operand" ""))
8255 (const_int 0)))]
8256 "TARGET_64BIT
8257 && ix86_match_ccmode (insn, CCNOmode)
8258 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8259 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8260 /* Ensure that resulting mask is zero or sign extended operand. */
8261 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8262 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8263 && INTVAL (operands[1]) > 32))
8264 && (GET_MODE (operands[0]) == SImode
8265 || GET_MODE (operands[0]) == DImode
8266 || GET_MODE (operands[0]) == HImode
8267 || GET_MODE (operands[0]) == QImode)"
8268 "#")
8269
8270 (define_split
8271 [(set (reg 17)
8272 (compare (zero_extract
8273 (match_operand 0 "nonimmediate_operand" "")
8274 (match_operand 1 "const_int_operand" "")
8275 (match_operand 2 "const_int_operand" ""))
8276 (const_int 0)))]
8277 "ix86_match_ccmode (insn, CCNOmode)"
8278 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8279 {
8280 HOST_WIDE_INT len = INTVAL (operands[1]);
8281 HOST_WIDE_INT pos = INTVAL (operands[2]);
8282 HOST_WIDE_INT mask;
8283 enum machine_mode mode, submode;
8284
8285 mode = GET_MODE (operands[0]);
8286 if (GET_CODE (operands[0]) == MEM)
8287 {
8288 /* ??? Combine likes to put non-volatile mem extractions in QImode
8289 no matter the size of the test. So find a mode that works. */
8290 if (! MEM_VOLATILE_P (operands[0]))
8291 {
8292 mode = smallest_mode_for_size (pos + len, MODE_INT);
8293 operands[0] = adjust_address (operands[0], mode, 0);
8294 }
8295 }
8296 else if (GET_CODE (operands[0]) == SUBREG
8297 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8298 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8299 && pos + len <= GET_MODE_BITSIZE (submode))
8300 {
8301 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8302 mode = submode;
8303 operands[0] = SUBREG_REG (operands[0]);
8304 }
8305 else if (mode == HImode && pos + len <= 8)
8306 {
8307 /* Small HImode tests can be converted to QImode. */
8308 mode = QImode;
8309 operands[0] = gen_lowpart (QImode, operands[0]);
8310 }
8311
8312 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8313 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8314
8315 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8316 })
8317
8318 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8319 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8320 ;; this is relatively important trick.
8321 ;; Do the conversion only post-reload to avoid limiting of the register class
8322 ;; to QI regs.
8323 (define_split
8324 [(set (reg 17)
8325 (compare
8326 (and (match_operand 0 "register_operand" "")
8327 (match_operand 1 "const_int_operand" ""))
8328 (const_int 0)))]
8329 "reload_completed
8330 && QI_REG_P (operands[0])
8331 && ((ix86_match_ccmode (insn, CCZmode)
8332 && !(INTVAL (operands[1]) & ~(255 << 8)))
8333 || (ix86_match_ccmode (insn, CCNOmode)
8334 && !(INTVAL (operands[1]) & ~(127 << 8))))
8335 && GET_MODE (operands[0]) != QImode"
8336 [(set (reg:CCNO 17)
8337 (compare:CCNO
8338 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8339 (match_dup 1))
8340 (const_int 0)))]
8341 "operands[0] = gen_lowpart (SImode, operands[0]);
8342 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8343
8344 (define_split
8345 [(set (reg 17)
8346 (compare
8347 (and (match_operand 0 "nonimmediate_operand" "")
8348 (match_operand 1 "const_int_operand" ""))
8349 (const_int 0)))]
8350 "reload_completed
8351 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8352 && ((ix86_match_ccmode (insn, CCZmode)
8353 && !(INTVAL (operands[1]) & ~255))
8354 || (ix86_match_ccmode (insn, CCNOmode)
8355 && !(INTVAL (operands[1]) & ~127)))
8356 && GET_MODE (operands[0]) != QImode"
8357 [(set (reg:CCNO 17)
8358 (compare:CCNO
8359 (and:QI (match_dup 0)
8360 (match_dup 1))
8361 (const_int 0)))]
8362 "operands[0] = gen_lowpart (QImode, operands[0]);
8363 operands[1] = gen_lowpart (QImode, operands[1]);")
8364
8365
8366 ;; %%% This used to optimize known byte-wide and operations to memory,
8367 ;; and sometimes to QImode registers. If this is considered useful,
8368 ;; it should be done with splitters.
8369
8370 (define_expand "anddi3"
8371 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8372 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8373 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8374 (clobber (reg:CC 17))]
8375 "TARGET_64BIT"
8376 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8377
8378 (define_insn "*anddi_1_rex64"
8379 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8380 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8381 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8382 (clobber (reg:CC 17))]
8383 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8384 {
8385 switch (get_attr_type (insn))
8386 {
8387 case TYPE_IMOVX:
8388 {
8389 enum machine_mode mode;
8390
8391 if (GET_CODE (operands[2]) != CONST_INT)
8392 abort ();
8393 if (INTVAL (operands[2]) == 0xff)
8394 mode = QImode;
8395 else if (INTVAL (operands[2]) == 0xffff)
8396 mode = HImode;
8397 else
8398 abort ();
8399
8400 operands[1] = gen_lowpart (mode, operands[1]);
8401 if (mode == QImode)
8402 return "movz{bq|x}\t{%1,%0|%0, %1}";
8403 else
8404 return "movz{wq|x}\t{%1,%0|%0, %1}";
8405 }
8406
8407 default:
8408 if (! rtx_equal_p (operands[0], operands[1]))
8409 abort ();
8410 if (get_attr_mode (insn) == MODE_SI)
8411 return "and{l}\t{%k2, %k0|%k0, %k2}";
8412 else
8413 return "and{q}\t{%2, %0|%0, %2}";
8414 }
8415 }
8416 [(set_attr "type" "alu,alu,alu,imovx")
8417 (set_attr "length_immediate" "*,*,*,0")
8418 (set_attr "mode" "SI,DI,DI,DI")])
8419
8420 (define_insn "*anddi_2"
8421 [(set (reg 17)
8422 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8423 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8424 (const_int 0)))
8425 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8426 (and:DI (match_dup 1) (match_dup 2)))]
8427 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8428 && ix86_binary_operator_ok (AND, DImode, operands)"
8429 "@
8430 and{l}\t{%k2, %k0|%k0, %k2}
8431 and{q}\t{%2, %0|%0, %2}
8432 and{q}\t{%2, %0|%0, %2}"
8433 [(set_attr "type" "alu")
8434 (set_attr "mode" "SI,DI,DI")])
8435
8436 (define_expand "andsi3"
8437 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8438 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8439 (match_operand:SI 2 "general_operand" "")))
8440 (clobber (reg:CC 17))]
8441 ""
8442 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8443
8444 (define_insn "*andsi_1"
8445 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8446 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8447 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8448 (clobber (reg:CC 17))]
8449 "ix86_binary_operator_ok (AND, SImode, operands)"
8450 {
8451 switch (get_attr_type (insn))
8452 {
8453 case TYPE_IMOVX:
8454 {
8455 enum machine_mode mode;
8456
8457 if (GET_CODE (operands[2]) != CONST_INT)
8458 abort ();
8459 if (INTVAL (operands[2]) == 0xff)
8460 mode = QImode;
8461 else if (INTVAL (operands[2]) == 0xffff)
8462 mode = HImode;
8463 else
8464 abort ();
8465
8466 operands[1] = gen_lowpart (mode, operands[1]);
8467 if (mode == QImode)
8468 return "movz{bl|x}\t{%1,%0|%0, %1}";
8469 else
8470 return "movz{wl|x}\t{%1,%0|%0, %1}";
8471 }
8472
8473 default:
8474 if (! rtx_equal_p (operands[0], operands[1]))
8475 abort ();
8476 return "and{l}\t{%2, %0|%0, %2}";
8477 }
8478 }
8479 [(set_attr "type" "alu,alu,imovx")
8480 (set_attr "length_immediate" "*,*,0")
8481 (set_attr "mode" "SI")])
8482
8483 (define_split
8484 [(set (match_operand 0 "register_operand" "")
8485 (and (match_dup 0)
8486 (const_int -65536)))
8487 (clobber (reg:CC 17))]
8488 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8489 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8490 "operands[1] = gen_lowpart (HImode, operands[0]);")
8491
8492 (define_split
8493 [(set (match_operand 0 "ext_register_operand" "")
8494 (and (match_dup 0)
8495 (const_int -256)))
8496 (clobber (reg:CC 17))]
8497 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8498 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8499 "operands[1] = gen_lowpart (QImode, operands[0]);")
8500
8501 (define_split
8502 [(set (match_operand 0 "ext_register_operand" "")
8503 (and (match_dup 0)
8504 (const_int -65281)))
8505 (clobber (reg:CC 17))]
8506 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8507 [(parallel [(set (zero_extract:SI (match_dup 0)
8508 (const_int 8)
8509 (const_int 8))
8510 (xor:SI
8511 (zero_extract:SI (match_dup 0)
8512 (const_int 8)
8513 (const_int 8))
8514 (zero_extract:SI (match_dup 0)
8515 (const_int 8)
8516 (const_int 8))))
8517 (clobber (reg:CC 17))])]
8518 "operands[0] = gen_lowpart (SImode, operands[0]);")
8519
8520 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8521 (define_insn "*andsi_1_zext"
8522 [(set (match_operand:DI 0 "register_operand" "=r")
8523 (zero_extend:DI
8524 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8525 (match_operand:SI 2 "general_operand" "rim"))))
8526 (clobber (reg:CC 17))]
8527 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8528 "and{l}\t{%2, %k0|%k0, %2}"
8529 [(set_attr "type" "alu")
8530 (set_attr "mode" "SI")])
8531
8532 (define_insn "*andsi_2"
8533 [(set (reg 17)
8534 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8535 (match_operand:SI 2 "general_operand" "rim,ri"))
8536 (const_int 0)))
8537 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8538 (and:SI (match_dup 1) (match_dup 2)))]
8539 "ix86_match_ccmode (insn, CCNOmode)
8540 && ix86_binary_operator_ok (AND, SImode, operands)"
8541 "and{l}\t{%2, %0|%0, %2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "mode" "SI")])
8544
8545 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8546 (define_insn "*andsi_2_zext"
8547 [(set (reg 17)
8548 (compare (and: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 (and:SI (match_dup 1) (match_dup 2))))]
8553 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8554 && ix86_binary_operator_ok (AND, SImode, operands)"
8555 "and{l}\t{%2, %k0|%k0, %2}"
8556 [(set_attr "type" "alu")
8557 (set_attr "mode" "SI")])
8558
8559 (define_expand "andhi3"
8560 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8561 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8562 (match_operand:HI 2 "general_operand" "")))
8563 (clobber (reg:CC 17))]
8564 "TARGET_HIMODE_MATH"
8565 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8566
8567 (define_insn "*andhi_1"
8568 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8569 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8570 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8571 (clobber (reg:CC 17))]
8572 "ix86_binary_operator_ok (AND, HImode, operands)"
8573 {
8574 switch (get_attr_type (insn))
8575 {
8576 case TYPE_IMOVX:
8577 if (GET_CODE (operands[2]) != CONST_INT)
8578 abort ();
8579 if (INTVAL (operands[2]) == 0xff)
8580 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8581 abort ();
8582
8583 default:
8584 if (! rtx_equal_p (operands[0], operands[1]))
8585 abort ();
8586
8587 return "and{w}\t{%2, %0|%0, %2}";
8588 }
8589 }
8590 [(set_attr "type" "alu,alu,imovx")
8591 (set_attr "length_immediate" "*,*,0")
8592 (set_attr "mode" "HI,HI,SI")])
8593
8594 (define_insn "*andhi_2"
8595 [(set (reg 17)
8596 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8597 (match_operand:HI 2 "general_operand" "rim,ri"))
8598 (const_int 0)))
8599 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8600 (and:HI (match_dup 1) (match_dup 2)))]
8601 "ix86_match_ccmode (insn, CCNOmode)
8602 && ix86_binary_operator_ok (AND, HImode, operands)"
8603 "and{w}\t{%2, %0|%0, %2}"
8604 [(set_attr "type" "alu")
8605 (set_attr "mode" "HI")])
8606
8607 (define_expand "andqi3"
8608 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8609 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8610 (match_operand:QI 2 "general_operand" "")))
8611 (clobber (reg:CC 17))]
8612 "TARGET_QIMODE_MATH"
8613 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8614
8615 ;; %%% Potential partial reg stall on alternative 2. What to do?
8616 (define_insn "*andqi_1"
8617 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8618 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8619 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8620 (clobber (reg:CC 17))]
8621 "ix86_binary_operator_ok (AND, QImode, operands)"
8622 "@
8623 and{b}\t{%2, %0|%0, %2}
8624 and{b}\t{%2, %0|%0, %2}
8625 and{l}\t{%k2, %k0|%k0, %k2}"
8626 [(set_attr "type" "alu")
8627 (set_attr "mode" "QI,QI,SI")])
8628
8629 (define_insn "*andqi_1_slp"
8630 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8631 (and:QI (match_dup 0)
8632 (match_operand:QI 1 "general_operand" "qi,qmi")))
8633 (clobber (reg:CC 17))]
8634 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8635 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8636 "and{b}\t{%1, %0|%0, %1}"
8637 [(set_attr "type" "alu1")
8638 (set_attr "mode" "QI")])
8639
8640 (define_insn "*andqi_2"
8641 [(set (reg 17)
8642 (compare (and:QI
8643 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8644 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8645 (const_int 0)))
8646 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8647 (and:QI (match_dup 1) (match_dup 2)))]
8648 "ix86_match_ccmode (insn, CCNOmode)
8649 && ix86_binary_operator_ok (AND, QImode, operands)"
8650 {
8651 if (which_alternative == 2)
8652 {
8653 if (GET_CODE (operands[2]) == CONST_INT
8654 && (INTVAL (operands[2]) & 0xffffff00))
8655 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8656 return "and{l}\t{%2, %k0|%k0, %2}";
8657 }
8658 return "and{b}\t{%2, %0|%0, %2}";
8659 }
8660 [(set_attr "type" "alu")
8661 (set_attr "mode" "QI,QI,SI")])
8662
8663 (define_insn "*andqi_2_slp"
8664 [(set (reg 17)
8665 (compare (and:QI
8666 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8667 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8668 (const_int 0)))
8669 (set (strict_low_part (match_dup 0))
8670 (and:QI (match_dup 0) (match_dup 1)))]
8671 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8672 && ix86_match_ccmode (insn, CCNOmode)
8673 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8674 "and{b}\t{%1, %0|%0, %1}"
8675 [(set_attr "type" "alu1")
8676 (set_attr "mode" "QI")])
8677
8678 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8679 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8680 ;; for a QImode operand, which of course failed.
8681
8682 (define_insn "andqi_ext_0"
8683 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8684 (const_int 8)
8685 (const_int 8))
8686 (and:SI
8687 (zero_extract:SI
8688 (match_operand 1 "ext_register_operand" "0")
8689 (const_int 8)
8690 (const_int 8))
8691 (match_operand 2 "const_int_operand" "n")))
8692 (clobber (reg:CC 17))]
8693 ""
8694 "and{b}\t{%2, %h0|%h0, %2}"
8695 [(set_attr "type" "alu")
8696 (set_attr "length_immediate" "1")
8697 (set_attr "mode" "QI")])
8698
8699 ;; Generated by peephole translating test to and. This shows up
8700 ;; often in fp comparisons.
8701
8702 (define_insn "*andqi_ext_0_cc"
8703 [(set (reg 17)
8704 (compare
8705 (and:SI
8706 (zero_extract:SI
8707 (match_operand 1 "ext_register_operand" "0")
8708 (const_int 8)
8709 (const_int 8))
8710 (match_operand 2 "const_int_operand" "n"))
8711 (const_int 0)))
8712 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8713 (const_int 8)
8714 (const_int 8))
8715 (and:SI
8716 (zero_extract:SI
8717 (match_dup 1)
8718 (const_int 8)
8719 (const_int 8))
8720 (match_dup 2)))]
8721 "ix86_match_ccmode (insn, CCNOmode)"
8722 "and{b}\t{%2, %h0|%h0, %2}"
8723 [(set_attr "type" "alu")
8724 (set_attr "length_immediate" "1")
8725 (set_attr "mode" "QI")])
8726
8727 (define_insn "*andqi_ext_1"
8728 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8729 (const_int 8)
8730 (const_int 8))
8731 (and:SI
8732 (zero_extract:SI
8733 (match_operand 1 "ext_register_operand" "0")
8734 (const_int 8)
8735 (const_int 8))
8736 (zero_extend:SI
8737 (match_operand:QI 2 "general_operand" "Qm"))))
8738 (clobber (reg:CC 17))]
8739 "!TARGET_64BIT"
8740 "and{b}\t{%2, %h0|%h0, %2}"
8741 [(set_attr "type" "alu")
8742 (set_attr "length_immediate" "0")
8743 (set_attr "mode" "QI")])
8744
8745 (define_insn "*andqi_ext_1_rex64"
8746 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8747 (const_int 8)
8748 (const_int 8))
8749 (and:SI
8750 (zero_extract:SI
8751 (match_operand 1 "ext_register_operand" "0")
8752 (const_int 8)
8753 (const_int 8))
8754 (zero_extend:SI
8755 (match_operand 2 "ext_register_operand" "Q"))))
8756 (clobber (reg:CC 17))]
8757 "TARGET_64BIT"
8758 "and{b}\t{%2, %h0|%h0, %2}"
8759 [(set_attr "type" "alu")
8760 (set_attr "length_immediate" "0")
8761 (set_attr "mode" "QI")])
8762
8763 (define_insn "*andqi_ext_2"
8764 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8765 (const_int 8)
8766 (const_int 8))
8767 (and:SI
8768 (zero_extract:SI
8769 (match_operand 1 "ext_register_operand" "%0")
8770 (const_int 8)
8771 (const_int 8))
8772 (zero_extract:SI
8773 (match_operand 2 "ext_register_operand" "Q")
8774 (const_int 8)
8775 (const_int 8))))
8776 (clobber (reg:CC 17))]
8777 ""
8778 "and{b}\t{%h2, %h0|%h0, %h2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "length_immediate" "0")
8781 (set_attr "mode" "QI")])
8782
8783 ;; Convert wide AND instructions with immediate operand to shorter QImode
8784 ;; equivalents when possible.
8785 ;; Don't do the splitting with memory operands, since it introduces risk
8786 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8787 ;; for size, but that can (should?) be handled by generic code instead.
8788 (define_split
8789 [(set (match_operand 0 "register_operand" "")
8790 (and (match_operand 1 "register_operand" "")
8791 (match_operand 2 "const_int_operand" "")))
8792 (clobber (reg:CC 17))]
8793 "reload_completed
8794 && QI_REG_P (operands[0])
8795 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8796 && !(~INTVAL (operands[2]) & ~(255 << 8))
8797 && GET_MODE (operands[0]) != QImode"
8798 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8799 (and:SI (zero_extract:SI (match_dup 1)
8800 (const_int 8) (const_int 8))
8801 (match_dup 2)))
8802 (clobber (reg:CC 17))])]
8803 "operands[0] = gen_lowpart (SImode, operands[0]);
8804 operands[1] = gen_lowpart (SImode, operands[1]);
8805 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8806
8807 ;; Since AND can be encoded with sign extended immediate, this is only
8808 ;; profitable when 7th bit is not set.
8809 (define_split
8810 [(set (match_operand 0 "register_operand" "")
8811 (and (match_operand 1 "general_operand" "")
8812 (match_operand 2 "const_int_operand" "")))
8813 (clobber (reg:CC 17))]
8814 "reload_completed
8815 && ANY_QI_REG_P (operands[0])
8816 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8817 && !(~INTVAL (operands[2]) & ~255)
8818 && !(INTVAL (operands[2]) & 128)
8819 && GET_MODE (operands[0]) != QImode"
8820 [(parallel [(set (strict_low_part (match_dup 0))
8821 (and:QI (match_dup 1)
8822 (match_dup 2)))
8823 (clobber (reg:CC 17))])]
8824 "operands[0] = gen_lowpart (QImode, operands[0]);
8825 operands[1] = gen_lowpart (QImode, operands[1]);
8826 operands[2] = gen_lowpart (QImode, operands[2]);")
8827 \f
8828 ;; Logical inclusive OR instructions
8829
8830 ;; %%% This used to optimize known byte-wide and operations to memory.
8831 ;; If this is considered useful, it should be done with splitters.
8832
8833 (define_expand "iordi3"
8834 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8835 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8836 (match_operand:DI 2 "x86_64_general_operand" "")))
8837 (clobber (reg:CC 17))]
8838 "TARGET_64BIT"
8839 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8840
8841 (define_insn "*iordi_1_rex64"
8842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8843 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8844 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8845 (clobber (reg:CC 17))]
8846 "TARGET_64BIT
8847 && ix86_binary_operator_ok (IOR, DImode, operands)"
8848 "or{q}\t{%2, %0|%0, %2}"
8849 [(set_attr "type" "alu")
8850 (set_attr "mode" "DI")])
8851
8852 (define_insn "*iordi_2_rex64"
8853 [(set (reg 17)
8854 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8855 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8856 (const_int 0)))
8857 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8858 (ior:DI (match_dup 1) (match_dup 2)))]
8859 "TARGET_64BIT
8860 && ix86_match_ccmode (insn, CCNOmode)
8861 && ix86_binary_operator_ok (IOR, DImode, operands)"
8862 "or{q}\t{%2, %0|%0, %2}"
8863 [(set_attr "type" "alu")
8864 (set_attr "mode" "DI")])
8865
8866 (define_insn "*iordi_3_rex64"
8867 [(set (reg 17)
8868 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8869 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8870 (const_int 0)))
8871 (clobber (match_scratch:DI 0 "=r"))]
8872 "TARGET_64BIT
8873 && ix86_match_ccmode (insn, CCNOmode)
8874 && ix86_binary_operator_ok (IOR, DImode, operands)"
8875 "or{q}\t{%2, %0|%0, %2}"
8876 [(set_attr "type" "alu")
8877 (set_attr "mode" "DI")])
8878
8879
8880 (define_expand "iorsi3"
8881 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8882 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8883 (match_operand:SI 2 "general_operand" "")))
8884 (clobber (reg:CC 17))]
8885 ""
8886 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8887
8888 (define_insn "*iorsi_1"
8889 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8890 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8891 (match_operand:SI 2 "general_operand" "ri,rmi")))
8892 (clobber (reg:CC 17))]
8893 "ix86_binary_operator_ok (IOR, SImode, operands)"
8894 "or{l}\t{%2, %0|%0, %2}"
8895 [(set_attr "type" "alu")
8896 (set_attr "mode" "SI")])
8897
8898 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8899 (define_insn "*iorsi_1_zext"
8900 [(set (match_operand:DI 0 "register_operand" "=rm")
8901 (zero_extend:DI
8902 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8903 (match_operand:SI 2 "general_operand" "rim"))))
8904 (clobber (reg:CC 17))]
8905 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8906 "or{l}\t{%2, %k0|%k0, %2}"
8907 [(set_attr "type" "alu")
8908 (set_attr "mode" "SI")])
8909
8910 (define_insn "*iorsi_1_zext_imm"
8911 [(set (match_operand:DI 0 "register_operand" "=rm")
8912 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8913 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8914 (clobber (reg:CC 17))]
8915 "TARGET_64BIT"
8916 "or{l}\t{%2, %k0|%k0, %2}"
8917 [(set_attr "type" "alu")
8918 (set_attr "mode" "SI")])
8919
8920 (define_insn "*iorsi_2"
8921 [(set (reg 17)
8922 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8923 (match_operand:SI 2 "general_operand" "rim,ri"))
8924 (const_int 0)))
8925 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8926 (ior:SI (match_dup 1) (match_dup 2)))]
8927 "ix86_match_ccmode (insn, CCNOmode)
8928 && ix86_binary_operator_ok (IOR, SImode, operands)"
8929 "or{l}\t{%2, %0|%0, %2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "mode" "SI")])
8932
8933 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8934 ;; ??? Special case for immediate operand is missing - it is tricky.
8935 (define_insn "*iorsi_2_zext"
8936 [(set (reg 17)
8937 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8938 (match_operand:SI 2 "general_operand" "rim"))
8939 (const_int 0)))
8940 (set (match_operand:DI 0 "register_operand" "=r")
8941 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8942 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8943 && ix86_binary_operator_ok (IOR, SImode, operands)"
8944 "or{l}\t{%2, %k0|%k0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "SI")])
8947
8948 (define_insn "*iorsi_2_zext_imm"
8949 [(set (reg 17)
8950 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8951 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8952 (const_int 0)))
8953 (set (match_operand:DI 0 "register_operand" "=r")
8954 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8955 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8956 && ix86_binary_operator_ok (IOR, SImode, operands)"
8957 "or{l}\t{%2, %k0|%k0, %2}"
8958 [(set_attr "type" "alu")
8959 (set_attr "mode" "SI")])
8960
8961 (define_insn "*iorsi_3"
8962 [(set (reg 17)
8963 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8964 (match_operand:SI 2 "general_operand" "rim"))
8965 (const_int 0)))
8966 (clobber (match_scratch:SI 0 "=r"))]
8967 "ix86_match_ccmode (insn, CCNOmode)
8968 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8969 "or{l}\t{%2, %0|%0, %2}"
8970 [(set_attr "type" "alu")
8971 (set_attr "mode" "SI")])
8972
8973 (define_expand "iorhi3"
8974 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8975 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8976 (match_operand:HI 2 "general_operand" "")))
8977 (clobber (reg:CC 17))]
8978 "TARGET_HIMODE_MATH"
8979 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8980
8981 (define_insn "*iorhi_1"
8982 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8983 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8984 (match_operand:HI 2 "general_operand" "rmi,ri")))
8985 (clobber (reg:CC 17))]
8986 "ix86_binary_operator_ok (IOR, HImode, operands)"
8987 "or{w}\t{%2, %0|%0, %2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "HI")])
8990
8991 (define_insn "*iorhi_2"
8992 [(set (reg 17)
8993 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8994 (match_operand:HI 2 "general_operand" "rim,ri"))
8995 (const_int 0)))
8996 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8997 (ior:HI (match_dup 1) (match_dup 2)))]
8998 "ix86_match_ccmode (insn, CCNOmode)
8999 && ix86_binary_operator_ok (IOR, HImode, operands)"
9000 "or{w}\t{%2, %0|%0, %2}"
9001 [(set_attr "type" "alu")
9002 (set_attr "mode" "HI")])
9003
9004 (define_insn "*iorhi_3"
9005 [(set (reg 17)
9006 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9007 (match_operand:HI 2 "general_operand" "rim"))
9008 (const_int 0)))
9009 (clobber (match_scratch:HI 0 "=r"))]
9010 "ix86_match_ccmode (insn, CCNOmode)
9011 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9012 "or{w}\t{%2, %0|%0, %2}"
9013 [(set_attr "type" "alu")
9014 (set_attr "mode" "HI")])
9015
9016 (define_expand "iorqi3"
9017 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9018 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9019 (match_operand:QI 2 "general_operand" "")))
9020 (clobber (reg:CC 17))]
9021 "TARGET_QIMODE_MATH"
9022 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9023
9024 ;; %%% Potential partial reg stall on alternative 2. What to do?
9025 (define_insn "*iorqi_1"
9026 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9027 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9028 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9029 (clobber (reg:CC 17))]
9030 "ix86_binary_operator_ok (IOR, QImode, operands)"
9031 "@
9032 or{b}\t{%2, %0|%0, %2}
9033 or{b}\t{%2, %0|%0, %2}
9034 or{l}\t{%k2, %k0|%k0, %k2}"
9035 [(set_attr "type" "alu")
9036 (set_attr "mode" "QI,QI,SI")])
9037
9038 (define_insn "*iorqi_1_slp"
9039 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9040 (ior:QI (match_dup 0)
9041 (match_operand:QI 1 "general_operand" "qmi,qi")))
9042 (clobber (reg:CC 17))]
9043 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9044 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9045 "or{b}\t{%1, %0|%0, %1}"
9046 [(set_attr "type" "alu1")
9047 (set_attr "mode" "QI")])
9048
9049 (define_insn "*iorqi_2"
9050 [(set (reg 17)
9051 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9052 (match_operand:QI 2 "general_operand" "qim,qi"))
9053 (const_int 0)))
9054 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9055 (ior:QI (match_dup 1) (match_dup 2)))]
9056 "ix86_match_ccmode (insn, CCNOmode)
9057 && ix86_binary_operator_ok (IOR, QImode, operands)"
9058 "or{b}\t{%2, %0|%0, %2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "QI")])
9061
9062 (define_insn "*iorqi_2_slp"
9063 [(set (reg 17)
9064 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9065 (match_operand:QI 1 "general_operand" "qim,qi"))
9066 (const_int 0)))
9067 (set (strict_low_part (match_dup 0))
9068 (ior:QI (match_dup 0) (match_dup 1)))]
9069 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9070 && ix86_match_ccmode (insn, CCNOmode)
9071 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9072 "or{b}\t{%1, %0|%0, %1}"
9073 [(set_attr "type" "alu1")
9074 (set_attr "mode" "QI")])
9075
9076 (define_insn "*iorqi_3"
9077 [(set (reg 17)
9078 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9079 (match_operand:QI 2 "general_operand" "qim"))
9080 (const_int 0)))
9081 (clobber (match_scratch:QI 0 "=q"))]
9082 "ix86_match_ccmode (insn, CCNOmode)
9083 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9084 "or{b}\t{%2, %0|%0, %2}"
9085 [(set_attr "type" "alu")
9086 (set_attr "mode" "QI")])
9087
9088 (define_insn "iorqi_ext_0"
9089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9090 (const_int 8)
9091 (const_int 8))
9092 (ior:SI
9093 (zero_extract:SI
9094 (match_operand 1 "ext_register_operand" "0")
9095 (const_int 8)
9096 (const_int 8))
9097 (match_operand 2 "const_int_operand" "n")))
9098 (clobber (reg:CC 17))]
9099 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9100 "or{b}\t{%2, %h0|%h0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "length_immediate" "1")
9103 (set_attr "mode" "QI")])
9104
9105 (define_insn "*iorqi_ext_1"
9106 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9107 (const_int 8)
9108 (const_int 8))
9109 (ior:SI
9110 (zero_extract:SI
9111 (match_operand 1 "ext_register_operand" "0")
9112 (const_int 8)
9113 (const_int 8))
9114 (zero_extend:SI
9115 (match_operand:QI 2 "general_operand" "Qm"))))
9116 (clobber (reg:CC 17))]
9117 "!TARGET_64BIT
9118 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9119 "or{b}\t{%2, %h0|%h0, %2}"
9120 [(set_attr "type" "alu")
9121 (set_attr "length_immediate" "0")
9122 (set_attr "mode" "QI")])
9123
9124 (define_insn "*iorqi_ext_1_rex64"
9125 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9126 (const_int 8)
9127 (const_int 8))
9128 (ior:SI
9129 (zero_extract:SI
9130 (match_operand 1 "ext_register_operand" "0")
9131 (const_int 8)
9132 (const_int 8))
9133 (zero_extend:SI
9134 (match_operand 2 "ext_register_operand" "Q"))))
9135 (clobber (reg:CC 17))]
9136 "TARGET_64BIT
9137 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138 "or{b}\t{%2, %h0|%h0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "length_immediate" "0")
9141 (set_attr "mode" "QI")])
9142
9143 (define_insn "*iorqi_ext_2"
9144 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (const_int 8)
9146 (const_int 8))
9147 (ior:SI
9148 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9149 (const_int 8)
9150 (const_int 8))
9151 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9152 (const_int 8)
9153 (const_int 8))))
9154 (clobber (reg:CC 17))]
9155 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9156 "ior{b}\t{%h2, %h0|%h0, %h2}"
9157 [(set_attr "type" "alu")
9158 (set_attr "length_immediate" "0")
9159 (set_attr "mode" "QI")])
9160
9161 (define_split
9162 [(set (match_operand 0 "register_operand" "")
9163 (ior (match_operand 1 "register_operand" "")
9164 (match_operand 2 "const_int_operand" "")))
9165 (clobber (reg:CC 17))]
9166 "reload_completed
9167 && QI_REG_P (operands[0])
9168 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9169 && !(INTVAL (operands[2]) & ~(255 << 8))
9170 && GET_MODE (operands[0]) != QImode"
9171 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9172 (ior:SI (zero_extract:SI (match_dup 1)
9173 (const_int 8) (const_int 8))
9174 (match_dup 2)))
9175 (clobber (reg:CC 17))])]
9176 "operands[0] = gen_lowpart (SImode, operands[0]);
9177 operands[1] = gen_lowpart (SImode, operands[1]);
9178 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9179
9180 ;; Since OR can be encoded with sign extended immediate, this is only
9181 ;; profitable when 7th bit is set.
9182 (define_split
9183 [(set (match_operand 0 "register_operand" "")
9184 (ior (match_operand 1 "general_operand" "")
9185 (match_operand 2 "const_int_operand" "")))
9186 (clobber (reg:CC 17))]
9187 "reload_completed
9188 && ANY_QI_REG_P (operands[0])
9189 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9190 && !(INTVAL (operands[2]) & ~255)
9191 && (INTVAL (operands[2]) & 128)
9192 && GET_MODE (operands[0]) != QImode"
9193 [(parallel [(set (strict_low_part (match_dup 0))
9194 (ior:QI (match_dup 1)
9195 (match_dup 2)))
9196 (clobber (reg:CC 17))])]
9197 "operands[0] = gen_lowpart (QImode, operands[0]);
9198 operands[1] = gen_lowpart (QImode, operands[1]);
9199 operands[2] = gen_lowpart (QImode, operands[2]);")
9200 \f
9201 ;; Logical XOR instructions
9202
9203 ;; %%% This used to optimize known byte-wide and operations to memory.
9204 ;; If this is considered useful, it should be done with splitters.
9205
9206 (define_expand "xordi3"
9207 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9208 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9209 (match_operand:DI 2 "x86_64_general_operand" "")))
9210 (clobber (reg:CC 17))]
9211 "TARGET_64BIT"
9212 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9213
9214 (define_insn "*xordi_1_rex64"
9215 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9216 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9217 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9218 (clobber (reg:CC 17))]
9219 "TARGET_64BIT
9220 && ix86_binary_operator_ok (XOR, DImode, operands)"
9221 "@
9222 xor{q}\t{%2, %0|%0, %2}
9223 xor{q}\t{%2, %0|%0, %2}"
9224 [(set_attr "type" "alu")
9225 (set_attr "mode" "DI,DI")])
9226
9227 (define_insn "*xordi_2_rex64"
9228 [(set (reg 17)
9229 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9230 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9231 (const_int 0)))
9232 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9233 (xor:DI (match_dup 1) (match_dup 2)))]
9234 "TARGET_64BIT
9235 && ix86_match_ccmode (insn, CCNOmode)
9236 && ix86_binary_operator_ok (XOR, DImode, operands)"
9237 "@
9238 xor{q}\t{%2, %0|%0, %2}
9239 xor{q}\t{%2, %0|%0, %2}"
9240 [(set_attr "type" "alu")
9241 (set_attr "mode" "DI,DI")])
9242
9243 (define_insn "*xordi_3_rex64"
9244 [(set (reg 17)
9245 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9246 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9247 (const_int 0)))
9248 (clobber (match_scratch:DI 0 "=r"))]
9249 "TARGET_64BIT
9250 && ix86_match_ccmode (insn, CCNOmode)
9251 && ix86_binary_operator_ok (XOR, DImode, operands)"
9252 "xor{q}\t{%2, %0|%0, %2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "mode" "DI")])
9255
9256 (define_expand "xorsi3"
9257 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9258 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9259 (match_operand:SI 2 "general_operand" "")))
9260 (clobber (reg:CC 17))]
9261 ""
9262 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9263
9264 (define_insn "*xorsi_1"
9265 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9266 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9267 (match_operand:SI 2 "general_operand" "ri,rm")))
9268 (clobber (reg:CC 17))]
9269 "ix86_binary_operator_ok (XOR, SImode, operands)"
9270 "xor{l}\t{%2, %0|%0, %2}"
9271 [(set_attr "type" "alu")
9272 (set_attr "mode" "SI")])
9273
9274 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9275 ;; Add speccase for immediates
9276 (define_insn "*xorsi_1_zext"
9277 [(set (match_operand:DI 0 "register_operand" "=r")
9278 (zero_extend:DI
9279 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9280 (match_operand:SI 2 "general_operand" "rim"))))
9281 (clobber (reg:CC 17))]
9282 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9283 "xor{l}\t{%2, %k0|%k0, %2}"
9284 [(set_attr "type" "alu")
9285 (set_attr "mode" "SI")])
9286
9287 (define_insn "*xorsi_1_zext_imm"
9288 [(set (match_operand:DI 0 "register_operand" "=r")
9289 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9290 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9291 (clobber (reg:CC 17))]
9292 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9293 "xor{l}\t{%2, %k0|%k0, %2}"
9294 [(set_attr "type" "alu")
9295 (set_attr "mode" "SI")])
9296
9297 (define_insn "*xorsi_2"
9298 [(set (reg 17)
9299 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9300 (match_operand:SI 2 "general_operand" "rim,ri"))
9301 (const_int 0)))
9302 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9303 (xor:SI (match_dup 1) (match_dup 2)))]
9304 "ix86_match_ccmode (insn, CCNOmode)
9305 && ix86_binary_operator_ok (XOR, SImode, operands)"
9306 "xor{l}\t{%2, %0|%0, %2}"
9307 [(set_attr "type" "alu")
9308 (set_attr "mode" "SI")])
9309
9310 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9311 ;; ??? Special case for immediate operand is missing - it is tricky.
9312 (define_insn "*xorsi_2_zext"
9313 [(set (reg 17)
9314 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9315 (match_operand:SI 2 "general_operand" "rim"))
9316 (const_int 0)))
9317 (set (match_operand:DI 0 "register_operand" "=r")
9318 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9319 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9320 && ix86_binary_operator_ok (XOR, SImode, operands)"
9321 "xor{l}\t{%2, %k0|%k0, %2}"
9322 [(set_attr "type" "alu")
9323 (set_attr "mode" "SI")])
9324
9325 (define_insn "*xorsi_2_zext_imm"
9326 [(set (reg 17)
9327 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9328 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9329 (const_int 0)))
9330 (set (match_operand:DI 0 "register_operand" "=r")
9331 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9332 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9333 && ix86_binary_operator_ok (XOR, SImode, operands)"
9334 "xor{l}\t{%2, %k0|%k0, %2}"
9335 [(set_attr "type" "alu")
9336 (set_attr "mode" "SI")])
9337
9338 (define_insn "*xorsi_3"
9339 [(set (reg 17)
9340 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9341 (match_operand:SI 2 "general_operand" "rim"))
9342 (const_int 0)))
9343 (clobber (match_scratch:SI 0 "=r"))]
9344 "ix86_match_ccmode (insn, CCNOmode)
9345 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9346 "xor{l}\t{%2, %0|%0, %2}"
9347 [(set_attr "type" "alu")
9348 (set_attr "mode" "SI")])
9349
9350 (define_expand "xorhi3"
9351 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9352 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9353 (match_operand:HI 2 "general_operand" "")))
9354 (clobber (reg:CC 17))]
9355 "TARGET_HIMODE_MATH"
9356 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9357
9358 (define_insn "*xorhi_1"
9359 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9360 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9361 (match_operand:HI 2 "general_operand" "rmi,ri")))
9362 (clobber (reg:CC 17))]
9363 "ix86_binary_operator_ok (XOR, HImode, operands)"
9364 "xor{w}\t{%2, %0|%0, %2}"
9365 [(set_attr "type" "alu")
9366 (set_attr "mode" "HI")])
9367
9368 (define_insn "*xorhi_2"
9369 [(set (reg 17)
9370 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9371 (match_operand:HI 2 "general_operand" "rim,ri"))
9372 (const_int 0)))
9373 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9374 (xor:HI (match_dup 1) (match_dup 2)))]
9375 "ix86_match_ccmode (insn, CCNOmode)
9376 && ix86_binary_operator_ok (XOR, HImode, operands)"
9377 "xor{w}\t{%2, %0|%0, %2}"
9378 [(set_attr "type" "alu")
9379 (set_attr "mode" "HI")])
9380
9381 (define_insn "*xorhi_3"
9382 [(set (reg 17)
9383 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9384 (match_operand:HI 2 "general_operand" "rim"))
9385 (const_int 0)))
9386 (clobber (match_scratch:HI 0 "=r"))]
9387 "ix86_match_ccmode (insn, CCNOmode)
9388 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9389 "xor{w}\t{%2, %0|%0, %2}"
9390 [(set_attr "type" "alu")
9391 (set_attr "mode" "HI")])
9392
9393 (define_expand "xorqi3"
9394 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9395 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9396 (match_operand:QI 2 "general_operand" "")))
9397 (clobber (reg:CC 17))]
9398 "TARGET_QIMODE_MATH"
9399 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9400
9401 ;; %%% Potential partial reg stall on alternative 2. What to do?
9402 (define_insn "*xorqi_1"
9403 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9404 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9405 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9406 (clobber (reg:CC 17))]
9407 "ix86_binary_operator_ok (XOR, QImode, operands)"
9408 "@
9409 xor{b}\t{%2, %0|%0, %2}
9410 xor{b}\t{%2, %0|%0, %2}
9411 xor{l}\t{%k2, %k0|%k0, %k2}"
9412 [(set_attr "type" "alu")
9413 (set_attr "mode" "QI,QI,SI")])
9414
9415 (define_insn "*xorqi_1_slp"
9416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9417 (xor:QI (match_dup 0)
9418 (match_operand:QI 1 "general_operand" "qi,qmi")))
9419 (clobber (reg:CC 17))]
9420 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9421 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9422 "xor{b}\t{%1, %0|%0, %1}"
9423 [(set_attr "type" "alu1")
9424 (set_attr "mode" "QI")])
9425
9426 (define_insn "xorqi_ext_0"
9427 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9428 (const_int 8)
9429 (const_int 8))
9430 (xor:SI
9431 (zero_extract:SI
9432 (match_operand 1 "ext_register_operand" "0")
9433 (const_int 8)
9434 (const_int 8))
9435 (match_operand 2 "const_int_operand" "n")))
9436 (clobber (reg:CC 17))]
9437 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9438 "xor{b}\t{%2, %h0|%h0, %2}"
9439 [(set_attr "type" "alu")
9440 (set_attr "length_immediate" "1")
9441 (set_attr "mode" "QI")])
9442
9443 (define_insn "*xorqi_ext_1"
9444 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9445 (const_int 8)
9446 (const_int 8))
9447 (xor:SI
9448 (zero_extract:SI
9449 (match_operand 1 "ext_register_operand" "0")
9450 (const_int 8)
9451 (const_int 8))
9452 (zero_extend:SI
9453 (match_operand:QI 2 "general_operand" "Qm"))))
9454 (clobber (reg:CC 17))]
9455 "!TARGET_64BIT
9456 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9457 "xor{b}\t{%2, %h0|%h0, %2}"
9458 [(set_attr "type" "alu")
9459 (set_attr "length_immediate" "0")
9460 (set_attr "mode" "QI")])
9461
9462 (define_insn "*xorqi_ext_1_rex64"
9463 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9464 (const_int 8)
9465 (const_int 8))
9466 (xor:SI
9467 (zero_extract:SI
9468 (match_operand 1 "ext_register_operand" "0")
9469 (const_int 8)
9470 (const_int 8))
9471 (zero_extend:SI
9472 (match_operand 2 "ext_register_operand" "Q"))))
9473 (clobber (reg:CC 17))]
9474 "TARGET_64BIT
9475 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9476 "xor{b}\t{%2, %h0|%h0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "length_immediate" "0")
9479 (set_attr "mode" "QI")])
9480
9481 (define_insn "*xorqi_ext_2"
9482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483 (const_int 8)
9484 (const_int 8))
9485 (xor:SI
9486 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9487 (const_int 8)
9488 (const_int 8))
9489 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9490 (const_int 8)
9491 (const_int 8))))
9492 (clobber (reg:CC 17))]
9493 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9494 "xor{b}\t{%h2, %h0|%h0, %h2}"
9495 [(set_attr "type" "alu")
9496 (set_attr "length_immediate" "0")
9497 (set_attr "mode" "QI")])
9498
9499 (define_insn "*xorqi_cc_1"
9500 [(set (reg 17)
9501 (compare
9502 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9503 (match_operand:QI 2 "general_operand" "qim,qi"))
9504 (const_int 0)))
9505 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9506 (xor:QI (match_dup 1) (match_dup 2)))]
9507 "ix86_match_ccmode (insn, CCNOmode)
9508 && ix86_binary_operator_ok (XOR, QImode, operands)"
9509 "xor{b}\t{%2, %0|%0, %2}"
9510 [(set_attr "type" "alu")
9511 (set_attr "mode" "QI")])
9512
9513 (define_insn "*xorqi_2_slp"
9514 [(set (reg 17)
9515 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9516 (match_operand:QI 1 "general_operand" "qim,qi"))
9517 (const_int 0)))
9518 (set (strict_low_part (match_dup 0))
9519 (xor:QI (match_dup 0) (match_dup 1)))]
9520 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9521 && ix86_match_ccmode (insn, CCNOmode)
9522 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9523 "xor{b}\t{%1, %0|%0, %1}"
9524 [(set_attr "type" "alu1")
9525 (set_attr "mode" "QI")])
9526
9527 (define_insn "*xorqi_cc_2"
9528 [(set (reg 17)
9529 (compare
9530 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9531 (match_operand:QI 2 "general_operand" "qim"))
9532 (const_int 0)))
9533 (clobber (match_scratch:QI 0 "=q"))]
9534 "ix86_match_ccmode (insn, CCNOmode)
9535 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9536 "xor{b}\t{%2, %0|%0, %2}"
9537 [(set_attr "type" "alu")
9538 (set_attr "mode" "QI")])
9539
9540 (define_insn "*xorqi_cc_ext_1"
9541 [(set (reg 17)
9542 (compare
9543 (xor:SI
9544 (zero_extract:SI
9545 (match_operand 1 "ext_register_operand" "0")
9546 (const_int 8)
9547 (const_int 8))
9548 (match_operand:QI 2 "general_operand" "qmn"))
9549 (const_int 0)))
9550 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9551 (const_int 8)
9552 (const_int 8))
9553 (xor:SI
9554 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9555 (match_dup 2)))]
9556 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9557 "xor{b}\t{%2, %h0|%h0, %2}"
9558 [(set_attr "type" "alu")
9559 (set_attr "mode" "QI")])
9560
9561 (define_insn "*xorqi_cc_ext_1_rex64"
9562 [(set (reg 17)
9563 (compare
9564 (xor:SI
9565 (zero_extract:SI
9566 (match_operand 1 "ext_register_operand" "0")
9567 (const_int 8)
9568 (const_int 8))
9569 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9570 (const_int 0)))
9571 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9572 (const_int 8)
9573 (const_int 8))
9574 (xor:SI
9575 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9576 (match_dup 2)))]
9577 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9578 "xor{b}\t{%2, %h0|%h0, %2}"
9579 [(set_attr "type" "alu")
9580 (set_attr "mode" "QI")])
9581
9582 (define_expand "xorqi_cc_ext_1"
9583 [(parallel [
9584 (set (reg:CCNO 17)
9585 (compare:CCNO
9586 (xor:SI
9587 (zero_extract:SI
9588 (match_operand 1 "ext_register_operand" "")
9589 (const_int 8)
9590 (const_int 8))
9591 (match_operand:QI 2 "general_operand" ""))
9592 (const_int 0)))
9593 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9594 (const_int 8)
9595 (const_int 8))
9596 (xor:SI
9597 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9598 (match_dup 2)))])]
9599 ""
9600 "")
9601
9602 (define_split
9603 [(set (match_operand 0 "register_operand" "")
9604 (xor (match_operand 1 "register_operand" "")
9605 (match_operand 2 "const_int_operand" "")))
9606 (clobber (reg:CC 17))]
9607 "reload_completed
9608 && QI_REG_P (operands[0])
9609 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9610 && !(INTVAL (operands[2]) & ~(255 << 8))
9611 && GET_MODE (operands[0]) != QImode"
9612 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9613 (xor:SI (zero_extract:SI (match_dup 1)
9614 (const_int 8) (const_int 8))
9615 (match_dup 2)))
9616 (clobber (reg:CC 17))])]
9617 "operands[0] = gen_lowpart (SImode, operands[0]);
9618 operands[1] = gen_lowpart (SImode, operands[1]);
9619 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9620
9621 ;; Since XOR can be encoded with sign extended immediate, this is only
9622 ;; profitable when 7th bit is set.
9623 (define_split
9624 [(set (match_operand 0 "register_operand" "")
9625 (xor (match_operand 1 "general_operand" "")
9626 (match_operand 2 "const_int_operand" "")))
9627 (clobber (reg:CC 17))]
9628 "reload_completed
9629 && ANY_QI_REG_P (operands[0])
9630 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9631 && !(INTVAL (operands[2]) & ~255)
9632 && (INTVAL (operands[2]) & 128)
9633 && GET_MODE (operands[0]) != QImode"
9634 [(parallel [(set (strict_low_part (match_dup 0))
9635 (xor:QI (match_dup 1)
9636 (match_dup 2)))
9637 (clobber (reg:CC 17))])]
9638 "operands[0] = gen_lowpart (QImode, operands[0]);
9639 operands[1] = gen_lowpart (QImode, operands[1]);
9640 operands[2] = gen_lowpart (QImode, operands[2]);")
9641 \f
9642 ;; Negation instructions
9643
9644 (define_expand "negdi2"
9645 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9646 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9647 (clobber (reg:CC 17))])]
9648 ""
9649 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9650
9651 (define_insn "*negdi2_1"
9652 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9653 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9654 (clobber (reg:CC 17))]
9655 "!TARGET_64BIT
9656 && ix86_unary_operator_ok (NEG, DImode, operands)"
9657 "#")
9658
9659 (define_split
9660 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9661 (neg:DI (match_operand:DI 1 "general_operand" "")))
9662 (clobber (reg:CC 17))]
9663 "!TARGET_64BIT && reload_completed"
9664 [(parallel
9665 [(set (reg:CCZ 17)
9666 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9667 (set (match_dup 0) (neg:SI (match_dup 2)))])
9668 (parallel
9669 [(set (match_dup 1)
9670 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9671 (match_dup 3))
9672 (const_int 0)))
9673 (clobber (reg:CC 17))])
9674 (parallel
9675 [(set (match_dup 1)
9676 (neg:SI (match_dup 1)))
9677 (clobber (reg:CC 17))])]
9678 "split_di (operands+1, 1, operands+2, operands+3);
9679 split_di (operands+0, 1, operands+0, operands+1);")
9680
9681 (define_insn "*negdi2_1_rex64"
9682 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9683 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9684 (clobber (reg:CC 17))]
9685 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9686 "neg{q}\t%0"
9687 [(set_attr "type" "negnot")
9688 (set_attr "mode" "DI")])
9689
9690 ;; The problem with neg is that it does not perform (compare x 0),
9691 ;; it really performs (compare 0 x), which leaves us with the zero
9692 ;; flag being the only useful item.
9693
9694 (define_insn "*negdi2_cmpz_rex64"
9695 [(set (reg:CCZ 17)
9696 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9697 (const_int 0)))
9698 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9699 (neg:DI (match_dup 1)))]
9700 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9701 "neg{q}\t%0"
9702 [(set_attr "type" "negnot")
9703 (set_attr "mode" "DI")])
9704
9705
9706 (define_expand "negsi2"
9707 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9708 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9709 (clobber (reg:CC 17))])]
9710 ""
9711 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9712
9713 (define_insn "*negsi2_1"
9714 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9715 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9716 (clobber (reg:CC 17))]
9717 "ix86_unary_operator_ok (NEG, SImode, operands)"
9718 "neg{l}\t%0"
9719 [(set_attr "type" "negnot")
9720 (set_attr "mode" "SI")])
9721
9722 ;; Combine is quite creative about this pattern.
9723 (define_insn "*negsi2_1_zext"
9724 [(set (match_operand:DI 0 "register_operand" "=r")
9725 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9726 (const_int 32)))
9727 (const_int 32)))
9728 (clobber (reg:CC 17))]
9729 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9730 "neg{l}\t%k0"
9731 [(set_attr "type" "negnot")
9732 (set_attr "mode" "SI")])
9733
9734 ;; The problem with neg is that it does not perform (compare x 0),
9735 ;; it really performs (compare 0 x), which leaves us with the zero
9736 ;; flag being the only useful item.
9737
9738 (define_insn "*negsi2_cmpz"
9739 [(set (reg:CCZ 17)
9740 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9741 (const_int 0)))
9742 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9743 (neg:SI (match_dup 1)))]
9744 "ix86_unary_operator_ok (NEG, SImode, operands)"
9745 "neg{l}\t%0"
9746 [(set_attr "type" "negnot")
9747 (set_attr "mode" "SI")])
9748
9749 (define_insn "*negsi2_cmpz_zext"
9750 [(set (reg:CCZ 17)
9751 (compare:CCZ (lshiftrt:DI
9752 (neg:DI (ashift:DI
9753 (match_operand:DI 1 "register_operand" "0")
9754 (const_int 32)))
9755 (const_int 32))
9756 (const_int 0)))
9757 (set (match_operand:DI 0 "register_operand" "=r")
9758 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9759 (const_int 32)))
9760 (const_int 32)))]
9761 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9762 "neg{l}\t%k0"
9763 [(set_attr "type" "negnot")
9764 (set_attr "mode" "SI")])
9765
9766 (define_expand "neghi2"
9767 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9768 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9769 (clobber (reg:CC 17))])]
9770 "TARGET_HIMODE_MATH"
9771 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9772
9773 (define_insn "*neghi2_1"
9774 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9775 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9776 (clobber (reg:CC 17))]
9777 "ix86_unary_operator_ok (NEG, HImode, operands)"
9778 "neg{w}\t%0"
9779 [(set_attr "type" "negnot")
9780 (set_attr "mode" "HI")])
9781
9782 (define_insn "*neghi2_cmpz"
9783 [(set (reg:CCZ 17)
9784 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9785 (const_int 0)))
9786 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9787 (neg:HI (match_dup 1)))]
9788 "ix86_unary_operator_ok (NEG, HImode, operands)"
9789 "neg{w}\t%0"
9790 [(set_attr "type" "negnot")
9791 (set_attr "mode" "HI")])
9792
9793 (define_expand "negqi2"
9794 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9795 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9796 (clobber (reg:CC 17))])]
9797 "TARGET_QIMODE_MATH"
9798 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9799
9800 (define_insn "*negqi2_1"
9801 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9802 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9803 (clobber (reg:CC 17))]
9804 "ix86_unary_operator_ok (NEG, QImode, operands)"
9805 "neg{b}\t%0"
9806 [(set_attr "type" "negnot")
9807 (set_attr "mode" "QI")])
9808
9809 (define_insn "*negqi2_cmpz"
9810 [(set (reg:CCZ 17)
9811 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9812 (const_int 0)))
9813 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9814 (neg:QI (match_dup 1)))]
9815 "ix86_unary_operator_ok (NEG, QImode, operands)"
9816 "neg{b}\t%0"
9817 [(set_attr "type" "negnot")
9818 (set_attr "mode" "QI")])
9819
9820 ;; Changing of sign for FP values is doable using integer unit too.
9821
9822 (define_expand "negsf2"
9823 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9824 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9825 (clobber (reg:CC 17))])]
9826 "TARGET_80387"
9827 "if (TARGET_SSE)
9828 {
9829 /* In case operand is in memory, we will not use SSE. */
9830 if (memory_operand (operands[0], VOIDmode)
9831 && rtx_equal_p (operands[0], operands[1]))
9832 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9833 else
9834 {
9835 /* Using SSE is tricky, since we need bitwise negation of -0
9836 in register. */
9837 rtx reg = gen_reg_rtx (SFmode);
9838 rtx dest = operands[0];
9839 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9840
9841 operands[1] = force_reg (SFmode, operands[1]);
9842 operands[0] = force_reg (SFmode, operands[0]);
9843 reg = force_reg (V4SFmode,
9844 gen_rtx_CONST_VECTOR (V4SFmode,
9845 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9846 CONST0_RTX (SFmode),
9847 CONST0_RTX (SFmode))));
9848 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9849 if (dest != operands[0])
9850 emit_move_insn (dest, operands[0]);
9851 }
9852 DONE;
9853 }
9854 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9855
9856 (define_insn "negsf2_memory"
9857 [(set (match_operand:SF 0 "memory_operand" "=m")
9858 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9859 (clobber (reg:CC 17))]
9860 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9861 "#")
9862
9863 (define_insn "negsf2_ifs"
9864 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9865 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9866 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9867 (clobber (reg:CC 17))]
9868 "TARGET_SSE
9869 && (reload_in_progress || reload_completed
9870 || (register_operand (operands[0], VOIDmode)
9871 && register_operand (operands[1], VOIDmode)))"
9872 "#")
9873
9874 (define_split
9875 [(set (match_operand:SF 0 "memory_operand" "")
9876 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9877 (use (match_operand:SF 2 "" ""))
9878 (clobber (reg:CC 17))]
9879 ""
9880 [(parallel [(set (match_dup 0)
9881 (neg:SF (match_dup 1)))
9882 (clobber (reg:CC 17))])])
9883
9884 (define_split
9885 [(set (match_operand:SF 0 "register_operand" "")
9886 (neg:SF (match_operand:SF 1 "register_operand" "")))
9887 (use (match_operand:V4SF 2 "" ""))
9888 (clobber (reg:CC 17))]
9889 "reload_completed && !SSE_REG_P (operands[0])"
9890 [(parallel [(set (match_dup 0)
9891 (neg:SF (match_dup 1)))
9892 (clobber (reg:CC 17))])])
9893
9894 (define_split
9895 [(set (match_operand:SF 0 "register_operand" "")
9896 (neg:SF (match_operand:SF 1 "register_operand" "")))
9897 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9898 (clobber (reg:CC 17))]
9899 "reload_completed && SSE_REG_P (operands[0])"
9900 [(set (subreg:TI (match_dup 0) 0)
9901 (xor:TI (match_dup 1)
9902 (match_dup 2)))]
9903 {
9904 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9905 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9906 if (operands_match_p (operands[0], operands[2]))
9907 {
9908 rtx tmp;
9909 tmp = operands[1];
9910 operands[1] = operands[2];
9911 operands[2] = tmp;
9912 }
9913 })
9914
9915
9916 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9917 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9918 ;; to itself.
9919 (define_insn "*negsf2_if"
9920 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9921 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9922 (clobber (reg:CC 17))]
9923 "TARGET_80387 && !TARGET_SSE
9924 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9925 "#")
9926
9927 (define_split
9928 [(set (match_operand:SF 0 "fp_register_operand" "")
9929 (neg:SF (match_operand:SF 1 "register_operand" "")))
9930 (clobber (reg:CC 17))]
9931 "TARGET_80387 && reload_completed"
9932 [(set (match_dup 0)
9933 (neg:SF (match_dup 1)))]
9934 "")
9935
9936 (define_split
9937 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9938 (neg:SF (match_operand:SF 1 "register_operand" "")))
9939 (clobber (reg:CC 17))]
9940 "TARGET_80387 && reload_completed"
9941 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9942 (clobber (reg:CC 17))])]
9943 "operands[1] = gen_int_mode (0x80000000, SImode);
9944 operands[0] = gen_lowpart (SImode, operands[0]);")
9945
9946 (define_split
9947 [(set (match_operand 0 "memory_operand" "")
9948 (neg (match_operand 1 "memory_operand" "")))
9949 (clobber (reg:CC 17))]
9950 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9951 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9952 (clobber (reg:CC 17))])]
9953 {
9954 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9955
9956 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9957 if (size >= 12)
9958 size = 10;
9959 operands[0] = adjust_address (operands[0], QImode, size - 1);
9960 operands[1] = gen_int_mode (0x80, QImode);
9961 })
9962
9963 (define_expand "negdf2"
9964 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9965 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9966 (clobber (reg:CC 17))])]
9967 "TARGET_80387"
9968 "if (TARGET_SSE2)
9969 {
9970 /* In case operand is in memory, we will not use SSE. */
9971 if (memory_operand (operands[0], VOIDmode)
9972 && rtx_equal_p (operands[0], operands[1]))
9973 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9974 else
9975 {
9976 /* Using SSE is tricky, since we need bitwise negation of -0
9977 in register. */
9978 rtx reg;
9979 #if HOST_BITS_PER_WIDE_INT >= 64
9980 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9981 #else
9982 rtx imm = immed_double_const (0, 0x80000000, DImode);
9983 #endif
9984 rtx dest = operands[0];
9985
9986 operands[1] = force_reg (DFmode, operands[1]);
9987 operands[0] = force_reg (DFmode, operands[0]);
9988 imm = gen_lowpart (DFmode, imm);
9989 reg = force_reg (V2DFmode,
9990 gen_rtx_CONST_VECTOR (V2DFmode,
9991 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9992 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9993 if (dest != operands[0])
9994 emit_move_insn (dest, operands[0]);
9995 }
9996 DONE;
9997 }
9998 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9999
10000 (define_insn "negdf2_memory"
10001 [(set (match_operand:DF 0 "memory_operand" "=m")
10002 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10003 (clobber (reg:CC 17))]
10004 "ix86_unary_operator_ok (NEG, DFmode, operands)"
10005 "#")
10006
10007 (define_insn "negdf2_ifs"
10008 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10009 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10010 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10011 (clobber (reg:CC 17))]
10012 "!TARGET_64BIT && TARGET_SSE2
10013 && (reload_in_progress || reload_completed
10014 || (register_operand (operands[0], VOIDmode)
10015 && register_operand (operands[1], VOIDmode)))"
10016 "#")
10017
10018 (define_insn "*negdf2_ifs_rex64"
10019 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10020 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10021 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10022 (clobber (reg:CC 17))]
10023 "TARGET_64BIT && TARGET_SSE2
10024 && (reload_in_progress || reload_completed
10025 || (register_operand (operands[0], VOIDmode)
10026 && register_operand (operands[1], VOIDmode)))"
10027 "#")
10028
10029 (define_split
10030 [(set (match_operand:DF 0 "memory_operand" "")
10031 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10032 (use (match_operand:V2DF 2 "" ""))
10033 (clobber (reg:CC 17))]
10034 ""
10035 [(parallel [(set (match_dup 0)
10036 (neg:DF (match_dup 1)))
10037 (clobber (reg:CC 17))])])
10038
10039 (define_split
10040 [(set (match_operand:DF 0 "register_operand" "")
10041 (neg:DF (match_operand:DF 1 "register_operand" "")))
10042 (use (match_operand:V2DF 2 "" ""))
10043 (clobber (reg:CC 17))]
10044 "reload_completed && !SSE_REG_P (operands[0])
10045 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10046 [(parallel [(set (match_dup 0)
10047 (neg:DF (match_dup 1)))
10048 (clobber (reg:CC 17))])])
10049
10050 (define_split
10051 [(set (match_operand:DF 0 "register_operand" "")
10052 (neg:DF (match_operand:DF 1 "register_operand" "")))
10053 (use (match_operand:V2DF 2 "" ""))
10054 (clobber (reg:CC 17))]
10055 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10056 [(parallel [(set (match_dup 0)
10057 (xor:DI (match_dup 1) (match_dup 2)))
10058 (clobber (reg:CC 17))])]
10059 "operands[0] = gen_lowpart (DImode, operands[0]);
10060 operands[1] = gen_lowpart (DImode, operands[1]);
10061 operands[2] = gen_lowpart (DImode, operands[2]);")
10062
10063 (define_split
10064 [(set (match_operand:DF 0 "register_operand" "")
10065 (neg:DF (match_operand:DF 1 "register_operand" "")))
10066 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10067 (clobber (reg:CC 17))]
10068 "reload_completed && SSE_REG_P (operands[0])"
10069 [(set (subreg:TI (match_dup 0) 0)
10070 (xor:TI (match_dup 1)
10071 (match_dup 2)))]
10072 {
10073 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10074 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10075 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10076 /* Avoid possible reformatting on the operands. */
10077 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10078 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10079 if (operands_match_p (operands[0], operands[2]))
10080 {
10081 rtx tmp;
10082 tmp = operands[1];
10083 operands[1] = operands[2];
10084 operands[2] = tmp;
10085 }
10086 })
10087
10088 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10089 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10090 ;; to itself.
10091 (define_insn "*negdf2_if"
10092 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10093 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10094 (clobber (reg:CC 17))]
10095 "!TARGET_64BIT && TARGET_80387
10096 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10097 "#")
10098
10099 ;; FIXME: We should to allow integer registers here. Problem is that
10100 ;; we need another scratch register to get constant from.
10101 ;; Forcing constant to mem if no register available in peep2 should be
10102 ;; safe even for PIC mode, because of RIP relative addressing.
10103 (define_insn "*negdf2_if_rex64"
10104 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10105 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10106 (clobber (reg:CC 17))]
10107 "TARGET_64BIT && TARGET_80387
10108 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10109 "#")
10110
10111 (define_split
10112 [(set (match_operand:DF 0 "fp_register_operand" "")
10113 (neg:DF (match_operand:DF 1 "register_operand" "")))
10114 (clobber (reg:CC 17))]
10115 "TARGET_80387 && reload_completed"
10116 [(set (match_dup 0)
10117 (neg:DF (match_dup 1)))]
10118 "")
10119
10120 (define_split
10121 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10122 (neg:DF (match_operand:DF 1 "register_operand" "")))
10123 (clobber (reg:CC 17))]
10124 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10125 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10126 (clobber (reg:CC 17))])]
10127 "operands[4] = gen_int_mode (0x80000000, SImode);
10128 split_di (operands+0, 1, operands+2, operands+3);")
10129
10130 (define_expand "negxf2"
10131 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10132 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10133 (clobber (reg:CC 17))])]
10134 "!TARGET_64BIT && TARGET_80387"
10135 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10136
10137 (define_expand "negtf2"
10138 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10139 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10140 (clobber (reg:CC 17))])]
10141 "TARGET_80387"
10142 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10143
10144 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10145 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10146 ;; to itself.
10147 (define_insn "*negxf2_if"
10148 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10149 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10150 (clobber (reg:CC 17))]
10151 "!TARGET_64BIT && TARGET_80387
10152 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10153 "#")
10154
10155 (define_split
10156 [(set (match_operand:XF 0 "fp_register_operand" "")
10157 (neg:XF (match_operand:XF 1 "register_operand" "")))
10158 (clobber (reg:CC 17))]
10159 "TARGET_80387 && reload_completed"
10160 [(set (match_dup 0)
10161 (neg:XF (match_dup 1)))]
10162 "")
10163
10164 (define_split
10165 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10166 (neg:XF (match_operand:XF 1 "register_operand" "")))
10167 (clobber (reg:CC 17))]
10168 "TARGET_80387 && reload_completed"
10169 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10170 (clobber (reg:CC 17))])]
10171 "operands[1] = GEN_INT (0x8000);
10172 operands[0] = gen_rtx_REG (SImode,
10173 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10174
10175 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10176 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10177 ;; to itself.
10178 (define_insn "*negtf2_if"
10179 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10180 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10181 (clobber (reg:CC 17))]
10182 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10183 "#")
10184
10185 (define_split
10186 [(set (match_operand:TF 0 "fp_register_operand" "")
10187 (neg:TF (match_operand:TF 1 "register_operand" "")))
10188 (clobber (reg:CC 17))]
10189 "TARGET_80387 && reload_completed"
10190 [(set (match_dup 0)
10191 (neg:TF (match_dup 1)))]
10192 "")
10193
10194 (define_split
10195 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10196 (neg:TF (match_operand:TF 1 "register_operand" "")))
10197 (clobber (reg:CC 17))]
10198 "TARGET_80387 && reload_completed"
10199 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10200 (clobber (reg:CC 17))])]
10201 "operands[1] = GEN_INT (0x8000);
10202 operands[0] = gen_rtx_REG (SImode,
10203 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10204
10205 ;; Conditionalize these after reload. If they matches before reload, we
10206 ;; lose the clobber and ability to use integer instructions.
10207
10208 (define_insn "*negsf2_1"
10209 [(set (match_operand:SF 0 "register_operand" "=f")
10210 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10211 "TARGET_80387 && reload_completed"
10212 "fchs"
10213 [(set_attr "type" "fsgn")
10214 (set_attr "mode" "SF")
10215 (set_attr "ppro_uops" "few")])
10216
10217 (define_insn "*negdf2_1"
10218 [(set (match_operand:DF 0 "register_operand" "=f")
10219 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10220 "TARGET_80387 && reload_completed"
10221 "fchs"
10222 [(set_attr "type" "fsgn")
10223 (set_attr "mode" "DF")
10224 (set_attr "ppro_uops" "few")])
10225
10226 (define_insn "*negextendsfdf2"
10227 [(set (match_operand:DF 0 "register_operand" "=f")
10228 (neg:DF (float_extend:DF
10229 (match_operand:SF 1 "register_operand" "0"))))]
10230 "TARGET_80387"
10231 "fchs"
10232 [(set_attr "type" "fsgn")
10233 (set_attr "mode" "DF")
10234 (set_attr "ppro_uops" "few")])
10235
10236 (define_insn "*negxf2_1"
10237 [(set (match_operand:XF 0 "register_operand" "=f")
10238 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10239 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10240 "fchs"
10241 [(set_attr "type" "fsgn")
10242 (set_attr "mode" "XF")
10243 (set_attr "ppro_uops" "few")])
10244
10245 (define_insn "*negextenddfxf2"
10246 [(set (match_operand:XF 0 "register_operand" "=f")
10247 (neg:XF (float_extend:XF
10248 (match_operand:DF 1 "register_operand" "0"))))]
10249 "!TARGET_64BIT && TARGET_80387"
10250 "fchs"
10251 [(set_attr "type" "fsgn")
10252 (set_attr "mode" "XF")
10253 (set_attr "ppro_uops" "few")])
10254
10255 (define_insn "*negextendsfxf2"
10256 [(set (match_operand:XF 0 "register_operand" "=f")
10257 (neg:XF (float_extend:XF
10258 (match_operand:SF 1 "register_operand" "0"))))]
10259 "!TARGET_64BIT && TARGET_80387"
10260 "fchs"
10261 [(set_attr "type" "fsgn")
10262 (set_attr "mode" "XF")
10263 (set_attr "ppro_uops" "few")])
10264
10265 (define_insn "*negtf2_1"
10266 [(set (match_operand:TF 0 "register_operand" "=f")
10267 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10268 "TARGET_80387 && reload_completed"
10269 "fchs"
10270 [(set_attr "type" "fsgn")
10271 (set_attr "mode" "XF")
10272 (set_attr "ppro_uops" "few")])
10273
10274 (define_insn "*negextenddftf2"
10275 [(set (match_operand:TF 0 "register_operand" "=f")
10276 (neg:TF (float_extend:TF
10277 (match_operand:DF 1 "register_operand" "0"))))]
10278 "TARGET_80387"
10279 "fchs"
10280 [(set_attr "type" "fsgn")
10281 (set_attr "mode" "XF")
10282 (set_attr "ppro_uops" "few")])
10283
10284 (define_insn "*negextendsftf2"
10285 [(set (match_operand:TF 0 "register_operand" "=f")
10286 (neg:TF (float_extend:TF
10287 (match_operand:SF 1 "register_operand" "0"))))]
10288 "TARGET_80387"
10289 "fchs"
10290 [(set_attr "type" "fsgn")
10291 (set_attr "mode" "XF")
10292 (set_attr "ppro_uops" "few")])
10293 \f
10294 ;; Absolute value instructions
10295
10296 (define_expand "abssf2"
10297 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10298 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10299 (clobber (reg:CC 17))])]
10300 "TARGET_80387"
10301 "if (TARGET_SSE)
10302 {
10303 /* In case operand is in memory, we will not use SSE. */
10304 if (memory_operand (operands[0], VOIDmode)
10305 && rtx_equal_p (operands[0], operands[1]))
10306 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10307 else
10308 {
10309 /* Using SSE is tricky, since we need bitwise negation of -0
10310 in register. */
10311 rtx reg = gen_reg_rtx (V4SFmode);
10312 rtx dest = operands[0];
10313 rtx imm;
10314
10315 operands[1] = force_reg (SFmode, operands[1]);
10316 operands[0] = force_reg (SFmode, operands[0]);
10317 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10318 reg = force_reg (V4SFmode,
10319 gen_rtx_CONST_VECTOR (V4SFmode,
10320 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10321 CONST0_RTX (SFmode),
10322 CONST0_RTX (SFmode))));
10323 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10324 if (dest != operands[0])
10325 emit_move_insn (dest, operands[0]);
10326 }
10327 DONE;
10328 }
10329 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10330
10331 (define_insn "abssf2_memory"
10332 [(set (match_operand:SF 0 "memory_operand" "=m")
10333 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10334 (clobber (reg:CC 17))]
10335 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10336 "#")
10337
10338 (define_insn "abssf2_ifs"
10339 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10340 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10341 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10342 (clobber (reg:CC 17))]
10343 "TARGET_SSE
10344 && (reload_in_progress || reload_completed
10345 || (register_operand (operands[0], VOIDmode)
10346 && register_operand (operands[1], VOIDmode)))"
10347 "#")
10348
10349 (define_split
10350 [(set (match_operand:SF 0 "memory_operand" "")
10351 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10352 (use (match_operand:V4SF 2 "" ""))
10353 (clobber (reg:CC 17))]
10354 ""
10355 [(parallel [(set (match_dup 0)
10356 (abs:SF (match_dup 1)))
10357 (clobber (reg:CC 17))])])
10358
10359 (define_split
10360 [(set (match_operand:SF 0 "register_operand" "")
10361 (abs:SF (match_operand:SF 1 "register_operand" "")))
10362 (use (match_operand:V4SF 2 "" ""))
10363 (clobber (reg:CC 17))]
10364 "reload_completed && !SSE_REG_P (operands[0])"
10365 [(parallel [(set (match_dup 0)
10366 (abs:SF (match_dup 1)))
10367 (clobber (reg:CC 17))])])
10368
10369 (define_split
10370 [(set (match_operand:SF 0 "register_operand" "")
10371 (abs:SF (match_operand:SF 1 "register_operand" "")))
10372 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10373 (clobber (reg:CC 17))]
10374 "reload_completed && SSE_REG_P (operands[0])"
10375 [(set (subreg:TI (match_dup 0) 0)
10376 (and:TI (match_dup 1)
10377 (match_dup 2)))]
10378 {
10379 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10380 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10381 if (operands_match_p (operands[0], operands[2]))
10382 {
10383 rtx tmp;
10384 tmp = operands[1];
10385 operands[1] = operands[2];
10386 operands[2] = tmp;
10387 }
10388 })
10389
10390 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10391 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10392 ;; to itself.
10393 (define_insn "*abssf2_if"
10394 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10395 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10396 (clobber (reg:CC 17))]
10397 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10398 "#")
10399
10400 (define_split
10401 [(set (match_operand:SF 0 "fp_register_operand" "")
10402 (abs:SF (match_operand:SF 1 "register_operand" "")))
10403 (clobber (reg:CC 17))]
10404 "TARGET_80387"
10405 [(set (match_dup 0)
10406 (abs:SF (match_dup 1)))]
10407 "")
10408
10409 (define_split
10410 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10411 (abs:SF (match_operand:SF 1 "register_operand" "")))
10412 (clobber (reg:CC 17))]
10413 "TARGET_80387 && reload_completed"
10414 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10415 (clobber (reg:CC 17))])]
10416 "operands[1] = gen_int_mode (~0x80000000, SImode);
10417 operands[0] = gen_lowpart (SImode, operands[0]);")
10418
10419 (define_split
10420 [(set (match_operand 0 "memory_operand" "")
10421 (abs (match_operand 1 "memory_operand" "")))
10422 (clobber (reg:CC 17))]
10423 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10424 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10425 (clobber (reg:CC 17))])]
10426 {
10427 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10428
10429 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10430 if (size >= 12)
10431 size = 10;
10432 operands[0] = adjust_address (operands[0], QImode, size - 1);
10433 operands[1] = gen_int_mode (~0x80, QImode);
10434 })
10435
10436 (define_expand "absdf2"
10437 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10438 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10439 (clobber (reg:CC 17))])]
10440 "TARGET_80387"
10441 "if (TARGET_SSE2)
10442 {
10443 /* In case operand is in memory, we will not use SSE. */
10444 if (memory_operand (operands[0], VOIDmode)
10445 && rtx_equal_p (operands[0], operands[1]))
10446 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10447 else
10448 {
10449 /* Using SSE is tricky, since we need bitwise negation of -0
10450 in register. */
10451 rtx reg = gen_reg_rtx (V2DFmode);
10452 #if HOST_BITS_PER_WIDE_INT >= 64
10453 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10454 #else
10455 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10456 #endif
10457 rtx dest = operands[0];
10458
10459 operands[1] = force_reg (DFmode, operands[1]);
10460 operands[0] = force_reg (DFmode, operands[0]);
10461
10462 /* Produce LONG_DOUBLE with the proper immediate argument. */
10463 imm = gen_lowpart (DFmode, imm);
10464 reg = force_reg (V2DFmode,
10465 gen_rtx_CONST_VECTOR (V2DFmode,
10466 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10467 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10468 if (dest != operands[0])
10469 emit_move_insn (dest, operands[0]);
10470 }
10471 DONE;
10472 }
10473 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10474
10475 (define_insn "absdf2_memory"
10476 [(set (match_operand:DF 0 "memory_operand" "=m")
10477 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10478 (clobber (reg:CC 17))]
10479 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10480 "#")
10481
10482 (define_insn "absdf2_ifs"
10483 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10484 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10485 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10486 (clobber (reg:CC 17))]
10487 "!TARGET_64BIT && TARGET_SSE2
10488 && (reload_in_progress || reload_completed
10489 || (register_operand (operands[0], VOIDmode)
10490 && register_operand (operands[1], VOIDmode)))"
10491 "#")
10492
10493 (define_insn "*absdf2_ifs_rex64"
10494 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10495 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10496 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10497 (clobber (reg:CC 17))]
10498 "TARGET_64BIT && TARGET_SSE2
10499 && (reload_in_progress || reload_completed
10500 || (register_operand (operands[0], VOIDmode)
10501 && register_operand (operands[1], VOIDmode)))"
10502 "#")
10503
10504 (define_split
10505 [(set (match_operand:DF 0 "memory_operand" "")
10506 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10507 (use (match_operand:V2DF 2 "" ""))
10508 (clobber (reg:CC 17))]
10509 ""
10510 [(parallel [(set (match_dup 0)
10511 (abs:DF (match_dup 1)))
10512 (clobber (reg:CC 17))])])
10513
10514 (define_split
10515 [(set (match_operand:DF 0 "register_operand" "")
10516 (abs:DF (match_operand:DF 1 "register_operand" "")))
10517 (use (match_operand:V2DF 2 "" ""))
10518 (clobber (reg:CC 17))]
10519 "reload_completed && !SSE_REG_P (operands[0])"
10520 [(parallel [(set (match_dup 0)
10521 (abs:DF (match_dup 1)))
10522 (clobber (reg:CC 17))])])
10523
10524 (define_split
10525 [(set (match_operand:DF 0 "register_operand" "")
10526 (abs:DF (match_operand:DF 1 "register_operand" "")))
10527 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10528 (clobber (reg:CC 17))]
10529 "reload_completed && SSE_REG_P (operands[0])"
10530 [(set (subreg:TI (match_dup 0) 0)
10531 (and:TI (match_dup 1)
10532 (match_dup 2)))]
10533 {
10534 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10535 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10536 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10537 /* Avoid possible reformatting on the operands. */
10538 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10539 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10540 if (operands_match_p (operands[0], operands[2]))
10541 {
10542 rtx tmp;
10543 tmp = operands[1];
10544 operands[1] = operands[2];
10545 operands[2] = tmp;
10546 }
10547 })
10548
10549
10550 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10551 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10552 ;; to itself.
10553 (define_insn "*absdf2_if"
10554 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10555 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10556 (clobber (reg:CC 17))]
10557 "!TARGET_64BIT && TARGET_80387
10558 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10559 "#")
10560
10561 ;; FIXME: We should to allow integer registers here. Problem is that
10562 ;; we need another scratch register to get constant from.
10563 ;; Forcing constant to mem if no register available in peep2 should be
10564 ;; safe even for PIC mode, because of RIP relative addressing.
10565 (define_insn "*absdf2_if_rex64"
10566 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10567 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10568 (clobber (reg:CC 17))]
10569 "TARGET_64BIT && TARGET_80387
10570 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10571 "#")
10572
10573 (define_split
10574 [(set (match_operand:DF 0 "fp_register_operand" "")
10575 (abs:DF (match_operand:DF 1 "register_operand" "")))
10576 (clobber (reg:CC 17))]
10577 "TARGET_80387 && reload_completed"
10578 [(set (match_dup 0)
10579 (abs:DF (match_dup 1)))]
10580 "")
10581
10582 (define_split
10583 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10584 (abs:DF (match_operand:DF 1 "register_operand" "")))
10585 (clobber (reg:CC 17))]
10586 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10587 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10588 (clobber (reg:CC 17))])]
10589 "operands[4] = gen_int_mode (~0x80000000, SImode);
10590 split_di (operands+0, 1, operands+2, operands+3);")
10591
10592 (define_expand "absxf2"
10593 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10594 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10595 (clobber (reg:CC 17))])]
10596 "!TARGET_64BIT && TARGET_80387"
10597 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10598
10599 (define_expand "abstf2"
10600 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10601 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10602 (clobber (reg:CC 17))])]
10603 "TARGET_80387"
10604 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10605
10606 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10607 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10608 ;; to itself.
10609 (define_insn "*absxf2_if"
10610 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10611 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10612 (clobber (reg:CC 17))]
10613 "!TARGET_64BIT && TARGET_80387
10614 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10615 "#")
10616
10617 (define_split
10618 [(set (match_operand:XF 0 "fp_register_operand" "")
10619 (abs:XF (match_operand:XF 1 "register_operand" "")))
10620 (clobber (reg:CC 17))]
10621 "TARGET_80387 && reload_completed"
10622 [(set (match_dup 0)
10623 (abs:XF (match_dup 1)))]
10624 "")
10625
10626 (define_split
10627 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10628 (abs:XF (match_operand:XF 1 "register_operand" "")))
10629 (clobber (reg:CC 17))]
10630 "TARGET_80387 && reload_completed"
10631 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10632 (clobber (reg:CC 17))])]
10633 "operands[1] = GEN_INT (~0x8000);
10634 operands[0] = gen_rtx_REG (SImode,
10635 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10636
10637 (define_insn "*abstf2_if"
10638 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10639 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10640 (clobber (reg:CC 17))]
10641 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10642 "#")
10643
10644 (define_split
10645 [(set (match_operand:TF 0 "fp_register_operand" "")
10646 (abs:TF (match_operand:TF 1 "register_operand" "")))
10647 (clobber (reg:CC 17))]
10648 "TARGET_80387 && reload_completed"
10649 [(set (match_dup 0)
10650 (abs:TF (match_dup 1)))]
10651 "")
10652
10653 (define_split
10654 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10655 (abs:TF (match_operand:TF 1 "register_operand" "")))
10656 (clobber (reg:CC 17))]
10657 "TARGET_80387 && reload_completed"
10658 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10659 (clobber (reg:CC 17))])]
10660 "operands[1] = GEN_INT (~0x8000);
10661 operands[0] = gen_rtx_REG (SImode,
10662 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10663
10664 (define_insn "*abssf2_1"
10665 [(set (match_operand:SF 0 "register_operand" "=f")
10666 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10667 "TARGET_80387 && reload_completed"
10668 "fabs"
10669 [(set_attr "type" "fsgn")
10670 (set_attr "mode" "SF")])
10671
10672 (define_insn "*absdf2_1"
10673 [(set (match_operand:DF 0 "register_operand" "=f")
10674 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10675 "TARGET_80387 && reload_completed"
10676 "fabs"
10677 [(set_attr "type" "fsgn")
10678 (set_attr "mode" "DF")])
10679
10680 (define_insn "*absextendsfdf2"
10681 [(set (match_operand:DF 0 "register_operand" "=f")
10682 (abs:DF (float_extend:DF
10683 (match_operand:SF 1 "register_operand" "0"))))]
10684 "TARGET_80387"
10685 "fabs"
10686 [(set_attr "type" "fsgn")
10687 (set_attr "mode" "DF")])
10688
10689 (define_insn "*absxf2_1"
10690 [(set (match_operand:XF 0 "register_operand" "=f")
10691 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10692 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10693 "fabs"
10694 [(set_attr "type" "fsgn")
10695 (set_attr "mode" "DF")])
10696
10697 (define_insn "*absextenddfxf2"
10698 [(set (match_operand:XF 0 "register_operand" "=f")
10699 (abs:XF (float_extend:XF
10700 (match_operand:DF 1 "register_operand" "0"))))]
10701 "!TARGET_64BIT && TARGET_80387"
10702 "fabs"
10703 [(set_attr "type" "fsgn")
10704 (set_attr "mode" "XF")])
10705
10706 (define_insn "*absextendsfxf2"
10707 [(set (match_operand:XF 0 "register_operand" "=f")
10708 (abs:XF (float_extend:XF
10709 (match_operand:SF 1 "register_operand" "0"))))]
10710 "!TARGET_64BIT && TARGET_80387"
10711 "fabs"
10712 [(set_attr "type" "fsgn")
10713 (set_attr "mode" "XF")])
10714
10715 (define_insn "*abstf2_1"
10716 [(set (match_operand:TF 0 "register_operand" "=f")
10717 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10718 "TARGET_80387 && reload_completed"
10719 "fabs"
10720 [(set_attr "type" "fsgn")
10721 (set_attr "mode" "DF")])
10722
10723 (define_insn "*absextenddftf2"
10724 [(set (match_operand:TF 0 "register_operand" "=f")
10725 (abs:TF (float_extend:TF
10726 (match_operand:DF 1 "register_operand" "0"))))]
10727 "TARGET_80387"
10728 "fabs"
10729 [(set_attr "type" "fsgn")
10730 (set_attr "mode" "XF")])
10731
10732 (define_insn "*absextendsftf2"
10733 [(set (match_operand:TF 0 "register_operand" "=f")
10734 (abs:TF (float_extend:TF
10735 (match_operand:SF 1 "register_operand" "0"))))]
10736 "TARGET_80387"
10737 "fabs"
10738 [(set_attr "type" "fsgn")
10739 (set_attr "mode" "XF")])
10740 \f
10741 ;; One complement instructions
10742
10743 (define_expand "one_cmpldi2"
10744 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10745 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10746 "TARGET_64BIT"
10747 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10748
10749 (define_insn "*one_cmpldi2_1_rex64"
10750 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10751 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10752 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10753 "not{q}\t%0"
10754 [(set_attr "type" "negnot")
10755 (set_attr "mode" "DI")])
10756
10757 (define_insn "*one_cmpldi2_2_rex64"
10758 [(set (reg 17)
10759 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10760 (const_int 0)))
10761 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10762 (not:DI (match_dup 1)))]
10763 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10764 && ix86_unary_operator_ok (NOT, DImode, operands)"
10765 "#"
10766 [(set_attr "type" "alu1")
10767 (set_attr "mode" "DI")])
10768
10769 (define_split
10770 [(set (reg 17)
10771 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10772 (const_int 0)))
10773 (set (match_operand:DI 0 "nonimmediate_operand" "")
10774 (not:DI (match_dup 1)))]
10775 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10776 [(parallel [(set (reg:CCNO 17)
10777 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10778 (const_int 0)))
10779 (set (match_dup 0)
10780 (xor:DI (match_dup 1) (const_int -1)))])]
10781 "")
10782
10783 (define_expand "one_cmplsi2"
10784 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10785 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10786 ""
10787 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10788
10789 (define_insn "*one_cmplsi2_1"
10790 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10791 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10792 "ix86_unary_operator_ok (NOT, SImode, operands)"
10793 "not{l}\t%0"
10794 [(set_attr "type" "negnot")
10795 (set_attr "mode" "SI")])
10796
10797 ;; ??? Currently never generated - xor is used instead.
10798 (define_insn "*one_cmplsi2_1_zext"
10799 [(set (match_operand:DI 0 "register_operand" "=r")
10800 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10801 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10802 "not{l}\t%k0"
10803 [(set_attr "type" "negnot")
10804 (set_attr "mode" "SI")])
10805
10806 (define_insn "*one_cmplsi2_2"
10807 [(set (reg 17)
10808 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10809 (const_int 0)))
10810 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10811 (not:SI (match_dup 1)))]
10812 "ix86_match_ccmode (insn, CCNOmode)
10813 && ix86_unary_operator_ok (NOT, SImode, operands)"
10814 "#"
10815 [(set_attr "type" "alu1")
10816 (set_attr "mode" "SI")])
10817
10818 (define_split
10819 [(set (reg 17)
10820 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10821 (const_int 0)))
10822 (set (match_operand:SI 0 "nonimmediate_operand" "")
10823 (not:SI (match_dup 1)))]
10824 "ix86_match_ccmode (insn, CCNOmode)"
10825 [(parallel [(set (reg:CCNO 17)
10826 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10827 (const_int 0)))
10828 (set (match_dup 0)
10829 (xor:SI (match_dup 1) (const_int -1)))])]
10830 "")
10831
10832 ;; ??? Currently never generated - xor is used instead.
10833 (define_insn "*one_cmplsi2_2_zext"
10834 [(set (reg 17)
10835 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10836 (const_int 0)))
10837 (set (match_operand:DI 0 "register_operand" "=r")
10838 (zero_extend:DI (not:SI (match_dup 1))))]
10839 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10840 && ix86_unary_operator_ok (NOT, SImode, operands)"
10841 "#"
10842 [(set_attr "type" "alu1")
10843 (set_attr "mode" "SI")])
10844
10845 (define_split
10846 [(set (reg 17)
10847 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10848 (const_int 0)))
10849 (set (match_operand:DI 0 "register_operand" "")
10850 (zero_extend:DI (not:SI (match_dup 1))))]
10851 "ix86_match_ccmode (insn, CCNOmode)"
10852 [(parallel [(set (reg:CCNO 17)
10853 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10854 (const_int 0)))
10855 (set (match_dup 0)
10856 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10857 "")
10858
10859 (define_expand "one_cmplhi2"
10860 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10861 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10862 "TARGET_HIMODE_MATH"
10863 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10864
10865 (define_insn "*one_cmplhi2_1"
10866 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10867 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10868 "ix86_unary_operator_ok (NOT, HImode, operands)"
10869 "not{w}\t%0"
10870 [(set_attr "type" "negnot")
10871 (set_attr "mode" "HI")])
10872
10873 (define_insn "*one_cmplhi2_2"
10874 [(set (reg 17)
10875 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10876 (const_int 0)))
10877 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10878 (not:HI (match_dup 1)))]
10879 "ix86_match_ccmode (insn, CCNOmode)
10880 && ix86_unary_operator_ok (NEG, HImode, operands)"
10881 "#"
10882 [(set_attr "type" "alu1")
10883 (set_attr "mode" "HI")])
10884
10885 (define_split
10886 [(set (reg 17)
10887 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10888 (const_int 0)))
10889 (set (match_operand:HI 0 "nonimmediate_operand" "")
10890 (not:HI (match_dup 1)))]
10891 "ix86_match_ccmode (insn, CCNOmode)"
10892 [(parallel [(set (reg:CCNO 17)
10893 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10894 (const_int 0)))
10895 (set (match_dup 0)
10896 (xor:HI (match_dup 1) (const_int -1)))])]
10897 "")
10898
10899 ;; %%% Potential partial reg stall on alternative 1. What to do?
10900 (define_expand "one_cmplqi2"
10901 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10902 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10903 "TARGET_QIMODE_MATH"
10904 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10905
10906 (define_insn "*one_cmplqi2_1"
10907 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10908 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10909 "ix86_unary_operator_ok (NOT, QImode, operands)"
10910 "@
10911 not{b}\t%0
10912 not{l}\t%k0"
10913 [(set_attr "type" "negnot")
10914 (set_attr "mode" "QI,SI")])
10915
10916 (define_insn "*one_cmplqi2_2"
10917 [(set (reg 17)
10918 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10919 (const_int 0)))
10920 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10921 (not:QI (match_dup 1)))]
10922 "ix86_match_ccmode (insn, CCNOmode)
10923 && ix86_unary_operator_ok (NOT, QImode, operands)"
10924 "#"
10925 [(set_attr "type" "alu1")
10926 (set_attr "mode" "QI")])
10927
10928 (define_split
10929 [(set (reg 17)
10930 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10931 (const_int 0)))
10932 (set (match_operand:QI 0 "nonimmediate_operand" "")
10933 (not:QI (match_dup 1)))]
10934 "ix86_match_ccmode (insn, CCNOmode)"
10935 [(parallel [(set (reg:CCNO 17)
10936 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10937 (const_int 0)))
10938 (set (match_dup 0)
10939 (xor:QI (match_dup 1) (const_int -1)))])]
10940 "")
10941 \f
10942 ;; Arithmetic shift instructions
10943
10944 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10945 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10946 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10947 ;; from the assembler input.
10948 ;;
10949 ;; This instruction shifts the target reg/mem as usual, but instead of
10950 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10951 ;; is a left shift double, bits are taken from the high order bits of
10952 ;; reg, else if the insn is a shift right double, bits are taken from the
10953 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10954 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10955 ;;
10956 ;; Since sh[lr]d does not change the `reg' operand, that is done
10957 ;; separately, making all shifts emit pairs of shift double and normal
10958 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10959 ;; support a 63 bit shift, each shift where the count is in a reg expands
10960 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10961 ;;
10962 ;; If the shift count is a constant, we need never emit more than one
10963 ;; shift pair, instead using moves and sign extension for counts greater
10964 ;; than 31.
10965
10966 (define_expand "ashldi3"
10967 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10968 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10969 (match_operand:QI 2 "nonmemory_operand" "")))
10970 (clobber (reg:CC 17))])]
10971 ""
10972 {
10973 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10974 {
10975 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10976 DONE;
10977 }
10978 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10979 DONE;
10980 })
10981
10982 (define_insn "*ashldi3_1_rex64"
10983 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10984 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10985 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10986 (clobber (reg:CC 17))]
10987 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10988 {
10989 switch (get_attr_type (insn))
10990 {
10991 case TYPE_ALU:
10992 if (operands[2] != const1_rtx)
10993 abort ();
10994 if (!rtx_equal_p (operands[0], operands[1]))
10995 abort ();
10996 return "add{q}\t{%0, %0|%0, %0}";
10997
10998 case TYPE_LEA:
10999 if (GET_CODE (operands[2]) != CONST_INT
11000 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11001 abort ();
11002 operands[1] = gen_rtx_MULT (DImode, operands[1],
11003 GEN_INT (1 << INTVAL (operands[2])));
11004 return "lea{q}\t{%a1, %0|%0, %a1}";
11005
11006 default:
11007 if (REG_P (operands[2]))
11008 return "sal{q}\t{%b2, %0|%0, %b2}";
11009 else if (GET_CODE (operands[2]) == CONST_INT
11010 && INTVAL (operands[2]) == 1
11011 && (TARGET_SHIFT1 || optimize_size))
11012 return "sal{q}\t%0";
11013 else
11014 return "sal{q}\t{%2, %0|%0, %2}";
11015 }
11016 }
11017 [(set (attr "type")
11018 (cond [(eq_attr "alternative" "1")
11019 (const_string "lea")
11020 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11021 (const_int 0))
11022 (match_operand 0 "register_operand" ""))
11023 (match_operand 2 "const1_operand" ""))
11024 (const_string "alu")
11025 ]
11026 (const_string "ishift")))
11027 (set_attr "mode" "DI")])
11028
11029 ;; Convert lea to the lea pattern to avoid flags dependency.
11030 (define_split
11031 [(set (match_operand:DI 0 "register_operand" "")
11032 (ashift:DI (match_operand:DI 1 "register_operand" "")
11033 (match_operand:QI 2 "immediate_operand" "")))
11034 (clobber (reg:CC 17))]
11035 "TARGET_64BIT && reload_completed
11036 && true_regnum (operands[0]) != true_regnum (operands[1])"
11037 [(set (match_dup 0)
11038 (mult:DI (match_dup 1)
11039 (match_dup 2)))]
11040 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11041
11042 ;; This pattern can't accept a variable shift count, since shifts by
11043 ;; zero don't affect the flags. We assume that shifts by constant
11044 ;; zero are optimized away.
11045 (define_insn "*ashldi3_cmp_rex64"
11046 [(set (reg 17)
11047 (compare
11048 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11049 (match_operand:QI 2 "immediate_operand" "e"))
11050 (const_int 0)))
11051 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11052 (ashift:DI (match_dup 1) (match_dup 2)))]
11053 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11054 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11055 {
11056 switch (get_attr_type (insn))
11057 {
11058 case TYPE_ALU:
11059 if (operands[2] != const1_rtx)
11060 abort ();
11061 return "add{q}\t{%0, %0|%0, %0}";
11062
11063 default:
11064 if (REG_P (operands[2]))
11065 return "sal{q}\t{%b2, %0|%0, %b2}";
11066 else if (GET_CODE (operands[2]) == CONST_INT
11067 && INTVAL (operands[2]) == 1
11068 && (TARGET_SHIFT1 || optimize_size))
11069 return "sal{q}\t%0";
11070 else
11071 return "sal{q}\t{%2, %0|%0, %2}";
11072 }
11073 }
11074 [(set (attr "type")
11075 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11076 (const_int 0))
11077 (match_operand 0 "register_operand" ""))
11078 (match_operand 2 "const1_operand" ""))
11079 (const_string "alu")
11080 ]
11081 (const_string "ishift")))
11082 (set_attr "mode" "DI")])
11083
11084 (define_insn "ashldi3_1"
11085 [(set (match_operand:DI 0 "register_operand" "=r")
11086 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11087 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11088 (clobber (match_scratch:SI 3 "=&r"))
11089 (clobber (reg:CC 17))]
11090 "!TARGET_64BIT && TARGET_CMOVE"
11091 "#"
11092 [(set_attr "type" "multi")])
11093
11094 (define_insn "*ashldi3_2"
11095 [(set (match_operand:DI 0 "register_operand" "=r")
11096 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11097 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11098 (clobber (reg:CC 17))]
11099 "!TARGET_64BIT"
11100 "#"
11101 [(set_attr "type" "multi")])
11102
11103 (define_split
11104 [(set (match_operand:DI 0 "register_operand" "")
11105 (ashift:DI (match_operand:DI 1 "register_operand" "")
11106 (match_operand:QI 2 "nonmemory_operand" "")))
11107 (clobber (match_scratch:SI 3 ""))
11108 (clobber (reg:CC 17))]
11109 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11110 [(const_int 0)]
11111 "ix86_split_ashldi (operands, operands[3]); DONE;")
11112
11113 (define_split
11114 [(set (match_operand:DI 0 "register_operand" "")
11115 (ashift:DI (match_operand:DI 1 "register_operand" "")
11116 (match_operand:QI 2 "nonmemory_operand" "")))
11117 (clobber (reg:CC 17))]
11118 "!TARGET_64BIT && reload_completed"
11119 [(const_int 0)]
11120 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11121
11122 (define_insn "x86_shld_1"
11123 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11124 (ior:SI (ashift:SI (match_dup 0)
11125 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11126 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11127 (minus:QI (const_int 32) (match_dup 2)))))
11128 (clobber (reg:CC 17))]
11129 ""
11130 "@
11131 shld{l}\t{%2, %1, %0|%0, %1, %2}
11132 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11133 [(set_attr "type" "ishift")
11134 (set_attr "prefix_0f" "1")
11135 (set_attr "mode" "SI")
11136 (set_attr "pent_pair" "np")
11137 (set_attr "athlon_decode" "vector")
11138 (set_attr "ppro_uops" "few")])
11139
11140 (define_expand "x86_shift_adj_1"
11141 [(set (reg:CCZ 17)
11142 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11143 (const_int 32))
11144 (const_int 0)))
11145 (set (match_operand:SI 0 "register_operand" "")
11146 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11147 (match_operand:SI 1 "register_operand" "")
11148 (match_dup 0)))
11149 (set (match_dup 1)
11150 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11151 (match_operand:SI 3 "register_operand" "r")
11152 (match_dup 1)))]
11153 "TARGET_CMOVE"
11154 "")
11155
11156 (define_expand "x86_shift_adj_2"
11157 [(use (match_operand:SI 0 "register_operand" ""))
11158 (use (match_operand:SI 1 "register_operand" ""))
11159 (use (match_operand:QI 2 "register_operand" ""))]
11160 ""
11161 {
11162 rtx label = gen_label_rtx ();
11163 rtx tmp;
11164
11165 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11166
11167 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11168 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11169 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11170 gen_rtx_LABEL_REF (VOIDmode, label),
11171 pc_rtx);
11172 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11173 JUMP_LABEL (tmp) = label;
11174
11175 emit_move_insn (operands[0], operands[1]);
11176 emit_move_insn (operands[1], const0_rtx);
11177
11178 emit_label (label);
11179 LABEL_NUSES (label) = 1;
11180
11181 DONE;
11182 })
11183
11184 (define_expand "ashlsi3"
11185 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11186 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11187 (match_operand:QI 2 "nonmemory_operand" "")))
11188 (clobber (reg:CC 17))]
11189 ""
11190 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11191
11192 (define_insn "*ashlsi3_1"
11193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11194 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11195 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11196 (clobber (reg:CC 17))]
11197 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11198 {
11199 switch (get_attr_type (insn))
11200 {
11201 case TYPE_ALU:
11202 if (operands[2] != const1_rtx)
11203 abort ();
11204 if (!rtx_equal_p (operands[0], operands[1]))
11205 abort ();
11206 return "add{l}\t{%0, %0|%0, %0}";
11207
11208 case TYPE_LEA:
11209 return "#";
11210
11211 default:
11212 if (REG_P (operands[2]))
11213 return "sal{l}\t{%b2, %0|%0, %b2}";
11214 else if (GET_CODE (operands[2]) == CONST_INT
11215 && INTVAL (operands[2]) == 1
11216 && (TARGET_SHIFT1 || optimize_size))
11217 return "sal{l}\t%0";
11218 else
11219 return "sal{l}\t{%2, %0|%0, %2}";
11220 }
11221 }
11222 [(set (attr "type")
11223 (cond [(eq_attr "alternative" "1")
11224 (const_string "lea")
11225 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11226 (const_int 0))
11227 (match_operand 0 "register_operand" ""))
11228 (match_operand 2 "const1_operand" ""))
11229 (const_string "alu")
11230 ]
11231 (const_string "ishift")))
11232 (set_attr "mode" "SI")])
11233
11234 ;; Convert lea to the lea pattern to avoid flags dependency.
11235 (define_split
11236 [(set (match_operand 0 "register_operand" "")
11237 (ashift (match_operand 1 "index_register_operand" "")
11238 (match_operand:QI 2 "const_int_operand" "")))
11239 (clobber (reg:CC 17))]
11240 "reload_completed
11241 && true_regnum (operands[0]) != true_regnum (operands[1])"
11242 [(const_int 0)]
11243 {
11244 rtx pat;
11245 operands[0] = gen_lowpart (SImode, operands[0]);
11246 operands[1] = gen_lowpart (Pmode, operands[1]);
11247 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11248 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11249 if (Pmode != SImode)
11250 pat = gen_rtx_SUBREG (SImode, pat, 0);
11251 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11252 DONE;
11253 })
11254
11255 ;; Rare case of shifting RSP is handled by generating move and shift
11256 (define_split
11257 [(set (match_operand 0 "register_operand" "")
11258 (ashift (match_operand 1 "register_operand" "")
11259 (match_operand:QI 2 "const_int_operand" "")))
11260 (clobber (reg:CC 17))]
11261 "reload_completed
11262 && true_regnum (operands[0]) != true_regnum (operands[1])"
11263 [(const_int 0)]
11264 {
11265 rtx pat, clob;
11266 emit_move_insn (operands[1], operands[0]);
11267 pat = gen_rtx_SET (VOIDmode, operands[0],
11268 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11269 operands[0], operands[2]));
11270 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11271 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11272 DONE;
11273 })
11274
11275 (define_insn "*ashlsi3_1_zext"
11276 [(set (match_operand:DI 0 "register_operand" "=r,r")
11277 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11278 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11279 (clobber (reg:CC 17))]
11280 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11281 {
11282 switch (get_attr_type (insn))
11283 {
11284 case TYPE_ALU:
11285 if (operands[2] != const1_rtx)
11286 abort ();
11287 return "add{l}\t{%k0, %k0|%k0, %k0}";
11288
11289 case TYPE_LEA:
11290 return "#";
11291
11292 default:
11293 if (REG_P (operands[2]))
11294 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11295 else if (GET_CODE (operands[2]) == CONST_INT
11296 && INTVAL (operands[2]) == 1
11297 && (TARGET_SHIFT1 || optimize_size))
11298 return "sal{l}\t%k0";
11299 else
11300 return "sal{l}\t{%2, %k0|%k0, %2}";
11301 }
11302 }
11303 [(set (attr "type")
11304 (cond [(eq_attr "alternative" "1")
11305 (const_string "lea")
11306 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11307 (const_int 0))
11308 (match_operand 2 "const1_operand" ""))
11309 (const_string "alu")
11310 ]
11311 (const_string "ishift")))
11312 (set_attr "mode" "SI")])
11313
11314 ;; Convert lea to the lea pattern to avoid flags dependency.
11315 (define_split
11316 [(set (match_operand:DI 0 "register_operand" "")
11317 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11318 (match_operand:QI 2 "const_int_operand" ""))))
11319 (clobber (reg:CC 17))]
11320 "TARGET_64BIT && reload_completed
11321 && true_regnum (operands[0]) != true_regnum (operands[1])"
11322 [(set (match_dup 0) (zero_extend:DI
11323 (subreg:SI (mult:SI (match_dup 1)
11324 (match_dup 2)) 0)))]
11325 {
11326 operands[1] = gen_lowpart (Pmode, operands[1]);
11327 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11328 })
11329
11330 ;; This pattern can't accept a variable shift count, since shifts by
11331 ;; zero don't affect the flags. We assume that shifts by constant
11332 ;; zero are optimized away.
11333 (define_insn "*ashlsi3_cmp"
11334 [(set (reg 17)
11335 (compare
11336 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11337 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11338 (const_int 0)))
11339 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11340 (ashift:SI (match_dup 1) (match_dup 2)))]
11341 "ix86_match_ccmode (insn, CCGOCmode)
11342 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11343 {
11344 switch (get_attr_type (insn))
11345 {
11346 case TYPE_ALU:
11347 if (operands[2] != const1_rtx)
11348 abort ();
11349 return "add{l}\t{%0, %0|%0, %0}";
11350
11351 default:
11352 if (REG_P (operands[2]))
11353 return "sal{l}\t{%b2, %0|%0, %b2}";
11354 else if (GET_CODE (operands[2]) == CONST_INT
11355 && INTVAL (operands[2]) == 1
11356 && (TARGET_SHIFT1 || optimize_size))
11357 return "sal{l}\t%0";
11358 else
11359 return "sal{l}\t{%2, %0|%0, %2}";
11360 }
11361 }
11362 [(set (attr "type")
11363 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11364 (const_int 0))
11365 (match_operand 0 "register_operand" ""))
11366 (match_operand 2 "const1_operand" ""))
11367 (const_string "alu")
11368 ]
11369 (const_string "ishift")))
11370 (set_attr "mode" "SI")])
11371
11372 (define_insn "*ashlsi3_cmp_zext"
11373 [(set (reg 17)
11374 (compare
11375 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11376 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11377 (const_int 0)))
11378 (set (match_operand:DI 0 "register_operand" "=r")
11379 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11380 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11381 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11382 {
11383 switch (get_attr_type (insn))
11384 {
11385 case TYPE_ALU:
11386 if (operands[2] != const1_rtx)
11387 abort ();
11388 return "add{l}\t{%k0, %k0|%k0, %k0}";
11389
11390 default:
11391 if (REG_P (operands[2]))
11392 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11393 else if (GET_CODE (operands[2]) == CONST_INT
11394 && INTVAL (operands[2]) == 1
11395 && (TARGET_SHIFT1 || optimize_size))
11396 return "sal{l}\t%k0";
11397 else
11398 return "sal{l}\t{%2, %k0|%k0, %2}";
11399 }
11400 }
11401 [(set (attr "type")
11402 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11403 (const_int 0))
11404 (match_operand 2 "const1_operand" ""))
11405 (const_string "alu")
11406 ]
11407 (const_string "ishift")))
11408 (set_attr "mode" "SI")])
11409
11410 (define_expand "ashlhi3"
11411 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11412 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11413 (match_operand:QI 2 "nonmemory_operand" "")))
11414 (clobber (reg:CC 17))]
11415 "TARGET_HIMODE_MATH"
11416 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11417
11418 (define_insn "*ashlhi3_1_lea"
11419 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11420 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11421 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11422 (clobber (reg:CC 17))]
11423 "!TARGET_PARTIAL_REG_STALL
11424 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11425 {
11426 switch (get_attr_type (insn))
11427 {
11428 case TYPE_LEA:
11429 return "#";
11430 case TYPE_ALU:
11431 if (operands[2] != const1_rtx)
11432 abort ();
11433 return "add{w}\t{%0, %0|%0, %0}";
11434
11435 default:
11436 if (REG_P (operands[2]))
11437 return "sal{w}\t{%b2, %0|%0, %b2}";
11438 else if (GET_CODE (operands[2]) == CONST_INT
11439 && INTVAL (operands[2]) == 1
11440 && (TARGET_SHIFT1 || optimize_size))
11441 return "sal{w}\t%0";
11442 else
11443 return "sal{w}\t{%2, %0|%0, %2}";
11444 }
11445 }
11446 [(set (attr "type")
11447 (cond [(eq_attr "alternative" "1")
11448 (const_string "lea")
11449 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11450 (const_int 0))
11451 (match_operand 0 "register_operand" ""))
11452 (match_operand 2 "const1_operand" ""))
11453 (const_string "alu")
11454 ]
11455 (const_string "ishift")))
11456 (set_attr "mode" "HI,SI")])
11457
11458 (define_insn "*ashlhi3_1"
11459 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11460 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11461 (match_operand:QI 2 "nonmemory_operand" "cI")))
11462 (clobber (reg:CC 17))]
11463 "TARGET_PARTIAL_REG_STALL
11464 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11465 {
11466 switch (get_attr_type (insn))
11467 {
11468 case TYPE_ALU:
11469 if (operands[2] != const1_rtx)
11470 abort ();
11471 return "add{w}\t{%0, %0|%0, %0}";
11472
11473 default:
11474 if (REG_P (operands[2]))
11475 return "sal{w}\t{%b2, %0|%0, %b2}";
11476 else if (GET_CODE (operands[2]) == CONST_INT
11477 && INTVAL (operands[2]) == 1
11478 && (TARGET_SHIFT1 || optimize_size))
11479 return "sal{w}\t%0";
11480 else
11481 return "sal{w}\t{%2, %0|%0, %2}";
11482 }
11483 }
11484 [(set (attr "type")
11485 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11486 (const_int 0))
11487 (match_operand 0 "register_operand" ""))
11488 (match_operand 2 "const1_operand" ""))
11489 (const_string "alu")
11490 ]
11491 (const_string "ishift")))
11492 (set_attr "mode" "HI")])
11493
11494 ;; This pattern can't accept a variable shift count, since shifts by
11495 ;; zero don't affect the flags. We assume that shifts by constant
11496 ;; zero are optimized away.
11497 (define_insn "*ashlhi3_cmp"
11498 [(set (reg 17)
11499 (compare
11500 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11501 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11502 (const_int 0)))
11503 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11504 (ashift:HI (match_dup 1) (match_dup 2)))]
11505 "ix86_match_ccmode (insn, CCGOCmode)
11506 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11507 {
11508 switch (get_attr_type (insn))
11509 {
11510 case TYPE_ALU:
11511 if (operands[2] != const1_rtx)
11512 abort ();
11513 return "add{w}\t{%0, %0|%0, %0}";
11514
11515 default:
11516 if (REG_P (operands[2]))
11517 return "sal{w}\t{%b2, %0|%0, %b2}";
11518 else if (GET_CODE (operands[2]) == CONST_INT
11519 && INTVAL (operands[2]) == 1
11520 && (TARGET_SHIFT1 || optimize_size))
11521 return "sal{w}\t%0";
11522 else
11523 return "sal{w}\t{%2, %0|%0, %2}";
11524 }
11525 }
11526 [(set (attr "type")
11527 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11528 (const_int 0))
11529 (match_operand 0 "register_operand" ""))
11530 (match_operand 2 "const1_operand" ""))
11531 (const_string "alu")
11532 ]
11533 (const_string "ishift")))
11534 (set_attr "mode" "HI")])
11535
11536 (define_expand "ashlqi3"
11537 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11538 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11539 (match_operand:QI 2 "nonmemory_operand" "")))
11540 (clobber (reg:CC 17))]
11541 "TARGET_QIMODE_MATH"
11542 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11543
11544 ;; %%% Potential partial reg stall on alternative 2. What to do?
11545
11546 (define_insn "*ashlqi3_1_lea"
11547 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11548 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11549 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11550 (clobber (reg:CC 17))]
11551 "!TARGET_PARTIAL_REG_STALL
11552 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11553 {
11554 switch (get_attr_type (insn))
11555 {
11556 case TYPE_LEA:
11557 return "#";
11558 case TYPE_ALU:
11559 if (operands[2] != const1_rtx)
11560 abort ();
11561 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11562 return "add{l}\t{%k0, %k0|%k0, %k0}";
11563 else
11564 return "add{b}\t{%0, %0|%0, %0}";
11565
11566 default:
11567 if (REG_P (operands[2]))
11568 {
11569 if (get_attr_mode (insn) == MODE_SI)
11570 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11571 else
11572 return "sal{b}\t{%b2, %0|%0, %b2}";
11573 }
11574 else if (GET_CODE (operands[2]) == CONST_INT
11575 && INTVAL (operands[2]) == 1
11576 && (TARGET_SHIFT1 || optimize_size))
11577 {
11578 if (get_attr_mode (insn) == MODE_SI)
11579 return "sal{l}\t%0";
11580 else
11581 return "sal{b}\t%0";
11582 }
11583 else
11584 {
11585 if (get_attr_mode (insn) == MODE_SI)
11586 return "sal{l}\t{%2, %k0|%k0, %2}";
11587 else
11588 return "sal{b}\t{%2, %0|%0, %2}";
11589 }
11590 }
11591 }
11592 [(set (attr "type")
11593 (cond [(eq_attr "alternative" "2")
11594 (const_string "lea")
11595 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11596 (const_int 0))
11597 (match_operand 0 "register_operand" ""))
11598 (match_operand 2 "const1_operand" ""))
11599 (const_string "alu")
11600 ]
11601 (const_string "ishift")))
11602 (set_attr "mode" "QI,SI,SI")])
11603
11604 (define_insn "*ashlqi3_1"
11605 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11606 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11607 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11608 (clobber (reg:CC 17))]
11609 "TARGET_PARTIAL_REG_STALL
11610 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11611 {
11612 switch (get_attr_type (insn))
11613 {
11614 case TYPE_ALU:
11615 if (operands[2] != const1_rtx)
11616 abort ();
11617 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11618 return "add{l}\t{%k0, %k0|%k0, %k0}";
11619 else
11620 return "add{b}\t{%0, %0|%0, %0}";
11621
11622 default:
11623 if (REG_P (operands[2]))
11624 {
11625 if (get_attr_mode (insn) == MODE_SI)
11626 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11627 else
11628 return "sal{b}\t{%b2, %0|%0, %b2}";
11629 }
11630 else if (GET_CODE (operands[2]) == CONST_INT
11631 && INTVAL (operands[2]) == 1
11632 && (TARGET_SHIFT1 || optimize_size))
11633 {
11634 if (get_attr_mode (insn) == MODE_SI)
11635 return "sal{l}\t%0";
11636 else
11637 return "sal{b}\t%0";
11638 }
11639 else
11640 {
11641 if (get_attr_mode (insn) == MODE_SI)
11642 return "sal{l}\t{%2, %k0|%k0, %2}";
11643 else
11644 return "sal{b}\t{%2, %0|%0, %2}";
11645 }
11646 }
11647 }
11648 [(set (attr "type")
11649 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11650 (const_int 0))
11651 (match_operand 0 "register_operand" ""))
11652 (match_operand 2 "const1_operand" ""))
11653 (const_string "alu")
11654 ]
11655 (const_string "ishift")))
11656 (set_attr "mode" "QI,SI")])
11657
11658 ;; This pattern can't accept a variable shift count, since shifts by
11659 ;; zero don't affect the flags. We assume that shifts by constant
11660 ;; zero are optimized away.
11661 (define_insn "*ashlqi3_cmp"
11662 [(set (reg 17)
11663 (compare
11664 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11665 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11666 (const_int 0)))
11667 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11668 (ashift:QI (match_dup 1) (match_dup 2)))]
11669 "ix86_match_ccmode (insn, CCGOCmode)
11670 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11671 {
11672 switch (get_attr_type (insn))
11673 {
11674 case TYPE_ALU:
11675 if (operands[2] != const1_rtx)
11676 abort ();
11677 return "add{b}\t{%0, %0|%0, %0}";
11678
11679 default:
11680 if (REG_P (operands[2]))
11681 return "sal{b}\t{%b2, %0|%0, %b2}";
11682 else if (GET_CODE (operands[2]) == CONST_INT
11683 && INTVAL (operands[2]) == 1
11684 && (TARGET_SHIFT1 || optimize_size))
11685 return "sal{b}\t%0";
11686 else
11687 return "sal{b}\t{%2, %0|%0, %2}";
11688 }
11689 }
11690 [(set (attr "type")
11691 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11692 (const_int 0))
11693 (match_operand 0 "register_operand" ""))
11694 (match_operand 2 "const1_operand" ""))
11695 (const_string "alu")
11696 ]
11697 (const_string "ishift")))
11698 (set_attr "mode" "QI")])
11699
11700 ;; See comment above `ashldi3' about how this works.
11701
11702 (define_expand "ashrdi3"
11703 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11704 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11705 (match_operand:QI 2 "nonmemory_operand" "")))
11706 (clobber (reg:CC 17))])]
11707 ""
11708 {
11709 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11710 {
11711 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11712 DONE;
11713 }
11714 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11715 DONE;
11716 })
11717
11718 (define_insn "ashrdi3_63_rex64"
11719 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11720 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11721 (match_operand:DI 2 "const_int_operand" "i,i")))
11722 (clobber (reg:CC 17))]
11723 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11724 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11725 "@
11726 {cqto|cqo}
11727 sar{q}\t{%2, %0|%0, %2}"
11728 [(set_attr "type" "imovx,ishift")
11729 (set_attr "prefix_0f" "0,*")
11730 (set_attr "length_immediate" "0,*")
11731 (set_attr "modrm" "0,1")
11732 (set_attr "mode" "DI")])
11733
11734 (define_insn "*ashrdi3_1_one_bit_rex64"
11735 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11736 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11737 (match_operand:QI 2 "const_int_1_operand" "")))
11738 (clobber (reg:CC 17))]
11739 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11740 && (TARGET_SHIFT1 || optimize_size)"
11741 "sar{q}\t%0"
11742 [(set_attr "type" "ishift")
11743 (set (attr "length")
11744 (if_then_else (match_operand:DI 0 "register_operand" "")
11745 (const_string "2")
11746 (const_string "*")))])
11747
11748 (define_insn "*ashrdi3_1_rex64"
11749 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11750 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11751 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11752 (clobber (reg:CC 17))]
11753 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11754 "@
11755 sar{q}\t{%2, %0|%0, %2}
11756 sar{q}\t{%b2, %0|%0, %b2}"
11757 [(set_attr "type" "ishift")
11758 (set_attr "mode" "DI")])
11759
11760 ;; This pattern can't accept a variable shift count, since shifts by
11761 ;; zero don't affect the flags. We assume that shifts by constant
11762 ;; zero are optimized away.
11763 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11764 [(set (reg 17)
11765 (compare
11766 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11767 (match_operand:QI 2 "const_int_1_operand" ""))
11768 (const_int 0)))
11769 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11770 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11771 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11772 && (TARGET_SHIFT1 || optimize_size)
11773 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11774 "sar{q}\t%0"
11775 [(set_attr "type" "ishift")
11776 (set (attr "length")
11777 (if_then_else (match_operand:DI 0 "register_operand" "")
11778 (const_string "2")
11779 (const_string "*")))])
11780
11781 ;; This pattern can't accept a variable shift count, since shifts by
11782 ;; zero don't affect the flags. We assume that shifts by constant
11783 ;; zero are optimized away.
11784 (define_insn "*ashrdi3_cmp_rex64"
11785 [(set (reg 17)
11786 (compare
11787 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11788 (match_operand:QI 2 "const_int_operand" "n"))
11789 (const_int 0)))
11790 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11791 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11792 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11793 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11794 "sar{q}\t{%2, %0|%0, %2}"
11795 [(set_attr "type" "ishift")
11796 (set_attr "mode" "DI")])
11797
11798
11799 (define_insn "ashrdi3_1"
11800 [(set (match_operand:DI 0 "register_operand" "=r")
11801 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11802 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11803 (clobber (match_scratch:SI 3 "=&r"))
11804 (clobber (reg:CC 17))]
11805 "!TARGET_64BIT && TARGET_CMOVE"
11806 "#"
11807 [(set_attr "type" "multi")])
11808
11809 (define_insn "*ashrdi3_2"
11810 [(set (match_operand:DI 0 "register_operand" "=r")
11811 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11812 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11813 (clobber (reg:CC 17))]
11814 "!TARGET_64BIT"
11815 "#"
11816 [(set_attr "type" "multi")])
11817
11818 (define_split
11819 [(set (match_operand:DI 0 "register_operand" "")
11820 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11821 (match_operand:QI 2 "nonmemory_operand" "")))
11822 (clobber (match_scratch:SI 3 ""))
11823 (clobber (reg:CC 17))]
11824 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11825 [(const_int 0)]
11826 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11827
11828 (define_split
11829 [(set (match_operand:DI 0 "register_operand" "")
11830 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11831 (match_operand:QI 2 "nonmemory_operand" "")))
11832 (clobber (reg:CC 17))]
11833 "!TARGET_64BIT && reload_completed"
11834 [(const_int 0)]
11835 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11836
11837 (define_insn "x86_shrd_1"
11838 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11839 (ior:SI (ashiftrt:SI (match_dup 0)
11840 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11841 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11842 (minus:QI (const_int 32) (match_dup 2)))))
11843 (clobber (reg:CC 17))]
11844 ""
11845 "@
11846 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11847 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11848 [(set_attr "type" "ishift")
11849 (set_attr "prefix_0f" "1")
11850 (set_attr "pent_pair" "np")
11851 (set_attr "ppro_uops" "few")
11852 (set_attr "mode" "SI")])
11853
11854 (define_expand "x86_shift_adj_3"
11855 [(use (match_operand:SI 0 "register_operand" ""))
11856 (use (match_operand:SI 1 "register_operand" ""))
11857 (use (match_operand:QI 2 "register_operand" ""))]
11858 ""
11859 {
11860 rtx label = gen_label_rtx ();
11861 rtx tmp;
11862
11863 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11864
11865 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11866 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11867 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11868 gen_rtx_LABEL_REF (VOIDmode, label),
11869 pc_rtx);
11870 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11871 JUMP_LABEL (tmp) = label;
11872
11873 emit_move_insn (operands[0], operands[1]);
11874 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11875
11876 emit_label (label);
11877 LABEL_NUSES (label) = 1;
11878
11879 DONE;
11880 })
11881
11882 (define_insn "ashrsi3_31"
11883 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11884 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11885 (match_operand:SI 2 "const_int_operand" "i,i")))
11886 (clobber (reg:CC 17))]
11887 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11888 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11889 "@
11890 {cltd|cdq}
11891 sar{l}\t{%2, %0|%0, %2}"
11892 [(set_attr "type" "imovx,ishift")
11893 (set_attr "prefix_0f" "0,*")
11894 (set_attr "length_immediate" "0,*")
11895 (set_attr "modrm" "0,1")
11896 (set_attr "mode" "SI")])
11897
11898 (define_insn "*ashrsi3_31_zext"
11899 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11900 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11901 (match_operand:SI 2 "const_int_operand" "i,i"))))
11902 (clobber (reg:CC 17))]
11903 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11904 && INTVAL (operands[2]) == 31
11905 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11906 "@
11907 {cltd|cdq}
11908 sar{l}\t{%2, %k0|%k0, %2}"
11909 [(set_attr "type" "imovx,ishift")
11910 (set_attr "prefix_0f" "0,*")
11911 (set_attr "length_immediate" "0,*")
11912 (set_attr "modrm" "0,1")
11913 (set_attr "mode" "SI")])
11914
11915 (define_expand "ashrsi3"
11916 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11917 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11918 (match_operand:QI 2 "nonmemory_operand" "")))
11919 (clobber (reg:CC 17))]
11920 ""
11921 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11922
11923 (define_insn "*ashrsi3_1_one_bit"
11924 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11925 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11926 (match_operand:QI 2 "const_int_1_operand" "")))
11927 (clobber (reg:CC 17))]
11928 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11929 && (TARGET_SHIFT1 || optimize_size)"
11930 "sar{l}\t%0"
11931 [(set_attr "type" "ishift")
11932 (set (attr "length")
11933 (if_then_else (match_operand:SI 0 "register_operand" "")
11934 (const_string "2")
11935 (const_string "*")))])
11936
11937 (define_insn "*ashrsi3_1_one_bit_zext"
11938 [(set (match_operand:DI 0 "register_operand" "=r")
11939 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11940 (match_operand:QI 2 "const_int_1_operand" ""))))
11941 (clobber (reg:CC 17))]
11942 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11943 && (TARGET_SHIFT1 || optimize_size)"
11944 "sar{l}\t%k0"
11945 [(set_attr "type" "ishift")
11946 (set_attr "length" "2")])
11947
11948 (define_insn "*ashrsi3_1"
11949 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11950 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11951 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11952 (clobber (reg:CC 17))]
11953 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11954 "@
11955 sar{l}\t{%2, %0|%0, %2}
11956 sar{l}\t{%b2, %0|%0, %b2}"
11957 [(set_attr "type" "ishift")
11958 (set_attr "mode" "SI")])
11959
11960 (define_insn "*ashrsi3_1_zext"
11961 [(set (match_operand:DI 0 "register_operand" "=r,r")
11962 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11963 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11964 (clobber (reg:CC 17))]
11965 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11966 "@
11967 sar{l}\t{%2, %k0|%k0, %2}
11968 sar{l}\t{%b2, %k0|%k0, %b2}"
11969 [(set_attr "type" "ishift")
11970 (set_attr "mode" "SI")])
11971
11972 ;; This pattern can't accept a variable shift count, since shifts by
11973 ;; zero don't affect the flags. We assume that shifts by constant
11974 ;; zero are optimized away.
11975 (define_insn "*ashrsi3_one_bit_cmp"
11976 [(set (reg 17)
11977 (compare
11978 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11979 (match_operand:QI 2 "const_int_1_operand" ""))
11980 (const_int 0)))
11981 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11982 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11983 "ix86_match_ccmode (insn, CCGOCmode)
11984 && (TARGET_SHIFT1 || optimize_size)
11985 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11986 "sar{l}\t%0"
11987 [(set_attr "type" "ishift")
11988 (set (attr "length")
11989 (if_then_else (match_operand:SI 0 "register_operand" "")
11990 (const_string "2")
11991 (const_string "*")))])
11992
11993 (define_insn "*ashrsi3_one_bit_cmp_zext"
11994 [(set (reg 17)
11995 (compare
11996 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11997 (match_operand:QI 2 "const_int_1_operand" ""))
11998 (const_int 0)))
11999 (set (match_operand:DI 0 "register_operand" "=r")
12000 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12001 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12002 && (TARGET_SHIFT1 || optimize_size)
12003 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12004 "sar{l}\t%k0"
12005 [(set_attr "type" "ishift")
12006 (set_attr "length" "2")])
12007
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags. We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*ashrsi3_cmp"
12012 [(set (reg 17)
12013 (compare
12014 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12015 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12016 (const_int 0)))
12017 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12018 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12019 "ix86_match_ccmode (insn, CCGOCmode)
12020 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12021 "sar{l}\t{%2, %0|%0, %2}"
12022 [(set_attr "type" "ishift")
12023 (set_attr "mode" "SI")])
12024
12025 (define_insn "*ashrsi3_cmp_zext"
12026 [(set (reg 17)
12027 (compare
12028 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12029 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12030 (const_int 0)))
12031 (set (match_operand:DI 0 "register_operand" "=r")
12032 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12033 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12034 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12035 "sar{l}\t{%2, %k0|%k0, %2}"
12036 [(set_attr "type" "ishift")
12037 (set_attr "mode" "SI")])
12038
12039 (define_expand "ashrhi3"
12040 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12041 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12042 (match_operand:QI 2 "nonmemory_operand" "")))
12043 (clobber (reg:CC 17))]
12044 "TARGET_HIMODE_MATH"
12045 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12046
12047 (define_insn "*ashrhi3_1_one_bit"
12048 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12049 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12050 (match_operand:QI 2 "const_int_1_operand" "")))
12051 (clobber (reg:CC 17))]
12052 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12053 && (TARGET_SHIFT1 || optimize_size)"
12054 "sar{w}\t%0"
12055 [(set_attr "type" "ishift")
12056 (set (attr "length")
12057 (if_then_else (match_operand 0 "register_operand" "")
12058 (const_string "2")
12059 (const_string "*")))])
12060
12061 (define_insn "*ashrhi3_1"
12062 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12063 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12064 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12065 (clobber (reg:CC 17))]
12066 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12067 "@
12068 sar{w}\t{%2, %0|%0, %2}
12069 sar{w}\t{%b2, %0|%0, %b2}"
12070 [(set_attr "type" "ishift")
12071 (set_attr "mode" "HI")])
12072
12073 ;; This pattern can't accept a variable shift count, since shifts by
12074 ;; zero don't affect the flags. We assume that shifts by constant
12075 ;; zero are optimized away.
12076 (define_insn "*ashrhi3_one_bit_cmp"
12077 [(set (reg 17)
12078 (compare
12079 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12080 (match_operand:QI 2 "const_int_1_operand" ""))
12081 (const_int 0)))
12082 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12083 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12084 "ix86_match_ccmode (insn, CCGOCmode)
12085 && (TARGET_SHIFT1 || optimize_size)
12086 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12087 "sar{w}\t%0"
12088 [(set_attr "type" "ishift")
12089 (set (attr "length")
12090 (if_then_else (match_operand 0 "register_operand" "")
12091 (const_string "2")
12092 (const_string "*")))])
12093
12094 ;; This pattern can't accept a variable shift count, since shifts by
12095 ;; zero don't affect the flags. We assume that shifts by constant
12096 ;; zero are optimized away.
12097 (define_insn "*ashrhi3_cmp"
12098 [(set (reg 17)
12099 (compare
12100 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12101 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12102 (const_int 0)))
12103 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12104 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12105 "ix86_match_ccmode (insn, CCGOCmode)
12106 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12107 "sar{w}\t{%2, %0|%0, %2}"
12108 [(set_attr "type" "ishift")
12109 (set_attr "mode" "HI")])
12110
12111 (define_expand "ashrqi3"
12112 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12113 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12114 (match_operand:QI 2 "nonmemory_operand" "")))
12115 (clobber (reg:CC 17))]
12116 "TARGET_QIMODE_MATH"
12117 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12118
12119 (define_insn "*ashrqi3_1_one_bit"
12120 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12121 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12122 (match_operand:QI 2 "const_int_1_operand" "")))
12123 (clobber (reg:CC 17))]
12124 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12125 && (TARGET_SHIFT1 || optimize_size)"
12126 "sar{b}\t%0"
12127 [(set_attr "type" "ishift")
12128 (set (attr "length")
12129 (if_then_else (match_operand 0 "register_operand" "")
12130 (const_string "2")
12131 (const_string "*")))])
12132
12133 (define_insn "*ashrqi3_1_one_bit_slp"
12134 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12135 (ashiftrt:QI (match_dup 0)
12136 (match_operand:QI 1 "const_int_1_operand" "")))
12137 (clobber (reg:CC 17))]
12138 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12139 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12140 && (TARGET_SHIFT1 || optimize_size)"
12141 "sar{b}\t%0"
12142 [(set_attr "type" "ishift1")
12143 (set (attr "length")
12144 (if_then_else (match_operand 0 "register_operand" "")
12145 (const_string "2")
12146 (const_string "*")))])
12147
12148 (define_insn "*ashrqi3_1"
12149 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12150 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12151 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12152 (clobber (reg:CC 17))]
12153 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12154 "@
12155 sar{b}\t{%2, %0|%0, %2}
12156 sar{b}\t{%b2, %0|%0, %b2}"
12157 [(set_attr "type" "ishift")
12158 (set_attr "mode" "QI")])
12159
12160 (define_insn "*ashrqi3_1_slp"
12161 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12162 (ashiftrt:QI (match_dup 0)
12163 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12164 (clobber (reg:CC 17))]
12165 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12166 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12167 "@
12168 sar{b}\t{%1, %0|%0, %1}
12169 sar{b}\t{%b1, %0|%0, %b1}"
12170 [(set_attr "type" "ishift1")
12171 (set_attr "mode" "QI")])
12172
12173 ;; This pattern can't accept a variable shift count, since shifts by
12174 ;; zero don't affect the flags. We assume that shifts by constant
12175 ;; zero are optimized away.
12176 (define_insn "*ashrqi3_one_bit_cmp"
12177 [(set (reg 17)
12178 (compare
12179 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12180 (match_operand:QI 2 "const_int_1_operand" "I"))
12181 (const_int 0)))
12182 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12183 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12184 "ix86_match_ccmode (insn, CCGOCmode)
12185 && (TARGET_SHIFT1 || optimize_size)
12186 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12187 "sar{b}\t%0"
12188 [(set_attr "type" "ishift")
12189 (set (attr "length")
12190 (if_then_else (match_operand 0 "register_operand" "")
12191 (const_string "2")
12192 (const_string "*")))])
12193
12194 ;; This pattern can't accept a variable shift count, since shifts by
12195 ;; zero don't affect the flags. We assume that shifts by constant
12196 ;; zero are optimized away.
12197 (define_insn "*ashrqi3_cmp"
12198 [(set (reg 17)
12199 (compare
12200 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12201 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12202 (const_int 0)))
12203 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12204 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12205 "ix86_match_ccmode (insn, CCGOCmode)
12206 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12207 "sar{b}\t{%2, %0|%0, %2}"
12208 [(set_attr "type" "ishift")
12209 (set_attr "mode" "QI")])
12210 \f
12211 ;; Logical shift instructions
12212
12213 ;; See comment above `ashldi3' about how this works.
12214
12215 (define_expand "lshrdi3"
12216 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12217 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12218 (match_operand:QI 2 "nonmemory_operand" "")))
12219 (clobber (reg:CC 17))])]
12220 ""
12221 {
12222 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12223 {
12224 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12225 DONE;
12226 }
12227 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12228 DONE;
12229 })
12230
12231 (define_insn "*lshrdi3_1_one_bit_rex64"
12232 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12233 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const_int_1_operand" "")))
12235 (clobber (reg:CC 17))]
12236 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12237 && (TARGET_SHIFT1 || optimize_size)"
12238 "shr{q}\t%0"
12239 [(set_attr "type" "ishift")
12240 (set (attr "length")
12241 (if_then_else (match_operand:DI 0 "register_operand" "")
12242 (const_string "2")
12243 (const_string "*")))])
12244
12245 (define_insn "*lshrdi3_1_rex64"
12246 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12247 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12248 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12249 (clobber (reg:CC 17))]
12250 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12251 "@
12252 shr{q}\t{%2, %0|%0, %2}
12253 shr{q}\t{%b2, %0|%0, %b2}"
12254 [(set_attr "type" "ishift")
12255 (set_attr "mode" "DI")])
12256
12257 ;; This pattern can't accept a variable shift count, since shifts by
12258 ;; zero don't affect the flags. We assume that shifts by constant
12259 ;; zero are optimized away.
12260 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12261 [(set (reg 17)
12262 (compare
12263 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12264 (match_operand:QI 2 "const_int_1_operand" ""))
12265 (const_int 0)))
12266 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12267 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12268 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12269 && (TARGET_SHIFT1 || optimize_size)
12270 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12271 "shr{q}\t%0"
12272 [(set_attr "type" "ishift")
12273 (set (attr "length")
12274 (if_then_else (match_operand:DI 0 "register_operand" "")
12275 (const_string "2")
12276 (const_string "*")))])
12277
12278 ;; This pattern can't accept a variable shift count, since shifts by
12279 ;; zero don't affect the flags. We assume that shifts by constant
12280 ;; zero are optimized away.
12281 (define_insn "*lshrdi3_cmp_rex64"
12282 [(set (reg 17)
12283 (compare
12284 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12285 (match_operand:QI 2 "const_int_operand" "e"))
12286 (const_int 0)))
12287 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12288 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12289 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12290 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12291 "shr{q}\t{%2, %0|%0, %2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "DI")])
12294
12295 (define_insn "lshrdi3_1"
12296 [(set (match_operand:DI 0 "register_operand" "=r")
12297 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12298 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12299 (clobber (match_scratch:SI 3 "=&r"))
12300 (clobber (reg:CC 17))]
12301 "!TARGET_64BIT && TARGET_CMOVE"
12302 "#"
12303 [(set_attr "type" "multi")])
12304
12305 (define_insn "*lshrdi3_2"
12306 [(set (match_operand:DI 0 "register_operand" "=r")
12307 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12308 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12309 (clobber (reg:CC 17))]
12310 "!TARGET_64BIT"
12311 "#"
12312 [(set_attr "type" "multi")])
12313
12314 (define_split
12315 [(set (match_operand:DI 0 "register_operand" "")
12316 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12317 (match_operand:QI 2 "nonmemory_operand" "")))
12318 (clobber (match_scratch:SI 3 ""))
12319 (clobber (reg:CC 17))]
12320 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12321 [(const_int 0)]
12322 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12323
12324 (define_split
12325 [(set (match_operand:DI 0 "register_operand" "")
12326 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12327 (match_operand:QI 2 "nonmemory_operand" "")))
12328 (clobber (reg:CC 17))]
12329 "!TARGET_64BIT && reload_completed"
12330 [(const_int 0)]
12331 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12332
12333 (define_expand "lshrsi3"
12334 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12335 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12336 (match_operand:QI 2 "nonmemory_operand" "")))
12337 (clobber (reg:CC 17))]
12338 ""
12339 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12340
12341 (define_insn "*lshrsi3_1_one_bit"
12342 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12343 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12344 (match_operand:QI 2 "const_int_1_operand" "")))
12345 (clobber (reg:CC 17))]
12346 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12347 && (TARGET_SHIFT1 || optimize_size)"
12348 "shr{l}\t%0"
12349 [(set_attr "type" "ishift")
12350 (set (attr "length")
12351 (if_then_else (match_operand:SI 0 "register_operand" "")
12352 (const_string "2")
12353 (const_string "*")))])
12354
12355 (define_insn "*lshrsi3_1_one_bit_zext"
12356 [(set (match_operand:DI 0 "register_operand" "=r")
12357 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12358 (match_operand:QI 2 "const_int_1_operand" "")))
12359 (clobber (reg:CC 17))]
12360 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12361 && (TARGET_SHIFT1 || optimize_size)"
12362 "shr{l}\t%k0"
12363 [(set_attr "type" "ishift")
12364 (set_attr "length" "2")])
12365
12366 (define_insn "*lshrsi3_1"
12367 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12368 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12369 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12370 (clobber (reg:CC 17))]
12371 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12372 "@
12373 shr{l}\t{%2, %0|%0, %2}
12374 shr{l}\t{%b2, %0|%0, %b2}"
12375 [(set_attr "type" "ishift")
12376 (set_attr "mode" "SI")])
12377
12378 (define_insn "*lshrsi3_1_zext"
12379 [(set (match_operand:DI 0 "register_operand" "=r,r")
12380 (zero_extend:DI
12381 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12382 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12383 (clobber (reg:CC 17))]
12384 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12385 "@
12386 shr{l}\t{%2, %k0|%k0, %2}
12387 shr{l}\t{%b2, %k0|%k0, %b2}"
12388 [(set_attr "type" "ishift")
12389 (set_attr "mode" "SI")])
12390
12391 ;; This pattern can't accept a variable shift count, since shifts by
12392 ;; zero don't affect the flags. We assume that shifts by constant
12393 ;; zero are optimized away.
12394 (define_insn "*lshrsi3_one_bit_cmp"
12395 [(set (reg 17)
12396 (compare
12397 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const_int_1_operand" ""))
12399 (const_int 0)))
12400 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12401 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12402 "ix86_match_ccmode (insn, CCGOCmode)
12403 && (TARGET_SHIFT1 || optimize_size)
12404 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12405 "shr{l}\t%0"
12406 [(set_attr "type" "ishift")
12407 (set (attr "length")
12408 (if_then_else (match_operand:SI 0 "register_operand" "")
12409 (const_string "2")
12410 (const_string "*")))])
12411
12412 (define_insn "*lshrsi3_cmp_one_bit_zext"
12413 [(set (reg 17)
12414 (compare
12415 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12416 (match_operand:QI 2 "const_int_1_operand" ""))
12417 (const_int 0)))
12418 (set (match_operand:DI 0 "register_operand" "=r")
12419 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12420 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12421 && (TARGET_SHIFT1 || optimize_size)
12422 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12423 "shr{l}\t%k0"
12424 [(set_attr "type" "ishift")
12425 (set_attr "length" "2")])
12426
12427 ;; This pattern can't accept a variable shift count, since shifts by
12428 ;; zero don't affect the flags. We assume that shifts by constant
12429 ;; zero are optimized away.
12430 (define_insn "*lshrsi3_cmp"
12431 [(set (reg 17)
12432 (compare
12433 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12434 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12435 (const_int 0)))
12436 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12437 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12438 "ix86_match_ccmode (insn, CCGOCmode)
12439 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12440 "shr{l}\t{%2, %0|%0, %2}"
12441 [(set_attr "type" "ishift")
12442 (set_attr "mode" "SI")])
12443
12444 (define_insn "*lshrsi3_cmp_zext"
12445 [(set (reg 17)
12446 (compare
12447 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12448 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12449 (const_int 0)))
12450 (set (match_operand:DI 0 "register_operand" "=r")
12451 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12452 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12453 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12454 "shr{l}\t{%2, %k0|%k0, %2}"
12455 [(set_attr "type" "ishift")
12456 (set_attr "mode" "SI")])
12457
12458 (define_expand "lshrhi3"
12459 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12460 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12461 (match_operand:QI 2 "nonmemory_operand" "")))
12462 (clobber (reg:CC 17))]
12463 "TARGET_HIMODE_MATH"
12464 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12465
12466 (define_insn "*lshrhi3_1_one_bit"
12467 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12468 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12469 (match_operand:QI 2 "const_int_1_operand" "")))
12470 (clobber (reg:CC 17))]
12471 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12472 && (TARGET_SHIFT1 || optimize_size)"
12473 "shr{w}\t%0"
12474 [(set_attr "type" "ishift")
12475 (set (attr "length")
12476 (if_then_else (match_operand 0 "register_operand" "")
12477 (const_string "2")
12478 (const_string "*")))])
12479
12480 (define_insn "*lshrhi3_1"
12481 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12482 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12483 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12484 (clobber (reg:CC 17))]
12485 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12486 "@
12487 shr{w}\t{%2, %0|%0, %2}
12488 shr{w}\t{%b2, %0|%0, %b2}"
12489 [(set_attr "type" "ishift")
12490 (set_attr "mode" "HI")])
12491
12492 ;; This pattern can't accept a variable shift count, since shifts by
12493 ;; zero don't affect the flags. We assume that shifts by constant
12494 ;; zero are optimized away.
12495 (define_insn "*lshrhi3_one_bit_cmp"
12496 [(set (reg 17)
12497 (compare
12498 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12499 (match_operand:QI 2 "const_int_1_operand" ""))
12500 (const_int 0)))
12501 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12502 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12503 "ix86_match_ccmode (insn, CCGOCmode)
12504 && (TARGET_SHIFT1 || optimize_size)
12505 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12506 "shr{w}\t%0"
12507 [(set_attr "type" "ishift")
12508 (set (attr "length")
12509 (if_then_else (match_operand:SI 0 "register_operand" "")
12510 (const_string "2")
12511 (const_string "*")))])
12512
12513 ;; This pattern can't accept a variable shift count, since shifts by
12514 ;; zero don't affect the flags. We assume that shifts by constant
12515 ;; zero are optimized away.
12516 (define_insn "*lshrhi3_cmp"
12517 [(set (reg 17)
12518 (compare
12519 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12520 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12521 (const_int 0)))
12522 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12523 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12524 "ix86_match_ccmode (insn, CCGOCmode)
12525 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12526 "shr{w}\t{%2, %0|%0, %2}"
12527 [(set_attr "type" "ishift")
12528 (set_attr "mode" "HI")])
12529
12530 (define_expand "lshrqi3"
12531 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12532 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12533 (match_operand:QI 2 "nonmemory_operand" "")))
12534 (clobber (reg:CC 17))]
12535 "TARGET_QIMODE_MATH"
12536 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12537
12538 (define_insn "*lshrqi3_1_one_bit"
12539 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12540 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12541 (match_operand:QI 2 "const_int_1_operand" "")))
12542 (clobber (reg:CC 17))]
12543 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12544 && (TARGET_SHIFT1 || optimize_size)"
12545 "shr{b}\t%0"
12546 [(set_attr "type" "ishift")
12547 (set (attr "length")
12548 (if_then_else (match_operand 0 "register_operand" "")
12549 (const_string "2")
12550 (const_string "*")))])
12551
12552 (define_insn "*lshrqi3_1_one_bit_slp"
12553 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12554 (lshiftrt:QI (match_dup 0)
12555 (match_operand:QI 1 "const_int_1_operand" "")))
12556 (clobber (reg:CC 17))]
12557 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12558 && (TARGET_SHIFT1 || optimize_size)"
12559 "shr{b}\t%0"
12560 [(set_attr "type" "ishift1")
12561 (set (attr "length")
12562 (if_then_else (match_operand 0 "register_operand" "")
12563 (const_string "2")
12564 (const_string "*")))])
12565
12566 (define_insn "*lshrqi3_1"
12567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12568 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12569 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12570 (clobber (reg:CC 17))]
12571 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12572 "@
12573 shr{b}\t{%2, %0|%0, %2}
12574 shr{b}\t{%b2, %0|%0, %b2}"
12575 [(set_attr "type" "ishift")
12576 (set_attr "mode" "QI")])
12577
12578 (define_insn "*lshrqi3_1_slp"
12579 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12580 (lshiftrt:QI (match_dup 0)
12581 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12582 (clobber (reg:CC 17))]
12583 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12584 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12585 "@
12586 shr{b}\t{%1, %0|%0, %1}
12587 shr{b}\t{%b1, %0|%0, %b1}"
12588 [(set_attr "type" "ishift1")
12589 (set_attr "mode" "QI")])
12590
12591 ;; This pattern can't accept a variable shift count, since shifts by
12592 ;; zero don't affect the flags. We assume that shifts by constant
12593 ;; zero are optimized away.
12594 (define_insn "*lshrqi2_one_bit_cmp"
12595 [(set (reg 17)
12596 (compare
12597 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12598 (match_operand:QI 2 "const_int_1_operand" ""))
12599 (const_int 0)))
12600 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12601 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12602 "ix86_match_ccmode (insn, CCGOCmode)
12603 && (TARGET_SHIFT1 || optimize_size)
12604 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12605 "shr{b}\t%0"
12606 [(set_attr "type" "ishift")
12607 (set (attr "length")
12608 (if_then_else (match_operand:SI 0 "register_operand" "")
12609 (const_string "2")
12610 (const_string "*")))])
12611
12612 ;; This pattern can't accept a variable shift count, since shifts by
12613 ;; zero don't affect the flags. We assume that shifts by constant
12614 ;; zero are optimized away.
12615 (define_insn "*lshrqi2_cmp"
12616 [(set (reg 17)
12617 (compare
12618 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12619 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12620 (const_int 0)))
12621 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12622 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12623 "ix86_match_ccmode (insn, CCGOCmode)
12624 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12625 "shr{b}\t{%2, %0|%0, %2}"
12626 [(set_attr "type" "ishift")
12627 (set_attr "mode" "QI")])
12628 \f
12629 ;; Rotate instructions
12630
12631 (define_expand "rotldi3"
12632 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12633 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12634 (match_operand:QI 2 "nonmemory_operand" "")))
12635 (clobber (reg:CC 17))]
12636 "TARGET_64BIT"
12637 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12638
12639 (define_insn "*rotlsi3_1_one_bit_rex64"
12640 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12641 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12642 (match_operand:QI 2 "const_int_1_operand" "")))
12643 (clobber (reg:CC 17))]
12644 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12645 && (TARGET_SHIFT1 || optimize_size)"
12646 "rol{q}\t%0"
12647 [(set_attr "type" "rotate")
12648 (set (attr "length")
12649 (if_then_else (match_operand:DI 0 "register_operand" "")
12650 (const_string "2")
12651 (const_string "*")))])
12652
12653 (define_insn "*rotldi3_1_rex64"
12654 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12655 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12656 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12657 (clobber (reg:CC 17))]
12658 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12659 "@
12660 rol{q}\t{%2, %0|%0, %2}
12661 rol{q}\t{%b2, %0|%0, %b2}"
12662 [(set_attr "type" "rotate")
12663 (set_attr "mode" "DI")])
12664
12665 (define_expand "rotlsi3"
12666 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12667 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12668 (match_operand:QI 2 "nonmemory_operand" "")))
12669 (clobber (reg:CC 17))]
12670 ""
12671 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12672
12673 (define_insn "*rotlsi3_1_one_bit"
12674 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12675 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12676 (match_operand:QI 2 "const_int_1_operand" "")))
12677 (clobber (reg:CC 17))]
12678 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12679 && (TARGET_SHIFT1 || optimize_size)"
12680 "rol{l}\t%0"
12681 [(set_attr "type" "rotate")
12682 (set (attr "length")
12683 (if_then_else (match_operand:SI 0 "register_operand" "")
12684 (const_string "2")
12685 (const_string "*")))])
12686
12687 (define_insn "*rotlsi3_1_one_bit_zext"
12688 [(set (match_operand:DI 0 "register_operand" "=r")
12689 (zero_extend:DI
12690 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12691 (match_operand:QI 2 "const_int_1_operand" ""))))
12692 (clobber (reg:CC 17))]
12693 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12694 && (TARGET_SHIFT1 || optimize_size)"
12695 "rol{l}\t%k0"
12696 [(set_attr "type" "rotate")
12697 (set_attr "length" "2")])
12698
12699 (define_insn "*rotlsi3_1"
12700 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12701 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12702 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12703 (clobber (reg:CC 17))]
12704 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12705 "@
12706 rol{l}\t{%2, %0|%0, %2}
12707 rol{l}\t{%b2, %0|%0, %b2}"
12708 [(set_attr "type" "rotate")
12709 (set_attr "mode" "SI")])
12710
12711 (define_insn "*rotlsi3_1_zext"
12712 [(set (match_operand:DI 0 "register_operand" "=r,r")
12713 (zero_extend:DI
12714 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12715 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12716 (clobber (reg:CC 17))]
12717 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12718 "@
12719 rol{l}\t{%2, %k0|%k0, %2}
12720 rol{l}\t{%b2, %k0|%k0, %b2}"
12721 [(set_attr "type" "rotate")
12722 (set_attr "mode" "SI")])
12723
12724 (define_expand "rotlhi3"
12725 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12726 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12727 (match_operand:QI 2 "nonmemory_operand" "")))
12728 (clobber (reg:CC 17))]
12729 "TARGET_HIMODE_MATH"
12730 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12731
12732 (define_insn "*rotlhi3_1_one_bit"
12733 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12734 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12735 (match_operand:QI 2 "const_int_1_operand" "")))
12736 (clobber (reg:CC 17))]
12737 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12738 && (TARGET_SHIFT1 || optimize_size)"
12739 "rol{w}\t%0"
12740 [(set_attr "type" "rotate")
12741 (set (attr "length")
12742 (if_then_else (match_operand 0 "register_operand" "")
12743 (const_string "2")
12744 (const_string "*")))])
12745
12746 (define_insn "*rotlhi3_1"
12747 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12748 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12749 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12750 (clobber (reg:CC 17))]
12751 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12752 "@
12753 rol{w}\t{%2, %0|%0, %2}
12754 rol{w}\t{%b2, %0|%0, %b2}"
12755 [(set_attr "type" "rotate")
12756 (set_attr "mode" "HI")])
12757
12758 (define_expand "rotlqi3"
12759 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12760 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12761 (match_operand:QI 2 "nonmemory_operand" "")))
12762 (clobber (reg:CC 17))]
12763 "TARGET_QIMODE_MATH"
12764 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12765
12766 (define_insn "*rotlqi3_1_one_bit_slp"
12767 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12768 (rotate:QI (match_dup 0)
12769 (match_operand:QI 1 "const_int_1_operand" "")))
12770 (clobber (reg:CC 17))]
12771 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12772 && (TARGET_SHIFT1 || optimize_size)"
12773 "rol{b}\t%0"
12774 [(set_attr "type" "rotate1")
12775 (set (attr "length")
12776 (if_then_else (match_operand 0 "register_operand" "")
12777 (const_string "2")
12778 (const_string "*")))])
12779
12780 (define_insn "*rotlqi3_1_one_bit"
12781 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12782 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12783 (match_operand:QI 2 "const_int_1_operand" "")))
12784 (clobber (reg:CC 17))]
12785 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12786 && (TARGET_SHIFT1 || optimize_size)"
12787 "rol{b}\t%0"
12788 [(set_attr "type" "rotate")
12789 (set (attr "length")
12790 (if_then_else (match_operand 0 "register_operand" "")
12791 (const_string "2")
12792 (const_string "*")))])
12793
12794 (define_insn "*rotlqi3_1_slp"
12795 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12796 (rotate:QI (match_dup 0)
12797 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12798 (clobber (reg:CC 17))]
12799 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12800 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12801 "@
12802 rol{b}\t{%1, %0|%0, %1}
12803 rol{b}\t{%b1, %0|%0, %b1}"
12804 [(set_attr "type" "rotate1")
12805 (set_attr "mode" "QI")])
12806
12807 (define_insn "*rotlqi3_1"
12808 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12809 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12810 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12811 (clobber (reg:CC 17))]
12812 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12813 "@
12814 rol{b}\t{%2, %0|%0, %2}
12815 rol{b}\t{%b2, %0|%0, %b2}"
12816 [(set_attr "type" "rotate")
12817 (set_attr "mode" "QI")])
12818
12819 (define_expand "rotrdi3"
12820 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12821 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12822 (match_operand:QI 2 "nonmemory_operand" "")))
12823 (clobber (reg:CC 17))]
12824 "TARGET_64BIT"
12825 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12826
12827 (define_insn "*rotrdi3_1_one_bit_rex64"
12828 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12829 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12830 (match_operand:QI 2 "const_int_1_operand" "")))
12831 (clobber (reg:CC 17))]
12832 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12833 && (TARGET_SHIFT1 || optimize_size)"
12834 "ror{q}\t%0"
12835 [(set_attr "type" "rotate")
12836 (set (attr "length")
12837 (if_then_else (match_operand:DI 0 "register_operand" "")
12838 (const_string "2")
12839 (const_string "*")))])
12840
12841 (define_insn "*rotrdi3_1_rex64"
12842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12843 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12844 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12845 (clobber (reg:CC 17))]
12846 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12847 "@
12848 ror{q}\t{%2, %0|%0, %2}
12849 ror{q}\t{%b2, %0|%0, %b2}"
12850 [(set_attr "type" "rotate")
12851 (set_attr "mode" "DI")])
12852
12853 (define_expand "rotrsi3"
12854 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12855 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12856 (match_operand:QI 2 "nonmemory_operand" "")))
12857 (clobber (reg:CC 17))]
12858 ""
12859 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12860
12861 (define_insn "*rotrsi3_1_one_bit"
12862 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12863 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12864 (match_operand:QI 2 "const_int_1_operand" "")))
12865 (clobber (reg:CC 17))]
12866 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12867 && (TARGET_SHIFT1 || optimize_size)"
12868 "ror{l}\t%0"
12869 [(set_attr "type" "rotate")
12870 (set (attr "length")
12871 (if_then_else (match_operand:SI 0 "register_operand" "")
12872 (const_string "2")
12873 (const_string "*")))])
12874
12875 (define_insn "*rotrsi3_1_one_bit_zext"
12876 [(set (match_operand:DI 0 "register_operand" "=r")
12877 (zero_extend:DI
12878 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12879 (match_operand:QI 2 "const_int_1_operand" ""))))
12880 (clobber (reg:CC 17))]
12881 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12882 && (TARGET_SHIFT1 || optimize_size)"
12883 "ror{l}\t%k0"
12884 [(set_attr "type" "rotate")
12885 (set (attr "length")
12886 (if_then_else (match_operand:SI 0 "register_operand" "")
12887 (const_string "2")
12888 (const_string "*")))])
12889
12890 (define_insn "*rotrsi3_1"
12891 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12892 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12893 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12894 (clobber (reg:CC 17))]
12895 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12896 "@
12897 ror{l}\t{%2, %0|%0, %2}
12898 ror{l}\t{%b2, %0|%0, %b2}"
12899 [(set_attr "type" "rotate")
12900 (set_attr "mode" "SI")])
12901
12902 (define_insn "*rotrsi3_1_zext"
12903 [(set (match_operand:DI 0 "register_operand" "=r,r")
12904 (zero_extend:DI
12905 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12906 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12907 (clobber (reg:CC 17))]
12908 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12909 "@
12910 ror{l}\t{%2, %k0|%k0, %2}
12911 ror{l}\t{%b2, %k0|%k0, %b2}"
12912 [(set_attr "type" "rotate")
12913 (set_attr "mode" "SI")])
12914
12915 (define_expand "rotrhi3"
12916 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12917 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12918 (match_operand:QI 2 "nonmemory_operand" "")))
12919 (clobber (reg:CC 17))]
12920 "TARGET_HIMODE_MATH"
12921 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12922
12923 (define_insn "*rotrhi3_one_bit"
12924 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12925 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12926 (match_operand:QI 2 "const_int_1_operand" "")))
12927 (clobber (reg:CC 17))]
12928 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12929 && (TARGET_SHIFT1 || optimize_size)"
12930 "ror{w}\t%0"
12931 [(set_attr "type" "rotate")
12932 (set (attr "length")
12933 (if_then_else (match_operand 0 "register_operand" "")
12934 (const_string "2")
12935 (const_string "*")))])
12936
12937 (define_insn "*rotrhi3"
12938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12939 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12940 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12941 (clobber (reg:CC 17))]
12942 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12943 "@
12944 ror{w}\t{%2, %0|%0, %2}
12945 ror{w}\t{%b2, %0|%0, %b2}"
12946 [(set_attr "type" "rotate")
12947 (set_attr "mode" "HI")])
12948
12949 (define_expand "rotrqi3"
12950 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12951 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12952 (match_operand:QI 2 "nonmemory_operand" "")))
12953 (clobber (reg:CC 17))]
12954 "TARGET_QIMODE_MATH"
12955 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12956
12957 (define_insn "*rotrqi3_1_one_bit"
12958 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12959 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12960 (match_operand:QI 2 "const_int_1_operand" "")))
12961 (clobber (reg:CC 17))]
12962 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12963 && (TARGET_SHIFT1 || optimize_size)"
12964 "ror{b}\t%0"
12965 [(set_attr "type" "rotate")
12966 (set (attr "length")
12967 (if_then_else (match_operand 0 "register_operand" "")
12968 (const_string "2")
12969 (const_string "*")))])
12970
12971 (define_insn "*rotrqi3_1_one_bit_slp"
12972 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12973 (rotatert:QI (match_dup 0)
12974 (match_operand:QI 1 "const_int_1_operand" "")))
12975 (clobber (reg:CC 17))]
12976 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12977 && (TARGET_SHIFT1 || optimize_size)"
12978 "ror{b}\t%0"
12979 [(set_attr "type" "rotate1")
12980 (set (attr "length")
12981 (if_then_else (match_operand 0 "register_operand" "")
12982 (const_string "2")
12983 (const_string "*")))])
12984
12985 (define_insn "*rotrqi3_1"
12986 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12987 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12988 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12989 (clobber (reg:CC 17))]
12990 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12991 "@
12992 ror{b}\t{%2, %0|%0, %2}
12993 ror{b}\t{%b2, %0|%0, %b2}"
12994 [(set_attr "type" "rotate")
12995 (set_attr "mode" "QI")])
12996
12997 (define_insn "*rotrqi3_1_slp"
12998 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12999 (rotatert:QI (match_dup 0)
13000 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13001 (clobber (reg:CC 17))]
13002 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13003 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13004 "@
13005 ror{b}\t{%1, %0|%0, %1}
13006 ror{b}\t{%b1, %0|%0, %b1}"
13007 [(set_attr "type" "rotate1")
13008 (set_attr "mode" "QI")])
13009 \f
13010 ;; Bit set / bit test instructions
13011
13012 (define_expand "extv"
13013 [(set (match_operand:SI 0 "register_operand" "")
13014 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13015 (match_operand:SI 2 "immediate_operand" "")
13016 (match_operand:SI 3 "immediate_operand" "")))]
13017 ""
13018 {
13019 /* Handle extractions from %ah et al. */
13020 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13021 FAIL;
13022
13023 /* From mips.md: extract_bit_field doesn't verify that our source
13024 matches the predicate, so check it again here. */
13025 if (! register_operand (operands[1], VOIDmode))
13026 FAIL;
13027 })
13028
13029 (define_expand "extzv"
13030 [(set (match_operand:SI 0 "register_operand" "")
13031 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13032 (match_operand:SI 2 "immediate_operand" "")
13033 (match_operand:SI 3 "immediate_operand" "")))]
13034 ""
13035 {
13036 /* Handle extractions from %ah et al. */
13037 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13038 FAIL;
13039
13040 /* From mips.md: extract_bit_field doesn't verify that our source
13041 matches the predicate, so check it again here. */
13042 if (! register_operand (operands[1], VOIDmode))
13043 FAIL;
13044 })
13045
13046 (define_expand "insv"
13047 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13048 (match_operand:SI 1 "immediate_operand" "")
13049 (match_operand:SI 2 "immediate_operand" ""))
13050 (match_operand:SI 3 "register_operand" ""))]
13051 ""
13052 {
13053 /* Handle extractions from %ah et al. */
13054 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13055 FAIL;
13056
13057 /* From mips.md: insert_bit_field doesn't verify that our source
13058 matches the predicate, so check it again here. */
13059 if (! register_operand (operands[0], VOIDmode))
13060 FAIL;
13061 })
13062
13063 ;; %%% bts, btr, btc, bt.
13064 \f
13065 ;; Store-flag instructions.
13066
13067 ;; For all sCOND expanders, also expand the compare or test insn that
13068 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13069
13070 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13071 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13072 ;; way, which can later delete the movzx if only QImode is needed.
13073
13074 (define_expand "seq"
13075 [(set (match_operand:QI 0 "register_operand" "")
13076 (eq:QI (reg:CC 17) (const_int 0)))]
13077 ""
13078 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13079
13080 (define_expand "sne"
13081 [(set (match_operand:QI 0 "register_operand" "")
13082 (ne:QI (reg:CC 17) (const_int 0)))]
13083 ""
13084 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13085
13086 (define_expand "sgt"
13087 [(set (match_operand:QI 0 "register_operand" "")
13088 (gt:QI (reg:CC 17) (const_int 0)))]
13089 ""
13090 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13091
13092 (define_expand "sgtu"
13093 [(set (match_operand:QI 0 "register_operand" "")
13094 (gtu:QI (reg:CC 17) (const_int 0)))]
13095 ""
13096 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13097
13098 (define_expand "slt"
13099 [(set (match_operand:QI 0 "register_operand" "")
13100 (lt:QI (reg:CC 17) (const_int 0)))]
13101 ""
13102 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13103
13104 (define_expand "sltu"
13105 [(set (match_operand:QI 0 "register_operand" "")
13106 (ltu:QI (reg:CC 17) (const_int 0)))]
13107 ""
13108 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13109
13110 (define_expand "sge"
13111 [(set (match_operand:QI 0 "register_operand" "")
13112 (ge:QI (reg:CC 17) (const_int 0)))]
13113 ""
13114 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13115
13116 (define_expand "sgeu"
13117 [(set (match_operand:QI 0 "register_operand" "")
13118 (geu:QI (reg:CC 17) (const_int 0)))]
13119 ""
13120 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13121
13122 (define_expand "sle"
13123 [(set (match_operand:QI 0 "register_operand" "")
13124 (le:QI (reg:CC 17) (const_int 0)))]
13125 ""
13126 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13127
13128 (define_expand "sleu"
13129 [(set (match_operand:QI 0 "register_operand" "")
13130 (leu:QI (reg:CC 17) (const_int 0)))]
13131 ""
13132 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13133
13134 (define_expand "sunordered"
13135 [(set (match_operand:QI 0 "register_operand" "")
13136 (unordered:QI (reg:CC 17) (const_int 0)))]
13137 "TARGET_80387 || TARGET_SSE"
13138 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13139
13140 (define_expand "sordered"
13141 [(set (match_operand:QI 0 "register_operand" "")
13142 (ordered:QI (reg:CC 17) (const_int 0)))]
13143 "TARGET_80387"
13144 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13145
13146 (define_expand "suneq"
13147 [(set (match_operand:QI 0 "register_operand" "")
13148 (uneq:QI (reg:CC 17) (const_int 0)))]
13149 "TARGET_80387 || TARGET_SSE"
13150 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13151
13152 (define_expand "sunge"
13153 [(set (match_operand:QI 0 "register_operand" "")
13154 (unge:QI (reg:CC 17) (const_int 0)))]
13155 "TARGET_80387 || TARGET_SSE"
13156 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13157
13158 (define_expand "sungt"
13159 [(set (match_operand:QI 0 "register_operand" "")
13160 (ungt:QI (reg:CC 17) (const_int 0)))]
13161 "TARGET_80387 || TARGET_SSE"
13162 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13163
13164 (define_expand "sunle"
13165 [(set (match_operand:QI 0 "register_operand" "")
13166 (unle:QI (reg:CC 17) (const_int 0)))]
13167 "TARGET_80387 || TARGET_SSE"
13168 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13169
13170 (define_expand "sunlt"
13171 [(set (match_operand:QI 0 "register_operand" "")
13172 (unlt:QI (reg:CC 17) (const_int 0)))]
13173 "TARGET_80387 || TARGET_SSE"
13174 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13175
13176 (define_expand "sltgt"
13177 [(set (match_operand:QI 0 "register_operand" "")
13178 (ltgt:QI (reg:CC 17) (const_int 0)))]
13179 "TARGET_80387 || TARGET_SSE"
13180 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13181
13182 (define_insn "*setcc_1"
13183 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13184 (match_operator:QI 1 "ix86_comparison_operator"
13185 [(reg 17) (const_int 0)]))]
13186 ""
13187 "set%C1\t%0"
13188 [(set_attr "type" "setcc")
13189 (set_attr "mode" "QI")])
13190
13191 (define_insn "setcc_2"
13192 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13193 (match_operator:QI 1 "ix86_comparison_operator"
13194 [(reg 17) (const_int 0)]))]
13195 ""
13196 "set%C1\t%0"
13197 [(set_attr "type" "setcc")
13198 (set_attr "mode" "QI")])
13199
13200 ;; In general it is not safe to assume too much about CCmode registers,
13201 ;; so simplify-rtx stops when it sees a second one. Under certain
13202 ;; conditions this is safe on x86, so help combine not create
13203 ;;
13204 ;; seta %al
13205 ;; testb %al, %al
13206 ;; sete %al
13207
13208 (define_split
13209 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13210 (ne:QI (match_operator 1 "ix86_comparison_operator"
13211 [(reg 17) (const_int 0)])
13212 (const_int 0)))]
13213 ""
13214 [(set (match_dup 0) (match_dup 1))]
13215 {
13216 PUT_MODE (operands[1], QImode);
13217 })
13218
13219 (define_split
13220 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13221 (ne:QI (match_operator 1 "ix86_comparison_operator"
13222 [(reg 17) (const_int 0)])
13223 (const_int 0)))]
13224 ""
13225 [(set (match_dup 0) (match_dup 1))]
13226 {
13227 PUT_MODE (operands[1], QImode);
13228 })
13229
13230 (define_split
13231 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13232 (eq:QI (match_operator 1 "ix86_comparison_operator"
13233 [(reg 17) (const_int 0)])
13234 (const_int 0)))]
13235 ""
13236 [(set (match_dup 0) (match_dup 1))]
13237 {
13238 rtx new_op1 = copy_rtx (operands[1]);
13239 operands[1] = new_op1;
13240 PUT_MODE (new_op1, QImode);
13241 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13242 GET_MODE (XEXP (new_op1, 0))));
13243
13244 /* Make sure that (a) the CCmode we have for the flags is strong
13245 enough for the reversed compare or (b) we have a valid FP compare. */
13246 if (! ix86_comparison_operator (new_op1, VOIDmode))
13247 FAIL;
13248 })
13249
13250 (define_split
13251 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13252 (eq:QI (match_operator 1 "ix86_comparison_operator"
13253 [(reg 17) (const_int 0)])
13254 (const_int 0)))]
13255 ""
13256 [(set (match_dup 0) (match_dup 1))]
13257 {
13258 rtx new_op1 = copy_rtx (operands[1]);
13259 operands[1] = new_op1;
13260 PUT_MODE (new_op1, QImode);
13261 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13262 GET_MODE (XEXP (new_op1, 0))));
13263
13264 /* Make sure that (a) the CCmode we have for the flags is strong
13265 enough for the reversed compare or (b) we have a valid FP compare. */
13266 if (! ix86_comparison_operator (new_op1, VOIDmode))
13267 FAIL;
13268 })
13269
13270 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13271 ;; subsequent logical operations are used to imitate conditional moves.
13272 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13273 ;; it directly. Further holding this value in pseudo register might bring
13274 ;; problem in implicit normalization in spill code.
13275 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13276 ;; instructions after reload by splitting the conditional move patterns.
13277
13278 (define_insn "*sse_setccsf"
13279 [(set (match_operand:SF 0 "register_operand" "=x")
13280 (match_operator:SF 1 "sse_comparison_operator"
13281 [(match_operand:SF 2 "register_operand" "0")
13282 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13283 "TARGET_SSE && reload_completed"
13284 "cmp%D1ss\t{%3, %0|%0, %3}"
13285 [(set_attr "type" "ssecmp")
13286 (set_attr "mode" "SF")])
13287
13288 (define_insn "*sse_setccdf"
13289 [(set (match_operand:DF 0 "register_operand" "=Y")
13290 (match_operator:DF 1 "sse_comparison_operator"
13291 [(match_operand:DF 2 "register_operand" "0")
13292 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13293 "TARGET_SSE2 && reload_completed"
13294 "cmp%D1sd\t{%3, %0|%0, %3}"
13295 [(set_attr "type" "ssecmp")
13296 (set_attr "mode" "DF")])
13297 \f
13298 ;; Basic conditional jump instructions.
13299 ;; We ignore the overflow flag for signed branch instructions.
13300
13301 ;; For all bCOND expanders, also expand the compare or test insn that
13302 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13303
13304 (define_expand "beq"
13305 [(set (pc)
13306 (if_then_else (match_dup 1)
13307 (label_ref (match_operand 0 "" ""))
13308 (pc)))]
13309 ""
13310 "ix86_expand_branch (EQ, operands[0]); DONE;")
13311
13312 (define_expand "bne"
13313 [(set (pc)
13314 (if_then_else (match_dup 1)
13315 (label_ref (match_operand 0 "" ""))
13316 (pc)))]
13317 ""
13318 "ix86_expand_branch (NE, operands[0]); DONE;")
13319
13320 (define_expand "bgt"
13321 [(set (pc)
13322 (if_then_else (match_dup 1)
13323 (label_ref (match_operand 0 "" ""))
13324 (pc)))]
13325 ""
13326 "ix86_expand_branch (GT, operands[0]); DONE;")
13327
13328 (define_expand "bgtu"
13329 [(set (pc)
13330 (if_then_else (match_dup 1)
13331 (label_ref (match_operand 0 "" ""))
13332 (pc)))]
13333 ""
13334 "ix86_expand_branch (GTU, operands[0]); DONE;")
13335
13336 (define_expand "blt"
13337 [(set (pc)
13338 (if_then_else (match_dup 1)
13339 (label_ref (match_operand 0 "" ""))
13340 (pc)))]
13341 ""
13342 "ix86_expand_branch (LT, operands[0]); DONE;")
13343
13344 (define_expand "bltu"
13345 [(set (pc)
13346 (if_then_else (match_dup 1)
13347 (label_ref (match_operand 0 "" ""))
13348 (pc)))]
13349 ""
13350 "ix86_expand_branch (LTU, operands[0]); DONE;")
13351
13352 (define_expand "bge"
13353 [(set (pc)
13354 (if_then_else (match_dup 1)
13355 (label_ref (match_operand 0 "" ""))
13356 (pc)))]
13357 ""
13358 "ix86_expand_branch (GE, operands[0]); DONE;")
13359
13360 (define_expand "bgeu"
13361 [(set (pc)
13362 (if_then_else (match_dup 1)
13363 (label_ref (match_operand 0 "" ""))
13364 (pc)))]
13365 ""
13366 "ix86_expand_branch (GEU, operands[0]); DONE;")
13367
13368 (define_expand "ble"
13369 [(set (pc)
13370 (if_then_else (match_dup 1)
13371 (label_ref (match_operand 0 "" ""))
13372 (pc)))]
13373 ""
13374 "ix86_expand_branch (LE, operands[0]); DONE;")
13375
13376 (define_expand "bleu"
13377 [(set (pc)
13378 (if_then_else (match_dup 1)
13379 (label_ref (match_operand 0 "" ""))
13380 (pc)))]
13381 ""
13382 "ix86_expand_branch (LEU, operands[0]); DONE;")
13383
13384 (define_expand "bunordered"
13385 [(set (pc)
13386 (if_then_else (match_dup 1)
13387 (label_ref (match_operand 0 "" ""))
13388 (pc)))]
13389 "TARGET_80387 || TARGET_SSE"
13390 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13391
13392 (define_expand "bordered"
13393 [(set (pc)
13394 (if_then_else (match_dup 1)
13395 (label_ref (match_operand 0 "" ""))
13396 (pc)))]
13397 "TARGET_80387 || TARGET_SSE"
13398 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13399
13400 (define_expand "buneq"
13401 [(set (pc)
13402 (if_then_else (match_dup 1)
13403 (label_ref (match_operand 0 "" ""))
13404 (pc)))]
13405 "TARGET_80387 || TARGET_SSE"
13406 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13407
13408 (define_expand "bunge"
13409 [(set (pc)
13410 (if_then_else (match_dup 1)
13411 (label_ref (match_operand 0 "" ""))
13412 (pc)))]
13413 "TARGET_80387 || TARGET_SSE"
13414 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13415
13416 (define_expand "bungt"
13417 [(set (pc)
13418 (if_then_else (match_dup 1)
13419 (label_ref (match_operand 0 "" ""))
13420 (pc)))]
13421 "TARGET_80387 || TARGET_SSE"
13422 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13423
13424 (define_expand "bunle"
13425 [(set (pc)
13426 (if_then_else (match_dup 1)
13427 (label_ref (match_operand 0 "" ""))
13428 (pc)))]
13429 "TARGET_80387 || TARGET_SSE"
13430 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13431
13432 (define_expand "bunlt"
13433 [(set (pc)
13434 (if_then_else (match_dup 1)
13435 (label_ref (match_operand 0 "" ""))
13436 (pc)))]
13437 "TARGET_80387 || TARGET_SSE"
13438 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13439
13440 (define_expand "bltgt"
13441 [(set (pc)
13442 (if_then_else (match_dup 1)
13443 (label_ref (match_operand 0 "" ""))
13444 (pc)))]
13445 "TARGET_80387 || TARGET_SSE"
13446 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13447
13448 (define_insn "*jcc_1"
13449 [(set (pc)
13450 (if_then_else (match_operator 1 "ix86_comparison_operator"
13451 [(reg 17) (const_int 0)])
13452 (label_ref (match_operand 0 "" ""))
13453 (pc)))]
13454 ""
13455 "%+j%C1\t%l0"
13456 [(set_attr "type" "ibr")
13457 (set_attr "modrm" "0")
13458 (set (attr "length")
13459 (if_then_else (and (ge (minus (match_dup 0) (pc))
13460 (const_int -126))
13461 (lt (minus (match_dup 0) (pc))
13462 (const_int 128)))
13463 (const_int 2)
13464 (const_int 6)))])
13465
13466 (define_insn "*jcc_2"
13467 [(set (pc)
13468 (if_then_else (match_operator 1 "ix86_comparison_operator"
13469 [(reg 17) (const_int 0)])
13470 (pc)
13471 (label_ref (match_operand 0 "" ""))))]
13472 ""
13473 "%+j%c1\t%l0"
13474 [(set_attr "type" "ibr")
13475 (set_attr "modrm" "0")
13476 (set (attr "length")
13477 (if_then_else (and (ge (minus (match_dup 0) (pc))
13478 (const_int -126))
13479 (lt (minus (match_dup 0) (pc))
13480 (const_int 128)))
13481 (const_int 2)
13482 (const_int 6)))])
13483
13484 ;; In general it is not safe to assume too much about CCmode registers,
13485 ;; so simplify-rtx stops when it sees a second one. Under certain
13486 ;; conditions this is safe on x86, so help combine not create
13487 ;;
13488 ;; seta %al
13489 ;; testb %al, %al
13490 ;; je Lfoo
13491
13492 (define_split
13493 [(set (pc)
13494 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13495 [(reg 17) (const_int 0)])
13496 (const_int 0))
13497 (label_ref (match_operand 1 "" ""))
13498 (pc)))]
13499 ""
13500 [(set (pc)
13501 (if_then_else (match_dup 0)
13502 (label_ref (match_dup 1))
13503 (pc)))]
13504 {
13505 PUT_MODE (operands[0], VOIDmode);
13506 })
13507
13508 (define_split
13509 [(set (pc)
13510 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13511 [(reg 17) (const_int 0)])
13512 (const_int 0))
13513 (label_ref (match_operand 1 "" ""))
13514 (pc)))]
13515 ""
13516 [(set (pc)
13517 (if_then_else (match_dup 0)
13518 (label_ref (match_dup 1))
13519 (pc)))]
13520 {
13521 rtx new_op0 = copy_rtx (operands[0]);
13522 operands[0] = new_op0;
13523 PUT_MODE (new_op0, VOIDmode);
13524 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13525 GET_MODE (XEXP (new_op0, 0))));
13526
13527 /* Make sure that (a) the CCmode we have for the flags is strong
13528 enough for the reversed compare or (b) we have a valid FP compare. */
13529 if (! ix86_comparison_operator (new_op0, VOIDmode))
13530 FAIL;
13531 })
13532
13533 ;; Define combination compare-and-branch fp compare instructions to use
13534 ;; during early optimization. Splitting the operation apart early makes
13535 ;; for bad code when we want to reverse the operation.
13536
13537 (define_insn "*fp_jcc_1"
13538 [(set (pc)
13539 (if_then_else (match_operator 0 "comparison_operator"
13540 [(match_operand 1 "register_operand" "f")
13541 (match_operand 2 "register_operand" "f")])
13542 (label_ref (match_operand 3 "" ""))
13543 (pc)))
13544 (clobber (reg:CCFP 18))
13545 (clobber (reg:CCFP 17))]
13546 "TARGET_CMOVE && TARGET_80387
13547 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13548 && FLOAT_MODE_P (GET_MODE (operands[1]))
13549 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13550 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13551 "#")
13552
13553 (define_insn "*fp_jcc_1_sse"
13554 [(set (pc)
13555 (if_then_else (match_operator 0 "comparison_operator"
13556 [(match_operand 1 "register_operand" "f#x,x#f")
13557 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13558 (label_ref (match_operand 3 "" ""))
13559 (pc)))
13560 (clobber (reg:CCFP 18))
13561 (clobber (reg:CCFP 17))]
13562 "TARGET_80387
13563 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13564 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13565 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13566 "#")
13567
13568 (define_insn "*fp_jcc_1_sse_only"
13569 [(set (pc)
13570 (if_then_else (match_operator 0 "comparison_operator"
13571 [(match_operand 1 "register_operand" "x")
13572 (match_operand 2 "nonimmediate_operand" "xm")])
13573 (label_ref (match_operand 3 "" ""))
13574 (pc)))
13575 (clobber (reg:CCFP 18))
13576 (clobber (reg:CCFP 17))]
13577 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13578 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13579 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13580 "#")
13581
13582 (define_insn "*fp_jcc_2"
13583 [(set (pc)
13584 (if_then_else (match_operator 0 "comparison_operator"
13585 [(match_operand 1 "register_operand" "f")
13586 (match_operand 2 "register_operand" "f")])
13587 (pc)
13588 (label_ref (match_operand 3 "" ""))))
13589 (clobber (reg:CCFP 18))
13590 (clobber (reg:CCFP 17))]
13591 "TARGET_CMOVE && TARGET_80387
13592 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13593 && FLOAT_MODE_P (GET_MODE (operands[1]))
13594 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13595 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13596 "#")
13597
13598 (define_insn "*fp_jcc_2_sse"
13599 [(set (pc)
13600 (if_then_else (match_operator 0 "comparison_operator"
13601 [(match_operand 1 "register_operand" "f#x,x#f")
13602 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13603 (pc)
13604 (label_ref (match_operand 3 "" ""))))
13605 (clobber (reg:CCFP 18))
13606 (clobber (reg:CCFP 17))]
13607 "TARGET_80387
13608 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13609 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13610 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13611 "#")
13612
13613 (define_insn "*fp_jcc_2_sse_only"
13614 [(set (pc)
13615 (if_then_else (match_operator 0 "comparison_operator"
13616 [(match_operand 1 "register_operand" "x")
13617 (match_operand 2 "nonimmediate_operand" "xm")])
13618 (pc)
13619 (label_ref (match_operand 3 "" ""))))
13620 (clobber (reg:CCFP 18))
13621 (clobber (reg:CCFP 17))]
13622 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13623 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13624 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13625 "#")
13626
13627 (define_insn "*fp_jcc_3"
13628 [(set (pc)
13629 (if_then_else (match_operator 0 "comparison_operator"
13630 [(match_operand 1 "register_operand" "f")
13631 (match_operand 2 "nonimmediate_operand" "fm")])
13632 (label_ref (match_operand 3 "" ""))
13633 (pc)))
13634 (clobber (reg:CCFP 18))
13635 (clobber (reg:CCFP 17))
13636 (clobber (match_scratch:HI 4 "=a"))]
13637 "TARGET_80387
13638 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13639 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13640 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13641 && SELECT_CC_MODE (GET_CODE (operands[0]),
13642 operands[1], operands[2]) == CCFPmode
13643 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13644 "#")
13645
13646 (define_insn "*fp_jcc_4"
13647 [(set (pc)
13648 (if_then_else (match_operator 0 "comparison_operator"
13649 [(match_operand 1 "register_operand" "f")
13650 (match_operand 2 "nonimmediate_operand" "fm")])
13651 (pc)
13652 (label_ref (match_operand 3 "" ""))))
13653 (clobber (reg:CCFP 18))
13654 (clobber (reg:CCFP 17))
13655 (clobber (match_scratch:HI 4 "=a"))]
13656 "TARGET_80387
13657 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13658 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13659 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13660 && SELECT_CC_MODE (GET_CODE (operands[0]),
13661 operands[1], operands[2]) == CCFPmode
13662 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13663 "#")
13664
13665 (define_insn "*fp_jcc_5"
13666 [(set (pc)
13667 (if_then_else (match_operator 0 "comparison_operator"
13668 [(match_operand 1 "register_operand" "f")
13669 (match_operand 2 "register_operand" "f")])
13670 (label_ref (match_operand 3 "" ""))
13671 (pc)))
13672 (clobber (reg:CCFP 18))
13673 (clobber (reg:CCFP 17))
13674 (clobber (match_scratch:HI 4 "=a"))]
13675 "TARGET_80387
13676 && FLOAT_MODE_P (GET_MODE (operands[1]))
13677 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13678 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13679 "#")
13680
13681 (define_insn "*fp_jcc_6"
13682 [(set (pc)
13683 (if_then_else (match_operator 0 "comparison_operator"
13684 [(match_operand 1 "register_operand" "f")
13685 (match_operand 2 "register_operand" "f")])
13686 (pc)
13687 (label_ref (match_operand 3 "" ""))))
13688 (clobber (reg:CCFP 18))
13689 (clobber (reg:CCFP 17))
13690 (clobber (match_scratch:HI 4 "=a"))]
13691 "TARGET_80387
13692 && FLOAT_MODE_P (GET_MODE (operands[1]))
13693 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13694 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13695 "#")
13696
13697 (define_split
13698 [(set (pc)
13699 (if_then_else (match_operator 0 "comparison_operator"
13700 [(match_operand 1 "register_operand" "")
13701 (match_operand 2 "nonimmediate_operand" "")])
13702 (match_operand 3 "" "")
13703 (match_operand 4 "" "")))
13704 (clobber (reg:CCFP 18))
13705 (clobber (reg:CCFP 17))]
13706 "reload_completed"
13707 [(const_int 0)]
13708 {
13709 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13710 operands[3], operands[4], NULL_RTX);
13711 DONE;
13712 })
13713
13714 (define_split
13715 [(set (pc)
13716 (if_then_else (match_operator 0 "comparison_operator"
13717 [(match_operand 1 "register_operand" "")
13718 (match_operand 2 "nonimmediate_operand" "")])
13719 (match_operand 3 "" "")
13720 (match_operand 4 "" "")))
13721 (clobber (reg:CCFP 18))
13722 (clobber (reg:CCFP 17))
13723 (clobber (match_scratch:HI 5 "=a"))]
13724 "reload_completed"
13725 [(set (pc)
13726 (if_then_else (match_dup 6)
13727 (match_dup 3)
13728 (match_dup 4)))]
13729 {
13730 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13731 operands[3], operands[4], operands[5]);
13732 DONE;
13733 })
13734 \f
13735 ;; Unconditional and other jump instructions
13736
13737 (define_insn "jump"
13738 [(set (pc)
13739 (label_ref (match_operand 0 "" "")))]
13740 ""
13741 "jmp\t%l0"
13742 [(set_attr "type" "ibr")
13743 (set (attr "length")
13744 (if_then_else (and (ge (minus (match_dup 0) (pc))
13745 (const_int -126))
13746 (lt (minus (match_dup 0) (pc))
13747 (const_int 128)))
13748 (const_int 2)
13749 (const_int 5)))
13750 (set_attr "modrm" "0")])
13751
13752 (define_expand "indirect_jump"
13753 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13754 ""
13755 "")
13756
13757 (define_insn "*indirect_jump"
13758 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13759 "!TARGET_64BIT"
13760 "jmp\t%A0"
13761 [(set_attr "type" "ibr")
13762 (set_attr "length_immediate" "0")])
13763
13764 (define_insn "*indirect_jump_rtx64"
13765 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13766 "TARGET_64BIT"
13767 "jmp\t%A0"
13768 [(set_attr "type" "ibr")
13769 (set_attr "length_immediate" "0")])
13770
13771 (define_expand "tablejump"
13772 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13773 (use (label_ref (match_operand 1 "" "")))])]
13774 ""
13775 {
13776 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13777 relative. Convert the relative address to an absolute address. */
13778 if (flag_pic)
13779 {
13780 rtx op0, op1;
13781 enum rtx_code code;
13782
13783 if (TARGET_64BIT)
13784 {
13785 code = PLUS;
13786 op0 = operands[0];
13787 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13788 }
13789 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13790 {
13791 code = PLUS;
13792 op0 = operands[0];
13793 op1 = pic_offset_table_rtx;
13794 }
13795 else
13796 {
13797 code = MINUS;
13798 op0 = pic_offset_table_rtx;
13799 op1 = operands[0];
13800 }
13801
13802 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13803 OPTAB_DIRECT);
13804 }
13805 })
13806
13807 (define_insn "*tablejump_1"
13808 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13809 (use (label_ref (match_operand 1 "" "")))]
13810 "!TARGET_64BIT"
13811 "jmp\t%A0"
13812 [(set_attr "type" "ibr")
13813 (set_attr "length_immediate" "0")])
13814
13815 (define_insn "*tablejump_1_rtx64"
13816 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13817 (use (label_ref (match_operand 1 "" "")))]
13818 "TARGET_64BIT"
13819 "jmp\t%A0"
13820 [(set_attr "type" "ibr")
13821 (set_attr "length_immediate" "0")])
13822 \f
13823 ;; Loop instruction
13824 ;;
13825 ;; This is all complicated by the fact that since this is a jump insn
13826 ;; we must handle our own reloads.
13827
13828 (define_expand "doloop_end"
13829 [(use (match_operand 0 "" "")) ; loop pseudo
13830 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13831 (use (match_operand 2 "" "")) ; max iterations
13832 (use (match_operand 3 "" "")) ; loop level
13833 (use (match_operand 4 "" ""))] ; label
13834 "!TARGET_64BIT && TARGET_USE_LOOP"
13835 "
13836 {
13837 /* Only use cloop on innermost loops. */
13838 if (INTVAL (operands[3]) > 1)
13839 FAIL;
13840 if (GET_MODE (operands[0]) != SImode)
13841 FAIL;
13842 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13843 operands[0]));
13844 DONE;
13845 }")
13846
13847 (define_insn "doloop_end_internal"
13848 [(set (pc)
13849 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13850 (const_int 1))
13851 (label_ref (match_operand 0 "" ""))
13852 (pc)))
13853 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13854 (plus:SI (match_dup 1)
13855 (const_int -1)))
13856 (clobber (match_scratch:SI 3 "=X,X,r"))
13857 (clobber (reg:CC 17))]
13858 "!TARGET_64BIT && TARGET_USE_LOOP"
13859 {
13860 if (which_alternative != 0)
13861 return "#";
13862 if (get_attr_length (insn) == 2)
13863 return "%+loop\t%l0";
13864 else
13865 return "dec{l}\t%1\;%+jne\t%l0";
13866 }
13867 [(set_attr "ppro_uops" "many")
13868 (set (attr "length")
13869 (if_then_else (and (eq_attr "alternative" "0")
13870 (and (ge (minus (match_dup 0) (pc))
13871 (const_int -126))
13872 (lt (minus (match_dup 0) (pc))
13873 (const_int 128))))
13874 (const_int 2)
13875 (const_int 16)))
13876 ;; We don't know the type before shorten branches. Optimistically expect
13877 ;; the loop instruction to match.
13878 (set (attr "type") (const_string "ibr"))])
13879
13880 (define_split
13881 [(set (pc)
13882 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13883 (const_int 1))
13884 (match_operand 0 "" "")
13885 (pc)))
13886 (set (match_dup 1)
13887 (plus:SI (match_dup 1)
13888 (const_int -1)))
13889 (clobber (match_scratch:SI 2 ""))
13890 (clobber (reg:CC 17))]
13891 "!TARGET_64BIT && TARGET_USE_LOOP
13892 && reload_completed
13893 && REGNO (operands[1]) != 2"
13894 [(parallel [(set (reg:CCZ 17)
13895 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13896 (const_int 0)))
13897 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13898 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13899 (match_dup 0)
13900 (pc)))]
13901 "")
13902
13903 (define_split
13904 [(set (pc)
13905 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13906 (const_int 1))
13907 (match_operand 0 "" "")
13908 (pc)))
13909 (set (match_operand:SI 2 "nonimmediate_operand" "")
13910 (plus:SI (match_dup 1)
13911 (const_int -1)))
13912 (clobber (match_scratch:SI 3 ""))
13913 (clobber (reg:CC 17))]
13914 "!TARGET_64BIT && TARGET_USE_LOOP
13915 && reload_completed
13916 && (! REG_P (operands[2])
13917 || ! rtx_equal_p (operands[1], operands[2]))"
13918 [(set (match_dup 3) (match_dup 1))
13919 (parallel [(set (reg:CCZ 17)
13920 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13921 (const_int 0)))
13922 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13923 (set (match_dup 2) (match_dup 3))
13924 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13925 (match_dup 0)
13926 (pc)))]
13927 "")
13928
13929 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13930
13931 (define_peephole2
13932 [(set (reg 17) (match_operand 0 "" ""))
13933 (set (match_operand:QI 1 "register_operand" "")
13934 (match_operator:QI 2 "ix86_comparison_operator"
13935 [(reg 17) (const_int 0)]))
13936 (set (match_operand 3 "q_regs_operand" "")
13937 (zero_extend (match_dup 1)))]
13938 "(peep2_reg_dead_p (3, operands[1])
13939 || operands_match_p (operands[1], operands[3]))
13940 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13941 [(set (match_dup 4) (match_dup 0))
13942 (set (strict_low_part (match_dup 5))
13943 (match_dup 2))]
13944 {
13945 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13946 operands[5] = gen_lowpart (QImode, operands[3]);
13947 ix86_expand_clear (operands[3]);
13948 })
13949
13950 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13951
13952 (define_peephole2
13953 [(set (reg 17) (match_operand 0 "" ""))
13954 (set (match_operand:QI 1 "register_operand" "")
13955 (match_operator:QI 2 "ix86_comparison_operator"
13956 [(reg 17) (const_int 0)]))
13957 (parallel [(set (match_operand 3 "q_regs_operand" "")
13958 (zero_extend (match_dup 1)))
13959 (clobber (reg:CC 17))])]
13960 "(peep2_reg_dead_p (3, operands[1])
13961 || operands_match_p (operands[1], operands[3]))
13962 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13963 [(set (match_dup 4) (match_dup 0))
13964 (set (strict_low_part (match_dup 5))
13965 (match_dup 2))]
13966 {
13967 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13968 operands[5] = gen_lowpart (QImode, operands[3]);
13969 ix86_expand_clear (operands[3]);
13970 })
13971 \f
13972 ;; Call instructions.
13973
13974 ;; The predicates normally associated with named expanders are not properly
13975 ;; checked for calls. This is a bug in the generic code, but it isn't that
13976 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13977
13978 ;; Call subroutine returning no value.
13979
13980 (define_expand "call_pop"
13981 [(parallel [(call (match_operand:QI 0 "" "")
13982 (match_operand:SI 1 "" ""))
13983 (set (reg:SI 7)
13984 (plus:SI (reg:SI 7)
13985 (match_operand:SI 3 "" "")))])]
13986 "!TARGET_64BIT"
13987 {
13988 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13989 DONE;
13990 })
13991
13992 (define_insn "*call_pop_0"
13993 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13994 (match_operand:SI 1 "" ""))
13995 (set (reg:SI 7) (plus:SI (reg:SI 7)
13996 (match_operand:SI 2 "immediate_operand" "")))]
13997 "!TARGET_64BIT"
13998 {
13999 if (SIBLING_CALL_P (insn))
14000 return "jmp\t%P0";
14001 else
14002 return "call\t%P0";
14003 }
14004 [(set_attr "type" "call")])
14005
14006 (define_insn "*call_pop_1"
14007 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14008 (match_operand:SI 1 "" ""))
14009 (set (reg:SI 7) (plus:SI (reg:SI 7)
14010 (match_operand:SI 2 "immediate_operand" "i")))]
14011 "!TARGET_64BIT"
14012 {
14013 if (constant_call_address_operand (operands[0], Pmode))
14014 {
14015 if (SIBLING_CALL_P (insn))
14016 return "jmp\t%P0";
14017 else
14018 return "call\t%P0";
14019 }
14020 if (SIBLING_CALL_P (insn))
14021 return "jmp\t%A0";
14022 else
14023 return "call\t%A0";
14024 }
14025 [(set_attr "type" "call")])
14026
14027 (define_expand "call"
14028 [(call (match_operand:QI 0 "" "")
14029 (match_operand 1 "" ""))
14030 (use (match_operand 2 "" ""))]
14031 ""
14032 {
14033 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14034 DONE;
14035 })
14036
14037 (define_expand "sibcall"
14038 [(call (match_operand:QI 0 "" "")
14039 (match_operand 1 "" ""))
14040 (use (match_operand 2 "" ""))]
14041 ""
14042 {
14043 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14044 DONE;
14045 })
14046
14047 (define_insn "*call_0"
14048 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14049 (match_operand 1 "" ""))]
14050 ""
14051 {
14052 if (SIBLING_CALL_P (insn))
14053 return "jmp\t%P0";
14054 else
14055 return "call\t%P0";
14056 }
14057 [(set_attr "type" "call")])
14058
14059 (define_insn "*call_1"
14060 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14061 (match_operand 1 "" ""))]
14062 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14063 {
14064 if (constant_call_address_operand (operands[0], QImode))
14065 return "call\t%P0";
14066 return "call\t%A0";
14067 }
14068 [(set_attr "type" "call")])
14069
14070 (define_insn "*sibcall_1"
14071 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14072 (match_operand 1 "" ""))]
14073 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14074 {
14075 if (constant_call_address_operand (operands[0], QImode))
14076 return "jmp\t%P0";
14077 return "jmp\t%A0";
14078 }
14079 [(set_attr "type" "call")])
14080
14081 (define_insn "*call_1_rex64"
14082 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14083 (match_operand 1 "" ""))]
14084 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14085 {
14086 if (constant_call_address_operand (operands[0], QImode))
14087 return "call\t%P0";
14088 return "call\t%A0";
14089 }
14090 [(set_attr "type" "call")])
14091
14092 (define_insn "*sibcall_1_rex64"
14093 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14094 (match_operand 1 "" ""))]
14095 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14096 "jmp\t%P0"
14097 [(set_attr "type" "call")])
14098
14099 (define_insn "*sibcall_1_rex64_v"
14100 [(call (mem:QI (reg:DI 40))
14101 (match_operand 0 "" ""))]
14102 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14103 "jmp\t*%%r11"
14104 [(set_attr "type" "call")])
14105
14106
14107 ;; Call subroutine, returning value in operand 0
14108
14109 (define_expand "call_value_pop"
14110 [(parallel [(set (match_operand 0 "" "")
14111 (call (match_operand:QI 1 "" "")
14112 (match_operand:SI 2 "" "")))
14113 (set (reg:SI 7)
14114 (plus:SI (reg:SI 7)
14115 (match_operand:SI 4 "" "")))])]
14116 "!TARGET_64BIT"
14117 {
14118 ix86_expand_call (operands[0], operands[1], operands[2],
14119 operands[3], operands[4], 0);
14120 DONE;
14121 })
14122
14123 (define_expand "call_value"
14124 [(set (match_operand 0 "" "")
14125 (call (match_operand:QI 1 "" "")
14126 (match_operand:SI 2 "" "")))
14127 (use (match_operand:SI 3 "" ""))]
14128 ;; Operand 2 not used on the i386.
14129 ""
14130 {
14131 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14132 DONE;
14133 })
14134
14135 (define_expand "sibcall_value"
14136 [(set (match_operand 0 "" "")
14137 (call (match_operand:QI 1 "" "")
14138 (match_operand:SI 2 "" "")))
14139 (use (match_operand:SI 3 "" ""))]
14140 ;; Operand 2 not used on the i386.
14141 ""
14142 {
14143 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14144 DONE;
14145 })
14146
14147 ;; Call subroutine returning any type.
14148
14149 (define_expand "untyped_call"
14150 [(parallel [(call (match_operand 0 "" "")
14151 (const_int 0))
14152 (match_operand 1 "" "")
14153 (match_operand 2 "" "")])]
14154 ""
14155 {
14156 int i;
14157
14158 /* In order to give reg-stack an easier job in validating two
14159 coprocessor registers as containing a possible return value,
14160 simply pretend the untyped call returns a complex long double
14161 value. */
14162
14163 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14164 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14165 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14166 NULL, 0);
14167
14168 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14169 {
14170 rtx set = XVECEXP (operands[2], 0, i);
14171 emit_move_insn (SET_DEST (set), SET_SRC (set));
14172 }
14173
14174 /* The optimizer does not know that the call sets the function value
14175 registers we stored in the result block. We avoid problems by
14176 claiming that all hard registers are used and clobbered at this
14177 point. */
14178 emit_insn (gen_blockage (const0_rtx));
14179
14180 DONE;
14181 })
14182 \f
14183 ;; Prologue and epilogue instructions
14184
14185 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14186 ;; all of memory. This blocks insns from being moved across this point.
14187
14188 (define_insn "blockage"
14189 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14190 ""
14191 ""
14192 [(set_attr "length" "0")])
14193
14194 ;; Insn emitted into the body of a function to return from a function.
14195 ;; This is only done if the function's epilogue is known to be simple.
14196 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14197
14198 (define_expand "return"
14199 [(return)]
14200 "ix86_can_use_return_insn_p ()"
14201 {
14202 if (current_function_pops_args)
14203 {
14204 rtx popc = GEN_INT (current_function_pops_args);
14205 emit_jump_insn (gen_return_pop_internal (popc));
14206 DONE;
14207 }
14208 })
14209
14210 (define_insn "return_internal"
14211 [(return)]
14212 "reload_completed"
14213 "ret"
14214 [(set_attr "length" "1")
14215 (set_attr "length_immediate" "0")
14216 (set_attr "modrm" "0")])
14217
14218 (define_insn "return_pop_internal"
14219 [(return)
14220 (use (match_operand:SI 0 "const_int_operand" ""))]
14221 "reload_completed"
14222 "ret\t%0"
14223 [(set_attr "length" "3")
14224 (set_attr "length_immediate" "2")
14225 (set_attr "modrm" "0")])
14226
14227 (define_insn "return_indirect_internal"
14228 [(return)
14229 (use (match_operand:SI 0 "register_operand" "r"))]
14230 "reload_completed"
14231 "jmp\t%A0"
14232 [(set_attr "type" "ibr")
14233 (set_attr "length_immediate" "0")])
14234
14235 (define_insn "nop"
14236 [(const_int 0)]
14237 ""
14238 "nop"
14239 [(set_attr "length" "1")
14240 (set_attr "length_immediate" "0")
14241 (set_attr "modrm" "0")
14242 (set_attr "ppro_uops" "one")])
14243
14244 (define_expand "prologue"
14245 [(const_int 1)]
14246 ""
14247 "ix86_expand_prologue (); DONE;")
14248
14249 (define_insn "set_got"
14250 [(set (match_operand:SI 0 "register_operand" "=r")
14251 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14252 (clobber (reg:CC 17))]
14253 "!TARGET_64BIT"
14254 { return output_set_got (operands[0]); }
14255 [(set_attr "type" "multi")
14256 (set_attr "length" "12")])
14257
14258 (define_expand "epilogue"
14259 [(const_int 1)]
14260 ""
14261 "ix86_expand_epilogue (1); DONE;")
14262
14263 (define_expand "sibcall_epilogue"
14264 [(const_int 1)]
14265 ""
14266 "ix86_expand_epilogue (0); DONE;")
14267
14268 (define_expand "eh_return"
14269 [(use (match_operand 0 "register_operand" ""))
14270 (use (match_operand 1 "register_operand" ""))]
14271 ""
14272 {
14273 rtx tmp, sa = operands[0], ra = operands[1];
14274
14275 /* Tricky bit: we write the address of the handler to which we will
14276 be returning into someone else's stack frame, one word below the
14277 stack address we wish to restore. */
14278 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14279 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14280 tmp = gen_rtx_MEM (Pmode, tmp);
14281 emit_move_insn (tmp, ra);
14282
14283 if (Pmode == SImode)
14284 emit_insn (gen_eh_return_si (sa));
14285 else
14286 emit_insn (gen_eh_return_di (sa));
14287 emit_barrier ();
14288 DONE;
14289 })
14290
14291 (define_insn_and_split "eh_return_si"
14292 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14293 UNSPECV_EH_RETURN)]
14294 "!TARGET_64BIT"
14295 "#"
14296 "reload_completed"
14297 [(const_int 1)]
14298 "ix86_expand_epilogue (2); DONE;")
14299
14300 (define_insn_and_split "eh_return_di"
14301 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14302 UNSPECV_EH_RETURN)]
14303 "TARGET_64BIT"
14304 "#"
14305 "reload_completed"
14306 [(const_int 1)]
14307 "ix86_expand_epilogue (2); DONE;")
14308
14309 (define_insn "leave"
14310 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14311 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14312 (clobber (mem:BLK (scratch)))]
14313 "!TARGET_64BIT"
14314 "leave"
14315 [(set_attr "type" "leave")])
14316
14317 (define_insn "leave_rex64"
14318 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14319 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14320 (clobber (mem:BLK (scratch)))]
14321 "TARGET_64BIT"
14322 "leave"
14323 [(set_attr "type" "leave")])
14324 \f
14325 (define_expand "ffssi2"
14326 [(parallel
14327 [(set (match_operand:SI 0 "register_operand" "")
14328 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14329 (clobber (match_scratch:SI 2 ""))
14330 (clobber (reg:CC 17))])]
14331 ""
14332 "")
14333
14334 (define_insn_and_split "*ffs_cmove"
14335 [(set (match_operand:SI 0 "register_operand" "=r")
14336 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14337 (clobber (match_scratch:SI 2 "=&r"))
14338 (clobber (reg:CC 17))]
14339 "TARGET_CMOVE"
14340 "#"
14341 "&& reload_completed"
14342 [(set (match_dup 2) (const_int -1))
14343 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14344 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14345 (set (match_dup 0) (if_then_else:SI
14346 (eq (reg:CCZ 17) (const_int 0))
14347 (match_dup 2)
14348 (match_dup 0)))
14349 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14350 (clobber (reg:CC 17))])]
14351 "")
14352
14353 (define_insn_and_split "*ffs_no_cmove"
14354 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14355 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14356 (clobber (match_scratch:SI 2 "=&r"))
14357 (clobber (reg:CC 17))]
14358 ""
14359 "#"
14360 "reload_completed"
14361 [(parallel [(set (match_dup 2) (const_int 0))
14362 (clobber (reg:CC 17))])
14363 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14364 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14365 (set (strict_low_part (match_dup 3))
14366 (eq:QI (reg:CCZ 17) (const_int 0)))
14367 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14368 (clobber (reg:CC 17))])
14369 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14370 (clobber (reg:CC 17))])
14371 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14372 (clobber (reg:CC 17))])]
14373 {
14374 operands[3] = gen_lowpart (QImode, operands[2]);
14375 })
14376
14377 (define_insn "*ffssi_1"
14378 [(set (reg:CCZ 17)
14379 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14380 (const_int 0)))
14381 (set (match_operand:SI 0 "register_operand" "=r")
14382 (ctz:SI (match_dup 1)))]
14383 ""
14384 "bsf{l}\t{%1, %0|%0, %1}"
14385 [(set_attr "prefix_0f" "1")
14386 (set_attr "ppro_uops" "few")])
14387
14388 (define_insn "ctzsi2"
14389 [(set (match_operand:SI 0 "register_operand" "=r")
14390 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14391 (clobber (reg:CC 17))]
14392 ""
14393 "bsf{l}\t{%1, %0|%0, %1}"
14394 [(set_attr "prefix_0f" "1")
14395 (set_attr "ppro_uops" "few")])
14396
14397 (define_expand "clzsi2"
14398 [(parallel
14399 [(set (match_operand:SI 0 "register_operand" "")
14400 (minus:SI (const_int 31)
14401 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14402 (clobber (reg:CC 17))])
14403 (parallel
14404 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14405 (clobber (reg:CC 17))])]
14406 ""
14407 "")
14408
14409 (define_insn "*bsr"
14410 [(set (match_operand:SI 0 "register_operand" "=r")
14411 (minus:SI (const_int 31)
14412 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14413 (clobber (reg:CC 17))]
14414 ""
14415 "bsr{l}\t{%1, %0|%0, %1}"
14416 [(set_attr "prefix_0f" "1")
14417 (set_attr "ppro_uops" "few")])
14418 \f
14419 ;; Thread-local storage patterns for ELF.
14420 ;;
14421 ;; Note that these code sequences must appear exactly as shown
14422 ;; in order to allow linker relaxation.
14423
14424 (define_insn "*tls_global_dynamic_32_gnu"
14425 [(set (match_operand:SI 0 "register_operand" "=a")
14426 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14427 (match_operand:SI 2 "tls_symbolic_operand" "")
14428 (match_operand:SI 3 "call_insn_operand" "")]
14429 UNSPEC_TLS_GD))
14430 (clobber (match_scratch:SI 4 "=d"))
14431 (clobber (match_scratch:SI 5 "=c"))
14432 (clobber (reg:CC 17))]
14433 "!TARGET_64BIT && TARGET_GNU_TLS"
14434 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14435 [(set_attr "type" "multi")
14436 (set_attr "length" "12")])
14437
14438 (define_insn "*tls_global_dynamic_32_sun"
14439 [(set (match_operand:SI 0 "register_operand" "=a")
14440 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14441 (match_operand:SI 2 "tls_symbolic_operand" "")
14442 (match_operand:SI 3 "call_insn_operand" "")]
14443 UNSPEC_TLS_GD))
14444 (clobber (match_scratch:SI 4 "=d"))
14445 (clobber (match_scratch:SI 5 "=c"))
14446 (clobber (reg:CC 17))]
14447 "!TARGET_64BIT && TARGET_SUN_TLS"
14448 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14449 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14450 [(set_attr "type" "multi")
14451 (set_attr "length" "14")])
14452
14453 (define_expand "tls_global_dynamic_32"
14454 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14455 (unspec:SI
14456 [(match_dup 2)
14457 (match_operand:SI 1 "tls_symbolic_operand" "")
14458 (match_dup 3)]
14459 UNSPEC_TLS_GD))
14460 (clobber (match_scratch:SI 4 ""))
14461 (clobber (match_scratch:SI 5 ""))
14462 (clobber (reg:CC 17))])]
14463 ""
14464 {
14465 if (flag_pic)
14466 operands[2] = pic_offset_table_rtx;
14467 else
14468 {
14469 operands[2] = gen_reg_rtx (Pmode);
14470 emit_insn (gen_set_got (operands[2]));
14471 }
14472 operands[3] = ix86_tls_get_addr ();
14473 })
14474
14475 (define_insn "*tls_global_dynamic_64"
14476 [(set (match_operand:DI 0 "register_operand" "=a")
14477 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14478 (match_operand:DI 3 "" "")))
14479 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14480 UNSPEC_TLS_GD)]
14481 "TARGET_64BIT"
14482 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14483 [(set_attr "type" "multi")
14484 (set_attr "length" "16")])
14485
14486 (define_expand "tls_global_dynamic_64"
14487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14488 (call (mem:QI (match_dup 2)) (const_int 0)))
14489 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14490 UNSPEC_TLS_GD)])]
14491 ""
14492 {
14493 operands[2] = ix86_tls_get_addr ();
14494 })
14495
14496 (define_insn "*tls_local_dynamic_base_32_gnu"
14497 [(set (match_operand:SI 0 "register_operand" "=a")
14498 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14499 (match_operand:SI 2 "call_insn_operand" "")]
14500 UNSPEC_TLS_LD_BASE))
14501 (clobber (match_scratch:SI 3 "=d"))
14502 (clobber (match_scratch:SI 4 "=c"))
14503 (clobber (reg:CC 17))]
14504 "!TARGET_64BIT && TARGET_GNU_TLS"
14505 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14506 [(set_attr "type" "multi")
14507 (set_attr "length" "11")])
14508
14509 (define_insn "*tls_local_dynamic_base_32_sun"
14510 [(set (match_operand:SI 0 "register_operand" "=a")
14511 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14512 (match_operand:SI 2 "call_insn_operand" "")]
14513 UNSPEC_TLS_LD_BASE))
14514 (clobber (match_scratch:SI 3 "=d"))
14515 (clobber (match_scratch:SI 4 "=c"))
14516 (clobber (reg:CC 17))]
14517 "!TARGET_64BIT && TARGET_SUN_TLS"
14518 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14519 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14520 [(set_attr "type" "multi")
14521 (set_attr "length" "13")])
14522
14523 (define_expand "tls_local_dynamic_base_32"
14524 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14525 (unspec:SI [(match_dup 1) (match_dup 2)]
14526 UNSPEC_TLS_LD_BASE))
14527 (clobber (match_scratch:SI 3 ""))
14528 (clobber (match_scratch:SI 4 ""))
14529 (clobber (reg:CC 17))])]
14530 ""
14531 {
14532 if (flag_pic)
14533 operands[1] = pic_offset_table_rtx;
14534 else
14535 {
14536 operands[1] = gen_reg_rtx (Pmode);
14537 emit_insn (gen_set_got (operands[1]));
14538 }
14539 operands[2] = ix86_tls_get_addr ();
14540 })
14541
14542 (define_insn "*tls_local_dynamic_base_64"
14543 [(set (match_operand:DI 0 "register_operand" "=a")
14544 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14545 (match_operand:DI 2 "" "")))
14546 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14547 "TARGET_64BIT"
14548 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14549 [(set_attr "type" "multi")
14550 (set_attr "length" "12")])
14551
14552 (define_expand "tls_local_dynamic_base_64"
14553 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14554 (call (mem:QI (match_dup 1)) (const_int 0)))
14555 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14556 ""
14557 {
14558 operands[1] = ix86_tls_get_addr ();
14559 })
14560
14561 ;; Local dynamic of a single variable is a lose. Show combine how
14562 ;; to convert that back to global dynamic.
14563
14564 (define_insn_and_split "*tls_local_dynamic_32_once"
14565 [(set (match_operand:SI 0 "register_operand" "=a")
14566 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14567 (match_operand:SI 2 "call_insn_operand" "")]
14568 UNSPEC_TLS_LD_BASE)
14569 (const:SI (unspec:SI
14570 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14571 UNSPEC_DTPOFF))))
14572 (clobber (match_scratch:SI 4 "=d"))
14573 (clobber (match_scratch:SI 5 "=c"))
14574 (clobber (reg:CC 17))]
14575 ""
14576 "#"
14577 ""
14578 [(parallel [(set (match_dup 0)
14579 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14580 UNSPEC_TLS_GD))
14581 (clobber (match_dup 4))
14582 (clobber (match_dup 5))
14583 (clobber (reg:CC 17))])]
14584 "")
14585 \f
14586 ;; These patterns match the binary 387 instructions for addM3, subM3,
14587 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14588 ;; SFmode. The first is the normal insn, the second the same insn but
14589 ;; with one operand a conversion, and the third the same insn but with
14590 ;; the other operand a conversion. The conversion may be SFmode or
14591 ;; SImode if the target mode DFmode, but only SImode if the target mode
14592 ;; is SFmode.
14593
14594 ;; Gcc is slightly more smart about handling normal two address instructions
14595 ;; so use special patterns for add and mull.
14596 (define_insn "*fop_sf_comm_nosse"
14597 [(set (match_operand:SF 0 "register_operand" "=f")
14598 (match_operator:SF 3 "binary_fp_operator"
14599 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14600 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14601 "TARGET_80387 && !TARGET_SSE_MATH
14602 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14603 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14604 "* return output_387_binary_op (insn, operands);"
14605 [(set (attr "type")
14606 (if_then_else (match_operand:SF 3 "mult_operator" "")
14607 (const_string "fmul")
14608 (const_string "fop")))
14609 (set_attr "mode" "SF")])
14610
14611 (define_insn "*fop_sf_comm"
14612 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14613 (match_operator:SF 3 "binary_fp_operator"
14614 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14615 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14616 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14617 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14618 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14619 "* return output_387_binary_op (insn, operands);"
14620 [(set (attr "type")
14621 (if_then_else (eq_attr "alternative" "1")
14622 (if_then_else (match_operand:SF 3 "mult_operator" "")
14623 (const_string "ssemul")
14624 (const_string "sseadd"))
14625 (if_then_else (match_operand:SF 3 "mult_operator" "")
14626 (const_string "fmul")
14627 (const_string "fop"))))
14628 (set_attr "mode" "SF")])
14629
14630 (define_insn "*fop_sf_comm_sse"
14631 [(set (match_operand:SF 0 "register_operand" "=x")
14632 (match_operator:SF 3 "binary_fp_operator"
14633 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14634 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14635 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14636 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14637 "* return output_387_binary_op (insn, operands);"
14638 [(set (attr "type")
14639 (if_then_else (match_operand:SF 3 "mult_operator" "")
14640 (const_string "ssemul")
14641 (const_string "sseadd")))
14642 (set_attr "mode" "SF")])
14643
14644 (define_insn "*fop_df_comm_nosse"
14645 [(set (match_operand:DF 0 "register_operand" "=f")
14646 (match_operator:DF 3 "binary_fp_operator"
14647 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14648 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14649 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14650 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14651 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14652 "* return output_387_binary_op (insn, operands);"
14653 [(set (attr "type")
14654 (if_then_else (match_operand:SF 3 "mult_operator" "")
14655 (const_string "fmul")
14656 (const_string "fop")))
14657 (set_attr "mode" "DF")])
14658
14659 (define_insn "*fop_df_comm"
14660 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14661 (match_operator:DF 3 "binary_fp_operator"
14662 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14663 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14664 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14665 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14666 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14667 "* return output_387_binary_op (insn, operands);"
14668 [(set (attr "type")
14669 (if_then_else (eq_attr "alternative" "1")
14670 (if_then_else (match_operand:SF 3 "mult_operator" "")
14671 (const_string "ssemul")
14672 (const_string "sseadd"))
14673 (if_then_else (match_operand:SF 3 "mult_operator" "")
14674 (const_string "fmul")
14675 (const_string "fop"))))
14676 (set_attr "mode" "DF")])
14677
14678 (define_insn "*fop_df_comm_sse"
14679 [(set (match_operand:DF 0 "register_operand" "=Y")
14680 (match_operator:DF 3 "binary_fp_operator"
14681 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14682 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14683 "TARGET_SSE2 && TARGET_SSE_MATH
14684 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14685 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14686 "* return output_387_binary_op (insn, operands);"
14687 [(set (attr "type")
14688 (if_then_else (match_operand:SF 3 "mult_operator" "")
14689 (const_string "ssemul")
14690 (const_string "sseadd")))
14691 (set_attr "mode" "DF")])
14692
14693 (define_insn "*fop_xf_comm"
14694 [(set (match_operand:XF 0 "register_operand" "=f")
14695 (match_operator:XF 3 "binary_fp_operator"
14696 [(match_operand:XF 1 "register_operand" "%0")
14697 (match_operand:XF 2 "register_operand" "f")]))]
14698 "!TARGET_64BIT && TARGET_80387
14699 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14700 "* return output_387_binary_op (insn, operands);"
14701 [(set (attr "type")
14702 (if_then_else (match_operand:XF 3 "mult_operator" "")
14703 (const_string "fmul")
14704 (const_string "fop")))
14705 (set_attr "mode" "XF")])
14706
14707 (define_insn "*fop_tf_comm"
14708 [(set (match_operand:TF 0 "register_operand" "=f")
14709 (match_operator:TF 3 "binary_fp_operator"
14710 [(match_operand:TF 1 "register_operand" "%0")
14711 (match_operand:TF 2 "register_operand" "f")]))]
14712 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14713 "* return output_387_binary_op (insn, operands);"
14714 [(set (attr "type")
14715 (if_then_else (match_operand:TF 3 "mult_operator" "")
14716 (const_string "fmul")
14717 (const_string "fop")))
14718 (set_attr "mode" "XF")])
14719
14720 (define_insn "*fop_sf_1_nosse"
14721 [(set (match_operand:SF 0 "register_operand" "=f,f")
14722 (match_operator:SF 3 "binary_fp_operator"
14723 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14724 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14725 "TARGET_80387 && !TARGET_SSE_MATH
14726 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14727 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14728 "* return output_387_binary_op (insn, operands);"
14729 [(set (attr "type")
14730 (cond [(match_operand:SF 3 "mult_operator" "")
14731 (const_string "fmul")
14732 (match_operand:SF 3 "div_operator" "")
14733 (const_string "fdiv")
14734 ]
14735 (const_string "fop")))
14736 (set_attr "mode" "SF")])
14737
14738 (define_insn "*fop_sf_1"
14739 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14740 (match_operator:SF 3 "binary_fp_operator"
14741 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14742 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14743 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14744 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14745 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14746 "* return output_387_binary_op (insn, operands);"
14747 [(set (attr "type")
14748 (cond [(and (eq_attr "alternative" "2")
14749 (match_operand:SF 3 "mult_operator" ""))
14750 (const_string "ssemul")
14751 (and (eq_attr "alternative" "2")
14752 (match_operand:SF 3 "div_operator" ""))
14753 (const_string "ssediv")
14754 (eq_attr "alternative" "2")
14755 (const_string "sseadd")
14756 (match_operand:SF 3 "mult_operator" "")
14757 (const_string "fmul")
14758 (match_operand:SF 3 "div_operator" "")
14759 (const_string "fdiv")
14760 ]
14761 (const_string "fop")))
14762 (set_attr "mode" "SF")])
14763
14764 (define_insn "*fop_sf_1_sse"
14765 [(set (match_operand:SF 0 "register_operand" "=x")
14766 (match_operator:SF 3 "binary_fp_operator"
14767 [(match_operand:SF 1 "register_operand" "0")
14768 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14769 "TARGET_SSE_MATH
14770 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14771 "* return output_387_binary_op (insn, operands);"
14772 [(set (attr "type")
14773 (cond [(match_operand:SF 3 "mult_operator" "")
14774 (const_string "ssemul")
14775 (match_operand:SF 3 "div_operator" "")
14776 (const_string "ssediv")
14777 ]
14778 (const_string "sseadd")))
14779 (set_attr "mode" "SF")])
14780
14781 ;; ??? Add SSE splitters for these!
14782 (define_insn "*fop_sf_2"
14783 [(set (match_operand:SF 0 "register_operand" "=f,f")
14784 (match_operator:SF 3 "binary_fp_operator"
14785 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14786 (match_operand:SF 2 "register_operand" "0,0")]))]
14787 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14788 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14789 [(set (attr "type")
14790 (cond [(match_operand:SF 3 "mult_operator" "")
14791 (const_string "fmul")
14792 (match_operand:SF 3 "div_operator" "")
14793 (const_string "fdiv")
14794 ]
14795 (const_string "fop")))
14796 (set_attr "fp_int_src" "true")
14797 (set_attr "ppro_uops" "many")
14798 (set_attr "mode" "SI")])
14799
14800 (define_insn "*fop_sf_3"
14801 [(set (match_operand:SF 0 "register_operand" "=f,f")
14802 (match_operator:SF 3 "binary_fp_operator"
14803 [(match_operand:SF 1 "register_operand" "0,0")
14804 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14805 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14806 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14807 [(set (attr "type")
14808 (cond [(match_operand:SF 3 "mult_operator" "")
14809 (const_string "fmul")
14810 (match_operand:SF 3 "div_operator" "")
14811 (const_string "fdiv")
14812 ]
14813 (const_string "fop")))
14814 (set_attr "fp_int_src" "true")
14815 (set_attr "ppro_uops" "many")
14816 (set_attr "mode" "SI")])
14817
14818 (define_insn "*fop_df_1_nosse"
14819 [(set (match_operand:DF 0 "register_operand" "=f,f")
14820 (match_operator:DF 3 "binary_fp_operator"
14821 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14822 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14823 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14824 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14825 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14826 "* return output_387_binary_op (insn, operands);"
14827 [(set (attr "type")
14828 (cond [(match_operand:DF 3 "mult_operator" "")
14829 (const_string "fmul")
14830 (match_operand:DF 3 "div_operator" "")
14831 (const_string "fdiv")
14832 ]
14833 (const_string "fop")))
14834 (set_attr "mode" "DF")])
14835
14836
14837 (define_insn "*fop_df_1"
14838 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14839 (match_operator:DF 3 "binary_fp_operator"
14840 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14841 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14842 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14843 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14844 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14845 "* return output_387_binary_op (insn, operands);"
14846 [(set (attr "type")
14847 (cond [(and (eq_attr "alternative" "2")
14848 (match_operand:SF 3 "mult_operator" ""))
14849 (const_string "ssemul")
14850 (and (eq_attr "alternative" "2")
14851 (match_operand:SF 3 "div_operator" ""))
14852 (const_string "ssediv")
14853 (eq_attr "alternative" "2")
14854 (const_string "sseadd")
14855 (match_operand:DF 3 "mult_operator" "")
14856 (const_string "fmul")
14857 (match_operand:DF 3 "div_operator" "")
14858 (const_string "fdiv")
14859 ]
14860 (const_string "fop")))
14861 (set_attr "mode" "DF")])
14862
14863 (define_insn "*fop_df_1_sse"
14864 [(set (match_operand:DF 0 "register_operand" "=Y")
14865 (match_operator:DF 3 "binary_fp_operator"
14866 [(match_operand:DF 1 "register_operand" "0")
14867 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14868 "TARGET_SSE2 && TARGET_SSE_MATH
14869 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14870 "* return output_387_binary_op (insn, operands);"
14871 [(set_attr "mode" "DF")
14872 (set (attr "type")
14873 (cond [(match_operand:SF 3 "mult_operator" "")
14874 (const_string "ssemul")
14875 (match_operand:SF 3 "div_operator" "")
14876 (const_string "ssediv")
14877 ]
14878 (const_string "sseadd")))])
14879
14880 ;; ??? Add SSE splitters for these!
14881 (define_insn "*fop_df_2"
14882 [(set (match_operand:DF 0 "register_operand" "=f,f")
14883 (match_operator:DF 3 "binary_fp_operator"
14884 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14885 (match_operand:DF 2 "register_operand" "0,0")]))]
14886 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14887 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14888 [(set (attr "type")
14889 (cond [(match_operand:DF 3 "mult_operator" "")
14890 (const_string "fmul")
14891 (match_operand:DF 3 "div_operator" "")
14892 (const_string "fdiv")
14893 ]
14894 (const_string "fop")))
14895 (set_attr "fp_int_src" "true")
14896 (set_attr "ppro_uops" "many")
14897 (set_attr "mode" "SI")])
14898
14899 (define_insn "*fop_df_3"
14900 [(set (match_operand:DF 0 "register_operand" "=f,f")
14901 (match_operator:DF 3 "binary_fp_operator"
14902 [(match_operand:DF 1 "register_operand" "0,0")
14903 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14904 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14905 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14906 [(set (attr "type")
14907 (cond [(match_operand:DF 3 "mult_operator" "")
14908 (const_string "fmul")
14909 (match_operand:DF 3 "div_operator" "")
14910 (const_string "fdiv")
14911 ]
14912 (const_string "fop")))
14913 (set_attr "fp_int_src" "true")
14914 (set_attr "ppro_uops" "many")
14915 (set_attr "mode" "SI")])
14916
14917 (define_insn "*fop_df_4"
14918 [(set (match_operand:DF 0 "register_operand" "=f,f")
14919 (match_operator:DF 3 "binary_fp_operator"
14920 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14921 (match_operand:DF 2 "register_operand" "0,f")]))]
14922 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14923 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14924 "* return output_387_binary_op (insn, operands);"
14925 [(set (attr "type")
14926 (cond [(match_operand:DF 3 "mult_operator" "")
14927 (const_string "fmul")
14928 (match_operand:DF 3 "div_operator" "")
14929 (const_string "fdiv")
14930 ]
14931 (const_string "fop")))
14932 (set_attr "mode" "SF")])
14933
14934 (define_insn "*fop_df_5"
14935 [(set (match_operand:DF 0 "register_operand" "=f,f")
14936 (match_operator:DF 3 "binary_fp_operator"
14937 [(match_operand:DF 1 "register_operand" "0,f")
14938 (float_extend:DF
14939 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14940 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14941 "* return output_387_binary_op (insn, operands);"
14942 [(set (attr "type")
14943 (cond [(match_operand:DF 3 "mult_operator" "")
14944 (const_string "fmul")
14945 (match_operand:DF 3 "div_operator" "")
14946 (const_string "fdiv")
14947 ]
14948 (const_string "fop")))
14949 (set_attr "mode" "SF")])
14950
14951 (define_insn "*fop_df_6"
14952 [(set (match_operand:DF 0 "register_operand" "=f,f")
14953 (match_operator:DF 3 "binary_fp_operator"
14954 [(float_extend:DF
14955 (match_operand:SF 1 "register_operand" "0,f"))
14956 (float_extend:DF
14957 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14958 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14959 "* return output_387_binary_op (insn, operands);"
14960 [(set (attr "type")
14961 (cond [(match_operand:DF 3 "mult_operator" "")
14962 (const_string "fmul")
14963 (match_operand:DF 3 "div_operator" "")
14964 (const_string "fdiv")
14965 ]
14966 (const_string "fop")))
14967 (set_attr "mode" "SF")])
14968
14969 (define_insn "*fop_xf_1"
14970 [(set (match_operand:XF 0 "register_operand" "=f,f")
14971 (match_operator:XF 3 "binary_fp_operator"
14972 [(match_operand:XF 1 "register_operand" "0,f")
14973 (match_operand:XF 2 "register_operand" "f,0")]))]
14974 "!TARGET_64BIT && TARGET_80387
14975 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14976 "* return output_387_binary_op (insn, operands);"
14977 [(set (attr "type")
14978 (cond [(match_operand:XF 3 "mult_operator" "")
14979 (const_string "fmul")
14980 (match_operand:XF 3 "div_operator" "")
14981 (const_string "fdiv")
14982 ]
14983 (const_string "fop")))
14984 (set_attr "mode" "XF")])
14985
14986 (define_insn "*fop_tf_1"
14987 [(set (match_operand:TF 0 "register_operand" "=f,f")
14988 (match_operator:TF 3 "binary_fp_operator"
14989 [(match_operand:TF 1 "register_operand" "0,f")
14990 (match_operand:TF 2 "register_operand" "f,0")]))]
14991 "TARGET_80387
14992 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14993 "* return output_387_binary_op (insn, operands);"
14994 [(set (attr "type")
14995 (cond [(match_operand:TF 3 "mult_operator" "")
14996 (const_string "fmul")
14997 (match_operand:TF 3 "div_operator" "")
14998 (const_string "fdiv")
14999 ]
15000 (const_string "fop")))
15001 (set_attr "mode" "XF")])
15002
15003 (define_insn "*fop_xf_2"
15004 [(set (match_operand:XF 0 "register_operand" "=f,f")
15005 (match_operator:XF 3 "binary_fp_operator"
15006 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15007 (match_operand:XF 2 "register_operand" "0,0")]))]
15008 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
15009 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15010 [(set (attr "type")
15011 (cond [(match_operand:XF 3 "mult_operator" "")
15012 (const_string "fmul")
15013 (match_operand:XF 3 "div_operator" "")
15014 (const_string "fdiv")
15015 ]
15016 (const_string "fop")))
15017 (set_attr "fp_int_src" "true")
15018 (set_attr "mode" "SI")
15019 (set_attr "ppro_uops" "many")])
15020
15021 (define_insn "*fop_tf_2"
15022 [(set (match_operand:TF 0 "register_operand" "=f,f")
15023 (match_operator:TF 3 "binary_fp_operator"
15024 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15025 (match_operand:TF 2 "register_operand" "0,0")]))]
15026 "TARGET_80387 && TARGET_USE_FIOP"
15027 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15028 [(set (attr "type")
15029 (cond [(match_operand:TF 3 "mult_operator" "")
15030 (const_string "fmul")
15031 (match_operand:TF 3 "div_operator" "")
15032 (const_string "fdiv")
15033 ]
15034 (const_string "fop")))
15035 (set_attr "fp_int_src" "true")
15036 (set_attr "mode" "SI")
15037 (set_attr "ppro_uops" "many")])
15038
15039 (define_insn "*fop_xf_3"
15040 [(set (match_operand:XF 0 "register_operand" "=f,f")
15041 (match_operator:XF 3 "binary_fp_operator"
15042 [(match_operand:XF 1 "register_operand" "0,0")
15043 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15044 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
15045 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15046 [(set (attr "type")
15047 (cond [(match_operand:XF 3 "mult_operator" "")
15048 (const_string "fmul")
15049 (match_operand:XF 3 "div_operator" "")
15050 (const_string "fdiv")
15051 ]
15052 (const_string "fop")))
15053 (set_attr "fp_int_src" "true")
15054 (set_attr "mode" "SI")
15055 (set_attr "ppro_uops" "many")])
15056
15057 (define_insn "*fop_tf_3"
15058 [(set (match_operand:TF 0 "register_operand" "=f,f")
15059 (match_operator:TF 3 "binary_fp_operator"
15060 [(match_operand:TF 1 "register_operand" "0,0")
15061 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15062 "TARGET_80387 && TARGET_USE_FIOP"
15063 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15064 [(set (attr "type")
15065 (cond [(match_operand:TF 3 "mult_operator" "")
15066 (const_string "fmul")
15067 (match_operand:TF 3 "div_operator" "")
15068 (const_string "fdiv")
15069 ]
15070 (const_string "fop")))
15071 (set_attr "fp_int_src" "true")
15072 (set_attr "mode" "SI")
15073 (set_attr "ppro_uops" "many")])
15074
15075 (define_insn "*fop_xf_4"
15076 [(set (match_operand:XF 0 "register_operand" "=f,f")
15077 (match_operator:XF 3 "binary_fp_operator"
15078 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15079 (match_operand:XF 2 "register_operand" "0,f")]))]
15080 "!TARGET_64BIT && TARGET_80387"
15081 "* return output_387_binary_op (insn, operands);"
15082 [(set (attr "type")
15083 (cond [(match_operand:XF 3 "mult_operator" "")
15084 (const_string "fmul")
15085 (match_operand:XF 3 "div_operator" "")
15086 (const_string "fdiv")
15087 ]
15088 (const_string "fop")))
15089 (set_attr "mode" "SF")])
15090
15091 (define_insn "*fop_tf_4"
15092 [(set (match_operand:TF 0 "register_operand" "=f,f")
15093 (match_operator:TF 3 "binary_fp_operator"
15094 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15095 (match_operand:TF 2 "register_operand" "0,f")]))]
15096 "TARGET_80387"
15097 "* return output_387_binary_op (insn, operands);"
15098 [(set (attr "type")
15099 (cond [(match_operand:TF 3 "mult_operator" "")
15100 (const_string "fmul")
15101 (match_operand:TF 3 "div_operator" "")
15102 (const_string "fdiv")
15103 ]
15104 (const_string "fop")))
15105 (set_attr "mode" "SF")])
15106
15107 (define_insn "*fop_xf_5"
15108 [(set (match_operand:XF 0 "register_operand" "=f,f")
15109 (match_operator:XF 3 "binary_fp_operator"
15110 [(match_operand:XF 1 "register_operand" "0,f")
15111 (float_extend:XF
15112 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15113 "!TARGET_64BIT && TARGET_80387"
15114 "* return output_387_binary_op (insn, operands);"
15115 [(set (attr "type")
15116 (cond [(match_operand:XF 3 "mult_operator" "")
15117 (const_string "fmul")
15118 (match_operand:XF 3 "div_operator" "")
15119 (const_string "fdiv")
15120 ]
15121 (const_string "fop")))
15122 (set_attr "mode" "SF")])
15123
15124 (define_insn "*fop_tf_5"
15125 [(set (match_operand:TF 0 "register_operand" "=f,f")
15126 (match_operator:TF 3 "binary_fp_operator"
15127 [(match_operand:TF 1 "register_operand" "0,f")
15128 (float_extend:TF
15129 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15130 "TARGET_80387"
15131 "* return output_387_binary_op (insn, operands);"
15132 [(set (attr "type")
15133 (cond [(match_operand:TF 3 "mult_operator" "")
15134 (const_string "fmul")
15135 (match_operand:TF 3 "div_operator" "")
15136 (const_string "fdiv")
15137 ]
15138 (const_string "fop")))
15139 (set_attr "mode" "SF")])
15140
15141 (define_insn "*fop_xf_6"
15142 [(set (match_operand:XF 0 "register_operand" "=f,f")
15143 (match_operator:XF 3 "binary_fp_operator"
15144 [(float_extend:XF
15145 (match_operand 1 "register_operand" "0,f"))
15146 (float_extend:XF
15147 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15148 "!TARGET_64BIT && TARGET_80387"
15149 "* return output_387_binary_op (insn, operands);"
15150 [(set (attr "type")
15151 (cond [(match_operand:XF 3 "mult_operator" "")
15152 (const_string "fmul")
15153 (match_operand:XF 3 "div_operator" "")
15154 (const_string "fdiv")
15155 ]
15156 (const_string "fop")))
15157 (set_attr "mode" "SF")])
15158
15159 (define_insn "*fop_tf_6"
15160 [(set (match_operand:TF 0 "register_operand" "=f,f")
15161 (match_operator:TF 3 "binary_fp_operator"
15162 [(float_extend:TF
15163 (match_operand 1 "register_operand" "0,f"))
15164 (float_extend:TF
15165 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15166 "TARGET_80387"
15167 "* return output_387_binary_op (insn, operands);"
15168 [(set (attr "type")
15169 (cond [(match_operand:TF 3 "mult_operator" "")
15170 (const_string "fmul")
15171 (match_operand:TF 3 "div_operator" "")
15172 (const_string "fdiv")
15173 ]
15174 (const_string "fop")))
15175 (set_attr "mode" "SF")])
15176
15177 (define_split
15178 [(set (match_operand 0 "register_operand" "")
15179 (match_operator 3 "binary_fp_operator"
15180 [(float (match_operand:SI 1 "register_operand" ""))
15181 (match_operand 2 "register_operand" "")]))]
15182 "TARGET_80387 && reload_completed
15183 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15184 [(const_int 0)]
15185 {
15186 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15187 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15188 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15189 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15190 GET_MODE (operands[3]),
15191 operands[4],
15192 operands[2])));
15193 ix86_free_from_memory (GET_MODE (operands[1]));
15194 DONE;
15195 })
15196
15197 (define_split
15198 [(set (match_operand 0 "register_operand" "")
15199 (match_operator 3 "binary_fp_operator"
15200 [(match_operand 1 "register_operand" "")
15201 (float (match_operand:SI 2 "register_operand" ""))]))]
15202 "TARGET_80387 && reload_completed
15203 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15204 [(const_int 0)]
15205 {
15206 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15207 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15208 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15209 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15210 GET_MODE (operands[3]),
15211 operands[1],
15212 operands[4])));
15213 ix86_free_from_memory (GET_MODE (operands[2]));
15214 DONE;
15215 })
15216 \f
15217 ;; FPU special functions.
15218
15219 (define_expand "sqrtsf2"
15220 [(set (match_operand:SF 0 "register_operand" "")
15221 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15222 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15223 {
15224 if (!TARGET_SSE_MATH)
15225 operands[1] = force_reg (SFmode, operands[1]);
15226 })
15227
15228 (define_insn "sqrtsf2_1"
15229 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15230 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15231 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15232 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15233 "@
15234 fsqrt
15235 sqrtss\t{%1, %0|%0, %1}"
15236 [(set_attr "type" "fpspc,sse")
15237 (set_attr "mode" "SF,SF")
15238 (set_attr "athlon_decode" "direct,*")])
15239
15240 (define_insn "sqrtsf2_1_sse_only"
15241 [(set (match_operand:SF 0 "register_operand" "=x")
15242 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15243 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15244 "sqrtss\t{%1, %0|%0, %1}"
15245 [(set_attr "type" "sse")
15246 (set_attr "mode" "SF")
15247 (set_attr "athlon_decode" "*")])
15248
15249 (define_insn "sqrtsf2_i387"
15250 [(set (match_operand:SF 0 "register_operand" "=f")
15251 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15252 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15253 && !TARGET_SSE_MATH"
15254 "fsqrt"
15255 [(set_attr "type" "fpspc")
15256 (set_attr "mode" "SF")
15257 (set_attr "athlon_decode" "direct")])
15258
15259 (define_expand "sqrtdf2"
15260 [(set (match_operand:DF 0 "register_operand" "")
15261 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15262 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15263 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15264 {
15265 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15266 operands[1] = force_reg (DFmode, operands[1]);
15267 })
15268
15269 (define_insn "sqrtdf2_1"
15270 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15271 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15272 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15273 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15274 "@
15275 fsqrt
15276 sqrtsd\t{%1, %0|%0, %1}"
15277 [(set_attr "type" "fpspc,sse")
15278 (set_attr "mode" "DF,DF")
15279 (set_attr "athlon_decode" "direct,*")])
15280
15281 (define_insn "sqrtdf2_1_sse_only"
15282 [(set (match_operand:DF 0 "register_operand" "=Y")
15283 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15284 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15285 "sqrtsd\t{%1, %0|%0, %1}"
15286 [(set_attr "type" "sse")
15287 (set_attr "mode" "DF")
15288 (set_attr "athlon_decode" "*")])
15289
15290 (define_insn "sqrtdf2_i387"
15291 [(set (match_operand:DF 0 "register_operand" "=f")
15292 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15293 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15294 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15295 "fsqrt"
15296 [(set_attr "type" "fpspc")
15297 (set_attr "mode" "DF")
15298 (set_attr "athlon_decode" "direct")])
15299
15300 (define_insn "*sqrtextendsfdf2"
15301 [(set (match_operand:DF 0 "register_operand" "=f")
15302 (sqrt:DF (float_extend:DF
15303 (match_operand:SF 1 "register_operand" "0"))))]
15304 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15305 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15306 "fsqrt"
15307 [(set_attr "type" "fpspc")
15308 (set_attr "mode" "DF")
15309 (set_attr "athlon_decode" "direct")])
15310
15311 (define_insn "sqrtxf2"
15312 [(set (match_operand:XF 0 "register_operand" "=f")
15313 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15314 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15315 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15316 "fsqrt"
15317 [(set_attr "type" "fpspc")
15318 (set_attr "mode" "XF")
15319 (set_attr "athlon_decode" "direct")])
15320
15321 (define_insn "sqrttf2"
15322 [(set (match_operand:TF 0 "register_operand" "=f")
15323 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15324 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15325 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15326 "fsqrt"
15327 [(set_attr "type" "fpspc")
15328 (set_attr "mode" "XF")
15329 (set_attr "athlon_decode" "direct")])
15330
15331 (define_insn "*sqrtextenddfxf2"
15332 [(set (match_operand:XF 0 "register_operand" "=f")
15333 (sqrt:XF (float_extend:XF
15334 (match_operand:DF 1 "register_operand" "0"))))]
15335 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15336 "fsqrt"
15337 [(set_attr "type" "fpspc")
15338 (set_attr "mode" "XF")
15339 (set_attr "athlon_decode" "direct")])
15340
15341 (define_insn "*sqrtextenddftf2"
15342 [(set (match_operand:TF 0 "register_operand" "=f")
15343 (sqrt:TF (float_extend:TF
15344 (match_operand:DF 1 "register_operand" "0"))))]
15345 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15346 "fsqrt"
15347 [(set_attr "type" "fpspc")
15348 (set_attr "mode" "XF")
15349 (set_attr "athlon_decode" "direct")])
15350
15351 (define_insn "*sqrtextendsfxf2"
15352 [(set (match_operand:XF 0 "register_operand" "=f")
15353 (sqrt:XF (float_extend:XF
15354 (match_operand:SF 1 "register_operand" "0"))))]
15355 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15356 "fsqrt"
15357 [(set_attr "type" "fpspc")
15358 (set_attr "mode" "XF")
15359 (set_attr "athlon_decode" "direct")])
15360
15361 (define_insn "*sqrtextendsftf2"
15362 [(set (match_operand:TF 0 "register_operand" "=f")
15363 (sqrt:TF (float_extend:TF
15364 (match_operand:SF 1 "register_operand" "0"))))]
15365 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15366 "fsqrt"
15367 [(set_attr "type" "fpspc")
15368 (set_attr "mode" "XF")
15369 (set_attr "athlon_decode" "direct")])
15370
15371 (define_insn "sindf2"
15372 [(set (match_operand:DF 0 "register_operand" "=f")
15373 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15374 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15375 && flag_unsafe_math_optimizations"
15376 "fsin"
15377 [(set_attr "type" "fpspc")
15378 (set_attr "mode" "DF")])
15379
15380 (define_insn "sinsf2"
15381 [(set (match_operand:SF 0 "register_operand" "=f")
15382 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15383 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15384 && flag_unsafe_math_optimizations"
15385 "fsin"
15386 [(set_attr "type" "fpspc")
15387 (set_attr "mode" "SF")])
15388
15389 (define_insn "*sinextendsfdf2"
15390 [(set (match_operand:DF 0 "register_operand" "=f")
15391 (unspec:DF [(float_extend:DF
15392 (match_operand:SF 1 "register_operand" "0"))]
15393 UNSPEC_SIN))]
15394 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15395 && flag_unsafe_math_optimizations"
15396 "fsin"
15397 [(set_attr "type" "fpspc")
15398 (set_attr "mode" "DF")])
15399
15400 (define_insn "sinxf2"
15401 [(set (match_operand:XF 0 "register_operand" "=f")
15402 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15403 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15404 && flag_unsafe_math_optimizations"
15405 "fsin"
15406 [(set_attr "type" "fpspc")
15407 (set_attr "mode" "XF")])
15408
15409 (define_insn "sintf2"
15410 [(set (match_operand:TF 0 "register_operand" "=f")
15411 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15412 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15413 && flag_unsafe_math_optimizations"
15414 "fsin"
15415 [(set_attr "type" "fpspc")
15416 (set_attr "mode" "XF")])
15417
15418 (define_insn "cosdf2"
15419 [(set (match_operand:DF 0 "register_operand" "=f")
15420 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15421 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15422 && flag_unsafe_math_optimizations"
15423 "fcos"
15424 [(set_attr "type" "fpspc")
15425 (set_attr "mode" "DF")])
15426
15427 (define_insn "cossf2"
15428 [(set (match_operand:SF 0 "register_operand" "=f")
15429 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15430 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15431 && flag_unsafe_math_optimizations"
15432 "fcos"
15433 [(set_attr "type" "fpspc")
15434 (set_attr "mode" "SF")])
15435
15436 (define_insn "*cosextendsfdf2"
15437 [(set (match_operand:DF 0 "register_operand" "=f")
15438 (unspec:DF [(float_extend:DF
15439 (match_operand:SF 1 "register_operand" "0"))]
15440 UNSPEC_COS))]
15441 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15442 && flag_unsafe_math_optimizations"
15443 "fcos"
15444 [(set_attr "type" "fpspc")
15445 (set_attr "mode" "DF")])
15446
15447 (define_insn "cosxf2"
15448 [(set (match_operand:XF 0 "register_operand" "=f")
15449 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15450 "!TARGET_64BIT && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15451 && flag_unsafe_math_optimizations"
15452 "fcos"
15453 [(set_attr "type" "fpspc")
15454 (set_attr "mode" "XF")])
15455
15456 (define_insn "costf2"
15457 [(set (match_operand:TF 0 "register_operand" "=f")
15458 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15459 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15460 && flag_unsafe_math_optimizations"
15461 "fcos"
15462 [(set_attr "type" "fpspc")
15463 (set_attr "mode" "XF")])
15464
15465 (define_insn "atan2df3"
15466 [(set (match_operand:DF 0 "register_operand" "=f")
15467 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15468 (match_operand:DF 1 "register_operand" "u")]
15469 UNSPEC_FPATAN))]
15470 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15471 && flag_unsafe_math_optimizations"
15472 "fpatan"
15473 [(set_attr "type" "fpspc")
15474 (set_attr "mode" "DF")])
15475
15476 (define_insn "atan2sf3"
15477 [(set (match_operand:SF 0 "register_operand" "=f")
15478 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15479 (match_operand:SF 1 "register_operand" "u")]
15480 UNSPEC_FPATAN))]
15481 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15482 && flag_unsafe_math_optimizations"
15483 "fpatan"
15484 [(set_attr "type" "fpspc")
15485 (set_attr "mode" "SF")])
15486
15487 (define_insn "atan2xf3"
15488 [(set (match_operand:XF 0 "register_operand" "=f")
15489 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15490 (match_operand:XF 1 "register_operand" "u")]
15491 UNSPEC_FPATAN))]
15492 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15493 && flag_unsafe_math_optimizations"
15494 "fpatan"
15495 [(set_attr "type" "fpspc")
15496 (set_attr "mode" "XF")])
15497
15498 (define_insn "atan2tf3"
15499 [(set (match_operand:TF 0 "register_operand" "=f")
15500 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15501 (match_operand:TF 1 "register_operand" "u")]
15502 UNSPEC_FPATAN))]
15503 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15504 && flag_unsafe_math_optimizations"
15505 "fpatan"
15506 [(set_attr "type" "fpspc")
15507 (set_attr "mode" "XF")])
15508 \f
15509 ;; Block operation instructions
15510
15511 (define_insn "cld"
15512 [(set (reg:SI 19) (const_int 0))]
15513 ""
15514 "cld"
15515 [(set_attr "type" "cld")])
15516
15517 (define_expand "movstrsi"
15518 [(use (match_operand:BLK 0 "memory_operand" ""))
15519 (use (match_operand:BLK 1 "memory_operand" ""))
15520 (use (match_operand:SI 2 "nonmemory_operand" ""))
15521 (use (match_operand:SI 3 "const_int_operand" ""))]
15522 ""
15523 {
15524 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15525 DONE;
15526 else
15527 FAIL;
15528 })
15529
15530 (define_expand "movstrdi"
15531 [(use (match_operand:BLK 0 "memory_operand" ""))
15532 (use (match_operand:BLK 1 "memory_operand" ""))
15533 (use (match_operand:DI 2 "nonmemory_operand" ""))
15534 (use (match_operand:DI 3 "const_int_operand" ""))]
15535 "TARGET_64BIT"
15536 {
15537 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15538 DONE;
15539 else
15540 FAIL;
15541 })
15542
15543 ;; Most CPUs don't like single string operations
15544 ;; Handle this case here to simplify previous expander.
15545
15546 (define_expand "strmovdi_rex64"
15547 [(set (match_dup 2)
15548 (mem:DI (match_operand:DI 1 "register_operand" "")))
15549 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15550 (match_dup 2))
15551 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15552 (clobber (reg:CC 17))])
15553 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15554 (clobber (reg:CC 17))])]
15555 "TARGET_64BIT"
15556 {
15557 if (TARGET_SINGLE_STRINGOP || optimize_size)
15558 {
15559 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15560 operands[1]));
15561 DONE;
15562 }
15563 else
15564 operands[2] = gen_reg_rtx (DImode);
15565 })
15566
15567
15568 (define_expand "strmovsi"
15569 [(set (match_dup 2)
15570 (mem:SI (match_operand:SI 1 "register_operand" "")))
15571 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15572 (match_dup 2))
15573 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15574 (clobber (reg:CC 17))])
15575 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15576 (clobber (reg:CC 17))])]
15577 ""
15578 {
15579 if (TARGET_64BIT)
15580 {
15581 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15582 DONE;
15583 }
15584 if (TARGET_SINGLE_STRINGOP || optimize_size)
15585 {
15586 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15587 operands[1]));
15588 DONE;
15589 }
15590 else
15591 operands[2] = gen_reg_rtx (SImode);
15592 })
15593
15594 (define_expand "strmovsi_rex64"
15595 [(set (match_dup 2)
15596 (mem:SI (match_operand:DI 1 "register_operand" "")))
15597 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15598 (match_dup 2))
15599 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15600 (clobber (reg:CC 17))])
15601 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15602 (clobber (reg:CC 17))])]
15603 "TARGET_64BIT"
15604 {
15605 if (TARGET_SINGLE_STRINGOP || optimize_size)
15606 {
15607 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15608 operands[1]));
15609 DONE;
15610 }
15611 else
15612 operands[2] = gen_reg_rtx (SImode);
15613 })
15614
15615 (define_expand "strmovhi"
15616 [(set (match_dup 2)
15617 (mem:HI (match_operand:SI 1 "register_operand" "")))
15618 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15619 (match_dup 2))
15620 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15621 (clobber (reg:CC 17))])
15622 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15623 (clobber (reg:CC 17))])]
15624 ""
15625 {
15626 if (TARGET_64BIT)
15627 {
15628 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15629 DONE;
15630 }
15631 if (TARGET_SINGLE_STRINGOP || optimize_size)
15632 {
15633 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15634 operands[1]));
15635 DONE;
15636 }
15637 else
15638 operands[2] = gen_reg_rtx (HImode);
15639 })
15640
15641 (define_expand "strmovhi_rex64"
15642 [(set (match_dup 2)
15643 (mem:HI (match_operand:DI 1 "register_operand" "")))
15644 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15645 (match_dup 2))
15646 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15647 (clobber (reg:CC 17))])
15648 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15649 (clobber (reg:CC 17))])]
15650 "TARGET_64BIT"
15651 {
15652 if (TARGET_SINGLE_STRINGOP || optimize_size)
15653 {
15654 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15655 operands[1]));
15656 DONE;
15657 }
15658 else
15659 operands[2] = gen_reg_rtx (HImode);
15660 })
15661
15662 (define_expand "strmovqi"
15663 [(set (match_dup 2)
15664 (mem:QI (match_operand:SI 1 "register_operand" "")))
15665 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15666 (match_dup 2))
15667 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15668 (clobber (reg:CC 17))])
15669 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15670 (clobber (reg:CC 17))])]
15671 ""
15672 {
15673 if (TARGET_64BIT)
15674 {
15675 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15676 DONE;
15677 }
15678 if (TARGET_SINGLE_STRINGOP || optimize_size)
15679 {
15680 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15681 operands[1]));
15682 DONE;
15683 }
15684 else
15685 operands[2] = gen_reg_rtx (QImode);
15686 })
15687
15688 (define_expand "strmovqi_rex64"
15689 [(set (match_dup 2)
15690 (mem:QI (match_operand:DI 1 "register_operand" "")))
15691 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15692 (match_dup 2))
15693 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15694 (clobber (reg:CC 17))])
15695 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15696 (clobber (reg:CC 17))])]
15697 "TARGET_64BIT"
15698 {
15699 if (TARGET_SINGLE_STRINGOP || optimize_size)
15700 {
15701 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15702 operands[1]));
15703 DONE;
15704 }
15705 else
15706 operands[2] = gen_reg_rtx (QImode);
15707 })
15708
15709 (define_insn "strmovdi_rex_1"
15710 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15711 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15712 (set (match_operand:DI 0 "register_operand" "=D")
15713 (plus:DI (match_dup 2)
15714 (const_int 8)))
15715 (set (match_operand:DI 1 "register_operand" "=S")
15716 (plus:DI (match_dup 3)
15717 (const_int 8)))
15718 (use (reg:SI 19))]
15719 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15720 "movsq"
15721 [(set_attr "type" "str")
15722 (set_attr "mode" "DI")
15723 (set_attr "memory" "both")])
15724
15725 (define_insn "strmovsi_1"
15726 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15727 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15728 (set (match_operand:SI 0 "register_operand" "=D")
15729 (plus:SI (match_dup 2)
15730 (const_int 4)))
15731 (set (match_operand:SI 1 "register_operand" "=S")
15732 (plus:SI (match_dup 3)
15733 (const_int 4)))
15734 (use (reg:SI 19))]
15735 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15736 "{movsl|movsd}"
15737 [(set_attr "type" "str")
15738 (set_attr "mode" "SI")
15739 (set_attr "memory" "both")])
15740
15741 (define_insn "strmovsi_rex_1"
15742 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15743 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15744 (set (match_operand:DI 0 "register_operand" "=D")
15745 (plus:DI (match_dup 2)
15746 (const_int 4)))
15747 (set (match_operand:DI 1 "register_operand" "=S")
15748 (plus:DI (match_dup 3)
15749 (const_int 4)))
15750 (use (reg:SI 19))]
15751 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15752 "{movsl|movsd}"
15753 [(set_attr "type" "str")
15754 (set_attr "mode" "SI")
15755 (set_attr "memory" "both")])
15756
15757 (define_insn "strmovhi_1"
15758 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15759 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15760 (set (match_operand:SI 0 "register_operand" "=D")
15761 (plus:SI (match_dup 2)
15762 (const_int 2)))
15763 (set (match_operand:SI 1 "register_operand" "=S")
15764 (plus:SI (match_dup 3)
15765 (const_int 2)))
15766 (use (reg:SI 19))]
15767 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15768 "movsw"
15769 [(set_attr "type" "str")
15770 (set_attr "memory" "both")
15771 (set_attr "mode" "HI")])
15772
15773 (define_insn "strmovhi_rex_1"
15774 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15775 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15776 (set (match_operand:DI 0 "register_operand" "=D")
15777 (plus:DI (match_dup 2)
15778 (const_int 2)))
15779 (set (match_operand:DI 1 "register_operand" "=S")
15780 (plus:DI (match_dup 3)
15781 (const_int 2)))
15782 (use (reg:SI 19))]
15783 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15784 "movsw"
15785 [(set_attr "type" "str")
15786 (set_attr "memory" "both")
15787 (set_attr "mode" "HI")])
15788
15789 (define_insn "strmovqi_1"
15790 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15791 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15792 (set (match_operand:SI 0 "register_operand" "=D")
15793 (plus:SI (match_dup 2)
15794 (const_int 1)))
15795 (set (match_operand:SI 1 "register_operand" "=S")
15796 (plus:SI (match_dup 3)
15797 (const_int 1)))
15798 (use (reg:SI 19))]
15799 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15800 "movsb"
15801 [(set_attr "type" "str")
15802 (set_attr "memory" "both")
15803 (set_attr "mode" "QI")])
15804
15805 (define_insn "strmovqi_rex_1"
15806 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15807 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15808 (set (match_operand:DI 0 "register_operand" "=D")
15809 (plus:DI (match_dup 2)
15810 (const_int 1)))
15811 (set (match_operand:DI 1 "register_operand" "=S")
15812 (plus:DI (match_dup 3)
15813 (const_int 1)))
15814 (use (reg:SI 19))]
15815 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15816 "movsb"
15817 [(set_attr "type" "str")
15818 (set_attr "memory" "both")
15819 (set_attr "mode" "QI")])
15820
15821 (define_insn "rep_movdi_rex64"
15822 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15823 (set (match_operand:DI 0 "register_operand" "=D")
15824 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15825 (const_int 3))
15826 (match_operand:DI 3 "register_operand" "0")))
15827 (set (match_operand:DI 1 "register_operand" "=S")
15828 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15829 (match_operand:DI 4 "register_operand" "1")))
15830 (set (mem:BLK (match_dup 3))
15831 (mem:BLK (match_dup 4)))
15832 (use (match_dup 5))
15833 (use (reg:SI 19))]
15834 "TARGET_64BIT"
15835 "{rep\;movsq|rep movsq}"
15836 [(set_attr "type" "str")
15837 (set_attr "prefix_rep" "1")
15838 (set_attr "memory" "both")
15839 (set_attr "mode" "DI")])
15840
15841 (define_insn "rep_movsi"
15842 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15843 (set (match_operand:SI 0 "register_operand" "=D")
15844 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15845 (const_int 2))
15846 (match_operand:SI 3 "register_operand" "0")))
15847 (set (match_operand:SI 1 "register_operand" "=S")
15848 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15849 (match_operand:SI 4 "register_operand" "1")))
15850 (set (mem:BLK (match_dup 3))
15851 (mem:BLK (match_dup 4)))
15852 (use (match_dup 5))
15853 (use (reg:SI 19))]
15854 "!TARGET_64BIT"
15855 "{rep\;movsl|rep movsd}"
15856 [(set_attr "type" "str")
15857 (set_attr "prefix_rep" "1")
15858 (set_attr "memory" "both")
15859 (set_attr "mode" "SI")])
15860
15861 (define_insn "rep_movsi_rex64"
15862 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15863 (set (match_operand:DI 0 "register_operand" "=D")
15864 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15865 (const_int 2))
15866 (match_operand:DI 3 "register_operand" "0")))
15867 (set (match_operand:DI 1 "register_operand" "=S")
15868 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15869 (match_operand:DI 4 "register_operand" "1")))
15870 (set (mem:BLK (match_dup 3))
15871 (mem:BLK (match_dup 4)))
15872 (use (match_dup 5))
15873 (use (reg:SI 19))]
15874 "TARGET_64BIT"
15875 "{rep\;movsl|rep movsd}"
15876 [(set_attr "type" "str")
15877 (set_attr "prefix_rep" "1")
15878 (set_attr "memory" "both")
15879 (set_attr "mode" "SI")])
15880
15881 (define_insn "rep_movqi"
15882 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15883 (set (match_operand:SI 0 "register_operand" "=D")
15884 (plus:SI (match_operand:SI 3 "register_operand" "0")
15885 (match_operand:SI 5 "register_operand" "2")))
15886 (set (match_operand:SI 1 "register_operand" "=S")
15887 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15888 (set (mem:BLK (match_dup 3))
15889 (mem:BLK (match_dup 4)))
15890 (use (match_dup 5))
15891 (use (reg:SI 19))]
15892 "!TARGET_64BIT"
15893 "{rep\;movsb|rep movsb}"
15894 [(set_attr "type" "str")
15895 (set_attr "prefix_rep" "1")
15896 (set_attr "memory" "both")
15897 (set_attr "mode" "SI")])
15898
15899 (define_insn "rep_movqi_rex64"
15900 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15901 (set (match_operand:DI 0 "register_operand" "=D")
15902 (plus:DI (match_operand:DI 3 "register_operand" "0")
15903 (match_operand:DI 5 "register_operand" "2")))
15904 (set (match_operand:DI 1 "register_operand" "=S")
15905 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15906 (set (mem:BLK (match_dup 3))
15907 (mem:BLK (match_dup 4)))
15908 (use (match_dup 5))
15909 (use (reg:SI 19))]
15910 "TARGET_64BIT"
15911 "{rep\;movsb|rep movsb}"
15912 [(set_attr "type" "str")
15913 (set_attr "prefix_rep" "1")
15914 (set_attr "memory" "both")
15915 (set_attr "mode" "SI")])
15916
15917 (define_expand "clrstrsi"
15918 [(use (match_operand:BLK 0 "memory_operand" ""))
15919 (use (match_operand:SI 1 "nonmemory_operand" ""))
15920 (use (match_operand 2 "const_int_operand" ""))]
15921 ""
15922 {
15923 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15924 DONE;
15925 else
15926 FAIL;
15927 })
15928
15929 (define_expand "clrstrdi"
15930 [(use (match_operand:BLK 0 "memory_operand" ""))
15931 (use (match_operand:DI 1 "nonmemory_operand" ""))
15932 (use (match_operand 2 "const_int_operand" ""))]
15933 "TARGET_64BIT"
15934 {
15935 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15936 DONE;
15937 else
15938 FAIL;
15939 })
15940
15941 ;; Most CPUs don't like single string operations
15942 ;; Handle this case here to simplify previous expander.
15943
15944 (define_expand "strsetdi_rex64"
15945 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15946 (match_operand:DI 1 "register_operand" ""))
15947 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15948 (clobber (reg:CC 17))])]
15949 "TARGET_64BIT"
15950 {
15951 if (TARGET_SINGLE_STRINGOP || optimize_size)
15952 {
15953 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15954 DONE;
15955 }
15956 })
15957
15958 (define_expand "strsetsi"
15959 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15960 (match_operand:SI 1 "register_operand" ""))
15961 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15962 (clobber (reg:CC 17))])]
15963 ""
15964 {
15965 if (TARGET_64BIT)
15966 {
15967 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15968 DONE;
15969 }
15970 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15971 {
15972 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15973 DONE;
15974 }
15975 })
15976
15977 (define_expand "strsetsi_rex64"
15978 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15979 (match_operand:SI 1 "register_operand" ""))
15980 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15981 (clobber (reg:CC 17))])]
15982 "TARGET_64BIT"
15983 {
15984 if (TARGET_SINGLE_STRINGOP || optimize_size)
15985 {
15986 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15987 DONE;
15988 }
15989 })
15990
15991 (define_expand "strsethi"
15992 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15993 (match_operand:HI 1 "register_operand" ""))
15994 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15995 (clobber (reg:CC 17))])]
15996 ""
15997 {
15998 if (TARGET_64BIT)
15999 {
16000 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16001 DONE;
16002 }
16003 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16004 {
16005 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16006 DONE;
16007 }
16008 })
16009
16010 (define_expand "strsethi_rex64"
16011 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16012 (match_operand:HI 1 "register_operand" ""))
16013 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16014 (clobber (reg:CC 17))])]
16015 "TARGET_64BIT"
16016 {
16017 if (TARGET_SINGLE_STRINGOP || optimize_size)
16018 {
16019 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16020 DONE;
16021 }
16022 })
16023
16024 (define_expand "strsetqi"
16025 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16026 (match_operand:QI 1 "register_operand" ""))
16027 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16028 (clobber (reg:CC 17))])]
16029 ""
16030 {
16031 if (TARGET_64BIT)
16032 {
16033 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16034 DONE;
16035 }
16036 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16037 {
16038 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16039 DONE;
16040 }
16041 })
16042
16043 (define_expand "strsetqi_rex64"
16044 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16045 (match_operand:QI 1 "register_operand" ""))
16046 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16047 (clobber (reg:CC 17))])]
16048 "TARGET_64BIT"
16049 {
16050 if (TARGET_SINGLE_STRINGOP || optimize_size)
16051 {
16052 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16053 DONE;
16054 }
16055 })
16056
16057 (define_insn "strsetdi_rex_1"
16058 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16059 (match_operand:SI 2 "register_operand" "a"))
16060 (set (match_operand:DI 0 "register_operand" "=D")
16061 (plus:DI (match_dup 1)
16062 (const_int 8)))
16063 (use (reg:SI 19))]
16064 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16065 "stosq"
16066 [(set_attr "type" "str")
16067 (set_attr "memory" "store")
16068 (set_attr "mode" "DI")])
16069
16070 (define_insn "strsetsi_1"
16071 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16072 (match_operand:SI 2 "register_operand" "a"))
16073 (set (match_operand:SI 0 "register_operand" "=D")
16074 (plus:SI (match_dup 1)
16075 (const_int 4)))
16076 (use (reg:SI 19))]
16077 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16078 "{stosl|stosd}"
16079 [(set_attr "type" "str")
16080 (set_attr "memory" "store")
16081 (set_attr "mode" "SI")])
16082
16083 (define_insn "strsetsi_rex_1"
16084 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16085 (match_operand:SI 2 "register_operand" "a"))
16086 (set (match_operand:DI 0 "register_operand" "=D")
16087 (plus:DI (match_dup 1)
16088 (const_int 4)))
16089 (use (reg:SI 19))]
16090 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16091 "{stosl|stosd}"
16092 [(set_attr "type" "str")
16093 (set_attr "memory" "store")
16094 (set_attr "mode" "SI")])
16095
16096 (define_insn "strsethi_1"
16097 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16098 (match_operand:HI 2 "register_operand" "a"))
16099 (set (match_operand:SI 0 "register_operand" "=D")
16100 (plus:SI (match_dup 1)
16101 (const_int 2)))
16102 (use (reg:SI 19))]
16103 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16104 "stosw"
16105 [(set_attr "type" "str")
16106 (set_attr "memory" "store")
16107 (set_attr "mode" "HI")])
16108
16109 (define_insn "strsethi_rex_1"
16110 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16111 (match_operand:HI 2 "register_operand" "a"))
16112 (set (match_operand:DI 0 "register_operand" "=D")
16113 (plus:DI (match_dup 1)
16114 (const_int 2)))
16115 (use (reg:SI 19))]
16116 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16117 "stosw"
16118 [(set_attr "type" "str")
16119 (set_attr "memory" "store")
16120 (set_attr "mode" "HI")])
16121
16122 (define_insn "strsetqi_1"
16123 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16124 (match_operand:QI 2 "register_operand" "a"))
16125 (set (match_operand:SI 0 "register_operand" "=D")
16126 (plus:SI (match_dup 1)
16127 (const_int 1)))
16128 (use (reg:SI 19))]
16129 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16130 "stosb"
16131 [(set_attr "type" "str")
16132 (set_attr "memory" "store")
16133 (set_attr "mode" "QI")])
16134
16135 (define_insn "strsetqi_rex_1"
16136 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16137 (match_operand:QI 2 "register_operand" "a"))
16138 (set (match_operand:DI 0 "register_operand" "=D")
16139 (plus:DI (match_dup 1)
16140 (const_int 1)))
16141 (use (reg:SI 19))]
16142 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16143 "stosb"
16144 [(set_attr "type" "str")
16145 (set_attr "memory" "store")
16146 (set_attr "mode" "QI")])
16147
16148 (define_insn "rep_stosdi_rex64"
16149 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16150 (set (match_operand:DI 0 "register_operand" "=D")
16151 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16152 (const_int 3))
16153 (match_operand:DI 3 "register_operand" "0")))
16154 (set (mem:BLK (match_dup 3))
16155 (const_int 0))
16156 (use (match_operand:DI 2 "register_operand" "a"))
16157 (use (match_dup 4))
16158 (use (reg:SI 19))]
16159 "TARGET_64BIT"
16160 "{rep\;stosq|rep stosq}"
16161 [(set_attr "type" "str")
16162 (set_attr "prefix_rep" "1")
16163 (set_attr "memory" "store")
16164 (set_attr "mode" "DI")])
16165
16166 (define_insn "rep_stossi"
16167 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16168 (set (match_operand:SI 0 "register_operand" "=D")
16169 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16170 (const_int 2))
16171 (match_operand:SI 3 "register_operand" "0")))
16172 (set (mem:BLK (match_dup 3))
16173 (const_int 0))
16174 (use (match_operand:SI 2 "register_operand" "a"))
16175 (use (match_dup 4))
16176 (use (reg:SI 19))]
16177 "!TARGET_64BIT"
16178 "{rep\;stosl|rep stosd}"
16179 [(set_attr "type" "str")
16180 (set_attr "prefix_rep" "1")
16181 (set_attr "memory" "store")
16182 (set_attr "mode" "SI")])
16183
16184 (define_insn "rep_stossi_rex64"
16185 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16186 (set (match_operand:DI 0 "register_operand" "=D")
16187 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16188 (const_int 2))
16189 (match_operand:DI 3 "register_operand" "0")))
16190 (set (mem:BLK (match_dup 3))
16191 (const_int 0))
16192 (use (match_operand:SI 2 "register_operand" "a"))
16193 (use (match_dup 4))
16194 (use (reg:SI 19))]
16195 "TARGET_64BIT"
16196 "{rep\;stosl|rep stosd}"
16197 [(set_attr "type" "str")
16198 (set_attr "prefix_rep" "1")
16199 (set_attr "memory" "store")
16200 (set_attr "mode" "SI")])
16201
16202 (define_insn "rep_stosqi"
16203 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16204 (set (match_operand:SI 0 "register_operand" "=D")
16205 (plus:SI (match_operand:SI 3 "register_operand" "0")
16206 (match_operand:SI 4 "register_operand" "1")))
16207 (set (mem:BLK (match_dup 3))
16208 (const_int 0))
16209 (use (match_operand:QI 2 "register_operand" "a"))
16210 (use (match_dup 4))
16211 (use (reg:SI 19))]
16212 "!TARGET_64BIT"
16213 "{rep\;stosb|rep stosb}"
16214 [(set_attr "type" "str")
16215 (set_attr "prefix_rep" "1")
16216 (set_attr "memory" "store")
16217 (set_attr "mode" "QI")])
16218
16219 (define_insn "rep_stosqi_rex64"
16220 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16221 (set (match_operand:DI 0 "register_operand" "=D")
16222 (plus:DI (match_operand:DI 3 "register_operand" "0")
16223 (match_operand:DI 4 "register_operand" "1")))
16224 (set (mem:BLK (match_dup 3))
16225 (const_int 0))
16226 (use (match_operand:QI 2 "register_operand" "a"))
16227 (use (match_dup 4))
16228 (use (reg:DI 19))]
16229 "TARGET_64BIT"
16230 "{rep\;stosb|rep stosb}"
16231 [(set_attr "type" "str")
16232 (set_attr "prefix_rep" "1")
16233 (set_attr "memory" "store")
16234 (set_attr "mode" "QI")])
16235
16236 (define_expand "cmpstrsi"
16237 [(set (match_operand:SI 0 "register_operand" "")
16238 (compare:SI (match_operand:BLK 1 "general_operand" "")
16239 (match_operand:BLK 2 "general_operand" "")))
16240 (use (match_operand 3 "general_operand" ""))
16241 (use (match_operand 4 "immediate_operand" ""))]
16242 ""
16243 {
16244 rtx addr1, addr2, out, outlow, count, countreg, align;
16245
16246 /* Can't use this if the user has appropriated esi or edi. */
16247 if (global_regs[4] || global_regs[5])
16248 FAIL;
16249
16250 out = operands[0];
16251 if (GET_CODE (out) != REG)
16252 out = gen_reg_rtx (SImode);
16253
16254 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16255 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16256
16257 count = operands[3];
16258 countreg = ix86_zero_extend_to_Pmode (count);
16259
16260 /* %%% Iff we are testing strict equality, we can use known alignment
16261 to good advantage. This may be possible with combine, particularly
16262 once cc0 is dead. */
16263 align = operands[4];
16264
16265 emit_insn (gen_cld ());
16266 if (GET_CODE (count) == CONST_INT)
16267 {
16268 if (INTVAL (count) == 0)
16269 {
16270 emit_move_insn (operands[0], const0_rtx);
16271 DONE;
16272 }
16273 if (TARGET_64BIT)
16274 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16275 addr1, addr2, countreg));
16276 else
16277 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16278 addr1, addr2, countreg));
16279 }
16280 else
16281 {
16282 if (TARGET_64BIT)
16283 {
16284 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16285 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16286 addr1, addr2, countreg));
16287 }
16288 else
16289 {
16290 emit_insn (gen_cmpsi_1 (countreg, countreg));
16291 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16292 addr1, addr2, countreg));
16293 }
16294 }
16295
16296 outlow = gen_lowpart (QImode, out);
16297 emit_insn (gen_cmpintqi (outlow));
16298 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16299
16300 if (operands[0] != out)
16301 emit_move_insn (operands[0], out);
16302
16303 DONE;
16304 })
16305
16306 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16307
16308 (define_expand "cmpintqi"
16309 [(set (match_dup 1)
16310 (gtu:QI (reg:CC 17) (const_int 0)))
16311 (set (match_dup 2)
16312 (ltu:QI (reg:CC 17) (const_int 0)))
16313 (parallel [(set (match_operand:QI 0 "register_operand" "")
16314 (minus:QI (match_dup 1)
16315 (match_dup 2)))
16316 (clobber (reg:CC 17))])]
16317 ""
16318 "operands[1] = gen_reg_rtx (QImode);
16319 operands[2] = gen_reg_rtx (QImode);")
16320
16321 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16322 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16323
16324 (define_insn "cmpstrqi_nz_1"
16325 [(set (reg:CC 17)
16326 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16327 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16328 (use (match_operand:SI 6 "register_operand" "2"))
16329 (use (match_operand:SI 3 "immediate_operand" "i"))
16330 (use (reg:SI 19))
16331 (clobber (match_operand:SI 0 "register_operand" "=S"))
16332 (clobber (match_operand:SI 1 "register_operand" "=D"))
16333 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16334 "!TARGET_64BIT"
16335 "repz{\;| }cmpsb"
16336 [(set_attr "type" "str")
16337 (set_attr "mode" "QI")
16338 (set_attr "prefix_rep" "1")])
16339
16340 (define_insn "cmpstrqi_nz_rex_1"
16341 [(set (reg:CC 17)
16342 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16343 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16344 (use (match_operand:DI 6 "register_operand" "2"))
16345 (use (match_operand:SI 3 "immediate_operand" "i"))
16346 (use (reg:SI 19))
16347 (clobber (match_operand:DI 0 "register_operand" "=S"))
16348 (clobber (match_operand:DI 1 "register_operand" "=D"))
16349 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16350 "TARGET_64BIT"
16351 "repz{\;| }cmpsb"
16352 [(set_attr "type" "str")
16353 (set_attr "mode" "QI")
16354 (set_attr "prefix_rep" "1")])
16355
16356 ;; The same, but the count is not known to not be zero.
16357
16358 (define_insn "cmpstrqi_1"
16359 [(set (reg:CC 17)
16360 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16361 (const_int 0))
16362 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16363 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16364 (const_int 0)))
16365 (use (match_operand:SI 3 "immediate_operand" "i"))
16366 (use (reg:CC 17))
16367 (use (reg:SI 19))
16368 (clobber (match_operand:SI 0 "register_operand" "=S"))
16369 (clobber (match_operand:SI 1 "register_operand" "=D"))
16370 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16371 "!TARGET_64BIT"
16372 "repz{\;| }cmpsb"
16373 [(set_attr "type" "str")
16374 (set_attr "mode" "QI")
16375 (set_attr "prefix_rep" "1")])
16376
16377 (define_insn "cmpstrqi_rex_1"
16378 [(set (reg:CC 17)
16379 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16380 (const_int 0))
16381 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16382 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16383 (const_int 0)))
16384 (use (match_operand:SI 3 "immediate_operand" "i"))
16385 (use (reg:CC 17))
16386 (use (reg:SI 19))
16387 (clobber (match_operand:DI 0 "register_operand" "=S"))
16388 (clobber (match_operand:DI 1 "register_operand" "=D"))
16389 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16390 "TARGET_64BIT"
16391 "repz{\;| }cmpsb"
16392 [(set_attr "type" "str")
16393 (set_attr "mode" "QI")
16394 (set_attr "prefix_rep" "1")])
16395
16396 (define_expand "strlensi"
16397 [(set (match_operand:SI 0 "register_operand" "")
16398 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16399 (match_operand:QI 2 "immediate_operand" "")
16400 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16401 ""
16402 {
16403 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16404 DONE;
16405 else
16406 FAIL;
16407 })
16408
16409 (define_expand "strlendi"
16410 [(set (match_operand:DI 0 "register_operand" "")
16411 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16412 (match_operand:QI 2 "immediate_operand" "")
16413 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16414 ""
16415 {
16416 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16417 DONE;
16418 else
16419 FAIL;
16420 })
16421
16422 (define_insn "strlenqi_1"
16423 [(set (match_operand:SI 0 "register_operand" "=&c")
16424 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16425 (match_operand:QI 2 "register_operand" "a")
16426 (match_operand:SI 3 "immediate_operand" "i")
16427 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16428 (use (reg:SI 19))
16429 (clobber (match_operand:SI 1 "register_operand" "=D"))
16430 (clobber (reg:CC 17))]
16431 "!TARGET_64BIT"
16432 "repnz{\;| }scasb"
16433 [(set_attr "type" "str")
16434 (set_attr "mode" "QI")
16435 (set_attr "prefix_rep" "1")])
16436
16437 (define_insn "strlenqi_rex_1"
16438 [(set (match_operand:DI 0 "register_operand" "=&c")
16439 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16440 (match_operand:QI 2 "register_operand" "a")
16441 (match_operand:DI 3 "immediate_operand" "i")
16442 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16443 (use (reg:SI 19))
16444 (clobber (match_operand:DI 1 "register_operand" "=D"))
16445 (clobber (reg:CC 17))]
16446 "TARGET_64BIT"
16447 "repnz{\;| }scasb"
16448 [(set_attr "type" "str")
16449 (set_attr "mode" "QI")
16450 (set_attr "prefix_rep" "1")])
16451
16452 ;; Peephole optimizations to clean up after cmpstr*. This should be
16453 ;; handled in combine, but it is not currently up to the task.
16454 ;; When used for their truth value, the cmpstr* expanders generate
16455 ;; code like this:
16456 ;;
16457 ;; repz cmpsb
16458 ;; seta %al
16459 ;; setb %dl
16460 ;; cmpb %al, %dl
16461 ;; jcc label
16462 ;;
16463 ;; The intermediate three instructions are unnecessary.
16464
16465 ;; This one handles cmpstr*_nz_1...
16466 (define_peephole2
16467 [(parallel[
16468 (set (reg:CC 17)
16469 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16470 (mem:BLK (match_operand 5 "register_operand" ""))))
16471 (use (match_operand 6 "register_operand" ""))
16472 (use (match_operand:SI 3 "immediate_operand" ""))
16473 (use (reg:SI 19))
16474 (clobber (match_operand 0 "register_operand" ""))
16475 (clobber (match_operand 1 "register_operand" ""))
16476 (clobber (match_operand 2 "register_operand" ""))])
16477 (set (match_operand:QI 7 "register_operand" "")
16478 (gtu:QI (reg:CC 17) (const_int 0)))
16479 (set (match_operand:QI 8 "register_operand" "")
16480 (ltu:QI (reg:CC 17) (const_int 0)))
16481 (set (reg 17)
16482 (compare (match_dup 7) (match_dup 8)))
16483 ]
16484 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16485 [(parallel[
16486 (set (reg:CC 17)
16487 (compare:CC (mem:BLK (match_dup 4))
16488 (mem:BLK (match_dup 5))))
16489 (use (match_dup 6))
16490 (use (match_dup 3))
16491 (use (reg:SI 19))
16492 (clobber (match_dup 0))
16493 (clobber (match_dup 1))
16494 (clobber (match_dup 2))])]
16495 "")
16496
16497 ;; ...and this one handles cmpstr*_1.
16498 (define_peephole2
16499 [(parallel[
16500 (set (reg:CC 17)
16501 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16502 (const_int 0))
16503 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16504 (mem:BLK (match_operand 5 "register_operand" "")))
16505 (const_int 0)))
16506 (use (match_operand:SI 3 "immediate_operand" ""))
16507 (use (reg:CC 17))
16508 (use (reg:SI 19))
16509 (clobber (match_operand 0 "register_operand" ""))
16510 (clobber (match_operand 1 "register_operand" ""))
16511 (clobber (match_operand 2 "register_operand" ""))])
16512 (set (match_operand:QI 7 "register_operand" "")
16513 (gtu:QI (reg:CC 17) (const_int 0)))
16514 (set (match_operand:QI 8 "register_operand" "")
16515 (ltu:QI (reg:CC 17) (const_int 0)))
16516 (set (reg 17)
16517 (compare (match_dup 7) (match_dup 8)))
16518 ]
16519 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16520 [(parallel[
16521 (set (reg:CC 17)
16522 (if_then_else:CC (ne (match_dup 6)
16523 (const_int 0))
16524 (compare:CC (mem:BLK (match_dup 4))
16525 (mem:BLK (match_dup 5)))
16526 (const_int 0)))
16527 (use (match_dup 3))
16528 (use (reg:CC 17))
16529 (use (reg:SI 19))
16530 (clobber (match_dup 0))
16531 (clobber (match_dup 1))
16532 (clobber (match_dup 2))])]
16533 "")
16534
16535
16536 \f
16537 ;; Conditional move instructions.
16538
16539 (define_expand "movdicc"
16540 [(set (match_operand:DI 0 "register_operand" "")
16541 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16542 (match_operand:DI 2 "general_operand" "")
16543 (match_operand:DI 3 "general_operand" "")))]
16544 "TARGET_64BIT"
16545 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16546
16547 (define_insn "x86_movdicc_0_m1_rex64"
16548 [(set (match_operand:DI 0 "register_operand" "=r")
16549 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16550 (const_int -1)
16551 (const_int 0)))
16552 (clobber (reg:CC 17))]
16553 "TARGET_64BIT"
16554 "sbb{q}\t%0, %0"
16555 ; Since we don't have the proper number of operands for an alu insn,
16556 ; fill in all the blanks.
16557 [(set_attr "type" "alu")
16558 (set_attr "pent_pair" "pu")
16559 (set_attr "memory" "none")
16560 (set_attr "imm_disp" "false")
16561 (set_attr "mode" "DI")
16562 (set_attr "length_immediate" "0")])
16563
16564 (define_insn "movdicc_c_rex64"
16565 [(set (match_operand:DI 0 "register_operand" "=r,r")
16566 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16567 [(reg 17) (const_int 0)])
16568 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16569 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16570 "TARGET_64BIT && TARGET_CMOVE
16571 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16572 "@
16573 cmov%O2%C1\t{%2, %0|%0, %2}
16574 cmov%O2%c1\t{%3, %0|%0, %3}"
16575 [(set_attr "type" "icmov")
16576 (set_attr "mode" "DI")])
16577
16578 (define_expand "movsicc"
16579 [(set (match_operand:SI 0 "register_operand" "")
16580 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16581 (match_operand:SI 2 "general_operand" "")
16582 (match_operand:SI 3 "general_operand" "")))]
16583 ""
16584 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16585
16586 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16587 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16588 ;; So just document what we're doing explicitly.
16589
16590 (define_insn "x86_movsicc_0_m1"
16591 [(set (match_operand:SI 0 "register_operand" "=r")
16592 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16593 (const_int -1)
16594 (const_int 0)))
16595 (clobber (reg:CC 17))]
16596 ""
16597 "sbb{l}\t%0, %0"
16598 ; Since we don't have the proper number of operands for an alu insn,
16599 ; fill in all the blanks.
16600 [(set_attr "type" "alu")
16601 (set_attr "pent_pair" "pu")
16602 (set_attr "memory" "none")
16603 (set_attr "imm_disp" "false")
16604 (set_attr "mode" "SI")
16605 (set_attr "length_immediate" "0")])
16606
16607 (define_insn "*movsicc_noc"
16608 [(set (match_operand:SI 0 "register_operand" "=r,r")
16609 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16610 [(reg 17) (const_int 0)])
16611 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16612 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16613 "TARGET_CMOVE
16614 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16615 "@
16616 cmov%O2%C1\t{%2, %0|%0, %2}
16617 cmov%O2%c1\t{%3, %0|%0, %3}"
16618 [(set_attr "type" "icmov")
16619 (set_attr "mode" "SI")])
16620
16621 (define_expand "movhicc"
16622 [(set (match_operand:HI 0 "register_operand" "")
16623 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16624 (match_operand:HI 2 "general_operand" "")
16625 (match_operand:HI 3 "general_operand" "")))]
16626 "TARGET_HIMODE_MATH"
16627 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16628
16629 (define_insn "*movhicc_noc"
16630 [(set (match_operand:HI 0 "register_operand" "=r,r")
16631 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16632 [(reg 17) (const_int 0)])
16633 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16634 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16635 "TARGET_CMOVE
16636 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16637 "@
16638 cmov%O2%C1\t{%2, %0|%0, %2}
16639 cmov%O2%c1\t{%3, %0|%0, %3}"
16640 [(set_attr "type" "icmov")
16641 (set_attr "mode" "HI")])
16642
16643 (define_expand "movqicc"
16644 [(set (match_operand:QI 0 "register_operand" "")
16645 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16646 (match_operand:QI 2 "general_operand" "")
16647 (match_operand:QI 3 "general_operand" "")))]
16648 "TARGET_QIMODE_MATH"
16649 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16650
16651 (define_insn_and_split "*movqicc_noc"
16652 [(set (match_operand:QI 0 "register_operand" "=r,r")
16653 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16654 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16655 (match_operand:QI 2 "register_operand" "r,0")
16656 (match_operand:QI 3 "register_operand" "0,r")))]
16657 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16658 "#"
16659 "&& reload_completed"
16660 [(set (match_dup 0)
16661 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16662 (match_dup 2)
16663 (match_dup 3)))]
16664 "operands[0] = gen_lowpart (SImode, operands[0]);
16665 operands[2] = gen_lowpart (SImode, operands[2]);
16666 operands[3] = gen_lowpart (SImode, operands[3]);"
16667 [(set_attr "type" "icmov")
16668 (set_attr "mode" "SI")])
16669
16670 (define_expand "movsfcc"
16671 [(set (match_operand:SF 0 "register_operand" "")
16672 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16673 (match_operand:SF 2 "register_operand" "")
16674 (match_operand:SF 3 "register_operand" "")))]
16675 "TARGET_CMOVE"
16676 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16677
16678 (define_insn "*movsfcc_1"
16679 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16680 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16681 [(reg 17) (const_int 0)])
16682 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16683 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16684 "TARGET_CMOVE
16685 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16686 "@
16687 fcmov%F1\t{%2, %0|%0, %2}
16688 fcmov%f1\t{%3, %0|%0, %3}
16689 cmov%O2%C1\t{%2, %0|%0, %2}
16690 cmov%O2%c1\t{%3, %0|%0, %3}"
16691 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16692 (set_attr "mode" "SF,SF,SI,SI")])
16693
16694 (define_expand "movdfcc"
16695 [(set (match_operand:DF 0 "register_operand" "")
16696 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16697 (match_operand:DF 2 "register_operand" "")
16698 (match_operand:DF 3 "register_operand" "")))]
16699 "TARGET_CMOVE"
16700 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16701
16702 (define_insn "*movdfcc_1"
16703 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16704 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16705 [(reg 17) (const_int 0)])
16706 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16707 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16708 "!TARGET_64BIT && TARGET_CMOVE
16709 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16710 "@
16711 fcmov%F1\t{%2, %0|%0, %2}
16712 fcmov%f1\t{%3, %0|%0, %3}
16713 #
16714 #"
16715 [(set_attr "type" "fcmov,fcmov,multi,multi")
16716 (set_attr "mode" "DF")])
16717
16718 (define_insn "*movdfcc_1_rex64"
16719 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16720 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16721 [(reg 17) (const_int 0)])
16722 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16723 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16724 "TARGET_64BIT && TARGET_CMOVE
16725 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16726 "@
16727 fcmov%F1\t{%2, %0|%0, %2}
16728 fcmov%f1\t{%3, %0|%0, %3}
16729 cmov%O2%C1\t{%2, %0|%0, %2}
16730 cmov%O2%c1\t{%3, %0|%0, %3}"
16731 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16732 (set_attr "mode" "DF")])
16733
16734 (define_split
16735 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16736 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16737 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16738 (match_operand:DF 2 "nonimmediate_operand" "")
16739 (match_operand:DF 3 "nonimmediate_operand" "")))]
16740 "!TARGET_64BIT && reload_completed"
16741 [(set (match_dup 2)
16742 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16743 (match_dup 5)
16744 (match_dup 7)))
16745 (set (match_dup 3)
16746 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16747 (match_dup 6)
16748 (match_dup 8)))]
16749 "split_di (operands+2, 1, operands+5, operands+6);
16750 split_di (operands+3, 1, operands+7, operands+8);
16751 split_di (operands, 1, operands+2, operands+3);")
16752
16753 (define_expand "movxfcc"
16754 [(set (match_operand:XF 0 "register_operand" "")
16755 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16756 (match_operand:XF 2 "register_operand" "")
16757 (match_operand:XF 3 "register_operand" "")))]
16758 "!TARGET_64BIT && TARGET_CMOVE"
16759 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16760
16761 (define_expand "movtfcc"
16762 [(set (match_operand:TF 0 "register_operand" "")
16763 (if_then_else:TF (match_operand 1 "comparison_operator" "")
16764 (match_operand:TF 2 "register_operand" "")
16765 (match_operand:TF 3 "register_operand" "")))]
16766 "TARGET_CMOVE"
16767 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16768
16769 (define_insn "*movxfcc_1"
16770 [(set (match_operand:XF 0 "register_operand" "=f,f")
16771 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16772 [(reg 17) (const_int 0)])
16773 (match_operand:XF 2 "register_operand" "f,0")
16774 (match_operand:XF 3 "register_operand" "0,f")))]
16775 "!TARGET_64BIT && TARGET_CMOVE"
16776 "@
16777 fcmov%F1\t{%2, %0|%0, %2}
16778 fcmov%f1\t{%3, %0|%0, %3}"
16779 [(set_attr "type" "fcmov")
16780 (set_attr "mode" "XF")])
16781
16782 (define_insn "*movtfcc_1"
16783 [(set (match_operand:TF 0 "register_operand" "=f,f")
16784 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
16785 [(reg 17) (const_int 0)])
16786 (match_operand:TF 2 "register_operand" "f,0")
16787 (match_operand:TF 3 "register_operand" "0,f")))]
16788 "TARGET_CMOVE"
16789 "@
16790 fcmov%F1\t{%2, %0|%0, %2}
16791 fcmov%f1\t{%3, %0|%0, %3}"
16792 [(set_attr "type" "fcmov")
16793 (set_attr "mode" "XF")])
16794
16795 (define_expand "minsf3"
16796 [(parallel [
16797 (set (match_operand:SF 0 "register_operand" "")
16798 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16799 (match_operand:SF 2 "nonimmediate_operand" ""))
16800 (match_dup 1)
16801 (match_dup 2)))
16802 (clobber (reg:CC 17))])]
16803 "TARGET_SSE"
16804 "")
16805
16806 (define_insn "*minsf"
16807 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16808 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16809 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16810 (match_dup 1)
16811 (match_dup 2)))
16812 (clobber (reg:CC 17))]
16813 "TARGET_SSE && TARGET_IEEE_FP"
16814 "#")
16815
16816 (define_insn "*minsf_nonieee"
16817 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16818 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16819 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16820 (match_dup 1)
16821 (match_dup 2)))
16822 (clobber (reg:CC 17))]
16823 "TARGET_SSE && !TARGET_IEEE_FP
16824 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16825 "#")
16826
16827 (define_split
16828 [(set (match_operand:SF 0 "register_operand" "")
16829 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16830 (match_operand:SF 2 "nonimmediate_operand" ""))
16831 (match_operand:SF 3 "register_operand" "")
16832 (match_operand:SF 4 "nonimmediate_operand" "")))
16833 (clobber (reg:CC 17))]
16834 "SSE_REG_P (operands[0]) && reload_completed
16835 && ((operands_match_p (operands[1], operands[3])
16836 && operands_match_p (operands[2], operands[4]))
16837 || (operands_match_p (operands[1], operands[4])
16838 && operands_match_p (operands[2], operands[3])))"
16839 [(set (match_dup 0)
16840 (if_then_else:SF (lt (match_dup 1)
16841 (match_dup 2))
16842 (match_dup 1)
16843 (match_dup 2)))])
16844
16845 ;; Conditional addition patterns
16846 (define_expand "addqicc"
16847 [(match_operand:QI 0 "register_operand" "")
16848 (match_operand 1 "comparison_operator" "")
16849 (match_operand:QI 2 "register_operand" "")
16850 (match_operand:QI 3 "const_int_operand" "")]
16851 ""
16852 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16853
16854 (define_expand "addhicc"
16855 [(match_operand:HI 0 "register_operand" "")
16856 (match_operand 1 "comparison_operator" "")
16857 (match_operand:HI 2 "register_operand" "")
16858 (match_operand:HI 3 "const_int_operand" "")]
16859 ""
16860 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16861
16862 (define_expand "addsicc"
16863 [(match_operand:SI 0 "register_operand" "")
16864 (match_operand 1 "comparison_operator" "")
16865 (match_operand:SI 2 "register_operand" "")
16866 (match_operand:SI 3 "const_int_operand" "")]
16867 ""
16868 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16869
16870 (define_expand "adddicc"
16871 [(match_operand:DI 0 "register_operand" "")
16872 (match_operand 1 "comparison_operator" "")
16873 (match_operand:DI 2 "register_operand" "")
16874 (match_operand:DI 3 "const_int_operand" "")]
16875 "TARGET_64BIT"
16876 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16877
16878 ;; We can't represent the LT test directly. Do this by swapping the operands.
16879
16880 (define_split
16881 [(set (match_operand:SF 0 "fp_register_operand" "")
16882 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16883 (match_operand:SF 2 "register_operand" ""))
16884 (match_operand:SF 3 "register_operand" "")
16885 (match_operand:SF 4 "register_operand" "")))
16886 (clobber (reg:CC 17))]
16887 "reload_completed
16888 && ((operands_match_p (operands[1], operands[3])
16889 && operands_match_p (operands[2], operands[4]))
16890 || (operands_match_p (operands[1], operands[4])
16891 && operands_match_p (operands[2], operands[3])))"
16892 [(set (reg:CCFP 17)
16893 (compare:CCFP (match_dup 2)
16894 (match_dup 1)))
16895 (set (match_dup 0)
16896 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16897 (match_dup 1)
16898 (match_dup 2)))])
16899
16900 (define_insn "*minsf_sse"
16901 [(set (match_operand:SF 0 "register_operand" "=x")
16902 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16903 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16904 (match_dup 1)
16905 (match_dup 2)))]
16906 "TARGET_SSE && reload_completed"
16907 "minss\t{%2, %0|%0, %2}"
16908 [(set_attr "type" "sse")
16909 (set_attr "mode" "SF")])
16910
16911 (define_expand "mindf3"
16912 [(parallel [
16913 (set (match_operand:DF 0 "register_operand" "")
16914 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16915 (match_operand:DF 2 "nonimmediate_operand" ""))
16916 (match_dup 1)
16917 (match_dup 2)))
16918 (clobber (reg:CC 17))])]
16919 "TARGET_SSE2 && TARGET_SSE_MATH"
16920 "#")
16921
16922 (define_insn "*mindf"
16923 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16924 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16925 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16926 (match_dup 1)
16927 (match_dup 2)))
16928 (clobber (reg:CC 17))]
16929 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16930 "#")
16931
16932 (define_insn "*mindf_nonieee"
16933 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16934 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16935 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16936 (match_dup 1)
16937 (match_dup 2)))
16938 (clobber (reg:CC 17))]
16939 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16941 "#")
16942
16943 (define_split
16944 [(set (match_operand:DF 0 "register_operand" "")
16945 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16946 (match_operand:DF 2 "nonimmediate_operand" ""))
16947 (match_operand:DF 3 "register_operand" "")
16948 (match_operand:DF 4 "nonimmediate_operand" "")))
16949 (clobber (reg:CC 17))]
16950 "SSE_REG_P (operands[0]) && reload_completed
16951 && ((operands_match_p (operands[1], operands[3])
16952 && operands_match_p (operands[2], operands[4]))
16953 || (operands_match_p (operands[1], operands[4])
16954 && operands_match_p (operands[2], operands[3])))"
16955 [(set (match_dup 0)
16956 (if_then_else:DF (lt (match_dup 1)
16957 (match_dup 2))
16958 (match_dup 1)
16959 (match_dup 2)))])
16960
16961 ;; We can't represent the LT test directly. Do this by swapping the operands.
16962 (define_split
16963 [(set (match_operand:DF 0 "fp_register_operand" "")
16964 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16965 (match_operand:DF 2 "register_operand" ""))
16966 (match_operand:DF 3 "register_operand" "")
16967 (match_operand:DF 4 "register_operand" "")))
16968 (clobber (reg:CC 17))]
16969 "reload_completed
16970 && ((operands_match_p (operands[1], operands[3])
16971 && operands_match_p (operands[2], operands[4]))
16972 || (operands_match_p (operands[1], operands[4])
16973 && operands_match_p (operands[2], operands[3])))"
16974 [(set (reg:CCFP 17)
16975 (compare:CCFP (match_dup 2)
16976 (match_dup 2)))
16977 (set (match_dup 0)
16978 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16979 (match_dup 1)
16980 (match_dup 2)))])
16981
16982 (define_insn "*mindf_sse"
16983 [(set (match_operand:DF 0 "register_operand" "=Y")
16984 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16985 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16986 (match_dup 1)
16987 (match_dup 2)))]
16988 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16989 "minsd\t{%2, %0|%0, %2}"
16990 [(set_attr "type" "sse")
16991 (set_attr "mode" "DF")])
16992
16993 (define_expand "maxsf3"
16994 [(parallel [
16995 (set (match_operand:SF 0 "register_operand" "")
16996 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16997 (match_operand:SF 2 "nonimmediate_operand" ""))
16998 (match_dup 1)
16999 (match_dup 2)))
17000 (clobber (reg:CC 17))])]
17001 "TARGET_SSE"
17002 "#")
17003
17004 (define_insn "*maxsf"
17005 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17006 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17007 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17008 (match_dup 1)
17009 (match_dup 2)))
17010 (clobber (reg:CC 17))]
17011 "TARGET_SSE && TARGET_IEEE_FP"
17012 "#")
17013
17014 (define_insn "*maxsf_nonieee"
17015 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17016 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17017 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17018 (match_dup 1)
17019 (match_dup 2)))
17020 (clobber (reg:CC 17))]
17021 "TARGET_SSE && !TARGET_IEEE_FP
17022 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17023 "#")
17024
17025 (define_split
17026 [(set (match_operand:SF 0 "register_operand" "")
17027 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17028 (match_operand:SF 2 "nonimmediate_operand" ""))
17029 (match_operand:SF 3 "register_operand" "")
17030 (match_operand:SF 4 "nonimmediate_operand" "")))
17031 (clobber (reg:CC 17))]
17032 "SSE_REG_P (operands[0]) && reload_completed
17033 && ((operands_match_p (operands[1], operands[3])
17034 && operands_match_p (operands[2], operands[4]))
17035 || (operands_match_p (operands[1], operands[4])
17036 && operands_match_p (operands[2], operands[3])))"
17037 [(set (match_dup 0)
17038 (if_then_else:SF (gt (match_dup 1)
17039 (match_dup 2))
17040 (match_dup 1)
17041 (match_dup 2)))])
17042
17043 (define_split
17044 [(set (match_operand:SF 0 "fp_register_operand" "")
17045 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17046 (match_operand:SF 2 "register_operand" ""))
17047 (match_operand:SF 3 "register_operand" "")
17048 (match_operand:SF 4 "register_operand" "")))
17049 (clobber (reg:CC 17))]
17050 "reload_completed
17051 && ((operands_match_p (operands[1], operands[3])
17052 && operands_match_p (operands[2], operands[4]))
17053 || (operands_match_p (operands[1], operands[4])
17054 && operands_match_p (operands[2], operands[3])))"
17055 [(set (reg:CCFP 17)
17056 (compare:CCFP (match_dup 1)
17057 (match_dup 2)))
17058 (set (match_dup 0)
17059 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17060 (match_dup 1)
17061 (match_dup 2)))])
17062
17063 (define_insn "*maxsf_sse"
17064 [(set (match_operand:SF 0 "register_operand" "=x")
17065 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17066 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17067 (match_dup 1)
17068 (match_dup 2)))]
17069 "TARGET_SSE && reload_completed"
17070 "maxss\t{%2, %0|%0, %2}"
17071 [(set_attr "type" "sse")
17072 (set_attr "mode" "SF")])
17073
17074 (define_expand "maxdf3"
17075 [(parallel [
17076 (set (match_operand:DF 0 "register_operand" "")
17077 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17078 (match_operand:DF 2 "nonimmediate_operand" ""))
17079 (match_dup 1)
17080 (match_dup 2)))
17081 (clobber (reg:CC 17))])]
17082 "TARGET_SSE2 && TARGET_SSE_MATH"
17083 "#")
17084
17085 (define_insn "*maxdf"
17086 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17087 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17088 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17089 (match_dup 1)
17090 (match_dup 2)))
17091 (clobber (reg:CC 17))]
17092 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17093 "#")
17094
17095 (define_insn "*maxdf_nonieee"
17096 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17097 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17098 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17099 (match_dup 1)
17100 (match_dup 2)))
17101 (clobber (reg:CC 17))]
17102 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17103 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17104 "#")
17105
17106 (define_split
17107 [(set (match_operand:DF 0 "register_operand" "")
17108 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17109 (match_operand:DF 2 "nonimmediate_operand" ""))
17110 (match_operand:DF 3 "register_operand" "")
17111 (match_operand:DF 4 "nonimmediate_operand" "")))
17112 (clobber (reg:CC 17))]
17113 "SSE_REG_P (operands[0]) && reload_completed
17114 && ((operands_match_p (operands[1], operands[3])
17115 && operands_match_p (operands[2], operands[4]))
17116 || (operands_match_p (operands[1], operands[4])
17117 && operands_match_p (operands[2], operands[3])))"
17118 [(set (match_dup 0)
17119 (if_then_else:DF (gt (match_dup 1)
17120 (match_dup 2))
17121 (match_dup 1)
17122 (match_dup 2)))])
17123
17124 (define_split
17125 [(set (match_operand:DF 0 "fp_register_operand" "")
17126 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17127 (match_operand:DF 2 "register_operand" ""))
17128 (match_operand:DF 3 "register_operand" "")
17129 (match_operand:DF 4 "register_operand" "")))
17130 (clobber (reg:CC 17))]
17131 "reload_completed
17132 && ((operands_match_p (operands[1], operands[3])
17133 && operands_match_p (operands[2], operands[4]))
17134 || (operands_match_p (operands[1], operands[4])
17135 && operands_match_p (operands[2], operands[3])))"
17136 [(set (reg:CCFP 17)
17137 (compare:CCFP (match_dup 1)
17138 (match_dup 2)))
17139 (set (match_dup 0)
17140 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17141 (match_dup 1)
17142 (match_dup 2)))])
17143
17144 (define_insn "*maxdf_sse"
17145 [(set (match_operand:DF 0 "register_operand" "=Y")
17146 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17147 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17148 (match_dup 1)
17149 (match_dup 2)))]
17150 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17151 "maxsd\t{%2, %0|%0, %2}"
17152 [(set_attr "type" "sse")
17153 (set_attr "mode" "DF")])
17154 \f
17155 ;; Misc patterns (?)
17156
17157 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17158 ;; Otherwise there will be nothing to keep
17159 ;;
17160 ;; [(set (reg ebp) (reg esp))]
17161 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17162 ;; (clobber (eflags)]
17163 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17164 ;;
17165 ;; in proper program order.
17166 (define_expand "pro_epilogue_adjust_stack"
17167 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17168 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17169 (match_operand:SI 2 "immediate_operand" "i,i")))
17170 (clobber (reg:CC 17))
17171 (clobber (mem:BLK (scratch)))])]
17172 ""
17173 {
17174 if (TARGET_64BIT)
17175 {
17176 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17177 (operands[0], operands[1], operands[2]));
17178 DONE;
17179 }
17180 })
17181
17182 (define_insn "*pro_epilogue_adjust_stack_1"
17183 [(set (match_operand:SI 0 "register_operand" "=r,r")
17184 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17185 (match_operand:SI 2 "immediate_operand" "i,i")))
17186 (clobber (reg:CC 17))
17187 (clobber (mem:BLK (scratch)))]
17188 "!TARGET_64BIT"
17189 {
17190 switch (get_attr_type (insn))
17191 {
17192 case TYPE_IMOV:
17193 return "mov{l}\t{%1, %0|%0, %1}";
17194
17195 case TYPE_ALU:
17196 if (GET_CODE (operands[2]) == CONST_INT
17197 && (INTVAL (operands[2]) == 128
17198 || (INTVAL (operands[2]) < 0
17199 && INTVAL (operands[2]) != -128)))
17200 {
17201 operands[2] = GEN_INT (-INTVAL (operands[2]));
17202 return "sub{l}\t{%2, %0|%0, %2}";
17203 }
17204 return "add{l}\t{%2, %0|%0, %2}";
17205
17206 case TYPE_LEA:
17207 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17208 return "lea{l}\t{%a2, %0|%0, %a2}";
17209
17210 default:
17211 abort ();
17212 }
17213 }
17214 [(set (attr "type")
17215 (cond [(eq_attr "alternative" "0")
17216 (const_string "alu")
17217 (match_operand:SI 2 "const0_operand" "")
17218 (const_string "imov")
17219 ]
17220 (const_string "lea")))
17221 (set_attr "mode" "SI")])
17222
17223 (define_insn "pro_epilogue_adjust_stack_rex64"
17224 [(set (match_operand:DI 0 "register_operand" "=r,r")
17225 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17226 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17227 (clobber (reg:CC 17))
17228 (clobber (mem:BLK (scratch)))]
17229 "TARGET_64BIT"
17230 {
17231 switch (get_attr_type (insn))
17232 {
17233 case TYPE_IMOV:
17234 return "mov{q}\t{%1, %0|%0, %1}";
17235
17236 case TYPE_ALU:
17237 if (GET_CODE (operands[2]) == CONST_INT
17238 && (INTVAL (operands[2]) == 128
17239 || (INTVAL (operands[2]) < 0
17240 && INTVAL (operands[2]) != -128)))
17241 {
17242 operands[2] = GEN_INT (-INTVAL (operands[2]));
17243 return "sub{q}\t{%2, %0|%0, %2}";
17244 }
17245 return "add{q}\t{%2, %0|%0, %2}";
17246
17247 case TYPE_LEA:
17248 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17249 return "lea{q}\t{%a2, %0|%0, %a2}";
17250
17251 default:
17252 abort ();
17253 }
17254 }
17255 [(set (attr "type")
17256 (cond [(eq_attr "alternative" "0")
17257 (const_string "alu")
17258 (match_operand:DI 2 "const0_operand" "")
17259 (const_string "imov")
17260 ]
17261 (const_string "lea")))
17262 (set_attr "mode" "DI")])
17263
17264
17265 ;; Placeholder for the conditional moves. This one is split either to SSE
17266 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17267 ;; fact is that compares supported by the cmp??ss instructions are exactly
17268 ;; swapped of those supported by cmove sequence.
17269 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17270 ;; supported by i387 comparisons and we do need to emit two conditional moves
17271 ;; in tandem.
17272
17273 (define_insn "sse_movsfcc"
17274 [(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")
17275 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17276 [(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")
17277 (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")])
17278 (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")
17279 (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")))
17280 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17281 (clobber (reg:CC 17))]
17282 "TARGET_SSE
17283 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17284 /* Avoid combine from being smart and converting min/max
17285 instruction patterns into conditional moves. */
17286 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17287 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17288 || !rtx_equal_p (operands[4], operands[2])
17289 || !rtx_equal_p (operands[5], operands[3]))
17290 && (!TARGET_IEEE_FP
17291 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17292 "#")
17293
17294 (define_insn "sse_movsfcc_eq"
17295 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17296 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17297 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17298 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17299 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17300 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17301 (clobber (reg:CC 17))]
17302 "TARGET_SSE
17303 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17304 "#")
17305
17306 (define_insn "sse_movdfcc"
17307 [(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")
17308 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17309 [(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")
17310 (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")])
17311 (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")
17312 (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")))
17313 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17314 (clobber (reg:CC 17))]
17315 "TARGET_SSE2
17316 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17317 /* Avoid combine from being smart and converting min/max
17318 instruction patterns into conditional moves. */
17319 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17320 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17321 || !rtx_equal_p (operands[4], operands[2])
17322 || !rtx_equal_p (operands[5], operands[3]))
17323 && (!TARGET_IEEE_FP
17324 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17325 "#")
17326
17327 (define_insn "sse_movdfcc_eq"
17328 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17329 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17330 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17331 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17332 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17333 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17334 (clobber (reg:CC 17))]
17335 "TARGET_SSE
17336 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17337 "#")
17338
17339 ;; For non-sse moves just expand the usual cmove sequence.
17340 (define_split
17341 [(set (match_operand 0 "register_operand" "")
17342 (if_then_else (match_operator 1 "comparison_operator"
17343 [(match_operand 4 "nonimmediate_operand" "")
17344 (match_operand 5 "register_operand" "")])
17345 (match_operand 2 "nonimmediate_operand" "")
17346 (match_operand 3 "nonimmediate_operand" "")))
17347 (clobber (match_operand 6 "" ""))
17348 (clobber (reg:CC 17))]
17349 "!SSE_REG_P (operands[0]) && reload_completed
17350 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17351 [(const_int 0)]
17352 {
17353 ix86_compare_op0 = operands[5];
17354 ix86_compare_op1 = operands[4];
17355 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17356 VOIDmode, operands[5], operands[4]);
17357 ix86_expand_fp_movcc (operands);
17358 DONE;
17359 })
17360
17361 ;; Split SSE based conditional move into sequence:
17362 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17363 ;; and op2, op0 - zero op2 if comparison was false
17364 ;; nand op0, op3 - load op3 to op0 if comparison was false
17365 ;; or op2, op0 - get the nonzero one into the result.
17366 (define_split
17367 [(set (match_operand 0 "register_operand" "")
17368 (if_then_else (match_operator 1 "sse_comparison_operator"
17369 [(match_operand 4 "register_operand" "")
17370 (match_operand 5 "nonimmediate_operand" "")])
17371 (match_operand 2 "register_operand" "")
17372 (match_operand 3 "register_operand" "")))
17373 (clobber (match_operand 6 "" ""))
17374 (clobber (reg:CC 17))]
17375 "SSE_REG_P (operands[0]) && reload_completed"
17376 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17377 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17378 (subreg:TI (match_dup 4) 0)))
17379 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17380 (subreg:TI (match_dup 3) 0)))
17381 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17382 (subreg:TI (match_dup 7) 0)))]
17383 {
17384 if (GET_MODE (operands[2]) == DFmode
17385 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17386 {
17387 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17388 emit_insn (gen_sse2_unpcklpd (op, op, op));
17389 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17390 emit_insn (gen_sse2_unpcklpd (op, op, op));
17391 }
17392
17393 /* If op2 == op3, op3 would be clobbered before it is used. */
17394 if (operands_match_p (operands[2], operands[3]))
17395 {
17396 emit_move_insn (operands[0], operands[2]);
17397 DONE;
17398 }
17399
17400 PUT_MODE (operands[1], GET_MODE (operands[0]));
17401 if (operands_match_p (operands[0], operands[4]))
17402 operands[6] = operands[4], operands[7] = operands[2];
17403 else
17404 operands[6] = operands[2], operands[7] = operands[4];
17405 })
17406
17407 ;; Special case of conditional move we can handle effectively.
17408 ;; Do not brother with the integer/floating point case, since these are
17409 ;; bot considerably slower, unlike in the generic case.
17410 (define_insn "*sse_movsfcc_const0_1"
17411 [(set (match_operand:SF 0 "register_operand" "=&x")
17412 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17413 [(match_operand:SF 4 "register_operand" "0")
17414 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17415 (match_operand:SF 2 "register_operand" "x")
17416 (match_operand:SF 3 "const0_operand" "X")))]
17417 "TARGET_SSE"
17418 "#")
17419
17420 (define_insn "*sse_movsfcc_const0_2"
17421 [(set (match_operand:SF 0 "register_operand" "=&x")
17422 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17423 [(match_operand:SF 4 "register_operand" "0")
17424 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17425 (match_operand:SF 2 "const0_operand" "X")
17426 (match_operand:SF 3 "register_operand" "x")))]
17427 "TARGET_SSE"
17428 "#")
17429
17430 (define_insn "*sse_movsfcc_const0_3"
17431 [(set (match_operand:SF 0 "register_operand" "=&x")
17432 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17433 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17434 (match_operand:SF 5 "register_operand" "0")])
17435 (match_operand:SF 2 "register_operand" "x")
17436 (match_operand:SF 3 "const0_operand" "X")))]
17437 "TARGET_SSE"
17438 "#")
17439
17440 (define_insn "*sse_movsfcc_const0_4"
17441 [(set (match_operand:SF 0 "register_operand" "=&x")
17442 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17443 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17444 (match_operand:SF 5 "register_operand" "0")])
17445 (match_operand:SF 2 "const0_operand" "X")
17446 (match_operand:SF 3 "register_operand" "x")))]
17447 "TARGET_SSE"
17448 "#")
17449
17450 (define_insn "*sse_movdfcc_const0_1"
17451 [(set (match_operand:DF 0 "register_operand" "=&Y")
17452 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17453 [(match_operand:DF 4 "register_operand" "0")
17454 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17455 (match_operand:DF 2 "register_operand" "Y")
17456 (match_operand:DF 3 "const0_operand" "X")))]
17457 "TARGET_SSE2"
17458 "#")
17459
17460 (define_insn "*sse_movdfcc_const0_2"
17461 [(set (match_operand:DF 0 "register_operand" "=&Y")
17462 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17463 [(match_operand:DF 4 "register_operand" "0")
17464 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17465 (match_operand:DF 2 "const0_operand" "X")
17466 (match_operand:DF 3 "register_operand" "Y")))]
17467 "TARGET_SSE2"
17468 "#")
17469
17470 (define_insn "*sse_movdfcc_const0_3"
17471 [(set (match_operand:DF 0 "register_operand" "=&Y")
17472 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17473 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17474 (match_operand:DF 5 "register_operand" "0")])
17475 (match_operand:DF 2 "register_operand" "Y")
17476 (match_operand:DF 3 "const0_operand" "X")))]
17477 "TARGET_SSE2"
17478 "#")
17479
17480 (define_insn "*sse_movdfcc_const0_4"
17481 [(set (match_operand:DF 0 "register_operand" "=&Y")
17482 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17483 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17484 (match_operand:DF 5 "register_operand" "0")])
17485 (match_operand:DF 2 "const0_operand" "X")
17486 (match_operand:DF 3 "register_operand" "Y")))]
17487 "TARGET_SSE2"
17488 "#")
17489
17490 (define_split
17491 [(set (match_operand 0 "register_operand" "")
17492 (if_then_else (match_operator 1 "comparison_operator"
17493 [(match_operand 4 "nonimmediate_operand" "")
17494 (match_operand 5 "nonimmediate_operand" "")])
17495 (match_operand 2 "nonmemory_operand" "")
17496 (match_operand 3 "nonmemory_operand" "")))]
17497 "SSE_REG_P (operands[0]) && reload_completed
17498 && (const0_operand (operands[2], GET_MODE (operands[0]))
17499 || const0_operand (operands[3], GET_MODE (operands[0])))"
17500 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17501 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17502 (match_dup 7)))]
17503 {
17504 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17505 && GET_MODE (operands[2]) == DFmode)
17506 {
17507 if (REG_P (operands[2]))
17508 {
17509 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17510 emit_insn (gen_sse2_unpcklpd (op, op, op));
17511 }
17512 if (REG_P (operands[3]))
17513 {
17514 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17515 emit_insn (gen_sse2_unpcklpd (op, op, op));
17516 }
17517 }
17518 PUT_MODE (operands[1], GET_MODE (operands[0]));
17519 if (!sse_comparison_operator (operands[1], VOIDmode)
17520 || !rtx_equal_p (operands[0], operands[4]))
17521 {
17522 rtx tmp = operands[5];
17523 operands[5] = operands[4];
17524 operands[4] = tmp;
17525 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17526 }
17527 if (!rtx_equal_p (operands[0], operands[4]))
17528 abort ();
17529 if (const0_operand (operands[2], GET_MODE (operands[0])))
17530 {
17531 operands[7] = operands[3];
17532 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17533 0));
17534 }
17535 else
17536 {
17537 operands[7] = operands[2];
17538 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17539 }
17540 operands[7] = simplify_gen_subreg (TImode, operands[7],
17541 GET_MODE (operands[7]), 0);
17542 })
17543
17544 (define_expand "allocate_stack_worker"
17545 [(match_operand:SI 0 "register_operand" "")]
17546 "TARGET_STACK_PROBE"
17547 {
17548 if (TARGET_64BIT)
17549 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17550 else
17551 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17552 DONE;
17553 })
17554
17555 (define_insn "allocate_stack_worker_1"
17556 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17557 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17558 (clobber (match_dup 0))
17559 (clobber (reg:CC 17))]
17560 "!TARGET_64BIT && TARGET_STACK_PROBE"
17561 "call\t__alloca"
17562 [(set_attr "type" "multi")
17563 (set_attr "length" "5")])
17564
17565 (define_insn "allocate_stack_worker_rex64"
17566 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17567 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17568 (clobber (match_dup 0))
17569 (clobber (reg:CC 17))]
17570 "TARGET_64BIT && TARGET_STACK_PROBE"
17571 "call\t__alloca"
17572 [(set_attr "type" "multi")
17573 (set_attr "length" "5")])
17574
17575 (define_expand "allocate_stack"
17576 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17577 (minus:SI (reg:SI 7)
17578 (match_operand:SI 1 "general_operand" "")))
17579 (clobber (reg:CC 17))])
17580 (parallel [(set (reg:SI 7)
17581 (minus:SI (reg:SI 7) (match_dup 1)))
17582 (clobber (reg:CC 17))])]
17583 "TARGET_STACK_PROBE"
17584 {
17585 #ifdef CHECK_STACK_LIMIT
17586 if (GET_CODE (operands[1]) == CONST_INT
17587 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17588 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17589 operands[1]));
17590 else
17591 #endif
17592 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17593 operands[1])));
17594
17595 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17596 DONE;
17597 })
17598
17599 (define_expand "builtin_setjmp_receiver"
17600 [(label_ref (match_operand 0 "" ""))]
17601 "!TARGET_64BIT && flag_pic"
17602 {
17603 emit_insn (gen_set_got (pic_offset_table_rtx));
17604 DONE;
17605 })
17606 \f
17607 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17608
17609 (define_split
17610 [(set (match_operand 0 "register_operand" "")
17611 (match_operator 3 "promotable_binary_operator"
17612 [(match_operand 1 "register_operand" "")
17613 (match_operand 2 "aligned_operand" "")]))
17614 (clobber (reg:CC 17))]
17615 "! TARGET_PARTIAL_REG_STALL && reload_completed
17616 && ((GET_MODE (operands[0]) == HImode
17617 && ((!optimize_size && !TARGET_FAST_PREFIX)
17618 || GET_CODE (operands[2]) != CONST_INT
17619 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17620 || (GET_MODE (operands[0]) == QImode
17621 && (TARGET_PROMOTE_QImode || optimize_size)))"
17622 [(parallel [(set (match_dup 0)
17623 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17624 (clobber (reg:CC 17))])]
17625 "operands[0] = gen_lowpart (SImode, operands[0]);
17626 operands[1] = gen_lowpart (SImode, operands[1]);
17627 if (GET_CODE (operands[3]) != ASHIFT)
17628 operands[2] = gen_lowpart (SImode, operands[2]);
17629 PUT_MODE (operands[3], SImode);")
17630
17631 (define_split
17632 [(set (reg 17)
17633 (compare (and (match_operand 1 "aligned_operand" "")
17634 (match_operand 2 "const_int_operand" ""))
17635 (const_int 0)))
17636 (set (match_operand 0 "register_operand" "")
17637 (and (match_dup 1) (match_dup 2)))]
17638 "! TARGET_PARTIAL_REG_STALL && reload_completed
17639 && ix86_match_ccmode (insn, CCNOmode)
17640 && (GET_MODE (operands[0]) == HImode
17641 || (GET_MODE (operands[0]) == QImode
17642 /* Ensure that the operand will remain sign extended immediate. */
17643 && INTVAL (operands[2]) >= 0
17644 && (TARGET_PROMOTE_QImode || optimize_size)))"
17645 [(parallel [(set (reg:CCNO 17)
17646 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17647 (const_int 0)))
17648 (set (match_dup 0)
17649 (and:SI (match_dup 1) (match_dup 2)))])]
17650 "operands[2]
17651 = gen_int_mode (INTVAL (operands[2])
17652 & GET_MODE_MASK (GET_MODE (operands[0])),
17653 SImode);
17654 operands[0] = gen_lowpart (SImode, operands[0]);
17655 operands[1] = gen_lowpart (SImode, operands[1]);")
17656
17657 ; Don't promote the QImode tests, as i386 don't have encoding of
17658 ; the test instruction with 32bit sign extended immediate and thus
17659 ; the code grows.
17660 (define_split
17661 [(set (reg 17)
17662 (compare (and (match_operand:HI 0 "aligned_operand" "")
17663 (match_operand:HI 1 "const_int_operand" ""))
17664 (const_int 0)))]
17665 "! TARGET_PARTIAL_REG_STALL && reload_completed
17666 && ix86_match_ccmode (insn, CCNOmode)
17667 && GET_MODE (operands[0]) == HImode"
17668 [(set (reg:CCNO 17)
17669 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17670 (const_int 0)))]
17671 "operands[1]
17672 = gen_int_mode (INTVAL (operands[1])
17673 & GET_MODE_MASK (GET_MODE (operands[0])),
17674 SImode);
17675 operands[0] = gen_lowpart (SImode, operands[0]);")
17676
17677 (define_split
17678 [(set (match_operand 0 "register_operand" "")
17679 (neg (match_operand 1 "register_operand" "")))
17680 (clobber (reg:CC 17))]
17681 "! TARGET_PARTIAL_REG_STALL && reload_completed
17682 && (GET_MODE (operands[0]) == HImode
17683 || (GET_MODE (operands[0]) == QImode
17684 && (TARGET_PROMOTE_QImode || optimize_size)))"
17685 [(parallel [(set (match_dup 0)
17686 (neg:SI (match_dup 1)))
17687 (clobber (reg:CC 17))])]
17688 "operands[0] = gen_lowpart (SImode, operands[0]);
17689 operands[1] = gen_lowpart (SImode, operands[1]);")
17690
17691 (define_split
17692 [(set (match_operand 0 "register_operand" "")
17693 (not (match_operand 1 "register_operand" "")))]
17694 "! TARGET_PARTIAL_REG_STALL && reload_completed
17695 && (GET_MODE (operands[0]) == HImode
17696 || (GET_MODE (operands[0]) == QImode
17697 && (TARGET_PROMOTE_QImode || optimize_size)))"
17698 [(set (match_dup 0)
17699 (not:SI (match_dup 1)))]
17700 "operands[0] = gen_lowpart (SImode, operands[0]);
17701 operands[1] = gen_lowpart (SImode, operands[1]);")
17702
17703 (define_split
17704 [(set (match_operand 0 "register_operand" "")
17705 (if_then_else (match_operator 1 "comparison_operator"
17706 [(reg 17) (const_int 0)])
17707 (match_operand 2 "register_operand" "")
17708 (match_operand 3 "register_operand" "")))]
17709 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17710 && (GET_MODE (operands[0]) == HImode
17711 || (GET_MODE (operands[0]) == QImode
17712 && (TARGET_PROMOTE_QImode || optimize_size)))"
17713 [(set (match_dup 0)
17714 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17715 "operands[0] = gen_lowpart (SImode, operands[0]);
17716 operands[2] = gen_lowpart (SImode, operands[2]);
17717 operands[3] = gen_lowpart (SImode, operands[3]);")
17718
17719 \f
17720 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17721 ;; transform a complex memory operation into two memory to register operations.
17722
17723 ;; Don't push memory operands
17724 (define_peephole2
17725 [(set (match_operand:SI 0 "push_operand" "")
17726 (match_operand:SI 1 "memory_operand" ""))
17727 (match_scratch:SI 2 "r")]
17728 "! optimize_size && ! TARGET_PUSH_MEMORY"
17729 [(set (match_dup 2) (match_dup 1))
17730 (set (match_dup 0) (match_dup 2))]
17731 "")
17732
17733 (define_peephole2
17734 [(set (match_operand:DI 0 "push_operand" "")
17735 (match_operand:DI 1 "memory_operand" ""))
17736 (match_scratch:DI 2 "r")]
17737 "! optimize_size && ! TARGET_PUSH_MEMORY"
17738 [(set (match_dup 2) (match_dup 1))
17739 (set (match_dup 0) (match_dup 2))]
17740 "")
17741
17742 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17743 ;; SImode pushes.
17744 (define_peephole2
17745 [(set (match_operand:SF 0 "push_operand" "")
17746 (match_operand:SF 1 "memory_operand" ""))
17747 (match_scratch:SF 2 "r")]
17748 "! optimize_size && ! TARGET_PUSH_MEMORY"
17749 [(set (match_dup 2) (match_dup 1))
17750 (set (match_dup 0) (match_dup 2))]
17751 "")
17752
17753 (define_peephole2
17754 [(set (match_operand:HI 0 "push_operand" "")
17755 (match_operand:HI 1 "memory_operand" ""))
17756 (match_scratch:HI 2 "r")]
17757 "! optimize_size && ! TARGET_PUSH_MEMORY"
17758 [(set (match_dup 2) (match_dup 1))
17759 (set (match_dup 0) (match_dup 2))]
17760 "")
17761
17762 (define_peephole2
17763 [(set (match_operand:QI 0 "push_operand" "")
17764 (match_operand:QI 1 "memory_operand" ""))
17765 (match_scratch:QI 2 "q")]
17766 "! optimize_size && ! TARGET_PUSH_MEMORY"
17767 [(set (match_dup 2) (match_dup 1))
17768 (set (match_dup 0) (match_dup 2))]
17769 "")
17770
17771 ;; Don't move an immediate directly to memory when the instruction
17772 ;; gets too big.
17773 (define_peephole2
17774 [(match_scratch:SI 1 "r")
17775 (set (match_operand:SI 0 "memory_operand" "")
17776 (const_int 0))]
17777 "! optimize_size
17778 && ! TARGET_USE_MOV0
17779 && TARGET_SPLIT_LONG_MOVES
17780 && get_attr_length (insn) >= ix86_cost->large_insn
17781 && peep2_regno_dead_p (0, FLAGS_REG)"
17782 [(parallel [(set (match_dup 1) (const_int 0))
17783 (clobber (reg:CC 17))])
17784 (set (match_dup 0) (match_dup 1))]
17785 "")
17786
17787 (define_peephole2
17788 [(match_scratch:HI 1 "r")
17789 (set (match_operand:HI 0 "memory_operand" "")
17790 (const_int 0))]
17791 "! optimize_size
17792 && ! TARGET_USE_MOV0
17793 && TARGET_SPLIT_LONG_MOVES
17794 && get_attr_length (insn) >= ix86_cost->large_insn
17795 && peep2_regno_dead_p (0, FLAGS_REG)"
17796 [(parallel [(set (match_dup 2) (const_int 0))
17797 (clobber (reg:CC 17))])
17798 (set (match_dup 0) (match_dup 1))]
17799 "operands[2] = gen_lowpart (SImode, operands[1]);")
17800
17801 (define_peephole2
17802 [(match_scratch:QI 1 "q")
17803 (set (match_operand:QI 0 "memory_operand" "")
17804 (const_int 0))]
17805 "! optimize_size
17806 && ! TARGET_USE_MOV0
17807 && TARGET_SPLIT_LONG_MOVES
17808 && get_attr_length (insn) >= ix86_cost->large_insn
17809 && peep2_regno_dead_p (0, FLAGS_REG)"
17810 [(parallel [(set (match_dup 2) (const_int 0))
17811 (clobber (reg:CC 17))])
17812 (set (match_dup 0) (match_dup 1))]
17813 "operands[2] = gen_lowpart (SImode, operands[1]);")
17814
17815 (define_peephole2
17816 [(match_scratch:SI 2 "r")
17817 (set (match_operand:SI 0 "memory_operand" "")
17818 (match_operand:SI 1 "immediate_operand" ""))]
17819 "! optimize_size
17820 && get_attr_length (insn) >= ix86_cost->large_insn
17821 && TARGET_SPLIT_LONG_MOVES"
17822 [(set (match_dup 2) (match_dup 1))
17823 (set (match_dup 0) (match_dup 2))]
17824 "")
17825
17826 (define_peephole2
17827 [(match_scratch:HI 2 "r")
17828 (set (match_operand:HI 0 "memory_operand" "")
17829 (match_operand:HI 1 "immediate_operand" ""))]
17830 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17831 && TARGET_SPLIT_LONG_MOVES"
17832 [(set (match_dup 2) (match_dup 1))
17833 (set (match_dup 0) (match_dup 2))]
17834 "")
17835
17836 (define_peephole2
17837 [(match_scratch:QI 2 "q")
17838 (set (match_operand:QI 0 "memory_operand" "")
17839 (match_operand:QI 1 "immediate_operand" ""))]
17840 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17841 && TARGET_SPLIT_LONG_MOVES"
17842 [(set (match_dup 2) (match_dup 1))
17843 (set (match_dup 0) (match_dup 2))]
17844 "")
17845
17846 ;; Don't compare memory with zero, load and use a test instead.
17847 (define_peephole2
17848 [(set (reg 17)
17849 (compare (match_operand:SI 0 "memory_operand" "")
17850 (const_int 0)))
17851 (match_scratch:SI 3 "r")]
17852 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17853 [(set (match_dup 3) (match_dup 0))
17854 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17855 "")
17856
17857 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17858 ;; Don't split NOTs with a displacement operand, because resulting XOR
17859 ;; will not be pairable anyway.
17860 ;;
17861 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17862 ;; represented using a modRM byte. The XOR replacement is long decoded,
17863 ;; so this split helps here as well.
17864 ;;
17865 ;; Note: Can't do this as a regular split because we can't get proper
17866 ;; lifetime information then.
17867
17868 (define_peephole2
17869 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17870 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17871 "!optimize_size
17872 && peep2_regno_dead_p (0, FLAGS_REG)
17873 && ((TARGET_PENTIUM
17874 && (GET_CODE (operands[0]) != MEM
17875 || !memory_displacement_operand (operands[0], SImode)))
17876 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17877 [(parallel [(set (match_dup 0)
17878 (xor:SI (match_dup 1) (const_int -1)))
17879 (clobber (reg:CC 17))])]
17880 "")
17881
17882 (define_peephole2
17883 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17884 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17885 "!optimize_size
17886 && peep2_regno_dead_p (0, FLAGS_REG)
17887 && ((TARGET_PENTIUM
17888 && (GET_CODE (operands[0]) != MEM
17889 || !memory_displacement_operand (operands[0], HImode)))
17890 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17891 [(parallel [(set (match_dup 0)
17892 (xor:HI (match_dup 1) (const_int -1)))
17893 (clobber (reg:CC 17))])]
17894 "")
17895
17896 (define_peephole2
17897 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17898 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17899 "!optimize_size
17900 && peep2_regno_dead_p (0, FLAGS_REG)
17901 && ((TARGET_PENTIUM
17902 && (GET_CODE (operands[0]) != MEM
17903 || !memory_displacement_operand (operands[0], QImode)))
17904 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17905 [(parallel [(set (match_dup 0)
17906 (xor:QI (match_dup 1) (const_int -1)))
17907 (clobber (reg:CC 17))])]
17908 "")
17909
17910 ;; Non pairable "test imm, reg" instructions can be translated to
17911 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17912 ;; byte opcode instead of two, have a short form for byte operands),
17913 ;; so do it for other CPUs as well. Given that the value was dead,
17914 ;; this should not create any new dependencies. Pass on the sub-word
17915 ;; versions if we're concerned about partial register stalls.
17916
17917 (define_peephole2
17918 [(set (reg 17)
17919 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17920 (match_operand:SI 1 "immediate_operand" ""))
17921 (const_int 0)))]
17922 "ix86_match_ccmode (insn, CCNOmode)
17923 && (true_regnum (operands[0]) != 0
17924 || (GET_CODE (operands[1]) == CONST_INT
17925 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17926 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17927 [(parallel
17928 [(set (reg:CCNO 17)
17929 (compare:CCNO (and:SI (match_dup 0)
17930 (match_dup 1))
17931 (const_int 0)))
17932 (set (match_dup 0)
17933 (and:SI (match_dup 0) (match_dup 1)))])]
17934 "")
17935
17936 ;; We don't need to handle HImode case, because it will be promoted to SImode
17937 ;; on ! TARGET_PARTIAL_REG_STALL
17938
17939 (define_peephole2
17940 [(set (reg 17)
17941 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17942 (match_operand:QI 1 "immediate_operand" ""))
17943 (const_int 0)))]
17944 "! TARGET_PARTIAL_REG_STALL
17945 && ix86_match_ccmode (insn, CCNOmode)
17946 && true_regnum (operands[0]) != 0
17947 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17948 [(parallel
17949 [(set (reg:CCNO 17)
17950 (compare:CCNO (and:QI (match_dup 0)
17951 (match_dup 1))
17952 (const_int 0)))
17953 (set (match_dup 0)
17954 (and:QI (match_dup 0) (match_dup 1)))])]
17955 "")
17956
17957 (define_peephole2
17958 [(set (reg 17)
17959 (compare
17960 (and:SI
17961 (zero_extract:SI
17962 (match_operand 0 "ext_register_operand" "")
17963 (const_int 8)
17964 (const_int 8))
17965 (match_operand 1 "const_int_operand" ""))
17966 (const_int 0)))]
17967 "! TARGET_PARTIAL_REG_STALL
17968 && ix86_match_ccmode (insn, CCNOmode)
17969 && true_regnum (operands[0]) != 0
17970 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17971 [(parallel [(set (reg:CCNO 17)
17972 (compare:CCNO
17973 (and:SI
17974 (zero_extract:SI
17975 (match_dup 0)
17976 (const_int 8)
17977 (const_int 8))
17978 (match_dup 1))
17979 (const_int 0)))
17980 (set (zero_extract:SI (match_dup 0)
17981 (const_int 8)
17982 (const_int 8))
17983 (and:SI
17984 (zero_extract:SI
17985 (match_dup 0)
17986 (const_int 8)
17987 (const_int 8))
17988 (match_dup 1)))])]
17989 "")
17990
17991 ;; Don't do logical operations with memory inputs.
17992 (define_peephole2
17993 [(match_scratch:SI 2 "r")
17994 (parallel [(set (match_operand:SI 0 "register_operand" "")
17995 (match_operator:SI 3 "arith_or_logical_operator"
17996 [(match_dup 0)
17997 (match_operand:SI 1 "memory_operand" "")]))
17998 (clobber (reg:CC 17))])]
17999 "! optimize_size && ! TARGET_READ_MODIFY"
18000 [(set (match_dup 2) (match_dup 1))
18001 (parallel [(set (match_dup 0)
18002 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18003 (clobber (reg:CC 17))])]
18004 "")
18005
18006 (define_peephole2
18007 [(match_scratch:SI 2 "r")
18008 (parallel [(set (match_operand:SI 0 "register_operand" "")
18009 (match_operator:SI 3 "arith_or_logical_operator"
18010 [(match_operand:SI 1 "memory_operand" "")
18011 (match_dup 0)]))
18012 (clobber (reg:CC 17))])]
18013 "! optimize_size && ! TARGET_READ_MODIFY"
18014 [(set (match_dup 2) (match_dup 1))
18015 (parallel [(set (match_dup 0)
18016 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18017 (clobber (reg:CC 17))])]
18018 "")
18019
18020 ; Don't do logical operations with memory outputs
18021 ;
18022 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18023 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18024 ; the same decoder scheduling characteristics as the original.
18025
18026 (define_peephole2
18027 [(match_scratch:SI 2 "r")
18028 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18029 (match_operator:SI 3 "arith_or_logical_operator"
18030 [(match_dup 0)
18031 (match_operand:SI 1 "nonmemory_operand" "")]))
18032 (clobber (reg:CC 17))])]
18033 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18034 [(set (match_dup 2) (match_dup 0))
18035 (parallel [(set (match_dup 2)
18036 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18037 (clobber (reg:CC 17))])
18038 (set (match_dup 0) (match_dup 2))]
18039 "")
18040
18041 (define_peephole2
18042 [(match_scratch:SI 2 "r")
18043 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18044 (match_operator:SI 3 "arith_or_logical_operator"
18045 [(match_operand:SI 1 "nonmemory_operand" "")
18046 (match_dup 0)]))
18047 (clobber (reg:CC 17))])]
18048 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18049 [(set (match_dup 2) (match_dup 0))
18050 (parallel [(set (match_dup 2)
18051 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18052 (clobber (reg:CC 17))])
18053 (set (match_dup 0) (match_dup 2))]
18054 "")
18055
18056 ;; Attempt to always use XOR for zeroing registers.
18057 (define_peephole2
18058 [(set (match_operand 0 "register_operand" "")
18059 (const_int 0))]
18060 "(GET_MODE (operands[0]) == QImode
18061 || GET_MODE (operands[0]) == HImode
18062 || GET_MODE (operands[0]) == SImode
18063 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18064 && (! TARGET_USE_MOV0 || optimize_size)
18065 && peep2_regno_dead_p (0, FLAGS_REG)"
18066 [(parallel [(set (match_dup 0) (const_int 0))
18067 (clobber (reg:CC 17))])]
18068 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18069 operands[0]);")
18070
18071 (define_peephole2
18072 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18073 (const_int 0))]
18074 "(GET_MODE (operands[0]) == QImode
18075 || GET_MODE (operands[0]) == HImode)
18076 && (! TARGET_USE_MOV0 || optimize_size)
18077 && peep2_regno_dead_p (0, FLAGS_REG)"
18078 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18079 (clobber (reg:CC 17))])])
18080
18081 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18082 (define_peephole2
18083 [(set (match_operand 0 "register_operand" "")
18084 (const_int -1))]
18085 "(GET_MODE (operands[0]) == HImode
18086 || GET_MODE (operands[0]) == SImode
18087 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18088 && (optimize_size || TARGET_PENTIUM)
18089 && peep2_regno_dead_p (0, FLAGS_REG)"
18090 [(parallel [(set (match_dup 0) (const_int -1))
18091 (clobber (reg:CC 17))])]
18092 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18093 operands[0]);")
18094
18095 ;; Attempt to convert simple leas to adds. These can be created by
18096 ;; move expanders.
18097 (define_peephole2
18098 [(set (match_operand:SI 0 "register_operand" "")
18099 (plus:SI (match_dup 0)
18100 (match_operand:SI 1 "nonmemory_operand" "")))]
18101 "peep2_regno_dead_p (0, FLAGS_REG)"
18102 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18103 (clobber (reg:CC 17))])]
18104 "")
18105
18106 (define_peephole2
18107 [(set (match_operand:SI 0 "register_operand" "")
18108 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18109 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18110 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18111 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18112 (clobber (reg:CC 17))])]
18113 "operands[2] = gen_lowpart (SImode, operands[2]);")
18114
18115 (define_peephole2
18116 [(set (match_operand:DI 0 "register_operand" "")
18117 (plus:DI (match_dup 0)
18118 (match_operand:DI 1 "x86_64_general_operand" "")))]
18119 "peep2_regno_dead_p (0, FLAGS_REG)"
18120 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18121 (clobber (reg:CC 17))])]
18122 "")
18123
18124 (define_peephole2
18125 [(set (match_operand:SI 0 "register_operand" "")
18126 (mult:SI (match_dup 0)
18127 (match_operand:SI 1 "const_int_operand" "")))]
18128 "exact_log2 (INTVAL (operands[1])) >= 0
18129 && peep2_regno_dead_p (0, FLAGS_REG)"
18130 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18131 (clobber (reg:CC 17))])]
18132 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18133
18134 (define_peephole2
18135 [(set (match_operand:DI 0 "register_operand" "")
18136 (mult:DI (match_dup 0)
18137 (match_operand:DI 1 "const_int_operand" "")))]
18138 "exact_log2 (INTVAL (operands[1])) >= 0
18139 && peep2_regno_dead_p (0, FLAGS_REG)"
18140 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18141 (clobber (reg:CC 17))])]
18142 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18143
18144 (define_peephole2
18145 [(set (match_operand:SI 0 "register_operand" "")
18146 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18147 (match_operand:DI 2 "const_int_operand" "")) 0))]
18148 "exact_log2 (INTVAL (operands[2])) >= 0
18149 && REGNO (operands[0]) == REGNO (operands[1])
18150 && peep2_regno_dead_p (0, FLAGS_REG)"
18151 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18152 (clobber (reg:CC 17))])]
18153 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18154
18155 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18156 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18157 ;; many CPUs it is also faster, since special hardware to avoid esp
18158 ;; dependencies is present.
18159
18160 ;; While some of these conversions may be done using splitters, we use peepholes
18161 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18162
18163 ;; Convert prologue esp subtractions to push.
18164 ;; We need register to push. In order to keep verify_flow_info happy we have
18165 ;; two choices
18166 ;; - use scratch and clobber it in order to avoid dependencies
18167 ;; - use already live register
18168 ;; We can't use the second way right now, since there is no reliable way how to
18169 ;; verify that given register is live. First choice will also most likely in
18170 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18171 ;; call clobbered registers are dead. We may want to use base pointer as an
18172 ;; alternative when no register is available later.
18173
18174 (define_peephole2
18175 [(match_scratch:SI 0 "r")
18176 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18177 (clobber (reg:CC 17))
18178 (clobber (mem:BLK (scratch)))])]
18179 "optimize_size || !TARGET_SUB_ESP_4"
18180 [(clobber (match_dup 0))
18181 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18182 (clobber (mem:BLK (scratch)))])])
18183
18184 (define_peephole2
18185 [(match_scratch:SI 0 "r")
18186 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18187 (clobber (reg:CC 17))
18188 (clobber (mem:BLK (scratch)))])]
18189 "optimize_size || !TARGET_SUB_ESP_8"
18190 [(clobber (match_dup 0))
18191 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18192 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18193 (clobber (mem:BLK (scratch)))])])
18194
18195 ;; Convert esp subtractions to push.
18196 (define_peephole2
18197 [(match_scratch:SI 0 "r")
18198 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18199 (clobber (reg:CC 17))])]
18200 "optimize_size || !TARGET_SUB_ESP_4"
18201 [(clobber (match_dup 0))
18202 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18203
18204 (define_peephole2
18205 [(match_scratch:SI 0 "r")
18206 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18207 (clobber (reg:CC 17))])]
18208 "optimize_size || !TARGET_SUB_ESP_8"
18209 [(clobber (match_dup 0))
18210 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18211 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18212
18213 ;; Convert epilogue deallocator to pop.
18214 (define_peephole2
18215 [(match_scratch:SI 0 "r")
18216 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18217 (clobber (reg:CC 17))
18218 (clobber (mem:BLK (scratch)))])]
18219 "optimize_size || !TARGET_ADD_ESP_4"
18220 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18221 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18222 (clobber (mem:BLK (scratch)))])]
18223 "")
18224
18225 ;; Two pops case is tricky, since pop causes dependency on destination register.
18226 ;; We use two registers if available.
18227 (define_peephole2
18228 [(match_scratch:SI 0 "r")
18229 (match_scratch:SI 1 "r")
18230 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18231 (clobber (reg:CC 17))
18232 (clobber (mem:BLK (scratch)))])]
18233 "optimize_size || !TARGET_ADD_ESP_8"
18234 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18235 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18236 (clobber (mem:BLK (scratch)))])
18237 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18238 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18239 "")
18240
18241 (define_peephole2
18242 [(match_scratch:SI 0 "r")
18243 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18244 (clobber (reg:CC 17))
18245 (clobber (mem:BLK (scratch)))])]
18246 "optimize_size"
18247 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18248 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18249 (clobber (mem:BLK (scratch)))])
18250 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18251 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18252 "")
18253
18254 ;; Convert esp additions to pop.
18255 (define_peephole2
18256 [(match_scratch:SI 0 "r")
18257 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18258 (clobber (reg:CC 17))])]
18259 ""
18260 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18261 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18262 "")
18263
18264 ;; Two pops case is tricky, since pop causes dependency on destination register.
18265 ;; We use two registers if available.
18266 (define_peephole2
18267 [(match_scratch:SI 0 "r")
18268 (match_scratch:SI 1 "r")
18269 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18270 (clobber (reg:CC 17))])]
18271 ""
18272 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18273 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18274 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18275 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18276 "")
18277
18278 (define_peephole2
18279 [(match_scratch:SI 0 "r")
18280 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18281 (clobber (reg:CC 17))])]
18282 "optimize_size"
18283 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18284 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18285 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18286 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18287 "")
18288 \f
18289 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18290 ;; required and register dies.
18291 (define_peephole2
18292 [(set (reg 17)
18293 (compare (match_operand:SI 0 "register_operand" "")
18294 (match_operand:SI 1 "incdec_operand" "")))]
18295 "ix86_match_ccmode (insn, CCGCmode)
18296 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18297 [(parallel [(set (reg:CCGC 17)
18298 (compare:CCGC (match_dup 0)
18299 (match_dup 1)))
18300 (clobber (match_dup 0))])]
18301 "")
18302
18303 (define_peephole2
18304 [(set (reg 17)
18305 (compare (match_operand:HI 0 "register_operand" "")
18306 (match_operand:HI 1 "incdec_operand" "")))]
18307 "ix86_match_ccmode (insn, CCGCmode)
18308 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18309 [(parallel [(set (reg:CCGC 17)
18310 (compare:CCGC (match_dup 0)
18311 (match_dup 1)))
18312 (clobber (match_dup 0))])]
18313 "")
18314
18315 (define_peephole2
18316 [(set (reg 17)
18317 (compare (match_operand:QI 0 "register_operand" "")
18318 (match_operand:QI 1 "incdec_operand" "")))]
18319 "ix86_match_ccmode (insn, CCGCmode)
18320 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18321 [(parallel [(set (reg:CCGC 17)
18322 (compare:CCGC (match_dup 0)
18323 (match_dup 1)))
18324 (clobber (match_dup 0))])]
18325 "")
18326
18327 ;; Convert compares with 128 to shorter add -128
18328 (define_peephole2
18329 [(set (reg 17)
18330 (compare (match_operand:SI 0 "register_operand" "")
18331 (const_int 128)))]
18332 "ix86_match_ccmode (insn, CCGCmode)
18333 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18334 [(parallel [(set (reg:CCGC 17)
18335 (compare:CCGC (match_dup 0)
18336 (const_int 128)))
18337 (clobber (match_dup 0))])]
18338 "")
18339
18340 (define_peephole2
18341 [(set (reg 17)
18342 (compare (match_operand:HI 0 "register_operand" "")
18343 (const_int 128)))]
18344 "ix86_match_ccmode (insn, CCGCmode)
18345 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18346 [(parallel [(set (reg:CCGC 17)
18347 (compare:CCGC (match_dup 0)
18348 (const_int 128)))
18349 (clobber (match_dup 0))])]
18350 "")
18351 \f
18352 (define_peephole2
18353 [(match_scratch:DI 0 "r")
18354 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18355 (clobber (reg:CC 17))
18356 (clobber (mem:BLK (scratch)))])]
18357 "optimize_size || !TARGET_SUB_ESP_4"
18358 [(clobber (match_dup 0))
18359 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18360 (clobber (mem:BLK (scratch)))])])
18361
18362 (define_peephole2
18363 [(match_scratch:DI 0 "r")
18364 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18365 (clobber (reg:CC 17))
18366 (clobber (mem:BLK (scratch)))])]
18367 "optimize_size || !TARGET_SUB_ESP_8"
18368 [(clobber (match_dup 0))
18369 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18370 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18371 (clobber (mem:BLK (scratch)))])])
18372
18373 ;; Convert esp subtractions to push.
18374 (define_peephole2
18375 [(match_scratch:DI 0 "r")
18376 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18377 (clobber (reg:CC 17))])]
18378 "optimize_size || !TARGET_SUB_ESP_4"
18379 [(clobber (match_dup 0))
18380 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18381
18382 (define_peephole2
18383 [(match_scratch:DI 0 "r")
18384 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18385 (clobber (reg:CC 17))])]
18386 "optimize_size || !TARGET_SUB_ESP_8"
18387 [(clobber (match_dup 0))
18388 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18389 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18390
18391 ;; Convert epilogue deallocator to pop.
18392 (define_peephole2
18393 [(match_scratch:DI 0 "r")
18394 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18395 (clobber (reg:CC 17))
18396 (clobber (mem:BLK (scratch)))])]
18397 "optimize_size || !TARGET_ADD_ESP_4"
18398 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18399 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18400 (clobber (mem:BLK (scratch)))])]
18401 "")
18402
18403 ;; Two pops case is tricky, since pop causes dependency on destination register.
18404 ;; We use two registers if available.
18405 (define_peephole2
18406 [(match_scratch:DI 0 "r")
18407 (match_scratch:DI 1 "r")
18408 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18409 (clobber (reg:CC 17))
18410 (clobber (mem:BLK (scratch)))])]
18411 "optimize_size || !TARGET_ADD_ESP_8"
18412 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18413 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18414 (clobber (mem:BLK (scratch)))])
18415 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18416 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18417 "")
18418
18419 (define_peephole2
18420 [(match_scratch:DI 0 "r")
18421 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18422 (clobber (reg:CC 17))
18423 (clobber (mem:BLK (scratch)))])]
18424 "optimize_size"
18425 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18426 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18427 (clobber (mem:BLK (scratch)))])
18428 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18429 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18430 "")
18431
18432 ;; Convert esp additions to pop.
18433 (define_peephole2
18434 [(match_scratch:DI 0 "r")
18435 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18436 (clobber (reg:CC 17))])]
18437 ""
18438 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18439 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18440 "")
18441
18442 ;; Two pops case is tricky, since pop causes dependency on destination register.
18443 ;; We use two registers if available.
18444 (define_peephole2
18445 [(match_scratch:DI 0 "r")
18446 (match_scratch:DI 1 "r")
18447 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18448 (clobber (reg:CC 17))])]
18449 ""
18450 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18451 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18452 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18453 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18454 "")
18455
18456 (define_peephole2
18457 [(match_scratch:DI 0 "r")
18458 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18459 (clobber (reg:CC 17))])]
18460 "optimize_size"
18461 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18462 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18463 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18464 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18465 "")
18466 \f
18467 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18468 ;; imul $32bit_imm, reg, reg is direct decoded.
18469 (define_peephole2
18470 [(match_scratch:DI 3 "r")
18471 (parallel [(set (match_operand:DI 0 "register_operand" "")
18472 (mult:DI (match_operand:DI 1 "memory_operand" "")
18473 (match_operand:DI 2 "immediate_operand" "")))
18474 (clobber (reg:CC 17))])]
18475 "TARGET_K8 && !optimize_size
18476 && (GET_CODE (operands[2]) != CONST_INT
18477 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18478 [(set (match_dup 3) (match_dup 1))
18479 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18480 (clobber (reg:CC 17))])]
18481 "")
18482
18483 (define_peephole2
18484 [(match_scratch:SI 3 "r")
18485 (parallel [(set (match_operand:SI 0 "register_operand" "")
18486 (mult:SI (match_operand:SI 1 "memory_operand" "")
18487 (match_operand:SI 2 "immediate_operand" "")))
18488 (clobber (reg:CC 17))])]
18489 "TARGET_K8 && !optimize_size
18490 && (GET_CODE (operands[2]) != CONST_INT
18491 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18492 [(set (match_dup 3) (match_dup 1))
18493 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18494 (clobber (reg:CC 17))])]
18495 "")
18496
18497 (define_peephole2
18498 [(match_scratch:SI 3 "r")
18499 (parallel [(set (match_operand:DI 0 "register_operand" "")
18500 (zero_extend:DI
18501 (mult:SI (match_operand:SI 1 "memory_operand" "")
18502 (match_operand:SI 2 "immediate_operand" ""))))
18503 (clobber (reg:CC 17))])]
18504 "TARGET_K8 && !optimize_size
18505 && (GET_CODE (operands[2]) != CONST_INT
18506 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18507 [(set (match_dup 3) (match_dup 1))
18508 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18509 (clobber (reg:CC 17))])]
18510 "")
18511
18512 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18513 ;; Convert it into imul reg, reg
18514 ;; It would be better to force assembler to encode instruction using long
18515 ;; immediate, but there is apparently no way to do so.
18516 (define_peephole2
18517 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18518 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18519 (match_operand:DI 2 "const_int_operand" "")))
18520 (clobber (reg:CC 17))])
18521 (match_scratch:DI 3 "r")]
18522 "TARGET_K8 && !optimize_size
18523 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18524 [(set (match_dup 3) (match_dup 2))
18525 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18526 (clobber (reg:CC 17))])]
18527 {
18528 if (!rtx_equal_p (operands[0], operands[1]))
18529 emit_move_insn (operands[0], operands[1]);
18530 })
18531
18532 (define_peephole2
18533 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18534 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18535 (match_operand:SI 2 "const_int_operand" "")))
18536 (clobber (reg:CC 17))])
18537 (match_scratch:SI 3 "r")]
18538 "TARGET_K8 && !optimize_size
18539 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18540 [(set (match_dup 3) (match_dup 2))
18541 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18542 (clobber (reg:CC 17))])]
18543 {
18544 if (!rtx_equal_p (operands[0], operands[1]))
18545 emit_move_insn (operands[0], operands[1]);
18546 })
18547
18548 (define_peephole2
18549 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18550 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18551 (match_operand:HI 2 "immediate_operand" "")))
18552 (clobber (reg:CC 17))])
18553 (match_scratch:HI 3 "r")]
18554 "TARGET_K8 && !optimize_size"
18555 [(set (match_dup 3) (match_dup 2))
18556 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18557 (clobber (reg:CC 17))])]
18558 {
18559 if (!rtx_equal_p (operands[0], operands[1]))
18560 emit_move_insn (operands[0], operands[1]);
18561 })
18562 \f
18563 ;; Call-value patterns last so that the wildcard operand does not
18564 ;; disrupt insn-recog's switch tables.
18565
18566 (define_insn "*call_value_pop_0"
18567 [(set (match_operand 0 "" "")
18568 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18569 (match_operand:SI 2 "" "")))
18570 (set (reg:SI 7) (plus:SI (reg:SI 7)
18571 (match_operand:SI 3 "immediate_operand" "")))]
18572 "!TARGET_64BIT"
18573 {
18574 if (SIBLING_CALL_P (insn))
18575 return "jmp\t%P1";
18576 else
18577 return "call\t%P1";
18578 }
18579 [(set_attr "type" "callv")])
18580
18581 (define_insn "*call_value_pop_1"
18582 [(set (match_operand 0 "" "")
18583 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18584 (match_operand:SI 2 "" "")))
18585 (set (reg:SI 7) (plus:SI (reg:SI 7)
18586 (match_operand:SI 3 "immediate_operand" "i")))]
18587 "!TARGET_64BIT"
18588 {
18589 if (constant_call_address_operand (operands[1], QImode))
18590 {
18591 if (SIBLING_CALL_P (insn))
18592 return "jmp\t%P1";
18593 else
18594 return "call\t%P1";
18595 }
18596 if (SIBLING_CALL_P (insn))
18597 return "jmp\t%A1";
18598 else
18599 return "call\t%A1";
18600 }
18601 [(set_attr "type" "callv")])
18602
18603 (define_insn "*call_value_0"
18604 [(set (match_operand 0 "" "")
18605 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18606 (match_operand:SI 2 "" "")))]
18607 "!TARGET_64BIT"
18608 {
18609 if (SIBLING_CALL_P (insn))
18610 return "jmp\t%P1";
18611 else
18612 return "call\t%P1";
18613 }
18614 [(set_attr "type" "callv")])
18615
18616 (define_insn "*call_value_0_rex64"
18617 [(set (match_operand 0 "" "")
18618 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18619 (match_operand:DI 2 "const_int_operand" "")))]
18620 "TARGET_64BIT"
18621 {
18622 if (SIBLING_CALL_P (insn))
18623 return "jmp\t%P1";
18624 else
18625 return "call\t%P1";
18626 }
18627 [(set_attr "type" "callv")])
18628
18629 (define_insn "*call_value_1"
18630 [(set (match_operand 0 "" "")
18631 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18632 (match_operand:SI 2 "" "")))]
18633 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18634 {
18635 if (constant_call_address_operand (operands[1], QImode))
18636 return "call\t%P1";
18637 return "call\t%*%1";
18638 }
18639 [(set_attr "type" "callv")])
18640
18641 (define_insn "*sibcall_value_1"
18642 [(set (match_operand 0 "" "")
18643 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18644 (match_operand:SI 2 "" "")))]
18645 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18646 {
18647 if (constant_call_address_operand (operands[1], QImode))
18648 return "jmp\t%P1";
18649 return "jmp\t%*%1";
18650 }
18651 [(set_attr "type" "callv")])
18652
18653 (define_insn "*call_value_1_rex64"
18654 [(set (match_operand 0 "" "")
18655 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18656 (match_operand:DI 2 "" "")))]
18657 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18658 {
18659 if (constant_call_address_operand (operands[1], QImode))
18660 return "call\t%P1";
18661 return "call\t%A1";
18662 }
18663 [(set_attr "type" "callv")])
18664
18665 (define_insn "*sibcall_value_1_rex64"
18666 [(set (match_operand 0 "" "")
18667 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18668 (match_operand:DI 2 "" "")))]
18669 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18670 "jmp\t%P1"
18671 [(set_attr "type" "callv")])
18672
18673 (define_insn "*sibcall_value_1_rex64_v"
18674 [(set (match_operand 0 "" "")
18675 (call (mem:QI (reg:DI 40))
18676 (match_operand:DI 1 "" "")))]
18677 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18678 "jmp\t*%%r11"
18679 [(set_attr "type" "callv")])
18680 \f
18681 (define_insn "trap"
18682 [(trap_if (const_int 1) (const_int 5))]
18683 ""
18684 "int\t$5")
18685
18686 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18687 ;;; for the sake of bounds checking. By emitting bounds checks as
18688 ;;; conditional traps rather than as conditional jumps around
18689 ;;; unconditional traps we avoid introducing spurious basic-block
18690 ;;; boundaries and facilitate elimination of redundant checks. In
18691 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18692 ;;; interrupt 5.
18693 ;;;
18694 ;;; FIXME: Static branch prediction rules for ix86 are such that
18695 ;;; forward conditional branches predict as untaken. As implemented
18696 ;;; below, pseudo conditional traps violate that rule. We should use
18697 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18698 ;;; section loaded at the end of the text segment and branch forward
18699 ;;; there on bounds-failure, and then jump back immediately (in case
18700 ;;; the system chooses to ignore bounds violations, or to report
18701 ;;; violations and continue execution).
18702
18703 (define_expand "conditional_trap"
18704 [(trap_if (match_operator 0 "comparison_operator"
18705 [(match_dup 2) (const_int 0)])
18706 (match_operand 1 "const_int_operand" ""))]
18707 ""
18708 {
18709 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18710 ix86_expand_compare (GET_CODE (operands[0]),
18711 NULL, NULL),
18712 operands[1]));
18713 DONE;
18714 })
18715
18716 (define_insn "*conditional_trap_1"
18717 [(trap_if (match_operator 0 "comparison_operator"
18718 [(reg 17) (const_int 0)])
18719 (match_operand 1 "const_int_operand" ""))]
18720 ""
18721 {
18722 operands[2] = gen_label_rtx ();
18723 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18724 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18725 CODE_LABEL_NUMBER (operands[2]));
18726 RET;
18727 })
18728
18729 ;; Pentium III SIMD instructions.
18730
18731 ;; Moves for SSE/MMX regs.
18732
18733 (define_insn "movv4sf_internal"
18734 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18735 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18736 "TARGET_SSE"
18737 "@
18738 xorps\t%0, %0
18739 movaps\t{%1, %0|%0, %1}
18740 movaps\t{%1, %0|%0, %1}"
18741 [(set_attr "type" "ssemov")
18742 (set_attr "mode" "V4SF")])
18743
18744 (define_split
18745 [(set (match_operand:V4SF 0 "register_operand" "")
18746 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18747 "TARGET_SSE"
18748 [(set (match_dup 0)
18749 (vec_merge:V4SF
18750 (vec_duplicate:V4SF (match_dup 1))
18751 (match_dup 2)
18752 (const_int 1)))]
18753 {
18754 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18755 operands[2] = CONST0_RTX (V4SFmode);
18756 })
18757
18758 (define_insn "movv4si_internal"
18759 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18760 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18761 "TARGET_SSE"
18762 {
18763 switch (which_alternative)
18764 {
18765 case 0:
18766 if (get_attr_mode (insn) == MODE_V4SF)
18767 return "xorps\t%0, %0";
18768 else
18769 return "pxor\t%0, %0";
18770 case 1:
18771 case 2:
18772 if (get_attr_mode (insn) == MODE_V4SF)
18773 return "movaps\t{%1, %0|%0, %1}";
18774 else
18775 return "movdqa\t{%1, %0|%0, %1}";
18776 default:
18777 abort ();
18778 }
18779 }
18780 [(set_attr "type" "ssemov")
18781 (set (attr "mode")
18782 (cond [(eq_attr "alternative" "0,1")
18783 (if_then_else
18784 (ne (symbol_ref "optimize_size")
18785 (const_int 0))
18786 (const_string "V4SF")
18787 (const_string "TI"))
18788 (eq_attr "alternative" "2")
18789 (if_then_else
18790 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18791 (const_int 0))
18792 (ne (symbol_ref "optimize_size")
18793 (const_int 0)))
18794 (const_string "V4SF")
18795 (const_string "TI"))]
18796 (const_string "TI")))])
18797
18798 (define_insn "movv2di_internal"
18799 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18800 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18801 "TARGET_SSE2"
18802 {
18803 switch (which_alternative)
18804 {
18805 case 0:
18806 if (get_attr_mode (insn) == MODE_V4SF)
18807 return "xorps\t%0, %0";
18808 else
18809 return "pxor\t%0, %0";
18810 case 1:
18811 case 2:
18812 if (get_attr_mode (insn) == MODE_V4SF)
18813 return "movaps\t{%1, %0|%0, %1}";
18814 else
18815 return "movdqa\t{%1, %0|%0, %1}";
18816 default:
18817 abort ();
18818 }
18819 }
18820 [(set_attr "type" "ssemov")
18821 (set (attr "mode")
18822 (cond [(eq_attr "alternative" "0,1")
18823 (if_then_else
18824 (ne (symbol_ref "optimize_size")
18825 (const_int 0))
18826 (const_string "V4SF")
18827 (const_string "TI"))
18828 (eq_attr "alternative" "2")
18829 (if_then_else
18830 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18831 (const_int 0))
18832 (ne (symbol_ref "optimize_size")
18833 (const_int 0)))
18834 (const_string "V4SF")
18835 (const_string "TI"))]
18836 (const_string "TI")))])
18837
18838 (define_split
18839 [(set (match_operand:V2DF 0 "register_operand" "")
18840 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18841 "TARGET_SSE2"
18842 [(set (match_dup 0)
18843 (vec_merge:V2DF
18844 (vec_duplicate:V2DF (match_dup 1))
18845 (match_dup 2)
18846 (const_int 1)))]
18847 {
18848 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18849 operands[2] = CONST0_RTX (V2DFmode);
18850 })
18851
18852 (define_insn "movv8qi_internal"
18853 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18854 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18855 "TARGET_MMX
18856 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18857 "@
18858 pxor\t%0, %0
18859 movq\t{%1, %0|%0, %1}
18860 movq\t{%1, %0|%0, %1}"
18861 [(set_attr "type" "mmxmov")
18862 (set_attr "mode" "DI")])
18863
18864 (define_insn "movv4hi_internal"
18865 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18866 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18867 "TARGET_MMX
18868 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18869 "@
18870 pxor\t%0, %0
18871 movq\t{%1, %0|%0, %1}
18872 movq\t{%1, %0|%0, %1}"
18873 [(set_attr "type" "mmxmov")
18874 (set_attr "mode" "DI")])
18875
18876 (define_insn "movv2si_internal"
18877 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18878 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18879 "TARGET_MMX
18880 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18881 "@
18882 pxor\t%0, %0
18883 movq\t{%1, %0|%0, %1}
18884 movq\t{%1, %0|%0, %1}"
18885 [(set_attr "type" "mmxcvt")
18886 (set_attr "mode" "DI")])
18887
18888 (define_insn "movv2sf_internal"
18889 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18890 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18891 "TARGET_3DNOW
18892 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18893 "@
18894 pxor\t%0, %0
18895 movq\t{%1, %0|%0, %1}
18896 movq\t{%1, %0|%0, %1}"
18897 [(set_attr "type" "mmxcvt")
18898 (set_attr "mode" "DI")])
18899
18900 (define_expand "movti"
18901 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18902 (match_operand:TI 1 "nonimmediate_operand" ""))]
18903 "TARGET_SSE || TARGET_64BIT"
18904 {
18905 if (TARGET_64BIT)
18906 ix86_expand_move (TImode, operands);
18907 else
18908 ix86_expand_vector_move (TImode, operands);
18909 DONE;
18910 })
18911
18912 (define_insn "movv2df_internal"
18913 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18914 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18915 "TARGET_SSE2
18916 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18917 {
18918 switch (which_alternative)
18919 {
18920 case 0:
18921 if (get_attr_mode (insn) == MODE_V4SF)
18922 return "xorps\t%0, %0";
18923 else
18924 return "xorpd\t%0, %0";
18925 case 1:
18926 case 2:
18927 if (get_attr_mode (insn) == MODE_V4SF)
18928 return "movaps\t{%1, %0|%0, %1}";
18929 else
18930 return "movapd\t{%1, %0|%0, %1}";
18931 default:
18932 abort ();
18933 }
18934 }
18935 [(set_attr "type" "ssemov")
18936 (set (attr "mode")
18937 (cond [(eq_attr "alternative" "0,1")
18938 (if_then_else
18939 (ne (symbol_ref "optimize_size")
18940 (const_int 0))
18941 (const_string "V4SF")
18942 (const_string "V2DF"))
18943 (eq_attr "alternative" "2")
18944 (if_then_else
18945 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18946 (const_int 0))
18947 (ne (symbol_ref "optimize_size")
18948 (const_int 0)))
18949 (const_string "V4SF")
18950 (const_string "V2DF"))]
18951 (const_string "V2DF")))])
18952
18953 (define_insn "movv8hi_internal"
18954 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18955 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18956 "TARGET_SSE2
18957 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18958 {
18959 switch (which_alternative)
18960 {
18961 case 0:
18962 if (get_attr_mode (insn) == MODE_V4SF)
18963 return "xorps\t%0, %0";
18964 else
18965 return "pxor\t%0, %0";
18966 case 1:
18967 case 2:
18968 if (get_attr_mode (insn) == MODE_V4SF)
18969 return "movaps\t{%1, %0|%0, %1}";
18970 else
18971 return "movdqa\t{%1, %0|%0, %1}";
18972 default:
18973 abort ();
18974 }
18975 }
18976 [(set_attr "type" "ssemov")
18977 (set (attr "mode")
18978 (cond [(eq_attr "alternative" "0,1")
18979 (if_then_else
18980 (ne (symbol_ref "optimize_size")
18981 (const_int 0))
18982 (const_string "V4SF")
18983 (const_string "TI"))
18984 (eq_attr "alternative" "2")
18985 (if_then_else
18986 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18987 (const_int 0))
18988 (ne (symbol_ref "optimize_size")
18989 (const_int 0)))
18990 (const_string "V4SF")
18991 (const_string "TI"))]
18992 (const_string "TI")))])
18993
18994 (define_insn "movv16qi_internal"
18995 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18996 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18997 "TARGET_SSE2
18998 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18999 {
19000 switch (which_alternative)
19001 {
19002 case 0:
19003 if (get_attr_mode (insn) == MODE_V4SF)
19004 return "xorps\t%0, %0";
19005 else
19006 return "pxor\t%0, %0";
19007 case 1:
19008 case 2:
19009 if (get_attr_mode (insn) == MODE_V4SF)
19010 return "movaps\t{%1, %0|%0, %1}";
19011 else
19012 return "movdqa\t{%1, %0|%0, %1}";
19013 default:
19014 abort ();
19015 }
19016 }
19017 [(set_attr "type" "ssemov")
19018 (set (attr "mode")
19019 (cond [(eq_attr "alternative" "0,1")
19020 (if_then_else
19021 (ne (symbol_ref "optimize_size")
19022 (const_int 0))
19023 (const_string "V4SF")
19024 (const_string "TI"))
19025 (eq_attr "alternative" "2")
19026 (if_then_else
19027 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19028 (const_int 0))
19029 (ne (symbol_ref "optimize_size")
19030 (const_int 0)))
19031 (const_string "V4SF")
19032 (const_string "TI"))]
19033 (const_string "TI")))])
19034
19035 (define_expand "movv2df"
19036 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19037 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19038 "TARGET_SSE2"
19039 {
19040 ix86_expand_vector_move (V2DFmode, operands);
19041 DONE;
19042 })
19043
19044 (define_expand "movv8hi"
19045 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19046 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19047 "TARGET_SSE2"
19048 {
19049 ix86_expand_vector_move (V8HImode, operands);
19050 DONE;
19051 })
19052
19053 (define_expand "movv16qi"
19054 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19055 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19056 "TARGET_SSE2"
19057 {
19058 ix86_expand_vector_move (V16QImode, operands);
19059 DONE;
19060 })
19061
19062 (define_expand "movv4sf"
19063 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19064 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19065 "TARGET_SSE"
19066 {
19067 ix86_expand_vector_move (V4SFmode, operands);
19068 DONE;
19069 })
19070
19071 (define_expand "movv4si"
19072 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19073 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19074 "TARGET_SSE"
19075 {
19076 ix86_expand_vector_move (V4SImode, operands);
19077 DONE;
19078 })
19079
19080 (define_expand "movv2di"
19081 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19082 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19083 "TARGET_SSE"
19084 {
19085 ix86_expand_vector_move (V2DImode, operands);
19086 DONE;
19087 })
19088
19089 (define_expand "movv2si"
19090 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19091 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19092 "TARGET_MMX"
19093 {
19094 ix86_expand_vector_move (V2SImode, operands);
19095 DONE;
19096 })
19097
19098 (define_expand "movv4hi"
19099 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19100 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19101 "TARGET_MMX"
19102 {
19103 ix86_expand_vector_move (V4HImode, operands);
19104 DONE;
19105 })
19106
19107 (define_expand "movv8qi"
19108 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19109 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19110 "TARGET_MMX"
19111 {
19112 ix86_expand_vector_move (V8QImode, operands);
19113 DONE;
19114 })
19115
19116 (define_expand "movv2sf"
19117 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19118 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19119 "TARGET_3DNOW"
19120 {
19121 ix86_expand_vector_move (V2SFmode, operands);
19122 DONE;
19123 })
19124
19125 (define_insn "*pushti"
19126 [(set (match_operand:TI 0 "push_operand" "=<")
19127 (match_operand:TI 1 "register_operand" "x"))]
19128 "TARGET_SSE"
19129 "#")
19130
19131 (define_insn "*pushv2df"
19132 [(set (match_operand:V2DF 0 "push_operand" "=<")
19133 (match_operand:V2DF 1 "register_operand" "x"))]
19134 "TARGET_SSE"
19135 "#")
19136
19137 (define_insn "*pushv2di"
19138 [(set (match_operand:V2DI 0 "push_operand" "=<")
19139 (match_operand:V2DI 1 "register_operand" "x"))]
19140 "TARGET_SSE2"
19141 "#")
19142
19143 (define_insn "*pushv8hi"
19144 [(set (match_operand:V8HI 0 "push_operand" "=<")
19145 (match_operand:V8HI 1 "register_operand" "x"))]
19146 "TARGET_SSE2"
19147 "#")
19148
19149 (define_insn "*pushv16qi"
19150 [(set (match_operand:V16QI 0 "push_operand" "=<")
19151 (match_operand:V16QI 1 "register_operand" "x"))]
19152 "TARGET_SSE2"
19153 "#")
19154
19155 (define_insn "*pushv4sf"
19156 [(set (match_operand:V4SF 0 "push_operand" "=<")
19157 (match_operand:V4SF 1 "register_operand" "x"))]
19158 "TARGET_SSE"
19159 "#")
19160
19161 (define_insn "*pushv4si"
19162 [(set (match_operand:V4SI 0 "push_operand" "=<")
19163 (match_operand:V4SI 1 "register_operand" "x"))]
19164 "TARGET_SSE2"
19165 "#")
19166
19167 (define_insn "*pushv2si"
19168 [(set (match_operand:V2SI 0 "push_operand" "=<")
19169 (match_operand:V2SI 1 "register_operand" "y"))]
19170 "TARGET_MMX"
19171 "#")
19172
19173 (define_insn "*pushv4hi"
19174 [(set (match_operand:V4HI 0 "push_operand" "=<")
19175 (match_operand:V4HI 1 "register_operand" "y"))]
19176 "TARGET_MMX"
19177 "#")
19178
19179 (define_insn "*pushv8qi"
19180 [(set (match_operand:V8QI 0 "push_operand" "=<")
19181 (match_operand:V8QI 1 "register_operand" "y"))]
19182 "TARGET_MMX"
19183 "#")
19184
19185 (define_insn "*pushv2sf"
19186 [(set (match_operand:V2SF 0 "push_operand" "=<")
19187 (match_operand:V2SF 1 "register_operand" "y"))]
19188 "TARGET_3DNOW"
19189 "#")
19190
19191 (define_split
19192 [(set (match_operand 0 "push_operand" "")
19193 (match_operand 1 "register_operand" ""))]
19194 "!TARGET_64BIT && reload_completed
19195 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19196 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19197 (set (match_dup 2) (match_dup 1))]
19198 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19199 stack_pointer_rtx);
19200 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19201
19202 (define_split
19203 [(set (match_operand 0 "push_operand" "")
19204 (match_operand 1 "register_operand" ""))]
19205 "TARGET_64BIT && reload_completed
19206 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19207 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19208 (set (match_dup 2) (match_dup 1))]
19209 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19210 stack_pointer_rtx);
19211 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19212
19213
19214 (define_insn "movti_internal"
19215 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19216 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19217 "TARGET_SSE && !TARGET_64BIT
19218 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19219 {
19220 switch (which_alternative)
19221 {
19222 case 0:
19223 if (get_attr_mode (insn) == MODE_V4SF)
19224 return "xorps\t%0, %0";
19225 else
19226 return "pxor\t%0, %0";
19227 case 1:
19228 case 2:
19229 if (get_attr_mode (insn) == MODE_V4SF)
19230 return "movaps\t{%1, %0|%0, %1}";
19231 else
19232 return "movdqa\t{%1, %0|%0, %1}";
19233 default:
19234 abort ();
19235 }
19236 }
19237 [(set_attr "type" "ssemov,ssemov,ssemov")
19238 (set (attr "mode")
19239 (cond [(eq_attr "alternative" "0,1")
19240 (if_then_else
19241 (ne (symbol_ref "optimize_size")
19242 (const_int 0))
19243 (const_string "V4SF")
19244 (const_string "TI"))
19245 (eq_attr "alternative" "2")
19246 (if_then_else
19247 (ne (symbol_ref "optimize_size")
19248 (const_int 0))
19249 (const_string "V4SF")
19250 (const_string "TI"))]
19251 (const_string "TI")))])
19252
19253 (define_insn "*movti_rex64"
19254 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19255 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19256 "TARGET_64BIT
19257 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19258 {
19259 switch (which_alternative)
19260 {
19261 case 0:
19262 case 1:
19263 return "#";
19264 case 2:
19265 if (get_attr_mode (insn) == MODE_V4SF)
19266 return "xorps\t%0, %0";
19267 else
19268 return "pxor\t%0, %0";
19269 case 3:
19270 case 4:
19271 if (get_attr_mode (insn) == MODE_V4SF)
19272 return "movaps\t{%1, %0|%0, %1}";
19273 else
19274 return "movdqa\t{%1, %0|%0, %1}";
19275 default:
19276 abort ();
19277 }
19278 }
19279 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19280 (set (attr "mode")
19281 (cond [(eq_attr "alternative" "2,3")
19282 (if_then_else
19283 (ne (symbol_ref "optimize_size")
19284 (const_int 0))
19285 (const_string "V4SF")
19286 (const_string "TI"))
19287 (eq_attr "alternative" "4")
19288 (if_then_else
19289 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19290 (const_int 0))
19291 (ne (symbol_ref "optimize_size")
19292 (const_int 0)))
19293 (const_string "V4SF")
19294 (const_string "TI"))]
19295 (const_string "DI")))])
19296
19297 (define_split
19298 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19299 (match_operand:TI 1 "general_operand" ""))]
19300 "reload_completed && !SSE_REG_P (operands[0])
19301 && !SSE_REG_P (operands[1])"
19302 [(const_int 0)]
19303 "ix86_split_long_move (operands); DONE;")
19304
19305 ;; These two patterns are useful for specifying exactly whether to use
19306 ;; movaps or movups
19307 (define_insn "sse_movaps"
19308 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19309 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19310 UNSPEC_MOVA))]
19311 "TARGET_SSE
19312 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19313 "movaps\t{%1, %0|%0, %1}"
19314 [(set_attr "type" "ssemov,ssemov")
19315 (set_attr "mode" "V4SF")])
19316
19317 (define_insn "sse_movups"
19318 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19319 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19320 UNSPEC_MOVU))]
19321 "TARGET_SSE
19322 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19323 "movups\t{%1, %0|%0, %1}"
19324 [(set_attr "type" "ssecvt,ssecvt")
19325 (set_attr "mode" "V4SF")])
19326
19327
19328 ;; SSE Strange Moves.
19329
19330 (define_insn "sse_movmskps"
19331 [(set (match_operand:SI 0 "register_operand" "=r")
19332 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19333 UNSPEC_MOVMSK))]
19334 "TARGET_SSE"
19335 "movmskps\t{%1, %0|%0, %1}"
19336 [(set_attr "type" "ssecvt")
19337 (set_attr "mode" "V4SF")])
19338
19339 (define_insn "mmx_pmovmskb"
19340 [(set (match_operand:SI 0 "register_operand" "=r")
19341 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19342 UNSPEC_MOVMSK))]
19343 "TARGET_SSE || TARGET_3DNOW_A"
19344 "pmovmskb\t{%1, %0|%0, %1}"
19345 [(set_attr "type" "ssecvt")
19346 (set_attr "mode" "V4SF")])
19347
19348
19349 (define_insn "mmx_maskmovq"
19350 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19351 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19352 (match_operand:V8QI 2 "register_operand" "y")]
19353 UNSPEC_MASKMOV))]
19354 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19355 ;; @@@ check ordering of operands in intel/nonintel syntax
19356 "maskmovq\t{%2, %1|%1, %2}"
19357 [(set_attr "type" "mmxcvt")
19358 (set_attr "mode" "DI")])
19359
19360 (define_insn "mmx_maskmovq_rex"
19361 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19362 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19363 (match_operand:V8QI 2 "register_operand" "y")]
19364 UNSPEC_MASKMOV))]
19365 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19366 ;; @@@ check ordering of operands in intel/nonintel syntax
19367 "maskmovq\t{%2, %1|%1, %2}"
19368 [(set_attr "type" "mmxcvt")
19369 (set_attr "mode" "DI")])
19370
19371 (define_insn "sse_movntv4sf"
19372 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19373 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19374 UNSPEC_MOVNT))]
19375 "TARGET_SSE"
19376 "movntps\t{%1, %0|%0, %1}"
19377 [(set_attr "type" "ssemov")
19378 (set_attr "mode" "V4SF")])
19379
19380 (define_insn "sse_movntdi"
19381 [(set (match_operand:DI 0 "memory_operand" "=m")
19382 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19383 UNSPEC_MOVNT))]
19384 "TARGET_SSE || TARGET_3DNOW_A"
19385 "movntq\t{%1, %0|%0, %1}"
19386 [(set_attr "type" "mmxmov")
19387 (set_attr "mode" "DI")])
19388
19389 (define_insn "sse_movhlps"
19390 [(set (match_operand:V4SF 0 "register_operand" "=x")
19391 (vec_merge:V4SF
19392 (match_operand:V4SF 1 "register_operand" "0")
19393 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19394 (parallel [(const_int 2)
19395 (const_int 3)
19396 (const_int 0)
19397 (const_int 1)]))
19398 (const_int 3)))]
19399 "TARGET_SSE"
19400 "movhlps\t{%2, %0|%0, %2}"
19401 [(set_attr "type" "ssecvt")
19402 (set_attr "mode" "V4SF")])
19403
19404 (define_insn "sse_movlhps"
19405 [(set (match_operand:V4SF 0 "register_operand" "=x")
19406 (vec_merge:V4SF
19407 (match_operand:V4SF 1 "register_operand" "0")
19408 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19409 (parallel [(const_int 2)
19410 (const_int 3)
19411 (const_int 0)
19412 (const_int 1)]))
19413 (const_int 12)))]
19414 "TARGET_SSE"
19415 "movlhps\t{%2, %0|%0, %2}"
19416 [(set_attr "type" "ssecvt")
19417 (set_attr "mode" "V4SF")])
19418
19419 (define_insn "sse_movhps"
19420 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19421 (vec_merge:V4SF
19422 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19423 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19424 (const_int 12)))]
19425 "TARGET_SSE
19426 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19427 "movhps\t{%2, %0|%0, %2}"
19428 [(set_attr "type" "ssecvt")
19429 (set_attr "mode" "V4SF")])
19430
19431 (define_insn "sse_movlps"
19432 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19433 (vec_merge:V4SF
19434 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19435 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19436 (const_int 3)))]
19437 "TARGET_SSE
19438 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19439 "movlps\t{%2, %0|%0, %2}"
19440 [(set_attr "type" "ssecvt")
19441 (set_attr "mode" "V4SF")])
19442
19443 (define_expand "sse_loadss"
19444 [(match_operand:V4SF 0 "register_operand" "")
19445 (match_operand:SF 1 "memory_operand" "")]
19446 "TARGET_SSE"
19447 {
19448 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19449 CONST0_RTX (V4SFmode)));
19450 DONE;
19451 })
19452
19453 (define_insn "sse_loadss_1"
19454 [(set (match_operand:V4SF 0 "register_operand" "=x")
19455 (vec_merge:V4SF
19456 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19457 (match_operand:V4SF 2 "const0_operand" "X")
19458 (const_int 1)))]
19459 "TARGET_SSE"
19460 "movss\t{%1, %0|%0, %1}"
19461 [(set_attr "type" "ssemov")
19462 (set_attr "mode" "SF")])
19463
19464 (define_insn "sse_movss"
19465 [(set (match_operand:V4SF 0 "register_operand" "=x")
19466 (vec_merge:V4SF
19467 (match_operand:V4SF 1 "register_operand" "0")
19468 (match_operand:V4SF 2 "register_operand" "x")
19469 (const_int 1)))]
19470 "TARGET_SSE"
19471 "movss\t{%2, %0|%0, %2}"
19472 [(set_attr "type" "ssemov")
19473 (set_attr "mode" "SF")])
19474
19475 (define_insn "sse_storess"
19476 [(set (match_operand:SF 0 "memory_operand" "=m")
19477 (vec_select:SF
19478 (match_operand:V4SF 1 "register_operand" "x")
19479 (parallel [(const_int 0)])))]
19480 "TARGET_SSE"
19481 "movss\t{%1, %0|%0, %1}"
19482 [(set_attr "type" "ssemov")
19483 (set_attr "mode" "SF")])
19484
19485 (define_insn "sse_shufps"
19486 [(set (match_operand:V4SF 0 "register_operand" "=x")
19487 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19488 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19489 (match_operand:SI 3 "immediate_operand" "i")]
19490 UNSPEC_SHUFFLE))]
19491 "TARGET_SSE"
19492 ;; @@@ check operand order for intel/nonintel syntax
19493 "shufps\t{%3, %2, %0|%0, %2, %3}"
19494 [(set_attr "type" "ssecvt")
19495 (set_attr "mode" "V4SF")])
19496
19497
19498 ;; SSE arithmetic
19499
19500 (define_insn "addv4sf3"
19501 [(set (match_operand:V4SF 0 "register_operand" "=x")
19502 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19503 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19504 "TARGET_SSE"
19505 "addps\t{%2, %0|%0, %2}"
19506 [(set_attr "type" "sseadd")
19507 (set_attr "mode" "V4SF")])
19508
19509 (define_insn "vmaddv4sf3"
19510 [(set (match_operand:V4SF 0 "register_operand" "=x")
19511 (vec_merge:V4SF
19512 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19513 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19514 (match_dup 1)
19515 (const_int 1)))]
19516 "TARGET_SSE"
19517 "addss\t{%2, %0|%0, %2}"
19518 [(set_attr "type" "sseadd")
19519 (set_attr "mode" "SF")])
19520
19521 (define_insn "subv4sf3"
19522 [(set (match_operand:V4SF 0 "register_operand" "=x")
19523 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19524 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19525 "TARGET_SSE"
19526 "subps\t{%2, %0|%0, %2}"
19527 [(set_attr "type" "sseadd")
19528 (set_attr "mode" "V4SF")])
19529
19530 (define_insn "vmsubv4sf3"
19531 [(set (match_operand:V4SF 0 "register_operand" "=x")
19532 (vec_merge:V4SF
19533 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19534 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19535 (match_dup 1)
19536 (const_int 1)))]
19537 "TARGET_SSE"
19538 "subss\t{%2, %0|%0, %2}"
19539 [(set_attr "type" "sseadd")
19540 (set_attr "mode" "SF")])
19541
19542 (define_insn "mulv4sf3"
19543 [(set (match_operand:V4SF 0 "register_operand" "=x")
19544 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19545 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19546 "TARGET_SSE"
19547 "mulps\t{%2, %0|%0, %2}"
19548 [(set_attr "type" "ssemul")
19549 (set_attr "mode" "V4SF")])
19550
19551 (define_insn "vmmulv4sf3"
19552 [(set (match_operand:V4SF 0 "register_operand" "=x")
19553 (vec_merge:V4SF
19554 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19555 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19556 (match_dup 1)
19557 (const_int 1)))]
19558 "TARGET_SSE"
19559 "mulss\t{%2, %0|%0, %2}"
19560 [(set_attr "type" "ssemul")
19561 (set_attr "mode" "SF")])
19562
19563 (define_insn "divv4sf3"
19564 [(set (match_operand:V4SF 0 "register_operand" "=x")
19565 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19566 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19567 "TARGET_SSE"
19568 "divps\t{%2, %0|%0, %2}"
19569 [(set_attr "type" "ssediv")
19570 (set_attr "mode" "V4SF")])
19571
19572 (define_insn "vmdivv4sf3"
19573 [(set (match_operand:V4SF 0 "register_operand" "=x")
19574 (vec_merge:V4SF
19575 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19576 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19577 (match_dup 1)
19578 (const_int 1)))]
19579 "TARGET_SSE"
19580 "divss\t{%2, %0|%0, %2}"
19581 [(set_attr "type" "ssediv")
19582 (set_attr "mode" "SF")])
19583
19584
19585 ;; SSE square root/reciprocal
19586
19587 (define_insn "rcpv4sf2"
19588 [(set (match_operand:V4SF 0 "register_operand" "=x")
19589 (unspec:V4SF
19590 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19591 "TARGET_SSE"
19592 "rcpps\t{%1, %0|%0, %1}"
19593 [(set_attr "type" "sse")
19594 (set_attr "mode" "V4SF")])
19595
19596 (define_insn "vmrcpv4sf2"
19597 [(set (match_operand:V4SF 0 "register_operand" "=x")
19598 (vec_merge:V4SF
19599 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19600 UNSPEC_RCP)
19601 (match_operand:V4SF 2 "register_operand" "0")
19602 (const_int 1)))]
19603 "TARGET_SSE"
19604 "rcpss\t{%1, %0|%0, %1}"
19605 [(set_attr "type" "sse")
19606 (set_attr "mode" "SF")])
19607
19608 (define_insn "rsqrtv4sf2"
19609 [(set (match_operand:V4SF 0 "register_operand" "=x")
19610 (unspec:V4SF
19611 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19612 "TARGET_SSE"
19613 "rsqrtps\t{%1, %0|%0, %1}"
19614 [(set_attr "type" "sse")
19615 (set_attr "mode" "V4SF")])
19616
19617 (define_insn "vmrsqrtv4sf2"
19618 [(set (match_operand:V4SF 0 "register_operand" "=x")
19619 (vec_merge:V4SF
19620 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19621 UNSPEC_RSQRT)
19622 (match_operand:V4SF 2 "register_operand" "0")
19623 (const_int 1)))]
19624 "TARGET_SSE"
19625 "rsqrtss\t{%1, %0|%0, %1}"
19626 [(set_attr "type" "sse")
19627 (set_attr "mode" "SF")])
19628
19629 (define_insn "sqrtv4sf2"
19630 [(set (match_operand:V4SF 0 "register_operand" "=x")
19631 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19632 "TARGET_SSE"
19633 "sqrtps\t{%1, %0|%0, %1}"
19634 [(set_attr "type" "sse")
19635 (set_attr "mode" "V4SF")])
19636
19637 (define_insn "vmsqrtv4sf2"
19638 [(set (match_operand:V4SF 0 "register_operand" "=x")
19639 (vec_merge:V4SF
19640 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19641 (match_operand:V4SF 2 "register_operand" "0")
19642 (const_int 1)))]
19643 "TARGET_SSE"
19644 "sqrtss\t{%1, %0|%0, %1}"
19645 [(set_attr "type" "sse")
19646 (set_attr "mode" "SF")])
19647
19648 ;; SSE logical operations.
19649
19650 ;; SSE defines logical operations on floating point values. This brings
19651 ;; interesting challenge to RTL representation where logicals are only valid
19652 ;; on integral types. We deal with this by representing the floating point
19653 ;; logical as logical on arguments casted to TImode as this is what hardware
19654 ;; really does. Unfortunately hardware requires the type information to be
19655 ;; present and thus we must avoid subregs from being simplified and eliminated
19656 ;; in later compilation phases.
19657 ;;
19658 ;; We have following variants from each instruction:
19659 ;; sse_andsf3 - the operation taking V4SF vector operands
19660 ;; and doing TImode cast on them
19661 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19662 ;; TImode, since backend insist on eliminating casts
19663 ;; on memory operands
19664 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19665 ;; We can not accept memory operand here as instruction reads
19666 ;; whole scalar. This is generated only post reload by GCC
19667 ;; scalar float operations that expands to logicals (fabs)
19668 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19669 ;; memory operand. Eventually combine can be able
19670 ;; to synthesize these using splitter.
19671 ;; sse2_anddf3, *sse2_anddf3_memory
19672 ;;
19673 ;;
19674 ;; These are not called andti3 etc. because we really really don't want
19675 ;; the compiler to widen DImode ands to TImode ands and then try to move
19676 ;; into DImode subregs of SSE registers, and them together, and move out
19677 ;; of DImode subregs again!
19678 ;; SSE1 single precision floating point logical operation
19679 (define_expand "sse_andv4sf3"
19680 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19681 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19682 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19683 "TARGET_SSE"
19684 "")
19685
19686 (define_insn "*sse_andv4sf3"
19687 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19688 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19689 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19690 "TARGET_SSE
19691 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19692 "andps\t{%2, %0|%0, %2}"
19693 [(set_attr "type" "sselog")
19694 (set_attr "mode" "V4SF")])
19695
19696 (define_insn "*sse_andsf3"
19697 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19698 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19699 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19700 "TARGET_SSE
19701 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19702 "andps\t{%2, %0|%0, %2}"
19703 [(set_attr "type" "sselog")
19704 (set_attr "mode" "V4SF")])
19705
19706 (define_expand "sse_nandv4sf3"
19707 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19708 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19709 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19710 "TARGET_SSE"
19711 "")
19712
19713 (define_insn "*sse_nandv4sf3"
19714 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19715 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19716 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19717 "TARGET_SSE"
19718 "andnps\t{%2, %0|%0, %2}"
19719 [(set_attr "type" "sselog")
19720 (set_attr "mode" "V4SF")])
19721
19722 (define_insn "*sse_nandsf3"
19723 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19724 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19725 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19726 "TARGET_SSE"
19727 "andnps\t{%2, %0|%0, %2}"
19728 [(set_attr "type" "sselog")
19729 (set_attr "mode" "V4SF")])
19730
19731 (define_expand "sse_iorv4sf3"
19732 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19733 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19734 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19735 "TARGET_SSE"
19736 "")
19737
19738 (define_insn "*sse_iorv4sf3"
19739 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19740 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19741 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19742 "TARGET_SSE
19743 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19744 "orps\t{%2, %0|%0, %2}"
19745 [(set_attr "type" "sselog")
19746 (set_attr "mode" "V4SF")])
19747
19748 (define_insn "*sse_iorsf3"
19749 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19750 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19751 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19752 "TARGET_SSE
19753 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19754 "orps\t{%2, %0|%0, %2}"
19755 [(set_attr "type" "sselog")
19756 (set_attr "mode" "V4SF")])
19757
19758 (define_expand "sse_xorv4sf3"
19759 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19760 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19761 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19762 "TARGET_SSE
19763 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19764 "")
19765
19766 (define_insn "*sse_xorv4sf3"
19767 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19768 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19769 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19770 "TARGET_SSE
19771 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19772 "xorps\t{%2, %0|%0, %2}"
19773 [(set_attr "type" "sselog")
19774 (set_attr "mode" "V4SF")])
19775
19776 (define_insn "*sse_xorsf3"
19777 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19778 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19779 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19780 "TARGET_SSE
19781 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19782 "xorps\t{%2, %0|%0, %2}"
19783 [(set_attr "type" "sselog")
19784 (set_attr "mode" "V4SF")])
19785
19786 ;; SSE2 double precision floating point logical operation
19787
19788 (define_expand "sse2_andv2df3"
19789 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19790 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19791 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19792 "TARGET_SSE2"
19793 "")
19794
19795 (define_insn "*sse2_andv2df3"
19796 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19797 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19798 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19799 "TARGET_SSE2
19800 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19801 "andpd\t{%2, %0|%0, %2}"
19802 [(set_attr "type" "sselog")
19803 (set_attr "mode" "V2DF")])
19804
19805 (define_insn "*sse2_andv2df3"
19806 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19807 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19808 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19809 "TARGET_SSE2
19810 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19811 "andpd\t{%2, %0|%0, %2}"
19812 [(set_attr "type" "sselog")
19813 (set_attr "mode" "V2DF")])
19814
19815 (define_expand "sse2_nandv2df3"
19816 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19817 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19818 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19819 "TARGET_SSE2"
19820 "")
19821
19822 (define_insn "*sse2_nandv2df3"
19823 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19824 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19825 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19826 "TARGET_SSE2"
19827 "andnpd\t{%2, %0|%0, %2}"
19828 [(set_attr "type" "sselog")
19829 (set_attr "mode" "V2DF")])
19830
19831 (define_insn "*sse_nandti3_df"
19832 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19833 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19834 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19835 "TARGET_SSE2"
19836 "andnpd\t{%2, %0|%0, %2}"
19837 [(set_attr "type" "sselog")
19838 (set_attr "mode" "V2DF")])
19839
19840 (define_expand "sse2_iorv2df3"
19841 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19842 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19843 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19844 "TARGET_SSE2"
19845 "")
19846
19847 (define_insn "*sse2_iorv2df3"
19848 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19849 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19850 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19851 "TARGET_SSE2
19852 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19853 "orpd\t{%2, %0|%0, %2}"
19854 [(set_attr "type" "sselog")
19855 (set_attr "mode" "V2DF")])
19856
19857 (define_insn "*sse2_iordf3"
19858 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19859 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19860 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19861 "TARGET_SSE2
19862 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19863 "orpd\t{%2, %0|%0, %2}"
19864 [(set_attr "type" "sselog")
19865 (set_attr "mode" "V2DF")])
19866
19867 (define_expand "sse2_xorv2df3"
19868 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19869 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19870 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19871 "TARGET_SSE2"
19872 "")
19873
19874 (define_insn "*sse2_xorv2df3"
19875 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19876 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19877 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19878 "TARGET_SSE2
19879 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19880 "xorpd\t{%2, %0|%0, %2}"
19881 [(set_attr "type" "sselog")
19882 (set_attr "mode" "V2DF")])
19883
19884 (define_insn "*sse2_xordf3"
19885 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19886 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19887 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19888 "TARGET_SSE2
19889 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19890 "xorpd\t{%2, %0|%0, %2}"
19891 [(set_attr "type" "sselog")
19892 (set_attr "mode" "V2DF")])
19893
19894 ;; SSE2 integral logicals. These patterns must always come after floating
19895 ;; point ones since we don't want compiler to use integer opcodes on floating
19896 ;; point SSE values to avoid matching of subregs in the match_operand.
19897 (define_insn "*sse2_andti3"
19898 [(set (match_operand:TI 0 "register_operand" "=x")
19899 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19900 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19901 "TARGET_SSE2
19902 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19903 "pand\t{%2, %0|%0, %2}"
19904 [(set_attr "type" "sselog")
19905 (set_attr "mode" "TI")])
19906
19907 (define_insn "sse2_andv2di3"
19908 [(set (match_operand:V2DI 0 "register_operand" "=x")
19909 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19910 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19911 "TARGET_SSE2
19912 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19913 "pand\t{%2, %0|%0, %2}"
19914 [(set_attr "type" "sselog")
19915 (set_attr "mode" "TI")])
19916
19917 (define_insn "*sse2_nandti3"
19918 [(set (match_operand:TI 0 "register_operand" "=x")
19919 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19920 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19921 "TARGET_SSE2"
19922 "pandn\t{%2, %0|%0, %2}"
19923 [(set_attr "type" "sselog")
19924 (set_attr "mode" "TI")])
19925
19926 (define_insn "sse2_nandv2di3"
19927 [(set (match_operand:V2DI 0 "register_operand" "=x")
19928 (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "0"))
19929 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19930 "TARGET_SSE2
19931 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19932 "pandn\t{%2, %0|%0, %2}"
19933 [(set_attr "type" "sselog")
19934 (set_attr "mode" "TI")])
19935
19936 (define_insn "*sse2_iorti3"
19937 [(set (match_operand:TI 0 "register_operand" "=x")
19938 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19939 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19940 "TARGET_SSE2
19941 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19942 "por\t{%2, %0|%0, %2}"
19943 [(set_attr "type" "sselog")
19944 (set_attr "mode" "TI")])
19945
19946 (define_insn "sse2_iorv2di3"
19947 [(set (match_operand:V2DI 0 "register_operand" "=x")
19948 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19949 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19950 "TARGET_SSE2
19951 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19952 "por\t{%2, %0|%0, %2}"
19953 [(set_attr "type" "sselog")
19954 (set_attr "mode" "TI")])
19955
19956 (define_insn "*sse2_xorti3"
19957 [(set (match_operand:TI 0 "register_operand" "=x")
19958 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19959 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19960 "TARGET_SSE2
19961 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19962 "pxor\t{%2, %0|%0, %2}"
19963 [(set_attr "type" "sselog")
19964 (set_attr "mode" "TI")])
19965
19966 (define_insn "sse2_xorv2di3"
19967 [(set (match_operand:V2DI 0 "register_operand" "=x")
19968 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19969 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19970 "TARGET_SSE2
19971 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19972 "pxor\t{%2, %0|%0, %2}"
19973 [(set_attr "type" "sselog")
19974 (set_attr "mode" "TI")])
19975
19976 ;; Use xor, but don't show input operands so they aren't live before
19977 ;; this insn.
19978 (define_insn "sse_clrv4sf"
19979 [(set (match_operand:V4SF 0 "register_operand" "=x")
19980 (match_operand:V4SF 1 "const0_operand" "X"))]
19981 "TARGET_SSE"
19982 {
19983 if (get_attr_mode (insn) == MODE_TI)
19984 return "pxor\t{%0, %0|%0, %0}";
19985 else
19986 return "xorps\t{%0, %0|%0, %0}";
19987 }
19988 [(set_attr "type" "sselog")
19989 (set_attr "memory" "none")
19990 (set (attr "mode")
19991 (if_then_else
19992 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19993 (const_int 0))
19994 (ne (symbol_ref "TARGET_SSE2")
19995 (const_int 0)))
19996 (eq (symbol_ref "optimize_size")
19997 (const_int 0)))
19998 (const_string "TI")
19999 (const_string "V4SF")))])
20000
20001 ;; Use xor, but don't show input operands so they aren't live before
20002 ;; this insn.
20003 (define_insn "sse_clrv2df"
20004 [(set (match_operand:V2DF 0 "register_operand" "=x")
20005 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20006 "TARGET_SSE2"
20007 "xorpd\t{%0, %0|%0, %0}"
20008 [(set_attr "type" "sselog")
20009 (set_attr "memory" "none")
20010 (set_attr "mode" "V4SF")])
20011
20012 ;; SSE mask-generating compares
20013
20014 (define_insn "maskcmpv4sf3"
20015 [(set (match_operand:V4SI 0 "register_operand" "=x")
20016 (match_operator:V4SI 3 "sse_comparison_operator"
20017 [(match_operand:V4SF 1 "register_operand" "0")
20018 (match_operand:V4SF 2 "register_operand" "x")]))]
20019 "TARGET_SSE"
20020 "cmp%D3ps\t{%2, %0|%0, %2}"
20021 [(set_attr "type" "ssecmp")
20022 (set_attr "mode" "V4SF")])
20023
20024 (define_insn "maskncmpv4sf3"
20025 [(set (match_operand:V4SI 0 "register_operand" "=x")
20026 (not:V4SI
20027 (match_operator:V4SI 3 "sse_comparison_operator"
20028 [(match_operand:V4SF 1 "register_operand" "0")
20029 (match_operand:V4SF 2 "register_operand" "x")])))]
20030 "TARGET_SSE"
20031 {
20032 if (GET_CODE (operands[3]) == UNORDERED)
20033 return "cmpordps\t{%2, %0|%0, %2}";
20034 else
20035 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20036 }
20037 [(set_attr "type" "ssecmp")
20038 (set_attr "mode" "V4SF")])
20039
20040 (define_insn "vmmaskcmpv4sf3"
20041 [(set (match_operand:V4SI 0 "register_operand" "=x")
20042 (vec_merge:V4SI
20043 (match_operator:V4SI 3 "sse_comparison_operator"
20044 [(match_operand:V4SF 1 "register_operand" "0")
20045 (match_operand:V4SF 2 "register_operand" "x")])
20046 (subreg:V4SI (match_dup 1) 0)
20047 (const_int 1)))]
20048 "TARGET_SSE"
20049 "cmp%D3ss\t{%2, %0|%0, %2}"
20050 [(set_attr "type" "ssecmp")
20051 (set_attr "mode" "SF")])
20052
20053 (define_insn "vmmaskncmpv4sf3"
20054 [(set (match_operand:V4SI 0 "register_operand" "=x")
20055 (vec_merge:V4SI
20056 (not:V4SI
20057 (match_operator:V4SI 3 "sse_comparison_operator"
20058 [(match_operand:V4SF 1 "register_operand" "0")
20059 (match_operand:V4SF 2 "register_operand" "x")]))
20060 (subreg:V4SI (match_dup 1) 0)
20061 (const_int 1)))]
20062 "TARGET_SSE"
20063 {
20064 if (GET_CODE (operands[3]) == UNORDERED)
20065 return "cmpordss\t{%2, %0|%0, %2}";
20066 else
20067 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20068 }
20069 [(set_attr "type" "ssecmp")
20070 (set_attr "mode" "SF")])
20071
20072 (define_insn "sse_comi"
20073 [(set (reg:CCFP 17)
20074 (compare:CCFP (vec_select:SF
20075 (match_operand:V4SF 0 "register_operand" "x")
20076 (parallel [(const_int 0)]))
20077 (vec_select:SF
20078 (match_operand:V4SF 1 "register_operand" "x")
20079 (parallel [(const_int 0)]))))]
20080 "TARGET_SSE"
20081 "comiss\t{%1, %0|%0, %1}"
20082 [(set_attr "type" "ssecomi")
20083 (set_attr "mode" "SF")])
20084
20085 (define_insn "sse_ucomi"
20086 [(set (reg:CCFPU 17)
20087 (compare:CCFPU (vec_select:SF
20088 (match_operand:V4SF 0 "register_operand" "x")
20089 (parallel [(const_int 0)]))
20090 (vec_select:SF
20091 (match_operand:V4SF 1 "register_operand" "x")
20092 (parallel [(const_int 0)]))))]
20093 "TARGET_SSE"
20094 "ucomiss\t{%1, %0|%0, %1}"
20095 [(set_attr "type" "ssecomi")
20096 (set_attr "mode" "SF")])
20097
20098
20099 ;; SSE unpack
20100
20101 (define_insn "sse_unpckhps"
20102 [(set (match_operand:V4SF 0 "register_operand" "=x")
20103 (vec_merge:V4SF
20104 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20105 (parallel [(const_int 2)
20106 (const_int 0)
20107 (const_int 3)
20108 (const_int 1)]))
20109 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20110 (parallel [(const_int 0)
20111 (const_int 2)
20112 (const_int 1)
20113 (const_int 3)]))
20114 (const_int 5)))]
20115 "TARGET_SSE"
20116 "unpckhps\t{%2, %0|%0, %2}"
20117 [(set_attr "type" "ssecvt")
20118 (set_attr "mode" "V4SF")])
20119
20120 (define_insn "sse_unpcklps"
20121 [(set (match_operand:V4SF 0 "register_operand" "=x")
20122 (vec_merge:V4SF
20123 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20124 (parallel [(const_int 0)
20125 (const_int 2)
20126 (const_int 1)
20127 (const_int 3)]))
20128 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20129 (parallel [(const_int 2)
20130 (const_int 0)
20131 (const_int 3)
20132 (const_int 1)]))
20133 (const_int 5)))]
20134 "TARGET_SSE"
20135 "unpcklps\t{%2, %0|%0, %2}"
20136 [(set_attr "type" "ssecvt")
20137 (set_attr "mode" "V4SF")])
20138
20139
20140 ;; SSE min/max
20141
20142 (define_insn "smaxv4sf3"
20143 [(set (match_operand:V4SF 0 "register_operand" "=x")
20144 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20145 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20146 "TARGET_SSE"
20147 "maxps\t{%2, %0|%0, %2}"
20148 [(set_attr "type" "sse")
20149 (set_attr "mode" "V4SF")])
20150
20151 (define_insn "vmsmaxv4sf3"
20152 [(set (match_operand:V4SF 0 "register_operand" "=x")
20153 (vec_merge:V4SF
20154 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20155 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20156 (match_dup 1)
20157 (const_int 1)))]
20158 "TARGET_SSE"
20159 "maxss\t{%2, %0|%0, %2}"
20160 [(set_attr "type" "sse")
20161 (set_attr "mode" "SF")])
20162
20163 (define_insn "sminv4sf3"
20164 [(set (match_operand:V4SF 0 "register_operand" "=x")
20165 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20166 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20167 "TARGET_SSE"
20168 "minps\t{%2, %0|%0, %2}"
20169 [(set_attr "type" "sse")
20170 (set_attr "mode" "V4SF")])
20171
20172 (define_insn "vmsminv4sf3"
20173 [(set (match_operand:V4SF 0 "register_operand" "=x")
20174 (vec_merge:V4SF
20175 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20176 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20177 (match_dup 1)
20178 (const_int 1)))]
20179 "TARGET_SSE"
20180 "minss\t{%2, %0|%0, %2}"
20181 [(set_attr "type" "sse")
20182 (set_attr "mode" "SF")])
20183
20184 ;; SSE <-> integer/MMX conversions
20185
20186 (define_insn "cvtpi2ps"
20187 [(set (match_operand:V4SF 0 "register_operand" "=x")
20188 (vec_merge:V4SF
20189 (match_operand:V4SF 1 "register_operand" "0")
20190 (vec_duplicate:V4SF
20191 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20192 (const_int 12)))]
20193 "TARGET_SSE"
20194 "cvtpi2ps\t{%2, %0|%0, %2}"
20195 [(set_attr "type" "ssecvt")
20196 (set_attr "mode" "V4SF")])
20197
20198 (define_insn "cvtps2pi"
20199 [(set (match_operand:V2SI 0 "register_operand" "=y")
20200 (vec_select:V2SI
20201 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20202 (parallel [(const_int 0) (const_int 1)])))]
20203 "TARGET_SSE"
20204 "cvtps2pi\t{%1, %0|%0, %1}"
20205 [(set_attr "type" "ssecvt")
20206 (set_attr "mode" "V4SF")])
20207
20208 (define_insn "cvttps2pi"
20209 [(set (match_operand:V2SI 0 "register_operand" "=y")
20210 (vec_select:V2SI
20211 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20212 UNSPEC_FIX)
20213 (parallel [(const_int 0) (const_int 1)])))]
20214 "TARGET_SSE"
20215 "cvttps2pi\t{%1, %0|%0, %1}"
20216 [(set_attr "type" "ssecvt")
20217 (set_attr "mode" "SF")])
20218
20219 (define_insn "cvtsi2ss"
20220 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20221 (vec_merge:V4SF
20222 (match_operand:V4SF 1 "register_operand" "0,0")
20223 (vec_duplicate:V4SF
20224 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20225 (const_int 14)))]
20226 "TARGET_SSE"
20227 "cvtsi2ss\t{%2, %0|%0, %2}"
20228 [(set_attr "type" "sseicvt")
20229 (set_attr "athlon_decode" "vector,double")
20230 (set_attr "mode" "SF")])
20231
20232 (define_insn "cvtsi2ssq"
20233 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20234 (vec_merge:V4SF
20235 (match_operand:V4SF 1 "register_operand" "0,0")
20236 (vec_duplicate:V4SF
20237 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20238 (const_int 14)))]
20239 "TARGET_SSE && TARGET_64BIT"
20240 "cvtsi2ssq\t{%2, %0|%0, %2}"
20241 [(set_attr "type" "sseicvt")
20242 (set_attr "athlon_decode" "vector,double")
20243 (set_attr "mode" "SF")])
20244
20245 (define_insn "cvtss2si"
20246 [(set (match_operand:SI 0 "register_operand" "=r,r")
20247 (vec_select:SI
20248 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20249 (parallel [(const_int 0)])))]
20250 "TARGET_SSE"
20251 "cvtss2si\t{%1, %0|%0, %1}"
20252 [(set_attr "type" "sseicvt")
20253 (set_attr "athlon_decode" "double,vector")
20254 (set_attr "mode" "SF")])
20255
20256 (define_insn "cvtss2siq"
20257 [(set (match_operand:DI 0 "register_operand" "=r,r")
20258 (vec_select:DI
20259 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20260 (parallel [(const_int 0)])))]
20261 "TARGET_SSE"
20262 "cvtss2siq\t{%1, %0|%0, %1}"
20263 [(set_attr "type" "sseicvt")
20264 (set_attr "athlon_decode" "double,vector")
20265 (set_attr "mode" "SF")])
20266
20267 (define_insn "cvttss2si"
20268 [(set (match_operand:SI 0 "register_operand" "=r,r")
20269 (vec_select:SI
20270 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20271 UNSPEC_FIX)
20272 (parallel [(const_int 0)])))]
20273 "TARGET_SSE"
20274 "cvttss2si\t{%1, %0|%0, %1}"
20275 [(set_attr "type" "sseicvt")
20276 (set_attr "mode" "SF")
20277 (set_attr "athlon_decode" "double,vector")])
20278
20279 (define_insn "cvttss2siq"
20280 [(set (match_operand:DI 0 "register_operand" "=r,r")
20281 (vec_select:DI
20282 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20283 UNSPEC_FIX)
20284 (parallel [(const_int 0)])))]
20285 "TARGET_SSE && TARGET_64BIT"
20286 "cvttss2siq\t{%1, %0|%0, %1}"
20287 [(set_attr "type" "sseicvt")
20288 (set_attr "mode" "SF")
20289 (set_attr "athlon_decode" "double,vector")])
20290
20291
20292 ;; MMX insns
20293
20294 ;; MMX arithmetic
20295
20296 (define_insn "addv8qi3"
20297 [(set (match_operand:V8QI 0 "register_operand" "=y")
20298 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20299 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20300 "TARGET_MMX"
20301 "paddb\t{%2, %0|%0, %2}"
20302 [(set_attr "type" "mmxadd")
20303 (set_attr "mode" "DI")])
20304
20305 (define_insn "addv4hi3"
20306 [(set (match_operand:V4HI 0 "register_operand" "=y")
20307 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20308 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20309 "TARGET_MMX"
20310 "paddw\t{%2, %0|%0, %2}"
20311 [(set_attr "type" "mmxadd")
20312 (set_attr "mode" "DI")])
20313
20314 (define_insn "addv2si3"
20315 [(set (match_operand:V2SI 0 "register_operand" "=y")
20316 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20317 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20318 "TARGET_MMX"
20319 "paddd\t{%2, %0|%0, %2}"
20320 [(set_attr "type" "mmxadd")
20321 (set_attr "mode" "DI")])
20322
20323 (define_insn "mmx_adddi3"
20324 [(set (match_operand:DI 0 "register_operand" "=y")
20325 (unspec:DI
20326 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20327 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20328 UNSPEC_NOP))]
20329 "TARGET_MMX"
20330 "paddq\t{%2, %0|%0, %2}"
20331 [(set_attr "type" "mmxadd")
20332 (set_attr "mode" "DI")])
20333
20334 (define_insn "ssaddv8qi3"
20335 [(set (match_operand:V8QI 0 "register_operand" "=y")
20336 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20337 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20338 "TARGET_MMX"
20339 "paddsb\t{%2, %0|%0, %2}"
20340 [(set_attr "type" "mmxadd")
20341 (set_attr "mode" "DI")])
20342
20343 (define_insn "ssaddv4hi3"
20344 [(set (match_operand:V4HI 0 "register_operand" "=y")
20345 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20346 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20347 "TARGET_MMX"
20348 "paddsw\t{%2, %0|%0, %2}"
20349 [(set_attr "type" "mmxadd")
20350 (set_attr "mode" "DI")])
20351
20352 (define_insn "usaddv8qi3"
20353 [(set (match_operand:V8QI 0 "register_operand" "=y")
20354 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20355 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20356 "TARGET_MMX"
20357 "paddusb\t{%2, %0|%0, %2}"
20358 [(set_attr "type" "mmxadd")
20359 (set_attr "mode" "DI")])
20360
20361 (define_insn "usaddv4hi3"
20362 [(set (match_operand:V4HI 0 "register_operand" "=y")
20363 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20364 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20365 "TARGET_MMX"
20366 "paddusw\t{%2, %0|%0, %2}"
20367 [(set_attr "type" "mmxadd")
20368 (set_attr "mode" "DI")])
20369
20370 (define_insn "subv8qi3"
20371 [(set (match_operand:V8QI 0 "register_operand" "=y")
20372 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20373 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20374 "TARGET_MMX"
20375 "psubb\t{%2, %0|%0, %2}"
20376 [(set_attr "type" "mmxadd")
20377 (set_attr "mode" "DI")])
20378
20379 (define_insn "subv4hi3"
20380 [(set (match_operand:V4HI 0 "register_operand" "=y")
20381 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20382 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20383 "TARGET_MMX"
20384 "psubw\t{%2, %0|%0, %2}"
20385 [(set_attr "type" "mmxadd")
20386 (set_attr "mode" "DI")])
20387
20388 (define_insn "subv2si3"
20389 [(set (match_operand:V2SI 0 "register_operand" "=y")
20390 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20391 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20392 "TARGET_MMX"
20393 "psubd\t{%2, %0|%0, %2}"
20394 [(set_attr "type" "mmxadd")
20395 (set_attr "mode" "DI")])
20396
20397 (define_insn "mmx_subdi3"
20398 [(set (match_operand:DI 0 "register_operand" "=y")
20399 (unspec:DI
20400 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20401 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20402 UNSPEC_NOP))]
20403 "TARGET_MMX"
20404 "psubq\t{%2, %0|%0, %2}"
20405 [(set_attr "type" "mmxadd")
20406 (set_attr "mode" "DI")])
20407
20408 (define_insn "sssubv8qi3"
20409 [(set (match_operand:V8QI 0 "register_operand" "=y")
20410 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20411 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20412 "TARGET_MMX"
20413 "psubsb\t{%2, %0|%0, %2}"
20414 [(set_attr "type" "mmxadd")
20415 (set_attr "mode" "DI")])
20416
20417 (define_insn "sssubv4hi3"
20418 [(set (match_operand:V4HI 0 "register_operand" "=y")
20419 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20420 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20421 "TARGET_MMX"
20422 "psubsw\t{%2, %0|%0, %2}"
20423 [(set_attr "type" "mmxadd")
20424 (set_attr "mode" "DI")])
20425
20426 (define_insn "ussubv8qi3"
20427 [(set (match_operand:V8QI 0 "register_operand" "=y")
20428 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20429 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20430 "TARGET_MMX"
20431 "psubusb\t{%2, %0|%0, %2}"
20432 [(set_attr "type" "mmxadd")
20433 (set_attr "mode" "DI")])
20434
20435 (define_insn "ussubv4hi3"
20436 [(set (match_operand:V4HI 0 "register_operand" "=y")
20437 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20438 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20439 "TARGET_MMX"
20440 "psubusw\t{%2, %0|%0, %2}"
20441 [(set_attr "type" "mmxadd")
20442 (set_attr "mode" "DI")])
20443
20444 (define_insn "mulv4hi3"
20445 [(set (match_operand:V4HI 0 "register_operand" "=y")
20446 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20447 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20448 "TARGET_MMX"
20449 "pmullw\t{%2, %0|%0, %2}"
20450 [(set_attr "type" "mmxmul")
20451 (set_attr "mode" "DI")])
20452
20453 (define_insn "smulv4hi3_highpart"
20454 [(set (match_operand:V4HI 0 "register_operand" "=y")
20455 (truncate:V4HI
20456 (lshiftrt:V4SI
20457 (mult:V4SI (sign_extend:V4SI
20458 (match_operand:V4HI 1 "register_operand" "0"))
20459 (sign_extend:V4SI
20460 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20461 (const_int 16))))]
20462 "TARGET_MMX"
20463 "pmulhw\t{%2, %0|%0, %2}"
20464 [(set_attr "type" "mmxmul")
20465 (set_attr "mode" "DI")])
20466
20467 (define_insn "umulv4hi3_highpart"
20468 [(set (match_operand:V4HI 0 "register_operand" "=y")
20469 (truncate:V4HI
20470 (lshiftrt:V4SI
20471 (mult:V4SI (zero_extend:V4SI
20472 (match_operand:V4HI 1 "register_operand" "0"))
20473 (zero_extend:V4SI
20474 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20475 (const_int 16))))]
20476 "TARGET_SSE || TARGET_3DNOW_A"
20477 "pmulhuw\t{%2, %0|%0, %2}"
20478 [(set_attr "type" "mmxmul")
20479 (set_attr "mode" "DI")])
20480
20481 (define_insn "mmx_pmaddwd"
20482 [(set (match_operand:V2SI 0 "register_operand" "=y")
20483 (plus:V2SI
20484 (mult:V2SI
20485 (sign_extend:V2SI
20486 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20487 (parallel [(const_int 0) (const_int 2)])))
20488 (sign_extend:V2SI
20489 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20490 (parallel [(const_int 0) (const_int 2)]))))
20491 (mult:V2SI
20492 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20493 (parallel [(const_int 1)
20494 (const_int 3)])))
20495 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20496 (parallel [(const_int 1)
20497 (const_int 3)]))))))]
20498 "TARGET_MMX"
20499 "pmaddwd\t{%2, %0|%0, %2}"
20500 [(set_attr "type" "mmxmul")
20501 (set_attr "mode" "DI")])
20502
20503
20504 ;; MMX logical operations
20505 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20506 ;; normal code that also wants to use the FPU from getting broken.
20507 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20508 (define_insn "mmx_iordi3"
20509 [(set (match_operand:DI 0 "register_operand" "=y")
20510 (unspec:DI
20511 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20512 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20513 UNSPEC_NOP))]
20514 "TARGET_MMX"
20515 "por\t{%2, %0|%0, %2}"
20516 [(set_attr "type" "mmxadd")
20517 (set_attr "mode" "DI")])
20518
20519 (define_insn "mmx_xordi3"
20520 [(set (match_operand:DI 0 "register_operand" "=y")
20521 (unspec:DI
20522 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20523 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20524 UNSPEC_NOP))]
20525 "TARGET_MMX"
20526 "pxor\t{%2, %0|%0, %2}"
20527 [(set_attr "type" "mmxadd")
20528 (set_attr "mode" "DI")
20529 (set_attr "memory" "none")])
20530
20531 ;; Same as pxor, but don't show input operands so that we don't think
20532 ;; they are live.
20533 (define_insn "mmx_clrdi"
20534 [(set (match_operand:DI 0 "register_operand" "=y")
20535 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20536 "TARGET_MMX"
20537 "pxor\t{%0, %0|%0, %0}"
20538 [(set_attr "type" "mmxadd")
20539 (set_attr "mode" "DI")
20540 (set_attr "memory" "none")])
20541
20542 (define_insn "mmx_anddi3"
20543 [(set (match_operand:DI 0 "register_operand" "=y")
20544 (unspec:DI
20545 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20546 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20547 UNSPEC_NOP))]
20548 "TARGET_MMX"
20549 "pand\t{%2, %0|%0, %2}"
20550 [(set_attr "type" "mmxadd")
20551 (set_attr "mode" "DI")])
20552
20553 (define_insn "mmx_nanddi3"
20554 [(set (match_operand:DI 0 "register_operand" "=y")
20555 (unspec:DI
20556 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20557 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20558 UNSPEC_NOP))]
20559 "TARGET_MMX"
20560 "pandn\t{%2, %0|%0, %2}"
20561 [(set_attr "type" "mmxadd")
20562 (set_attr "mode" "DI")])
20563
20564
20565 ;; MMX unsigned averages/sum of absolute differences
20566
20567 (define_insn "mmx_uavgv8qi3"
20568 [(set (match_operand:V8QI 0 "register_operand" "=y")
20569 (ashiftrt:V8QI
20570 (plus:V8QI (plus:V8QI
20571 (match_operand:V8QI 1 "register_operand" "0")
20572 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20573 (const_vector:V8QI [(const_int 1)
20574 (const_int 1)
20575 (const_int 1)
20576 (const_int 1)
20577 (const_int 1)
20578 (const_int 1)
20579 (const_int 1)
20580 (const_int 1)]))
20581 (const_int 1)))]
20582 "TARGET_SSE || TARGET_3DNOW_A"
20583 "pavgb\t{%2, %0|%0, %2}"
20584 [(set_attr "type" "mmxshft")
20585 (set_attr "mode" "DI")])
20586
20587 (define_insn "mmx_uavgv4hi3"
20588 [(set (match_operand:V4HI 0 "register_operand" "=y")
20589 (ashiftrt:V4HI
20590 (plus:V4HI (plus:V4HI
20591 (match_operand:V4HI 1 "register_operand" "0")
20592 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20593 (const_vector:V4HI [(const_int 1)
20594 (const_int 1)
20595 (const_int 1)
20596 (const_int 1)]))
20597 (const_int 1)))]
20598 "TARGET_SSE || TARGET_3DNOW_A"
20599 "pavgw\t{%2, %0|%0, %2}"
20600 [(set_attr "type" "mmxshft")
20601 (set_attr "mode" "DI")])
20602
20603 (define_insn "mmx_psadbw"
20604 [(set (match_operand:DI 0 "register_operand" "=y")
20605 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20606 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20607 UNSPEC_PSADBW))]
20608 "TARGET_SSE || TARGET_3DNOW_A"
20609 "psadbw\t{%2, %0|%0, %2}"
20610 [(set_attr "type" "mmxshft")
20611 (set_attr "mode" "DI")])
20612
20613
20614 ;; MMX insert/extract/shuffle
20615
20616 (define_insn "mmx_pinsrw"
20617 [(set (match_operand:V4HI 0 "register_operand" "=y")
20618 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20619 (vec_duplicate:V4HI
20620 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20621 (match_operand:SI 3 "immediate_operand" "i")))]
20622 "TARGET_SSE || TARGET_3DNOW_A"
20623 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20624 [(set_attr "type" "mmxcvt")
20625 (set_attr "mode" "DI")])
20626
20627 (define_insn "mmx_pextrw"
20628 [(set (match_operand:SI 0 "register_operand" "=r")
20629 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20630 (parallel
20631 [(match_operand:SI 2 "immediate_operand" "i")]))))]
20632 "TARGET_SSE || TARGET_3DNOW_A"
20633 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20634 [(set_attr "type" "mmxcvt")
20635 (set_attr "mode" "DI")])
20636
20637 (define_insn "mmx_pshufw"
20638 [(set (match_operand:V4HI 0 "register_operand" "=y")
20639 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20640 (match_operand:SI 2 "immediate_operand" "i")]
20641 UNSPEC_SHUFFLE))]
20642 "TARGET_SSE || TARGET_3DNOW_A"
20643 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20644 [(set_attr "type" "mmxcvt")
20645 (set_attr "mode" "DI")])
20646
20647
20648 ;; MMX mask-generating comparisons
20649
20650 (define_insn "eqv8qi3"
20651 [(set (match_operand:V8QI 0 "register_operand" "=y")
20652 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20653 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20654 "TARGET_MMX"
20655 "pcmpeqb\t{%2, %0|%0, %2}"
20656 [(set_attr "type" "mmxcmp")
20657 (set_attr "mode" "DI")])
20658
20659 (define_insn "eqv4hi3"
20660 [(set (match_operand:V4HI 0 "register_operand" "=y")
20661 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20662 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20663 "TARGET_MMX"
20664 "pcmpeqw\t{%2, %0|%0, %2}"
20665 [(set_attr "type" "mmxcmp")
20666 (set_attr "mode" "DI")])
20667
20668 (define_insn "eqv2si3"
20669 [(set (match_operand:V2SI 0 "register_operand" "=y")
20670 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20671 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20672 "TARGET_MMX"
20673 "pcmpeqd\t{%2, %0|%0, %2}"
20674 [(set_attr "type" "mmxcmp")
20675 (set_attr "mode" "DI")])
20676
20677 (define_insn "gtv8qi3"
20678 [(set (match_operand:V8QI 0 "register_operand" "=y")
20679 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20680 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20681 "TARGET_MMX"
20682 "pcmpgtb\t{%2, %0|%0, %2}"
20683 [(set_attr "type" "mmxcmp")
20684 (set_attr "mode" "DI")])
20685
20686 (define_insn "gtv4hi3"
20687 [(set (match_operand:V4HI 0 "register_operand" "=y")
20688 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20689 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20690 "TARGET_MMX"
20691 "pcmpgtw\t{%2, %0|%0, %2}"
20692 [(set_attr "type" "mmxcmp")
20693 (set_attr "mode" "DI")])
20694
20695 (define_insn "gtv2si3"
20696 [(set (match_operand:V2SI 0 "register_operand" "=y")
20697 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20698 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20699 "TARGET_MMX"
20700 "pcmpgtd\t{%2, %0|%0, %2}"
20701 [(set_attr "type" "mmxcmp")
20702 (set_attr "mode" "DI")])
20703
20704
20705 ;; MMX max/min insns
20706
20707 (define_insn "umaxv8qi3"
20708 [(set (match_operand:V8QI 0 "register_operand" "=y")
20709 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20710 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20711 "TARGET_SSE || TARGET_3DNOW_A"
20712 "pmaxub\t{%2, %0|%0, %2}"
20713 [(set_attr "type" "mmxadd")
20714 (set_attr "mode" "DI")])
20715
20716 (define_insn "smaxv4hi3"
20717 [(set (match_operand:V4HI 0 "register_operand" "=y")
20718 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20719 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20720 "TARGET_SSE || TARGET_3DNOW_A"
20721 "pmaxsw\t{%2, %0|%0, %2}"
20722 [(set_attr "type" "mmxadd")
20723 (set_attr "mode" "DI")])
20724
20725 (define_insn "uminv8qi3"
20726 [(set (match_operand:V8QI 0 "register_operand" "=y")
20727 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20728 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20729 "TARGET_SSE || TARGET_3DNOW_A"
20730 "pminub\t{%2, %0|%0, %2}"
20731 [(set_attr "type" "mmxadd")
20732 (set_attr "mode" "DI")])
20733
20734 (define_insn "sminv4hi3"
20735 [(set (match_operand:V4HI 0 "register_operand" "=y")
20736 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20737 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20738 "TARGET_SSE || TARGET_3DNOW_A"
20739 "pminsw\t{%2, %0|%0, %2}"
20740 [(set_attr "type" "mmxadd")
20741 (set_attr "mode" "DI")])
20742
20743
20744 ;; MMX shifts
20745
20746 (define_insn "ashrv4hi3"
20747 [(set (match_operand:V4HI 0 "register_operand" "=y")
20748 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20749 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20750 "TARGET_MMX"
20751 "psraw\t{%2, %0|%0, %2}"
20752 [(set_attr "type" "mmxshft")
20753 (set_attr "mode" "DI")])
20754
20755 (define_insn "ashrv2si3"
20756 [(set (match_operand:V2SI 0 "register_operand" "=y")
20757 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20758 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20759 "TARGET_MMX"
20760 "psrad\t{%2, %0|%0, %2}"
20761 [(set_attr "type" "mmxshft")
20762 (set_attr "mode" "DI")])
20763
20764 (define_insn "lshrv4hi3"
20765 [(set (match_operand:V4HI 0 "register_operand" "=y")
20766 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20767 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20768 "TARGET_MMX"
20769 "psrlw\t{%2, %0|%0, %2}"
20770 [(set_attr "type" "mmxshft")
20771 (set_attr "mode" "DI")])
20772
20773 (define_insn "lshrv2si3"
20774 [(set (match_operand:V2SI 0 "register_operand" "=y")
20775 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20776 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20777 "TARGET_MMX"
20778 "psrld\t{%2, %0|%0, %2}"
20779 [(set_attr "type" "mmxshft")
20780 (set_attr "mode" "DI")])
20781
20782 ;; See logical MMX insns.
20783 (define_insn "mmx_lshrdi3"
20784 [(set (match_operand:DI 0 "register_operand" "=y")
20785 (unspec:DI
20786 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20787 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20788 UNSPEC_NOP))]
20789 "TARGET_MMX"
20790 "psrlq\t{%2, %0|%0, %2}"
20791 [(set_attr "type" "mmxshft")
20792 (set_attr "mode" "DI")])
20793
20794 (define_insn "ashlv4hi3"
20795 [(set (match_operand:V4HI 0 "register_operand" "=y")
20796 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20797 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20798 "TARGET_MMX"
20799 "psllw\t{%2, %0|%0, %2}"
20800 [(set_attr "type" "mmxshft")
20801 (set_attr "mode" "DI")])
20802
20803 (define_insn "ashlv2si3"
20804 [(set (match_operand:V2SI 0 "register_operand" "=y")
20805 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20806 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20807 "TARGET_MMX"
20808 "pslld\t{%2, %0|%0, %2}"
20809 [(set_attr "type" "mmxshft")
20810 (set_attr "mode" "DI")])
20811
20812 ;; See logical MMX insns.
20813 (define_insn "mmx_ashldi3"
20814 [(set (match_operand:DI 0 "register_operand" "=y")
20815 (unspec:DI
20816 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20817 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20818 UNSPEC_NOP))]
20819 "TARGET_MMX"
20820 "psllq\t{%2, %0|%0, %2}"
20821 [(set_attr "type" "mmxshft")
20822 (set_attr "mode" "DI")])
20823
20824
20825 ;; MMX pack/unpack insns.
20826
20827 (define_insn "mmx_packsswb"
20828 [(set (match_operand:V8QI 0 "register_operand" "=y")
20829 (vec_concat:V8QI
20830 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20831 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20832 "TARGET_MMX"
20833 "packsswb\t{%2, %0|%0, %2}"
20834 [(set_attr "type" "mmxshft")
20835 (set_attr "mode" "DI")])
20836
20837 (define_insn "mmx_packssdw"
20838 [(set (match_operand:V4HI 0 "register_operand" "=y")
20839 (vec_concat:V4HI
20840 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20841 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20842 "TARGET_MMX"
20843 "packssdw\t{%2, %0|%0, %2}"
20844 [(set_attr "type" "mmxshft")
20845 (set_attr "mode" "DI")])
20846
20847 (define_insn "mmx_packuswb"
20848 [(set (match_operand:V8QI 0 "register_operand" "=y")
20849 (vec_concat:V8QI
20850 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20851 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20852 "TARGET_MMX"
20853 "packuswb\t{%2, %0|%0, %2}"
20854 [(set_attr "type" "mmxshft")
20855 (set_attr "mode" "DI")])
20856
20857 (define_insn "mmx_punpckhbw"
20858 [(set (match_operand:V8QI 0 "register_operand" "=y")
20859 (vec_merge:V8QI
20860 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20861 (parallel [(const_int 4)
20862 (const_int 0)
20863 (const_int 5)
20864 (const_int 1)
20865 (const_int 6)
20866 (const_int 2)
20867 (const_int 7)
20868 (const_int 3)]))
20869 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20870 (parallel [(const_int 0)
20871 (const_int 4)
20872 (const_int 1)
20873 (const_int 5)
20874 (const_int 2)
20875 (const_int 6)
20876 (const_int 3)
20877 (const_int 7)]))
20878 (const_int 85)))]
20879 "TARGET_MMX"
20880 "punpckhbw\t{%2, %0|%0, %2}"
20881 [(set_attr "type" "mmxcvt")
20882 (set_attr "mode" "DI")])
20883
20884 (define_insn "mmx_punpckhwd"
20885 [(set (match_operand:V4HI 0 "register_operand" "=y")
20886 (vec_merge:V4HI
20887 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20888 (parallel [(const_int 0)
20889 (const_int 2)
20890 (const_int 1)
20891 (const_int 3)]))
20892 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20893 (parallel [(const_int 2)
20894 (const_int 0)
20895 (const_int 3)
20896 (const_int 1)]))
20897 (const_int 5)))]
20898 "TARGET_MMX"
20899 "punpckhwd\t{%2, %0|%0, %2}"
20900 [(set_attr "type" "mmxcvt")
20901 (set_attr "mode" "DI")])
20902
20903 (define_insn "mmx_punpckhdq"
20904 [(set (match_operand:V2SI 0 "register_operand" "=y")
20905 (vec_merge:V2SI
20906 (match_operand:V2SI 1 "register_operand" "0")
20907 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20908 (parallel [(const_int 1)
20909 (const_int 0)]))
20910 (const_int 1)))]
20911 "TARGET_MMX"
20912 "punpckhdq\t{%2, %0|%0, %2}"
20913 [(set_attr "type" "mmxcvt")
20914 (set_attr "mode" "DI")])
20915
20916 (define_insn "mmx_punpcklbw"
20917 [(set (match_operand:V8QI 0 "register_operand" "=y")
20918 (vec_merge:V8QI
20919 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20920 (parallel [(const_int 0)
20921 (const_int 4)
20922 (const_int 1)
20923 (const_int 5)
20924 (const_int 2)
20925 (const_int 6)
20926 (const_int 3)
20927 (const_int 7)]))
20928 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20929 (parallel [(const_int 4)
20930 (const_int 0)
20931 (const_int 5)
20932 (const_int 1)
20933 (const_int 6)
20934 (const_int 2)
20935 (const_int 7)
20936 (const_int 3)]))
20937 (const_int 85)))]
20938 "TARGET_MMX"
20939 "punpcklbw\t{%2, %0|%0, %2}"
20940 [(set_attr "type" "mmxcvt")
20941 (set_attr "mode" "DI")])
20942
20943 (define_insn "mmx_punpcklwd"
20944 [(set (match_operand:V4HI 0 "register_operand" "=y")
20945 (vec_merge:V4HI
20946 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20947 (parallel [(const_int 2)
20948 (const_int 0)
20949 (const_int 3)
20950 (const_int 1)]))
20951 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20952 (parallel [(const_int 0)
20953 (const_int 2)
20954 (const_int 1)
20955 (const_int 3)]))
20956 (const_int 5)))]
20957 "TARGET_MMX"
20958 "punpcklwd\t{%2, %0|%0, %2}"
20959 [(set_attr "type" "mmxcvt")
20960 (set_attr "mode" "DI")])
20961
20962 (define_insn "mmx_punpckldq"
20963 [(set (match_operand:V2SI 0 "register_operand" "=y")
20964 (vec_merge:V2SI
20965 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20966 (parallel [(const_int 1)
20967 (const_int 0)]))
20968 (match_operand:V2SI 2 "register_operand" "y")
20969 (const_int 1)))]
20970 "TARGET_MMX"
20971 "punpckldq\t{%2, %0|%0, %2}"
20972 [(set_attr "type" "mmxcvt")
20973 (set_attr "mode" "DI")])
20974
20975
20976 ;; Miscellaneous stuff
20977
20978 (define_insn "emms"
20979 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20980 (clobber (reg:XF 8))
20981 (clobber (reg:XF 9))
20982 (clobber (reg:XF 10))
20983 (clobber (reg:XF 11))
20984 (clobber (reg:XF 12))
20985 (clobber (reg:XF 13))
20986 (clobber (reg:XF 14))
20987 (clobber (reg:XF 15))
20988 (clobber (reg:DI 29))
20989 (clobber (reg:DI 30))
20990 (clobber (reg:DI 31))
20991 (clobber (reg:DI 32))
20992 (clobber (reg:DI 33))
20993 (clobber (reg:DI 34))
20994 (clobber (reg:DI 35))
20995 (clobber (reg:DI 36))]
20996 "TARGET_MMX"
20997 "emms"
20998 [(set_attr "type" "mmx")
20999 (set_attr "memory" "unknown")])
21000
21001 (define_insn "ldmxcsr"
21002 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21003 UNSPECV_LDMXCSR)]
21004 "TARGET_SSE"
21005 "ldmxcsr\t%0"
21006 [(set_attr "type" "sse")
21007 (set_attr "memory" "load")])
21008
21009 (define_insn "stmxcsr"
21010 [(set (match_operand:SI 0 "memory_operand" "=m")
21011 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21012 "TARGET_SSE"
21013 "stmxcsr\t%0"
21014 [(set_attr "type" "sse")
21015 (set_attr "memory" "store")])
21016
21017 (define_expand "sfence"
21018 [(set (match_dup 0)
21019 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21020 "TARGET_SSE || TARGET_3DNOW_A"
21021 {
21022 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21023 MEM_VOLATILE_P (operands[0]) = 1;
21024 })
21025
21026 (define_insn "*sfence_insn"
21027 [(set (match_operand:BLK 0 "" "")
21028 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21029 "TARGET_SSE || TARGET_3DNOW_A"
21030 "sfence"
21031 [(set_attr "type" "sse")
21032 (set_attr "memory" "unknown")])
21033
21034 (define_expand "sse_prologue_save"
21035 [(parallel [(set (match_operand:BLK 0 "" "")
21036 (unspec:BLK [(reg:DI 21)
21037 (reg:DI 22)
21038 (reg:DI 23)
21039 (reg:DI 24)
21040 (reg:DI 25)
21041 (reg:DI 26)
21042 (reg:DI 27)
21043 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21044 (use (match_operand:DI 1 "register_operand" ""))
21045 (use (match_operand:DI 2 "immediate_operand" ""))
21046 (use (label_ref:DI (match_operand 3 "" "")))])]
21047 "TARGET_64BIT"
21048 "")
21049
21050 (define_insn "*sse_prologue_save_insn"
21051 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21052 (match_operand:DI 4 "const_int_operand" "n")))
21053 (unspec:BLK [(reg:DI 21)
21054 (reg:DI 22)
21055 (reg:DI 23)
21056 (reg:DI 24)
21057 (reg:DI 25)
21058 (reg:DI 26)
21059 (reg:DI 27)
21060 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21061 (use (match_operand:DI 1 "register_operand" "r"))
21062 (use (match_operand:DI 2 "const_int_operand" "i"))
21063 (use (label_ref:DI (match_operand 3 "" "X")))]
21064 "TARGET_64BIT
21065 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21066 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21067 "*
21068 {
21069 int i;
21070 operands[0] = gen_rtx_MEM (Pmode,
21071 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21072 output_asm_insn (\"jmp\\t%A1\", operands);
21073 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21074 {
21075 operands[4] = adjust_address (operands[0], DImode, i*16);
21076 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21077 PUT_MODE (operands[4], TImode);
21078 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21079 output_asm_insn (\"rex\", operands);
21080 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21081 }
21082 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21083 CODE_LABEL_NUMBER (operands[3]));
21084 RET;
21085 }
21086 "
21087 [(set_attr "type" "other")
21088 (set_attr "length_immediate" "0")
21089 (set_attr "length_address" "0")
21090 (set_attr "length" "135")
21091 (set_attr "memory" "store")
21092 (set_attr "modrm" "0")
21093 (set_attr "mode" "DI")])
21094
21095 ;; 3Dnow! instructions
21096
21097 (define_insn "addv2sf3"
21098 [(set (match_operand:V2SF 0 "register_operand" "=y")
21099 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21100 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21101 "TARGET_3DNOW"
21102 "pfadd\\t{%2, %0|%0, %2}"
21103 [(set_attr "type" "mmxadd")
21104 (set_attr "mode" "V2SF")])
21105
21106 (define_insn "subv2sf3"
21107 [(set (match_operand:V2SF 0 "register_operand" "=y")
21108 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21109 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21110 "TARGET_3DNOW"
21111 "pfsub\\t{%2, %0|%0, %2}"
21112 [(set_attr "type" "mmxadd")
21113 (set_attr "mode" "V2SF")])
21114
21115 (define_insn "subrv2sf3"
21116 [(set (match_operand:V2SF 0 "register_operand" "=y")
21117 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21118 (match_operand:V2SF 1 "register_operand" "0")))]
21119 "TARGET_3DNOW"
21120 "pfsubr\\t{%2, %0|%0, %2}"
21121 [(set_attr "type" "mmxadd")
21122 (set_attr "mode" "V2SF")])
21123
21124 (define_insn "gtv2sf3"
21125 [(set (match_operand:V2SI 0 "register_operand" "=y")
21126 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21127 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21128 "TARGET_3DNOW"
21129 "pfcmpgt\\t{%2, %0|%0, %2}"
21130 [(set_attr "type" "mmxcmp")
21131 (set_attr "mode" "V2SF")])
21132
21133 (define_insn "gev2sf3"
21134 [(set (match_operand:V2SI 0 "register_operand" "=y")
21135 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21136 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21137 "TARGET_3DNOW"
21138 "pfcmpge\\t{%2, %0|%0, %2}"
21139 [(set_attr "type" "mmxcmp")
21140 (set_attr "mode" "V2SF")])
21141
21142 (define_insn "eqv2sf3"
21143 [(set (match_operand:V2SI 0 "register_operand" "=y")
21144 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21145 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21146 "TARGET_3DNOW"
21147 "pfcmpeq\\t{%2, %0|%0, %2}"
21148 [(set_attr "type" "mmxcmp")
21149 (set_attr "mode" "V2SF")])
21150
21151 (define_insn "pfmaxv2sf3"
21152 [(set (match_operand:V2SF 0 "register_operand" "=y")
21153 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21154 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21155 "TARGET_3DNOW"
21156 "pfmax\\t{%2, %0|%0, %2}"
21157 [(set_attr "type" "mmxadd")
21158 (set_attr "mode" "V2SF")])
21159
21160 (define_insn "pfminv2sf3"
21161 [(set (match_operand:V2SF 0 "register_operand" "=y")
21162 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21163 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21164 "TARGET_3DNOW"
21165 "pfmin\\t{%2, %0|%0, %2}"
21166 [(set_attr "type" "mmxadd")
21167 (set_attr "mode" "V2SF")])
21168
21169 (define_insn "mulv2sf3"
21170 [(set (match_operand:V2SF 0 "register_operand" "=y")
21171 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21172 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21173 "TARGET_3DNOW"
21174 "pfmul\\t{%2, %0|%0, %2}"
21175 [(set_attr "type" "mmxmul")
21176 (set_attr "mode" "V2SF")])
21177
21178 (define_insn "femms"
21179 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21180 (clobber (reg:XF 8))
21181 (clobber (reg:XF 9))
21182 (clobber (reg:XF 10))
21183 (clobber (reg:XF 11))
21184 (clobber (reg:XF 12))
21185 (clobber (reg:XF 13))
21186 (clobber (reg:XF 14))
21187 (clobber (reg:XF 15))
21188 (clobber (reg:DI 29))
21189 (clobber (reg:DI 30))
21190 (clobber (reg:DI 31))
21191 (clobber (reg:DI 32))
21192 (clobber (reg:DI 33))
21193 (clobber (reg:DI 34))
21194 (clobber (reg:DI 35))
21195 (clobber (reg:DI 36))]
21196 "TARGET_3DNOW"
21197 "femms"
21198 [(set_attr "type" "mmx")
21199 (set_attr "memory" "none")])
21200
21201 (define_insn "pf2id"
21202 [(set (match_operand:V2SI 0 "register_operand" "=y")
21203 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21204 "TARGET_3DNOW"
21205 "pf2id\\t{%1, %0|%0, %1}"
21206 [(set_attr "type" "mmxcvt")
21207 (set_attr "mode" "V2SF")])
21208
21209 (define_insn "pf2iw"
21210 [(set (match_operand:V2SI 0 "register_operand" "=y")
21211 (sign_extend:V2SI
21212 (ss_truncate:V2HI
21213 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21214 "TARGET_3DNOW_A"
21215 "pf2iw\\t{%1, %0|%0, %1}"
21216 [(set_attr "type" "mmxcvt")
21217 (set_attr "mode" "V2SF")])
21218
21219 (define_insn "pfacc"
21220 [(set (match_operand:V2SF 0 "register_operand" "=y")
21221 (vec_concat:V2SF
21222 (plus:SF
21223 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21224 (parallel [(const_int 0)]))
21225 (vec_select:SF (match_dup 1)
21226 (parallel [(const_int 1)])))
21227 (plus:SF
21228 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21229 (parallel [(const_int 0)]))
21230 (vec_select:SF (match_dup 2)
21231 (parallel [(const_int 1)])))))]
21232 "TARGET_3DNOW"
21233 "pfacc\\t{%2, %0|%0, %2}"
21234 [(set_attr "type" "mmxadd")
21235 (set_attr "mode" "V2SF")])
21236
21237 (define_insn "pfnacc"
21238 [(set (match_operand:V2SF 0 "register_operand" "=y")
21239 (vec_concat:V2SF
21240 (minus:SF
21241 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21242 (parallel [(const_int 0)]))
21243 (vec_select:SF (match_dup 1)
21244 (parallel [(const_int 1)])))
21245 (minus:SF
21246 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21247 (parallel [(const_int 0)]))
21248 (vec_select:SF (match_dup 2)
21249 (parallel [(const_int 1)])))))]
21250 "TARGET_3DNOW_A"
21251 "pfnacc\\t{%2, %0|%0, %2}"
21252 [(set_attr "type" "mmxadd")
21253 (set_attr "mode" "V2SF")])
21254
21255 (define_insn "pfpnacc"
21256 [(set (match_operand:V2SF 0 "register_operand" "=y")
21257 (vec_concat:V2SF
21258 (minus:SF
21259 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21260 (parallel [(const_int 0)]))
21261 (vec_select:SF (match_dup 1)
21262 (parallel [(const_int 1)])))
21263 (plus:SF
21264 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21265 (parallel [(const_int 0)]))
21266 (vec_select:SF (match_dup 2)
21267 (parallel [(const_int 1)])))))]
21268 "TARGET_3DNOW_A"
21269 "pfpnacc\\t{%2, %0|%0, %2}"
21270 [(set_attr "type" "mmxadd")
21271 (set_attr "mode" "V2SF")])
21272
21273 (define_insn "pi2fw"
21274 [(set (match_operand:V2SF 0 "register_operand" "=y")
21275 (float:V2SF
21276 (vec_concat:V2SI
21277 (sign_extend:SI
21278 (truncate:HI
21279 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21280 (parallel [(const_int 0)]))))
21281 (sign_extend:SI
21282 (truncate:HI
21283 (vec_select:SI (match_dup 1)
21284 (parallel [(const_int 1)])))))))]
21285 "TARGET_3DNOW_A"
21286 "pi2fw\\t{%1, %0|%0, %1}"
21287 [(set_attr "type" "mmxcvt")
21288 (set_attr "mode" "V2SF")])
21289
21290 (define_insn "floatv2si2"
21291 [(set (match_operand:V2SF 0 "register_operand" "=y")
21292 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21293 "TARGET_3DNOW"
21294 "pi2fd\\t{%1, %0|%0, %1}"
21295 [(set_attr "type" "mmxcvt")
21296 (set_attr "mode" "V2SF")])
21297
21298 ;; This insn is identical to pavgb in operation, but the opcode is
21299 ;; different. To avoid accidentally matching pavgb, use an unspec.
21300
21301 (define_insn "pavgusb"
21302 [(set (match_operand:V8QI 0 "register_operand" "=y")
21303 (unspec:V8QI
21304 [(match_operand:V8QI 1 "register_operand" "0")
21305 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21306 UNSPEC_PAVGUSB))]
21307 "TARGET_3DNOW"
21308 "pavgusb\\t{%2, %0|%0, %2}"
21309 [(set_attr "type" "mmxshft")
21310 (set_attr "mode" "TI")])
21311
21312 ;; 3DNow reciprocal and sqrt
21313
21314 (define_insn "pfrcpv2sf2"
21315 [(set (match_operand:V2SF 0 "register_operand" "=y")
21316 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21317 UNSPEC_PFRCP))]
21318 "TARGET_3DNOW"
21319 "pfrcp\\t{%1, %0|%0, %1}"
21320 [(set_attr "type" "mmx")
21321 (set_attr "mode" "TI")])
21322
21323 (define_insn "pfrcpit1v2sf3"
21324 [(set (match_operand:V2SF 0 "register_operand" "=y")
21325 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21326 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21327 UNSPEC_PFRCPIT1))]
21328 "TARGET_3DNOW"
21329 "pfrcpit1\\t{%2, %0|%0, %2}"
21330 [(set_attr "type" "mmx")
21331 (set_attr "mode" "TI")])
21332
21333 (define_insn "pfrcpit2v2sf3"
21334 [(set (match_operand:V2SF 0 "register_operand" "=y")
21335 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21336 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21337 UNSPEC_PFRCPIT2))]
21338 "TARGET_3DNOW"
21339 "pfrcpit2\\t{%2, %0|%0, %2}"
21340 [(set_attr "type" "mmx")
21341 (set_attr "mode" "TI")])
21342
21343 (define_insn "pfrsqrtv2sf2"
21344 [(set (match_operand:V2SF 0 "register_operand" "=y")
21345 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21346 UNSPEC_PFRSQRT))]
21347 "TARGET_3DNOW"
21348 "pfrsqrt\\t{%1, %0|%0, %1}"
21349 [(set_attr "type" "mmx")
21350 (set_attr "mode" "TI")])
21351
21352 (define_insn "pfrsqit1v2sf3"
21353 [(set (match_operand:V2SF 0 "register_operand" "=y")
21354 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21355 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21356 UNSPEC_PFRSQIT1))]
21357 "TARGET_3DNOW"
21358 "pfrsqit1\\t{%2, %0|%0, %2}"
21359 [(set_attr "type" "mmx")
21360 (set_attr "mode" "TI")])
21361
21362 (define_insn "pmulhrwv4hi3"
21363 [(set (match_operand:V4HI 0 "register_operand" "=y")
21364 (truncate:V4HI
21365 (lshiftrt:V4SI
21366 (plus:V4SI
21367 (mult:V4SI
21368 (sign_extend:V4SI
21369 (match_operand:V4HI 1 "register_operand" "0"))
21370 (sign_extend:V4SI
21371 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21372 (const_vector:V4SI [(const_int 32768)
21373 (const_int 32768)
21374 (const_int 32768)
21375 (const_int 32768)]))
21376 (const_int 16))))]
21377 "TARGET_3DNOW"
21378 "pmulhrw\\t{%2, %0|%0, %2}"
21379 [(set_attr "type" "mmxmul")
21380 (set_attr "mode" "TI")])
21381
21382 (define_insn "pswapdv2si2"
21383 [(set (match_operand:V2SI 0 "register_operand" "=y")
21384 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21385 (parallel [(const_int 1) (const_int 0)])))]
21386 "TARGET_3DNOW_A"
21387 "pswapd\\t{%1, %0|%0, %1}"
21388 [(set_attr "type" "mmxcvt")
21389 (set_attr "mode" "TI")])
21390
21391 (define_insn "pswapdv2sf2"
21392 [(set (match_operand:V2SF 0 "register_operand" "=y")
21393 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21394 (parallel [(const_int 1) (const_int 0)])))]
21395 "TARGET_3DNOW_A"
21396 "pswapd\\t{%1, %0|%0, %1}"
21397 [(set_attr "type" "mmxcvt")
21398 (set_attr "mode" "TI")])
21399
21400 (define_expand "prefetch"
21401 [(prefetch (match_operand 0 "address_operand" "")
21402 (match_operand:SI 1 "const_int_operand" "")
21403 (match_operand:SI 2 "const_int_operand" ""))]
21404 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21405 {
21406 int rw = INTVAL (operands[1]);
21407 int locality = INTVAL (operands[2]);
21408
21409 if (rw != 0 && rw != 1)
21410 abort ();
21411 if (locality < 0 || locality > 3)
21412 abort ();
21413 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21414 abort ();
21415
21416 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21417 suported by SSE counterpart or the SSE prefetch is not available
21418 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21419 of locality. */
21420 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21421 operands[2] = GEN_INT (3);
21422 else
21423 operands[1] = const0_rtx;
21424 })
21425
21426 (define_insn "*prefetch_sse"
21427 [(prefetch (match_operand:SI 0 "address_operand" "p")
21428 (const_int 0)
21429 (match_operand:SI 1 "const_int_operand" ""))]
21430 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21431 {
21432 static const char * const patterns[4] = {
21433 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21434 };
21435
21436 int locality = INTVAL (operands[1]);
21437 if (locality < 0 || locality > 3)
21438 abort ();
21439
21440 return patterns[locality];
21441 }
21442 [(set_attr "type" "sse")
21443 (set_attr "memory" "none")])
21444
21445 (define_insn "*prefetch_sse_rex"
21446 [(prefetch (match_operand:DI 0 "address_operand" "p")
21447 (const_int 0)
21448 (match_operand:SI 1 "const_int_operand" ""))]
21449 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21450 {
21451 static const char * const patterns[4] = {
21452 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21453 };
21454
21455 int locality = INTVAL (operands[1]);
21456 if (locality < 0 || locality > 3)
21457 abort ();
21458
21459 return patterns[locality];
21460 }
21461 [(set_attr "type" "sse")
21462 (set_attr "memory" "none")])
21463
21464 (define_insn "*prefetch_3dnow"
21465 [(prefetch (match_operand:SI 0 "address_operand" "p")
21466 (match_operand:SI 1 "const_int_operand" "n")
21467 (const_int 3))]
21468 "TARGET_3DNOW && !TARGET_64BIT"
21469 {
21470 if (INTVAL (operands[1]) == 0)
21471 return "prefetch\t%a0";
21472 else
21473 return "prefetchw\t%a0";
21474 }
21475 [(set_attr "type" "mmx")
21476 (set_attr "memory" "none")])
21477
21478 (define_insn "*prefetch_3dnow_rex"
21479 [(prefetch (match_operand:DI 0 "address_operand" "p")
21480 (match_operand:SI 1 "const_int_operand" "n")
21481 (const_int 3))]
21482 "TARGET_3DNOW && TARGET_64BIT"
21483 {
21484 if (INTVAL (operands[1]) == 0)
21485 return "prefetch\t%a0";
21486 else
21487 return "prefetchw\t%a0";
21488 }
21489 [(set_attr "type" "mmx")
21490 (set_attr "memory" "none")])
21491
21492 ;; SSE2 support
21493
21494 (define_insn "addv2df3"
21495 [(set (match_operand:V2DF 0 "register_operand" "=x")
21496 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21497 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21498 "TARGET_SSE2"
21499 "addpd\t{%2, %0|%0, %2}"
21500 [(set_attr "type" "sseadd")
21501 (set_attr "mode" "V2DF")])
21502
21503 (define_insn "vmaddv2df3"
21504 [(set (match_operand:V2DF 0 "register_operand" "=x")
21505 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21506 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21507 (match_dup 1)
21508 (const_int 1)))]
21509 "TARGET_SSE2"
21510 "addsd\t{%2, %0|%0, %2}"
21511 [(set_attr "type" "sseadd")
21512 (set_attr "mode" "DF")])
21513
21514 (define_insn "subv2df3"
21515 [(set (match_operand:V2DF 0 "register_operand" "=x")
21516 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21517 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21518 "TARGET_SSE2"
21519 "subpd\t{%2, %0|%0, %2}"
21520 [(set_attr "type" "sseadd")
21521 (set_attr "mode" "V2DF")])
21522
21523 (define_insn "vmsubv2df3"
21524 [(set (match_operand:V2DF 0 "register_operand" "=x")
21525 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21526 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21527 (match_dup 1)
21528 (const_int 1)))]
21529 "TARGET_SSE2"
21530 "subsd\t{%2, %0|%0, %2}"
21531 [(set_attr "type" "sseadd")
21532 (set_attr "mode" "DF")])
21533
21534 (define_insn "mulv2df3"
21535 [(set (match_operand:V2DF 0 "register_operand" "=x")
21536 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21537 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21538 "TARGET_SSE2"
21539 "mulpd\t{%2, %0|%0, %2}"
21540 [(set_attr "type" "ssemul")
21541 (set_attr "mode" "V2DF")])
21542
21543 (define_insn "vmmulv2df3"
21544 [(set (match_operand:V2DF 0 "register_operand" "=x")
21545 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21546 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21547 (match_dup 1)
21548 (const_int 1)))]
21549 "TARGET_SSE2"
21550 "mulsd\t{%2, %0|%0, %2}"
21551 [(set_attr "type" "ssemul")
21552 (set_attr "mode" "DF")])
21553
21554 (define_insn "divv2df3"
21555 [(set (match_operand:V2DF 0 "register_operand" "=x")
21556 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21557 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21558 "TARGET_SSE2"
21559 "divpd\t{%2, %0|%0, %2}"
21560 [(set_attr "type" "ssediv")
21561 (set_attr "mode" "V2DF")])
21562
21563 (define_insn "vmdivv2df3"
21564 [(set (match_operand:V2DF 0 "register_operand" "=x")
21565 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21566 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21567 (match_dup 1)
21568 (const_int 1)))]
21569 "TARGET_SSE2"
21570 "divsd\t{%2, %0|%0, %2}"
21571 [(set_attr "type" "ssediv")
21572 (set_attr "mode" "DF")])
21573
21574 ;; SSE min/max
21575
21576 (define_insn "smaxv2df3"
21577 [(set (match_operand:V2DF 0 "register_operand" "=x")
21578 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21579 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21580 "TARGET_SSE2"
21581 "maxpd\t{%2, %0|%0, %2}"
21582 [(set_attr "type" "sseadd")
21583 (set_attr "mode" "V2DF")])
21584
21585 (define_insn "vmsmaxv2df3"
21586 [(set (match_operand:V2DF 0 "register_operand" "=x")
21587 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21588 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21589 (match_dup 1)
21590 (const_int 1)))]
21591 "TARGET_SSE2"
21592 "maxsd\t{%2, %0|%0, %2}"
21593 [(set_attr "type" "sseadd")
21594 (set_attr "mode" "DF")])
21595
21596 (define_insn "sminv2df3"
21597 [(set (match_operand:V2DF 0 "register_operand" "=x")
21598 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21599 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21600 "TARGET_SSE2"
21601 "minpd\t{%2, %0|%0, %2}"
21602 [(set_attr "type" "sseadd")
21603 (set_attr "mode" "V2DF")])
21604
21605 (define_insn "vmsminv2df3"
21606 [(set (match_operand:V2DF 0 "register_operand" "=x")
21607 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21608 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21609 (match_dup 1)
21610 (const_int 1)))]
21611 "TARGET_SSE2"
21612 "minsd\t{%2, %0|%0, %2}"
21613 [(set_attr "type" "sseadd")
21614 (set_attr "mode" "DF")])
21615 ;; SSE2 square root. There doesn't appear to be an extension for the
21616 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21617
21618 (define_insn "sqrtv2df2"
21619 [(set (match_operand:V2DF 0 "register_operand" "=x")
21620 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21621 "TARGET_SSE2"
21622 "sqrtpd\t{%1, %0|%0, %1}"
21623 [(set_attr "type" "sse")
21624 (set_attr "mode" "V2DF")])
21625
21626 (define_insn "vmsqrtv2df2"
21627 [(set (match_operand:V2DF 0 "register_operand" "=x")
21628 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21629 (match_operand:V2DF 2 "register_operand" "0")
21630 (const_int 1)))]
21631 "TARGET_SSE2"
21632 "sqrtsd\t{%1, %0|%0, %1}"
21633 [(set_attr "type" "sse")
21634 (set_attr "mode" "SF")])
21635
21636 ;; SSE mask-generating compares
21637
21638 (define_insn "maskcmpv2df3"
21639 [(set (match_operand:V2DI 0 "register_operand" "=x")
21640 (match_operator:V2DI 3 "sse_comparison_operator"
21641 [(match_operand:V2DF 1 "register_operand" "0")
21642 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21643 "TARGET_SSE2"
21644 "cmp%D3pd\t{%2, %0|%0, %2}"
21645 [(set_attr "type" "ssecmp")
21646 (set_attr "mode" "V2DF")])
21647
21648 (define_insn "maskncmpv2df3"
21649 [(set (match_operand:V2DI 0 "register_operand" "=x")
21650 (not:V2DI
21651 (match_operator:V2DI 3 "sse_comparison_operator"
21652 [(match_operand:V2DF 1 "register_operand" "0")
21653 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21654 "TARGET_SSE2"
21655 {
21656 if (GET_CODE (operands[3]) == UNORDERED)
21657 return "cmpordps\t{%2, %0|%0, %2}";
21658 else
21659 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21660 }
21661 [(set_attr "type" "ssecmp")
21662 (set_attr "mode" "V2DF")])
21663
21664 (define_insn "vmmaskcmpv2df3"
21665 [(set (match_operand:V2DI 0 "register_operand" "=x")
21666 (vec_merge:V2DI
21667 (match_operator:V2DI 3 "sse_comparison_operator"
21668 [(match_operand:V2DF 1 "register_operand" "0")
21669 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21670 (subreg:V2DI (match_dup 1) 0)
21671 (const_int 1)))]
21672 "TARGET_SSE2"
21673 "cmp%D3sd\t{%2, %0|%0, %2}"
21674 [(set_attr "type" "ssecmp")
21675 (set_attr "mode" "DF")])
21676
21677 (define_insn "vmmaskncmpv2df3"
21678 [(set (match_operand:V2DI 0 "register_operand" "=x")
21679 (vec_merge:V2DI
21680 (not:V2DI
21681 (match_operator:V2DI 3 "sse_comparison_operator"
21682 [(match_operand:V2DF 1 "register_operand" "0")
21683 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21684 (subreg:V2DI (match_dup 1) 0)
21685 (const_int 1)))]
21686 "TARGET_SSE2"
21687 {
21688 if (GET_CODE (operands[3]) == UNORDERED)
21689 return "cmpordsd\t{%2, %0|%0, %2}";
21690 else
21691 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21692 }
21693 [(set_attr "type" "ssecmp")
21694 (set_attr "mode" "DF")])
21695
21696 (define_insn "sse2_comi"
21697 [(set (reg:CCFP 17)
21698 (compare:CCFP (vec_select:DF
21699 (match_operand:V2DF 0 "register_operand" "x")
21700 (parallel [(const_int 0)]))
21701 (vec_select:DF
21702 (match_operand:V2DF 1 "register_operand" "x")
21703 (parallel [(const_int 0)]))))]
21704 "TARGET_SSE2"
21705 "comisd\t{%1, %0|%0, %1}"
21706 [(set_attr "type" "ssecomi")
21707 (set_attr "mode" "DF")])
21708
21709 (define_insn "sse2_ucomi"
21710 [(set (reg:CCFPU 17)
21711 (compare:CCFPU (vec_select:DF
21712 (match_operand:V2DF 0 "register_operand" "x")
21713 (parallel [(const_int 0)]))
21714 (vec_select:DF
21715 (match_operand:V2DF 1 "register_operand" "x")
21716 (parallel [(const_int 0)]))))]
21717 "TARGET_SSE2"
21718 "ucomisd\t{%1, %0|%0, %1}"
21719 [(set_attr "type" "ssecomi")
21720 (set_attr "mode" "DF")])
21721
21722 ;; SSE Strange Moves.
21723
21724 (define_insn "sse2_movmskpd"
21725 [(set (match_operand:SI 0 "register_operand" "=r")
21726 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21727 UNSPEC_MOVMSK))]
21728 "TARGET_SSE2"
21729 "movmskpd\t{%1, %0|%0, %1}"
21730 [(set_attr "type" "ssecvt")
21731 (set_attr "mode" "V2DF")])
21732
21733 (define_insn "sse2_pmovmskb"
21734 [(set (match_operand:SI 0 "register_operand" "=r")
21735 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21736 UNSPEC_MOVMSK))]
21737 "TARGET_SSE2"
21738 "pmovmskb\t{%1, %0|%0, %1}"
21739 [(set_attr "type" "ssecvt")
21740 (set_attr "mode" "V2DF")])
21741
21742 (define_insn "sse2_maskmovdqu"
21743 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21744 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21745 (match_operand:V16QI 2 "register_operand" "x")]
21746 UNSPEC_MASKMOV))]
21747 "TARGET_SSE2"
21748 ;; @@@ check ordering of operands in intel/nonintel syntax
21749 "maskmovdqu\t{%2, %1|%1, %2}"
21750 [(set_attr "type" "ssecvt")
21751 (set_attr "mode" "TI")])
21752
21753 (define_insn "sse2_maskmovdqu_rex64"
21754 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21755 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21756 (match_operand:V16QI 2 "register_operand" "x")]
21757 UNSPEC_MASKMOV))]
21758 "TARGET_SSE2"
21759 ;; @@@ check ordering of operands in intel/nonintel syntax
21760 "maskmovdqu\t{%2, %1|%1, %2}"
21761 [(set_attr "type" "ssecvt")
21762 (set_attr "mode" "TI")])
21763
21764 (define_insn "sse2_movntv2df"
21765 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21766 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21767 UNSPEC_MOVNT))]
21768 "TARGET_SSE2"
21769 "movntpd\t{%1, %0|%0, %1}"
21770 [(set_attr "type" "ssecvt")
21771 (set_attr "mode" "V2DF")])
21772
21773 (define_insn "sse2_movntv2di"
21774 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21775 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21776 UNSPEC_MOVNT))]
21777 "TARGET_SSE2"
21778 "movntdq\t{%1, %0|%0, %1}"
21779 [(set_attr "type" "ssecvt")
21780 (set_attr "mode" "TI")])
21781
21782 (define_insn "sse2_movntsi"
21783 [(set (match_operand:SI 0 "memory_operand" "=m")
21784 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21785 UNSPEC_MOVNT))]
21786 "TARGET_SSE2"
21787 "movnti\t{%1, %0|%0, %1}"
21788 [(set_attr "type" "ssecvt")
21789 (set_attr "mode" "V2DF")])
21790
21791 ;; SSE <-> integer/MMX conversions
21792
21793 ;; Conversions between SI and SF
21794
21795 (define_insn "cvtdq2ps"
21796 [(set (match_operand:V4SF 0 "register_operand" "=x")
21797 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21798 "TARGET_SSE2"
21799 "cvtdq2ps\t{%1, %0|%0, %1}"
21800 [(set_attr "type" "ssecvt")
21801 (set_attr "mode" "V2DF")])
21802
21803 (define_insn "cvtps2dq"
21804 [(set (match_operand:V4SI 0 "register_operand" "=x")
21805 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21806 "TARGET_SSE2"
21807 "cvtps2dq\t{%1, %0|%0, %1}"
21808 [(set_attr "type" "ssecvt")
21809 (set_attr "mode" "TI")])
21810
21811 (define_insn "cvttps2dq"
21812 [(set (match_operand:V4SI 0 "register_operand" "=x")
21813 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21814 UNSPEC_FIX))]
21815 "TARGET_SSE2"
21816 "cvttps2dq\t{%1, %0|%0, %1}"
21817 [(set_attr "type" "ssecvt")
21818 (set_attr "mode" "TI")])
21819
21820 ;; Conversions between SI and DF
21821
21822 (define_insn "cvtdq2pd"
21823 [(set (match_operand:V2DF 0 "register_operand" "=x")
21824 (float:V2DF (vec_select:V2SI
21825 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21826 (parallel
21827 [(const_int 0)
21828 (const_int 1)]))))]
21829 "TARGET_SSE2"
21830 "cvtdq2pd\t{%1, %0|%0, %1}"
21831 [(set_attr "type" "ssecvt")
21832 (set_attr "mode" "V2DF")])
21833
21834 (define_insn "cvtpd2dq"
21835 [(set (match_operand:V4SI 0 "register_operand" "=x")
21836 (vec_concat:V4SI
21837 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21838 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21839 "TARGET_SSE2"
21840 "cvtpd2dq\t{%1, %0|%0, %1}"
21841 [(set_attr "type" "ssecvt")
21842 (set_attr "mode" "TI")])
21843
21844 (define_insn "cvttpd2dq"
21845 [(set (match_operand:V4SI 0 "register_operand" "=x")
21846 (vec_concat:V4SI
21847 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21848 UNSPEC_FIX)
21849 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21850 "TARGET_SSE2"
21851 "cvttpd2dq\t{%1, %0|%0, %1}"
21852 [(set_attr "type" "ssecvt")
21853 (set_attr "mode" "TI")])
21854
21855 (define_insn "cvtpd2pi"
21856 [(set (match_operand:V2SI 0 "register_operand" "=y")
21857 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21858 "TARGET_SSE2"
21859 "cvtpd2pi\t{%1, %0|%0, %1}"
21860 [(set_attr "type" "ssecvt")
21861 (set_attr "mode" "TI")])
21862
21863 (define_insn "cvttpd2pi"
21864 [(set (match_operand:V2SI 0 "register_operand" "=y")
21865 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21866 UNSPEC_FIX))]
21867 "TARGET_SSE2"
21868 "cvttpd2pi\t{%1, %0|%0, %1}"
21869 [(set_attr "type" "ssecvt")
21870 (set_attr "mode" "TI")])
21871
21872 (define_insn "cvtpi2pd"
21873 [(set (match_operand:V2DF 0 "register_operand" "=x")
21874 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21875 "TARGET_SSE2"
21876 "cvtpi2pd\t{%1, %0|%0, %1}"
21877 [(set_attr "type" "ssecvt")
21878 (set_attr "mode" "TI")])
21879
21880 ;; Conversions between SI and DF
21881
21882 (define_insn "cvtsd2si"
21883 [(set (match_operand:SI 0 "register_operand" "=r")
21884 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
21885 (parallel [(const_int 0)]))))]
21886 "TARGET_SSE2"
21887 "cvtsd2si\t{%1, %0|%0, %1}"
21888 [(set_attr "type" "sseicvt")
21889 (set_attr "mode" "SI")])
21890
21891 (define_insn "cvtsd2siq"
21892 [(set (match_operand:DI 0 "register_operand" "=r")
21893 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
21894 (parallel [(const_int 0)]))))]
21895 "TARGET_SSE2 && TARGET_64BIT"
21896 "cvtsd2siq\t{%1, %0|%0, %1}"
21897 [(set_attr "type" "sseicvt")
21898 (set_attr "mode" "SI")])
21899
21900 (define_insn "cvttsd2si"
21901 [(set (match_operand:SI 0 "register_operand" "=r,r")
21902 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21903 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21904 "TARGET_SSE2"
21905 "cvttsd2si\t{%1, %0|%0, %1}"
21906 [(set_attr "type" "sseicvt")
21907 (set_attr "mode" "SI")
21908 (set_attr "athlon_decode" "double,vector")])
21909
21910 (define_insn "cvttsd2siq"
21911 [(set (match_operand:DI 0 "register_operand" "=r,r")
21912 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21913 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21914 "TARGET_SSE2 && TARGET_64BIT"
21915 "cvttsd2siq\t{%1, %0|%0, %1}"
21916 [(set_attr "type" "sseicvt")
21917 (set_attr "mode" "DI")
21918 (set_attr "athlon_decode" "double,vector")])
21919
21920 (define_insn "cvtsi2sd"
21921 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21922 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21923 (vec_duplicate:V2DF
21924 (float:DF
21925 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21926 (const_int 2)))]
21927 "TARGET_SSE2"
21928 "cvtsi2sd\t{%2, %0|%0, %2}"
21929 [(set_attr "type" "sseicvt")
21930 (set_attr "mode" "DF")
21931 (set_attr "athlon_decode" "double,direct")])
21932
21933 (define_insn "cvtsi2sdq"
21934 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21935 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21936 (vec_duplicate:V2DF
21937 (float:DF
21938 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21939 (const_int 2)))]
21940 "TARGET_SSE2 && TARGET_64BIT"
21941 "cvtsi2sdq\t{%2, %0|%0, %2}"
21942 [(set_attr "type" "sseicvt")
21943 (set_attr "mode" "DF")
21944 (set_attr "athlon_decode" "double,direct")])
21945
21946 ;; Conversions between SF and DF
21947
21948 (define_insn "cvtsd2ss"
21949 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21950 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21951 (vec_duplicate:V4SF
21952 (float_truncate:V2SF
21953 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21954 (const_int 14)))]
21955 "TARGET_SSE2"
21956 "cvtsd2ss\t{%2, %0|%0, %2}"
21957 [(set_attr "type" "ssecvt")
21958 (set_attr "athlon_decode" "vector,double")
21959 (set_attr "mode" "SF")])
21960
21961 (define_insn "cvtss2sd"
21962 [(set (match_operand:V2DF 0 "register_operand" "=x")
21963 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21964 (float_extend:V2DF
21965 (vec_select:V2SF
21966 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21967 (parallel [(const_int 0)
21968 (const_int 1)])))
21969 (const_int 2)))]
21970 "TARGET_SSE2"
21971 "cvtss2sd\t{%2, %0|%0, %2}"
21972 [(set_attr "type" "ssecvt")
21973 (set_attr "mode" "DF")])
21974
21975 (define_insn "cvtpd2ps"
21976 [(set (match_operand:V4SF 0 "register_operand" "=x")
21977 (subreg:V4SF
21978 (vec_concat:V4SI
21979 (subreg:V2SI (float_truncate:V2SF
21980 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21981 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21982 "TARGET_SSE2"
21983 "cvtpd2ps\t{%1, %0|%0, %1}"
21984 [(set_attr "type" "ssecvt")
21985 (set_attr "mode" "V4SF")])
21986
21987 (define_insn "cvtps2pd"
21988 [(set (match_operand:V2DF 0 "register_operand" "=x")
21989 (float_extend:V2DF
21990 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21991 (parallel [(const_int 0)
21992 (const_int 1)]))))]
21993 "TARGET_SSE2"
21994 "cvtps2pd\t{%1, %0|%0, %1}"
21995 [(set_attr "type" "ssecvt")
21996 (set_attr "mode" "V2DF")])
21997
21998 ;; SSE2 variants of MMX insns
21999
22000 ;; MMX arithmetic
22001
22002 (define_insn "addv16qi3"
22003 [(set (match_operand:V16QI 0 "register_operand" "=x")
22004 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22005 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22006 "TARGET_SSE2"
22007 "paddb\t{%2, %0|%0, %2}"
22008 [(set_attr "type" "sseiadd")
22009 (set_attr "mode" "TI")])
22010
22011 (define_insn "addv8hi3"
22012 [(set (match_operand:V8HI 0 "register_operand" "=x")
22013 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22014 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22015 "TARGET_SSE2"
22016 "paddw\t{%2, %0|%0, %2}"
22017 [(set_attr "type" "sseiadd")
22018 (set_attr "mode" "TI")])
22019
22020 (define_insn "addv4si3"
22021 [(set (match_operand:V4SI 0 "register_operand" "=x")
22022 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22023 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22024 "TARGET_SSE2"
22025 "paddd\t{%2, %0|%0, %2}"
22026 [(set_attr "type" "sseiadd")
22027 (set_attr "mode" "TI")])
22028
22029 (define_insn "addv2di3"
22030 [(set (match_operand:V2DI 0 "register_operand" "=x")
22031 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22032 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22033 "TARGET_SSE2"
22034 "paddq\t{%2, %0|%0, %2}"
22035 [(set_attr "type" "sseiadd")
22036 (set_attr "mode" "TI")])
22037
22038 (define_insn "ssaddv16qi3"
22039 [(set (match_operand:V16QI 0 "register_operand" "=x")
22040 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22041 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22042 "TARGET_SSE2"
22043 "paddsb\t{%2, %0|%0, %2}"
22044 [(set_attr "type" "sseiadd")
22045 (set_attr "mode" "TI")])
22046
22047 (define_insn "ssaddv8hi3"
22048 [(set (match_operand:V8HI 0 "register_operand" "=x")
22049 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22050 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22051 "TARGET_SSE2"
22052 "paddsw\t{%2, %0|%0, %2}"
22053 [(set_attr "type" "sseiadd")
22054 (set_attr "mode" "TI")])
22055
22056 (define_insn "usaddv16qi3"
22057 [(set (match_operand:V16QI 0 "register_operand" "=x")
22058 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22059 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22060 "TARGET_SSE2"
22061 "paddusb\t{%2, %0|%0, %2}"
22062 [(set_attr "type" "sseiadd")
22063 (set_attr "mode" "TI")])
22064
22065 (define_insn "usaddv8hi3"
22066 [(set (match_operand:V8HI 0 "register_operand" "=x")
22067 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22068 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22069 "TARGET_SSE2"
22070 "paddusw\t{%2, %0|%0, %2}"
22071 [(set_attr "type" "sseiadd")
22072 (set_attr "mode" "TI")])
22073
22074 (define_insn "subv16qi3"
22075 [(set (match_operand:V16QI 0 "register_operand" "=x")
22076 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22077 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22078 "TARGET_SSE2"
22079 "psubb\t{%2, %0|%0, %2}"
22080 [(set_attr "type" "sseiadd")
22081 (set_attr "mode" "TI")])
22082
22083 (define_insn "subv8hi3"
22084 [(set (match_operand:V8HI 0 "register_operand" "=x")
22085 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22086 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22087 "TARGET_SSE2"
22088 "psubw\t{%2, %0|%0, %2}"
22089 [(set_attr "type" "sseiadd")
22090 (set_attr "mode" "TI")])
22091
22092 (define_insn "subv4si3"
22093 [(set (match_operand:V4SI 0 "register_operand" "=x")
22094 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22095 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22096 "TARGET_SSE2"
22097 "psubd\t{%2, %0|%0, %2}"
22098 [(set_attr "type" "sseiadd")
22099 (set_attr "mode" "TI")])
22100
22101 (define_insn "subv2di3"
22102 [(set (match_operand:V2DI 0 "register_operand" "=x")
22103 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22104 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22105 "TARGET_SSE2"
22106 "psubq\t{%2, %0|%0, %2}"
22107 [(set_attr "type" "sseiadd")
22108 (set_attr "mode" "TI")])
22109
22110 (define_insn "sssubv16qi3"
22111 [(set (match_operand:V16QI 0 "register_operand" "=x")
22112 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22113 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22114 "TARGET_SSE2"
22115 "psubsb\t{%2, %0|%0, %2}"
22116 [(set_attr "type" "sseiadd")
22117 (set_attr "mode" "TI")])
22118
22119 (define_insn "sssubv8hi3"
22120 [(set (match_operand:V8HI 0 "register_operand" "=x")
22121 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22122 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22123 "TARGET_SSE2"
22124 "psubsw\t{%2, %0|%0, %2}"
22125 [(set_attr "type" "sseiadd")
22126 (set_attr "mode" "TI")])
22127
22128 (define_insn "ussubv16qi3"
22129 [(set (match_operand:V16QI 0 "register_operand" "=x")
22130 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22131 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22132 "TARGET_SSE2"
22133 "psubusb\t{%2, %0|%0, %2}"
22134 [(set_attr "type" "sseiadd")
22135 (set_attr "mode" "TI")])
22136
22137 (define_insn "ussubv8hi3"
22138 [(set (match_operand:V8HI 0 "register_operand" "=x")
22139 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22140 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22141 "TARGET_SSE2"
22142 "psubusw\t{%2, %0|%0, %2}"
22143 [(set_attr "type" "sseiadd")
22144 (set_attr "mode" "TI")])
22145
22146 (define_insn "mulv8hi3"
22147 [(set (match_operand:V8HI 0 "register_operand" "=x")
22148 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22149 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22150 "TARGET_SSE2"
22151 "pmullw\t{%2, %0|%0, %2}"
22152 [(set_attr "type" "sseimul")
22153 (set_attr "mode" "TI")])
22154
22155 (define_insn "smulv8hi3_highpart"
22156 [(set (match_operand:V8HI 0 "register_operand" "=x")
22157 (truncate:V8HI
22158 (lshiftrt:V8SI
22159 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22160 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22161 (const_int 16))))]
22162 "TARGET_SSE2"
22163 "pmulhw\t{%2, %0|%0, %2}"
22164 [(set_attr "type" "sseimul")
22165 (set_attr "mode" "TI")])
22166
22167 (define_insn "umulv8hi3_highpart"
22168 [(set (match_operand:V8HI 0 "register_operand" "=x")
22169 (truncate:V8HI
22170 (lshiftrt:V8SI
22171 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22172 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22173 (const_int 16))))]
22174 "TARGET_SSE2"
22175 "pmulhuw\t{%2, %0|%0, %2}"
22176 [(set_attr "type" "sseimul")
22177 (set_attr "mode" "TI")])
22178
22179 (define_insn "sse2_umulsidi3"
22180 [(set (match_operand:DI 0 "register_operand" "=y")
22181 (mult:DI (zero_extend:DI (vec_select:SI
22182 (match_operand:V2SI 1 "register_operand" "0")
22183 (parallel [(const_int 0)])))
22184 (zero_extend:DI (vec_select:SI
22185 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22186 (parallel [(const_int 0)])))))]
22187 "TARGET_SSE2"
22188 "pmuludq\t{%2, %0|%0, %2}"
22189 [(set_attr "type" "sseimul")
22190 (set_attr "mode" "TI")])
22191
22192 (define_insn "sse2_umulv2siv2di3"
22193 [(set (match_operand:V2DI 0 "register_operand" "=x")
22194 (mult:V2DI (zero_extend:V2DI
22195 (vec_select:V2SI
22196 (match_operand:V4SI 1 "register_operand" "0")
22197 (parallel [(const_int 0) (const_int 2)])))
22198 (zero_extend:V2DI
22199 (vec_select:V2SI
22200 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22201 (parallel [(const_int 0) (const_int 2)])))))]
22202 "TARGET_SSE2"
22203 "pmuludq\t{%2, %0|%0, %2}"
22204 [(set_attr "type" "sseimul")
22205 (set_attr "mode" "TI")])
22206
22207 (define_insn "sse2_pmaddwd"
22208 [(set (match_operand:V4SI 0 "register_operand" "=x")
22209 (plus:V4SI
22210 (mult:V4SI
22211 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22212 (parallel [(const_int 0)
22213 (const_int 2)
22214 (const_int 4)
22215 (const_int 6)])))
22216 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22217 (parallel [(const_int 0)
22218 (const_int 2)
22219 (const_int 4)
22220 (const_int 6)]))))
22221 (mult:V4SI
22222 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22223 (parallel [(const_int 1)
22224 (const_int 3)
22225 (const_int 5)
22226 (const_int 7)])))
22227 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22228 (parallel [(const_int 1)
22229 (const_int 3)
22230 (const_int 5)
22231 (const_int 7)]))))))]
22232 "TARGET_SSE2"
22233 "pmaddwd\t{%2, %0|%0, %2}"
22234 [(set_attr "type" "sseiadd")
22235 (set_attr "mode" "TI")])
22236
22237 ;; Same as pxor, but don't show input operands so that we don't think
22238 ;; they are live.
22239 (define_insn "sse2_clrti"
22240 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22241 "TARGET_SSE2"
22242 {
22243 if (get_attr_mode (insn) == MODE_TI)
22244 return "pxor\t%0, %0";
22245 else
22246 return "xorps\t%0, %0";
22247 }
22248 [(set_attr "type" "ssemov")
22249 (set_attr "memory" "none")
22250 (set (attr "mode")
22251 (if_then_else
22252 (ne (symbol_ref "optimize_size")
22253 (const_int 0))
22254 (const_string "V4SF")
22255 (const_string "TI")))])
22256
22257 ;; MMX unsigned averages/sum of absolute differences
22258
22259 (define_insn "sse2_uavgv16qi3"
22260 [(set (match_operand:V16QI 0 "register_operand" "=x")
22261 (ashiftrt:V16QI
22262 (plus:V16QI (plus:V16QI
22263 (match_operand:V16QI 1 "register_operand" "0")
22264 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22265 (const_vector:V16QI [(const_int 1) (const_int 1)
22266 (const_int 1) (const_int 1)
22267 (const_int 1) (const_int 1)
22268 (const_int 1) (const_int 1)
22269 (const_int 1) (const_int 1)
22270 (const_int 1) (const_int 1)
22271 (const_int 1) (const_int 1)
22272 (const_int 1) (const_int 1)]))
22273 (const_int 1)))]
22274 "TARGET_SSE2"
22275 "pavgb\t{%2, %0|%0, %2}"
22276 [(set_attr "type" "sseiadd")
22277 (set_attr "mode" "TI")])
22278
22279 (define_insn "sse2_uavgv8hi3"
22280 [(set (match_operand:V8HI 0 "register_operand" "=x")
22281 (ashiftrt:V8HI
22282 (plus:V8HI (plus:V8HI
22283 (match_operand:V8HI 1 "register_operand" "0")
22284 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22285 (const_vector:V8HI [(const_int 1) (const_int 1)
22286 (const_int 1) (const_int 1)
22287 (const_int 1) (const_int 1)
22288 (const_int 1) (const_int 1)]))
22289 (const_int 1)))]
22290 "TARGET_SSE2"
22291 "pavgw\t{%2, %0|%0, %2}"
22292 [(set_attr "type" "sseiadd")
22293 (set_attr "mode" "TI")])
22294
22295 ;; @@@ this isn't the right representation.
22296 (define_insn "sse2_psadbw"
22297 [(set (match_operand:V2DI 0 "register_operand" "=x")
22298 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22299 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22300 UNSPEC_PSADBW))]
22301 "TARGET_SSE2"
22302 "psadbw\t{%2, %0|%0, %2}"
22303 [(set_attr "type" "sseiadd")
22304 (set_attr "mode" "TI")])
22305
22306
22307 ;; MMX insert/extract/shuffle
22308
22309 (define_insn "sse2_pinsrw"
22310 [(set (match_operand:V8HI 0 "register_operand" "=x")
22311 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22312 (vec_duplicate:V8HI
22313 (truncate:HI
22314 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22315 (match_operand:SI 3 "immediate_operand" "i")))]
22316 "TARGET_SSE2"
22317 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22318 [(set_attr "type" "ssecvt")
22319 (set_attr "mode" "TI")])
22320
22321 (define_insn "sse2_pextrw"
22322 [(set (match_operand:SI 0 "register_operand" "=r")
22323 (zero_extend:SI
22324 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22325 (parallel
22326 [(match_operand:SI 2 "immediate_operand" "i")]))))]
22327 "TARGET_SSE2"
22328 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22329 [(set_attr "type" "ssecvt")
22330 (set_attr "mode" "TI")])
22331
22332 (define_insn "sse2_pshufd"
22333 [(set (match_operand:V4SI 0 "register_operand" "=x")
22334 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22335 (match_operand:SI 2 "immediate_operand" "i")]
22336 UNSPEC_SHUFFLE))]
22337 "TARGET_SSE2"
22338 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22339 [(set_attr "type" "ssecvt")
22340 (set_attr "mode" "TI")])
22341
22342 (define_insn "sse2_pshuflw"
22343 [(set (match_operand:V8HI 0 "register_operand" "=x")
22344 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22345 (match_operand:SI 2 "immediate_operand" "i")]
22346 UNSPEC_PSHUFLW))]
22347 "TARGET_SSE2"
22348 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22349 [(set_attr "type" "ssecvt")
22350 (set_attr "mode" "TI")])
22351
22352 (define_insn "sse2_pshufhw"
22353 [(set (match_operand:V8HI 0 "register_operand" "=x")
22354 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22355 (match_operand:SI 2 "immediate_operand" "i")]
22356 UNSPEC_PSHUFHW))]
22357 "TARGET_SSE2"
22358 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22359 [(set_attr "type" "ssecvt")
22360 (set_attr "mode" "TI")])
22361
22362 ;; MMX mask-generating comparisons
22363
22364 (define_insn "eqv16qi3"
22365 [(set (match_operand:V16QI 0 "register_operand" "=x")
22366 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22367 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22368 "TARGET_SSE2"
22369 "pcmpeqb\t{%2, %0|%0, %2}"
22370 [(set_attr "type" "ssecmp")
22371 (set_attr "mode" "TI")])
22372
22373 (define_insn "eqv8hi3"
22374 [(set (match_operand:V8HI 0 "register_operand" "=x")
22375 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22376 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22377 "TARGET_SSE2"
22378 "pcmpeqw\t{%2, %0|%0, %2}"
22379 [(set_attr "type" "ssecmp")
22380 (set_attr "mode" "TI")])
22381
22382 (define_insn "eqv4si3"
22383 [(set (match_operand:V4SI 0 "register_operand" "=x")
22384 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22385 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22386 "TARGET_SSE2"
22387 "pcmpeqd\t{%2, %0|%0, %2}"
22388 [(set_attr "type" "ssecmp")
22389 (set_attr "mode" "TI")])
22390
22391 (define_insn "gtv16qi3"
22392 [(set (match_operand:V16QI 0 "register_operand" "=x")
22393 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22394 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22395 "TARGET_SSE2"
22396 "pcmpgtb\t{%2, %0|%0, %2}"
22397 [(set_attr "type" "ssecmp")
22398 (set_attr "mode" "TI")])
22399
22400 (define_insn "gtv8hi3"
22401 [(set (match_operand:V8HI 0 "register_operand" "=x")
22402 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22403 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22404 "TARGET_SSE2"
22405 "pcmpgtw\t{%2, %0|%0, %2}"
22406 [(set_attr "type" "ssecmp")
22407 (set_attr "mode" "TI")])
22408
22409 (define_insn "gtv4si3"
22410 [(set (match_operand:V4SI 0 "register_operand" "=x")
22411 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22412 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22413 "TARGET_SSE2"
22414 "pcmpgtd\t{%2, %0|%0, %2}"
22415 [(set_attr "type" "ssecmp")
22416 (set_attr "mode" "TI")])
22417
22418
22419 ;; MMX max/min insns
22420
22421 (define_insn "umaxv16qi3"
22422 [(set (match_operand:V16QI 0 "register_operand" "=x")
22423 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22424 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22425 "TARGET_SSE2"
22426 "pmaxub\t{%2, %0|%0, %2}"
22427 [(set_attr "type" "sseiadd")
22428 (set_attr "mode" "TI")])
22429
22430 (define_insn "smaxv8hi3"
22431 [(set (match_operand:V8HI 0 "register_operand" "=x")
22432 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22433 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22434 "TARGET_SSE2"
22435 "pmaxsw\t{%2, %0|%0, %2}"
22436 [(set_attr "type" "sseiadd")
22437 (set_attr "mode" "TI")])
22438
22439 (define_insn "uminv16qi3"
22440 [(set (match_operand:V16QI 0 "register_operand" "=x")
22441 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22442 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22443 "TARGET_SSE2"
22444 "pminub\t{%2, %0|%0, %2}"
22445 [(set_attr "type" "sseiadd")
22446 (set_attr "mode" "TI")])
22447
22448 (define_insn "sminv8hi3"
22449 [(set (match_operand:V8HI 0 "register_operand" "=x")
22450 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22451 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22452 "TARGET_SSE2"
22453 "pminsw\t{%2, %0|%0, %2}"
22454 [(set_attr "type" "sseiadd")
22455 (set_attr "mode" "TI")])
22456
22457
22458 ;; MMX shifts
22459
22460 (define_insn "ashrv8hi3"
22461 [(set (match_operand:V8HI 0 "register_operand" "=x")
22462 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22463 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22464 "TARGET_SSE2"
22465 "psraw\t{%2, %0|%0, %2}"
22466 [(set_attr "type" "sseishft")
22467 (set_attr "mode" "TI")])
22468
22469 (define_insn "ashrv4si3"
22470 [(set (match_operand:V4SI 0 "register_operand" "=x")
22471 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22472 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22473 "TARGET_SSE2"
22474 "psrad\t{%2, %0|%0, %2}"
22475 [(set_attr "type" "sseishft")
22476 (set_attr "mode" "TI")])
22477
22478 (define_insn "lshrv8hi3"
22479 [(set (match_operand:V8HI 0 "register_operand" "=x")
22480 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22481 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22482 "TARGET_SSE2"
22483 "psrlw\t{%2, %0|%0, %2}"
22484 [(set_attr "type" "sseishft")
22485 (set_attr "mode" "TI")])
22486
22487 (define_insn "lshrv4si3"
22488 [(set (match_operand:V4SI 0 "register_operand" "=x")
22489 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22490 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22491 "TARGET_SSE2"
22492 "psrld\t{%2, %0|%0, %2}"
22493 [(set_attr "type" "sseishft")
22494 (set_attr "mode" "TI")])
22495
22496 (define_insn "lshrv2di3"
22497 [(set (match_operand:V2DI 0 "register_operand" "=x")
22498 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22499 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22500 "TARGET_SSE2"
22501 "psrlq\t{%2, %0|%0, %2}"
22502 [(set_attr "type" "sseishft")
22503 (set_attr "mode" "TI")])
22504
22505 (define_insn "ashlv8hi3"
22506 [(set (match_operand:V8HI 0 "register_operand" "=x")
22507 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22508 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22509 "TARGET_SSE2"
22510 "psllw\t{%2, %0|%0, %2}"
22511 [(set_attr "type" "sseishft")
22512 (set_attr "mode" "TI")])
22513
22514 (define_insn "ashlv4si3"
22515 [(set (match_operand:V4SI 0 "register_operand" "=x")
22516 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22517 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22518 "TARGET_SSE2"
22519 "pslld\t{%2, %0|%0, %2}"
22520 [(set_attr "type" "sseishft")
22521 (set_attr "mode" "TI")])
22522
22523 (define_insn "ashlv2di3"
22524 [(set (match_operand:V2DI 0 "register_operand" "=x")
22525 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22526 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22527 "TARGET_SSE2"
22528 "psllq\t{%2, %0|%0, %2}"
22529 [(set_attr "type" "sseishft")
22530 (set_attr "mode" "TI")])
22531
22532 (define_insn "ashrv8hi3_ti"
22533 [(set (match_operand:V8HI 0 "register_operand" "=x")
22534 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22535 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22536 "TARGET_SSE2"
22537 "psraw\t{%2, %0|%0, %2}"
22538 [(set_attr "type" "sseishft")
22539 (set_attr "mode" "TI")])
22540
22541 (define_insn "ashrv4si3_ti"
22542 [(set (match_operand:V4SI 0 "register_operand" "=x")
22543 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22544 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22545 "TARGET_SSE2"
22546 "psrad\t{%2, %0|%0, %2}"
22547 [(set_attr "type" "sseishft")
22548 (set_attr "mode" "TI")])
22549
22550 (define_insn "lshrv8hi3_ti"
22551 [(set (match_operand:V8HI 0 "register_operand" "=x")
22552 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22553 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22554 "TARGET_SSE2"
22555 "psrlw\t{%2, %0|%0, %2}"
22556 [(set_attr "type" "sseishft")
22557 (set_attr "mode" "TI")])
22558
22559 (define_insn "lshrv4si3_ti"
22560 [(set (match_operand:V4SI 0 "register_operand" "=x")
22561 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22562 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22563 "TARGET_SSE2"
22564 "psrld\t{%2, %0|%0, %2}"
22565 [(set_attr "type" "sseishft")
22566 (set_attr "mode" "TI")])
22567
22568 (define_insn "lshrv2di3_ti"
22569 [(set (match_operand:V2DI 0 "register_operand" "=x")
22570 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22571 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22572 "TARGET_SSE2"
22573 "psrlq\t{%2, %0|%0, %2}"
22574 [(set_attr "type" "sseishft")
22575 (set_attr "mode" "TI")])
22576
22577 (define_insn "ashlv8hi3_ti"
22578 [(set (match_operand:V8HI 0 "register_operand" "=x")
22579 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22580 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22581 "TARGET_SSE2"
22582 "psllw\t{%2, %0|%0, %2}"
22583 [(set_attr "type" "sseishft")
22584 (set_attr "mode" "TI")])
22585
22586 (define_insn "ashlv4si3_ti"
22587 [(set (match_operand:V4SI 0 "register_operand" "=x")
22588 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22589 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22590 "TARGET_SSE2"
22591 "pslld\t{%2, %0|%0, %2}"
22592 [(set_attr "type" "sseishft")
22593 (set_attr "mode" "TI")])
22594
22595 (define_insn "ashlv2di3_ti"
22596 [(set (match_operand:V2DI 0 "register_operand" "=x")
22597 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22598 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22599 "TARGET_SSE2"
22600 "psllq\t{%2, %0|%0, %2}"
22601 [(set_attr "type" "sseishft")
22602 (set_attr "mode" "TI")])
22603
22604 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22605 ;; we wouldn't need here it since we never generate TImode arithmetic.
22606
22607 ;; There has to be some kind of prize for the weirdest new instruction...
22608 (define_insn "sse2_ashlti3"
22609 [(set (match_operand:TI 0 "register_operand" "=x")
22610 (unspec:TI
22611 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22612 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22613 (const_int 8)))] UNSPEC_NOP))]
22614 "TARGET_SSE2"
22615 "pslldq\t{%2, %0|%0, %2}"
22616 [(set_attr "type" "sseishft")
22617 (set_attr "mode" "TI")])
22618
22619 (define_insn "sse2_lshrti3"
22620 [(set (match_operand:TI 0 "register_operand" "=x")
22621 (unspec:TI
22622 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22623 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22624 (const_int 8)))] UNSPEC_NOP))]
22625 "TARGET_SSE2"
22626 "psrldq\t{%2, %0|%0, %2}"
22627 [(set_attr "type" "sseishft")
22628 (set_attr "mode" "TI")])
22629
22630 ;; SSE unpack
22631
22632 (define_insn "sse2_unpckhpd"
22633 [(set (match_operand:V2DF 0 "register_operand" "=x")
22634 (vec_concat:V2DF
22635 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22636 (parallel [(const_int 1)]))
22637 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22638 (parallel [(const_int 0)]))))]
22639 "TARGET_SSE2"
22640 "unpckhpd\t{%2, %0|%0, %2}"
22641 [(set_attr "type" "ssecvt")
22642 (set_attr "mode" "TI")])
22643
22644 (define_insn "sse2_unpcklpd"
22645 [(set (match_operand:V2DF 0 "register_operand" "=x")
22646 (vec_concat:V2DF
22647 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22648 (parallel [(const_int 0)]))
22649 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22650 (parallel [(const_int 1)]))))]
22651 "TARGET_SSE2"
22652 "unpcklpd\t{%2, %0|%0, %2}"
22653 [(set_attr "type" "ssecvt")
22654 (set_attr "mode" "TI")])
22655
22656 ;; MMX pack/unpack insns.
22657
22658 (define_insn "sse2_packsswb"
22659 [(set (match_operand:V16QI 0 "register_operand" "=x")
22660 (vec_concat:V16QI
22661 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22662 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22663 "TARGET_SSE2"
22664 "packsswb\t{%2, %0|%0, %2}"
22665 [(set_attr "type" "ssecvt")
22666 (set_attr "mode" "TI")])
22667
22668 (define_insn "sse2_packssdw"
22669 [(set (match_operand:V8HI 0 "register_operand" "=x")
22670 (vec_concat:V8HI
22671 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22672 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22673 "TARGET_SSE2"
22674 "packssdw\t{%2, %0|%0, %2}"
22675 [(set_attr "type" "ssecvt")
22676 (set_attr "mode" "TI")])
22677
22678 (define_insn "sse2_packuswb"
22679 [(set (match_operand:V16QI 0 "register_operand" "=x")
22680 (vec_concat:V16QI
22681 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22682 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22683 "TARGET_SSE2"
22684 "packuswb\t{%2, %0|%0, %2}"
22685 [(set_attr "type" "ssecvt")
22686 (set_attr "mode" "TI")])
22687
22688 (define_insn "sse2_punpckhbw"
22689 [(set (match_operand:V16QI 0 "register_operand" "=x")
22690 (vec_merge:V16QI
22691 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22692 (parallel [(const_int 8) (const_int 0)
22693 (const_int 9) (const_int 1)
22694 (const_int 10) (const_int 2)
22695 (const_int 11) (const_int 3)
22696 (const_int 12) (const_int 4)
22697 (const_int 13) (const_int 5)
22698 (const_int 14) (const_int 6)
22699 (const_int 15) (const_int 7)]))
22700 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22701 (parallel [(const_int 0) (const_int 8)
22702 (const_int 1) (const_int 9)
22703 (const_int 2) (const_int 10)
22704 (const_int 3) (const_int 11)
22705 (const_int 4) (const_int 12)
22706 (const_int 5) (const_int 13)
22707 (const_int 6) (const_int 14)
22708 (const_int 7) (const_int 15)]))
22709 (const_int 21845)))]
22710 "TARGET_SSE2"
22711 "punpckhbw\t{%2, %0|%0, %2}"
22712 [(set_attr "type" "ssecvt")
22713 (set_attr "mode" "TI")])
22714
22715 (define_insn "sse2_punpckhwd"
22716 [(set (match_operand:V8HI 0 "register_operand" "=x")
22717 (vec_merge:V8HI
22718 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22719 (parallel [(const_int 4) (const_int 0)
22720 (const_int 5) (const_int 1)
22721 (const_int 6) (const_int 2)
22722 (const_int 7) (const_int 3)]))
22723 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22724 (parallel [(const_int 0) (const_int 4)
22725 (const_int 1) (const_int 5)
22726 (const_int 2) (const_int 6)
22727 (const_int 3) (const_int 7)]))
22728 (const_int 85)))]
22729 "TARGET_SSE2"
22730 "punpckhwd\t{%2, %0|%0, %2}"
22731 [(set_attr "type" "ssecvt")
22732 (set_attr "mode" "TI")])
22733
22734 (define_insn "sse2_punpckhdq"
22735 [(set (match_operand:V4SI 0 "register_operand" "=x")
22736 (vec_merge:V4SI
22737 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22738 (parallel [(const_int 2) (const_int 0)
22739 (const_int 3) (const_int 1)]))
22740 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22741 (parallel [(const_int 0) (const_int 2)
22742 (const_int 1) (const_int 3)]))
22743 (const_int 5)))]
22744 "TARGET_SSE2"
22745 "punpckhdq\t{%2, %0|%0, %2}"
22746 [(set_attr "type" "ssecvt")
22747 (set_attr "mode" "TI")])
22748
22749 (define_insn "sse2_punpcklbw"
22750 [(set (match_operand:V16QI 0 "register_operand" "=x")
22751 (vec_merge:V16QI
22752 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22753 (parallel [(const_int 0) (const_int 8)
22754 (const_int 1) (const_int 9)
22755 (const_int 2) (const_int 10)
22756 (const_int 3) (const_int 11)
22757 (const_int 4) (const_int 12)
22758 (const_int 5) (const_int 13)
22759 (const_int 6) (const_int 14)
22760 (const_int 7) (const_int 15)]))
22761 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22762 (parallel [(const_int 8) (const_int 0)
22763 (const_int 9) (const_int 1)
22764 (const_int 10) (const_int 2)
22765 (const_int 11) (const_int 3)
22766 (const_int 12) (const_int 4)
22767 (const_int 13) (const_int 5)
22768 (const_int 14) (const_int 6)
22769 (const_int 15) (const_int 7)]))
22770 (const_int 21845)))]
22771 "TARGET_SSE2"
22772 "punpcklbw\t{%2, %0|%0, %2}"
22773 [(set_attr "type" "ssecvt")
22774 (set_attr "mode" "TI")])
22775
22776 (define_insn "sse2_punpcklwd"
22777 [(set (match_operand:V8HI 0 "register_operand" "=x")
22778 (vec_merge:V8HI
22779 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22780 (parallel [(const_int 0) (const_int 4)
22781 (const_int 1) (const_int 5)
22782 (const_int 2) (const_int 6)
22783 (const_int 3) (const_int 7)]))
22784 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22785 (parallel [(const_int 4) (const_int 0)
22786 (const_int 5) (const_int 1)
22787 (const_int 6) (const_int 2)
22788 (const_int 7) (const_int 3)]))
22789 (const_int 85)))]
22790 "TARGET_SSE2"
22791 "punpcklwd\t{%2, %0|%0, %2}"
22792 [(set_attr "type" "ssecvt")
22793 (set_attr "mode" "TI")])
22794
22795 (define_insn "sse2_punpckldq"
22796 [(set (match_operand:V4SI 0 "register_operand" "=x")
22797 (vec_merge:V4SI
22798 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22799 (parallel [(const_int 0) (const_int 2)
22800 (const_int 1) (const_int 3)]))
22801 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22802 (parallel [(const_int 2) (const_int 0)
22803 (const_int 3) (const_int 1)]))
22804 (const_int 5)))]
22805 "TARGET_SSE2"
22806 "punpckldq\t{%2, %0|%0, %2}"
22807 [(set_attr "type" "ssecvt")
22808 (set_attr "mode" "TI")])
22809
22810 (define_insn "sse2_punpcklqdq"
22811 [(set (match_operand:V2DI 0 "register_operand" "=x")
22812 (vec_merge:V2DI
22813 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22814 (parallel [(const_int 1)
22815 (const_int 0)]))
22816 (match_operand:V2DI 1 "register_operand" "0")
22817 (const_int 1)))]
22818 "TARGET_SSE2"
22819 "punpcklqdq\t{%2, %0|%0, %2}"
22820 [(set_attr "type" "ssecvt")
22821 (set_attr "mode" "TI")])
22822
22823 (define_insn "sse2_punpckhqdq"
22824 [(set (match_operand:V2DI 0 "register_operand" "=x")
22825 (vec_merge:V2DI
22826 (match_operand:V2DI 1 "register_operand" "0")
22827 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22828 (parallel [(const_int 1)
22829 (const_int 0)]))
22830 (const_int 1)))]
22831 "TARGET_SSE2"
22832 "punpckhqdq\t{%2, %0|%0, %2}"
22833 [(set_attr "type" "ssecvt")
22834 (set_attr "mode" "TI")])
22835
22836 ;; SSE2 moves
22837
22838 (define_insn "sse2_movapd"
22839 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22840 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22841 UNSPEC_MOVA))]
22842 "TARGET_SSE2
22843 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22844 "movapd\t{%1, %0|%0, %1}"
22845 [(set_attr "type" "ssemov")
22846 (set_attr "mode" "V2DF")])
22847
22848 (define_insn "sse2_movupd"
22849 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22850 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22851 UNSPEC_MOVU))]
22852 "TARGET_SSE2
22853 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22854 "movupd\t{%1, %0|%0, %1}"
22855 [(set_attr "type" "ssecvt")
22856 (set_attr "mode" "V2DF")])
22857
22858 (define_insn "sse2_movdqa"
22859 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22860 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22861 UNSPEC_MOVA))]
22862 "TARGET_SSE2
22863 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22864 "movdqa\t{%1, %0|%0, %1}"
22865 [(set_attr "type" "ssemov")
22866 (set_attr "mode" "TI")])
22867
22868 (define_insn "sse2_movdqu"
22869 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22870 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22871 UNSPEC_MOVU))]
22872 "TARGET_SSE2
22873 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22874 "movdqu\t{%1, %0|%0, %1}"
22875 [(set_attr "type" "ssecvt")
22876 (set_attr "mode" "TI")])
22877
22878 (define_insn "sse2_movdq2q"
22879 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22880 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22881 (parallel [(const_int 0)])))]
22882 "TARGET_SSE2 && !TARGET_64BIT"
22883 "@
22884 movq\t{%1, %0|%0, %1}
22885 movdq2q\t{%1, %0|%0, %1}"
22886 [(set_attr "type" "ssecvt")
22887 (set_attr "mode" "TI")])
22888
22889 (define_insn "sse2_movdq2q_rex64"
22890 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22891 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22892 (parallel [(const_int 0)])))]
22893 "TARGET_SSE2 && TARGET_64BIT"
22894 "@
22895 movq\t{%1, %0|%0, %1}
22896 movdq2q\t{%1, %0|%0, %1}
22897 movd\t{%1, %0|%0, %1}"
22898 [(set_attr "type" "ssecvt")
22899 (set_attr "mode" "TI")])
22900
22901 (define_insn "sse2_movq2dq"
22902 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22903 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22904 (const_int 0)))]
22905 "TARGET_SSE2 && !TARGET_64BIT"
22906 "@
22907 movq\t{%1, %0|%0, %1}
22908 movq2dq\t{%1, %0|%0, %1}"
22909 [(set_attr "type" "ssecvt,ssemov")
22910 (set_attr "mode" "TI")])
22911
22912 (define_insn "sse2_movq2dq_rex64"
22913 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22914 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22915 (const_int 0)))]
22916 "TARGET_SSE2 && TARGET_64BIT"
22917 "@
22918 movq\t{%1, %0|%0, %1}
22919 movq2dq\t{%1, %0|%0, %1}
22920 movd\t{%1, %0|%0, %1}"
22921 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22922 (set_attr "mode" "TI")])
22923
22924 (define_insn "sse2_movq"
22925 [(set (match_operand:V2DI 0 "register_operand" "=x")
22926 (vec_concat:V2DI (vec_select:DI
22927 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22928 (parallel [(const_int 0)]))
22929 (const_int 0)))]
22930 "TARGET_SSE2"
22931 "movq\t{%1, %0|%0, %1}"
22932 [(set_attr "type" "ssemov")
22933 (set_attr "mode" "TI")])
22934
22935 (define_insn "sse2_loadd"
22936 [(set (match_operand:V4SI 0 "register_operand" "=x")
22937 (vec_merge:V4SI
22938 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22939 (const_vector:V4SI [(const_int 0)
22940 (const_int 0)
22941 (const_int 0)
22942 (const_int 0)])
22943 (const_int 1)))]
22944 "TARGET_SSE2"
22945 "movd\t{%1, %0|%0, %1}"
22946 [(set_attr "type" "ssemov")
22947 (set_attr "mode" "TI")])
22948
22949 (define_insn "sse2_stored"
22950 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22951 (vec_select:SI
22952 (match_operand:V4SI 1 "register_operand" "x")
22953 (parallel [(const_int 0)])))]
22954 "TARGET_SSE2"
22955 "movd\t{%1, %0|%0, %1}"
22956 [(set_attr "type" "ssemov")
22957 (set_attr "mode" "TI")])
22958
22959 (define_insn "sse2_movhpd"
22960 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22961 (vec_merge:V2DF
22962 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22963 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22964 (const_int 2)))]
22965 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22966 "movhpd\t{%2, %0|%0, %2}"
22967 [(set_attr "type" "ssecvt")
22968 (set_attr "mode" "V2DF")])
22969
22970 (define_insn "sse2_movlpd"
22971 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22972 (vec_merge:V2DF
22973 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22974 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22975 (const_int 1)))]
22976 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22977 "movlpd\t{%2, %0|%0, %2}"
22978 [(set_attr "type" "ssecvt")
22979 (set_attr "mode" "V2DF")])
22980
22981 (define_expand "sse2_loadsd"
22982 [(match_operand:V2DF 0 "register_operand" "")
22983 (match_operand:DF 1 "memory_operand" "")]
22984 "TARGET_SSE2"
22985 {
22986 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22987 CONST0_RTX (V2DFmode)));
22988 DONE;
22989 })
22990
22991 (define_insn "sse2_loadsd_1"
22992 [(set (match_operand:V2DF 0 "register_operand" "=x")
22993 (vec_merge:V2DF
22994 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22995 (match_operand:V2DF 2 "const0_operand" "X")
22996 (const_int 1)))]
22997 "TARGET_SSE2"
22998 "movsd\t{%1, %0|%0, %1}"
22999 [(set_attr "type" "ssecvt")
23000 (set_attr "mode" "DF")])
23001
23002 (define_insn "sse2_movsd"
23003 [(set (match_operand:V2DF 0 "register_operand" "=x")
23004 (vec_merge:V2DF
23005 (match_operand:V2DF 1 "register_operand" "0")
23006 (match_operand:V2DF 2 "register_operand" "x")
23007 (const_int 1)))]
23008 "TARGET_SSE2"
23009 "movsd\t{%2, %0|%0, %2}"
23010 [(set_attr "type" "ssecvt")
23011 (set_attr "mode" "DF")])
23012
23013 (define_insn "sse2_storesd"
23014 [(set (match_operand:DF 0 "memory_operand" "=m")
23015 (vec_select:DF
23016 (match_operand:V2DF 1 "register_operand" "x")
23017 (parallel [(const_int 0)])))]
23018 "TARGET_SSE2"
23019 "movsd\t{%1, %0|%0, %1}"
23020 [(set_attr "type" "ssecvt")
23021 (set_attr "mode" "DF")])
23022
23023 (define_insn "sse2_shufpd"
23024 [(set (match_operand:V2DF 0 "register_operand" "=x")
23025 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23026 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23027 (match_operand:SI 3 "immediate_operand" "i")]
23028 UNSPEC_SHUFFLE))]
23029 "TARGET_SSE2"
23030 ;; @@@ check operand order for intel/nonintel syntax
23031 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23032 [(set_attr "type" "ssecvt")
23033 (set_attr "mode" "V2DF")])
23034
23035 (define_insn "sse2_clflush"
23036 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23037 UNSPECV_CLFLUSH)]
23038 "TARGET_SSE2"
23039 "clflush %0"
23040 [(set_attr "type" "sse")
23041 (set_attr "memory" "unknown")])
23042
23043 (define_expand "sse2_mfence"
23044 [(set (match_dup 0)
23045 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23046 "TARGET_SSE2"
23047 {
23048 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23049 MEM_VOLATILE_P (operands[0]) = 1;
23050 })
23051
23052 (define_insn "*mfence_insn"
23053 [(set (match_operand:BLK 0 "" "")
23054 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23055 "TARGET_SSE2"
23056 "mfence"
23057 [(set_attr "type" "sse")
23058 (set_attr "memory" "unknown")])
23059
23060 (define_expand "sse2_lfence"
23061 [(set (match_dup 0)
23062 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23063 "TARGET_SSE2"
23064 {
23065 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23066 MEM_VOLATILE_P (operands[0]) = 1;
23067 })
23068
23069 (define_insn "*lfence_insn"
23070 [(set (match_operand:BLK 0 "" "")
23071 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23072 "TARGET_SSE2"
23073 "lfence"
23074 [(set_attr "type" "sse")
23075 (set_attr "memory" "unknown")])