except.c (EH_RETURN_STACKADJ_RTX): Do not define.
[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) == MODE_TI)
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) == MODE_DI)
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) == MODE_TI)
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) == MODE_DI)
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" "SF,SF,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" "SF")])
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 (set_attr "mode" "DI")])
4448
4449 (define_insn "fix_truncdi_nomemory"
4450 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4451 (fix:DI (match_operand 1 "register_operand" "f,f")))
4452 (use (match_operand:HI 2 "memory_operand" "m,m"))
4453 (use (match_operand:HI 3 "memory_operand" "m,m"))
4454 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4455 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4456 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4457 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4458 "#"
4459 [(set_attr "type" "fistp")
4460 (set_attr "mode" "DI")])
4461
4462 (define_insn "fix_truncdi_memory"
4463 [(set (match_operand:DI 0 "memory_operand" "=m")
4464 (fix:DI (match_operand 1 "register_operand" "f")))
4465 (use (match_operand:HI 2 "memory_operand" "m"))
4466 (use (match_operand:HI 3 "memory_operand" "m"))
4467 (clobber (match_scratch:DF 4 "=&1f"))]
4468 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4469 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4470 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4471 [(set_attr "type" "fistp")
4472 (set_attr "mode" "DI")])
4473
4474 (define_split
4475 [(set (match_operand:DI 0 "register_operand" "")
4476 (fix:DI (match_operand 1 "register_operand" "")))
4477 (use (match_operand:HI 2 "memory_operand" ""))
4478 (use (match_operand:HI 3 "memory_operand" ""))
4479 (clobber (match_operand:DI 4 "memory_operand" ""))
4480 (clobber (match_scratch 5 ""))]
4481 "reload_completed"
4482 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4483 (use (match_dup 2))
4484 (use (match_dup 3))
4485 (clobber (match_dup 5))])
4486 (set (match_dup 0) (match_dup 4))]
4487 "")
4488
4489 (define_split
4490 [(set (match_operand:DI 0 "memory_operand" "")
4491 (fix:DI (match_operand 1 "register_operand" "")))
4492 (use (match_operand:HI 2 "memory_operand" ""))
4493 (use (match_operand:HI 3 "memory_operand" ""))
4494 (clobber (match_operand:DI 4 "memory_operand" ""))
4495 (clobber (match_scratch 5 ""))]
4496 "reload_completed"
4497 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4498 (use (match_dup 2))
4499 (use (match_dup 3))
4500 (clobber (match_dup 5))])]
4501 "")
4502
4503 ;; When SSE available, it is always faster to use it!
4504 (define_insn "fix_truncsfdi_sse"
4505 [(set (match_operand:DI 0 "register_operand" "=r,r")
4506 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4507 "TARGET_64BIT && TARGET_SSE"
4508 "cvttss2si{q}\t{%1, %0|%0, %1}"
4509 [(set_attr "type" "sseicvt")
4510 (set_attr "mode" "SF")
4511 (set_attr "athlon_decode" "double,vector")])
4512
4513 ;; Avoid vector decoded form of the instruction.
4514 (define_peephole2
4515 [(match_scratch:SF 2 "x")
4516 (set (match_operand:DI 0 "register_operand" "")
4517 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4518 "TARGET_K8 && !optimize_size"
4519 [(set (match_dup 2) (match_dup 1))
4520 (set (match_dup 0) (fix:DI (match_dup 2)))]
4521 "")
4522
4523 (define_insn "fix_truncdfdi_sse"
4524 [(set (match_operand:DI 0 "register_operand" "=r,r")
4525 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4526 "TARGET_64BIT && TARGET_SSE2"
4527 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4528 [(set_attr "type" "sseicvt,sseicvt")
4529 (set_attr "mode" "DF")
4530 (set_attr "athlon_decode" "double,vector")])
4531
4532 ;; Avoid vector decoded form of the instruction.
4533 (define_peephole2
4534 [(match_scratch:DF 2 "Y")
4535 (set (match_operand:DI 0 "register_operand" "")
4536 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4537 "TARGET_K8 && !optimize_size"
4538 [(set (match_dup 2) (match_dup 1))
4539 (set (match_dup 0) (fix:DI (match_dup 2)))]
4540 "")
4541
4542 ;; Signed conversion to SImode.
4543
4544 (define_expand "fix_truncxfsi2"
4545 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4546 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4547 "!TARGET_64BIT && TARGET_80387"
4548 "")
4549
4550 (define_expand "fix_trunctfsi2"
4551 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4552 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4553 "TARGET_80387"
4554 "")
4555
4556 (define_expand "fix_truncdfsi2"
4557 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4558 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4559 "TARGET_80387 || TARGET_SSE2"
4560 {
4561 if (TARGET_SSE2)
4562 {
4563 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4564 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4565 if (out != operands[0])
4566 emit_move_insn (operands[0], out);
4567 DONE;
4568 }
4569 })
4570
4571 (define_expand "fix_truncsfsi2"
4572 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4573 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4574 "TARGET_80387 || TARGET_SSE"
4575 {
4576 if (TARGET_SSE)
4577 {
4578 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4579 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4580 if (out != operands[0])
4581 emit_move_insn (operands[0], out);
4582 DONE;
4583 }
4584 })
4585
4586 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4587 ;; of the machinery.
4588 (define_insn_and_split "*fix_truncsi_1"
4589 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4590 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4591 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4592 && !reload_completed && !reload_in_progress
4593 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4594 "#"
4595 "&& 1"
4596 [(const_int 0)]
4597 {
4598 ix86_optimize_mode_switching = 1;
4599 operands[2] = assign_386_stack_local (HImode, 1);
4600 operands[3] = assign_386_stack_local (HImode, 2);
4601 if (memory_operand (operands[0], VOIDmode))
4602 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4603 operands[2], operands[3]));
4604 else
4605 {
4606 operands[4] = assign_386_stack_local (SImode, 0);
4607 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4608 operands[2], operands[3],
4609 operands[4]));
4610 }
4611 DONE;
4612 }
4613 [(set_attr "type" "fistp")
4614 (set_attr "mode" "SI")])
4615
4616 (define_insn "fix_truncsi_nomemory"
4617 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4618 (fix:SI (match_operand 1 "register_operand" "f,f")))
4619 (use (match_operand:HI 2 "memory_operand" "m,m"))
4620 (use (match_operand:HI 3 "memory_operand" "m,m"))
4621 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4622 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4623 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4624 "#"
4625 [(set_attr "type" "fistp")
4626 (set_attr "mode" "SI")])
4627
4628 (define_insn "fix_truncsi_memory"
4629 [(set (match_operand:SI 0 "memory_operand" "=m")
4630 (fix:SI (match_operand 1 "register_operand" "f")))
4631 (use (match_operand:HI 2 "memory_operand" "m"))
4632 (use (match_operand:HI 3 "memory_operand" "m"))]
4633 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4634 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4635 "* return output_fix_trunc (insn, operands);"
4636 [(set_attr "type" "fistp")
4637 (set_attr "mode" "SI")])
4638
4639 ;; When SSE available, it is always faster to use it!
4640 (define_insn "fix_truncsfsi_sse"
4641 [(set (match_operand:SI 0 "register_operand" "=r,r")
4642 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4643 "TARGET_SSE"
4644 "cvttss2si\t{%1, %0|%0, %1}"
4645 [(set_attr "type" "sseicvt")
4646 (set_attr "mode" "DF")
4647 (set_attr "athlon_decode" "double,vector")])
4648
4649 ;; Avoid vector decoded form of the instruction.
4650 (define_peephole2
4651 [(match_scratch:SF 2 "x")
4652 (set (match_operand:SI 0 "register_operand" "")
4653 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4654 "TARGET_K8 && !optimize_size"
4655 [(set (match_dup 2) (match_dup 1))
4656 (set (match_dup 0) (fix:SI (match_dup 2)))]
4657 "")
4658
4659 (define_insn "fix_truncdfsi_sse"
4660 [(set (match_operand:SI 0 "register_operand" "=r,r")
4661 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4662 "TARGET_SSE2"
4663 "cvttsd2si\t{%1, %0|%0, %1}"
4664 [(set_attr "type" "sseicvt")
4665 (set_attr "mode" "DF")
4666 (set_attr "athlon_decode" "double,vector")])
4667
4668 ;; Avoid vector decoded form of the instruction.
4669 (define_peephole2
4670 [(match_scratch:DF 2 "Y")
4671 (set (match_operand:SI 0 "register_operand" "")
4672 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4673 "TARGET_K8 && !optimize_size"
4674 [(set (match_dup 2) (match_dup 1))
4675 (set (match_dup 0) (fix:SI (match_dup 2)))]
4676 "")
4677
4678 (define_split
4679 [(set (match_operand:SI 0 "register_operand" "")
4680 (fix:SI (match_operand 1 "register_operand" "")))
4681 (use (match_operand:HI 2 "memory_operand" ""))
4682 (use (match_operand:HI 3 "memory_operand" ""))
4683 (clobber (match_operand:SI 4 "memory_operand" ""))]
4684 "reload_completed"
4685 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4686 (use (match_dup 2))
4687 (use (match_dup 3))])
4688 (set (match_dup 0) (match_dup 4))]
4689 "")
4690
4691 (define_split
4692 [(set (match_operand:SI 0 "memory_operand" "")
4693 (fix:SI (match_operand 1 "register_operand" "")))
4694 (use (match_operand:HI 2 "memory_operand" ""))
4695 (use (match_operand:HI 3 "memory_operand" ""))
4696 (clobber (match_operand:SI 4 "memory_operand" ""))]
4697 "reload_completed"
4698 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4699 (use (match_dup 2))
4700 (use (match_dup 3))])]
4701 "")
4702
4703 ;; Signed conversion to HImode.
4704
4705 (define_expand "fix_truncxfhi2"
4706 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4707 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4708 "!TARGET_64BIT && TARGET_80387"
4709 "")
4710
4711 (define_expand "fix_trunctfhi2"
4712 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4713 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4714 "TARGET_80387"
4715 "")
4716
4717 (define_expand "fix_truncdfhi2"
4718 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4719 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4720 "TARGET_80387 && !TARGET_SSE2"
4721 "")
4722
4723 (define_expand "fix_truncsfhi2"
4724 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4725 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4726 "TARGET_80387 && !TARGET_SSE"
4727 "")
4728
4729 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4730 ;; of the machinery.
4731 (define_insn_and_split "*fix_trunchi_1"
4732 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4733 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4734 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && !reload_completed && !reload_in_progress
4736 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4737 "#"
4738 ""
4739 [(const_int 0)]
4740 {
4741 ix86_optimize_mode_switching = 1;
4742 operands[2] = assign_386_stack_local (HImode, 1);
4743 operands[3] = assign_386_stack_local (HImode, 2);
4744 if (memory_operand (operands[0], VOIDmode))
4745 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4746 operands[2], operands[3]));
4747 else
4748 {
4749 operands[4] = assign_386_stack_local (HImode, 0);
4750 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4751 operands[2], operands[3],
4752 operands[4]));
4753 }
4754 DONE;
4755 }
4756 [(set_attr "type" "fistp")
4757 (set_attr "mode" "HI")])
4758
4759 (define_insn "fix_trunchi_nomemory"
4760 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4761 (fix:HI (match_operand 1 "register_operand" "f,f")))
4762 (use (match_operand:HI 2 "memory_operand" "m,m"))
4763 (use (match_operand:HI 3 "memory_operand" "m,m"))
4764 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4765 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4766 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4767 "#"
4768 [(set_attr "type" "fistp")
4769 (set_attr "mode" "HI")])
4770
4771 (define_insn "fix_trunchi_memory"
4772 [(set (match_operand:HI 0 "memory_operand" "=m")
4773 (fix:HI (match_operand 1 "register_operand" "f")))
4774 (use (match_operand:HI 2 "memory_operand" "m"))
4775 (use (match_operand:HI 3 "memory_operand" "m"))]
4776 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4777 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4778 "* return output_fix_trunc (insn, operands);"
4779 [(set_attr "type" "fistp")
4780 (set_attr "mode" "HI")])
4781
4782 (define_split
4783 [(set (match_operand:HI 0 "memory_operand" "")
4784 (fix:HI (match_operand 1 "register_operand" "")))
4785 (use (match_operand:HI 2 "memory_operand" ""))
4786 (use (match_operand:HI 3 "memory_operand" ""))
4787 (clobber (match_operand:HI 4 "memory_operand" ""))]
4788 "reload_completed"
4789 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4790 (use (match_dup 2))
4791 (use (match_dup 3))])]
4792 "")
4793
4794 (define_split
4795 [(set (match_operand:HI 0 "register_operand" "")
4796 (fix:HI (match_operand 1 "register_operand" "")))
4797 (use (match_operand:HI 2 "memory_operand" ""))
4798 (use (match_operand:HI 3 "memory_operand" ""))
4799 (clobber (match_operand:HI 4 "memory_operand" ""))]
4800 "reload_completed"
4801 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4802 (use (match_dup 2))
4803 (use (match_dup 3))
4804 (clobber (match_dup 4))])
4805 (set (match_dup 0) (match_dup 4))]
4806 "")
4807
4808 ;; %% Not used yet.
4809 (define_insn "x86_fnstcw_1"
4810 [(set (match_operand:HI 0 "memory_operand" "=m")
4811 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4812 "TARGET_80387"
4813 "fnstcw\t%0"
4814 [(set_attr "length" "2")
4815 (set_attr "mode" "HI")
4816 (set_attr "unit" "i387")
4817 (set_attr "ppro_uops" "few")])
4818
4819 (define_insn "x86_fldcw_1"
4820 [(set (reg:HI 18)
4821 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4822 "TARGET_80387"
4823 "fldcw\t%0"
4824 [(set_attr "length" "2")
4825 (set_attr "mode" "HI")
4826 (set_attr "unit" "i387")
4827 (set_attr "athlon_decode" "vector")
4828 (set_attr "ppro_uops" "few")])
4829 \f
4830 ;; Conversion between fixed point and floating point.
4831
4832 ;; Even though we only accept memory inputs, the backend _really_
4833 ;; wants to be able to do this between registers.
4834
4835 (define_expand "floathisf2"
4836 [(set (match_operand:SF 0 "register_operand" "")
4837 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4838 "TARGET_SSE || TARGET_80387"
4839 {
4840 if (TARGET_SSE && TARGET_SSE_MATH)
4841 {
4842 emit_insn (gen_floatsisf2 (operands[0],
4843 convert_to_mode (SImode, operands[1], 0)));
4844 DONE;
4845 }
4846 })
4847
4848 (define_insn "*floathisf2_1"
4849 [(set (match_operand:SF 0 "register_operand" "=f,f")
4850 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4851 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4852 "@
4853 fild%z1\t%1
4854 #"
4855 [(set_attr "type" "fmov,multi")
4856 (set_attr "mode" "SF")
4857 (set_attr "fp_int_src" "true")])
4858
4859 (define_expand "floatsisf2"
4860 [(set (match_operand:SF 0 "register_operand" "")
4861 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4862 "TARGET_SSE || TARGET_80387"
4863 "")
4864
4865 (define_insn "*floatsisf2_i387"
4866 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4867 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4868 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4869 "@
4870 fild%z1\t%1
4871 #
4872 cvtsi2ss\t{%1, %0|%0, %1}
4873 cvtsi2ss\t{%1, %0|%0, %1}"
4874 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4875 (set_attr "mode" "SF")
4876 (set_attr "athlon_decode" "*,*,vector,double")
4877 (set_attr "fp_int_src" "true")])
4878
4879 (define_insn "*floatsisf2_sse"
4880 [(set (match_operand:SF 0 "register_operand" "=x,x")
4881 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4882 "TARGET_SSE"
4883 "cvtsi2ss\t{%1, %0|%0, %1}"
4884 [(set_attr "type" "sseicvt")
4885 (set_attr "mode" "SF")
4886 (set_attr "athlon_decode" "vector,double")
4887 (set_attr "fp_int_src" "true")])
4888
4889 ; Avoid possible reformatting penalty on the destination by first
4890 ; zeroing it out
4891 (define_split
4892 [(set (match_operand:SF 0 "register_operand" "")
4893 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4894 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4895 && SSE_REG_P (operands[0])"
4896 [(const_int 0)]
4897 {
4898 rtx dest;
4899 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4900 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4901 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4902 DONE;
4903 })
4904
4905 (define_expand "floatdisf2"
4906 [(set (match_operand:SF 0 "register_operand" "")
4907 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4908 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4909 "")
4910
4911 (define_insn "*floatdisf2_i387_only"
4912 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4913 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4914 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4915 "@
4916 fild%z1\t%1
4917 #"
4918 [(set_attr "type" "fmov,multi")
4919 (set_attr "mode" "SF")
4920 (set_attr "fp_int_src" "true")])
4921
4922 (define_insn "*floatdisf2_i387"
4923 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4924 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4925 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4926 "@
4927 fild%z1\t%1
4928 #
4929 cvtsi2ss{q}\t{%1, %0|%0, %1}
4930 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4931 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4932 (set_attr "mode" "SF")
4933 (set_attr "athlon_decode" "*,*,vector,double")
4934 (set_attr "fp_int_src" "true")])
4935
4936 (define_insn "*floatdisf2_sse"
4937 [(set (match_operand:SF 0 "register_operand" "=x,x")
4938 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4939 "TARGET_64BIT && TARGET_SSE"
4940 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4941 [(set_attr "type" "sseicvt")
4942 (set_attr "mode" "SF")
4943 (set_attr "athlon_decode" "vector,double")
4944 (set_attr "fp_int_src" "true")])
4945
4946 ; Avoid possible reformatting penalty on the destination by first
4947 ; zeroing it out
4948 (define_split
4949 [(set (match_operand:SF 0 "register_operand" "")
4950 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4951 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4952 && SSE_REG_P (operands[0])"
4953 [(const_int 0)]
4954 {
4955 rtx dest;
4956 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4957 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4958 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4959 DONE;
4960 })
4961
4962 (define_expand "floathidf2"
4963 [(set (match_operand:DF 0 "register_operand" "")
4964 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4965 "TARGET_SSE2 || TARGET_80387"
4966 {
4967 if (TARGET_SSE && TARGET_SSE_MATH)
4968 {
4969 emit_insn (gen_floatsidf2 (operands[0],
4970 convert_to_mode (SImode, operands[1], 0)));
4971 DONE;
4972 }
4973 })
4974
4975 (define_insn "*floathidf2_1"
4976 [(set (match_operand:DF 0 "register_operand" "=f,f")
4977 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4978 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4979 "@
4980 fild%z1\t%1
4981 #"
4982 [(set_attr "type" "fmov,multi")
4983 (set_attr "mode" "DF")
4984 (set_attr "fp_int_src" "true")])
4985
4986 (define_expand "floatsidf2"
4987 [(set (match_operand:DF 0 "register_operand" "")
4988 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4989 "TARGET_80387 || TARGET_SSE2"
4990 "")
4991
4992 (define_insn "*floatsidf2_i387"
4993 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4994 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4995 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4996 "@
4997 fild%z1\t%1
4998 #
4999 cvtsi2sd\t{%1, %0|%0, %1}
5000 cvtsi2sd\t{%1, %0|%0, %1}"
5001 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5002 (set_attr "mode" "DF")
5003 (set_attr "athlon_decode" "*,*,double,direct")
5004 (set_attr "fp_int_src" "true")])
5005
5006 (define_insn "*floatsidf2_sse"
5007 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5008 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
5009 "TARGET_SSE2"
5010 "cvtsi2sd\t{%1, %0|%0, %1}"
5011 [(set_attr "type" "sseicvt")
5012 (set_attr "mode" "DF")
5013 (set_attr "athlon_decode" "double,direct")
5014 (set_attr "fp_int_src" "true")])
5015
5016 (define_expand "floatdidf2"
5017 [(set (match_operand:DF 0 "register_operand" "")
5018 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5019 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5020 "")
5021
5022 (define_insn "*floatdidf2_i387_only"
5023 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5024 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5025 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5026 "@
5027 fild%z1\t%1
5028 #"
5029 [(set_attr "type" "fmov,multi")
5030 (set_attr "mode" "DF")
5031 (set_attr "fp_int_src" "true")])
5032
5033 (define_insn "*floatdidf2_i387"
5034 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5035 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5036 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5037 "@
5038 fild%z1\t%1
5039 #
5040 cvtsi2sd{q}\t{%1, %0|%0, %1}
5041 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5042 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5043 (set_attr "mode" "DF")
5044 (set_attr "athlon_decode" "*,*,double,direct")
5045 (set_attr "fp_int_src" "true")])
5046
5047 (define_insn "*floatdidf2_sse"
5048 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5049 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5050 "TARGET_SSE2"
5051 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5052 [(set_attr "type" "sseicvt")
5053 (set_attr "mode" "DF")
5054 (set_attr "athlon_decode" "double,direct")
5055 (set_attr "fp_int_src" "true")])
5056
5057 (define_insn "floathixf2"
5058 [(set (match_operand:XF 0 "register_operand" "=f,f")
5059 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5060 "!TARGET_64BIT && TARGET_80387"
5061 "@
5062 fild%z1\t%1
5063 #"
5064 [(set_attr "type" "fmov,multi")
5065 (set_attr "mode" "XF")
5066 (set_attr "fp_int_src" "true")])
5067
5068 (define_insn "floathitf2"
5069 [(set (match_operand:TF 0 "register_operand" "=f,f")
5070 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5071 "TARGET_80387"
5072 "@
5073 fild%z1\t%1
5074 #"
5075 [(set_attr "type" "fmov,multi")
5076 (set_attr "mode" "XF")
5077 (set_attr "fp_int_src" "true")])
5078
5079 (define_insn "floatsixf2"
5080 [(set (match_operand:XF 0 "register_operand" "=f,f")
5081 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5082 "!TARGET_64BIT && TARGET_80387"
5083 "@
5084 fild%z1\t%1
5085 #"
5086 [(set_attr "type" "fmov,multi")
5087 (set_attr "mode" "XF")
5088 (set_attr "fp_int_src" "true")])
5089
5090 (define_insn "floatsitf2"
5091 [(set (match_operand:TF 0 "register_operand" "=f,f")
5092 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5093 "TARGET_80387"
5094 "@
5095 fild%z1\t%1
5096 #"
5097 [(set_attr "type" "fmov,multi")
5098 (set_attr "mode" "XF")
5099 (set_attr "fp_int_src" "true")])
5100
5101 (define_insn "floatdixf2"
5102 [(set (match_operand:XF 0 "register_operand" "=f,f")
5103 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5104 "!TARGET_64BIT && TARGET_80387"
5105 "@
5106 fild%z1\t%1
5107 #"
5108 [(set_attr "type" "fmov,multi")
5109 (set_attr "mode" "XF")
5110 (set_attr "fp_int_src" "true")])
5111
5112 (define_insn "floatditf2"
5113 [(set (match_operand:TF 0 "register_operand" "=f,f")
5114 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5115 "TARGET_80387"
5116 "@
5117 fild%z1\t%1
5118 #"
5119 [(set_attr "type" "fmov,multi")
5120 (set_attr "mode" "XF")
5121 (set_attr "fp_int_src" "true")])
5122
5123 ;; %%% Kill these when reload knows how to do it.
5124 (define_split
5125 [(set (match_operand 0 "fp_register_operand" "")
5126 (float (match_operand 1 "register_operand" "")))]
5127 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5128 [(const_int 0)]
5129 {
5130 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5131 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5132 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5133 ix86_free_from_memory (GET_MODE (operands[1]));
5134 DONE;
5135 })
5136
5137 (define_expand "floatunssisf2"
5138 [(use (match_operand:SF 0 "register_operand" ""))
5139 (use (match_operand:SI 1 "register_operand" ""))]
5140 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5141 "x86_emit_floatuns (operands); DONE;")
5142
5143 (define_expand "floatunsdisf2"
5144 [(use (match_operand:SF 0 "register_operand" ""))
5145 (use (match_operand:DI 1 "register_operand" ""))]
5146 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5147 "x86_emit_floatuns (operands); DONE;")
5148
5149 (define_expand "floatunsdidf2"
5150 [(use (match_operand:DF 0 "register_operand" ""))
5151 (use (match_operand:DI 1 "register_operand" ""))]
5152 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5153 "x86_emit_floatuns (operands); DONE;")
5154 \f
5155 ;; Add instructions
5156
5157 ;; %%% splits for addsidi3
5158 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5159 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5160 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5161
5162 (define_expand "adddi3"
5163 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5164 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5165 (match_operand:DI 2 "x86_64_general_operand" "")))
5166 (clobber (reg:CC 17))]
5167 ""
5168 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5169
5170 (define_insn "*adddi3_1"
5171 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5172 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5173 (match_operand:DI 2 "general_operand" "roiF,riF")))
5174 (clobber (reg:CC 17))]
5175 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5176 "#")
5177
5178 (define_split
5179 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5180 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5181 (match_operand:DI 2 "general_operand" "")))
5182 (clobber (reg:CC 17))]
5183 "!TARGET_64BIT && reload_completed"
5184 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5185 UNSPEC_ADD_CARRY))
5186 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5187 (parallel [(set (match_dup 3)
5188 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5189 (match_dup 4))
5190 (match_dup 5)))
5191 (clobber (reg:CC 17))])]
5192 "split_di (operands+0, 1, operands+0, operands+3);
5193 split_di (operands+1, 1, operands+1, operands+4);
5194 split_di (operands+2, 1, operands+2, operands+5);")
5195
5196 (define_insn "adddi3_carry_rex64"
5197 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5198 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5199 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5200 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5201 (clobber (reg:CC 17))]
5202 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5203 "adc{q}\t{%2, %0|%0, %2}"
5204 [(set_attr "type" "alu")
5205 (set_attr "pent_pair" "pu")
5206 (set_attr "mode" "DI")
5207 (set_attr "ppro_uops" "few")])
5208
5209 (define_insn "*adddi3_cc_rex64"
5210 [(set (reg:CC 17)
5211 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5212 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5213 UNSPEC_ADD_CARRY))
5214 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5215 (plus:DI (match_dup 1) (match_dup 2)))]
5216 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5217 "add{q}\t{%2, %0|%0, %2}"
5218 [(set_attr "type" "alu")
5219 (set_attr "mode" "DI")])
5220
5221 (define_insn "addqi3_carry"
5222 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5223 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5224 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5225 (match_operand:QI 2 "general_operand" "ri,rm")))
5226 (clobber (reg:CC 17))]
5227 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5228 "adc{b}\t{%2, %0|%0, %2}"
5229 [(set_attr "type" "alu")
5230 (set_attr "pent_pair" "pu")
5231 (set_attr "mode" "QI")
5232 (set_attr "ppro_uops" "few")])
5233
5234 (define_insn "addhi3_carry"
5235 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5236 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5237 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5238 (match_operand:HI 2 "general_operand" "ri,rm")))
5239 (clobber (reg:CC 17))]
5240 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5241 "adc{w}\t{%2, %0|%0, %2}"
5242 [(set_attr "type" "alu")
5243 (set_attr "pent_pair" "pu")
5244 (set_attr "mode" "HI")
5245 (set_attr "ppro_uops" "few")])
5246
5247 (define_insn "addsi3_carry"
5248 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5249 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5250 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5251 (match_operand:SI 2 "general_operand" "ri,rm")))
5252 (clobber (reg:CC 17))]
5253 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5254 "adc{l}\t{%2, %0|%0, %2}"
5255 [(set_attr "type" "alu")
5256 (set_attr "pent_pair" "pu")
5257 (set_attr "mode" "SI")
5258 (set_attr "ppro_uops" "few")])
5259
5260 (define_insn "*addsi3_carry_zext"
5261 [(set (match_operand:DI 0 "register_operand" "=r")
5262 (zero_extend:DI
5263 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5264 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5265 (match_operand:SI 2 "general_operand" "rim"))))
5266 (clobber (reg:CC 17))]
5267 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5268 "adc{l}\t{%2, %k0|%k0, %2}"
5269 [(set_attr "type" "alu")
5270 (set_attr "pent_pair" "pu")
5271 (set_attr "mode" "SI")
5272 (set_attr "ppro_uops" "few")])
5273
5274 (define_insn "*addsi3_cc"
5275 [(set (reg:CC 17)
5276 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5277 (match_operand:SI 2 "general_operand" "ri,rm")]
5278 UNSPEC_ADD_CARRY))
5279 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5280 (plus:SI (match_dup 1) (match_dup 2)))]
5281 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5282 "add{l}\t{%2, %0|%0, %2}"
5283 [(set_attr "type" "alu")
5284 (set_attr "mode" "SI")])
5285
5286 (define_insn "addqi3_cc"
5287 [(set (reg:CC 17)
5288 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5289 (match_operand:QI 2 "general_operand" "qi,qm")]
5290 UNSPEC_ADD_CARRY))
5291 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5292 (plus:QI (match_dup 1) (match_dup 2)))]
5293 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5294 "add{b}\t{%2, %0|%0, %2}"
5295 [(set_attr "type" "alu")
5296 (set_attr "mode" "QI")])
5297
5298 (define_expand "addsi3"
5299 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5300 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5301 (match_operand:SI 2 "general_operand" "")))
5302 (clobber (reg:CC 17))])]
5303 ""
5304 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5305
5306 (define_insn "*lea_1"
5307 [(set (match_operand:SI 0 "register_operand" "=r")
5308 (match_operand:SI 1 "address_operand" "p"))]
5309 "!TARGET_64BIT"
5310 "lea{l}\t{%a1, %0|%0, %a1}"
5311 [(set_attr "type" "lea")
5312 (set_attr "mode" "SI")])
5313
5314 (define_insn "*lea_1_rex64"
5315 [(set (match_operand:SI 0 "register_operand" "=r")
5316 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5317 "TARGET_64BIT"
5318 "lea{l}\t{%a1, %0|%0, %a1}"
5319 [(set_attr "type" "lea")
5320 (set_attr "mode" "SI")])
5321
5322 (define_insn "*lea_1_zext"
5323 [(set (match_operand:DI 0 "register_operand" "=r")
5324 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5325 "TARGET_64BIT"
5326 "lea{l}\t{%a1, %k0|%k0, %a1}"
5327 [(set_attr "type" "lea")
5328 (set_attr "mode" "SI")])
5329
5330 (define_insn "*lea_2_rex64"
5331 [(set (match_operand:DI 0 "register_operand" "=r")
5332 (match_operand:DI 1 "address_operand" "p"))]
5333 "TARGET_64BIT"
5334 "lea{q}\t{%a1, %0|%0, %a1}"
5335 [(set_attr "type" "lea")
5336 (set_attr "mode" "DI")])
5337
5338 ;; The lea patterns for non-Pmodes needs to be matched by several
5339 ;; insns converted to real lea by splitters.
5340
5341 (define_insn_and_split "*lea_general_1"
5342 [(set (match_operand 0 "register_operand" "=r")
5343 (plus (plus (match_operand 1 "index_register_operand" "r")
5344 (match_operand 2 "register_operand" "r"))
5345 (match_operand 3 "immediate_operand" "i")))]
5346 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5347 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5348 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5349 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5350 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5351 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5352 || GET_MODE (operands[3]) == VOIDmode)"
5353 "#"
5354 "&& reload_completed"
5355 [(const_int 0)]
5356 {
5357 rtx pat;
5358 operands[0] = gen_lowpart (SImode, operands[0]);
5359 operands[1] = gen_lowpart (Pmode, operands[1]);
5360 operands[2] = gen_lowpart (Pmode, operands[2]);
5361 operands[3] = gen_lowpart (Pmode, operands[3]);
5362 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5363 operands[3]);
5364 if (Pmode != SImode)
5365 pat = gen_rtx_SUBREG (SImode, pat, 0);
5366 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5367 DONE;
5368 }
5369 [(set_attr "type" "lea")
5370 (set_attr "mode" "SI")])
5371
5372 (define_insn_and_split "*lea_general_1_zext"
5373 [(set (match_operand:DI 0 "register_operand" "=r")
5374 (zero_extend:DI
5375 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5376 (match_operand:SI 2 "register_operand" "r"))
5377 (match_operand:SI 3 "immediate_operand" "i"))))]
5378 "TARGET_64BIT"
5379 "#"
5380 "&& reload_completed"
5381 [(set (match_dup 0)
5382 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5383 (match_dup 2))
5384 (match_dup 3)) 0)))]
5385 {
5386 operands[1] = gen_lowpart (Pmode, operands[1]);
5387 operands[2] = gen_lowpart (Pmode, operands[2]);
5388 operands[3] = gen_lowpart (Pmode, operands[3]);
5389 }
5390 [(set_attr "type" "lea")
5391 (set_attr "mode" "SI")])
5392
5393 (define_insn_and_split "*lea_general_2"
5394 [(set (match_operand 0 "register_operand" "=r")
5395 (plus (mult (match_operand 1 "index_register_operand" "r")
5396 (match_operand 2 "const248_operand" "i"))
5397 (match_operand 3 "nonmemory_operand" "ri")))]
5398 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5399 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5400 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5401 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5402 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5403 || GET_MODE (operands[3]) == VOIDmode)"
5404 "#"
5405 "&& reload_completed"
5406 [(const_int 0)]
5407 {
5408 rtx pat;
5409 operands[0] = gen_lowpart (SImode, operands[0]);
5410 operands[1] = gen_lowpart (Pmode, operands[1]);
5411 operands[3] = gen_lowpart (Pmode, operands[3]);
5412 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5413 operands[3]);
5414 if (Pmode != SImode)
5415 pat = gen_rtx_SUBREG (SImode, pat, 0);
5416 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5417 DONE;
5418 }
5419 [(set_attr "type" "lea")
5420 (set_attr "mode" "SI")])
5421
5422 (define_insn_and_split "*lea_general_2_zext"
5423 [(set (match_operand:DI 0 "register_operand" "=r")
5424 (zero_extend:DI
5425 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5426 (match_operand:SI 2 "const248_operand" "n"))
5427 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5428 "TARGET_64BIT"
5429 "#"
5430 "&& reload_completed"
5431 [(set (match_dup 0)
5432 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5433 (match_dup 2))
5434 (match_dup 3)) 0)))]
5435 {
5436 operands[1] = gen_lowpart (Pmode, operands[1]);
5437 operands[3] = gen_lowpart (Pmode, operands[3]);
5438 }
5439 [(set_attr "type" "lea")
5440 (set_attr "mode" "SI")])
5441
5442 (define_insn_and_split "*lea_general_3"
5443 [(set (match_operand 0 "register_operand" "=r")
5444 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5445 (match_operand 2 "const248_operand" "i"))
5446 (match_operand 3 "register_operand" "r"))
5447 (match_operand 4 "immediate_operand" "i")))]
5448 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5449 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5450 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5451 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5452 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5453 "#"
5454 "&& reload_completed"
5455 [(const_int 0)]
5456 {
5457 rtx pat;
5458 operands[0] = gen_lowpart (SImode, operands[0]);
5459 operands[1] = gen_lowpart (Pmode, operands[1]);
5460 operands[3] = gen_lowpart (Pmode, operands[3]);
5461 operands[4] = gen_lowpart (Pmode, operands[4]);
5462 pat = gen_rtx_PLUS (Pmode,
5463 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5464 operands[2]),
5465 operands[3]),
5466 operands[4]);
5467 if (Pmode != SImode)
5468 pat = gen_rtx_SUBREG (SImode, pat, 0);
5469 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5470 DONE;
5471 }
5472 [(set_attr "type" "lea")
5473 (set_attr "mode" "SI")])
5474
5475 (define_insn_and_split "*lea_general_3_zext"
5476 [(set (match_operand:DI 0 "register_operand" "=r")
5477 (zero_extend:DI
5478 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5479 (match_operand:SI 2 "const248_operand" "n"))
5480 (match_operand:SI 3 "register_operand" "r"))
5481 (match_operand:SI 4 "immediate_operand" "i"))))]
5482 "TARGET_64BIT"
5483 "#"
5484 "&& reload_completed"
5485 [(set (match_dup 0)
5486 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5487 (match_dup 2))
5488 (match_dup 3))
5489 (match_dup 4)) 0)))]
5490 {
5491 operands[1] = gen_lowpart (Pmode, operands[1]);
5492 operands[3] = gen_lowpart (Pmode, operands[3]);
5493 operands[4] = gen_lowpart (Pmode, operands[4]);
5494 }
5495 [(set_attr "type" "lea")
5496 (set_attr "mode" "SI")])
5497
5498 (define_insn "*adddi_1_rex64"
5499 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5500 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5501 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5502 (clobber (reg:CC 17))]
5503 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5504 {
5505 switch (get_attr_type (insn))
5506 {
5507 case TYPE_LEA:
5508 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5509 return "lea{q}\t{%a2, %0|%0, %a2}";
5510
5511 case TYPE_INCDEC:
5512 if (! rtx_equal_p (operands[0], operands[1]))
5513 abort ();
5514 if (operands[2] == const1_rtx)
5515 return "inc{q}\t%0";
5516 else if (operands[2] == constm1_rtx)
5517 return "dec{q}\t%0";
5518 else
5519 abort ();
5520
5521 default:
5522 if (! rtx_equal_p (operands[0], operands[1]))
5523 abort ();
5524
5525 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5526 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5527 if (GET_CODE (operands[2]) == CONST_INT
5528 /* Avoid overflows. */
5529 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5530 && (INTVAL (operands[2]) == 128
5531 || (INTVAL (operands[2]) < 0
5532 && INTVAL (operands[2]) != -128)))
5533 {
5534 operands[2] = GEN_INT (-INTVAL (operands[2]));
5535 return "sub{q}\t{%2, %0|%0, %2}";
5536 }
5537 return "add{q}\t{%2, %0|%0, %2}";
5538 }
5539 }
5540 [(set (attr "type")
5541 (cond [(eq_attr "alternative" "2")
5542 (const_string "lea")
5543 ; Current assemblers are broken and do not allow @GOTOFF in
5544 ; ought but a memory context.
5545 (match_operand:DI 2 "pic_symbolic_operand" "")
5546 (const_string "lea")
5547 (match_operand:DI 2 "incdec_operand" "")
5548 (const_string "incdec")
5549 ]
5550 (const_string "alu")))
5551 (set_attr "mode" "DI")])
5552
5553 ;; Convert lea to the lea pattern to avoid flags dependency.
5554 (define_split
5555 [(set (match_operand:DI 0 "register_operand" "")
5556 (plus:DI (match_operand:DI 1 "register_operand" "")
5557 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5558 (clobber (reg:CC 17))]
5559 "TARGET_64BIT && reload_completed
5560 && true_regnum (operands[0]) != true_regnum (operands[1])"
5561 [(set (match_dup 0)
5562 (plus:DI (match_dup 1)
5563 (match_dup 2)))]
5564 "")
5565
5566 (define_insn "*adddi_2_rex64"
5567 [(set (reg 17)
5568 (compare
5569 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5570 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5571 (const_int 0)))
5572 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5573 (plus:DI (match_dup 1) (match_dup 2)))]
5574 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5575 && ix86_binary_operator_ok (PLUS, DImode, operands)
5576 /* Current assemblers are broken and do not allow @GOTOFF in
5577 ought but a memory context. */
5578 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5579 {
5580 switch (get_attr_type (insn))
5581 {
5582 case TYPE_INCDEC:
5583 if (! rtx_equal_p (operands[0], operands[1]))
5584 abort ();
5585 if (operands[2] == const1_rtx)
5586 return "inc{q}\t%0";
5587 else if (operands[2] == constm1_rtx)
5588 return "dec{q}\t%0";
5589 else
5590 abort ();
5591
5592 default:
5593 if (! rtx_equal_p (operands[0], operands[1]))
5594 abort ();
5595 /* ???? We ought to handle there the 32bit case too
5596 - do we need new constraint? */
5597 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5598 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5599 if (GET_CODE (operands[2]) == CONST_INT
5600 /* Avoid overflows. */
5601 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5602 && (INTVAL (operands[2]) == 128
5603 || (INTVAL (operands[2]) < 0
5604 && INTVAL (operands[2]) != -128)))
5605 {
5606 operands[2] = GEN_INT (-INTVAL (operands[2]));
5607 return "sub{q}\t{%2, %0|%0, %2}";
5608 }
5609 return "add{q}\t{%2, %0|%0, %2}";
5610 }
5611 }
5612 [(set (attr "type")
5613 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5614 (const_string "incdec")
5615 (const_string "alu")))
5616 (set_attr "mode" "DI")])
5617
5618 (define_insn "*adddi_3_rex64"
5619 [(set (reg 17)
5620 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5621 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5622 (clobber (match_scratch:DI 0 "=r"))]
5623 "TARGET_64BIT
5624 && ix86_match_ccmode (insn, CCZmode)
5625 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5626 /* Current assemblers are broken and do not allow @GOTOFF in
5627 ought but a memory context. */
5628 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5629 {
5630 switch (get_attr_type (insn))
5631 {
5632 case TYPE_INCDEC:
5633 if (! rtx_equal_p (operands[0], operands[1]))
5634 abort ();
5635 if (operands[2] == const1_rtx)
5636 return "inc{q}\t%0";
5637 else if (operands[2] == constm1_rtx)
5638 return "dec{q}\t%0";
5639 else
5640 abort ();
5641
5642 default:
5643 if (! rtx_equal_p (operands[0], operands[1]))
5644 abort ();
5645 /* ???? We ought to handle there the 32bit case too
5646 - do we need new constraint? */
5647 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5648 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5649 if (GET_CODE (operands[2]) == CONST_INT
5650 /* Avoid overflows. */
5651 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5652 && (INTVAL (operands[2]) == 128
5653 || (INTVAL (operands[2]) < 0
5654 && INTVAL (operands[2]) != -128)))
5655 {
5656 operands[2] = GEN_INT (-INTVAL (operands[2]));
5657 return "sub{q}\t{%2, %0|%0, %2}";
5658 }
5659 return "add{q}\t{%2, %0|%0, %2}";
5660 }
5661 }
5662 [(set (attr "type")
5663 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5664 (const_string "incdec")
5665 (const_string "alu")))
5666 (set_attr "mode" "DI")])
5667
5668 ; For comparisons against 1, -1 and 128, we may generate better code
5669 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5670 ; is matched then. We can't accept general immediate, because for
5671 ; case of overflows, the result is messed up.
5672 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5673 ; when negated.
5674 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5675 ; only for comparisons not depending on it.
5676 (define_insn "*adddi_4_rex64"
5677 [(set (reg 17)
5678 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5679 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5680 (clobber (match_scratch:DI 0 "=rm"))]
5681 "TARGET_64BIT
5682 && ix86_match_ccmode (insn, CCGCmode)"
5683 {
5684 switch (get_attr_type (insn))
5685 {
5686 case TYPE_INCDEC:
5687 if (operands[2] == constm1_rtx)
5688 return "inc{q}\t%0";
5689 else if (operands[2] == const1_rtx)
5690 return "dec{q}\t%0";
5691 else
5692 abort();
5693
5694 default:
5695 if (! rtx_equal_p (operands[0], operands[1]))
5696 abort ();
5697 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5698 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5699 if ((INTVAL (operands[2]) == -128
5700 || (INTVAL (operands[2]) > 0
5701 && INTVAL (operands[2]) != 128))
5702 /* Avoid overflows. */
5703 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5704 return "sub{q}\t{%2, %0|%0, %2}";
5705 operands[2] = GEN_INT (-INTVAL (operands[2]));
5706 return "add{q}\t{%2, %0|%0, %2}";
5707 }
5708 }
5709 [(set (attr "type")
5710 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5711 (const_string "incdec")
5712 (const_string "alu")))
5713 (set_attr "mode" "DI")])
5714
5715 (define_insn "*adddi_5_rex64"
5716 [(set (reg 17)
5717 (compare
5718 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5719 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5720 (const_int 0)))
5721 (clobber (match_scratch:DI 0 "=r"))]
5722 "TARGET_64BIT
5723 && ix86_match_ccmode (insn, CCGOCmode)
5724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5725 /* Current assemblers are broken and do not allow @GOTOFF in
5726 ought but a memory context. */
5727 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5728 {
5729 switch (get_attr_type (insn))
5730 {
5731 case TYPE_INCDEC:
5732 if (! rtx_equal_p (operands[0], operands[1]))
5733 abort ();
5734 if (operands[2] == const1_rtx)
5735 return "inc{q}\t%0";
5736 else if (operands[2] == constm1_rtx)
5737 return "dec{q}\t%0";
5738 else
5739 abort();
5740
5741 default:
5742 if (! rtx_equal_p (operands[0], operands[1]))
5743 abort ();
5744 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5745 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5746 if (GET_CODE (operands[2]) == CONST_INT
5747 /* Avoid overflows. */
5748 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5749 && (INTVAL (operands[2]) == 128
5750 || (INTVAL (operands[2]) < 0
5751 && INTVAL (operands[2]) != -128)))
5752 {
5753 operands[2] = GEN_INT (-INTVAL (operands[2]));
5754 return "sub{q}\t{%2, %0|%0, %2}";
5755 }
5756 return "add{q}\t{%2, %0|%0, %2}";
5757 }
5758 }
5759 [(set (attr "type")
5760 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5761 (const_string "incdec")
5762 (const_string "alu")))
5763 (set_attr "mode" "DI")])
5764
5765
5766 (define_insn "*addsi_1"
5767 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5768 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5769 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5770 (clobber (reg:CC 17))]
5771 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5772 {
5773 switch (get_attr_type (insn))
5774 {
5775 case TYPE_LEA:
5776 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5777 return "lea{l}\t{%a2, %0|%0, %a2}";
5778
5779 case TYPE_INCDEC:
5780 if (! rtx_equal_p (operands[0], operands[1]))
5781 abort ();
5782 if (operands[2] == const1_rtx)
5783 return "inc{l}\t%0";
5784 else if (operands[2] == constm1_rtx)
5785 return "dec{l}\t%0";
5786 else
5787 abort();
5788
5789 default:
5790 if (! rtx_equal_p (operands[0], operands[1]))
5791 abort ();
5792
5793 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5794 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5795 if (GET_CODE (operands[2]) == CONST_INT
5796 && (INTVAL (operands[2]) == 128
5797 || (INTVAL (operands[2]) < 0
5798 && INTVAL (operands[2]) != -128)))
5799 {
5800 operands[2] = GEN_INT (-INTVAL (operands[2]));
5801 return "sub{l}\t{%2, %0|%0, %2}";
5802 }
5803 return "add{l}\t{%2, %0|%0, %2}";
5804 }
5805 }
5806 [(set (attr "type")
5807 (cond [(eq_attr "alternative" "2")
5808 (const_string "lea")
5809 ; Current assemblers are broken and do not allow @GOTOFF in
5810 ; ought but a memory context.
5811 (match_operand:SI 2 "pic_symbolic_operand" "")
5812 (const_string "lea")
5813 (match_operand:SI 2 "incdec_operand" "")
5814 (const_string "incdec")
5815 ]
5816 (const_string "alu")))
5817 (set_attr "mode" "SI")])
5818
5819 ;; Convert lea to the lea pattern to avoid flags dependency.
5820 (define_split
5821 [(set (match_operand 0 "register_operand" "")
5822 (plus (match_operand 1 "register_operand" "")
5823 (match_operand 2 "nonmemory_operand" "")))
5824 (clobber (reg:CC 17))]
5825 "reload_completed
5826 && true_regnum (operands[0]) != true_regnum (operands[1])"
5827 [(const_int 0)]
5828 {
5829 rtx pat;
5830 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5831 may confuse gen_lowpart. */
5832 if (GET_MODE (operands[0]) != Pmode)
5833 {
5834 operands[1] = gen_lowpart (Pmode, operands[1]);
5835 operands[2] = gen_lowpart (Pmode, operands[2]);
5836 }
5837 operands[0] = gen_lowpart (SImode, operands[0]);
5838 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5839 if (Pmode != SImode)
5840 pat = gen_rtx_SUBREG (SImode, pat, 0);
5841 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5842 DONE;
5843 })
5844
5845 ;; It may seem that nonimmediate operand is proper one for operand 1.
5846 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5847 ;; we take care in ix86_binary_operator_ok to not allow two memory
5848 ;; operands so proper swapping will be done in reload. This allow
5849 ;; patterns constructed from addsi_1 to match.
5850 (define_insn "addsi_1_zext"
5851 [(set (match_operand:DI 0 "register_operand" "=r,r")
5852 (zero_extend:DI
5853 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5854 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5855 (clobber (reg:CC 17))]
5856 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5857 {
5858 switch (get_attr_type (insn))
5859 {
5860 case TYPE_LEA:
5861 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5862 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5863
5864 case TYPE_INCDEC:
5865 if (operands[2] == const1_rtx)
5866 return "inc{l}\t%k0";
5867 else if (operands[2] == constm1_rtx)
5868 return "dec{l}\t%k0";
5869 else
5870 abort();
5871
5872 default:
5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5875 if (GET_CODE (operands[2]) == CONST_INT
5876 && (INTVAL (operands[2]) == 128
5877 || (INTVAL (operands[2]) < 0
5878 && INTVAL (operands[2]) != -128)))
5879 {
5880 operands[2] = GEN_INT (-INTVAL (operands[2]));
5881 return "sub{l}\t{%2, %k0|%k0, %2}";
5882 }
5883 return "add{l}\t{%2, %k0|%k0, %2}";
5884 }
5885 }
5886 [(set (attr "type")
5887 (cond [(eq_attr "alternative" "1")
5888 (const_string "lea")
5889 ; Current assemblers are broken and do not allow @GOTOFF in
5890 ; ought but a memory context.
5891 (match_operand:SI 2 "pic_symbolic_operand" "")
5892 (const_string "lea")
5893 (match_operand:SI 2 "incdec_operand" "")
5894 (const_string "incdec")
5895 ]
5896 (const_string "alu")))
5897 (set_attr "mode" "SI")])
5898
5899 ;; Convert lea to the lea pattern to avoid flags dependency.
5900 (define_split
5901 [(set (match_operand:DI 0 "register_operand" "")
5902 (zero_extend:DI
5903 (plus:SI (match_operand:SI 1 "register_operand" "")
5904 (match_operand:SI 2 "nonmemory_operand" ""))))
5905 (clobber (reg:CC 17))]
5906 "TARGET_64BIT && reload_completed
5907 && true_regnum (operands[0]) != true_regnum (operands[1])"
5908 [(set (match_dup 0)
5909 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5910 {
5911 operands[1] = gen_lowpart (Pmode, operands[1]);
5912 operands[2] = gen_lowpart (Pmode, operands[2]);
5913 })
5914
5915 (define_insn "*addsi_2"
5916 [(set (reg 17)
5917 (compare
5918 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5919 (match_operand:SI 2 "general_operand" "rmni,rni"))
5920 (const_int 0)))
5921 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5922 (plus:SI (match_dup 1) (match_dup 2)))]
5923 "ix86_match_ccmode (insn, CCGOCmode)
5924 && ix86_binary_operator_ok (PLUS, SImode, operands)
5925 /* Current assemblers are broken and do not allow @GOTOFF in
5926 ought but a memory context. */
5927 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5928 {
5929 switch (get_attr_type (insn))
5930 {
5931 case TYPE_INCDEC:
5932 if (! rtx_equal_p (operands[0], operands[1]))
5933 abort ();
5934 if (operands[2] == const1_rtx)
5935 return "inc{l}\t%0";
5936 else if (operands[2] == constm1_rtx)
5937 return "dec{l}\t%0";
5938 else
5939 abort();
5940
5941 default:
5942 if (! rtx_equal_p (operands[0], operands[1]))
5943 abort ();
5944 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5945 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5946 if (GET_CODE (operands[2]) == CONST_INT
5947 && (INTVAL (operands[2]) == 128
5948 || (INTVAL (operands[2]) < 0
5949 && INTVAL (operands[2]) != -128)))
5950 {
5951 operands[2] = GEN_INT (-INTVAL (operands[2]));
5952 return "sub{l}\t{%2, %0|%0, %2}";
5953 }
5954 return "add{l}\t{%2, %0|%0, %2}";
5955 }
5956 }
5957 [(set (attr "type")
5958 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5959 (const_string "incdec")
5960 (const_string "alu")))
5961 (set_attr "mode" "SI")])
5962
5963 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5964 (define_insn "*addsi_2_zext"
5965 [(set (reg 17)
5966 (compare
5967 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5968 (match_operand:SI 2 "general_operand" "rmni"))
5969 (const_int 0)))
5970 (set (match_operand:DI 0 "register_operand" "=r")
5971 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5972 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5973 && ix86_binary_operator_ok (PLUS, SImode, operands)
5974 /* Current assemblers are broken and do not allow @GOTOFF in
5975 ought but a memory context. */
5976 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5977 {
5978 switch (get_attr_type (insn))
5979 {
5980 case TYPE_INCDEC:
5981 if (operands[2] == const1_rtx)
5982 return "inc{l}\t%k0";
5983 else if (operands[2] == constm1_rtx)
5984 return "dec{l}\t%k0";
5985 else
5986 abort();
5987
5988 default:
5989 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5990 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5991 if (GET_CODE (operands[2]) == CONST_INT
5992 && (INTVAL (operands[2]) == 128
5993 || (INTVAL (operands[2]) < 0
5994 && INTVAL (operands[2]) != -128)))
5995 {
5996 operands[2] = GEN_INT (-INTVAL (operands[2]));
5997 return "sub{l}\t{%2, %k0|%k0, %2}";
5998 }
5999 return "add{l}\t{%2, %k0|%k0, %2}";
6000 }
6001 }
6002 [(set (attr "type")
6003 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6004 (const_string "incdec")
6005 (const_string "alu")))
6006 (set_attr "mode" "SI")])
6007
6008 (define_insn "*addsi_3"
6009 [(set (reg 17)
6010 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6011 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6012 (clobber (match_scratch:SI 0 "=r"))]
6013 "ix86_match_ccmode (insn, CCZmode)
6014 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6015 /* Current assemblers are broken and do not allow @GOTOFF in
6016 ought but a memory context. */
6017 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6018 {
6019 switch (get_attr_type (insn))
6020 {
6021 case TYPE_INCDEC:
6022 if (! rtx_equal_p (operands[0], operands[1]))
6023 abort ();
6024 if (operands[2] == const1_rtx)
6025 return "inc{l}\t%0";
6026 else if (operands[2] == constm1_rtx)
6027 return "dec{l}\t%0";
6028 else
6029 abort();
6030
6031 default:
6032 if (! rtx_equal_p (operands[0], operands[1]))
6033 abort ();
6034 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6036 if (GET_CODE (operands[2]) == CONST_INT
6037 && (INTVAL (operands[2]) == 128
6038 || (INTVAL (operands[2]) < 0
6039 && INTVAL (operands[2]) != -128)))
6040 {
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "sub{l}\t{%2, %0|%0, %2}";
6043 }
6044 return "add{l}\t{%2, %0|%0, %2}";
6045 }
6046 }
6047 [(set (attr "type")
6048 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6049 (const_string "incdec")
6050 (const_string "alu")))
6051 (set_attr "mode" "SI")])
6052
6053 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6054 (define_insn "*addsi_3_zext"
6055 [(set (reg 17)
6056 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6057 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6058 (set (match_operand:DI 0 "register_operand" "=r")
6059 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6060 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6061 && ix86_binary_operator_ok (PLUS, SImode, operands)
6062 /* Current assemblers are broken and do not allow @GOTOFF in
6063 ought but a memory context. */
6064 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6065 {
6066 switch (get_attr_type (insn))
6067 {
6068 case TYPE_INCDEC:
6069 if (operands[2] == const1_rtx)
6070 return "inc{l}\t%k0";
6071 else if (operands[2] == constm1_rtx)
6072 return "dec{l}\t%k0";
6073 else
6074 abort();
6075
6076 default:
6077 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6078 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6079 if (GET_CODE (operands[2]) == CONST_INT
6080 && (INTVAL (operands[2]) == 128
6081 || (INTVAL (operands[2]) < 0
6082 && INTVAL (operands[2]) != -128)))
6083 {
6084 operands[2] = GEN_INT (-INTVAL (operands[2]));
6085 return "sub{l}\t{%2, %k0|%k0, %2}";
6086 }
6087 return "add{l}\t{%2, %k0|%k0, %2}";
6088 }
6089 }
6090 [(set (attr "type")
6091 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6092 (const_string "incdec")
6093 (const_string "alu")))
6094 (set_attr "mode" "SI")])
6095
6096 ; For comparisons against 1, -1 and 128, we may generate better code
6097 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6098 ; is matched then. We can't accept general immediate, because for
6099 ; case of overflows, the result is messed up.
6100 ; This pattern also don't hold of 0x80000000, since the value overflows
6101 ; when negated.
6102 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6103 ; only for comparisons not depending on it.
6104 (define_insn "*addsi_4"
6105 [(set (reg 17)
6106 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6107 (match_operand:SI 2 "const_int_operand" "n")))
6108 (clobber (match_scratch:SI 0 "=rm"))]
6109 "ix86_match_ccmode (insn, CCGCmode)
6110 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6111 {
6112 switch (get_attr_type (insn))
6113 {
6114 case TYPE_INCDEC:
6115 if (operands[2] == constm1_rtx)
6116 return "inc{l}\t%0";
6117 else if (operands[2] == const1_rtx)
6118 return "dec{l}\t%0";
6119 else
6120 abort();
6121
6122 default:
6123 if (! rtx_equal_p (operands[0], operands[1]))
6124 abort ();
6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if ((INTVAL (operands[2]) == -128
6128 || (INTVAL (operands[2]) > 0
6129 && INTVAL (operands[2]) != 128)))
6130 return "sub{l}\t{%2, %0|%0, %2}";
6131 operands[2] = GEN_INT (-INTVAL (operands[2]));
6132 return "add{l}\t{%2, %0|%0, %2}";
6133 }
6134 }
6135 [(set (attr "type")
6136 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6137 (const_string "incdec")
6138 (const_string "alu")))
6139 (set_attr "mode" "SI")])
6140
6141 (define_insn "*addsi_5"
6142 [(set (reg 17)
6143 (compare
6144 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6145 (match_operand:SI 2 "general_operand" "rmni"))
6146 (const_int 0)))
6147 (clobber (match_scratch:SI 0 "=r"))]
6148 "ix86_match_ccmode (insn, CCGOCmode)
6149 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6150 /* Current assemblers are broken and do not allow @GOTOFF in
6151 ought but a memory context. */
6152 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6153 {
6154 switch (get_attr_type (insn))
6155 {
6156 case TYPE_INCDEC:
6157 if (! rtx_equal_p (operands[0], operands[1]))
6158 abort ();
6159 if (operands[2] == const1_rtx)
6160 return "inc{l}\t%0";
6161 else if (operands[2] == constm1_rtx)
6162 return "dec{l}\t%0";
6163 else
6164 abort();
6165
6166 default:
6167 if (! rtx_equal_p (operands[0], operands[1]))
6168 abort ();
6169 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6170 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6171 if (GET_CODE (operands[2]) == CONST_INT
6172 && (INTVAL (operands[2]) == 128
6173 || (INTVAL (operands[2]) < 0
6174 && INTVAL (operands[2]) != -128)))
6175 {
6176 operands[2] = GEN_INT (-INTVAL (operands[2]));
6177 return "sub{l}\t{%2, %0|%0, %2}";
6178 }
6179 return "add{l}\t{%2, %0|%0, %2}";
6180 }
6181 }
6182 [(set (attr "type")
6183 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6184 (const_string "incdec")
6185 (const_string "alu")))
6186 (set_attr "mode" "SI")])
6187
6188 (define_expand "addhi3"
6189 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6190 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6191 (match_operand:HI 2 "general_operand" "")))
6192 (clobber (reg:CC 17))])]
6193 "TARGET_HIMODE_MATH"
6194 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6195
6196 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6197 ;; type optimizations enabled by define-splits. This is not important
6198 ;; for PII, and in fact harmful because of partial register stalls.
6199
6200 (define_insn "*addhi_1_lea"
6201 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6202 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6203 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6204 (clobber (reg:CC 17))]
6205 "!TARGET_PARTIAL_REG_STALL
6206 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6207 {
6208 switch (get_attr_type (insn))
6209 {
6210 case TYPE_LEA:
6211 return "#";
6212 case TYPE_INCDEC:
6213 if (operands[2] == const1_rtx)
6214 return "inc{w}\t%0";
6215 else if (operands[2] == constm1_rtx)
6216 return "dec{w}\t%0";
6217 abort();
6218
6219 default:
6220 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6221 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6222 if (GET_CODE (operands[2]) == CONST_INT
6223 && (INTVAL (operands[2]) == 128
6224 || (INTVAL (operands[2]) < 0
6225 && INTVAL (operands[2]) != -128)))
6226 {
6227 operands[2] = GEN_INT (-INTVAL (operands[2]));
6228 return "sub{w}\t{%2, %0|%0, %2}";
6229 }
6230 return "add{w}\t{%2, %0|%0, %2}";
6231 }
6232 }
6233 [(set (attr "type")
6234 (if_then_else (eq_attr "alternative" "2")
6235 (const_string "lea")
6236 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6237 (const_string "incdec")
6238 (const_string "alu"))))
6239 (set_attr "mode" "HI,HI,SI")])
6240
6241 (define_insn "*addhi_1"
6242 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6243 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6244 (match_operand:HI 2 "general_operand" "ri,rm")))
6245 (clobber (reg:CC 17))]
6246 "TARGET_PARTIAL_REG_STALL
6247 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6248 {
6249 switch (get_attr_type (insn))
6250 {
6251 case TYPE_INCDEC:
6252 if (operands[2] == const1_rtx)
6253 return "inc{w}\t%0";
6254 else if (operands[2] == constm1_rtx)
6255 return "dec{w}\t%0";
6256 abort();
6257
6258 default:
6259 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6260 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6261 if (GET_CODE (operands[2]) == CONST_INT
6262 && (INTVAL (operands[2]) == 128
6263 || (INTVAL (operands[2]) < 0
6264 && INTVAL (operands[2]) != -128)))
6265 {
6266 operands[2] = GEN_INT (-INTVAL (operands[2]));
6267 return "sub{w}\t{%2, %0|%0, %2}";
6268 }
6269 return "add{w}\t{%2, %0|%0, %2}";
6270 }
6271 }
6272 [(set (attr "type")
6273 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6274 (const_string "incdec")
6275 (const_string "alu")))
6276 (set_attr "mode" "HI")])
6277
6278 (define_insn "*addhi_2"
6279 [(set (reg 17)
6280 (compare
6281 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6282 (match_operand:HI 2 "general_operand" "rmni,rni"))
6283 (const_int 0)))
6284 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6285 (plus:HI (match_dup 1) (match_dup 2)))]
6286 "ix86_match_ccmode (insn, CCGOCmode)
6287 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6288 {
6289 switch (get_attr_type (insn))
6290 {
6291 case TYPE_INCDEC:
6292 if (operands[2] == const1_rtx)
6293 return "inc{w}\t%0";
6294 else if (operands[2] == constm1_rtx)
6295 return "dec{w}\t%0";
6296 abort();
6297
6298 default:
6299 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6300 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6301 if (GET_CODE (operands[2]) == CONST_INT
6302 && (INTVAL (operands[2]) == 128
6303 || (INTVAL (operands[2]) < 0
6304 && INTVAL (operands[2]) != -128)))
6305 {
6306 operands[2] = GEN_INT (-INTVAL (operands[2]));
6307 return "sub{w}\t{%2, %0|%0, %2}";
6308 }
6309 return "add{w}\t{%2, %0|%0, %2}";
6310 }
6311 }
6312 [(set (attr "type")
6313 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6314 (const_string "incdec")
6315 (const_string "alu")))
6316 (set_attr "mode" "HI")])
6317
6318 (define_insn "*addhi_3"
6319 [(set (reg 17)
6320 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6321 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6322 (clobber (match_scratch:HI 0 "=r"))]
6323 "ix86_match_ccmode (insn, CCZmode)
6324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6325 {
6326 switch (get_attr_type (insn))
6327 {
6328 case TYPE_INCDEC:
6329 if (operands[2] == const1_rtx)
6330 return "inc{w}\t%0";
6331 else if (operands[2] == constm1_rtx)
6332 return "dec{w}\t%0";
6333 abort();
6334
6335 default:
6336 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6337 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6338 if (GET_CODE (operands[2]) == CONST_INT
6339 && (INTVAL (operands[2]) == 128
6340 || (INTVAL (operands[2]) < 0
6341 && INTVAL (operands[2]) != -128)))
6342 {
6343 operands[2] = GEN_INT (-INTVAL (operands[2]));
6344 return "sub{w}\t{%2, %0|%0, %2}";
6345 }
6346 return "add{w}\t{%2, %0|%0, %2}";
6347 }
6348 }
6349 [(set (attr "type")
6350 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6351 (const_string "incdec")
6352 (const_string "alu")))
6353 (set_attr "mode" "HI")])
6354
6355 ; See comments above addsi_3_imm for details.
6356 (define_insn "*addhi_4"
6357 [(set (reg 17)
6358 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6359 (match_operand:HI 2 "const_int_operand" "n")))
6360 (clobber (match_scratch:HI 0 "=rm"))]
6361 "ix86_match_ccmode (insn, CCGCmode)
6362 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6363 {
6364 switch (get_attr_type (insn))
6365 {
6366 case TYPE_INCDEC:
6367 if (operands[2] == constm1_rtx)
6368 return "inc{w}\t%0";
6369 else if (operands[2] == const1_rtx)
6370 return "dec{w}\t%0";
6371 else
6372 abort();
6373
6374 default:
6375 if (! rtx_equal_p (operands[0], operands[1]))
6376 abort ();
6377 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6378 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6379 if ((INTVAL (operands[2]) == -128
6380 || (INTVAL (operands[2]) > 0
6381 && INTVAL (operands[2]) != 128)))
6382 return "sub{w}\t{%2, %0|%0, %2}";
6383 operands[2] = GEN_INT (-INTVAL (operands[2]));
6384 return "add{w}\t{%2, %0|%0, %2}";
6385 }
6386 }
6387 [(set (attr "type")
6388 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6389 (const_string "incdec")
6390 (const_string "alu")))
6391 (set_attr "mode" "SI")])
6392
6393
6394 (define_insn "*addhi_5"
6395 [(set (reg 17)
6396 (compare
6397 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6398 (match_operand:HI 2 "general_operand" "rmni"))
6399 (const_int 0)))
6400 (clobber (match_scratch:HI 0 "=r"))]
6401 "ix86_match_ccmode (insn, CCGOCmode)
6402 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6403 {
6404 switch (get_attr_type (insn))
6405 {
6406 case TYPE_INCDEC:
6407 if (operands[2] == const1_rtx)
6408 return "inc{w}\t%0";
6409 else if (operands[2] == constm1_rtx)
6410 return "dec{w}\t%0";
6411 abort();
6412
6413 default:
6414 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6415 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6416 if (GET_CODE (operands[2]) == CONST_INT
6417 && (INTVAL (operands[2]) == 128
6418 || (INTVAL (operands[2]) < 0
6419 && INTVAL (operands[2]) != -128)))
6420 {
6421 operands[2] = GEN_INT (-INTVAL (operands[2]));
6422 return "sub{w}\t{%2, %0|%0, %2}";
6423 }
6424 return "add{w}\t{%2, %0|%0, %2}";
6425 }
6426 }
6427 [(set (attr "type")
6428 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "HI")])
6432
6433 (define_expand "addqi3"
6434 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6435 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6436 (match_operand:QI 2 "general_operand" "")))
6437 (clobber (reg:CC 17))])]
6438 "TARGET_QIMODE_MATH"
6439 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6440
6441 ;; %%% Potential partial reg stall on alternative 2. What to do?
6442 (define_insn "*addqi_1_lea"
6443 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6444 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6445 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6446 (clobber (reg:CC 17))]
6447 "!TARGET_PARTIAL_REG_STALL
6448 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6449 {
6450 int widen = (which_alternative == 2);
6451 switch (get_attr_type (insn))
6452 {
6453 case TYPE_LEA:
6454 return "#";
6455 case TYPE_INCDEC:
6456 if (operands[2] == const1_rtx)
6457 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6458 else if (operands[2] == constm1_rtx)
6459 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6460 abort();
6461
6462 default:
6463 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6464 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6465 if (GET_CODE (operands[2]) == CONST_INT
6466 && (INTVAL (operands[2]) == 128
6467 || (INTVAL (operands[2]) < 0
6468 && INTVAL (operands[2]) != -128)))
6469 {
6470 operands[2] = GEN_INT (-INTVAL (operands[2]));
6471 if (widen)
6472 return "sub{l}\t{%2, %k0|%k0, %2}";
6473 else
6474 return "sub{b}\t{%2, %0|%0, %2}";
6475 }
6476 if (widen)
6477 return "add{l}\t{%k2, %k0|%k0, %k2}";
6478 else
6479 return "add{b}\t{%2, %0|%0, %2}";
6480 }
6481 }
6482 [(set (attr "type")
6483 (if_then_else (eq_attr "alternative" "3")
6484 (const_string "lea")
6485 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6486 (const_string "incdec")
6487 (const_string "alu"))))
6488 (set_attr "mode" "QI,QI,SI,SI")])
6489
6490 (define_insn "*addqi_1"
6491 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6492 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6493 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6494 (clobber (reg:CC 17))]
6495 "TARGET_PARTIAL_REG_STALL
6496 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6497 {
6498 int widen = (which_alternative == 2);
6499 switch (get_attr_type (insn))
6500 {
6501 case TYPE_INCDEC:
6502 if (operands[2] == const1_rtx)
6503 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6504 else if (operands[2] == constm1_rtx)
6505 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6506 abort();
6507
6508 default:
6509 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6510 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6511 if (GET_CODE (operands[2]) == CONST_INT
6512 && (INTVAL (operands[2]) == 128
6513 || (INTVAL (operands[2]) < 0
6514 && INTVAL (operands[2]) != -128)))
6515 {
6516 operands[2] = GEN_INT (-INTVAL (operands[2]));
6517 if (widen)
6518 return "sub{l}\t{%2, %k0|%k0, %2}";
6519 else
6520 return "sub{b}\t{%2, %0|%0, %2}";
6521 }
6522 if (widen)
6523 return "add{l}\t{%k2, %k0|%k0, %k2}";
6524 else
6525 return "add{b}\t{%2, %0|%0, %2}";
6526 }
6527 }
6528 [(set (attr "type")
6529 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6530 (const_string "incdec")
6531 (const_string "alu")))
6532 (set_attr "mode" "QI,QI,SI")])
6533
6534 (define_insn "*addqi_1_slp"
6535 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6536 (plus:QI (match_dup 0)
6537 (match_operand:QI 1 "general_operand" "qn,qnm")))
6538 (clobber (reg:CC 17))]
6539 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6540 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6541 {
6542 switch (get_attr_type (insn))
6543 {
6544 case TYPE_INCDEC:
6545 if (operands[1] == const1_rtx)
6546 return "inc{b}\t%0";
6547 else if (operands[1] == constm1_rtx)
6548 return "dec{b}\t%0";
6549 abort();
6550
6551 default:
6552 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6553 if (GET_CODE (operands[1]) == CONST_INT
6554 && INTVAL (operands[1]) < 0)
6555 {
6556 operands[2] = GEN_INT (-INTVAL (operands[2]));
6557 return "sub{b}\t{%1, %0|%0, %1}";
6558 }
6559 return "add{b}\t{%1, %0|%0, %1}";
6560 }
6561 }
6562 [(set (attr "type")
6563 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6564 (const_string "incdec")
6565 (const_string "alu1")))
6566 (set_attr "mode" "QI")])
6567
6568 (define_insn "*addqi_2"
6569 [(set (reg 17)
6570 (compare
6571 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6572 (match_operand:QI 2 "general_operand" "qmni,qni"))
6573 (const_int 0)))
6574 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6575 (plus:QI (match_dup 1) (match_dup 2)))]
6576 "ix86_match_ccmode (insn, CCGOCmode)
6577 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6578 {
6579 switch (get_attr_type (insn))
6580 {
6581 case TYPE_INCDEC:
6582 if (operands[2] == const1_rtx)
6583 return "inc{b}\t%0";
6584 else if (operands[2] == constm1_rtx
6585 || (GET_CODE (operands[2]) == CONST_INT
6586 && INTVAL (operands[2]) == 255))
6587 return "dec{b}\t%0";
6588 abort();
6589
6590 default:
6591 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6592 if (GET_CODE (operands[2]) == CONST_INT
6593 && INTVAL (operands[2]) < 0)
6594 {
6595 operands[2] = GEN_INT (-INTVAL (operands[2]));
6596 return "sub{b}\t{%2, %0|%0, %2}";
6597 }
6598 return "add{b}\t{%2, %0|%0, %2}";
6599 }
6600 }
6601 [(set (attr "type")
6602 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6603 (const_string "incdec")
6604 (const_string "alu")))
6605 (set_attr "mode" "QI")])
6606
6607 (define_insn "*addqi_3"
6608 [(set (reg 17)
6609 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6610 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6611 (clobber (match_scratch:QI 0 "=q"))]
6612 "ix86_match_ccmode (insn, CCZmode)
6613 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6614 {
6615 switch (get_attr_type (insn))
6616 {
6617 case TYPE_INCDEC:
6618 if (operands[2] == const1_rtx)
6619 return "inc{b}\t%0";
6620 else if (operands[2] == constm1_rtx
6621 || (GET_CODE (operands[2]) == CONST_INT
6622 && INTVAL (operands[2]) == 255))
6623 return "dec{b}\t%0";
6624 abort();
6625
6626 default:
6627 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6628 if (GET_CODE (operands[2]) == CONST_INT
6629 && INTVAL (operands[2]) < 0)
6630 {
6631 operands[2] = GEN_INT (-INTVAL (operands[2]));
6632 return "sub{b}\t{%2, %0|%0, %2}";
6633 }
6634 return "add{b}\t{%2, %0|%0, %2}";
6635 }
6636 }
6637 [(set (attr "type")
6638 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6639 (const_string "incdec")
6640 (const_string "alu")))
6641 (set_attr "mode" "QI")])
6642
6643 ; See comments above addsi_3_imm for details.
6644 (define_insn "*addqi_4"
6645 [(set (reg 17)
6646 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6647 (match_operand:QI 2 "const_int_operand" "n")))
6648 (clobber (match_scratch:QI 0 "=qm"))]
6649 "ix86_match_ccmode (insn, CCGCmode)
6650 && (INTVAL (operands[2]) & 0xff) != 0x80"
6651 {
6652 switch (get_attr_type (insn))
6653 {
6654 case TYPE_INCDEC:
6655 if (operands[2] == constm1_rtx
6656 || (GET_CODE (operands[2]) == CONST_INT
6657 && INTVAL (operands[2]) == 255))
6658 return "inc{b}\t%0";
6659 else if (operands[2] == const1_rtx)
6660 return "dec{b}\t%0";
6661 else
6662 abort();
6663
6664 default:
6665 if (! rtx_equal_p (operands[0], operands[1]))
6666 abort ();
6667 if (INTVAL (operands[2]) < 0)
6668 {
6669 operands[2] = GEN_INT (-INTVAL (operands[2]));
6670 return "add{b}\t{%2, %0|%0, %2}";
6671 }
6672 return "sub{b}\t{%2, %0|%0, %2}";
6673 }
6674 }
6675 [(set (attr "type")
6676 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6677 (const_string "incdec")
6678 (const_string "alu")))
6679 (set_attr "mode" "QI")])
6680
6681
6682 (define_insn "*addqi_5"
6683 [(set (reg 17)
6684 (compare
6685 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6686 (match_operand:QI 2 "general_operand" "qmni"))
6687 (const_int 0)))
6688 (clobber (match_scratch:QI 0 "=q"))]
6689 "ix86_match_ccmode (insn, CCGOCmode)
6690 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6691 {
6692 switch (get_attr_type (insn))
6693 {
6694 case TYPE_INCDEC:
6695 if (operands[2] == const1_rtx)
6696 return "inc{b}\t%0";
6697 else if (operands[2] == constm1_rtx
6698 || (GET_CODE (operands[2]) == CONST_INT
6699 && INTVAL (operands[2]) == 255))
6700 return "dec{b}\t%0";
6701 abort();
6702
6703 default:
6704 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6705 if (GET_CODE (operands[2]) == CONST_INT
6706 && INTVAL (operands[2]) < 0)
6707 {
6708 operands[2] = GEN_INT (-INTVAL (operands[2]));
6709 return "sub{b}\t{%2, %0|%0, %2}";
6710 }
6711 return "add{b}\t{%2, %0|%0, %2}";
6712 }
6713 }
6714 [(set (attr "type")
6715 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6716 (const_string "incdec")
6717 (const_string "alu")))
6718 (set_attr "mode" "QI")])
6719
6720
6721 (define_insn "addqi_ext_1"
6722 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6723 (const_int 8)
6724 (const_int 8))
6725 (plus:SI
6726 (zero_extract:SI
6727 (match_operand 1 "ext_register_operand" "0")
6728 (const_int 8)
6729 (const_int 8))
6730 (match_operand:QI 2 "general_operand" "Qmn")))
6731 (clobber (reg:CC 17))]
6732 "!TARGET_64BIT"
6733 {
6734 switch (get_attr_type (insn))
6735 {
6736 case TYPE_INCDEC:
6737 if (operands[2] == const1_rtx)
6738 return "inc{b}\t%h0";
6739 else if (operands[2] == constm1_rtx
6740 || (GET_CODE (operands[2]) == CONST_INT
6741 && INTVAL (operands[2]) == 255))
6742 return "dec{b}\t%h0";
6743 abort();
6744
6745 default:
6746 return "add{b}\t{%2, %h0|%h0, %2}";
6747 }
6748 }
6749 [(set (attr "type")
6750 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6751 (const_string "incdec")
6752 (const_string "alu")))
6753 (set_attr "mode" "QI")])
6754
6755 (define_insn "*addqi_ext_1_rex64"
6756 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6757 (const_int 8)
6758 (const_int 8))
6759 (plus:SI
6760 (zero_extract:SI
6761 (match_operand 1 "ext_register_operand" "0")
6762 (const_int 8)
6763 (const_int 8))
6764 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6765 (clobber (reg:CC 17))]
6766 "TARGET_64BIT"
6767 {
6768 switch (get_attr_type (insn))
6769 {
6770 case TYPE_INCDEC:
6771 if (operands[2] == const1_rtx)
6772 return "inc{b}\t%h0";
6773 else if (operands[2] == constm1_rtx
6774 || (GET_CODE (operands[2]) == CONST_INT
6775 && INTVAL (operands[2]) == 255))
6776 return "dec{b}\t%h0";
6777 abort();
6778
6779 default:
6780 return "add{b}\t{%2, %h0|%h0, %2}";
6781 }
6782 }
6783 [(set (attr "type")
6784 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6785 (const_string "incdec")
6786 (const_string "alu")))
6787 (set_attr "mode" "QI")])
6788
6789 (define_insn "*addqi_ext_2"
6790 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6791 (const_int 8)
6792 (const_int 8))
6793 (plus:SI
6794 (zero_extract:SI
6795 (match_operand 1 "ext_register_operand" "%0")
6796 (const_int 8)
6797 (const_int 8))
6798 (zero_extract:SI
6799 (match_operand 2 "ext_register_operand" "Q")
6800 (const_int 8)
6801 (const_int 8))))
6802 (clobber (reg:CC 17))]
6803 ""
6804 "add{b}\t{%h2, %h0|%h0, %h2}"
6805 [(set_attr "type" "alu")
6806 (set_attr "mode" "QI")])
6807
6808 ;; The patterns that match these are at the end of this file.
6809
6810 (define_expand "addxf3"
6811 [(set (match_operand:XF 0 "register_operand" "")
6812 (plus:XF (match_operand:XF 1 "register_operand" "")
6813 (match_operand:XF 2 "register_operand" "")))]
6814 "!TARGET_64BIT && TARGET_80387"
6815 "")
6816
6817 (define_expand "addtf3"
6818 [(set (match_operand:TF 0 "register_operand" "")
6819 (plus:TF (match_operand:TF 1 "register_operand" "")
6820 (match_operand:TF 2 "register_operand" "")))]
6821 "TARGET_80387"
6822 "")
6823
6824 (define_expand "adddf3"
6825 [(set (match_operand:DF 0 "register_operand" "")
6826 (plus:DF (match_operand:DF 1 "register_operand" "")
6827 (match_operand:DF 2 "nonimmediate_operand" "")))]
6828 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6829 "")
6830
6831 (define_expand "addsf3"
6832 [(set (match_operand:SF 0 "register_operand" "")
6833 (plus:SF (match_operand:SF 1 "register_operand" "")
6834 (match_operand:SF 2 "nonimmediate_operand" "")))]
6835 "TARGET_80387 || TARGET_SSE_MATH"
6836 "")
6837 \f
6838 ;; Subtract instructions
6839
6840 ;; %%% splits for subsidi3
6841
6842 (define_expand "subdi3"
6843 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6844 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6845 (match_operand:DI 2 "x86_64_general_operand" "")))
6846 (clobber (reg:CC 17))])]
6847 ""
6848 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6849
6850 (define_insn "*subdi3_1"
6851 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6852 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6853 (match_operand:DI 2 "general_operand" "roiF,riF")))
6854 (clobber (reg:CC 17))]
6855 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6856 "#")
6857
6858 (define_split
6859 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6860 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6861 (match_operand:DI 2 "general_operand" "")))
6862 (clobber (reg:CC 17))]
6863 "!TARGET_64BIT && reload_completed"
6864 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6865 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6866 (parallel [(set (match_dup 3)
6867 (minus:SI (match_dup 4)
6868 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6869 (match_dup 5))))
6870 (clobber (reg:CC 17))])]
6871 "split_di (operands+0, 1, operands+0, operands+3);
6872 split_di (operands+1, 1, operands+1, operands+4);
6873 split_di (operands+2, 1, operands+2, operands+5);")
6874
6875 (define_insn "subdi3_carry_rex64"
6876 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6877 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6878 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6879 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6880 (clobber (reg:CC 17))]
6881 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6882 "sbb{q}\t{%2, %0|%0, %2}"
6883 [(set_attr "type" "alu")
6884 (set_attr "pent_pair" "pu")
6885 (set_attr "ppro_uops" "few")
6886 (set_attr "mode" "DI")])
6887
6888 (define_insn "*subdi_1_rex64"
6889 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6890 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6891 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6892 (clobber (reg:CC 17))]
6893 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6894 "sub{q}\t{%2, %0|%0, %2}"
6895 [(set_attr "type" "alu")
6896 (set_attr "mode" "DI")])
6897
6898 (define_insn "*subdi_2_rex64"
6899 [(set (reg 17)
6900 (compare
6901 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6902 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6903 (const_int 0)))
6904 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6905 (minus:DI (match_dup 1) (match_dup 2)))]
6906 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6907 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6908 "sub{q}\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "alu")
6910 (set_attr "mode" "DI")])
6911
6912 (define_insn "*subdi_3_rex63"
6913 [(set (reg 17)
6914 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6915 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6916 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6917 (minus:DI (match_dup 1) (match_dup 2)))]
6918 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6919 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6920 "sub{q}\t{%2, %0|%0, %2}"
6921 [(set_attr "type" "alu")
6922 (set_attr "mode" "DI")])
6923
6924 (define_insn "subqi3_carry"
6925 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6926 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6927 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6928 (match_operand:QI 2 "general_operand" "ri,rm"))))
6929 (clobber (reg:CC 17))]
6930 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6931 "sbb{b}\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" "QI")])
6936
6937 (define_insn "subhi3_carry"
6938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6939 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6940 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6941 (match_operand:HI 2 "general_operand" "ri,rm"))))
6942 (clobber (reg:CC 17))]
6943 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6944 "sbb{w}\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" "HI")])
6949
6950 (define_insn "subsi3_carry"
6951 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6952 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6953 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6954 (match_operand:SI 2 "general_operand" "ri,rm"))))
6955 (clobber (reg:CC 17))]
6956 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6957 "sbb{l}\t{%2, %0|%0, %2}"
6958 [(set_attr "type" "alu")
6959 (set_attr "pent_pair" "pu")
6960 (set_attr "ppro_uops" "few")
6961 (set_attr "mode" "SI")])
6962
6963 (define_insn "subsi3_carry_zext"
6964 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6965 (zero_extend:DI
6966 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6967 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6968 (match_operand:SI 2 "general_operand" "ri,rm")))))
6969 (clobber (reg:CC 17))]
6970 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6971 "sbb{l}\t{%2, %k0|%k0, %2}"
6972 [(set_attr "type" "alu")
6973 (set_attr "pent_pair" "pu")
6974 (set_attr "ppro_uops" "few")
6975 (set_attr "mode" "SI")])
6976
6977 (define_expand "subsi3"
6978 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6979 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6980 (match_operand:SI 2 "general_operand" "")))
6981 (clobber (reg:CC 17))])]
6982 ""
6983 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6984
6985 (define_insn "*subsi_1"
6986 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6987 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6988 (match_operand:SI 2 "general_operand" "ri,rm")))
6989 (clobber (reg:CC 17))]
6990 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6991 "sub{l}\t{%2, %0|%0, %2}"
6992 [(set_attr "type" "alu")
6993 (set_attr "mode" "SI")])
6994
6995 (define_insn "*subsi_1_zext"
6996 [(set (match_operand:DI 0 "register_operand" "=r")
6997 (zero_extend:DI
6998 (minus:SI (match_operand:SI 1 "register_operand" "0")
6999 (match_operand:SI 2 "general_operand" "rim"))))
7000 (clobber (reg:CC 17))]
7001 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7002 "sub{l}\t{%2, %k0|%k0, %2}"
7003 [(set_attr "type" "alu")
7004 (set_attr "mode" "SI")])
7005
7006 (define_insn "*subsi_2"
7007 [(set (reg 17)
7008 (compare
7009 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7010 (match_operand:SI 2 "general_operand" "ri,rm"))
7011 (const_int 0)))
7012 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7013 (minus:SI (match_dup 1) (match_dup 2)))]
7014 "ix86_match_ccmode (insn, CCGOCmode)
7015 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7016 "sub{l}\t{%2, %0|%0, %2}"
7017 [(set_attr "type" "alu")
7018 (set_attr "mode" "SI")])
7019
7020 (define_insn "*subsi_2_zext"
7021 [(set (reg 17)
7022 (compare
7023 (minus:SI (match_operand:SI 1 "register_operand" "0")
7024 (match_operand:SI 2 "general_operand" "rim"))
7025 (const_int 0)))
7026 (set (match_operand:DI 0 "register_operand" "=r")
7027 (zero_extend:DI
7028 (minus:SI (match_dup 1)
7029 (match_dup 2))))]
7030 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7031 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7032 "sub{l}\t{%2, %k0|%k0, %2}"
7033 [(set_attr "type" "alu")
7034 (set_attr "mode" "SI")])
7035
7036 (define_insn "*subsi_3"
7037 [(set (reg 17)
7038 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7039 (match_operand:SI 2 "general_operand" "ri,rm")))
7040 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7041 (minus:SI (match_dup 1) (match_dup 2)))]
7042 "ix86_match_ccmode (insn, CCmode)
7043 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7044 "sub{l}\t{%2, %0|%0, %2}"
7045 [(set_attr "type" "alu")
7046 (set_attr "mode" "SI")])
7047
7048 (define_insn "*subsi_3_zext"
7049 [(set (reg 17)
7050 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7051 (match_operand:SI 2 "general_operand" "rim")))
7052 (set (match_operand:DI 0 "register_operand" "=r")
7053 (zero_extend:DI
7054 (minus:SI (match_dup 1)
7055 (match_dup 2))))]
7056 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7057 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7058 "sub{q}\t{%2, %0|%0, %2}"
7059 [(set_attr "type" "alu")
7060 (set_attr "mode" "DI")])
7061
7062 (define_expand "subhi3"
7063 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7064 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7065 (match_operand:HI 2 "general_operand" "")))
7066 (clobber (reg:CC 17))])]
7067 "TARGET_HIMODE_MATH"
7068 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7069
7070 (define_insn "*subhi_1"
7071 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7072 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7073 (match_operand:HI 2 "general_operand" "ri,rm")))
7074 (clobber (reg:CC 17))]
7075 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7076 "sub{w}\t{%2, %0|%0, %2}"
7077 [(set_attr "type" "alu")
7078 (set_attr "mode" "HI")])
7079
7080 (define_insn "*subhi_2"
7081 [(set (reg 17)
7082 (compare
7083 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7084 (match_operand:HI 2 "general_operand" "ri,rm"))
7085 (const_int 0)))
7086 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7087 (minus:HI (match_dup 1) (match_dup 2)))]
7088 "ix86_match_ccmode (insn, CCGOCmode)
7089 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7090 "sub{w}\t{%2, %0|%0, %2}"
7091 [(set_attr "type" "alu")
7092 (set_attr "mode" "HI")])
7093
7094 (define_insn "*subhi_3"
7095 [(set (reg 17)
7096 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7097 (match_operand:HI 2 "general_operand" "ri,rm")))
7098 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7099 (minus:HI (match_dup 1) (match_dup 2)))]
7100 "ix86_match_ccmode (insn, CCmode)
7101 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7102 "sub{w}\t{%2, %0|%0, %2}"
7103 [(set_attr "type" "alu")
7104 (set_attr "mode" "HI")])
7105
7106 (define_expand "subqi3"
7107 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7108 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7109 (match_operand:QI 2 "general_operand" "")))
7110 (clobber (reg:CC 17))])]
7111 "TARGET_QIMODE_MATH"
7112 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7113
7114 (define_insn "*subqi_1"
7115 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7116 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7117 (match_operand:QI 2 "general_operand" "qn,qmn")))
7118 (clobber (reg:CC 17))]
7119 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7120 "sub{b}\t{%2, %0|%0, %2}"
7121 [(set_attr "type" "alu")
7122 (set_attr "mode" "QI")])
7123
7124 (define_insn "*subqi_1_slp"
7125 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7126 (minus:QI (match_dup 0)
7127 (match_operand:QI 1 "general_operand" "qn,qmn")))
7128 (clobber (reg:CC 17))]
7129 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7130 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7131 "sub{b}\t{%1, %0|%0, %1}"
7132 [(set_attr "type" "alu1")
7133 (set_attr "mode" "QI")])
7134
7135 (define_insn "*subqi_2"
7136 [(set (reg 17)
7137 (compare
7138 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7139 (match_operand:QI 2 "general_operand" "qi,qm"))
7140 (const_int 0)))
7141 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7142 (minus:HI (match_dup 1) (match_dup 2)))]
7143 "ix86_match_ccmode (insn, CCGOCmode)
7144 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7145 "sub{b}\t{%2, %0|%0, %2}"
7146 [(set_attr "type" "alu")
7147 (set_attr "mode" "QI")])
7148
7149 (define_insn "*subqi_3"
7150 [(set (reg 17)
7151 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7152 (match_operand:QI 2 "general_operand" "qi,qm")))
7153 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7154 (minus:HI (match_dup 1) (match_dup 2)))]
7155 "ix86_match_ccmode (insn, CCmode)
7156 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7157 "sub{b}\t{%2, %0|%0, %2}"
7158 [(set_attr "type" "alu")
7159 (set_attr "mode" "QI")])
7160
7161 ;; The patterns that match these are at the end of this file.
7162
7163 (define_expand "subxf3"
7164 [(set (match_operand:XF 0 "register_operand" "")
7165 (minus:XF (match_operand:XF 1 "register_operand" "")
7166 (match_operand:XF 2 "register_operand" "")))]
7167 "!TARGET_64BIT && TARGET_80387"
7168 "")
7169
7170 (define_expand "subtf3"
7171 [(set (match_operand:TF 0 "register_operand" "")
7172 (minus:TF (match_operand:TF 1 "register_operand" "")
7173 (match_operand:TF 2 "register_operand" "")))]
7174 "TARGET_80387"
7175 "")
7176
7177 (define_expand "subdf3"
7178 [(set (match_operand:DF 0 "register_operand" "")
7179 (minus:DF (match_operand:DF 1 "register_operand" "")
7180 (match_operand:DF 2 "nonimmediate_operand" "")))]
7181 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7182 "")
7183
7184 (define_expand "subsf3"
7185 [(set (match_operand:SF 0 "register_operand" "")
7186 (minus:SF (match_operand:SF 1 "register_operand" "")
7187 (match_operand:SF 2 "nonimmediate_operand" "")))]
7188 "TARGET_80387 || TARGET_SSE_MATH"
7189 "")
7190 \f
7191 ;; Multiply instructions
7192
7193 (define_expand "muldi3"
7194 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7195 (mult:DI (match_operand:DI 1 "register_operand" "")
7196 (match_operand:DI 2 "x86_64_general_operand" "")))
7197 (clobber (reg:CC 17))])]
7198 "TARGET_64BIT"
7199 "")
7200
7201 (define_insn "*muldi3_1_rex64"
7202 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7203 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7204 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7205 (clobber (reg:CC 17))]
7206 "TARGET_64BIT
7207 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7208 "@
7209 imul{q}\t{%2, %1, %0|%0, %1, %2}
7210 imul{q}\t{%2, %1, %0|%0, %1, %2}
7211 imul{q}\t{%2, %0|%0, %2}"
7212 [(set_attr "type" "imul")
7213 (set_attr "prefix_0f" "0,0,1")
7214 (set (attr "athlon_decode")
7215 (cond [(eq_attr "cpu" "athlon")
7216 (const_string "vector")
7217 (eq_attr "alternative" "1")
7218 (const_string "vector")
7219 (and (eq_attr "alternative" "2")
7220 (match_operand 1 "memory_operand" ""))
7221 (const_string "vector")]
7222 (const_string "direct")))
7223 (set_attr "mode" "DI")])
7224
7225 (define_expand "mulsi3"
7226 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7227 (mult:SI (match_operand:SI 1 "register_operand" "")
7228 (match_operand:SI 2 "general_operand" "")))
7229 (clobber (reg:CC 17))])]
7230 ""
7231 "")
7232
7233 (define_insn "*mulsi3_1"
7234 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7235 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7236 (match_operand:SI 2 "general_operand" "K,i,mr")))
7237 (clobber (reg:CC 17))]
7238 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7239 "@
7240 imul{l}\t{%2, %1, %0|%0, %1, %2}
7241 imul{l}\t{%2, %1, %0|%0, %1, %2}
7242 imul{l}\t{%2, %0|%0, %2}"
7243 [(set_attr "type" "imul")
7244 (set_attr "prefix_0f" "0,0,1")
7245 (set (attr "athlon_decode")
7246 (cond [(eq_attr "cpu" "athlon")
7247 (const_string "vector")
7248 (eq_attr "alternative" "1")
7249 (const_string "vector")
7250 (and (eq_attr "alternative" "2")
7251 (match_operand 1 "memory_operand" ""))
7252 (const_string "vector")]
7253 (const_string "direct")))
7254 (set_attr "mode" "SI")])
7255
7256 (define_insn "*mulsi3_1_zext"
7257 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7258 (zero_extend:DI
7259 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7260 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7261 (clobber (reg:CC 17))]
7262 "TARGET_64BIT
7263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264 "@
7265 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7266 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7267 imul{l}\t{%2, %k0|%k0, %2}"
7268 [(set_attr "type" "imul")
7269 (set_attr "prefix_0f" "0,0,1")
7270 (set (attr "athlon_decode")
7271 (cond [(eq_attr "cpu" "athlon")
7272 (const_string "vector")
7273 (eq_attr "alternative" "1")
7274 (const_string "vector")
7275 (and (eq_attr "alternative" "2")
7276 (match_operand 1 "memory_operand" ""))
7277 (const_string "vector")]
7278 (const_string "direct")))
7279 (set_attr "mode" "SI")])
7280
7281 (define_expand "mulhi3"
7282 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7283 (mult:HI (match_operand:HI 1 "register_operand" "")
7284 (match_operand:HI 2 "general_operand" "")))
7285 (clobber (reg:CC 17))])]
7286 "TARGET_HIMODE_MATH"
7287 "")
7288
7289 (define_insn "*mulhi3_1"
7290 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7291 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7292 (match_operand:HI 2 "general_operand" "K,i,mr")))
7293 (clobber (reg:CC 17))]
7294 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7295 "@
7296 imul{w}\t{%2, %1, %0|%0, %1, %2}
7297 imul{w}\t{%2, %1, %0|%0, %1, %2}
7298 imul{w}\t{%2, %0|%0, %2}"
7299 [(set_attr "type" "imul")
7300 (set_attr "prefix_0f" "0,0,1")
7301 (set (attr "athlon_decode")
7302 (cond [(eq_attr "cpu" "athlon")
7303 (const_string "vector")
7304 (eq_attr "alternative" "1,2")
7305 (const_string "vector")]
7306 (const_string "direct")))
7307 (set_attr "mode" "HI")])
7308
7309 (define_expand "mulqi3"
7310 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7311 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7312 (match_operand:QI 2 "register_operand" "")))
7313 (clobber (reg:CC 17))])]
7314 "TARGET_QIMODE_MATH"
7315 "")
7316
7317 (define_insn "*mulqi3_1"
7318 [(set (match_operand:QI 0 "register_operand" "=a")
7319 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7320 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7321 (clobber (reg:CC 17))]
7322 "TARGET_QIMODE_MATH
7323 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7324 "mul{b}\t%2"
7325 [(set_attr "type" "imul")
7326 (set_attr "length_immediate" "0")
7327 (set (attr "athlon_decode")
7328 (if_then_else (eq_attr "cpu" "athlon")
7329 (const_string "vector")
7330 (const_string "direct")))
7331 (set_attr "mode" "QI")])
7332
7333 (define_expand "umulqihi3"
7334 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7335 (mult:HI (zero_extend:HI
7336 (match_operand:QI 1 "nonimmediate_operand" ""))
7337 (zero_extend:HI
7338 (match_operand:QI 2 "register_operand" ""))))
7339 (clobber (reg:CC 17))])]
7340 "TARGET_QIMODE_MATH"
7341 "")
7342
7343 (define_insn "*umulqihi3_1"
7344 [(set (match_operand:HI 0 "register_operand" "=a")
7345 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7346 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7347 (clobber (reg:CC 17))]
7348 "TARGET_QIMODE_MATH
7349 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7350 "mul{b}\t%2"
7351 [(set_attr "type" "imul")
7352 (set_attr "length_immediate" "0")
7353 (set (attr "athlon_decode")
7354 (if_then_else (eq_attr "cpu" "athlon")
7355 (const_string "vector")
7356 (const_string "direct")))
7357 (set_attr "mode" "QI")])
7358
7359 (define_expand "mulqihi3"
7360 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7361 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7362 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7363 (clobber (reg:CC 17))])]
7364 "TARGET_QIMODE_MATH"
7365 "")
7366
7367 (define_insn "*mulqihi3_insn"
7368 [(set (match_operand:HI 0 "register_operand" "=a")
7369 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7370 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7371 (clobber (reg:CC 17))]
7372 "TARGET_QIMODE_MATH
7373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7374 "imul{b}\t%2"
7375 [(set_attr "type" "imul")
7376 (set_attr "length_immediate" "0")
7377 (set (attr "athlon_decode")
7378 (if_then_else (eq_attr "cpu" "athlon")
7379 (const_string "vector")
7380 (const_string "direct")))
7381 (set_attr "mode" "QI")])
7382
7383 (define_expand "umulditi3"
7384 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7385 (mult:TI (zero_extend:TI
7386 (match_operand:DI 1 "nonimmediate_operand" ""))
7387 (zero_extend:TI
7388 (match_operand:DI 2 "register_operand" ""))))
7389 (clobber (reg:CC 17))])]
7390 "TARGET_64BIT"
7391 "")
7392
7393 (define_insn "*umulditi3_insn"
7394 [(set (match_operand:TI 0 "register_operand" "=A")
7395 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7396 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7397 (clobber (reg:CC 17))]
7398 "TARGET_64BIT
7399 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7400 "mul{q}\t%2"
7401 [(set_attr "type" "imul")
7402 (set_attr "ppro_uops" "few")
7403 (set_attr "length_immediate" "0")
7404 (set (attr "athlon_decode")
7405 (if_then_else (eq_attr "cpu" "athlon")
7406 (const_string "vector")
7407 (const_string "double")))
7408 (set_attr "mode" "DI")])
7409
7410 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7411 (define_expand "umulsidi3"
7412 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7413 (mult:DI (zero_extend:DI
7414 (match_operand:SI 1 "nonimmediate_operand" ""))
7415 (zero_extend:DI
7416 (match_operand:SI 2 "register_operand" ""))))
7417 (clobber (reg:CC 17))])]
7418 "!TARGET_64BIT"
7419 "")
7420
7421 (define_insn "*umulsidi3_insn"
7422 [(set (match_operand:DI 0 "register_operand" "=A")
7423 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7424 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7425 (clobber (reg:CC 17))]
7426 "!TARGET_64BIT
7427 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7428 "mul{l}\t%2"
7429 [(set_attr "type" "imul")
7430 (set_attr "ppro_uops" "few")
7431 (set_attr "length_immediate" "0")
7432 (set (attr "athlon_decode")
7433 (if_then_else (eq_attr "cpu" "athlon")
7434 (const_string "vector")
7435 (const_string "double")))
7436 (set_attr "mode" "SI")])
7437
7438 (define_expand "mulditi3"
7439 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7440 (mult:TI (sign_extend:TI
7441 (match_operand:DI 1 "nonimmediate_operand" ""))
7442 (sign_extend:TI
7443 (match_operand:DI 2 "register_operand" ""))))
7444 (clobber (reg:CC 17))])]
7445 "TARGET_64BIT"
7446 "")
7447
7448 (define_insn "*mulditi3_insn"
7449 [(set (match_operand:TI 0 "register_operand" "=A")
7450 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7451 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7452 (clobber (reg:CC 17))]
7453 "TARGET_64BIT
7454 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7455 "imul{q}\t%2"
7456 [(set_attr "type" "imul")
7457 (set_attr "length_immediate" "0")
7458 (set (attr "athlon_decode")
7459 (if_then_else (eq_attr "cpu" "athlon")
7460 (const_string "vector")
7461 (const_string "double")))
7462 (set_attr "mode" "DI")])
7463
7464 (define_expand "mulsidi3"
7465 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7466 (mult:DI (sign_extend:DI
7467 (match_operand:SI 1 "nonimmediate_operand" ""))
7468 (sign_extend:DI
7469 (match_operand:SI 2 "register_operand" ""))))
7470 (clobber (reg:CC 17))])]
7471 "!TARGET_64BIT"
7472 "")
7473
7474 (define_insn "*mulsidi3_insn"
7475 [(set (match_operand:DI 0 "register_operand" "=A")
7476 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7477 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7478 (clobber (reg:CC 17))]
7479 "!TARGET_64BIT
7480 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7481 "imul{l}\t%2"
7482 [(set_attr "type" "imul")
7483 (set_attr "length_immediate" "0")
7484 (set (attr "athlon_decode")
7485 (if_then_else (eq_attr "cpu" "athlon")
7486 (const_string "vector")
7487 (const_string "double")))
7488 (set_attr "mode" "SI")])
7489
7490 (define_expand "umuldi3_highpart"
7491 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7492 (truncate:DI
7493 (lshiftrt:TI
7494 (mult:TI (zero_extend:TI
7495 (match_operand:DI 1 "nonimmediate_operand" ""))
7496 (zero_extend:TI
7497 (match_operand:DI 2 "register_operand" "")))
7498 (const_int 64))))
7499 (clobber (match_scratch:DI 3 ""))
7500 (clobber (reg:CC 17))])]
7501 "TARGET_64BIT"
7502 "")
7503
7504 (define_insn "*umuldi3_highpart_rex64"
7505 [(set (match_operand:DI 0 "register_operand" "=d")
7506 (truncate:DI
7507 (lshiftrt:TI
7508 (mult:TI (zero_extend:TI
7509 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7510 (zero_extend:TI
7511 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7512 (const_int 64))))
7513 (clobber (match_scratch:DI 3 "=1"))
7514 (clobber (reg:CC 17))]
7515 "TARGET_64BIT
7516 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7517 "mul{q}\t%2"
7518 [(set_attr "type" "imul")
7519 (set_attr "ppro_uops" "few")
7520 (set_attr "length_immediate" "0")
7521 (set (attr "athlon_decode")
7522 (if_then_else (eq_attr "cpu" "athlon")
7523 (const_string "vector")
7524 (const_string "double")))
7525 (set_attr "mode" "DI")])
7526
7527 (define_expand "umulsi3_highpart"
7528 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7529 (truncate:SI
7530 (lshiftrt:DI
7531 (mult:DI (zero_extend:DI
7532 (match_operand:SI 1 "nonimmediate_operand" ""))
7533 (zero_extend:DI
7534 (match_operand:SI 2 "register_operand" "")))
7535 (const_int 32))))
7536 (clobber (match_scratch:SI 3 ""))
7537 (clobber (reg:CC 17))])]
7538 ""
7539 "")
7540
7541 (define_insn "*umulsi3_highpart_insn"
7542 [(set (match_operand:SI 0 "register_operand" "=d")
7543 (truncate:SI
7544 (lshiftrt:DI
7545 (mult:DI (zero_extend:DI
7546 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7547 (zero_extend:DI
7548 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7549 (const_int 32))))
7550 (clobber (match_scratch:SI 3 "=1"))
7551 (clobber (reg:CC 17))]
7552 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7553 "mul{l}\t%2"
7554 [(set_attr "type" "imul")
7555 (set_attr "ppro_uops" "few")
7556 (set_attr "length_immediate" "0")
7557 (set (attr "athlon_decode")
7558 (if_then_else (eq_attr "cpu" "athlon")
7559 (const_string "vector")
7560 (const_string "double")))
7561 (set_attr "mode" "SI")])
7562
7563 (define_insn "*umulsi3_highpart_zext"
7564 [(set (match_operand:DI 0 "register_operand" "=d")
7565 (zero_extend:DI (truncate:SI
7566 (lshiftrt:DI
7567 (mult:DI (zero_extend:DI
7568 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7569 (zero_extend:DI
7570 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7571 (const_int 32)))))
7572 (clobber (match_scratch:SI 3 "=1"))
7573 (clobber (reg:CC 17))]
7574 "TARGET_64BIT
7575 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7576 "mul{l}\t%2"
7577 [(set_attr "type" "imul")
7578 (set_attr "ppro_uops" "few")
7579 (set_attr "length_immediate" "0")
7580 (set (attr "athlon_decode")
7581 (if_then_else (eq_attr "cpu" "athlon")
7582 (const_string "vector")
7583 (const_string "double")))
7584 (set_attr "mode" "SI")])
7585
7586 (define_expand "smuldi3_highpart"
7587 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7588 (truncate:DI
7589 (lshiftrt:TI
7590 (mult:TI (sign_extend:TI
7591 (match_operand:DI 1 "nonimmediate_operand" ""))
7592 (sign_extend:TI
7593 (match_operand:DI 2 "register_operand" "")))
7594 (const_int 64))))
7595 (clobber (match_scratch:DI 3 ""))
7596 (clobber (reg:CC 17))])]
7597 "TARGET_64BIT"
7598 "")
7599
7600 (define_insn "*smuldi3_highpart_rex64"
7601 [(set (match_operand:DI 0 "register_operand" "=d")
7602 (truncate:DI
7603 (lshiftrt:TI
7604 (mult:TI (sign_extend:TI
7605 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7606 (sign_extend:TI
7607 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7608 (const_int 64))))
7609 (clobber (match_scratch:DI 3 "=1"))
7610 (clobber (reg:CC 17))]
7611 "TARGET_64BIT
7612 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7613 "imul{q}\t%2"
7614 [(set_attr "type" "imul")
7615 (set_attr "ppro_uops" "few")
7616 (set (attr "athlon_decode")
7617 (if_then_else (eq_attr "cpu" "athlon")
7618 (const_string "vector")
7619 (const_string "double")))
7620 (set_attr "mode" "DI")])
7621
7622 (define_expand "smulsi3_highpart"
7623 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7624 (truncate:SI
7625 (lshiftrt:DI
7626 (mult:DI (sign_extend:DI
7627 (match_operand:SI 1 "nonimmediate_operand" ""))
7628 (sign_extend:DI
7629 (match_operand:SI 2 "register_operand" "")))
7630 (const_int 32))))
7631 (clobber (match_scratch:SI 3 ""))
7632 (clobber (reg:CC 17))])]
7633 ""
7634 "")
7635
7636 (define_insn "*smulsi3_highpart_insn"
7637 [(set (match_operand:SI 0 "register_operand" "=d")
7638 (truncate:SI
7639 (lshiftrt:DI
7640 (mult:DI (sign_extend:DI
7641 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7642 (sign_extend:DI
7643 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7644 (const_int 32))))
7645 (clobber (match_scratch:SI 3 "=1"))
7646 (clobber (reg:CC 17))]
7647 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7648 "imul{l}\t%2"
7649 [(set_attr "type" "imul")
7650 (set_attr "ppro_uops" "few")
7651 (set (attr "athlon_decode")
7652 (if_then_else (eq_attr "cpu" "athlon")
7653 (const_string "vector")
7654 (const_string "double")))
7655 (set_attr "mode" "SI")])
7656
7657 (define_insn "*smulsi3_highpart_zext"
7658 [(set (match_operand:DI 0 "register_operand" "=d")
7659 (zero_extend:DI (truncate:SI
7660 (lshiftrt:DI
7661 (mult:DI (sign_extend:DI
7662 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7663 (sign_extend:DI
7664 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7665 (const_int 32)))))
7666 (clobber (match_scratch:SI 3 "=1"))
7667 (clobber (reg:CC 17))]
7668 "TARGET_64BIT
7669 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7670 "imul{l}\t%2"
7671 [(set_attr "type" "imul")
7672 (set_attr "ppro_uops" "few")
7673 (set (attr "athlon_decode")
7674 (if_then_else (eq_attr "cpu" "athlon")
7675 (const_string "vector")
7676 (const_string "double")))
7677 (set_attr "mode" "SI")])
7678
7679 ;; The patterns that match these are at the end of this file.
7680
7681 (define_expand "mulxf3"
7682 [(set (match_operand:XF 0 "register_operand" "")
7683 (mult:XF (match_operand:XF 1 "register_operand" "")
7684 (match_operand:XF 2 "register_operand" "")))]
7685 "!TARGET_64BIT && TARGET_80387"
7686 "")
7687
7688 (define_expand "multf3"
7689 [(set (match_operand:TF 0 "register_operand" "")
7690 (mult:TF (match_operand:TF 1 "register_operand" "")
7691 (match_operand:TF 2 "register_operand" "")))]
7692 "TARGET_80387"
7693 "")
7694
7695 (define_expand "muldf3"
7696 [(set (match_operand:DF 0 "register_operand" "")
7697 (mult:DF (match_operand:DF 1 "register_operand" "")
7698 (match_operand:DF 2 "nonimmediate_operand" "")))]
7699 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7700 "")
7701
7702 (define_expand "mulsf3"
7703 [(set (match_operand:SF 0 "register_operand" "")
7704 (mult:SF (match_operand:SF 1 "register_operand" "")
7705 (match_operand:SF 2 "nonimmediate_operand" "")))]
7706 "TARGET_80387 || TARGET_SSE_MATH"
7707 "")
7708 \f
7709 ;; Divide instructions
7710
7711 (define_insn "divqi3"
7712 [(set (match_operand:QI 0 "register_operand" "=a")
7713 (div:QI (match_operand:HI 1 "register_operand" "0")
7714 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7715 (clobber (reg:CC 17))]
7716 "TARGET_QIMODE_MATH"
7717 "idiv{b}\t%2"
7718 [(set_attr "type" "idiv")
7719 (set_attr "mode" "QI")
7720 (set_attr "ppro_uops" "few")])
7721
7722 (define_insn "udivqi3"
7723 [(set (match_operand:QI 0 "register_operand" "=a")
7724 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7725 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7726 (clobber (reg:CC 17))]
7727 "TARGET_QIMODE_MATH"
7728 "div{b}\t%2"
7729 [(set_attr "type" "idiv")
7730 (set_attr "mode" "QI")
7731 (set_attr "ppro_uops" "few")])
7732
7733 ;; The patterns that match these are at the end of this file.
7734
7735 (define_expand "divxf3"
7736 [(set (match_operand:XF 0 "register_operand" "")
7737 (div:XF (match_operand:XF 1 "register_operand" "")
7738 (match_operand:XF 2 "register_operand" "")))]
7739 "!TARGET_64BIT && TARGET_80387"
7740 "")
7741
7742 (define_expand "divtf3"
7743 [(set (match_operand:TF 0 "register_operand" "")
7744 (div:TF (match_operand:TF 1 "register_operand" "")
7745 (match_operand:TF 2 "register_operand" "")))]
7746 "TARGET_80387"
7747 "")
7748
7749 (define_expand "divdf3"
7750 [(set (match_operand:DF 0 "register_operand" "")
7751 (div:DF (match_operand:DF 1 "register_operand" "")
7752 (match_operand:DF 2 "nonimmediate_operand" "")))]
7753 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7754 "")
7755
7756 (define_expand "divsf3"
7757 [(set (match_operand:SF 0 "register_operand" "")
7758 (div:SF (match_operand:SF 1 "register_operand" "")
7759 (match_operand:SF 2 "nonimmediate_operand" "")))]
7760 "TARGET_80387 || TARGET_SSE_MATH"
7761 "")
7762 \f
7763 ;; Remainder instructions.
7764
7765 (define_expand "divmoddi4"
7766 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7767 (div:DI (match_operand:DI 1 "register_operand" "")
7768 (match_operand:DI 2 "nonimmediate_operand" "")))
7769 (set (match_operand:DI 3 "register_operand" "")
7770 (mod:DI (match_dup 1) (match_dup 2)))
7771 (clobber (reg:CC 17))])]
7772 "TARGET_64BIT"
7773 "")
7774
7775 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7776 ;; Penalize eax case slightly because it results in worse scheduling
7777 ;; of code.
7778 (define_insn "*divmoddi4_nocltd_rex64"
7779 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7780 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7781 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7782 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7783 (mod:DI (match_dup 2) (match_dup 3)))
7784 (clobber (reg:CC 17))]
7785 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7786 "#"
7787 [(set_attr "type" "multi")])
7788
7789 (define_insn "*divmoddi4_cltd_rex64"
7790 [(set (match_operand:DI 0 "register_operand" "=a")
7791 (div:DI (match_operand:DI 2 "register_operand" "a")
7792 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7793 (set (match_operand:DI 1 "register_operand" "=&d")
7794 (mod:DI (match_dup 2) (match_dup 3)))
7795 (clobber (reg:CC 17))]
7796 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7797 "#"
7798 [(set_attr "type" "multi")])
7799
7800 (define_insn "*divmoddi_noext_rex64"
7801 [(set (match_operand:DI 0 "register_operand" "=a")
7802 (div:DI (match_operand:DI 1 "register_operand" "0")
7803 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7804 (set (match_operand:DI 3 "register_operand" "=d")
7805 (mod:DI (match_dup 1) (match_dup 2)))
7806 (use (match_operand:DI 4 "register_operand" "3"))
7807 (clobber (reg:CC 17))]
7808 "TARGET_64BIT"
7809 "idiv{q}\t%2"
7810 [(set_attr "type" "idiv")
7811 (set_attr "mode" "DI")
7812 (set_attr "ppro_uops" "few")])
7813
7814 (define_split
7815 [(set (match_operand:DI 0 "register_operand" "")
7816 (div:DI (match_operand:DI 1 "register_operand" "")
7817 (match_operand:DI 2 "nonimmediate_operand" "")))
7818 (set (match_operand:DI 3 "register_operand" "")
7819 (mod:DI (match_dup 1) (match_dup 2)))
7820 (clobber (reg:CC 17))]
7821 "TARGET_64BIT && reload_completed"
7822 [(parallel [(set (match_dup 3)
7823 (ashiftrt:DI (match_dup 4) (const_int 63)))
7824 (clobber (reg:CC 17))])
7825 (parallel [(set (match_dup 0)
7826 (div:DI (reg:DI 0) (match_dup 2)))
7827 (set (match_dup 3)
7828 (mod:DI (reg:DI 0) (match_dup 2)))
7829 (use (match_dup 3))
7830 (clobber (reg:CC 17))])]
7831 {
7832 /* Avoid use of cltd in favor of a mov+shift. */
7833 if (!TARGET_USE_CLTD && !optimize_size)
7834 {
7835 if (true_regnum (operands[1]))
7836 emit_move_insn (operands[0], operands[1]);
7837 else
7838 emit_move_insn (operands[3], operands[1]);
7839 operands[4] = operands[3];
7840 }
7841 else
7842 {
7843 if (true_regnum (operands[1]))
7844 abort();
7845 operands[4] = operands[1];
7846 }
7847 })
7848
7849
7850 (define_expand "divmodsi4"
7851 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7852 (div:SI (match_operand:SI 1 "register_operand" "")
7853 (match_operand:SI 2 "nonimmediate_operand" "")))
7854 (set (match_operand:SI 3 "register_operand" "")
7855 (mod:SI (match_dup 1) (match_dup 2)))
7856 (clobber (reg:CC 17))])]
7857 ""
7858 "")
7859
7860 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7861 ;; Penalize eax case slightly because it results in worse scheduling
7862 ;; of code.
7863 (define_insn "*divmodsi4_nocltd"
7864 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7865 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7866 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7867 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7868 (mod:SI (match_dup 2) (match_dup 3)))
7869 (clobber (reg:CC 17))]
7870 "!optimize_size && !TARGET_USE_CLTD"
7871 "#"
7872 [(set_attr "type" "multi")])
7873
7874 (define_insn "*divmodsi4_cltd"
7875 [(set (match_operand:SI 0 "register_operand" "=a")
7876 (div:SI (match_operand:SI 2 "register_operand" "a")
7877 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7878 (set (match_operand:SI 1 "register_operand" "=&d")
7879 (mod:SI (match_dup 2) (match_dup 3)))
7880 (clobber (reg:CC 17))]
7881 "optimize_size || TARGET_USE_CLTD"
7882 "#"
7883 [(set_attr "type" "multi")])
7884
7885 (define_insn "*divmodsi_noext"
7886 [(set (match_operand:SI 0 "register_operand" "=a")
7887 (div:SI (match_operand:SI 1 "register_operand" "0")
7888 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7889 (set (match_operand:SI 3 "register_operand" "=d")
7890 (mod:SI (match_dup 1) (match_dup 2)))
7891 (use (match_operand:SI 4 "register_operand" "3"))
7892 (clobber (reg:CC 17))]
7893 ""
7894 "idiv{l}\t%2"
7895 [(set_attr "type" "idiv")
7896 (set_attr "mode" "SI")
7897 (set_attr "ppro_uops" "few")])
7898
7899 (define_split
7900 [(set (match_operand:SI 0 "register_operand" "")
7901 (div:SI (match_operand:SI 1 "register_operand" "")
7902 (match_operand:SI 2 "nonimmediate_operand" "")))
7903 (set (match_operand:SI 3 "register_operand" "")
7904 (mod:SI (match_dup 1) (match_dup 2)))
7905 (clobber (reg:CC 17))]
7906 "reload_completed"
7907 [(parallel [(set (match_dup 3)
7908 (ashiftrt:SI (match_dup 4) (const_int 31)))
7909 (clobber (reg:CC 17))])
7910 (parallel [(set (match_dup 0)
7911 (div:SI (reg:SI 0) (match_dup 2)))
7912 (set (match_dup 3)
7913 (mod:SI (reg:SI 0) (match_dup 2)))
7914 (use (match_dup 3))
7915 (clobber (reg:CC 17))])]
7916 {
7917 /* Avoid use of cltd in favor of a mov+shift. */
7918 if (!TARGET_USE_CLTD && !optimize_size)
7919 {
7920 if (true_regnum (operands[1]))
7921 emit_move_insn (operands[0], operands[1]);
7922 else
7923 emit_move_insn (operands[3], operands[1]);
7924 operands[4] = operands[3];
7925 }
7926 else
7927 {
7928 if (true_regnum (operands[1]))
7929 abort();
7930 operands[4] = operands[1];
7931 }
7932 })
7933 ;; %%% Split me.
7934 (define_insn "divmodhi4"
7935 [(set (match_operand:HI 0 "register_operand" "=a")
7936 (div:HI (match_operand:HI 1 "register_operand" "0")
7937 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7938 (set (match_operand:HI 3 "register_operand" "=&d")
7939 (mod:HI (match_dup 1) (match_dup 2)))
7940 (clobber (reg:CC 17))]
7941 "TARGET_HIMODE_MATH"
7942 "cwtd\;idiv{w}\t%2"
7943 [(set_attr "type" "multi")
7944 (set_attr "length_immediate" "0")
7945 (set_attr "mode" "SI")])
7946
7947 (define_insn "udivmoddi4"
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 (clobber (reg:CC 17))]
7954 "TARGET_64BIT"
7955 "xor{q}\t%3, %3\;div{q}\t%2"
7956 [(set_attr "type" "multi")
7957 (set_attr "length_immediate" "0")
7958 (set_attr "mode" "DI")])
7959
7960 (define_insn "*udivmoddi4_noext"
7961 [(set (match_operand:DI 0 "register_operand" "=a")
7962 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7963 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7964 (set (match_operand:DI 3 "register_operand" "=d")
7965 (umod:DI (match_dup 1) (match_dup 2)))
7966 (use (match_dup 3))
7967 (clobber (reg:CC 17))]
7968 "TARGET_64BIT"
7969 "div{q}\t%2"
7970 [(set_attr "type" "idiv")
7971 (set_attr "ppro_uops" "few")
7972 (set_attr "mode" "DI")])
7973
7974 (define_split
7975 [(set (match_operand:DI 0 "register_operand" "")
7976 (udiv:DI (match_operand:DI 1 "register_operand" "")
7977 (match_operand:DI 2 "nonimmediate_operand" "")))
7978 (set (match_operand:DI 3 "register_operand" "")
7979 (umod:DI (match_dup 1) (match_dup 2)))
7980 (clobber (reg:CC 17))]
7981 "TARGET_64BIT && reload_completed"
7982 [(set (match_dup 3) (const_int 0))
7983 (parallel [(set (match_dup 0)
7984 (udiv:DI (match_dup 1) (match_dup 2)))
7985 (set (match_dup 3)
7986 (umod:DI (match_dup 1) (match_dup 2)))
7987 (use (match_dup 3))
7988 (clobber (reg:CC 17))])]
7989 "")
7990
7991 (define_insn "udivmodsi4"
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 (clobber (reg:CC 17))]
7998 ""
7999 "xor{l}\t%3, %3\;div{l}\t%2"
8000 [(set_attr "type" "multi")
8001 (set_attr "length_immediate" "0")
8002 (set_attr "mode" "SI")])
8003
8004 (define_insn "*udivmodsi4_noext"
8005 [(set (match_operand:SI 0 "register_operand" "=a")
8006 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8007 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8008 (set (match_operand:SI 3 "register_operand" "=d")
8009 (umod:SI (match_dup 1) (match_dup 2)))
8010 (use (match_dup 3))
8011 (clobber (reg:CC 17))]
8012 ""
8013 "div{l}\t%2"
8014 [(set_attr "type" "idiv")
8015 (set_attr "ppro_uops" "few")
8016 (set_attr "mode" "SI")])
8017
8018 (define_split
8019 [(set (match_operand:SI 0 "register_operand" "")
8020 (udiv:SI (match_operand:SI 1 "register_operand" "")
8021 (match_operand:SI 2 "nonimmediate_operand" "")))
8022 (set (match_operand:SI 3 "register_operand" "")
8023 (umod:SI (match_dup 1) (match_dup 2)))
8024 (clobber (reg:CC 17))]
8025 "reload_completed"
8026 [(set (match_dup 3) (const_int 0))
8027 (parallel [(set (match_dup 0)
8028 (udiv:SI (match_dup 1) (match_dup 2)))
8029 (set (match_dup 3)
8030 (umod:SI (match_dup 1) (match_dup 2)))
8031 (use (match_dup 3))
8032 (clobber (reg:CC 17))])]
8033 "")
8034
8035 (define_expand "udivmodhi4"
8036 [(set (match_dup 4) (const_int 0))
8037 (parallel [(set (match_operand:HI 0 "register_operand" "")
8038 (udiv:HI (match_operand:HI 1 "register_operand" "")
8039 (match_operand:HI 2 "nonimmediate_operand" "")))
8040 (set (match_operand:HI 3 "register_operand" "")
8041 (umod:HI (match_dup 1) (match_dup 2)))
8042 (use (match_dup 4))
8043 (clobber (reg:CC 17))])]
8044 "TARGET_HIMODE_MATH"
8045 "operands[4] = gen_reg_rtx (HImode);")
8046
8047 (define_insn "*udivmodhi_noext"
8048 [(set (match_operand:HI 0 "register_operand" "=a")
8049 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8050 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8051 (set (match_operand:HI 3 "register_operand" "=d")
8052 (umod:HI (match_dup 1) (match_dup 2)))
8053 (use (match_operand:HI 4 "register_operand" "3"))
8054 (clobber (reg:CC 17))]
8055 ""
8056 "div{w}\t%2"
8057 [(set_attr "type" "idiv")
8058 (set_attr "mode" "HI")
8059 (set_attr "ppro_uops" "few")])
8060
8061 ;; We can not use div/idiv for double division, because it causes
8062 ;; "division by zero" on the overflow and that's not what we expect
8063 ;; from truncate. Because true (non truncating) double division is
8064 ;; never generated, we can't create this insn anyway.
8065 ;
8066 ;(define_insn ""
8067 ; [(set (match_operand:SI 0 "register_operand" "=a")
8068 ; (truncate:SI
8069 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8070 ; (zero_extend:DI
8071 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8072 ; (set (match_operand:SI 3 "register_operand" "=d")
8073 ; (truncate:SI
8074 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8075 ; (clobber (reg:CC 17))]
8076 ; ""
8077 ; "div{l}\t{%2, %0|%0, %2}"
8078 ; [(set_attr "type" "idiv")
8079 ; (set_attr "ppro_uops" "few")])
8080 \f
8081 ;;- Logical AND instructions
8082
8083 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8084 ;; Note that this excludes ah.
8085
8086 (define_insn "*testdi_1_rex64"
8087 [(set (reg 17)
8088 (compare
8089 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8090 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8091 (const_int 0)))]
8092 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8094 "@
8095 test{l}\t{%k1, %k0|%k0, %k1}
8096 test{l}\t{%k1, %k0|%k0, %k1}
8097 test{q}\t{%1, %0|%0, %1}
8098 test{q}\t{%1, %0|%0, %1}
8099 test{q}\t{%1, %0|%0, %1}"
8100 [(set_attr "type" "test")
8101 (set_attr "modrm" "0,1,0,1,1")
8102 (set_attr "mode" "SI,SI,DI,DI,DI")
8103 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8104
8105 (define_insn "testsi_1"
8106 [(set (reg 17)
8107 (compare
8108 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8109 (match_operand:SI 1 "general_operand" "in,in,rin"))
8110 (const_int 0)))]
8111 "ix86_match_ccmode (insn, CCNOmode)
8112 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8113 "test{l}\t{%1, %0|%0, %1}"
8114 [(set_attr "type" "test")
8115 (set_attr "modrm" "0,1,1")
8116 (set_attr "mode" "SI")
8117 (set_attr "pent_pair" "uv,np,uv")])
8118
8119 (define_expand "testsi_ccno_1"
8120 [(set (reg:CCNO 17)
8121 (compare:CCNO
8122 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8123 (match_operand:SI 1 "nonmemory_operand" ""))
8124 (const_int 0)))]
8125 ""
8126 "")
8127
8128 (define_insn "*testhi_1"
8129 [(set (reg 17)
8130 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8131 (match_operand:HI 1 "general_operand" "n,n,rn"))
8132 (const_int 0)))]
8133 "ix86_match_ccmode (insn, CCNOmode)
8134 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8135 "test{w}\t{%1, %0|%0, %1}"
8136 [(set_attr "type" "test")
8137 (set_attr "modrm" "0,1,1")
8138 (set_attr "mode" "HI")
8139 (set_attr "pent_pair" "uv,np,uv")])
8140
8141 (define_expand "testqi_ccz_1"
8142 [(set (reg:CCZ 17)
8143 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8144 (match_operand:QI 1 "nonmemory_operand" ""))
8145 (const_int 0)))]
8146 ""
8147 "")
8148
8149 (define_insn "*testqi_1"
8150 [(set (reg 17)
8151 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8152 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8153 (const_int 0)))]
8154 "ix86_match_ccmode (insn, CCNOmode)
8155 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8156 {
8157 if (which_alternative == 3)
8158 {
8159 if (GET_CODE (operands[1]) == CONST_INT
8160 && (INTVAL (operands[1]) & 0xffffff00))
8161 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8162 return "test{l}\t{%1, %k0|%k0, %1}";
8163 }
8164 return "test{b}\t{%1, %0|%0, %1}";
8165 }
8166 [(set_attr "type" "test")
8167 (set_attr "modrm" "0,1,1,1")
8168 (set_attr "mode" "QI,QI,QI,SI")
8169 (set_attr "pent_pair" "uv,np,uv,np")])
8170
8171 (define_expand "testqi_ext_ccno_0"
8172 [(set (reg:CCNO 17)
8173 (compare:CCNO
8174 (and:SI
8175 (zero_extract:SI
8176 (match_operand 0 "ext_register_operand" "")
8177 (const_int 8)
8178 (const_int 8))
8179 (match_operand 1 "const_int_operand" ""))
8180 (const_int 0)))]
8181 ""
8182 "")
8183
8184 (define_insn "*testqi_ext_0"
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 (match_operand 1 "const_int_operand" "n"))
8193 (const_int 0)))]
8194 "ix86_match_ccmode (insn, CCNOmode)"
8195 "test{b}\t{%1, %h0|%h0, %1}"
8196 [(set_attr "type" "test")
8197 (set_attr "mode" "QI")
8198 (set_attr "length_immediate" "1")
8199 (set_attr "pent_pair" "np")])
8200
8201 (define_insn "*testqi_ext_1"
8202 [(set (reg 17)
8203 (compare
8204 (and:SI
8205 (zero_extract:SI
8206 (match_operand 0 "ext_register_operand" "Q")
8207 (const_int 8)
8208 (const_int 8))
8209 (zero_extend:SI
8210 (match_operand:QI 1 "general_operand" "Qm")))
8211 (const_int 0)))]
8212 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8213 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8214 "test{b}\t{%1, %h0|%h0, %1}"
8215 [(set_attr "type" "test")
8216 (set_attr "mode" "QI")])
8217
8218 (define_insn "*testqi_ext_1_rex64"
8219 [(set (reg 17)
8220 (compare
8221 (and:SI
8222 (zero_extract:SI
8223 (match_operand 0 "ext_register_operand" "Q")
8224 (const_int 8)
8225 (const_int 8))
8226 (zero_extend:SI
8227 (match_operand:QI 1 "register_operand" "Q")))
8228 (const_int 0)))]
8229 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8230 "test{b}\t{%1, %h0|%h0, %1}"
8231 [(set_attr "type" "test")
8232 (set_attr "mode" "QI")])
8233
8234 (define_insn "*testqi_ext_2"
8235 [(set (reg 17)
8236 (compare
8237 (and:SI
8238 (zero_extract:SI
8239 (match_operand 0 "ext_register_operand" "Q")
8240 (const_int 8)
8241 (const_int 8))
8242 (zero_extract:SI
8243 (match_operand 1 "ext_register_operand" "Q")
8244 (const_int 8)
8245 (const_int 8)))
8246 (const_int 0)))]
8247 "ix86_match_ccmode (insn, CCNOmode)"
8248 "test{b}\t{%h1, %h0|%h0, %h1}"
8249 [(set_attr "type" "test")
8250 (set_attr "mode" "QI")])
8251
8252 ;; Combine likes to form bit extractions for some tests. Humor it.
8253 (define_insn "*testqi_ext_3"
8254 [(set (reg 17)
8255 (compare (zero_extract:SI
8256 (match_operand 0 "nonimmediate_operand" "rm")
8257 (match_operand:SI 1 "const_int_operand" "")
8258 (match_operand:SI 2 "const_int_operand" ""))
8259 (const_int 0)))]
8260 "ix86_match_ccmode (insn, CCNOmode)
8261 && (GET_MODE (operands[0]) == SImode
8262 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8263 || GET_MODE (operands[0]) == HImode
8264 || GET_MODE (operands[0]) == QImode)"
8265 "#")
8266
8267 (define_insn "*testqi_ext_3_rex64"
8268 [(set (reg 17)
8269 (compare (zero_extract:DI
8270 (match_operand 0 "nonimmediate_operand" "rm")
8271 (match_operand:DI 1 "const_int_operand" "")
8272 (match_operand:DI 2 "const_int_operand" ""))
8273 (const_int 0)))]
8274 "TARGET_64BIT
8275 && ix86_match_ccmode (insn, CCNOmode)
8276 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8277 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8278 /* Ensure that resulting mask is zero or sign extended operand. */
8279 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8280 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8281 && INTVAL (operands[1]) > 32))
8282 && (GET_MODE (operands[0]) == SImode
8283 || GET_MODE (operands[0]) == DImode
8284 || GET_MODE (operands[0]) == HImode
8285 || GET_MODE (operands[0]) == QImode)"
8286 "#")
8287
8288 (define_split
8289 [(set (reg 17)
8290 (compare (zero_extract
8291 (match_operand 0 "nonimmediate_operand" "")
8292 (match_operand 1 "const_int_operand" "")
8293 (match_operand 2 "const_int_operand" ""))
8294 (const_int 0)))]
8295 "ix86_match_ccmode (insn, CCNOmode)"
8296 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8297 {
8298 HOST_WIDE_INT len = INTVAL (operands[1]);
8299 HOST_WIDE_INT pos = INTVAL (operands[2]);
8300 HOST_WIDE_INT mask;
8301 enum machine_mode mode, submode;
8302
8303 mode = GET_MODE (operands[0]);
8304 if (GET_CODE (operands[0]) == MEM)
8305 {
8306 /* ??? Combine likes to put non-volatile mem extractions in QImode
8307 no matter the size of the test. So find a mode that works. */
8308 if (! MEM_VOLATILE_P (operands[0]))
8309 {
8310 mode = smallest_mode_for_size (pos + len, MODE_INT);
8311 operands[0] = adjust_address (operands[0], mode, 0);
8312 }
8313 }
8314 else if (GET_CODE (operands[0]) == SUBREG
8315 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8316 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8317 && pos + len <= GET_MODE_BITSIZE (submode))
8318 {
8319 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8320 mode = submode;
8321 operands[0] = SUBREG_REG (operands[0]);
8322 }
8323 else if (mode == HImode && pos + len <= 8)
8324 {
8325 /* Small HImode tests can be converted to QImode. */
8326 mode = QImode;
8327 operands[0] = gen_lowpart (QImode, operands[0]);
8328 }
8329
8330 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8331 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8332
8333 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8334 })
8335
8336 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8337 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8338 ;; this is relatively important trick.
8339 ;; Do the conversion only post-reload to avoid limiting of the register class
8340 ;; to QI regs.
8341 (define_split
8342 [(set (reg 17)
8343 (compare
8344 (and (match_operand 0 "register_operand" "")
8345 (match_operand 1 "const_int_operand" ""))
8346 (const_int 0)))]
8347 "reload_completed
8348 && QI_REG_P (operands[0])
8349 && ((ix86_match_ccmode (insn, CCZmode)
8350 && !(INTVAL (operands[1]) & ~(255 << 8)))
8351 || (ix86_match_ccmode (insn, CCNOmode)
8352 && !(INTVAL (operands[1]) & ~(127 << 8))))
8353 && GET_MODE (operands[0]) != QImode"
8354 [(set (reg:CCNO 17)
8355 (compare:CCNO
8356 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8357 (match_dup 1))
8358 (const_int 0)))]
8359 "operands[0] = gen_lowpart (SImode, operands[0]);
8360 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8361
8362 (define_split
8363 [(set (reg 17)
8364 (compare
8365 (and (match_operand 0 "nonimmediate_operand" "")
8366 (match_operand 1 "const_int_operand" ""))
8367 (const_int 0)))]
8368 "reload_completed
8369 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8370 && ((ix86_match_ccmode (insn, CCZmode)
8371 && !(INTVAL (operands[1]) & ~255))
8372 || (ix86_match_ccmode (insn, CCNOmode)
8373 && !(INTVAL (operands[1]) & ~127)))
8374 && GET_MODE (operands[0]) != QImode"
8375 [(set (reg:CCNO 17)
8376 (compare:CCNO
8377 (and:QI (match_dup 0)
8378 (match_dup 1))
8379 (const_int 0)))]
8380 "operands[0] = gen_lowpart (QImode, operands[0]);
8381 operands[1] = gen_lowpart (QImode, operands[1]);")
8382
8383
8384 ;; %%% This used to optimize known byte-wide and operations to memory,
8385 ;; and sometimes to QImode registers. If this is considered useful,
8386 ;; it should be done with splitters.
8387
8388 (define_expand "anddi3"
8389 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8390 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8391 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8392 (clobber (reg:CC 17))]
8393 "TARGET_64BIT"
8394 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8395
8396 (define_insn "*anddi_1_rex64"
8397 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8398 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8399 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8400 (clobber (reg:CC 17))]
8401 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8402 {
8403 switch (get_attr_type (insn))
8404 {
8405 case TYPE_IMOVX:
8406 {
8407 enum machine_mode mode;
8408
8409 if (GET_CODE (operands[2]) != CONST_INT)
8410 abort ();
8411 if (INTVAL (operands[2]) == 0xff)
8412 mode = QImode;
8413 else if (INTVAL (operands[2]) == 0xffff)
8414 mode = HImode;
8415 else
8416 abort ();
8417
8418 operands[1] = gen_lowpart (mode, operands[1]);
8419 if (mode == QImode)
8420 return "movz{bq|x}\t{%1,%0|%0, %1}";
8421 else
8422 return "movz{wq|x}\t{%1,%0|%0, %1}";
8423 }
8424
8425 default:
8426 if (! rtx_equal_p (operands[0], operands[1]))
8427 abort ();
8428 if (get_attr_mode (insn) == MODE_SI)
8429 return "and{l}\t{%k2, %k0|%k0, %k2}";
8430 else
8431 return "and{q}\t{%2, %0|%0, %2}";
8432 }
8433 }
8434 [(set_attr "type" "alu,alu,alu,imovx")
8435 (set_attr "length_immediate" "*,*,*,0")
8436 (set_attr "mode" "SI,DI,DI,DI")])
8437
8438 (define_insn "*anddi_2"
8439 [(set (reg 17)
8440 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8441 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8442 (const_int 0)))
8443 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8444 (and:DI (match_dup 1) (match_dup 2)))]
8445 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8446 && ix86_binary_operator_ok (AND, DImode, operands)"
8447 "@
8448 and{l}\t{%k2, %k0|%k0, %k2}
8449 and{q}\t{%2, %0|%0, %2}
8450 and{q}\t{%2, %0|%0, %2}"
8451 [(set_attr "type" "alu")
8452 (set_attr "mode" "SI,DI,DI")])
8453
8454 (define_expand "andsi3"
8455 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8456 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8457 (match_operand:SI 2 "general_operand" "")))
8458 (clobber (reg:CC 17))]
8459 ""
8460 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8461
8462 (define_insn "*andsi_1"
8463 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8464 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8465 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8466 (clobber (reg:CC 17))]
8467 "ix86_binary_operator_ok (AND, SImode, operands)"
8468 {
8469 switch (get_attr_type (insn))
8470 {
8471 case TYPE_IMOVX:
8472 {
8473 enum machine_mode mode;
8474
8475 if (GET_CODE (operands[2]) != CONST_INT)
8476 abort ();
8477 if (INTVAL (operands[2]) == 0xff)
8478 mode = QImode;
8479 else if (INTVAL (operands[2]) == 0xffff)
8480 mode = HImode;
8481 else
8482 abort ();
8483
8484 operands[1] = gen_lowpart (mode, operands[1]);
8485 if (mode == QImode)
8486 return "movz{bl|x}\t{%1,%0|%0, %1}";
8487 else
8488 return "movz{wl|x}\t{%1,%0|%0, %1}";
8489 }
8490
8491 default:
8492 if (! rtx_equal_p (operands[0], operands[1]))
8493 abort ();
8494 return "and{l}\t{%2, %0|%0, %2}";
8495 }
8496 }
8497 [(set_attr "type" "alu,alu,imovx")
8498 (set_attr "length_immediate" "*,*,0")
8499 (set_attr "mode" "SI")])
8500
8501 (define_split
8502 [(set (match_operand 0 "register_operand" "")
8503 (and (match_dup 0)
8504 (const_int -65536)))
8505 (clobber (reg:CC 17))]
8506 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8507 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8508 "operands[1] = gen_lowpart (HImode, operands[0]);")
8509
8510 (define_split
8511 [(set (match_operand 0 "ext_register_operand" "")
8512 (and (match_dup 0)
8513 (const_int -256)))
8514 (clobber (reg:CC 17))]
8515 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8516 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8517 "operands[1] = gen_lowpart (QImode, operands[0]);")
8518
8519 (define_split
8520 [(set (match_operand 0 "ext_register_operand" "")
8521 (and (match_dup 0)
8522 (const_int -65281)))
8523 (clobber (reg:CC 17))]
8524 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8525 [(parallel [(set (zero_extract:SI (match_dup 0)
8526 (const_int 8)
8527 (const_int 8))
8528 (xor:SI
8529 (zero_extract:SI (match_dup 0)
8530 (const_int 8)
8531 (const_int 8))
8532 (zero_extract:SI (match_dup 0)
8533 (const_int 8)
8534 (const_int 8))))
8535 (clobber (reg:CC 17))])]
8536 "operands[0] = gen_lowpart (SImode, operands[0]);")
8537
8538 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8539 (define_insn "*andsi_1_zext"
8540 [(set (match_operand:DI 0 "register_operand" "=r")
8541 (zero_extend:DI
8542 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8543 (match_operand:SI 2 "general_operand" "rim"))))
8544 (clobber (reg:CC 17))]
8545 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8546 "and{l}\t{%2, %k0|%k0, %2}"
8547 [(set_attr "type" "alu")
8548 (set_attr "mode" "SI")])
8549
8550 (define_insn "*andsi_2"
8551 [(set (reg 17)
8552 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8553 (match_operand:SI 2 "general_operand" "rim,ri"))
8554 (const_int 0)))
8555 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8556 (and:SI (match_dup 1) (match_dup 2)))]
8557 "ix86_match_ccmode (insn, CCNOmode)
8558 && ix86_binary_operator_ok (AND, SImode, operands)"
8559 "and{l}\t{%2, %0|%0, %2}"
8560 [(set_attr "type" "alu")
8561 (set_attr "mode" "SI")])
8562
8563 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8564 (define_insn "*andsi_2_zext"
8565 [(set (reg 17)
8566 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8567 (match_operand:SI 2 "general_operand" "rim"))
8568 (const_int 0)))
8569 (set (match_operand:DI 0 "register_operand" "=r")
8570 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8571 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8572 && ix86_binary_operator_ok (AND, SImode, operands)"
8573 "and{l}\t{%2, %k0|%k0, %2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "mode" "SI")])
8576
8577 (define_expand "andhi3"
8578 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8579 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8580 (match_operand:HI 2 "general_operand" "")))
8581 (clobber (reg:CC 17))]
8582 "TARGET_HIMODE_MATH"
8583 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8584
8585 (define_insn "*andhi_1"
8586 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8587 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8588 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8589 (clobber (reg:CC 17))]
8590 "ix86_binary_operator_ok (AND, HImode, operands)"
8591 {
8592 switch (get_attr_type (insn))
8593 {
8594 case TYPE_IMOVX:
8595 if (GET_CODE (operands[2]) != CONST_INT)
8596 abort ();
8597 if (INTVAL (operands[2]) == 0xff)
8598 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8599 abort ();
8600
8601 default:
8602 if (! rtx_equal_p (operands[0], operands[1]))
8603 abort ();
8604
8605 return "and{w}\t{%2, %0|%0, %2}";
8606 }
8607 }
8608 [(set_attr "type" "alu,alu,imovx")
8609 (set_attr "length_immediate" "*,*,0")
8610 (set_attr "mode" "HI,HI,SI")])
8611
8612 (define_insn "*andhi_2"
8613 [(set (reg 17)
8614 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8615 (match_operand:HI 2 "general_operand" "rim,ri"))
8616 (const_int 0)))
8617 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8618 (and:HI (match_dup 1) (match_dup 2)))]
8619 "ix86_match_ccmode (insn, CCNOmode)
8620 && ix86_binary_operator_ok (AND, HImode, operands)"
8621 "and{w}\t{%2, %0|%0, %2}"
8622 [(set_attr "type" "alu")
8623 (set_attr "mode" "HI")])
8624
8625 (define_expand "andqi3"
8626 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8627 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8628 (match_operand:QI 2 "general_operand" "")))
8629 (clobber (reg:CC 17))]
8630 "TARGET_QIMODE_MATH"
8631 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8632
8633 ;; %%% Potential partial reg stall on alternative 2. What to do?
8634 (define_insn "*andqi_1"
8635 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8636 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8637 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8638 (clobber (reg:CC 17))]
8639 "ix86_binary_operator_ok (AND, QImode, operands)"
8640 "@
8641 and{b}\t{%2, %0|%0, %2}
8642 and{b}\t{%2, %0|%0, %2}
8643 and{l}\t{%k2, %k0|%k0, %k2}"
8644 [(set_attr "type" "alu")
8645 (set_attr "mode" "QI,QI,SI")])
8646
8647 (define_insn "*andqi_1_slp"
8648 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8649 (and:QI (match_dup 0)
8650 (match_operand:QI 1 "general_operand" "qi,qmi")))
8651 (clobber (reg:CC 17))]
8652 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8653 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8654 "and{b}\t{%1, %0|%0, %1}"
8655 [(set_attr "type" "alu1")
8656 (set_attr "mode" "QI")])
8657
8658 (define_insn "*andqi_2"
8659 [(set (reg 17)
8660 (compare (and:QI
8661 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8662 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8663 (const_int 0)))
8664 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8665 (and:QI (match_dup 1) (match_dup 2)))]
8666 "ix86_match_ccmode (insn, CCNOmode)
8667 && ix86_binary_operator_ok (AND, QImode, operands)"
8668 {
8669 if (which_alternative == 2)
8670 {
8671 if (GET_CODE (operands[2]) == CONST_INT
8672 && (INTVAL (operands[2]) & 0xffffff00))
8673 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8674 return "and{l}\t{%2, %k0|%k0, %2}";
8675 }
8676 return "and{b}\t{%2, %0|%0, %2}";
8677 }
8678 [(set_attr "type" "alu")
8679 (set_attr "mode" "QI,QI,SI")])
8680
8681 (define_insn "*andqi_2_slp"
8682 [(set (reg 17)
8683 (compare (and:QI
8684 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8685 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8686 (const_int 0)))
8687 (set (strict_low_part (match_dup 0))
8688 (and:QI (match_dup 0) (match_dup 1)))]
8689 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8690 && ix86_match_ccmode (insn, CCNOmode)
8691 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8692 "and{b}\t{%1, %0|%0, %1}"
8693 [(set_attr "type" "alu1")
8694 (set_attr "mode" "QI")])
8695
8696 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8697 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8698 ;; for a QImode operand, which of course failed.
8699
8700 (define_insn "andqi_ext_0"
8701 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8702 (const_int 8)
8703 (const_int 8))
8704 (and:SI
8705 (zero_extract:SI
8706 (match_operand 1 "ext_register_operand" "0")
8707 (const_int 8)
8708 (const_int 8))
8709 (match_operand 2 "const_int_operand" "n")))
8710 (clobber (reg:CC 17))]
8711 ""
8712 "and{b}\t{%2, %h0|%h0, %2}"
8713 [(set_attr "type" "alu")
8714 (set_attr "length_immediate" "1")
8715 (set_attr "mode" "QI")])
8716
8717 ;; Generated by peephole translating test to and. This shows up
8718 ;; often in fp comparisons.
8719
8720 (define_insn "*andqi_ext_0_cc"
8721 [(set (reg 17)
8722 (compare
8723 (and:SI
8724 (zero_extract:SI
8725 (match_operand 1 "ext_register_operand" "0")
8726 (const_int 8)
8727 (const_int 8))
8728 (match_operand 2 "const_int_operand" "n"))
8729 (const_int 0)))
8730 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8731 (const_int 8)
8732 (const_int 8))
8733 (and:SI
8734 (zero_extract:SI
8735 (match_dup 1)
8736 (const_int 8)
8737 (const_int 8))
8738 (match_dup 2)))]
8739 "ix86_match_ccmode (insn, CCNOmode)"
8740 "and{b}\t{%2, %h0|%h0, %2}"
8741 [(set_attr "type" "alu")
8742 (set_attr "length_immediate" "1")
8743 (set_attr "mode" "QI")])
8744
8745 (define_insn "*andqi_ext_1"
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:QI 2 "general_operand" "Qm"))))
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_1_rex64"
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_extend:SI
8773 (match_operand 2 "ext_register_operand" "Q"))))
8774 (clobber (reg:CC 17))]
8775 "TARGET_64BIT"
8776 "and{b}\t{%2, %h0|%h0, %2}"
8777 [(set_attr "type" "alu")
8778 (set_attr "length_immediate" "0")
8779 (set_attr "mode" "QI")])
8780
8781 (define_insn "*andqi_ext_2"
8782 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8783 (const_int 8)
8784 (const_int 8))
8785 (and:SI
8786 (zero_extract:SI
8787 (match_operand 1 "ext_register_operand" "%0")
8788 (const_int 8)
8789 (const_int 8))
8790 (zero_extract:SI
8791 (match_operand 2 "ext_register_operand" "Q")
8792 (const_int 8)
8793 (const_int 8))))
8794 (clobber (reg:CC 17))]
8795 ""
8796 "and{b}\t{%h2, %h0|%h0, %h2}"
8797 [(set_attr "type" "alu")
8798 (set_attr "length_immediate" "0")
8799 (set_attr "mode" "QI")])
8800
8801 ;; Convert wide AND instructions with immediate operand to shorter QImode
8802 ;; equivalents when possible.
8803 ;; Don't do the splitting with memory operands, since it introduces risk
8804 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8805 ;; for size, but that can (should?) be handled by generic code instead.
8806 (define_split
8807 [(set (match_operand 0 "register_operand" "")
8808 (and (match_operand 1 "register_operand" "")
8809 (match_operand 2 "const_int_operand" "")))
8810 (clobber (reg:CC 17))]
8811 "reload_completed
8812 && QI_REG_P (operands[0])
8813 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8814 && !(~INTVAL (operands[2]) & ~(255 << 8))
8815 && GET_MODE (operands[0]) != QImode"
8816 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8817 (and:SI (zero_extract:SI (match_dup 1)
8818 (const_int 8) (const_int 8))
8819 (match_dup 2)))
8820 (clobber (reg:CC 17))])]
8821 "operands[0] = gen_lowpart (SImode, operands[0]);
8822 operands[1] = gen_lowpart (SImode, operands[1]);
8823 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8824
8825 ;; Since AND can be encoded with sign extended immediate, this is only
8826 ;; profitable when 7th bit is not set.
8827 (define_split
8828 [(set (match_operand 0 "register_operand" "")
8829 (and (match_operand 1 "general_operand" "")
8830 (match_operand 2 "const_int_operand" "")))
8831 (clobber (reg:CC 17))]
8832 "reload_completed
8833 && ANY_QI_REG_P (operands[0])
8834 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8835 && !(~INTVAL (operands[2]) & ~255)
8836 && !(INTVAL (operands[2]) & 128)
8837 && GET_MODE (operands[0]) != QImode"
8838 [(parallel [(set (strict_low_part (match_dup 0))
8839 (and:QI (match_dup 1)
8840 (match_dup 2)))
8841 (clobber (reg:CC 17))])]
8842 "operands[0] = gen_lowpart (QImode, operands[0]);
8843 operands[1] = gen_lowpart (QImode, operands[1]);
8844 operands[2] = gen_lowpart (QImode, operands[2]);")
8845 \f
8846 ;; Logical inclusive OR instructions
8847
8848 ;; %%% This used to optimize known byte-wide and operations to memory.
8849 ;; If this is considered useful, it should be done with splitters.
8850
8851 (define_expand "iordi3"
8852 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8853 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8854 (match_operand:DI 2 "x86_64_general_operand" "")))
8855 (clobber (reg:CC 17))]
8856 "TARGET_64BIT"
8857 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8858
8859 (define_insn "*iordi_1_rex64"
8860 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8861 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8862 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8863 (clobber (reg:CC 17))]
8864 "TARGET_64BIT
8865 && ix86_binary_operator_ok (IOR, DImode, operands)"
8866 "or{q}\t{%2, %0|%0, %2}"
8867 [(set_attr "type" "alu")
8868 (set_attr "mode" "DI")])
8869
8870 (define_insn "*iordi_2_rex64"
8871 [(set (reg 17)
8872 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8873 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8874 (const_int 0)))
8875 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8876 (ior:DI (match_dup 1) (match_dup 2)))]
8877 "TARGET_64BIT
8878 && ix86_match_ccmode (insn, CCNOmode)
8879 && ix86_binary_operator_ok (IOR, DImode, operands)"
8880 "or{q}\t{%2, %0|%0, %2}"
8881 [(set_attr "type" "alu")
8882 (set_attr "mode" "DI")])
8883
8884 (define_insn "*iordi_3_rex64"
8885 [(set (reg 17)
8886 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8887 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8888 (const_int 0)))
8889 (clobber (match_scratch:DI 0 "=r"))]
8890 "TARGET_64BIT
8891 && ix86_match_ccmode (insn, CCNOmode)
8892 && ix86_binary_operator_ok (IOR, DImode, operands)"
8893 "or{q}\t{%2, %0|%0, %2}"
8894 [(set_attr "type" "alu")
8895 (set_attr "mode" "DI")])
8896
8897
8898 (define_expand "iorsi3"
8899 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8900 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8901 (match_operand:SI 2 "general_operand" "")))
8902 (clobber (reg:CC 17))]
8903 ""
8904 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8905
8906 (define_insn "*iorsi_1"
8907 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8908 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8909 (match_operand:SI 2 "general_operand" "ri,rmi")))
8910 (clobber (reg:CC 17))]
8911 "ix86_binary_operator_ok (IOR, SImode, operands)"
8912 "or{l}\t{%2, %0|%0, %2}"
8913 [(set_attr "type" "alu")
8914 (set_attr "mode" "SI")])
8915
8916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8917 (define_insn "*iorsi_1_zext"
8918 [(set (match_operand:DI 0 "register_operand" "=rm")
8919 (zero_extend:DI
8920 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921 (match_operand:SI 2 "general_operand" "rim"))))
8922 (clobber (reg:CC 17))]
8923 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8924 "or{l}\t{%2, %k0|%k0, %2}"
8925 [(set_attr "type" "alu")
8926 (set_attr "mode" "SI")])
8927
8928 (define_insn "*iorsi_1_zext_imm"
8929 [(set (match_operand:DI 0 "register_operand" "=rm")
8930 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8931 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8932 (clobber (reg:CC 17))]
8933 "TARGET_64BIT"
8934 "or{l}\t{%2, %k0|%k0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "SI")])
8937
8938 (define_insn "*iorsi_2"
8939 [(set (reg 17)
8940 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8941 (match_operand:SI 2 "general_operand" "rim,ri"))
8942 (const_int 0)))
8943 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8944 (ior:SI (match_dup 1) (match_dup 2)))]
8945 "ix86_match_ccmode (insn, CCNOmode)
8946 && ix86_binary_operator_ok (IOR, SImode, operands)"
8947 "or{l}\t{%2, %0|%0, %2}"
8948 [(set_attr "type" "alu")
8949 (set_attr "mode" "SI")])
8950
8951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952 ;; ??? Special case for immediate operand is missing - it is tricky.
8953 (define_insn "*iorsi_2_zext"
8954 [(set (reg 17)
8955 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "general_operand" "rim"))
8957 (const_int 0)))
8958 (set (match_operand:DI 0 "register_operand" "=r")
8959 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8960 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961 && ix86_binary_operator_ok (IOR, SImode, operands)"
8962 "or{l}\t{%2, %k0|%k0, %2}"
8963 [(set_attr "type" "alu")
8964 (set_attr "mode" "SI")])
8965
8966 (define_insn "*iorsi_2_zext_imm"
8967 [(set (reg 17)
8968 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8969 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8970 (const_int 0)))
8971 (set (match_operand:DI 0 "register_operand" "=r")
8972 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8973 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8974 && ix86_binary_operator_ok (IOR, SImode, operands)"
8975 "or{l}\t{%2, %k0|%k0, %2}"
8976 [(set_attr "type" "alu")
8977 (set_attr "mode" "SI")])
8978
8979 (define_insn "*iorsi_3"
8980 [(set (reg 17)
8981 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8982 (match_operand:SI 2 "general_operand" "rim"))
8983 (const_int 0)))
8984 (clobber (match_scratch:SI 0 "=r"))]
8985 "ix86_match_ccmode (insn, CCNOmode)
8986 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8987 "or{l}\t{%2, %0|%0, %2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "SI")])
8990
8991 (define_expand "iorhi3"
8992 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8993 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8994 (match_operand:HI 2 "general_operand" "")))
8995 (clobber (reg:CC 17))]
8996 "TARGET_HIMODE_MATH"
8997 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8998
8999 (define_insn "*iorhi_1"
9000 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9001 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9002 (match_operand:HI 2 "general_operand" "rmi,ri")))
9003 (clobber (reg:CC 17))]
9004 "ix86_binary_operator_ok (IOR, HImode, operands)"
9005 "or{w}\t{%2, %0|%0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "HI")])
9008
9009 (define_insn "*iorhi_2"
9010 [(set (reg 17)
9011 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9012 (match_operand:HI 2 "general_operand" "rim,ri"))
9013 (const_int 0)))
9014 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9015 (ior:HI (match_dup 1) (match_dup 2)))]
9016 "ix86_match_ccmode (insn, CCNOmode)
9017 && ix86_binary_operator_ok (IOR, HImode, operands)"
9018 "or{w}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "HI")])
9021
9022 (define_insn "*iorhi_3"
9023 [(set (reg 17)
9024 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9025 (match_operand:HI 2 "general_operand" "rim"))
9026 (const_int 0)))
9027 (clobber (match_scratch:HI 0 "=r"))]
9028 "ix86_match_ccmode (insn, CCNOmode)
9029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9030 "or{w}\t{%2, %0|%0, %2}"
9031 [(set_attr "type" "alu")
9032 (set_attr "mode" "HI")])
9033
9034 (define_expand "iorqi3"
9035 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9036 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9037 (match_operand:QI 2 "general_operand" "")))
9038 (clobber (reg:CC 17))]
9039 "TARGET_QIMODE_MATH"
9040 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9041
9042 ;; %%% Potential partial reg stall on alternative 2. What to do?
9043 (define_insn "*iorqi_1"
9044 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9045 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9046 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9047 (clobber (reg:CC 17))]
9048 "ix86_binary_operator_ok (IOR, QImode, operands)"
9049 "@
9050 or{b}\t{%2, %0|%0, %2}
9051 or{b}\t{%2, %0|%0, %2}
9052 or{l}\t{%k2, %k0|%k0, %k2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "QI,QI,SI")])
9055
9056 (define_insn "*iorqi_1_slp"
9057 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9058 (ior:QI (match_dup 0)
9059 (match_operand:QI 1 "general_operand" "qmi,qi")))
9060 (clobber (reg:CC 17))]
9061 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9062 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9063 "or{b}\t{%1, %0|%0, %1}"
9064 [(set_attr "type" "alu1")
9065 (set_attr "mode" "QI")])
9066
9067 (define_insn "*iorqi_2"
9068 [(set (reg 17)
9069 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9070 (match_operand:QI 2 "general_operand" "qim,qi"))
9071 (const_int 0)))
9072 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9073 (ior:QI (match_dup 1) (match_dup 2)))]
9074 "ix86_match_ccmode (insn, CCNOmode)
9075 && ix86_binary_operator_ok (IOR, QImode, operands)"
9076 "or{b}\t{%2, %0|%0, %2}"
9077 [(set_attr "type" "alu")
9078 (set_attr "mode" "QI")])
9079
9080 (define_insn "*iorqi_2_slp"
9081 [(set (reg 17)
9082 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9083 (match_operand:QI 1 "general_operand" "qim,qi"))
9084 (const_int 0)))
9085 (set (strict_low_part (match_dup 0))
9086 (ior:QI (match_dup 0) (match_dup 1)))]
9087 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9088 && ix86_match_ccmode (insn, CCNOmode)
9089 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9090 "or{b}\t{%1, %0|%0, %1}"
9091 [(set_attr "type" "alu1")
9092 (set_attr "mode" "QI")])
9093
9094 (define_insn "*iorqi_3"
9095 [(set (reg 17)
9096 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9097 (match_operand:QI 2 "general_operand" "qim"))
9098 (const_int 0)))
9099 (clobber (match_scratch:QI 0 "=q"))]
9100 "ix86_match_ccmode (insn, CCNOmode)
9101 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9102 "or{b}\t{%2, %0|%0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "QI")])
9105
9106 (define_insn "iorqi_ext_0"
9107 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9108 (const_int 8)
9109 (const_int 8))
9110 (ior:SI
9111 (zero_extract:SI
9112 (match_operand 1 "ext_register_operand" "0")
9113 (const_int 8)
9114 (const_int 8))
9115 (match_operand 2 "const_int_operand" "n")))
9116 (clobber (reg:CC 17))]
9117 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9118 "or{b}\t{%2, %h0|%h0, %2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "length_immediate" "1")
9121 (set_attr "mode" "QI")])
9122
9123 (define_insn "*iorqi_ext_1"
9124 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9125 (const_int 8)
9126 (const_int 8))
9127 (ior:SI
9128 (zero_extract:SI
9129 (match_operand 1 "ext_register_operand" "0")
9130 (const_int 8)
9131 (const_int 8))
9132 (zero_extend:SI
9133 (match_operand:QI 2 "general_operand" "Qm"))))
9134 (clobber (reg:CC 17))]
9135 "!TARGET_64BIT
9136 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9137 "or{b}\t{%2, %h0|%h0, %2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "length_immediate" "0")
9140 (set_attr "mode" "QI")])
9141
9142 (define_insn "*iorqi_ext_1_rex64"
9143 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9144 (const_int 8)
9145 (const_int 8))
9146 (ior:SI
9147 (zero_extract:SI
9148 (match_operand 1 "ext_register_operand" "0")
9149 (const_int 8)
9150 (const_int 8))
9151 (zero_extend:SI
9152 (match_operand 2 "ext_register_operand" "Q"))))
9153 (clobber (reg:CC 17))]
9154 "TARGET_64BIT
9155 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9156 "or{b}\t{%2, %h0|%h0, %2}"
9157 [(set_attr "type" "alu")
9158 (set_attr "length_immediate" "0")
9159 (set_attr "mode" "QI")])
9160
9161 (define_insn "*iorqi_ext_2"
9162 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9163 (const_int 8)
9164 (const_int 8))
9165 (ior:SI
9166 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9167 (const_int 8)
9168 (const_int 8))
9169 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9170 (const_int 8)
9171 (const_int 8))))
9172 (clobber (reg:CC 17))]
9173 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9174 "ior{b}\t{%h2, %h0|%h0, %h2}"
9175 [(set_attr "type" "alu")
9176 (set_attr "length_immediate" "0")
9177 (set_attr "mode" "QI")])
9178
9179 (define_split
9180 [(set (match_operand 0 "register_operand" "")
9181 (ior (match_operand 1 "register_operand" "")
9182 (match_operand 2 "const_int_operand" "")))
9183 (clobber (reg:CC 17))]
9184 "reload_completed
9185 && QI_REG_P (operands[0])
9186 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9187 && !(INTVAL (operands[2]) & ~(255 << 8))
9188 && GET_MODE (operands[0]) != QImode"
9189 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9190 (ior:SI (zero_extract:SI (match_dup 1)
9191 (const_int 8) (const_int 8))
9192 (match_dup 2)))
9193 (clobber (reg:CC 17))])]
9194 "operands[0] = gen_lowpart (SImode, operands[0]);
9195 operands[1] = gen_lowpart (SImode, operands[1]);
9196 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9197
9198 ;; Since OR can be encoded with sign extended immediate, this is only
9199 ;; profitable when 7th bit is set.
9200 (define_split
9201 [(set (match_operand 0 "register_operand" "")
9202 (ior (match_operand 1 "general_operand" "")
9203 (match_operand 2 "const_int_operand" "")))
9204 (clobber (reg:CC 17))]
9205 "reload_completed
9206 && ANY_QI_REG_P (operands[0])
9207 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9208 && !(INTVAL (operands[2]) & ~255)
9209 && (INTVAL (operands[2]) & 128)
9210 && GET_MODE (operands[0]) != QImode"
9211 [(parallel [(set (strict_low_part (match_dup 0))
9212 (ior:QI (match_dup 1)
9213 (match_dup 2)))
9214 (clobber (reg:CC 17))])]
9215 "operands[0] = gen_lowpart (QImode, operands[0]);
9216 operands[1] = gen_lowpart (QImode, operands[1]);
9217 operands[2] = gen_lowpart (QImode, operands[2]);")
9218 \f
9219 ;; Logical XOR instructions
9220
9221 ;; %%% This used to optimize known byte-wide and operations to memory.
9222 ;; If this is considered useful, it should be done with splitters.
9223
9224 (define_expand "xordi3"
9225 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9226 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9227 (match_operand:DI 2 "x86_64_general_operand" "")))
9228 (clobber (reg:CC 17))]
9229 "TARGET_64BIT"
9230 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9231
9232 (define_insn "*xordi_1_rex64"
9233 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9234 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9235 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9236 (clobber (reg:CC 17))]
9237 "TARGET_64BIT
9238 && ix86_binary_operator_ok (XOR, DImode, operands)"
9239 "@
9240 xor{q}\t{%2, %0|%0, %2}
9241 xor{q}\t{%2, %0|%0, %2}"
9242 [(set_attr "type" "alu")
9243 (set_attr "mode" "DI,DI")])
9244
9245 (define_insn "*xordi_2_rex64"
9246 [(set (reg 17)
9247 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9248 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9249 (const_int 0)))
9250 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9251 (xor:DI (match_dup 1) (match_dup 2)))]
9252 "TARGET_64BIT
9253 && ix86_match_ccmode (insn, CCNOmode)
9254 && ix86_binary_operator_ok (XOR, DImode, operands)"
9255 "@
9256 xor{q}\t{%2, %0|%0, %2}
9257 xor{q}\t{%2, %0|%0, %2}"
9258 [(set_attr "type" "alu")
9259 (set_attr "mode" "DI,DI")])
9260
9261 (define_insn "*xordi_3_rex64"
9262 [(set (reg 17)
9263 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9264 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9265 (const_int 0)))
9266 (clobber (match_scratch:DI 0 "=r"))]
9267 "TARGET_64BIT
9268 && ix86_match_ccmode (insn, CCNOmode)
9269 && ix86_binary_operator_ok (XOR, DImode, operands)"
9270 "xor{q}\t{%2, %0|%0, %2}"
9271 [(set_attr "type" "alu")
9272 (set_attr "mode" "DI")])
9273
9274 (define_expand "xorsi3"
9275 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9276 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9277 (match_operand:SI 2 "general_operand" "")))
9278 (clobber (reg:CC 17))]
9279 ""
9280 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9281
9282 (define_insn "*xorsi_1"
9283 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9284 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9285 (match_operand:SI 2 "general_operand" "ri,rm")))
9286 (clobber (reg:CC 17))]
9287 "ix86_binary_operator_ok (XOR, SImode, operands)"
9288 "xor{l}\t{%2, %0|%0, %2}"
9289 [(set_attr "type" "alu")
9290 (set_attr "mode" "SI")])
9291
9292 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9293 ;; Add speccase for immediates
9294 (define_insn "*xorsi_1_zext"
9295 [(set (match_operand:DI 0 "register_operand" "=r")
9296 (zero_extend:DI
9297 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9298 (match_operand:SI 2 "general_operand" "rim"))))
9299 (clobber (reg:CC 17))]
9300 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9301 "xor{l}\t{%2, %k0|%k0, %2}"
9302 [(set_attr "type" "alu")
9303 (set_attr "mode" "SI")])
9304
9305 (define_insn "*xorsi_1_zext_imm"
9306 [(set (match_operand:DI 0 "register_operand" "=r")
9307 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9308 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9309 (clobber (reg:CC 17))]
9310 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9311 "xor{l}\t{%2, %k0|%k0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "SI")])
9314
9315 (define_insn "*xorsi_2"
9316 [(set (reg 17)
9317 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9318 (match_operand:SI 2 "general_operand" "rim,ri"))
9319 (const_int 0)))
9320 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9321 (xor:SI (match_dup 1) (match_dup 2)))]
9322 "ix86_match_ccmode (insn, CCNOmode)
9323 && ix86_binary_operator_ok (XOR, SImode, operands)"
9324 "xor{l}\t{%2, %0|%0, %2}"
9325 [(set_attr "type" "alu")
9326 (set_attr "mode" "SI")])
9327
9328 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9329 ;; ??? Special case for immediate operand is missing - it is tricky.
9330 (define_insn "*xorsi_2_zext"
9331 [(set (reg 17)
9332 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9333 (match_operand:SI 2 "general_operand" "rim"))
9334 (const_int 0)))
9335 (set (match_operand:DI 0 "register_operand" "=r")
9336 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9337 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9338 && ix86_binary_operator_ok (XOR, SImode, operands)"
9339 "xor{l}\t{%2, %k0|%k0, %2}"
9340 [(set_attr "type" "alu")
9341 (set_attr "mode" "SI")])
9342
9343 (define_insn "*xorsi_2_zext_imm"
9344 [(set (reg 17)
9345 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9346 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9347 (const_int 0)))
9348 (set (match_operand:DI 0 "register_operand" "=r")
9349 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9350 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9351 && ix86_binary_operator_ok (XOR, SImode, operands)"
9352 "xor{l}\t{%2, %k0|%k0, %2}"
9353 [(set_attr "type" "alu")
9354 (set_attr "mode" "SI")])
9355
9356 (define_insn "*xorsi_3"
9357 [(set (reg 17)
9358 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9359 (match_operand:SI 2 "general_operand" "rim"))
9360 (const_int 0)))
9361 (clobber (match_scratch:SI 0 "=r"))]
9362 "ix86_match_ccmode (insn, CCNOmode)
9363 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9364 "xor{l}\t{%2, %0|%0, %2}"
9365 [(set_attr "type" "alu")
9366 (set_attr "mode" "SI")])
9367
9368 (define_expand "xorhi3"
9369 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9370 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9371 (match_operand:HI 2 "general_operand" "")))
9372 (clobber (reg:CC 17))]
9373 "TARGET_HIMODE_MATH"
9374 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9375
9376 (define_insn "*xorhi_1"
9377 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9378 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9379 (match_operand:HI 2 "general_operand" "rmi,ri")))
9380 (clobber (reg:CC 17))]
9381 "ix86_binary_operator_ok (XOR, HImode, operands)"
9382 "xor{w}\t{%2, %0|%0, %2}"
9383 [(set_attr "type" "alu")
9384 (set_attr "mode" "HI")])
9385
9386 (define_insn "*xorhi_2"
9387 [(set (reg 17)
9388 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9389 (match_operand:HI 2 "general_operand" "rim,ri"))
9390 (const_int 0)))
9391 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9392 (xor:HI (match_dup 1) (match_dup 2)))]
9393 "ix86_match_ccmode (insn, CCNOmode)
9394 && ix86_binary_operator_ok (XOR, HImode, operands)"
9395 "xor{w}\t{%2, %0|%0, %2}"
9396 [(set_attr "type" "alu")
9397 (set_attr "mode" "HI")])
9398
9399 (define_insn "*xorhi_3"
9400 [(set (reg 17)
9401 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9402 (match_operand:HI 2 "general_operand" "rim"))
9403 (const_int 0)))
9404 (clobber (match_scratch:HI 0 "=r"))]
9405 "ix86_match_ccmode (insn, CCNOmode)
9406 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9407 "xor{w}\t{%2, %0|%0, %2}"
9408 [(set_attr "type" "alu")
9409 (set_attr "mode" "HI")])
9410
9411 (define_expand "xorqi3"
9412 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9413 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9414 (match_operand:QI 2 "general_operand" "")))
9415 (clobber (reg:CC 17))]
9416 "TARGET_QIMODE_MATH"
9417 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9418
9419 ;; %%% Potential partial reg stall on alternative 2. What to do?
9420 (define_insn "*xorqi_1"
9421 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9422 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9423 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9424 (clobber (reg:CC 17))]
9425 "ix86_binary_operator_ok (XOR, QImode, operands)"
9426 "@
9427 xor{b}\t{%2, %0|%0, %2}
9428 xor{b}\t{%2, %0|%0, %2}
9429 xor{l}\t{%k2, %k0|%k0, %k2}"
9430 [(set_attr "type" "alu")
9431 (set_attr "mode" "QI,QI,SI")])
9432
9433 (define_insn "*xorqi_1_slp"
9434 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9435 (xor:QI (match_dup 0)
9436 (match_operand:QI 1 "general_operand" "qi,qmi")))
9437 (clobber (reg:CC 17))]
9438 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9439 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9440 "xor{b}\t{%1, %0|%0, %1}"
9441 [(set_attr "type" "alu1")
9442 (set_attr "mode" "QI")])
9443
9444 (define_insn "xorqi_ext_0"
9445 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9446 (const_int 8)
9447 (const_int 8))
9448 (xor:SI
9449 (zero_extract:SI
9450 (match_operand 1 "ext_register_operand" "0")
9451 (const_int 8)
9452 (const_int 8))
9453 (match_operand 2 "const_int_operand" "n")))
9454 (clobber (reg:CC 17))]
9455 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9456 "xor{b}\t{%2, %h0|%h0, %2}"
9457 [(set_attr "type" "alu")
9458 (set_attr "length_immediate" "1")
9459 (set_attr "mode" "QI")])
9460
9461 (define_insn "*xorqi_ext_1"
9462 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9463 (const_int 8)
9464 (const_int 8))
9465 (xor:SI
9466 (zero_extract:SI
9467 (match_operand 1 "ext_register_operand" "0")
9468 (const_int 8)
9469 (const_int 8))
9470 (zero_extend:SI
9471 (match_operand:QI 2 "general_operand" "Qm"))))
9472 (clobber (reg:CC 17))]
9473 "!TARGET_64BIT
9474 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9475 "xor{b}\t{%2, %h0|%h0, %2}"
9476 [(set_attr "type" "alu")
9477 (set_attr "length_immediate" "0")
9478 (set_attr "mode" "QI")])
9479
9480 (define_insn "*xorqi_ext_1_rex64"
9481 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9482 (const_int 8)
9483 (const_int 8))
9484 (xor:SI
9485 (zero_extract:SI
9486 (match_operand 1 "ext_register_operand" "0")
9487 (const_int 8)
9488 (const_int 8))
9489 (zero_extend:SI
9490 (match_operand 2 "ext_register_operand" "Q"))))
9491 (clobber (reg:CC 17))]
9492 "TARGET_64BIT
9493 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9494 "xor{b}\t{%2, %h0|%h0, %2}"
9495 [(set_attr "type" "alu")
9496 (set_attr "length_immediate" "0")
9497 (set_attr "mode" "QI")])
9498
9499 (define_insn "*xorqi_ext_2"
9500 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9501 (const_int 8)
9502 (const_int 8))
9503 (xor:SI
9504 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9505 (const_int 8)
9506 (const_int 8))
9507 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9508 (const_int 8)
9509 (const_int 8))))
9510 (clobber (reg:CC 17))]
9511 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9512 "xor{b}\t{%h2, %h0|%h0, %h2}"
9513 [(set_attr "type" "alu")
9514 (set_attr "length_immediate" "0")
9515 (set_attr "mode" "QI")])
9516
9517 (define_insn "*xorqi_cc_1"
9518 [(set (reg 17)
9519 (compare
9520 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9521 (match_operand:QI 2 "general_operand" "qim,qi"))
9522 (const_int 0)))
9523 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9524 (xor:QI (match_dup 1) (match_dup 2)))]
9525 "ix86_match_ccmode (insn, CCNOmode)
9526 && ix86_binary_operator_ok (XOR, QImode, operands)"
9527 "xor{b}\t{%2, %0|%0, %2}"
9528 [(set_attr "type" "alu")
9529 (set_attr "mode" "QI")])
9530
9531 (define_insn "*xorqi_2_slp"
9532 [(set (reg 17)
9533 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9534 (match_operand:QI 1 "general_operand" "qim,qi"))
9535 (const_int 0)))
9536 (set (strict_low_part (match_dup 0))
9537 (xor:QI (match_dup 0) (match_dup 1)))]
9538 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9539 && ix86_match_ccmode (insn, CCNOmode)
9540 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9541 "xor{b}\t{%1, %0|%0, %1}"
9542 [(set_attr "type" "alu1")
9543 (set_attr "mode" "QI")])
9544
9545 (define_insn "*xorqi_cc_2"
9546 [(set (reg 17)
9547 (compare
9548 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9549 (match_operand:QI 2 "general_operand" "qim"))
9550 (const_int 0)))
9551 (clobber (match_scratch:QI 0 "=q"))]
9552 "ix86_match_ccmode (insn, CCNOmode)
9553 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9554 "xor{b}\t{%2, %0|%0, %2}"
9555 [(set_attr "type" "alu")
9556 (set_attr "mode" "QI")])
9557
9558 (define_insn "*xorqi_cc_ext_1"
9559 [(set (reg 17)
9560 (compare
9561 (xor:SI
9562 (zero_extract:SI
9563 (match_operand 1 "ext_register_operand" "0")
9564 (const_int 8)
9565 (const_int 8))
9566 (match_operand:QI 2 "general_operand" "qmn"))
9567 (const_int 0)))
9568 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9569 (const_int 8)
9570 (const_int 8))
9571 (xor:SI
9572 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9573 (match_dup 2)))]
9574 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9575 "xor{b}\t{%2, %h0|%h0, %2}"
9576 [(set_attr "type" "alu")
9577 (set_attr "mode" "QI")])
9578
9579 (define_insn "*xorqi_cc_ext_1_rex64"
9580 [(set (reg 17)
9581 (compare
9582 (xor:SI
9583 (zero_extract:SI
9584 (match_operand 1 "ext_register_operand" "0")
9585 (const_int 8)
9586 (const_int 8))
9587 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9588 (const_int 0)))
9589 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9590 (const_int 8)
9591 (const_int 8))
9592 (xor:SI
9593 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9594 (match_dup 2)))]
9595 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9596 "xor{b}\t{%2, %h0|%h0, %2}"
9597 [(set_attr "type" "alu")
9598 (set_attr "mode" "QI")])
9599
9600 (define_expand "xorqi_cc_ext_1"
9601 [(parallel [
9602 (set (reg:CCNO 17)
9603 (compare:CCNO
9604 (xor:SI
9605 (zero_extract:SI
9606 (match_operand 1 "ext_register_operand" "")
9607 (const_int 8)
9608 (const_int 8))
9609 (match_operand:QI 2 "general_operand" ""))
9610 (const_int 0)))
9611 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9612 (const_int 8)
9613 (const_int 8))
9614 (xor:SI
9615 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9616 (match_dup 2)))])]
9617 ""
9618 "")
9619
9620 (define_split
9621 [(set (match_operand 0 "register_operand" "")
9622 (xor (match_operand 1 "register_operand" "")
9623 (match_operand 2 "const_int_operand" "")))
9624 (clobber (reg:CC 17))]
9625 "reload_completed
9626 && QI_REG_P (operands[0])
9627 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9628 && !(INTVAL (operands[2]) & ~(255 << 8))
9629 && GET_MODE (operands[0]) != QImode"
9630 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9631 (xor:SI (zero_extract:SI (match_dup 1)
9632 (const_int 8) (const_int 8))
9633 (match_dup 2)))
9634 (clobber (reg:CC 17))])]
9635 "operands[0] = gen_lowpart (SImode, operands[0]);
9636 operands[1] = gen_lowpart (SImode, operands[1]);
9637 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9638
9639 ;; Since XOR can be encoded with sign extended immediate, this is only
9640 ;; profitable when 7th bit is set.
9641 (define_split
9642 [(set (match_operand 0 "register_operand" "")
9643 (xor (match_operand 1 "general_operand" "")
9644 (match_operand 2 "const_int_operand" "")))
9645 (clobber (reg:CC 17))]
9646 "reload_completed
9647 && ANY_QI_REG_P (operands[0])
9648 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9649 && !(INTVAL (operands[2]) & ~255)
9650 && (INTVAL (operands[2]) & 128)
9651 && GET_MODE (operands[0]) != QImode"
9652 [(parallel [(set (strict_low_part (match_dup 0))
9653 (xor:QI (match_dup 1)
9654 (match_dup 2)))
9655 (clobber (reg:CC 17))])]
9656 "operands[0] = gen_lowpart (QImode, operands[0]);
9657 operands[1] = gen_lowpart (QImode, operands[1]);
9658 operands[2] = gen_lowpart (QImode, operands[2]);")
9659 \f
9660 ;; Negation instructions
9661
9662 (define_expand "negdi2"
9663 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9664 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9665 (clobber (reg:CC 17))])]
9666 ""
9667 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9668
9669 (define_insn "*negdi2_1"
9670 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9671 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9672 (clobber (reg:CC 17))]
9673 "!TARGET_64BIT
9674 && ix86_unary_operator_ok (NEG, DImode, operands)"
9675 "#")
9676
9677 (define_split
9678 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9679 (neg:DI (match_operand:DI 1 "general_operand" "")))
9680 (clobber (reg:CC 17))]
9681 "!TARGET_64BIT && reload_completed"
9682 [(parallel
9683 [(set (reg:CCZ 17)
9684 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9685 (set (match_dup 0) (neg:SI (match_dup 2)))])
9686 (parallel
9687 [(set (match_dup 1)
9688 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9689 (match_dup 3))
9690 (const_int 0)))
9691 (clobber (reg:CC 17))])
9692 (parallel
9693 [(set (match_dup 1)
9694 (neg:SI (match_dup 1)))
9695 (clobber (reg:CC 17))])]
9696 "split_di (operands+1, 1, operands+2, operands+3);
9697 split_di (operands+0, 1, operands+0, operands+1);")
9698
9699 (define_insn "*negdi2_1_rex64"
9700 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9701 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9702 (clobber (reg:CC 17))]
9703 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9704 "neg{q}\t%0"
9705 [(set_attr "type" "negnot")
9706 (set_attr "mode" "DI")])
9707
9708 ;; The problem with neg is that it does not perform (compare x 0),
9709 ;; it really performs (compare 0 x), which leaves us with the zero
9710 ;; flag being the only useful item.
9711
9712 (define_insn "*negdi2_cmpz_rex64"
9713 [(set (reg:CCZ 17)
9714 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9715 (const_int 0)))
9716 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9717 (neg:DI (match_dup 1)))]
9718 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9719 "neg{q}\t%0"
9720 [(set_attr "type" "negnot")
9721 (set_attr "mode" "DI")])
9722
9723
9724 (define_expand "negsi2"
9725 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9726 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9727 (clobber (reg:CC 17))])]
9728 ""
9729 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9730
9731 (define_insn "*negsi2_1"
9732 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9733 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9734 (clobber (reg:CC 17))]
9735 "ix86_unary_operator_ok (NEG, SImode, operands)"
9736 "neg{l}\t%0"
9737 [(set_attr "type" "negnot")
9738 (set_attr "mode" "SI")])
9739
9740 ;; Combine is quite creative about this pattern.
9741 (define_insn "*negsi2_1_zext"
9742 [(set (match_operand:DI 0 "register_operand" "=r")
9743 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9744 (const_int 32)))
9745 (const_int 32)))
9746 (clobber (reg:CC 17))]
9747 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9748 "neg{l}\t%k0"
9749 [(set_attr "type" "negnot")
9750 (set_attr "mode" "SI")])
9751
9752 ;; The problem with neg is that it does not perform (compare x 0),
9753 ;; it really performs (compare 0 x), which leaves us with the zero
9754 ;; flag being the only useful item.
9755
9756 (define_insn "*negsi2_cmpz"
9757 [(set (reg:CCZ 17)
9758 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9759 (const_int 0)))
9760 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9761 (neg:SI (match_dup 1)))]
9762 "ix86_unary_operator_ok (NEG, SImode, operands)"
9763 "neg{l}\t%0"
9764 [(set_attr "type" "negnot")
9765 (set_attr "mode" "SI")])
9766
9767 (define_insn "*negsi2_cmpz_zext"
9768 [(set (reg:CCZ 17)
9769 (compare:CCZ (lshiftrt:DI
9770 (neg:DI (ashift:DI
9771 (match_operand:DI 1 "register_operand" "0")
9772 (const_int 32)))
9773 (const_int 32))
9774 (const_int 0)))
9775 (set (match_operand:DI 0 "register_operand" "=r")
9776 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9777 (const_int 32)))
9778 (const_int 32)))]
9779 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9780 "neg{l}\t%k0"
9781 [(set_attr "type" "negnot")
9782 (set_attr "mode" "SI")])
9783
9784 (define_expand "neghi2"
9785 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9786 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9787 (clobber (reg:CC 17))])]
9788 "TARGET_HIMODE_MATH"
9789 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9790
9791 (define_insn "*neghi2_1"
9792 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9793 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9794 (clobber (reg:CC 17))]
9795 "ix86_unary_operator_ok (NEG, HImode, operands)"
9796 "neg{w}\t%0"
9797 [(set_attr "type" "negnot")
9798 (set_attr "mode" "HI")])
9799
9800 (define_insn "*neghi2_cmpz"
9801 [(set (reg:CCZ 17)
9802 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9803 (const_int 0)))
9804 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9805 (neg:HI (match_dup 1)))]
9806 "ix86_unary_operator_ok (NEG, HImode, operands)"
9807 "neg{w}\t%0"
9808 [(set_attr "type" "negnot")
9809 (set_attr "mode" "HI")])
9810
9811 (define_expand "negqi2"
9812 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9813 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9814 (clobber (reg:CC 17))])]
9815 "TARGET_QIMODE_MATH"
9816 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9817
9818 (define_insn "*negqi2_1"
9819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9820 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9821 (clobber (reg:CC 17))]
9822 "ix86_unary_operator_ok (NEG, QImode, operands)"
9823 "neg{b}\t%0"
9824 [(set_attr "type" "negnot")
9825 (set_attr "mode" "QI")])
9826
9827 (define_insn "*negqi2_cmpz"
9828 [(set (reg:CCZ 17)
9829 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9830 (const_int 0)))
9831 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9832 (neg:QI (match_dup 1)))]
9833 "ix86_unary_operator_ok (NEG, QImode, operands)"
9834 "neg{b}\t%0"
9835 [(set_attr "type" "negnot")
9836 (set_attr "mode" "QI")])
9837
9838 ;; Changing of sign for FP values is doable using integer unit too.
9839
9840 (define_expand "negsf2"
9841 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9842 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9843 (clobber (reg:CC 17))])]
9844 "TARGET_80387"
9845 "if (TARGET_SSE)
9846 {
9847 /* In case operand is in memory, we will not use SSE. */
9848 if (memory_operand (operands[0], VOIDmode)
9849 && rtx_equal_p (operands[0], operands[1]))
9850 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9851 else
9852 {
9853 /* Using SSE is tricky, since we need bitwise negation of -0
9854 in register. */
9855 rtx reg = gen_reg_rtx (SFmode);
9856 rtx dest = operands[0];
9857 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9858
9859 operands[1] = force_reg (SFmode, operands[1]);
9860 operands[0] = force_reg (SFmode, operands[0]);
9861 reg = force_reg (V4SFmode,
9862 gen_rtx_CONST_VECTOR (V4SFmode,
9863 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9864 CONST0_RTX (SFmode),
9865 CONST0_RTX (SFmode))));
9866 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9867 if (dest != operands[0])
9868 emit_move_insn (dest, operands[0]);
9869 }
9870 DONE;
9871 }
9872 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9873
9874 (define_insn "negsf2_memory"
9875 [(set (match_operand:SF 0 "memory_operand" "=m")
9876 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9877 (clobber (reg:CC 17))]
9878 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9879 "#")
9880
9881 (define_insn "negsf2_ifs"
9882 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9883 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9884 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9885 (clobber (reg:CC 17))]
9886 "TARGET_SSE
9887 && (reload_in_progress || reload_completed
9888 || (register_operand (operands[0], VOIDmode)
9889 && register_operand (operands[1], VOIDmode)))"
9890 "#")
9891
9892 (define_split
9893 [(set (match_operand:SF 0 "memory_operand" "")
9894 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9895 (use (match_operand:SF 2 "" ""))
9896 (clobber (reg:CC 17))]
9897 ""
9898 [(parallel [(set (match_dup 0)
9899 (neg:SF (match_dup 1)))
9900 (clobber (reg:CC 17))])])
9901
9902 (define_split
9903 [(set (match_operand:SF 0 "register_operand" "")
9904 (neg:SF (match_operand:SF 1 "register_operand" "")))
9905 (use (match_operand:V4SF 2 "" ""))
9906 (clobber (reg:CC 17))]
9907 "reload_completed && !SSE_REG_P (operands[0])"
9908 [(parallel [(set (match_dup 0)
9909 (neg:SF (match_dup 1)))
9910 (clobber (reg:CC 17))])])
9911
9912 (define_split
9913 [(set (match_operand:SF 0 "register_operand" "")
9914 (neg:SF (match_operand:SF 1 "register_operand" "")))
9915 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9916 (clobber (reg:CC 17))]
9917 "reload_completed && SSE_REG_P (operands[0])"
9918 [(set (subreg:TI (match_dup 0) 0)
9919 (xor:TI (match_dup 1)
9920 (match_dup 2)))]
9921 {
9922 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9923 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9924 if (operands_match_p (operands[0], operands[2]))
9925 {
9926 rtx tmp;
9927 tmp = operands[1];
9928 operands[1] = operands[2];
9929 operands[2] = tmp;
9930 }
9931 })
9932
9933
9934 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9935 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9936 ;; to itself.
9937 (define_insn "*negsf2_if"
9938 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9939 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9940 (clobber (reg:CC 17))]
9941 "TARGET_80387 && !TARGET_SSE
9942 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9943 "#")
9944
9945 (define_split
9946 [(set (match_operand:SF 0 "fp_register_operand" "")
9947 (neg:SF (match_operand:SF 1 "register_operand" "")))
9948 (clobber (reg:CC 17))]
9949 "TARGET_80387 && reload_completed"
9950 [(set (match_dup 0)
9951 (neg:SF (match_dup 1)))]
9952 "")
9953
9954 (define_split
9955 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9956 (neg:SF (match_operand:SF 1 "register_operand" "")))
9957 (clobber (reg:CC 17))]
9958 "TARGET_80387 && reload_completed"
9959 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9960 (clobber (reg:CC 17))])]
9961 "operands[1] = gen_int_mode (0x80000000, SImode);
9962 operands[0] = gen_lowpart (SImode, operands[0]);")
9963
9964 (define_split
9965 [(set (match_operand 0 "memory_operand" "")
9966 (neg (match_operand 1 "memory_operand" "")))
9967 (clobber (reg:CC 17))]
9968 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9969 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9970 (clobber (reg:CC 17))])]
9971 {
9972 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9973
9974 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9975 if (size >= 12)
9976 size = 10;
9977 operands[0] = adjust_address (operands[0], QImode, size - 1);
9978 operands[1] = gen_int_mode (0x80, QImode);
9979 })
9980
9981 (define_expand "negdf2"
9982 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9983 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9984 (clobber (reg:CC 17))])]
9985 "TARGET_80387"
9986 "if (TARGET_SSE2)
9987 {
9988 /* In case operand is in memory, we will not use SSE. */
9989 if (memory_operand (operands[0], VOIDmode)
9990 && rtx_equal_p (operands[0], operands[1]))
9991 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9992 else
9993 {
9994 /* Using SSE is tricky, since we need bitwise negation of -0
9995 in register. */
9996 rtx reg;
9997 #if HOST_BITS_PER_WIDE_INT >= 64
9998 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9999 #else
10000 rtx imm = immed_double_const (0, 0x80000000, DImode);
10001 #endif
10002 rtx dest = operands[0];
10003
10004 operands[1] = force_reg (DFmode, operands[1]);
10005 operands[0] = force_reg (DFmode, operands[0]);
10006 imm = gen_lowpart (DFmode, imm);
10007 reg = force_reg (V2DFmode,
10008 gen_rtx_CONST_VECTOR (V2DFmode,
10009 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10010 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
10011 if (dest != operands[0])
10012 emit_move_insn (dest, operands[0]);
10013 }
10014 DONE;
10015 }
10016 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
10017
10018 (define_insn "negdf2_memory"
10019 [(set (match_operand:DF 0 "memory_operand" "=m")
10020 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10021 (clobber (reg:CC 17))]
10022 "ix86_unary_operator_ok (NEG, DFmode, operands)"
10023 "#")
10024
10025 (define_insn "negdf2_ifs"
10026 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10027 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10028 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10029 (clobber (reg:CC 17))]
10030 "!TARGET_64BIT && TARGET_SSE2
10031 && (reload_in_progress || reload_completed
10032 || (register_operand (operands[0], VOIDmode)
10033 && register_operand (operands[1], VOIDmode)))"
10034 "#")
10035
10036 (define_insn "*negdf2_ifs_rex64"
10037 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10038 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10039 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10040 (clobber (reg:CC 17))]
10041 "TARGET_64BIT && TARGET_SSE2
10042 && (reload_in_progress || reload_completed
10043 || (register_operand (operands[0], VOIDmode)
10044 && register_operand (operands[1], VOIDmode)))"
10045 "#")
10046
10047 (define_split
10048 [(set (match_operand:DF 0 "memory_operand" "")
10049 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10050 (use (match_operand:V2DF 2 "" ""))
10051 (clobber (reg:CC 17))]
10052 ""
10053 [(parallel [(set (match_dup 0)
10054 (neg:DF (match_dup 1)))
10055 (clobber (reg:CC 17))])])
10056
10057 (define_split
10058 [(set (match_operand:DF 0 "register_operand" "")
10059 (neg:DF (match_operand:DF 1 "register_operand" "")))
10060 (use (match_operand:V2DF 2 "" ""))
10061 (clobber (reg:CC 17))]
10062 "reload_completed && !SSE_REG_P (operands[0])
10063 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10064 [(parallel [(set (match_dup 0)
10065 (neg:DF (match_dup 1)))
10066 (clobber (reg:CC 17))])])
10067
10068 (define_split
10069 [(set (match_operand:DF 0 "register_operand" "")
10070 (neg:DF (match_operand:DF 1 "register_operand" "")))
10071 (use (match_operand:V2DF 2 "" ""))
10072 (clobber (reg:CC 17))]
10073 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10074 [(parallel [(set (match_dup 0)
10075 (xor:DI (match_dup 1) (match_dup 2)))
10076 (clobber (reg:CC 17))])]
10077 "operands[0] = gen_lowpart (DImode, operands[0]);
10078 operands[1] = gen_lowpart (DImode, operands[1]);
10079 operands[2] = gen_lowpart (DImode, operands[2]);")
10080
10081 (define_split
10082 [(set (match_operand:DF 0 "register_operand" "")
10083 (neg:DF (match_operand:DF 1 "register_operand" "")))
10084 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10085 (clobber (reg:CC 17))]
10086 "reload_completed && SSE_REG_P (operands[0])"
10087 [(set (subreg:TI (match_dup 0) 0)
10088 (xor:TI (match_dup 1)
10089 (match_dup 2)))]
10090 {
10091 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10092 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10093 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10094 /* Avoid possible reformatting on the operands. */
10095 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10096 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10097 if (operands_match_p (operands[0], operands[2]))
10098 {
10099 rtx tmp;
10100 tmp = operands[1];
10101 operands[1] = operands[2];
10102 operands[2] = tmp;
10103 }
10104 })
10105
10106 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10107 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10108 ;; to itself.
10109 (define_insn "*negdf2_if"
10110 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10111 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10112 (clobber (reg:CC 17))]
10113 "!TARGET_64BIT && TARGET_80387
10114 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10115 "#")
10116
10117 ;; FIXME: We should to allow integer registers here. Problem is that
10118 ;; we need another scratch register to get constant from.
10119 ;; Forcing constant to mem if no register available in peep2 should be
10120 ;; safe even for PIC mode, because of RIP relative addressing.
10121 (define_insn "*negdf2_if_rex64"
10122 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10123 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10124 (clobber (reg:CC 17))]
10125 "TARGET_64BIT && TARGET_80387
10126 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10127 "#")
10128
10129 (define_split
10130 [(set (match_operand:DF 0 "fp_register_operand" "")
10131 (neg:DF (match_operand:DF 1 "register_operand" "")))
10132 (clobber (reg:CC 17))]
10133 "TARGET_80387 && reload_completed"
10134 [(set (match_dup 0)
10135 (neg:DF (match_dup 1)))]
10136 "")
10137
10138 (define_split
10139 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10140 (neg:DF (match_operand:DF 1 "register_operand" "")))
10141 (clobber (reg:CC 17))]
10142 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10143 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10144 (clobber (reg:CC 17))])]
10145 "operands[4] = gen_int_mode (0x80000000, SImode);
10146 split_di (operands+0, 1, operands+2, operands+3);")
10147
10148 (define_expand "negxf2"
10149 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10150 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10151 (clobber (reg:CC 17))])]
10152 "!TARGET_64BIT && TARGET_80387"
10153 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10154
10155 (define_expand "negtf2"
10156 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10157 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10158 (clobber (reg:CC 17))])]
10159 "TARGET_80387"
10160 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10161
10162 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10163 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10164 ;; to itself.
10165 (define_insn "*negxf2_if"
10166 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10167 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10168 (clobber (reg:CC 17))]
10169 "!TARGET_64BIT && TARGET_80387
10170 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10171 "#")
10172
10173 (define_split
10174 [(set (match_operand:XF 0 "fp_register_operand" "")
10175 (neg:XF (match_operand:XF 1 "register_operand" "")))
10176 (clobber (reg:CC 17))]
10177 "TARGET_80387 && reload_completed"
10178 [(set (match_dup 0)
10179 (neg:XF (match_dup 1)))]
10180 "")
10181
10182 (define_split
10183 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10184 (neg:XF (match_operand:XF 1 "register_operand" "")))
10185 (clobber (reg:CC 17))]
10186 "TARGET_80387 && reload_completed"
10187 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10188 (clobber (reg:CC 17))])]
10189 "operands[1] = GEN_INT (0x8000);
10190 operands[0] = gen_rtx_REG (SImode,
10191 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10192
10193 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10194 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10195 ;; to itself.
10196 (define_insn "*negtf2_if"
10197 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10198 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10199 (clobber (reg:CC 17))]
10200 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10201 "#")
10202
10203 (define_split
10204 [(set (match_operand:TF 0 "fp_register_operand" "")
10205 (neg:TF (match_operand:TF 1 "register_operand" "")))
10206 (clobber (reg:CC 17))]
10207 "TARGET_80387 && reload_completed"
10208 [(set (match_dup 0)
10209 (neg:TF (match_dup 1)))]
10210 "")
10211
10212 (define_split
10213 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10214 (neg:TF (match_operand:TF 1 "register_operand" "")))
10215 (clobber (reg:CC 17))]
10216 "TARGET_80387 && reload_completed"
10217 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10218 (clobber (reg:CC 17))])]
10219 "operands[1] = GEN_INT (0x8000);
10220 operands[0] = gen_rtx_REG (SImode,
10221 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10222
10223 ;; Conditionalize these after reload. If they matches before reload, we
10224 ;; lose the clobber and ability to use integer instructions.
10225
10226 (define_insn "*negsf2_1"
10227 [(set (match_operand:SF 0 "register_operand" "=f")
10228 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10229 "TARGET_80387 && reload_completed"
10230 "fchs"
10231 [(set_attr "type" "fsgn")
10232 (set_attr "mode" "SF")
10233 (set_attr "ppro_uops" "few")])
10234
10235 (define_insn "*negdf2_1"
10236 [(set (match_operand:DF 0 "register_operand" "=f")
10237 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10238 "TARGET_80387 && reload_completed"
10239 "fchs"
10240 [(set_attr "type" "fsgn")
10241 (set_attr "mode" "DF")
10242 (set_attr "ppro_uops" "few")])
10243
10244 (define_insn "*negextendsfdf2"
10245 [(set (match_operand:DF 0 "register_operand" "=f")
10246 (neg:DF (float_extend:DF
10247 (match_operand:SF 1 "register_operand" "0"))))]
10248 "TARGET_80387"
10249 "fchs"
10250 [(set_attr "type" "fsgn")
10251 (set_attr "mode" "DF")
10252 (set_attr "ppro_uops" "few")])
10253
10254 (define_insn "*negxf2_1"
10255 [(set (match_operand:XF 0 "register_operand" "=f")
10256 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10257 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10258 "fchs"
10259 [(set_attr "type" "fsgn")
10260 (set_attr "mode" "XF")
10261 (set_attr "ppro_uops" "few")])
10262
10263 (define_insn "*negextenddfxf2"
10264 [(set (match_operand:XF 0 "register_operand" "=f")
10265 (neg:XF (float_extend:XF
10266 (match_operand:DF 1 "register_operand" "0"))))]
10267 "!TARGET_64BIT && TARGET_80387"
10268 "fchs"
10269 [(set_attr "type" "fsgn")
10270 (set_attr "mode" "XF")
10271 (set_attr "ppro_uops" "few")])
10272
10273 (define_insn "*negextendsfxf2"
10274 [(set (match_operand:XF 0 "register_operand" "=f")
10275 (neg:XF (float_extend:XF
10276 (match_operand:SF 1 "register_operand" "0"))))]
10277 "!TARGET_64BIT && TARGET_80387"
10278 "fchs"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "XF")
10281 (set_attr "ppro_uops" "few")])
10282
10283 (define_insn "*negtf2_1"
10284 [(set (match_operand:TF 0 "register_operand" "=f")
10285 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10286 "TARGET_80387 && reload_completed"
10287 "fchs"
10288 [(set_attr "type" "fsgn")
10289 (set_attr "mode" "XF")
10290 (set_attr "ppro_uops" "few")])
10291
10292 (define_insn "*negextenddftf2"
10293 [(set (match_operand:TF 0 "register_operand" "=f")
10294 (neg:TF (float_extend:TF
10295 (match_operand:DF 1 "register_operand" "0"))))]
10296 "TARGET_80387"
10297 "fchs"
10298 [(set_attr "type" "fsgn")
10299 (set_attr "mode" "XF")
10300 (set_attr "ppro_uops" "few")])
10301
10302 (define_insn "*negextendsftf2"
10303 [(set (match_operand:TF 0 "register_operand" "=f")
10304 (neg:TF (float_extend:TF
10305 (match_operand:SF 1 "register_operand" "0"))))]
10306 "TARGET_80387"
10307 "fchs"
10308 [(set_attr "type" "fsgn")
10309 (set_attr "mode" "XF")
10310 (set_attr "ppro_uops" "few")])
10311 \f
10312 ;; Absolute value instructions
10313
10314 (define_expand "abssf2"
10315 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10316 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10317 (clobber (reg:CC 17))])]
10318 "TARGET_80387"
10319 "if (TARGET_SSE)
10320 {
10321 /* In case operand is in memory, we will not use SSE. */
10322 if (memory_operand (operands[0], VOIDmode)
10323 && rtx_equal_p (operands[0], operands[1]))
10324 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10325 else
10326 {
10327 /* Using SSE is tricky, since we need bitwise negation of -0
10328 in register. */
10329 rtx reg = gen_reg_rtx (V4SFmode);
10330 rtx dest = operands[0];
10331 rtx imm;
10332
10333 operands[1] = force_reg (SFmode, operands[1]);
10334 operands[0] = force_reg (SFmode, operands[0]);
10335 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10336 reg = force_reg (V4SFmode,
10337 gen_rtx_CONST_VECTOR (V4SFmode,
10338 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10339 CONST0_RTX (SFmode),
10340 CONST0_RTX (SFmode))));
10341 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10342 if (dest != operands[0])
10343 emit_move_insn (dest, operands[0]);
10344 }
10345 DONE;
10346 }
10347 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10348
10349 (define_insn "abssf2_memory"
10350 [(set (match_operand:SF 0 "memory_operand" "=m")
10351 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10352 (clobber (reg:CC 17))]
10353 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10354 "#")
10355
10356 (define_insn "abssf2_ifs"
10357 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10358 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10359 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10360 (clobber (reg:CC 17))]
10361 "TARGET_SSE
10362 && (reload_in_progress || reload_completed
10363 || (register_operand (operands[0], VOIDmode)
10364 && register_operand (operands[1], VOIDmode)))"
10365 "#")
10366
10367 (define_split
10368 [(set (match_operand:SF 0 "memory_operand" "")
10369 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10370 (use (match_operand:V4SF 2 "" ""))
10371 (clobber (reg:CC 17))]
10372 ""
10373 [(parallel [(set (match_dup 0)
10374 (abs:SF (match_dup 1)))
10375 (clobber (reg:CC 17))])])
10376
10377 (define_split
10378 [(set (match_operand:SF 0 "register_operand" "")
10379 (abs:SF (match_operand:SF 1 "register_operand" "")))
10380 (use (match_operand:V4SF 2 "" ""))
10381 (clobber (reg:CC 17))]
10382 "reload_completed && !SSE_REG_P (operands[0])"
10383 [(parallel [(set (match_dup 0)
10384 (abs:SF (match_dup 1)))
10385 (clobber (reg:CC 17))])])
10386
10387 (define_split
10388 [(set (match_operand:SF 0 "register_operand" "")
10389 (abs:SF (match_operand:SF 1 "register_operand" "")))
10390 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10391 (clobber (reg:CC 17))]
10392 "reload_completed && SSE_REG_P (operands[0])"
10393 [(set (subreg:TI (match_dup 0) 0)
10394 (and:TI (match_dup 1)
10395 (match_dup 2)))]
10396 {
10397 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10398 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10399 if (operands_match_p (operands[0], operands[2]))
10400 {
10401 rtx tmp;
10402 tmp = operands[1];
10403 operands[1] = operands[2];
10404 operands[2] = tmp;
10405 }
10406 })
10407
10408 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10409 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10410 ;; to itself.
10411 (define_insn "*abssf2_if"
10412 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10413 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10414 (clobber (reg:CC 17))]
10415 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10416 "#")
10417
10418 (define_split
10419 [(set (match_operand:SF 0 "fp_register_operand" "")
10420 (abs:SF (match_operand:SF 1 "register_operand" "")))
10421 (clobber (reg:CC 17))]
10422 "TARGET_80387 && reload_completed"
10423 [(set (match_dup 0)
10424 (abs:SF (match_dup 1)))]
10425 "")
10426
10427 (define_split
10428 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10429 (abs:SF (match_operand:SF 1 "register_operand" "")))
10430 (clobber (reg:CC 17))]
10431 "TARGET_80387 && reload_completed"
10432 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10433 (clobber (reg:CC 17))])]
10434 "operands[1] = gen_int_mode (~0x80000000, SImode);
10435 operands[0] = gen_lowpart (SImode, operands[0]);")
10436
10437 (define_split
10438 [(set (match_operand 0 "memory_operand" "")
10439 (abs (match_operand 1 "memory_operand" "")))
10440 (clobber (reg:CC 17))]
10441 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10442 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10443 (clobber (reg:CC 17))])]
10444 {
10445 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10446
10447 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10448 if (size >= 12)
10449 size = 10;
10450 operands[0] = adjust_address (operands[0], QImode, size - 1);
10451 operands[1] = gen_int_mode (~0x80, QImode);
10452 })
10453
10454 (define_expand "absdf2"
10455 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10456 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10457 (clobber (reg:CC 17))])]
10458 "TARGET_80387"
10459 "if (TARGET_SSE2)
10460 {
10461 /* In case operand is in memory, we will not use SSE. */
10462 if (memory_operand (operands[0], VOIDmode)
10463 && rtx_equal_p (operands[0], operands[1]))
10464 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10465 else
10466 {
10467 /* Using SSE is tricky, since we need bitwise negation of -0
10468 in register. */
10469 rtx reg = gen_reg_rtx (V2DFmode);
10470 #if HOST_BITS_PER_WIDE_INT >= 64
10471 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10472 #else
10473 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10474 #endif
10475 rtx dest = operands[0];
10476
10477 operands[1] = force_reg (DFmode, operands[1]);
10478 operands[0] = force_reg (DFmode, operands[0]);
10479
10480 /* Produce LONG_DOUBLE with the proper immediate argument. */
10481 imm = gen_lowpart (DFmode, imm);
10482 reg = force_reg (V2DFmode,
10483 gen_rtx_CONST_VECTOR (V2DFmode,
10484 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10485 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10486 if (dest != operands[0])
10487 emit_move_insn (dest, operands[0]);
10488 }
10489 DONE;
10490 }
10491 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10492
10493 (define_insn "absdf2_memory"
10494 [(set (match_operand:DF 0 "memory_operand" "=m")
10495 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10496 (clobber (reg:CC 17))]
10497 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10498 "#")
10499
10500 (define_insn "absdf2_ifs"
10501 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10502 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10503 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10504 (clobber (reg:CC 17))]
10505 "!TARGET_64BIT && TARGET_SSE2
10506 && (reload_in_progress || reload_completed
10507 || (register_operand (operands[0], VOIDmode)
10508 && register_operand (operands[1], VOIDmode)))"
10509 "#")
10510
10511 (define_insn "*absdf2_ifs_rex64"
10512 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10513 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10514 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10515 (clobber (reg:CC 17))]
10516 "TARGET_64BIT && TARGET_SSE2
10517 && (reload_in_progress || reload_completed
10518 || (register_operand (operands[0], VOIDmode)
10519 && register_operand (operands[1], VOIDmode)))"
10520 "#")
10521
10522 (define_split
10523 [(set (match_operand:DF 0 "memory_operand" "")
10524 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10525 (use (match_operand:V2DF 2 "" ""))
10526 (clobber (reg:CC 17))]
10527 ""
10528 [(parallel [(set (match_dup 0)
10529 (abs:DF (match_dup 1)))
10530 (clobber (reg:CC 17))])])
10531
10532 (define_split
10533 [(set (match_operand:DF 0 "register_operand" "")
10534 (abs:DF (match_operand:DF 1 "register_operand" "")))
10535 (use (match_operand:V2DF 2 "" ""))
10536 (clobber (reg:CC 17))]
10537 "reload_completed && !SSE_REG_P (operands[0])"
10538 [(parallel [(set (match_dup 0)
10539 (abs:DF (match_dup 1)))
10540 (clobber (reg:CC 17))])])
10541
10542 (define_split
10543 [(set (match_operand:DF 0 "register_operand" "")
10544 (abs:DF (match_operand:DF 1 "register_operand" "")))
10545 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10546 (clobber (reg:CC 17))]
10547 "reload_completed && SSE_REG_P (operands[0])"
10548 [(set (subreg:TI (match_dup 0) 0)
10549 (and:TI (match_dup 1)
10550 (match_dup 2)))]
10551 {
10552 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10553 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10554 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10555 /* Avoid possible reformatting on the operands. */
10556 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10557 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10558 if (operands_match_p (operands[0], operands[2]))
10559 {
10560 rtx tmp;
10561 tmp = operands[1];
10562 operands[1] = operands[2];
10563 operands[2] = tmp;
10564 }
10565 })
10566
10567
10568 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10569 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10570 ;; to itself.
10571 (define_insn "*absdf2_if"
10572 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10573 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10574 (clobber (reg:CC 17))]
10575 "!TARGET_64BIT && TARGET_80387
10576 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10577 "#")
10578
10579 ;; FIXME: We should to allow integer registers here. Problem is that
10580 ;; we need another scratch register to get constant from.
10581 ;; Forcing constant to mem if no register available in peep2 should be
10582 ;; safe even for PIC mode, because of RIP relative addressing.
10583 (define_insn "*absdf2_if_rex64"
10584 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10585 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10586 (clobber (reg:CC 17))]
10587 "TARGET_64BIT && TARGET_80387
10588 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10589 "#")
10590
10591 (define_split
10592 [(set (match_operand:DF 0 "fp_register_operand" "")
10593 (abs:DF (match_operand:DF 1 "register_operand" "")))
10594 (clobber (reg:CC 17))]
10595 "TARGET_80387 && reload_completed"
10596 [(set (match_dup 0)
10597 (abs:DF (match_dup 1)))]
10598 "")
10599
10600 (define_split
10601 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10602 (abs:DF (match_operand:DF 1 "register_operand" "")))
10603 (clobber (reg:CC 17))]
10604 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10605 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10606 (clobber (reg:CC 17))])]
10607 "operands[4] = gen_int_mode (~0x80000000, SImode);
10608 split_di (operands+0, 1, operands+2, operands+3);")
10609
10610 (define_expand "absxf2"
10611 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10612 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10613 (clobber (reg:CC 17))])]
10614 "!TARGET_64BIT && TARGET_80387"
10615 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10616
10617 (define_expand "abstf2"
10618 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10619 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10620 (clobber (reg:CC 17))])]
10621 "TARGET_80387"
10622 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10623
10624 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10625 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10626 ;; to itself.
10627 (define_insn "*absxf2_if"
10628 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10629 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10630 (clobber (reg:CC 17))]
10631 "!TARGET_64BIT && TARGET_80387
10632 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10633 "#")
10634
10635 (define_split
10636 [(set (match_operand:XF 0 "fp_register_operand" "")
10637 (abs:XF (match_operand:XF 1 "register_operand" "")))
10638 (clobber (reg:CC 17))]
10639 "TARGET_80387 && reload_completed"
10640 [(set (match_dup 0)
10641 (abs:XF (match_dup 1)))]
10642 "")
10643
10644 (define_split
10645 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10646 (abs:XF (match_operand:XF 1 "register_operand" "")))
10647 (clobber (reg:CC 17))]
10648 "TARGET_80387 && reload_completed"
10649 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10650 (clobber (reg:CC 17))])]
10651 "operands[1] = GEN_INT (~0x8000);
10652 operands[0] = gen_rtx_REG (SImode,
10653 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10654
10655 (define_insn "*abstf2_if"
10656 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10657 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10658 (clobber (reg:CC 17))]
10659 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10660 "#")
10661
10662 (define_split
10663 [(set (match_operand:TF 0 "fp_register_operand" "")
10664 (abs:TF (match_operand:TF 1 "register_operand" "")))
10665 (clobber (reg:CC 17))]
10666 "TARGET_80387 && reload_completed"
10667 [(set (match_dup 0)
10668 (abs:TF (match_dup 1)))]
10669 "")
10670
10671 (define_split
10672 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10673 (abs:TF (match_operand:TF 1 "register_operand" "")))
10674 (clobber (reg:CC 17))]
10675 "TARGET_80387 && reload_completed"
10676 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10677 (clobber (reg:CC 17))])]
10678 "operands[1] = GEN_INT (~0x8000);
10679 operands[0] = gen_rtx_REG (SImode,
10680 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10681
10682 (define_insn "*abssf2_1"
10683 [(set (match_operand:SF 0 "register_operand" "=f")
10684 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10685 "TARGET_80387 && reload_completed"
10686 "fabs"
10687 [(set_attr "type" "fsgn")
10688 (set_attr "mode" "SF")])
10689
10690 (define_insn "*absdf2_1"
10691 [(set (match_operand:DF 0 "register_operand" "=f")
10692 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10693 "TARGET_80387 && reload_completed"
10694 "fabs"
10695 [(set_attr "type" "fsgn")
10696 (set_attr "mode" "DF")])
10697
10698 (define_insn "*absextendsfdf2"
10699 [(set (match_operand:DF 0 "register_operand" "=f")
10700 (abs:DF (float_extend:DF
10701 (match_operand:SF 1 "register_operand" "0"))))]
10702 "TARGET_80387"
10703 "fabs"
10704 [(set_attr "type" "fsgn")
10705 (set_attr "mode" "DF")])
10706
10707 (define_insn "*absxf2_1"
10708 [(set (match_operand:XF 0 "register_operand" "=f")
10709 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10710 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10711 "fabs"
10712 [(set_attr "type" "fsgn")
10713 (set_attr "mode" "DF")])
10714
10715 (define_insn "*absextenddfxf2"
10716 [(set (match_operand:XF 0 "register_operand" "=f")
10717 (abs:XF (float_extend:XF
10718 (match_operand:DF 1 "register_operand" "0"))))]
10719 "!TARGET_64BIT && TARGET_80387"
10720 "fabs"
10721 [(set_attr "type" "fsgn")
10722 (set_attr "mode" "XF")])
10723
10724 (define_insn "*absextendsfxf2"
10725 [(set (match_operand:XF 0 "register_operand" "=f")
10726 (abs:XF (float_extend:XF
10727 (match_operand:SF 1 "register_operand" "0"))))]
10728 "!TARGET_64BIT && TARGET_80387"
10729 "fabs"
10730 [(set_attr "type" "fsgn")
10731 (set_attr "mode" "XF")])
10732
10733 (define_insn "*abstf2_1"
10734 [(set (match_operand:TF 0 "register_operand" "=f")
10735 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10736 "TARGET_80387 && reload_completed"
10737 "fabs"
10738 [(set_attr "type" "fsgn")
10739 (set_attr "mode" "DF")])
10740
10741 (define_insn "*absextenddftf2"
10742 [(set (match_operand:TF 0 "register_operand" "=f")
10743 (abs:TF (float_extend:TF
10744 (match_operand:DF 1 "register_operand" "0"))))]
10745 "TARGET_80387"
10746 "fabs"
10747 [(set_attr "type" "fsgn")
10748 (set_attr "mode" "XF")])
10749
10750 (define_insn "*absextendsftf2"
10751 [(set (match_operand:TF 0 "register_operand" "=f")
10752 (abs:TF (float_extend:TF
10753 (match_operand:SF 1 "register_operand" "0"))))]
10754 "TARGET_80387"
10755 "fabs"
10756 [(set_attr "type" "fsgn")
10757 (set_attr "mode" "XF")])
10758 \f
10759 ;; One complement instructions
10760
10761 (define_expand "one_cmpldi2"
10762 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10763 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10764 "TARGET_64BIT"
10765 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10766
10767 (define_insn "*one_cmpldi2_1_rex64"
10768 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10769 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10770 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10771 "not{q}\t%0"
10772 [(set_attr "type" "negnot")
10773 (set_attr "mode" "DI")])
10774
10775 (define_insn "*one_cmpldi2_2_rex64"
10776 [(set (reg 17)
10777 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10778 (const_int 0)))
10779 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10780 (not:DI (match_dup 1)))]
10781 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10782 && ix86_unary_operator_ok (NOT, DImode, operands)"
10783 "#"
10784 [(set_attr "type" "alu1")
10785 (set_attr "mode" "DI")])
10786
10787 (define_split
10788 [(set (reg 17)
10789 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10790 (const_int 0)))
10791 (set (match_operand:DI 0 "nonimmediate_operand" "")
10792 (not:DI (match_dup 1)))]
10793 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10794 [(parallel [(set (reg:CCNO 17)
10795 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10796 (const_int 0)))
10797 (set (match_dup 0)
10798 (xor:DI (match_dup 1) (const_int -1)))])]
10799 "")
10800
10801 (define_expand "one_cmplsi2"
10802 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10803 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10804 ""
10805 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10806
10807 (define_insn "*one_cmplsi2_1"
10808 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10809 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10810 "ix86_unary_operator_ok (NOT, SImode, operands)"
10811 "not{l}\t%0"
10812 [(set_attr "type" "negnot")
10813 (set_attr "mode" "SI")])
10814
10815 ;; ??? Currently never generated - xor is used instead.
10816 (define_insn "*one_cmplsi2_1_zext"
10817 [(set (match_operand:DI 0 "register_operand" "=r")
10818 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10819 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10820 "not{l}\t%k0"
10821 [(set_attr "type" "negnot")
10822 (set_attr "mode" "SI")])
10823
10824 (define_insn "*one_cmplsi2_2"
10825 [(set (reg 17)
10826 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10827 (const_int 0)))
10828 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10829 (not:SI (match_dup 1)))]
10830 "ix86_match_ccmode (insn, CCNOmode)
10831 && ix86_unary_operator_ok (NOT, SImode, operands)"
10832 "#"
10833 [(set_attr "type" "alu1")
10834 (set_attr "mode" "SI")])
10835
10836 (define_split
10837 [(set (reg 17)
10838 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10839 (const_int 0)))
10840 (set (match_operand:SI 0 "nonimmediate_operand" "")
10841 (not:SI (match_dup 1)))]
10842 "ix86_match_ccmode (insn, CCNOmode)"
10843 [(parallel [(set (reg:CCNO 17)
10844 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10845 (const_int 0)))
10846 (set (match_dup 0)
10847 (xor:SI (match_dup 1) (const_int -1)))])]
10848 "")
10849
10850 ;; ??? Currently never generated - xor is used instead.
10851 (define_insn "*one_cmplsi2_2_zext"
10852 [(set (reg 17)
10853 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10854 (const_int 0)))
10855 (set (match_operand:DI 0 "register_operand" "=r")
10856 (zero_extend:DI (not:SI (match_dup 1))))]
10857 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10858 && ix86_unary_operator_ok (NOT, SImode, operands)"
10859 "#"
10860 [(set_attr "type" "alu1")
10861 (set_attr "mode" "SI")])
10862
10863 (define_split
10864 [(set (reg 17)
10865 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10866 (const_int 0)))
10867 (set (match_operand:DI 0 "register_operand" "")
10868 (zero_extend:DI (not:SI (match_dup 1))))]
10869 "ix86_match_ccmode (insn, CCNOmode)"
10870 [(parallel [(set (reg:CCNO 17)
10871 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10872 (const_int 0)))
10873 (set (match_dup 0)
10874 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10875 "")
10876
10877 (define_expand "one_cmplhi2"
10878 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10879 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10880 "TARGET_HIMODE_MATH"
10881 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10882
10883 (define_insn "*one_cmplhi2_1"
10884 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10885 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10886 "ix86_unary_operator_ok (NOT, HImode, operands)"
10887 "not{w}\t%0"
10888 [(set_attr "type" "negnot")
10889 (set_attr "mode" "HI")])
10890
10891 (define_insn "*one_cmplhi2_2"
10892 [(set (reg 17)
10893 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10894 (const_int 0)))
10895 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10896 (not:HI (match_dup 1)))]
10897 "ix86_match_ccmode (insn, CCNOmode)
10898 && ix86_unary_operator_ok (NEG, HImode, operands)"
10899 "#"
10900 [(set_attr "type" "alu1")
10901 (set_attr "mode" "HI")])
10902
10903 (define_split
10904 [(set (reg 17)
10905 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10906 (const_int 0)))
10907 (set (match_operand:HI 0 "nonimmediate_operand" "")
10908 (not:HI (match_dup 1)))]
10909 "ix86_match_ccmode (insn, CCNOmode)"
10910 [(parallel [(set (reg:CCNO 17)
10911 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10912 (const_int 0)))
10913 (set (match_dup 0)
10914 (xor:HI (match_dup 1) (const_int -1)))])]
10915 "")
10916
10917 ;; %%% Potential partial reg stall on alternative 1. What to do?
10918 (define_expand "one_cmplqi2"
10919 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10920 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10921 "TARGET_QIMODE_MATH"
10922 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10923
10924 (define_insn "*one_cmplqi2_1"
10925 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10926 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10927 "ix86_unary_operator_ok (NOT, QImode, operands)"
10928 "@
10929 not{b}\t%0
10930 not{l}\t%k0"
10931 [(set_attr "type" "negnot")
10932 (set_attr "mode" "QI,SI")])
10933
10934 (define_insn "*one_cmplqi2_2"
10935 [(set (reg 17)
10936 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10937 (const_int 0)))
10938 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10939 (not:QI (match_dup 1)))]
10940 "ix86_match_ccmode (insn, CCNOmode)
10941 && ix86_unary_operator_ok (NOT, QImode, operands)"
10942 "#"
10943 [(set_attr "type" "alu1")
10944 (set_attr "mode" "QI")])
10945
10946 (define_split
10947 [(set (reg 17)
10948 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10949 (const_int 0)))
10950 (set (match_operand:QI 0 "nonimmediate_operand" "")
10951 (not:QI (match_dup 1)))]
10952 "ix86_match_ccmode (insn, CCNOmode)"
10953 [(parallel [(set (reg:CCNO 17)
10954 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10955 (const_int 0)))
10956 (set (match_dup 0)
10957 (xor:QI (match_dup 1) (const_int -1)))])]
10958 "")
10959 \f
10960 ;; Arithmetic shift instructions
10961
10962 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10963 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10964 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10965 ;; from the assembler input.
10966 ;;
10967 ;; This instruction shifts the target reg/mem as usual, but instead of
10968 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10969 ;; is a left shift double, bits are taken from the high order bits of
10970 ;; reg, else if the insn is a shift right double, bits are taken from the
10971 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10972 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10973 ;;
10974 ;; Since sh[lr]d does not change the `reg' operand, that is done
10975 ;; separately, making all shifts emit pairs of shift double and normal
10976 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10977 ;; support a 63 bit shift, each shift where the count is in a reg expands
10978 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10979 ;;
10980 ;; If the shift count is a constant, we need never emit more than one
10981 ;; shift pair, instead using moves and sign extension for counts greater
10982 ;; than 31.
10983
10984 (define_expand "ashldi3"
10985 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10986 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10987 (match_operand:QI 2 "nonmemory_operand" "")))
10988 (clobber (reg:CC 17))])]
10989 ""
10990 {
10991 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10992 {
10993 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10994 DONE;
10995 }
10996 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10997 DONE;
10998 })
10999
11000 (define_insn "*ashldi3_1_rex64"
11001 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11002 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
11003 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11004 (clobber (reg:CC 17))]
11005 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11006 {
11007 switch (get_attr_type (insn))
11008 {
11009 case TYPE_ALU:
11010 if (operands[2] != const1_rtx)
11011 abort ();
11012 if (!rtx_equal_p (operands[0], operands[1]))
11013 abort ();
11014 return "add{q}\t{%0, %0|%0, %0}";
11015
11016 case TYPE_LEA:
11017 if (GET_CODE (operands[2]) != CONST_INT
11018 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11019 abort ();
11020 operands[1] = gen_rtx_MULT (DImode, operands[1],
11021 GEN_INT (1 << INTVAL (operands[2])));
11022 return "lea{q}\t{%a1, %0|%0, %a1}";
11023
11024 default:
11025 if (REG_P (operands[2]))
11026 return "sal{q}\t{%b2, %0|%0, %b2}";
11027 else if (GET_CODE (operands[2]) == CONST_INT
11028 && INTVAL (operands[2]) == 1
11029 && (TARGET_SHIFT1 || optimize_size))
11030 return "sal{q}\t%0";
11031 else
11032 return "sal{q}\t{%2, %0|%0, %2}";
11033 }
11034 }
11035 [(set (attr "type")
11036 (cond [(eq_attr "alternative" "1")
11037 (const_string "lea")
11038 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11039 (const_int 0))
11040 (match_operand 0 "register_operand" ""))
11041 (match_operand 2 "const1_operand" ""))
11042 (const_string "alu")
11043 ]
11044 (const_string "ishift")))
11045 (set_attr "mode" "DI")])
11046
11047 ;; Convert lea to the lea pattern to avoid flags dependency.
11048 (define_split
11049 [(set (match_operand:DI 0 "register_operand" "")
11050 (ashift:DI (match_operand:DI 1 "register_operand" "")
11051 (match_operand:QI 2 "immediate_operand" "")))
11052 (clobber (reg:CC 17))]
11053 "TARGET_64BIT && reload_completed
11054 && true_regnum (operands[0]) != true_regnum (operands[1])"
11055 [(set (match_dup 0)
11056 (mult:DI (match_dup 1)
11057 (match_dup 2)))]
11058 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11059
11060 ;; This pattern can't accept a variable shift count, since shifts by
11061 ;; zero don't affect the flags. We assume that shifts by constant
11062 ;; zero are optimized away.
11063 (define_insn "*ashldi3_cmp_rex64"
11064 [(set (reg 17)
11065 (compare
11066 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11067 (match_operand:QI 2 "immediate_operand" "e"))
11068 (const_int 0)))
11069 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11070 (ashift:DI (match_dup 1) (match_dup 2)))]
11071 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11072 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11073 {
11074 switch (get_attr_type (insn))
11075 {
11076 case TYPE_ALU:
11077 if (operands[2] != const1_rtx)
11078 abort ();
11079 return "add{q}\t{%0, %0|%0, %0}";
11080
11081 default:
11082 if (REG_P (operands[2]))
11083 return "sal{q}\t{%b2, %0|%0, %b2}";
11084 else if (GET_CODE (operands[2]) == CONST_INT
11085 && INTVAL (operands[2]) == 1
11086 && (TARGET_SHIFT1 || optimize_size))
11087 return "sal{q}\t%0";
11088 else
11089 return "sal{q}\t{%2, %0|%0, %2}";
11090 }
11091 }
11092 [(set (attr "type")
11093 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11094 (const_int 0))
11095 (match_operand 0 "register_operand" ""))
11096 (match_operand 2 "const1_operand" ""))
11097 (const_string "alu")
11098 ]
11099 (const_string "ishift")))
11100 (set_attr "mode" "DI")])
11101
11102 (define_insn "ashldi3_1"
11103 [(set (match_operand:DI 0 "register_operand" "=r")
11104 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11105 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11106 (clobber (match_scratch:SI 3 "=&r"))
11107 (clobber (reg:CC 17))]
11108 "!TARGET_64BIT && TARGET_CMOVE"
11109 "#"
11110 [(set_attr "type" "multi")])
11111
11112 (define_insn "*ashldi3_2"
11113 [(set (match_operand:DI 0 "register_operand" "=r")
11114 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11115 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11116 (clobber (reg:CC 17))]
11117 "!TARGET_64BIT"
11118 "#"
11119 [(set_attr "type" "multi")])
11120
11121 (define_split
11122 [(set (match_operand:DI 0 "register_operand" "")
11123 (ashift:DI (match_operand:DI 1 "register_operand" "")
11124 (match_operand:QI 2 "nonmemory_operand" "")))
11125 (clobber (match_scratch:SI 3 ""))
11126 (clobber (reg:CC 17))]
11127 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11128 [(const_int 0)]
11129 "ix86_split_ashldi (operands, operands[3]); DONE;")
11130
11131 (define_split
11132 [(set (match_operand:DI 0 "register_operand" "")
11133 (ashift:DI (match_operand:DI 1 "register_operand" "")
11134 (match_operand:QI 2 "nonmemory_operand" "")))
11135 (clobber (reg:CC 17))]
11136 "!TARGET_64BIT && reload_completed"
11137 [(const_int 0)]
11138 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11139
11140 (define_insn "x86_shld_1"
11141 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11142 (ior:SI (ashift:SI (match_dup 0)
11143 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11144 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11145 (minus:QI (const_int 32) (match_dup 2)))))
11146 (clobber (reg:CC 17))]
11147 ""
11148 "@
11149 shld{l}\t{%2, %1, %0|%0, %1, %2}
11150 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11151 [(set_attr "type" "ishift")
11152 (set_attr "prefix_0f" "1")
11153 (set_attr "mode" "SI")
11154 (set_attr "pent_pair" "np")
11155 (set_attr "athlon_decode" "vector")
11156 (set_attr "ppro_uops" "few")])
11157
11158 (define_expand "x86_shift_adj_1"
11159 [(set (reg:CCZ 17)
11160 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11161 (const_int 32))
11162 (const_int 0)))
11163 (set (match_operand:SI 0 "register_operand" "")
11164 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11165 (match_operand:SI 1 "register_operand" "")
11166 (match_dup 0)))
11167 (set (match_dup 1)
11168 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11169 (match_operand:SI 3 "register_operand" "r")
11170 (match_dup 1)))]
11171 "TARGET_CMOVE"
11172 "")
11173
11174 (define_expand "x86_shift_adj_2"
11175 [(use (match_operand:SI 0 "register_operand" ""))
11176 (use (match_operand:SI 1 "register_operand" ""))
11177 (use (match_operand:QI 2 "register_operand" ""))]
11178 ""
11179 {
11180 rtx label = gen_label_rtx ();
11181 rtx tmp;
11182
11183 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11184
11185 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11186 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11187 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11188 gen_rtx_LABEL_REF (VOIDmode, label),
11189 pc_rtx);
11190 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11191 JUMP_LABEL (tmp) = label;
11192
11193 emit_move_insn (operands[0], operands[1]);
11194 emit_move_insn (operands[1], const0_rtx);
11195
11196 emit_label (label);
11197 LABEL_NUSES (label) = 1;
11198
11199 DONE;
11200 })
11201
11202 (define_expand "ashlsi3"
11203 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11204 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11205 (match_operand:QI 2 "nonmemory_operand" "")))
11206 (clobber (reg:CC 17))]
11207 ""
11208 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11209
11210 (define_insn "*ashlsi3_1"
11211 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11212 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11213 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11214 (clobber (reg:CC 17))]
11215 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11216 {
11217 switch (get_attr_type (insn))
11218 {
11219 case TYPE_ALU:
11220 if (operands[2] != const1_rtx)
11221 abort ();
11222 if (!rtx_equal_p (operands[0], operands[1]))
11223 abort ();
11224 return "add{l}\t{%0, %0|%0, %0}";
11225
11226 case TYPE_LEA:
11227 return "#";
11228
11229 default:
11230 if (REG_P (operands[2]))
11231 return "sal{l}\t{%b2, %0|%0, %b2}";
11232 else if (GET_CODE (operands[2]) == CONST_INT
11233 && INTVAL (operands[2]) == 1
11234 && (TARGET_SHIFT1 || optimize_size))
11235 return "sal{l}\t%0";
11236 else
11237 return "sal{l}\t{%2, %0|%0, %2}";
11238 }
11239 }
11240 [(set (attr "type")
11241 (cond [(eq_attr "alternative" "1")
11242 (const_string "lea")
11243 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11244 (const_int 0))
11245 (match_operand 0 "register_operand" ""))
11246 (match_operand 2 "const1_operand" ""))
11247 (const_string "alu")
11248 ]
11249 (const_string "ishift")))
11250 (set_attr "mode" "SI")])
11251
11252 ;; Convert lea to the lea pattern to avoid flags dependency.
11253 (define_split
11254 [(set (match_operand 0 "register_operand" "")
11255 (ashift (match_operand 1 "index_register_operand" "")
11256 (match_operand:QI 2 "const_int_operand" "")))
11257 (clobber (reg:CC 17))]
11258 "reload_completed
11259 && true_regnum (operands[0]) != true_regnum (operands[1])"
11260 [(const_int 0)]
11261 {
11262 rtx pat;
11263 operands[0] = gen_lowpart (SImode, operands[0]);
11264 operands[1] = gen_lowpart (Pmode, operands[1]);
11265 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11266 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11267 if (Pmode != SImode)
11268 pat = gen_rtx_SUBREG (SImode, pat, 0);
11269 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11270 DONE;
11271 })
11272
11273 ;; Rare case of shifting RSP is handled by generating move and shift
11274 (define_split
11275 [(set (match_operand 0 "register_operand" "")
11276 (ashift (match_operand 1 "register_operand" "")
11277 (match_operand:QI 2 "const_int_operand" "")))
11278 (clobber (reg:CC 17))]
11279 "reload_completed
11280 && true_regnum (operands[0]) != true_regnum (operands[1])"
11281 [(const_int 0)]
11282 {
11283 rtx pat, clob;
11284 emit_move_insn (operands[1], operands[0]);
11285 pat = gen_rtx_SET (VOIDmode, operands[0],
11286 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11287 operands[0], operands[2]));
11288 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11289 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11290 DONE;
11291 })
11292
11293 (define_insn "*ashlsi3_1_zext"
11294 [(set (match_operand:DI 0 "register_operand" "=r,r")
11295 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11296 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11297 (clobber (reg:CC 17))]
11298 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11299 {
11300 switch (get_attr_type (insn))
11301 {
11302 case TYPE_ALU:
11303 if (operands[2] != const1_rtx)
11304 abort ();
11305 return "add{l}\t{%k0, %k0|%k0, %k0}";
11306
11307 case TYPE_LEA:
11308 return "#";
11309
11310 default:
11311 if (REG_P (operands[2]))
11312 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11313 else if (GET_CODE (operands[2]) == CONST_INT
11314 && INTVAL (operands[2]) == 1
11315 && (TARGET_SHIFT1 || optimize_size))
11316 return "sal{l}\t%k0";
11317 else
11318 return "sal{l}\t{%2, %k0|%k0, %2}";
11319 }
11320 }
11321 [(set (attr "type")
11322 (cond [(eq_attr "alternative" "1")
11323 (const_string "lea")
11324 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11325 (const_int 0))
11326 (match_operand 2 "const1_operand" ""))
11327 (const_string "alu")
11328 ]
11329 (const_string "ishift")))
11330 (set_attr "mode" "SI")])
11331
11332 ;; Convert lea to the lea pattern to avoid flags dependency.
11333 (define_split
11334 [(set (match_operand:DI 0 "register_operand" "")
11335 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11336 (match_operand:QI 2 "const_int_operand" ""))))
11337 (clobber (reg:CC 17))]
11338 "TARGET_64BIT && reload_completed
11339 && true_regnum (operands[0]) != true_regnum (operands[1])"
11340 [(set (match_dup 0) (zero_extend:DI
11341 (subreg:SI (mult:SI (match_dup 1)
11342 (match_dup 2)) 0)))]
11343 {
11344 operands[1] = gen_lowpart (Pmode, operands[1]);
11345 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11346 })
11347
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags. We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashlsi3_cmp"
11352 [(set (reg 17)
11353 (compare
11354 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11355 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11356 (const_int 0)))
11357 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11358 (ashift:SI (match_dup 1) (match_dup 2)))]
11359 "ix86_match_ccmode (insn, CCGOCmode)
11360 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11361 {
11362 switch (get_attr_type (insn))
11363 {
11364 case TYPE_ALU:
11365 if (operands[2] != const1_rtx)
11366 abort ();
11367 return "add{l}\t{%0, %0|%0, %0}";
11368
11369 default:
11370 if (REG_P (operands[2]))
11371 return "sal{l}\t{%b2, %0|%0, %b2}";
11372 else if (GET_CODE (operands[2]) == CONST_INT
11373 && INTVAL (operands[2]) == 1
11374 && (TARGET_SHIFT1 || optimize_size))
11375 return "sal{l}\t%0";
11376 else
11377 return "sal{l}\t{%2, %0|%0, %2}";
11378 }
11379 }
11380 [(set (attr "type")
11381 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11382 (const_int 0))
11383 (match_operand 0 "register_operand" ""))
11384 (match_operand 2 "const1_operand" ""))
11385 (const_string "alu")
11386 ]
11387 (const_string "ishift")))
11388 (set_attr "mode" "SI")])
11389
11390 (define_insn "*ashlsi3_cmp_zext"
11391 [(set (reg 17)
11392 (compare
11393 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11394 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11395 (const_int 0)))
11396 (set (match_operand:DI 0 "register_operand" "=r")
11397 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11399 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11400 {
11401 switch (get_attr_type (insn))
11402 {
11403 case TYPE_ALU:
11404 if (operands[2] != const1_rtx)
11405 abort ();
11406 return "add{l}\t{%k0, %k0|%k0, %k0}";
11407
11408 default:
11409 if (REG_P (operands[2]))
11410 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11411 else if (GET_CODE (operands[2]) == CONST_INT
11412 && INTVAL (operands[2]) == 1
11413 && (TARGET_SHIFT1 || optimize_size))
11414 return "sal{l}\t%k0";
11415 else
11416 return "sal{l}\t{%2, %k0|%k0, %2}";
11417 }
11418 }
11419 [(set (attr "type")
11420 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11421 (const_int 0))
11422 (match_operand 2 "const1_operand" ""))
11423 (const_string "alu")
11424 ]
11425 (const_string "ishift")))
11426 (set_attr "mode" "SI")])
11427
11428 (define_expand "ashlhi3"
11429 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11430 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11431 (match_operand:QI 2 "nonmemory_operand" "")))
11432 (clobber (reg:CC 17))]
11433 "TARGET_HIMODE_MATH"
11434 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11435
11436 (define_insn "*ashlhi3_1_lea"
11437 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11438 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11439 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11440 (clobber (reg:CC 17))]
11441 "!TARGET_PARTIAL_REG_STALL
11442 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11443 {
11444 switch (get_attr_type (insn))
11445 {
11446 case TYPE_LEA:
11447 return "#";
11448 case TYPE_ALU:
11449 if (operands[2] != const1_rtx)
11450 abort ();
11451 return "add{w}\t{%0, %0|%0, %0}";
11452
11453 default:
11454 if (REG_P (operands[2]))
11455 return "sal{w}\t{%b2, %0|%0, %b2}";
11456 else if (GET_CODE (operands[2]) == CONST_INT
11457 && INTVAL (operands[2]) == 1
11458 && (TARGET_SHIFT1 || optimize_size))
11459 return "sal{w}\t%0";
11460 else
11461 return "sal{w}\t{%2, %0|%0, %2}";
11462 }
11463 }
11464 [(set (attr "type")
11465 (cond [(eq_attr "alternative" "1")
11466 (const_string "lea")
11467 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11468 (const_int 0))
11469 (match_operand 0 "register_operand" ""))
11470 (match_operand 2 "const1_operand" ""))
11471 (const_string "alu")
11472 ]
11473 (const_string "ishift")))
11474 (set_attr "mode" "HI,SI")])
11475
11476 (define_insn "*ashlhi3_1"
11477 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11478 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11479 (match_operand:QI 2 "nonmemory_operand" "cI")))
11480 (clobber (reg:CC 17))]
11481 "TARGET_PARTIAL_REG_STALL
11482 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11483 {
11484 switch (get_attr_type (insn))
11485 {
11486 case TYPE_ALU:
11487 if (operands[2] != const1_rtx)
11488 abort ();
11489 return "add{w}\t{%0, %0|%0, %0}";
11490
11491 default:
11492 if (REG_P (operands[2]))
11493 return "sal{w}\t{%b2, %0|%0, %b2}";
11494 else if (GET_CODE (operands[2]) == CONST_INT
11495 && INTVAL (operands[2]) == 1
11496 && (TARGET_SHIFT1 || optimize_size))
11497 return "sal{w}\t%0";
11498 else
11499 return "sal{w}\t{%2, %0|%0, %2}";
11500 }
11501 }
11502 [(set (attr "type")
11503 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11504 (const_int 0))
11505 (match_operand 0 "register_operand" ""))
11506 (match_operand 2 "const1_operand" ""))
11507 (const_string "alu")
11508 ]
11509 (const_string "ishift")))
11510 (set_attr "mode" "HI")])
11511
11512 ;; This pattern can't accept a variable shift count, since shifts by
11513 ;; zero don't affect the flags. We assume that shifts by constant
11514 ;; zero are optimized away.
11515 (define_insn "*ashlhi3_cmp"
11516 [(set (reg 17)
11517 (compare
11518 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11519 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11520 (const_int 0)))
11521 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11522 (ashift:HI (match_dup 1) (match_dup 2)))]
11523 "ix86_match_ccmode (insn, CCGOCmode)
11524 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11525 {
11526 switch (get_attr_type (insn))
11527 {
11528 case TYPE_ALU:
11529 if (operands[2] != const1_rtx)
11530 abort ();
11531 return "add{w}\t{%0, %0|%0, %0}";
11532
11533 default:
11534 if (REG_P (operands[2]))
11535 return "sal{w}\t{%b2, %0|%0, %b2}";
11536 else if (GET_CODE (operands[2]) == CONST_INT
11537 && INTVAL (operands[2]) == 1
11538 && (TARGET_SHIFT1 || optimize_size))
11539 return "sal{w}\t%0";
11540 else
11541 return "sal{w}\t{%2, %0|%0, %2}";
11542 }
11543 }
11544 [(set (attr "type")
11545 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11546 (const_int 0))
11547 (match_operand 0 "register_operand" ""))
11548 (match_operand 2 "const1_operand" ""))
11549 (const_string "alu")
11550 ]
11551 (const_string "ishift")))
11552 (set_attr "mode" "HI")])
11553
11554 (define_expand "ashlqi3"
11555 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11556 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11557 (match_operand:QI 2 "nonmemory_operand" "")))
11558 (clobber (reg:CC 17))]
11559 "TARGET_QIMODE_MATH"
11560 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11561
11562 ;; %%% Potential partial reg stall on alternative 2. What to do?
11563
11564 (define_insn "*ashlqi3_1_lea"
11565 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11566 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11567 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11568 (clobber (reg:CC 17))]
11569 "!TARGET_PARTIAL_REG_STALL
11570 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11571 {
11572 switch (get_attr_type (insn))
11573 {
11574 case TYPE_LEA:
11575 return "#";
11576 case TYPE_ALU:
11577 if (operands[2] != const1_rtx)
11578 abort ();
11579 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11580 return "add{l}\t{%k0, %k0|%k0, %k0}";
11581 else
11582 return "add{b}\t{%0, %0|%0, %0}";
11583
11584 default:
11585 if (REG_P (operands[2]))
11586 {
11587 if (get_attr_mode (insn) == MODE_SI)
11588 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11589 else
11590 return "sal{b}\t{%b2, %0|%0, %b2}";
11591 }
11592 else if (GET_CODE (operands[2]) == CONST_INT
11593 && INTVAL (operands[2]) == 1
11594 && (TARGET_SHIFT1 || optimize_size))
11595 {
11596 if (get_attr_mode (insn) == MODE_SI)
11597 return "sal{l}\t%0";
11598 else
11599 return "sal{b}\t%0";
11600 }
11601 else
11602 {
11603 if (get_attr_mode (insn) == MODE_SI)
11604 return "sal{l}\t{%2, %k0|%k0, %2}";
11605 else
11606 return "sal{b}\t{%2, %0|%0, %2}";
11607 }
11608 }
11609 }
11610 [(set (attr "type")
11611 (cond [(eq_attr "alternative" "2")
11612 (const_string "lea")
11613 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11614 (const_int 0))
11615 (match_operand 0 "register_operand" ""))
11616 (match_operand 2 "const1_operand" ""))
11617 (const_string "alu")
11618 ]
11619 (const_string "ishift")))
11620 (set_attr "mode" "QI,SI,SI")])
11621
11622 (define_insn "*ashlqi3_1"
11623 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11624 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11625 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11626 (clobber (reg:CC 17))]
11627 "TARGET_PARTIAL_REG_STALL
11628 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11629 {
11630 switch (get_attr_type (insn))
11631 {
11632 case TYPE_ALU:
11633 if (operands[2] != const1_rtx)
11634 abort ();
11635 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11636 return "add{l}\t{%k0, %k0|%k0, %k0}";
11637 else
11638 return "add{b}\t{%0, %0|%0, %0}";
11639
11640 default:
11641 if (REG_P (operands[2]))
11642 {
11643 if (get_attr_mode (insn) == MODE_SI)
11644 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11645 else
11646 return "sal{b}\t{%b2, %0|%0, %b2}";
11647 }
11648 else if (GET_CODE (operands[2]) == CONST_INT
11649 && INTVAL (operands[2]) == 1
11650 && (TARGET_SHIFT1 || optimize_size))
11651 {
11652 if (get_attr_mode (insn) == MODE_SI)
11653 return "sal{l}\t%0";
11654 else
11655 return "sal{b}\t%0";
11656 }
11657 else
11658 {
11659 if (get_attr_mode (insn) == MODE_SI)
11660 return "sal{l}\t{%2, %k0|%k0, %2}";
11661 else
11662 return "sal{b}\t{%2, %0|%0, %2}";
11663 }
11664 }
11665 }
11666 [(set (attr "type")
11667 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11668 (const_int 0))
11669 (match_operand 0 "register_operand" ""))
11670 (match_operand 2 "const1_operand" ""))
11671 (const_string "alu")
11672 ]
11673 (const_string "ishift")))
11674 (set_attr "mode" "QI,SI")])
11675
11676 ;; This pattern can't accept a variable shift count, since shifts by
11677 ;; zero don't affect the flags. We assume that shifts by constant
11678 ;; zero are optimized away.
11679 (define_insn "*ashlqi3_cmp"
11680 [(set (reg 17)
11681 (compare
11682 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11683 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11684 (const_int 0)))
11685 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11686 (ashift:QI (match_dup 1) (match_dup 2)))]
11687 "ix86_match_ccmode (insn, CCGOCmode)
11688 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11689 {
11690 switch (get_attr_type (insn))
11691 {
11692 case TYPE_ALU:
11693 if (operands[2] != const1_rtx)
11694 abort ();
11695 return "add{b}\t{%0, %0|%0, %0}";
11696
11697 default:
11698 if (REG_P (operands[2]))
11699 return "sal{b}\t{%b2, %0|%0, %b2}";
11700 else if (GET_CODE (operands[2]) == CONST_INT
11701 && INTVAL (operands[2]) == 1
11702 && (TARGET_SHIFT1 || optimize_size))
11703 return "sal{b}\t%0";
11704 else
11705 return "sal{b}\t{%2, %0|%0, %2}";
11706 }
11707 }
11708 [(set (attr "type")
11709 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11710 (const_int 0))
11711 (match_operand 0 "register_operand" ""))
11712 (match_operand 2 "const1_operand" ""))
11713 (const_string "alu")
11714 ]
11715 (const_string "ishift")))
11716 (set_attr "mode" "QI")])
11717
11718 ;; See comment above `ashldi3' about how this works.
11719
11720 (define_expand "ashrdi3"
11721 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11722 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11723 (match_operand:QI 2 "nonmemory_operand" "")))
11724 (clobber (reg:CC 17))])]
11725 ""
11726 {
11727 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11728 {
11729 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11730 DONE;
11731 }
11732 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11733 DONE;
11734 })
11735
11736 (define_insn "ashrdi3_63_rex64"
11737 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11738 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11739 (match_operand:DI 2 "const_int_operand" "i,i")))
11740 (clobber (reg:CC 17))]
11741 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11742 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11743 "@
11744 {cqto|cqo}
11745 sar{q}\t{%2, %0|%0, %2}"
11746 [(set_attr "type" "imovx,ishift")
11747 (set_attr "prefix_0f" "0,*")
11748 (set_attr "length_immediate" "0,*")
11749 (set_attr "modrm" "0,1")
11750 (set_attr "mode" "DI")])
11751
11752 (define_insn "*ashrdi3_1_one_bit_rex64"
11753 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11754 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11755 (match_operand:QI 2 "const_int_1_operand" "")))
11756 (clobber (reg:CC 17))]
11757 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11758 && (TARGET_SHIFT1 || optimize_size)"
11759 "sar{q}\t%0"
11760 [(set_attr "type" "ishift")
11761 (set (attr "length")
11762 (if_then_else (match_operand:DI 0 "register_operand" "")
11763 (const_string "2")
11764 (const_string "*")))])
11765
11766 (define_insn "*ashrdi3_1_rex64"
11767 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11768 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11769 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11770 (clobber (reg:CC 17))]
11771 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11772 "@
11773 sar{q}\t{%2, %0|%0, %2}
11774 sar{q}\t{%b2, %0|%0, %b2}"
11775 [(set_attr "type" "ishift")
11776 (set_attr "mode" "DI")])
11777
11778 ;; This pattern can't accept a variable shift count, since shifts by
11779 ;; zero don't affect the flags. We assume that shifts by constant
11780 ;; zero are optimized away.
11781 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11782 [(set (reg 17)
11783 (compare
11784 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11785 (match_operand:QI 2 "const_int_1_operand" ""))
11786 (const_int 0)))
11787 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11788 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11789 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11790 && (TARGET_SHIFT1 || optimize_size)
11791 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11792 "sar{q}\t%0"
11793 [(set_attr "type" "ishift")
11794 (set (attr "length")
11795 (if_then_else (match_operand:DI 0 "register_operand" "")
11796 (const_string "2")
11797 (const_string "*")))])
11798
11799 ;; This pattern can't accept a variable shift count, since shifts by
11800 ;; zero don't affect the flags. We assume that shifts by constant
11801 ;; zero are optimized away.
11802 (define_insn "*ashrdi3_cmp_rex64"
11803 [(set (reg 17)
11804 (compare
11805 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11806 (match_operand:QI 2 "const_int_operand" "n"))
11807 (const_int 0)))
11808 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11809 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11810 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11811 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11812 "sar{q}\t{%2, %0|%0, %2}"
11813 [(set_attr "type" "ishift")
11814 (set_attr "mode" "DI")])
11815
11816
11817 (define_insn "ashrdi3_1"
11818 [(set (match_operand:DI 0 "register_operand" "=r")
11819 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11820 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11821 (clobber (match_scratch:SI 3 "=&r"))
11822 (clobber (reg:CC 17))]
11823 "!TARGET_64BIT && TARGET_CMOVE"
11824 "#"
11825 [(set_attr "type" "multi")])
11826
11827 (define_insn "*ashrdi3_2"
11828 [(set (match_operand:DI 0 "register_operand" "=r")
11829 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11830 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11831 (clobber (reg:CC 17))]
11832 "!TARGET_64BIT"
11833 "#"
11834 [(set_attr "type" "multi")])
11835
11836 (define_split
11837 [(set (match_operand:DI 0 "register_operand" "")
11838 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11839 (match_operand:QI 2 "nonmemory_operand" "")))
11840 (clobber (match_scratch:SI 3 ""))
11841 (clobber (reg:CC 17))]
11842 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11843 [(const_int 0)]
11844 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11845
11846 (define_split
11847 [(set (match_operand:DI 0 "register_operand" "")
11848 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11849 (match_operand:QI 2 "nonmemory_operand" "")))
11850 (clobber (reg:CC 17))]
11851 "!TARGET_64BIT && reload_completed"
11852 [(const_int 0)]
11853 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11854
11855 (define_insn "x86_shrd_1"
11856 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11857 (ior:SI (ashiftrt:SI (match_dup 0)
11858 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11859 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11860 (minus:QI (const_int 32) (match_dup 2)))))
11861 (clobber (reg:CC 17))]
11862 ""
11863 "@
11864 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11865 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11866 [(set_attr "type" "ishift")
11867 (set_attr "prefix_0f" "1")
11868 (set_attr "pent_pair" "np")
11869 (set_attr "ppro_uops" "few")
11870 (set_attr "mode" "SI")])
11871
11872 (define_expand "x86_shift_adj_3"
11873 [(use (match_operand:SI 0 "register_operand" ""))
11874 (use (match_operand:SI 1 "register_operand" ""))
11875 (use (match_operand:QI 2 "register_operand" ""))]
11876 ""
11877 {
11878 rtx label = gen_label_rtx ();
11879 rtx tmp;
11880
11881 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11882
11883 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11884 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11885 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11886 gen_rtx_LABEL_REF (VOIDmode, label),
11887 pc_rtx);
11888 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11889 JUMP_LABEL (tmp) = label;
11890
11891 emit_move_insn (operands[0], operands[1]);
11892 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11893
11894 emit_label (label);
11895 LABEL_NUSES (label) = 1;
11896
11897 DONE;
11898 })
11899
11900 (define_insn "ashrsi3_31"
11901 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11902 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11903 (match_operand:SI 2 "const_int_operand" "i,i")))
11904 (clobber (reg:CC 17))]
11905 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11906 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11907 "@
11908 {cltd|cdq}
11909 sar{l}\t{%2, %0|%0, %2}"
11910 [(set_attr "type" "imovx,ishift")
11911 (set_attr "prefix_0f" "0,*")
11912 (set_attr "length_immediate" "0,*")
11913 (set_attr "modrm" "0,1")
11914 (set_attr "mode" "SI")])
11915
11916 (define_insn "*ashrsi3_31_zext"
11917 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11918 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11919 (match_operand:SI 2 "const_int_operand" "i,i"))))
11920 (clobber (reg:CC 17))]
11921 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11922 && INTVAL (operands[2]) == 31
11923 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11924 "@
11925 {cltd|cdq}
11926 sar{l}\t{%2, %k0|%k0, %2}"
11927 [(set_attr "type" "imovx,ishift")
11928 (set_attr "prefix_0f" "0,*")
11929 (set_attr "length_immediate" "0,*")
11930 (set_attr "modrm" "0,1")
11931 (set_attr "mode" "SI")])
11932
11933 (define_expand "ashrsi3"
11934 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11935 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11936 (match_operand:QI 2 "nonmemory_operand" "")))
11937 (clobber (reg:CC 17))]
11938 ""
11939 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11940
11941 (define_insn "*ashrsi3_1_one_bit"
11942 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11943 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11944 (match_operand:QI 2 "const_int_1_operand" "")))
11945 (clobber (reg:CC 17))]
11946 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11947 && (TARGET_SHIFT1 || optimize_size)"
11948 "sar{l}\t%0"
11949 [(set_attr "type" "ishift")
11950 (set (attr "length")
11951 (if_then_else (match_operand:SI 0 "register_operand" "")
11952 (const_string "2")
11953 (const_string "*")))])
11954
11955 (define_insn "*ashrsi3_1_one_bit_zext"
11956 [(set (match_operand:DI 0 "register_operand" "=r")
11957 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11958 (match_operand:QI 2 "const_int_1_operand" ""))))
11959 (clobber (reg:CC 17))]
11960 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11961 && (TARGET_SHIFT1 || optimize_size)"
11962 "sar{l}\t%k0"
11963 [(set_attr "type" "ishift")
11964 (set_attr "length" "2")])
11965
11966 (define_insn "*ashrsi3_1"
11967 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11968 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11969 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11970 (clobber (reg:CC 17))]
11971 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11972 "@
11973 sar{l}\t{%2, %0|%0, %2}
11974 sar{l}\t{%b2, %0|%0, %b2}"
11975 [(set_attr "type" "ishift")
11976 (set_attr "mode" "SI")])
11977
11978 (define_insn "*ashrsi3_1_zext"
11979 [(set (match_operand:DI 0 "register_operand" "=r,r")
11980 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11981 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11982 (clobber (reg:CC 17))]
11983 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11984 "@
11985 sar{l}\t{%2, %k0|%k0, %2}
11986 sar{l}\t{%b2, %k0|%k0, %b2}"
11987 [(set_attr "type" "ishift")
11988 (set_attr "mode" "SI")])
11989
11990 ;; This pattern can't accept a variable shift count, since shifts by
11991 ;; zero don't affect the flags. We assume that shifts by constant
11992 ;; zero are optimized away.
11993 (define_insn "*ashrsi3_one_bit_cmp"
11994 [(set (reg 17)
11995 (compare
11996 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11997 (match_operand:QI 2 "const_int_1_operand" ""))
11998 (const_int 0)))
11999 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12000 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12001 "ix86_match_ccmode (insn, CCGOCmode)
12002 && (TARGET_SHIFT1 || optimize_size)
12003 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12004 "sar{l}\t%0"
12005 [(set_attr "type" "ishift")
12006 (set (attr "length")
12007 (if_then_else (match_operand:SI 0 "register_operand" "")
12008 (const_string "2")
12009 (const_string "*")))])
12010
12011 (define_insn "*ashrsi3_one_bit_cmp_zext"
12012 [(set (reg 17)
12013 (compare
12014 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12015 (match_operand:QI 2 "const_int_1_operand" ""))
12016 (const_int 0)))
12017 (set (match_operand:DI 0 "register_operand" "=r")
12018 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12019 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12020 && (TARGET_SHIFT1 || optimize_size)
12021 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12022 "sar{l}\t%k0"
12023 [(set_attr "type" "ishift")
12024 (set_attr "length" "2")])
12025
12026 ;; This pattern can't accept a variable shift count, since shifts by
12027 ;; zero don't affect the flags. We assume that shifts by constant
12028 ;; zero are optimized away.
12029 (define_insn "*ashrsi3_cmp"
12030 [(set (reg 17)
12031 (compare
12032 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12033 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12034 (const_int 0)))
12035 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12036 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12037 "ix86_match_ccmode (insn, CCGOCmode)
12038 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12039 "sar{l}\t{%2, %0|%0, %2}"
12040 [(set_attr "type" "ishift")
12041 (set_attr "mode" "SI")])
12042
12043 (define_insn "*ashrsi3_cmp_zext"
12044 [(set (reg 17)
12045 (compare
12046 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12047 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12048 (const_int 0)))
12049 (set (match_operand:DI 0 "register_operand" "=r")
12050 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12051 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12052 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12053 "sar{l}\t{%2, %k0|%k0, %2}"
12054 [(set_attr "type" "ishift")
12055 (set_attr "mode" "SI")])
12056
12057 (define_expand "ashrhi3"
12058 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12059 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12060 (match_operand:QI 2 "nonmemory_operand" "")))
12061 (clobber (reg:CC 17))]
12062 "TARGET_HIMODE_MATH"
12063 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12064
12065 (define_insn "*ashrhi3_1_one_bit"
12066 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12067 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12068 (match_operand:QI 2 "const_int_1_operand" "")))
12069 (clobber (reg:CC 17))]
12070 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12071 && (TARGET_SHIFT1 || optimize_size)"
12072 "sar{w}\t%0"
12073 [(set_attr "type" "ishift")
12074 (set (attr "length")
12075 (if_then_else (match_operand 0 "register_operand" "")
12076 (const_string "2")
12077 (const_string "*")))])
12078
12079 (define_insn "*ashrhi3_1"
12080 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12081 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12082 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12083 (clobber (reg:CC 17))]
12084 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12085 "@
12086 sar{w}\t{%2, %0|%0, %2}
12087 sar{w}\t{%b2, %0|%0, %b2}"
12088 [(set_attr "type" "ishift")
12089 (set_attr "mode" "HI")])
12090
12091 ;; This pattern can't accept a variable shift count, since shifts by
12092 ;; zero don't affect the flags. We assume that shifts by constant
12093 ;; zero are optimized away.
12094 (define_insn "*ashrhi3_one_bit_cmp"
12095 [(set (reg 17)
12096 (compare
12097 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12098 (match_operand:QI 2 "const_int_1_operand" ""))
12099 (const_int 0)))
12100 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12101 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12102 "ix86_match_ccmode (insn, CCGOCmode)
12103 && (TARGET_SHIFT1 || optimize_size)
12104 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12105 "sar{w}\t%0"
12106 [(set_attr "type" "ishift")
12107 (set (attr "length")
12108 (if_then_else (match_operand 0 "register_operand" "")
12109 (const_string "2")
12110 (const_string "*")))])
12111
12112 ;; This pattern can't accept a variable shift count, since shifts by
12113 ;; zero don't affect the flags. We assume that shifts by constant
12114 ;; zero are optimized away.
12115 (define_insn "*ashrhi3_cmp"
12116 [(set (reg 17)
12117 (compare
12118 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12119 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12120 (const_int 0)))
12121 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12122 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12123 "ix86_match_ccmode (insn, CCGOCmode)
12124 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12125 "sar{w}\t{%2, %0|%0, %2}"
12126 [(set_attr "type" "ishift")
12127 (set_attr "mode" "HI")])
12128
12129 (define_expand "ashrqi3"
12130 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12131 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12132 (match_operand:QI 2 "nonmemory_operand" "")))
12133 (clobber (reg:CC 17))]
12134 "TARGET_QIMODE_MATH"
12135 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12136
12137 (define_insn "*ashrqi3_1_one_bit"
12138 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12139 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12140 (match_operand:QI 2 "const_int_1_operand" "")))
12141 (clobber (reg:CC 17))]
12142 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12143 && (TARGET_SHIFT1 || optimize_size)"
12144 "sar{b}\t%0"
12145 [(set_attr "type" "ishift")
12146 (set (attr "length")
12147 (if_then_else (match_operand 0 "register_operand" "")
12148 (const_string "2")
12149 (const_string "*")))])
12150
12151 (define_insn "*ashrqi3_1_one_bit_slp"
12152 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12153 (ashiftrt:QI (match_dup 0)
12154 (match_operand:QI 1 "const_int_1_operand" "")))
12155 (clobber (reg:CC 17))]
12156 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12157 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12158 && (TARGET_SHIFT1 || optimize_size)"
12159 "sar{b}\t%0"
12160 [(set_attr "type" "ishift1")
12161 (set (attr "length")
12162 (if_then_else (match_operand 0 "register_operand" "")
12163 (const_string "2")
12164 (const_string "*")))])
12165
12166 (define_insn "*ashrqi3_1"
12167 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12168 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12169 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12170 (clobber (reg:CC 17))]
12171 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12172 "@
12173 sar{b}\t{%2, %0|%0, %2}
12174 sar{b}\t{%b2, %0|%0, %b2}"
12175 [(set_attr "type" "ishift")
12176 (set_attr "mode" "QI")])
12177
12178 (define_insn "*ashrqi3_1_slp"
12179 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12180 (ashiftrt:QI (match_dup 0)
12181 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12182 (clobber (reg:CC 17))]
12183 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12184 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12185 "@
12186 sar{b}\t{%1, %0|%0, %1}
12187 sar{b}\t{%b1, %0|%0, %b1}"
12188 [(set_attr "type" "ishift1")
12189 (set_attr "mode" "QI")])
12190
12191 ;; This pattern can't accept a variable shift count, since shifts by
12192 ;; zero don't affect the flags. We assume that shifts by constant
12193 ;; zero are optimized away.
12194 (define_insn "*ashrqi3_one_bit_cmp"
12195 [(set (reg 17)
12196 (compare
12197 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12198 (match_operand:QI 2 "const_int_1_operand" "I"))
12199 (const_int 0)))
12200 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12201 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12202 "ix86_match_ccmode (insn, CCGOCmode)
12203 && (TARGET_SHIFT1 || optimize_size)
12204 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12205 "sar{b}\t%0"
12206 [(set_attr "type" "ishift")
12207 (set (attr "length")
12208 (if_then_else (match_operand 0 "register_operand" "")
12209 (const_string "2")
12210 (const_string "*")))])
12211
12212 ;; This pattern can't accept a variable shift count, since shifts by
12213 ;; zero don't affect the flags. We assume that shifts by constant
12214 ;; zero are optimized away.
12215 (define_insn "*ashrqi3_cmp"
12216 [(set (reg 17)
12217 (compare
12218 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12219 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12220 (const_int 0)))
12221 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12222 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12223 "ix86_match_ccmode (insn, CCGOCmode)
12224 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12225 "sar{b}\t{%2, %0|%0, %2}"
12226 [(set_attr "type" "ishift")
12227 (set_attr "mode" "QI")])
12228 \f
12229 ;; Logical shift instructions
12230
12231 ;; See comment above `ashldi3' about how this works.
12232
12233 (define_expand "lshrdi3"
12234 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12235 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12236 (match_operand:QI 2 "nonmemory_operand" "")))
12237 (clobber (reg:CC 17))])]
12238 ""
12239 {
12240 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12241 {
12242 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12243 DONE;
12244 }
12245 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12246 DONE;
12247 })
12248
12249 (define_insn "*lshrdi3_1_one_bit_rex64"
12250 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12251 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12252 (match_operand:QI 2 "const_int_1_operand" "")))
12253 (clobber (reg:CC 17))]
12254 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12255 && (TARGET_SHIFT1 || optimize_size)"
12256 "shr{q}\t%0"
12257 [(set_attr "type" "ishift")
12258 (set (attr "length")
12259 (if_then_else (match_operand:DI 0 "register_operand" "")
12260 (const_string "2")
12261 (const_string "*")))])
12262
12263 (define_insn "*lshrdi3_1_rex64"
12264 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12265 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12266 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12267 (clobber (reg:CC 17))]
12268 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12269 "@
12270 shr{q}\t{%2, %0|%0, %2}
12271 shr{q}\t{%b2, %0|%0, %b2}"
12272 [(set_attr "type" "ishift")
12273 (set_attr "mode" "DI")])
12274
12275 ;; This pattern can't accept a variable shift count, since shifts by
12276 ;; zero don't affect the flags. We assume that shifts by constant
12277 ;; zero are optimized away.
12278 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12279 [(set (reg 17)
12280 (compare
12281 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12282 (match_operand:QI 2 "const_int_1_operand" ""))
12283 (const_int 0)))
12284 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12285 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12286 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12287 && (TARGET_SHIFT1 || optimize_size)
12288 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289 "shr{q}\t%0"
12290 [(set_attr "type" "ishift")
12291 (set (attr "length")
12292 (if_then_else (match_operand:DI 0 "register_operand" "")
12293 (const_string "2")
12294 (const_string "*")))])
12295
12296 ;; This pattern can't accept a variable shift count, since shifts by
12297 ;; zero don't affect the flags. We assume that shifts by constant
12298 ;; zero are optimized away.
12299 (define_insn "*lshrdi3_cmp_rex64"
12300 [(set (reg 17)
12301 (compare
12302 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12303 (match_operand:QI 2 "const_int_operand" "e"))
12304 (const_int 0)))
12305 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12306 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12307 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12308 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12309 "shr{q}\t{%2, %0|%0, %2}"
12310 [(set_attr "type" "ishift")
12311 (set_attr "mode" "DI")])
12312
12313 (define_insn "lshrdi3_1"
12314 [(set (match_operand:DI 0 "register_operand" "=r")
12315 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12316 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12317 (clobber (match_scratch:SI 3 "=&r"))
12318 (clobber (reg:CC 17))]
12319 "!TARGET_64BIT && TARGET_CMOVE"
12320 "#"
12321 [(set_attr "type" "multi")])
12322
12323 (define_insn "*lshrdi3_2"
12324 [(set (match_operand:DI 0 "register_operand" "=r")
12325 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12326 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12327 (clobber (reg:CC 17))]
12328 "!TARGET_64BIT"
12329 "#"
12330 [(set_attr "type" "multi")])
12331
12332 (define_split
12333 [(set (match_operand:DI 0 "register_operand" "")
12334 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12335 (match_operand:QI 2 "nonmemory_operand" "")))
12336 (clobber (match_scratch:SI 3 ""))
12337 (clobber (reg:CC 17))]
12338 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12339 [(const_int 0)]
12340 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12341
12342 (define_split
12343 [(set (match_operand:DI 0 "register_operand" "")
12344 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12345 (match_operand:QI 2 "nonmemory_operand" "")))
12346 (clobber (reg:CC 17))]
12347 "!TARGET_64BIT && reload_completed"
12348 [(const_int 0)]
12349 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12350
12351 (define_expand "lshrsi3"
12352 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12353 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12354 (match_operand:QI 2 "nonmemory_operand" "")))
12355 (clobber (reg:CC 17))]
12356 ""
12357 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12358
12359 (define_insn "*lshrsi3_1_one_bit"
12360 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12361 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12362 (match_operand:QI 2 "const_int_1_operand" "")))
12363 (clobber (reg:CC 17))]
12364 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12365 && (TARGET_SHIFT1 || optimize_size)"
12366 "shr{l}\t%0"
12367 [(set_attr "type" "ishift")
12368 (set (attr "length")
12369 (if_then_else (match_operand:SI 0 "register_operand" "")
12370 (const_string "2")
12371 (const_string "*")))])
12372
12373 (define_insn "*lshrsi3_1_one_bit_zext"
12374 [(set (match_operand:DI 0 "register_operand" "=r")
12375 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12376 (match_operand:QI 2 "const_int_1_operand" "")))
12377 (clobber (reg:CC 17))]
12378 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12379 && (TARGET_SHIFT1 || optimize_size)"
12380 "shr{l}\t%k0"
12381 [(set_attr "type" "ishift")
12382 (set_attr "length" "2")])
12383
12384 (define_insn "*lshrsi3_1"
12385 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12386 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12387 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12388 (clobber (reg:CC 17))]
12389 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12390 "@
12391 shr{l}\t{%2, %0|%0, %2}
12392 shr{l}\t{%b2, %0|%0, %b2}"
12393 [(set_attr "type" "ishift")
12394 (set_attr "mode" "SI")])
12395
12396 (define_insn "*lshrsi3_1_zext"
12397 [(set (match_operand:DI 0 "register_operand" "=r,r")
12398 (zero_extend:DI
12399 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12400 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12401 (clobber (reg:CC 17))]
12402 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12403 "@
12404 shr{l}\t{%2, %k0|%k0, %2}
12405 shr{l}\t{%b2, %k0|%k0, %b2}"
12406 [(set_attr "type" "ishift")
12407 (set_attr "mode" "SI")])
12408
12409 ;; This pattern can't accept a variable shift count, since shifts by
12410 ;; zero don't affect the flags. We assume that shifts by constant
12411 ;; zero are optimized away.
12412 (define_insn "*lshrsi3_one_bit_cmp"
12413 [(set (reg 17)
12414 (compare
12415 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12416 (match_operand:QI 2 "const_int_1_operand" ""))
12417 (const_int 0)))
12418 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12419 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12420 "ix86_match_ccmode (insn, CCGOCmode)
12421 && (TARGET_SHIFT1 || optimize_size)
12422 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12423 "shr{l}\t%0"
12424 [(set_attr "type" "ishift")
12425 (set (attr "length")
12426 (if_then_else (match_operand:SI 0 "register_operand" "")
12427 (const_string "2")
12428 (const_string "*")))])
12429
12430 (define_insn "*lshrsi3_cmp_one_bit_zext"
12431 [(set (reg 17)
12432 (compare
12433 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12434 (match_operand:QI 2 "const_int_1_operand" ""))
12435 (const_int 0)))
12436 (set (match_operand:DI 0 "register_operand" "=r")
12437 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12439 && (TARGET_SHIFT1 || optimize_size)
12440 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12441 "shr{l}\t%k0"
12442 [(set_attr "type" "ishift")
12443 (set_attr "length" "2")])
12444
12445 ;; This pattern can't accept a variable shift count, since shifts by
12446 ;; zero don't affect the flags. We assume that shifts by constant
12447 ;; zero are optimized away.
12448 (define_insn "*lshrsi3_cmp"
12449 [(set (reg 17)
12450 (compare
12451 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12452 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12453 (const_int 0)))
12454 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12456 "ix86_match_ccmode (insn, CCGOCmode)
12457 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12458 "shr{l}\t{%2, %0|%0, %2}"
12459 [(set_attr "type" "ishift")
12460 (set_attr "mode" "SI")])
12461
12462 (define_insn "*lshrsi3_cmp_zext"
12463 [(set (reg 17)
12464 (compare
12465 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12466 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12467 (const_int 0)))
12468 (set (match_operand:DI 0 "register_operand" "=r")
12469 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12470 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12471 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12472 "shr{l}\t{%2, %k0|%k0, %2}"
12473 [(set_attr "type" "ishift")
12474 (set_attr "mode" "SI")])
12475
12476 (define_expand "lshrhi3"
12477 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12478 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12479 (match_operand:QI 2 "nonmemory_operand" "")))
12480 (clobber (reg:CC 17))]
12481 "TARGET_HIMODE_MATH"
12482 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12483
12484 (define_insn "*lshrhi3_1_one_bit"
12485 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12486 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12487 (match_operand:QI 2 "const_int_1_operand" "")))
12488 (clobber (reg:CC 17))]
12489 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12490 && (TARGET_SHIFT1 || optimize_size)"
12491 "shr{w}\t%0"
12492 [(set_attr "type" "ishift")
12493 (set (attr "length")
12494 (if_then_else (match_operand 0 "register_operand" "")
12495 (const_string "2")
12496 (const_string "*")))])
12497
12498 (define_insn "*lshrhi3_1"
12499 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12500 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12501 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12502 (clobber (reg:CC 17))]
12503 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12504 "@
12505 shr{w}\t{%2, %0|%0, %2}
12506 shr{w}\t{%b2, %0|%0, %b2}"
12507 [(set_attr "type" "ishift")
12508 (set_attr "mode" "HI")])
12509
12510 ;; This pattern can't accept a variable shift count, since shifts by
12511 ;; zero don't affect the flags. We assume that shifts by constant
12512 ;; zero are optimized away.
12513 (define_insn "*lshrhi3_one_bit_cmp"
12514 [(set (reg 17)
12515 (compare
12516 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12517 (match_operand:QI 2 "const_int_1_operand" ""))
12518 (const_int 0)))
12519 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12520 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12521 "ix86_match_ccmode (insn, CCGOCmode)
12522 && (TARGET_SHIFT1 || optimize_size)
12523 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12524 "shr{w}\t%0"
12525 [(set_attr "type" "ishift")
12526 (set (attr "length")
12527 (if_then_else (match_operand:SI 0 "register_operand" "")
12528 (const_string "2")
12529 (const_string "*")))])
12530
12531 ;; This pattern can't accept a variable shift count, since shifts by
12532 ;; zero don't affect the flags. We assume that shifts by constant
12533 ;; zero are optimized away.
12534 (define_insn "*lshrhi3_cmp"
12535 [(set (reg 17)
12536 (compare
12537 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12538 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12539 (const_int 0)))
12540 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12541 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12542 "ix86_match_ccmode (insn, CCGOCmode)
12543 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12544 "shr{w}\t{%2, %0|%0, %2}"
12545 [(set_attr "type" "ishift")
12546 (set_attr "mode" "HI")])
12547
12548 (define_expand "lshrqi3"
12549 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12550 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12551 (match_operand:QI 2 "nonmemory_operand" "")))
12552 (clobber (reg:CC 17))]
12553 "TARGET_QIMODE_MATH"
12554 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12555
12556 (define_insn "*lshrqi3_1_one_bit"
12557 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12558 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12559 (match_operand:QI 2 "const_int_1_operand" "")))
12560 (clobber (reg:CC 17))]
12561 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12562 && (TARGET_SHIFT1 || optimize_size)"
12563 "shr{b}\t%0"
12564 [(set_attr "type" "ishift")
12565 (set (attr "length")
12566 (if_then_else (match_operand 0 "register_operand" "")
12567 (const_string "2")
12568 (const_string "*")))])
12569
12570 (define_insn "*lshrqi3_1_one_bit_slp"
12571 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12572 (lshiftrt:QI (match_dup 0)
12573 (match_operand:QI 1 "const_int_1_operand" "")))
12574 (clobber (reg:CC 17))]
12575 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12576 && (TARGET_SHIFT1 || optimize_size)"
12577 "shr{b}\t%0"
12578 [(set_attr "type" "ishift1")
12579 (set (attr "length")
12580 (if_then_else (match_operand 0 "register_operand" "")
12581 (const_string "2")
12582 (const_string "*")))])
12583
12584 (define_insn "*lshrqi3_1"
12585 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12586 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12587 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12588 (clobber (reg:CC 17))]
12589 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12590 "@
12591 shr{b}\t{%2, %0|%0, %2}
12592 shr{b}\t{%b2, %0|%0, %b2}"
12593 [(set_attr "type" "ishift")
12594 (set_attr "mode" "QI")])
12595
12596 (define_insn "*lshrqi3_1_slp"
12597 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12598 (lshiftrt:QI (match_dup 0)
12599 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12600 (clobber (reg:CC 17))]
12601 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12602 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12603 "@
12604 shr{b}\t{%1, %0|%0, %1}
12605 shr{b}\t{%b1, %0|%0, %b1}"
12606 [(set_attr "type" "ishift1")
12607 (set_attr "mode" "QI")])
12608
12609 ;; This pattern can't accept a variable shift count, since shifts by
12610 ;; zero don't affect the flags. We assume that shifts by constant
12611 ;; zero are optimized away.
12612 (define_insn "*lshrqi2_one_bit_cmp"
12613 [(set (reg 17)
12614 (compare
12615 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12616 (match_operand:QI 2 "const_int_1_operand" ""))
12617 (const_int 0)))
12618 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12619 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12620 "ix86_match_ccmode (insn, CCGOCmode)
12621 && (TARGET_SHIFT1 || optimize_size)
12622 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12623 "shr{b}\t%0"
12624 [(set_attr "type" "ishift")
12625 (set (attr "length")
12626 (if_then_else (match_operand:SI 0 "register_operand" "")
12627 (const_string "2")
12628 (const_string "*")))])
12629
12630 ;; This pattern can't accept a variable shift count, since shifts by
12631 ;; zero don't affect the flags. We assume that shifts by constant
12632 ;; zero are optimized away.
12633 (define_insn "*lshrqi2_cmp"
12634 [(set (reg 17)
12635 (compare
12636 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12637 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12638 (const_int 0)))
12639 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12640 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12641 "ix86_match_ccmode (insn, CCGOCmode)
12642 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12643 "shr{b}\t{%2, %0|%0, %2}"
12644 [(set_attr "type" "ishift")
12645 (set_attr "mode" "QI")])
12646 \f
12647 ;; Rotate instructions
12648
12649 (define_expand "rotldi3"
12650 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12651 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12652 (match_operand:QI 2 "nonmemory_operand" "")))
12653 (clobber (reg:CC 17))]
12654 "TARGET_64BIT"
12655 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12656
12657 (define_insn "*rotlsi3_1_one_bit_rex64"
12658 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12659 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12660 (match_operand:QI 2 "const_int_1_operand" "")))
12661 (clobber (reg:CC 17))]
12662 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12663 && (TARGET_SHIFT1 || optimize_size)"
12664 "rol{q}\t%0"
12665 [(set_attr "type" "rotate")
12666 (set (attr "length")
12667 (if_then_else (match_operand:DI 0 "register_operand" "")
12668 (const_string "2")
12669 (const_string "*")))])
12670
12671 (define_insn "*rotldi3_1_rex64"
12672 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12673 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12674 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12675 (clobber (reg:CC 17))]
12676 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12677 "@
12678 rol{q}\t{%2, %0|%0, %2}
12679 rol{q}\t{%b2, %0|%0, %b2}"
12680 [(set_attr "type" "rotate")
12681 (set_attr "mode" "DI")])
12682
12683 (define_expand "rotlsi3"
12684 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12685 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12686 (match_operand:QI 2 "nonmemory_operand" "")))
12687 (clobber (reg:CC 17))]
12688 ""
12689 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12690
12691 (define_insn "*rotlsi3_1_one_bit"
12692 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12693 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12694 (match_operand:QI 2 "const_int_1_operand" "")))
12695 (clobber (reg:CC 17))]
12696 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12697 && (TARGET_SHIFT1 || optimize_size)"
12698 "rol{l}\t%0"
12699 [(set_attr "type" "rotate")
12700 (set (attr "length")
12701 (if_then_else (match_operand:SI 0 "register_operand" "")
12702 (const_string "2")
12703 (const_string "*")))])
12704
12705 (define_insn "*rotlsi3_1_one_bit_zext"
12706 [(set (match_operand:DI 0 "register_operand" "=r")
12707 (zero_extend:DI
12708 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12709 (match_operand:QI 2 "const_int_1_operand" ""))))
12710 (clobber (reg:CC 17))]
12711 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12712 && (TARGET_SHIFT1 || optimize_size)"
12713 "rol{l}\t%k0"
12714 [(set_attr "type" "rotate")
12715 (set_attr "length" "2")])
12716
12717 (define_insn "*rotlsi3_1"
12718 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12719 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12720 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12721 (clobber (reg:CC 17))]
12722 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12723 "@
12724 rol{l}\t{%2, %0|%0, %2}
12725 rol{l}\t{%b2, %0|%0, %b2}"
12726 [(set_attr "type" "rotate")
12727 (set_attr "mode" "SI")])
12728
12729 (define_insn "*rotlsi3_1_zext"
12730 [(set (match_operand:DI 0 "register_operand" "=r,r")
12731 (zero_extend:DI
12732 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12733 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12734 (clobber (reg:CC 17))]
12735 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12736 "@
12737 rol{l}\t{%2, %k0|%k0, %2}
12738 rol{l}\t{%b2, %k0|%k0, %b2}"
12739 [(set_attr "type" "rotate")
12740 (set_attr "mode" "SI")])
12741
12742 (define_expand "rotlhi3"
12743 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12744 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12745 (match_operand:QI 2 "nonmemory_operand" "")))
12746 (clobber (reg:CC 17))]
12747 "TARGET_HIMODE_MATH"
12748 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12749
12750 (define_insn "*rotlhi3_1_one_bit"
12751 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12752 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12753 (match_operand:QI 2 "const_int_1_operand" "")))
12754 (clobber (reg:CC 17))]
12755 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12756 && (TARGET_SHIFT1 || optimize_size)"
12757 "rol{w}\t%0"
12758 [(set_attr "type" "rotate")
12759 (set (attr "length")
12760 (if_then_else (match_operand 0 "register_operand" "")
12761 (const_string "2")
12762 (const_string "*")))])
12763
12764 (define_insn "*rotlhi3_1"
12765 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12766 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12767 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12768 (clobber (reg:CC 17))]
12769 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12770 "@
12771 rol{w}\t{%2, %0|%0, %2}
12772 rol{w}\t{%b2, %0|%0, %b2}"
12773 [(set_attr "type" "rotate")
12774 (set_attr "mode" "HI")])
12775
12776 (define_expand "rotlqi3"
12777 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12778 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12779 (match_operand:QI 2 "nonmemory_operand" "")))
12780 (clobber (reg:CC 17))]
12781 "TARGET_QIMODE_MATH"
12782 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12783
12784 (define_insn "*rotlqi3_1_one_bit_slp"
12785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12786 (rotate:QI (match_dup 0)
12787 (match_operand:QI 1 "const_int_1_operand" "")))
12788 (clobber (reg:CC 17))]
12789 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12790 && (TARGET_SHIFT1 || optimize_size)"
12791 "rol{b}\t%0"
12792 [(set_attr "type" "rotate1")
12793 (set (attr "length")
12794 (if_then_else (match_operand 0 "register_operand" "")
12795 (const_string "2")
12796 (const_string "*")))])
12797
12798 (define_insn "*rotlqi3_1_one_bit"
12799 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12800 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12801 (match_operand:QI 2 "const_int_1_operand" "")))
12802 (clobber (reg:CC 17))]
12803 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12804 && (TARGET_SHIFT1 || optimize_size)"
12805 "rol{b}\t%0"
12806 [(set_attr "type" "rotate")
12807 (set (attr "length")
12808 (if_then_else (match_operand 0 "register_operand" "")
12809 (const_string "2")
12810 (const_string "*")))])
12811
12812 (define_insn "*rotlqi3_1_slp"
12813 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12814 (rotate:QI (match_dup 0)
12815 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12816 (clobber (reg:CC 17))]
12817 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12818 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12819 "@
12820 rol{b}\t{%1, %0|%0, %1}
12821 rol{b}\t{%b1, %0|%0, %b1}"
12822 [(set_attr "type" "rotate1")
12823 (set_attr "mode" "QI")])
12824
12825 (define_insn "*rotlqi3_1"
12826 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12827 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12828 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12829 (clobber (reg:CC 17))]
12830 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12831 "@
12832 rol{b}\t{%2, %0|%0, %2}
12833 rol{b}\t{%b2, %0|%0, %b2}"
12834 [(set_attr "type" "rotate")
12835 (set_attr "mode" "QI")])
12836
12837 (define_expand "rotrdi3"
12838 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12839 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12840 (match_operand:QI 2 "nonmemory_operand" "")))
12841 (clobber (reg:CC 17))]
12842 "TARGET_64BIT"
12843 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12844
12845 (define_insn "*rotrdi3_1_one_bit_rex64"
12846 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12847 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12848 (match_operand:QI 2 "const_int_1_operand" "")))
12849 (clobber (reg:CC 17))]
12850 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12851 && (TARGET_SHIFT1 || optimize_size)"
12852 "ror{q}\t%0"
12853 [(set_attr "type" "rotate")
12854 (set (attr "length")
12855 (if_then_else (match_operand:DI 0 "register_operand" "")
12856 (const_string "2")
12857 (const_string "*")))])
12858
12859 (define_insn "*rotrdi3_1_rex64"
12860 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12861 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12862 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12863 (clobber (reg:CC 17))]
12864 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12865 "@
12866 ror{q}\t{%2, %0|%0, %2}
12867 ror{q}\t{%b2, %0|%0, %b2}"
12868 [(set_attr "type" "rotate")
12869 (set_attr "mode" "DI")])
12870
12871 (define_expand "rotrsi3"
12872 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12873 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12874 (match_operand:QI 2 "nonmemory_operand" "")))
12875 (clobber (reg:CC 17))]
12876 ""
12877 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12878
12879 (define_insn "*rotrsi3_1_one_bit"
12880 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12881 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12882 (match_operand:QI 2 "const_int_1_operand" "")))
12883 (clobber (reg:CC 17))]
12884 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12885 && (TARGET_SHIFT1 || optimize_size)"
12886 "ror{l}\t%0"
12887 [(set_attr "type" "rotate")
12888 (set (attr "length")
12889 (if_then_else (match_operand:SI 0 "register_operand" "")
12890 (const_string "2")
12891 (const_string "*")))])
12892
12893 (define_insn "*rotrsi3_1_one_bit_zext"
12894 [(set (match_operand:DI 0 "register_operand" "=r")
12895 (zero_extend:DI
12896 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12897 (match_operand:QI 2 "const_int_1_operand" ""))))
12898 (clobber (reg:CC 17))]
12899 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12900 && (TARGET_SHIFT1 || optimize_size)"
12901 "ror{l}\t%k0"
12902 [(set_attr "type" "rotate")
12903 (set (attr "length")
12904 (if_then_else (match_operand:SI 0 "register_operand" "")
12905 (const_string "2")
12906 (const_string "*")))])
12907
12908 (define_insn "*rotrsi3_1"
12909 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12910 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12911 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12912 (clobber (reg:CC 17))]
12913 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12914 "@
12915 ror{l}\t{%2, %0|%0, %2}
12916 ror{l}\t{%b2, %0|%0, %b2}"
12917 [(set_attr "type" "rotate")
12918 (set_attr "mode" "SI")])
12919
12920 (define_insn "*rotrsi3_1_zext"
12921 [(set (match_operand:DI 0 "register_operand" "=r,r")
12922 (zero_extend:DI
12923 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12924 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12925 (clobber (reg:CC 17))]
12926 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12927 "@
12928 ror{l}\t{%2, %k0|%k0, %2}
12929 ror{l}\t{%b2, %k0|%k0, %b2}"
12930 [(set_attr "type" "rotate")
12931 (set_attr "mode" "SI")])
12932
12933 (define_expand "rotrhi3"
12934 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12935 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12936 (match_operand:QI 2 "nonmemory_operand" "")))
12937 (clobber (reg:CC 17))]
12938 "TARGET_HIMODE_MATH"
12939 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12940
12941 (define_insn "*rotrhi3_one_bit"
12942 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12943 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12944 (match_operand:QI 2 "const_int_1_operand" "")))
12945 (clobber (reg:CC 17))]
12946 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12947 && (TARGET_SHIFT1 || optimize_size)"
12948 "ror{w}\t%0"
12949 [(set_attr "type" "rotate")
12950 (set (attr "length")
12951 (if_then_else (match_operand 0 "register_operand" "")
12952 (const_string "2")
12953 (const_string "*")))])
12954
12955 (define_insn "*rotrhi3"
12956 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12957 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12958 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12959 (clobber (reg:CC 17))]
12960 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12961 "@
12962 ror{w}\t{%2, %0|%0, %2}
12963 ror{w}\t{%b2, %0|%0, %b2}"
12964 [(set_attr "type" "rotate")
12965 (set_attr "mode" "HI")])
12966
12967 (define_expand "rotrqi3"
12968 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12969 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12970 (match_operand:QI 2 "nonmemory_operand" "")))
12971 (clobber (reg:CC 17))]
12972 "TARGET_QIMODE_MATH"
12973 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12974
12975 (define_insn "*rotrqi3_1_one_bit"
12976 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12977 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12978 (match_operand:QI 2 "const_int_1_operand" "")))
12979 (clobber (reg:CC 17))]
12980 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12981 && (TARGET_SHIFT1 || optimize_size)"
12982 "ror{b}\t%0"
12983 [(set_attr "type" "rotate")
12984 (set (attr "length")
12985 (if_then_else (match_operand 0 "register_operand" "")
12986 (const_string "2")
12987 (const_string "*")))])
12988
12989 (define_insn "*rotrqi3_1_one_bit_slp"
12990 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12991 (rotatert:QI (match_dup 0)
12992 (match_operand:QI 1 "const_int_1_operand" "")))
12993 (clobber (reg:CC 17))]
12994 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12995 && (TARGET_SHIFT1 || optimize_size)"
12996 "ror{b}\t%0"
12997 [(set_attr "type" "rotate1")
12998 (set (attr "length")
12999 (if_then_else (match_operand 0 "register_operand" "")
13000 (const_string "2")
13001 (const_string "*")))])
13002
13003 (define_insn "*rotrqi3_1"
13004 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13005 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13006 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13007 (clobber (reg:CC 17))]
13008 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13009 "@
13010 ror{b}\t{%2, %0|%0, %2}
13011 ror{b}\t{%b2, %0|%0, %b2}"
13012 [(set_attr "type" "rotate")
13013 (set_attr "mode" "QI")])
13014
13015 (define_insn "*rotrqi3_1_slp"
13016 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13017 (rotatert:QI (match_dup 0)
13018 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13019 (clobber (reg:CC 17))]
13020 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13021 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13022 "@
13023 ror{b}\t{%1, %0|%0, %1}
13024 ror{b}\t{%b1, %0|%0, %b1}"
13025 [(set_attr "type" "rotate1")
13026 (set_attr "mode" "QI")])
13027 \f
13028 ;; Bit set / bit test instructions
13029
13030 (define_expand "extv"
13031 [(set (match_operand:SI 0 "register_operand" "")
13032 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13033 (match_operand:SI 2 "immediate_operand" "")
13034 (match_operand:SI 3 "immediate_operand" "")))]
13035 ""
13036 {
13037 /* Handle extractions from %ah et al. */
13038 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13039 FAIL;
13040
13041 /* From mips.md: extract_bit_field doesn't verify that our source
13042 matches the predicate, so check it again here. */
13043 if (! register_operand (operands[1], VOIDmode))
13044 FAIL;
13045 })
13046
13047 (define_expand "extzv"
13048 [(set (match_operand:SI 0 "register_operand" "")
13049 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13050 (match_operand:SI 2 "immediate_operand" "")
13051 (match_operand:SI 3 "immediate_operand" "")))]
13052 ""
13053 {
13054 /* Handle extractions from %ah et al. */
13055 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13056 FAIL;
13057
13058 /* From mips.md: extract_bit_field doesn't verify that our source
13059 matches the predicate, so check it again here. */
13060 if (! register_operand (operands[1], VOIDmode))
13061 FAIL;
13062 })
13063
13064 (define_expand "insv"
13065 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13066 (match_operand:SI 1 "immediate_operand" "")
13067 (match_operand:SI 2 "immediate_operand" ""))
13068 (match_operand:SI 3 "register_operand" ""))]
13069 ""
13070 {
13071 /* Handle extractions from %ah et al. */
13072 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13073 FAIL;
13074
13075 /* From mips.md: insert_bit_field doesn't verify that our source
13076 matches the predicate, so check it again here. */
13077 if (! register_operand (operands[0], VOIDmode))
13078 FAIL;
13079 })
13080
13081 ;; %%% bts, btr, btc, bt.
13082 \f
13083 ;; Store-flag instructions.
13084
13085 ;; For all sCOND expanders, also expand the compare or test insn that
13086 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13087
13088 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13089 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13090 ;; way, which can later delete the movzx if only QImode is needed.
13091
13092 (define_expand "seq"
13093 [(set (match_operand:QI 0 "register_operand" "")
13094 (eq:QI (reg:CC 17) (const_int 0)))]
13095 ""
13096 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13097
13098 (define_expand "sne"
13099 [(set (match_operand:QI 0 "register_operand" "")
13100 (ne:QI (reg:CC 17) (const_int 0)))]
13101 ""
13102 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13103
13104 (define_expand "sgt"
13105 [(set (match_operand:QI 0 "register_operand" "")
13106 (gt:QI (reg:CC 17) (const_int 0)))]
13107 ""
13108 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13109
13110 (define_expand "sgtu"
13111 [(set (match_operand:QI 0 "register_operand" "")
13112 (gtu:QI (reg:CC 17) (const_int 0)))]
13113 ""
13114 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13115
13116 (define_expand "slt"
13117 [(set (match_operand:QI 0 "register_operand" "")
13118 (lt:QI (reg:CC 17) (const_int 0)))]
13119 ""
13120 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13121
13122 (define_expand "sltu"
13123 [(set (match_operand:QI 0 "register_operand" "")
13124 (ltu:QI (reg:CC 17) (const_int 0)))]
13125 ""
13126 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13127
13128 (define_expand "sge"
13129 [(set (match_operand:QI 0 "register_operand" "")
13130 (ge:QI (reg:CC 17) (const_int 0)))]
13131 ""
13132 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13133
13134 (define_expand "sgeu"
13135 [(set (match_operand:QI 0 "register_operand" "")
13136 (geu:QI (reg:CC 17) (const_int 0)))]
13137 ""
13138 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13139
13140 (define_expand "sle"
13141 [(set (match_operand:QI 0 "register_operand" "")
13142 (le:QI (reg:CC 17) (const_int 0)))]
13143 ""
13144 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13145
13146 (define_expand "sleu"
13147 [(set (match_operand:QI 0 "register_operand" "")
13148 (leu:QI (reg:CC 17) (const_int 0)))]
13149 ""
13150 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13151
13152 (define_expand "sunordered"
13153 [(set (match_operand:QI 0 "register_operand" "")
13154 (unordered:QI (reg:CC 17) (const_int 0)))]
13155 "TARGET_80387 || TARGET_SSE"
13156 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13157
13158 (define_expand "sordered"
13159 [(set (match_operand:QI 0 "register_operand" "")
13160 (ordered:QI (reg:CC 17) (const_int 0)))]
13161 "TARGET_80387"
13162 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13163
13164 (define_expand "suneq"
13165 [(set (match_operand:QI 0 "register_operand" "")
13166 (uneq:QI (reg:CC 17) (const_int 0)))]
13167 "TARGET_80387 || TARGET_SSE"
13168 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13169
13170 (define_expand "sunge"
13171 [(set (match_operand:QI 0 "register_operand" "")
13172 (unge:QI (reg:CC 17) (const_int 0)))]
13173 "TARGET_80387 || TARGET_SSE"
13174 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13175
13176 (define_expand "sungt"
13177 [(set (match_operand:QI 0 "register_operand" "")
13178 (ungt:QI (reg:CC 17) (const_int 0)))]
13179 "TARGET_80387 || TARGET_SSE"
13180 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13181
13182 (define_expand "sunle"
13183 [(set (match_operand:QI 0 "register_operand" "")
13184 (unle:QI (reg:CC 17) (const_int 0)))]
13185 "TARGET_80387 || TARGET_SSE"
13186 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13187
13188 (define_expand "sunlt"
13189 [(set (match_operand:QI 0 "register_operand" "")
13190 (unlt:QI (reg:CC 17) (const_int 0)))]
13191 "TARGET_80387 || TARGET_SSE"
13192 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13193
13194 (define_expand "sltgt"
13195 [(set (match_operand:QI 0 "register_operand" "")
13196 (ltgt:QI (reg:CC 17) (const_int 0)))]
13197 "TARGET_80387 || TARGET_SSE"
13198 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13199
13200 (define_insn "*setcc_1"
13201 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13202 (match_operator:QI 1 "ix86_comparison_operator"
13203 [(reg 17) (const_int 0)]))]
13204 ""
13205 "set%C1\t%0"
13206 [(set_attr "type" "setcc")
13207 (set_attr "mode" "QI")])
13208
13209 (define_insn "setcc_2"
13210 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13211 (match_operator:QI 1 "ix86_comparison_operator"
13212 [(reg 17) (const_int 0)]))]
13213 ""
13214 "set%C1\t%0"
13215 [(set_attr "type" "setcc")
13216 (set_attr "mode" "QI")])
13217
13218 ;; In general it is not safe to assume too much about CCmode registers,
13219 ;; so simplify-rtx stops when it sees a second one. Under certain
13220 ;; conditions this is safe on x86, so help combine not create
13221 ;;
13222 ;; seta %al
13223 ;; testb %al, %al
13224 ;; sete %al
13225
13226 (define_split
13227 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13228 (ne:QI (match_operator 1 "ix86_comparison_operator"
13229 [(reg 17) (const_int 0)])
13230 (const_int 0)))]
13231 ""
13232 [(set (match_dup 0) (match_dup 1))]
13233 {
13234 PUT_MODE (operands[1], QImode);
13235 })
13236
13237 (define_split
13238 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13239 (ne:QI (match_operator 1 "ix86_comparison_operator"
13240 [(reg 17) (const_int 0)])
13241 (const_int 0)))]
13242 ""
13243 [(set (match_dup 0) (match_dup 1))]
13244 {
13245 PUT_MODE (operands[1], QImode);
13246 })
13247
13248 (define_split
13249 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13250 (eq:QI (match_operator 1 "ix86_comparison_operator"
13251 [(reg 17) (const_int 0)])
13252 (const_int 0)))]
13253 ""
13254 [(set (match_dup 0) (match_dup 1))]
13255 {
13256 rtx new_op1 = copy_rtx (operands[1]);
13257 operands[1] = new_op1;
13258 PUT_MODE (new_op1, QImode);
13259 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13260 GET_MODE (XEXP (new_op1, 0))));
13261
13262 /* Make sure that (a) the CCmode we have for the flags is strong
13263 enough for the reversed compare or (b) we have a valid FP compare. */
13264 if (! ix86_comparison_operator (new_op1, VOIDmode))
13265 FAIL;
13266 })
13267
13268 (define_split
13269 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13270 (eq:QI (match_operator 1 "ix86_comparison_operator"
13271 [(reg 17) (const_int 0)])
13272 (const_int 0)))]
13273 ""
13274 [(set (match_dup 0) (match_dup 1))]
13275 {
13276 rtx new_op1 = copy_rtx (operands[1]);
13277 operands[1] = new_op1;
13278 PUT_MODE (new_op1, QImode);
13279 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13280 GET_MODE (XEXP (new_op1, 0))));
13281
13282 /* Make sure that (a) the CCmode we have for the flags is strong
13283 enough for the reversed compare or (b) we have a valid FP compare. */
13284 if (! ix86_comparison_operator (new_op1, VOIDmode))
13285 FAIL;
13286 })
13287
13288 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13289 ;; subsequent logical operations are used to imitate conditional moves.
13290 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13291 ;; it directly. Further holding this value in pseudo register might bring
13292 ;; problem in implicit normalization in spill code.
13293 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13294 ;; instructions after reload by splitting the conditional move patterns.
13295
13296 (define_insn "*sse_setccsf"
13297 [(set (match_operand:SF 0 "register_operand" "=x")
13298 (match_operator:SF 1 "sse_comparison_operator"
13299 [(match_operand:SF 2 "register_operand" "0")
13300 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13301 "TARGET_SSE && reload_completed"
13302 "cmp%D1ss\t{%3, %0|%0, %3}"
13303 [(set_attr "type" "ssecmp")
13304 (set_attr "mode" "SF")])
13305
13306 (define_insn "*sse_setccdf"
13307 [(set (match_operand:DF 0 "register_operand" "=Y")
13308 (match_operator:DF 1 "sse_comparison_operator"
13309 [(match_operand:DF 2 "register_operand" "0")
13310 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13311 "TARGET_SSE2 && reload_completed"
13312 "cmp%D1sd\t{%3, %0|%0, %3}"
13313 [(set_attr "type" "ssecmp")
13314 (set_attr "mode" "DF")])
13315 \f
13316 ;; Basic conditional jump instructions.
13317 ;; We ignore the overflow flag for signed branch instructions.
13318
13319 ;; For all bCOND expanders, also expand the compare or test insn that
13320 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13321
13322 (define_expand "beq"
13323 [(set (pc)
13324 (if_then_else (match_dup 1)
13325 (label_ref (match_operand 0 "" ""))
13326 (pc)))]
13327 ""
13328 "ix86_expand_branch (EQ, operands[0]); DONE;")
13329
13330 (define_expand "bne"
13331 [(set (pc)
13332 (if_then_else (match_dup 1)
13333 (label_ref (match_operand 0 "" ""))
13334 (pc)))]
13335 ""
13336 "ix86_expand_branch (NE, operands[0]); DONE;")
13337
13338 (define_expand "bgt"
13339 [(set (pc)
13340 (if_then_else (match_dup 1)
13341 (label_ref (match_operand 0 "" ""))
13342 (pc)))]
13343 ""
13344 "ix86_expand_branch (GT, operands[0]); DONE;")
13345
13346 (define_expand "bgtu"
13347 [(set (pc)
13348 (if_then_else (match_dup 1)
13349 (label_ref (match_operand 0 "" ""))
13350 (pc)))]
13351 ""
13352 "ix86_expand_branch (GTU, operands[0]); DONE;")
13353
13354 (define_expand "blt"
13355 [(set (pc)
13356 (if_then_else (match_dup 1)
13357 (label_ref (match_operand 0 "" ""))
13358 (pc)))]
13359 ""
13360 "ix86_expand_branch (LT, operands[0]); DONE;")
13361
13362 (define_expand "bltu"
13363 [(set (pc)
13364 (if_then_else (match_dup 1)
13365 (label_ref (match_operand 0 "" ""))
13366 (pc)))]
13367 ""
13368 "ix86_expand_branch (LTU, operands[0]); DONE;")
13369
13370 (define_expand "bge"
13371 [(set (pc)
13372 (if_then_else (match_dup 1)
13373 (label_ref (match_operand 0 "" ""))
13374 (pc)))]
13375 ""
13376 "ix86_expand_branch (GE, operands[0]); DONE;")
13377
13378 (define_expand "bgeu"
13379 [(set (pc)
13380 (if_then_else (match_dup 1)
13381 (label_ref (match_operand 0 "" ""))
13382 (pc)))]
13383 ""
13384 "ix86_expand_branch (GEU, operands[0]); DONE;")
13385
13386 (define_expand "ble"
13387 [(set (pc)
13388 (if_then_else (match_dup 1)
13389 (label_ref (match_operand 0 "" ""))
13390 (pc)))]
13391 ""
13392 "ix86_expand_branch (LE, operands[0]); DONE;")
13393
13394 (define_expand "bleu"
13395 [(set (pc)
13396 (if_then_else (match_dup 1)
13397 (label_ref (match_operand 0 "" ""))
13398 (pc)))]
13399 ""
13400 "ix86_expand_branch (LEU, operands[0]); DONE;")
13401
13402 (define_expand "bunordered"
13403 [(set (pc)
13404 (if_then_else (match_dup 1)
13405 (label_ref (match_operand 0 "" ""))
13406 (pc)))]
13407 "TARGET_80387 || TARGET_SSE"
13408 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13409
13410 (define_expand "bordered"
13411 [(set (pc)
13412 (if_then_else (match_dup 1)
13413 (label_ref (match_operand 0 "" ""))
13414 (pc)))]
13415 "TARGET_80387 || TARGET_SSE"
13416 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13417
13418 (define_expand "buneq"
13419 [(set (pc)
13420 (if_then_else (match_dup 1)
13421 (label_ref (match_operand 0 "" ""))
13422 (pc)))]
13423 "TARGET_80387 || TARGET_SSE"
13424 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13425
13426 (define_expand "bunge"
13427 [(set (pc)
13428 (if_then_else (match_dup 1)
13429 (label_ref (match_operand 0 "" ""))
13430 (pc)))]
13431 "TARGET_80387 || TARGET_SSE"
13432 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13433
13434 (define_expand "bungt"
13435 [(set (pc)
13436 (if_then_else (match_dup 1)
13437 (label_ref (match_operand 0 "" ""))
13438 (pc)))]
13439 "TARGET_80387 || TARGET_SSE"
13440 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13441
13442 (define_expand "bunle"
13443 [(set (pc)
13444 (if_then_else (match_dup 1)
13445 (label_ref (match_operand 0 "" ""))
13446 (pc)))]
13447 "TARGET_80387 || TARGET_SSE"
13448 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13449
13450 (define_expand "bunlt"
13451 [(set (pc)
13452 (if_then_else (match_dup 1)
13453 (label_ref (match_operand 0 "" ""))
13454 (pc)))]
13455 "TARGET_80387 || TARGET_SSE"
13456 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13457
13458 (define_expand "bltgt"
13459 [(set (pc)
13460 (if_then_else (match_dup 1)
13461 (label_ref (match_operand 0 "" ""))
13462 (pc)))]
13463 "TARGET_80387 || TARGET_SSE"
13464 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13465
13466 (define_insn "*jcc_1"
13467 [(set (pc)
13468 (if_then_else (match_operator 1 "ix86_comparison_operator"
13469 [(reg 17) (const_int 0)])
13470 (label_ref (match_operand 0 "" ""))
13471 (pc)))]
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 (define_insn "*jcc_2"
13485 [(set (pc)
13486 (if_then_else (match_operator 1 "ix86_comparison_operator"
13487 [(reg 17) (const_int 0)])
13488 (pc)
13489 (label_ref (match_operand 0 "" ""))))]
13490 ""
13491 "%+j%c1\t%l0"
13492 [(set_attr "type" "ibr")
13493 (set_attr "modrm" "0")
13494 (set (attr "length")
13495 (if_then_else (and (ge (minus (match_dup 0) (pc))
13496 (const_int -126))
13497 (lt (minus (match_dup 0) (pc))
13498 (const_int 128)))
13499 (const_int 2)
13500 (const_int 6)))])
13501
13502 ;; In general it is not safe to assume too much about CCmode registers,
13503 ;; so simplify-rtx stops when it sees a second one. Under certain
13504 ;; conditions this is safe on x86, so help combine not create
13505 ;;
13506 ;; seta %al
13507 ;; testb %al, %al
13508 ;; je Lfoo
13509
13510 (define_split
13511 [(set (pc)
13512 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13513 [(reg 17) (const_int 0)])
13514 (const_int 0))
13515 (label_ref (match_operand 1 "" ""))
13516 (pc)))]
13517 ""
13518 [(set (pc)
13519 (if_then_else (match_dup 0)
13520 (label_ref (match_dup 1))
13521 (pc)))]
13522 {
13523 PUT_MODE (operands[0], VOIDmode);
13524 })
13525
13526 (define_split
13527 [(set (pc)
13528 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13529 [(reg 17) (const_int 0)])
13530 (const_int 0))
13531 (label_ref (match_operand 1 "" ""))
13532 (pc)))]
13533 ""
13534 [(set (pc)
13535 (if_then_else (match_dup 0)
13536 (label_ref (match_dup 1))
13537 (pc)))]
13538 {
13539 rtx new_op0 = copy_rtx (operands[0]);
13540 operands[0] = new_op0;
13541 PUT_MODE (new_op0, VOIDmode);
13542 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13543 GET_MODE (XEXP (new_op0, 0))));
13544
13545 /* Make sure that (a) the CCmode we have for the flags is strong
13546 enough for the reversed compare or (b) we have a valid FP compare. */
13547 if (! ix86_comparison_operator (new_op0, VOIDmode))
13548 FAIL;
13549 })
13550
13551 ;; Define combination compare-and-branch fp compare instructions to use
13552 ;; during early optimization. Splitting the operation apart early makes
13553 ;; for bad code when we want to reverse the operation.
13554
13555 (define_insn "*fp_jcc_1"
13556 [(set (pc)
13557 (if_then_else (match_operator 0 "comparison_operator"
13558 [(match_operand 1 "register_operand" "f")
13559 (match_operand 2 "register_operand" "f")])
13560 (label_ref (match_operand 3 "" ""))
13561 (pc)))
13562 (clobber (reg:CCFP 18))
13563 (clobber (reg:CCFP 17))]
13564 "TARGET_CMOVE && TARGET_80387
13565 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13566 && FLOAT_MODE_P (GET_MODE (operands[1]))
13567 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13568 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13569 "#")
13570
13571 (define_insn "*fp_jcc_1_sse"
13572 [(set (pc)
13573 (if_then_else (match_operator 0 "comparison_operator"
13574 [(match_operand 1 "register_operand" "f#x,x#f")
13575 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13576 (label_ref (match_operand 3 "" ""))
13577 (pc)))
13578 (clobber (reg:CCFP 18))
13579 (clobber (reg:CCFP 17))]
13580 "TARGET_80387
13581 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13582 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13583 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13584 "#")
13585
13586 (define_insn "*fp_jcc_1_sse_only"
13587 [(set (pc)
13588 (if_then_else (match_operator 0 "comparison_operator"
13589 [(match_operand 1 "register_operand" "x")
13590 (match_operand 2 "nonimmediate_operand" "xm")])
13591 (label_ref (match_operand 3 "" ""))
13592 (pc)))
13593 (clobber (reg:CCFP 18))
13594 (clobber (reg:CCFP 17))]
13595 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13596 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13597 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13598 "#")
13599
13600 (define_insn "*fp_jcc_2"
13601 [(set (pc)
13602 (if_then_else (match_operator 0 "comparison_operator"
13603 [(match_operand 1 "register_operand" "f")
13604 (match_operand 2 "register_operand" "f")])
13605 (pc)
13606 (label_ref (match_operand 3 "" ""))))
13607 (clobber (reg:CCFP 18))
13608 (clobber (reg:CCFP 17))]
13609 "TARGET_CMOVE && TARGET_80387
13610 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13611 && FLOAT_MODE_P (GET_MODE (operands[1]))
13612 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13613 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13614 "#")
13615
13616 (define_insn "*fp_jcc_2_sse"
13617 [(set (pc)
13618 (if_then_else (match_operator 0 "comparison_operator"
13619 [(match_operand 1 "register_operand" "f#x,x#f")
13620 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13621 (pc)
13622 (label_ref (match_operand 3 "" ""))))
13623 (clobber (reg:CCFP 18))
13624 (clobber (reg:CCFP 17))]
13625 "TARGET_80387
13626 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13627 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13628 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13629 "#")
13630
13631 (define_insn "*fp_jcc_2_sse_only"
13632 [(set (pc)
13633 (if_then_else (match_operator 0 "comparison_operator"
13634 [(match_operand 1 "register_operand" "x")
13635 (match_operand 2 "nonimmediate_operand" "xm")])
13636 (pc)
13637 (label_ref (match_operand 3 "" ""))))
13638 (clobber (reg:CCFP 18))
13639 (clobber (reg:CCFP 17))]
13640 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13641 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13642 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13643 "#")
13644
13645 (define_insn "*fp_jcc_3"
13646 [(set (pc)
13647 (if_then_else (match_operator 0 "comparison_operator"
13648 [(match_operand 1 "register_operand" "f")
13649 (match_operand 2 "nonimmediate_operand" "fm")])
13650 (label_ref (match_operand 3 "" ""))
13651 (pc)))
13652 (clobber (reg:CCFP 18))
13653 (clobber (reg:CCFP 17))
13654 (clobber (match_scratch:HI 4 "=a"))]
13655 "TARGET_80387
13656 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13657 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13658 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13659 && SELECT_CC_MODE (GET_CODE (operands[0]),
13660 operands[1], operands[2]) == CCFPmode
13661 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13662 "#")
13663
13664 (define_insn "*fp_jcc_4"
13665 [(set (pc)
13666 (if_then_else (match_operator 0 "comparison_operator"
13667 [(match_operand 1 "register_operand" "f")
13668 (match_operand 2 "nonimmediate_operand" "fm")])
13669 (pc)
13670 (label_ref (match_operand 3 "" ""))))
13671 (clobber (reg:CCFP 18))
13672 (clobber (reg:CCFP 17))
13673 (clobber (match_scratch:HI 4 "=a"))]
13674 "TARGET_80387
13675 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13676 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13677 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13678 && SELECT_CC_MODE (GET_CODE (operands[0]),
13679 operands[1], operands[2]) == CCFPmode
13680 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13681 "#")
13682
13683 (define_insn "*fp_jcc_5"
13684 [(set (pc)
13685 (if_then_else (match_operator 0 "comparison_operator"
13686 [(match_operand 1 "register_operand" "f")
13687 (match_operand 2 "register_operand" "f")])
13688 (label_ref (match_operand 3 "" ""))
13689 (pc)))
13690 (clobber (reg:CCFP 18))
13691 (clobber (reg:CCFP 17))
13692 (clobber (match_scratch:HI 4 "=a"))]
13693 "TARGET_80387
13694 && FLOAT_MODE_P (GET_MODE (operands[1]))
13695 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13696 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13697 "#")
13698
13699 (define_insn "*fp_jcc_6"
13700 [(set (pc)
13701 (if_then_else (match_operator 0 "comparison_operator"
13702 [(match_operand 1 "register_operand" "f")
13703 (match_operand 2 "register_operand" "f")])
13704 (pc)
13705 (label_ref (match_operand 3 "" ""))))
13706 (clobber (reg:CCFP 18))
13707 (clobber (reg:CCFP 17))
13708 (clobber (match_scratch:HI 4 "=a"))]
13709 "TARGET_80387
13710 && FLOAT_MODE_P (GET_MODE (operands[1]))
13711 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13712 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13713 "#")
13714
13715 (define_split
13716 [(set (pc)
13717 (if_then_else (match_operator 0 "comparison_operator"
13718 [(match_operand 1 "register_operand" "")
13719 (match_operand 2 "nonimmediate_operand" "")])
13720 (match_operand 3 "" "")
13721 (match_operand 4 "" "")))
13722 (clobber (reg:CCFP 18))
13723 (clobber (reg:CCFP 17))]
13724 "reload_completed"
13725 [(const_int 0)]
13726 {
13727 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13728 operands[3], operands[4], NULL_RTX);
13729 DONE;
13730 })
13731
13732 (define_split
13733 [(set (pc)
13734 (if_then_else (match_operator 0 "comparison_operator"
13735 [(match_operand 1 "register_operand" "")
13736 (match_operand 2 "nonimmediate_operand" "")])
13737 (match_operand 3 "" "")
13738 (match_operand 4 "" "")))
13739 (clobber (reg:CCFP 18))
13740 (clobber (reg:CCFP 17))
13741 (clobber (match_scratch:HI 5 "=a"))]
13742 "reload_completed"
13743 [(set (pc)
13744 (if_then_else (match_dup 6)
13745 (match_dup 3)
13746 (match_dup 4)))]
13747 {
13748 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13749 operands[3], operands[4], operands[5]);
13750 DONE;
13751 })
13752 \f
13753 ;; Unconditional and other jump instructions
13754
13755 (define_insn "jump"
13756 [(set (pc)
13757 (label_ref (match_operand 0 "" "")))]
13758 ""
13759 "jmp\t%l0"
13760 [(set_attr "type" "ibr")
13761 (set (attr "length")
13762 (if_then_else (and (ge (minus (match_dup 0) (pc))
13763 (const_int -126))
13764 (lt (minus (match_dup 0) (pc))
13765 (const_int 128)))
13766 (const_int 2)
13767 (const_int 5)))
13768 (set_attr "modrm" "0")])
13769
13770 (define_expand "indirect_jump"
13771 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13772 ""
13773 "")
13774
13775 (define_insn "*indirect_jump"
13776 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13777 "!TARGET_64BIT"
13778 "jmp\t%A0"
13779 [(set_attr "type" "ibr")
13780 (set_attr "length_immediate" "0")])
13781
13782 (define_insn "*indirect_jump_rtx64"
13783 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13784 "TARGET_64BIT"
13785 "jmp\t%A0"
13786 [(set_attr "type" "ibr")
13787 (set_attr "length_immediate" "0")])
13788
13789 (define_expand "tablejump"
13790 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13791 (use (label_ref (match_operand 1 "" "")))])]
13792 ""
13793 {
13794 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13795 relative. Convert the relative address to an absolute address. */
13796 if (flag_pic)
13797 {
13798 rtx op0, op1;
13799 enum rtx_code code;
13800
13801 if (TARGET_64BIT)
13802 {
13803 code = PLUS;
13804 op0 = operands[0];
13805 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13806 }
13807 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13808 {
13809 code = PLUS;
13810 op0 = operands[0];
13811 op1 = pic_offset_table_rtx;
13812 }
13813 else
13814 {
13815 code = MINUS;
13816 op0 = pic_offset_table_rtx;
13817 op1 = operands[0];
13818 }
13819
13820 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13821 OPTAB_DIRECT);
13822 }
13823 })
13824
13825 (define_insn "*tablejump_1"
13826 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13827 (use (label_ref (match_operand 1 "" "")))]
13828 "!TARGET_64BIT"
13829 "jmp\t%A0"
13830 [(set_attr "type" "ibr")
13831 (set_attr "length_immediate" "0")])
13832
13833 (define_insn "*tablejump_1_rtx64"
13834 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13835 (use (label_ref (match_operand 1 "" "")))]
13836 "TARGET_64BIT"
13837 "jmp\t%A0"
13838 [(set_attr "type" "ibr")
13839 (set_attr "length_immediate" "0")])
13840 \f
13841 ;; Loop instruction
13842 ;;
13843 ;; This is all complicated by the fact that since this is a jump insn
13844 ;; we must handle our own reloads.
13845
13846 (define_expand "doloop_end"
13847 [(use (match_operand 0 "" "")) ; loop pseudo
13848 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13849 (use (match_operand 2 "" "")) ; max iterations
13850 (use (match_operand 3 "" "")) ; loop level
13851 (use (match_operand 4 "" ""))] ; label
13852 "!TARGET_64BIT && TARGET_USE_LOOP"
13853 "
13854 {
13855 /* Only use cloop on innermost loops. */
13856 if (INTVAL (operands[3]) > 1)
13857 FAIL;
13858 if (GET_MODE (operands[0]) != SImode)
13859 FAIL;
13860 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13861 operands[0]));
13862 DONE;
13863 }")
13864
13865 (define_insn "doloop_end_internal"
13866 [(set (pc)
13867 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13868 (const_int 1))
13869 (label_ref (match_operand 0 "" ""))
13870 (pc)))
13871 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13872 (plus:SI (match_dup 1)
13873 (const_int -1)))
13874 (clobber (match_scratch:SI 3 "=X,X,r"))
13875 (clobber (reg:CC 17))]
13876 "!TARGET_64BIT && TARGET_USE_LOOP"
13877 {
13878 if (which_alternative != 0)
13879 return "#";
13880 if (get_attr_length (insn) == 2)
13881 return "%+loop\t%l0";
13882 else
13883 return "dec{l}\t%1\;%+jne\t%l0";
13884 }
13885 [(set_attr "ppro_uops" "many")
13886 (set (attr "length")
13887 (if_then_else (and (eq_attr "alternative" "0")
13888 (and (ge (minus (match_dup 0) (pc))
13889 (const_int -126))
13890 (lt (minus (match_dup 0) (pc))
13891 (const_int 128))))
13892 (const_int 2)
13893 (const_int 16)))
13894 ;; We don't know the type before shorten branches. Optimistically expect
13895 ;; the loop instruction to match.
13896 (set (attr "type") (const_string "ibr"))])
13897
13898 (define_split
13899 [(set (pc)
13900 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13901 (const_int 1))
13902 (match_operand 0 "" "")
13903 (pc)))
13904 (set (match_dup 1)
13905 (plus:SI (match_dup 1)
13906 (const_int -1)))
13907 (clobber (match_scratch:SI 2 ""))
13908 (clobber (reg:CC 17))]
13909 "!TARGET_64BIT && TARGET_USE_LOOP
13910 && reload_completed
13911 && REGNO (operands[1]) != 2"
13912 [(parallel [(set (reg:CCZ 17)
13913 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13914 (const_int 0)))
13915 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13916 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13917 (match_dup 0)
13918 (pc)))]
13919 "")
13920
13921 (define_split
13922 [(set (pc)
13923 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13924 (const_int 1))
13925 (match_operand 0 "" "")
13926 (pc)))
13927 (set (match_operand:SI 2 "nonimmediate_operand" "")
13928 (plus:SI (match_dup 1)
13929 (const_int -1)))
13930 (clobber (match_scratch:SI 3 ""))
13931 (clobber (reg:CC 17))]
13932 "!TARGET_64BIT && TARGET_USE_LOOP
13933 && reload_completed
13934 && (! REG_P (operands[2])
13935 || ! rtx_equal_p (operands[1], operands[2]))"
13936 [(set (match_dup 3) (match_dup 1))
13937 (parallel [(set (reg:CCZ 17)
13938 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13939 (const_int 0)))
13940 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13941 (set (match_dup 2) (match_dup 3))
13942 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13943 (match_dup 0)
13944 (pc)))]
13945 "")
13946
13947 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13948
13949 (define_peephole2
13950 [(set (reg 17) (match_operand 0 "" ""))
13951 (set (match_operand:QI 1 "register_operand" "")
13952 (match_operator:QI 2 "ix86_comparison_operator"
13953 [(reg 17) (const_int 0)]))
13954 (set (match_operand 3 "q_regs_operand" "")
13955 (zero_extend (match_dup 1)))]
13956 "(peep2_reg_dead_p (3, operands[1])
13957 || operands_match_p (operands[1], operands[3]))
13958 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13959 [(set (match_dup 4) (match_dup 0))
13960 (set (strict_low_part (match_dup 5))
13961 (match_dup 2))]
13962 {
13963 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13964 operands[5] = gen_lowpart (QImode, operands[3]);
13965 ix86_expand_clear (operands[3]);
13966 })
13967
13968 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13969
13970 (define_peephole2
13971 [(set (reg 17) (match_operand 0 "" ""))
13972 (set (match_operand:QI 1 "register_operand" "")
13973 (match_operator:QI 2 "ix86_comparison_operator"
13974 [(reg 17) (const_int 0)]))
13975 (parallel [(set (match_operand 3 "q_regs_operand" "")
13976 (zero_extend (match_dup 1)))
13977 (clobber (reg:CC 17))])]
13978 "(peep2_reg_dead_p (3, operands[1])
13979 || operands_match_p (operands[1], operands[3]))
13980 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13981 [(set (match_dup 4) (match_dup 0))
13982 (set (strict_low_part (match_dup 5))
13983 (match_dup 2))]
13984 {
13985 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13986 operands[5] = gen_lowpart (QImode, operands[3]);
13987 ix86_expand_clear (operands[3]);
13988 })
13989 \f
13990 ;; Call instructions.
13991
13992 ;; The predicates normally associated with named expanders are not properly
13993 ;; checked for calls. This is a bug in the generic code, but it isn't that
13994 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13995
13996 ;; Call subroutine returning no value.
13997
13998 (define_expand "call_pop"
13999 [(parallel [(call (match_operand:QI 0 "" "")
14000 (match_operand:SI 1 "" ""))
14001 (set (reg:SI 7)
14002 (plus:SI (reg:SI 7)
14003 (match_operand:SI 3 "" "")))])]
14004 "!TARGET_64BIT"
14005 {
14006 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14007 DONE;
14008 })
14009
14010 (define_insn "*call_pop_0"
14011 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14012 (match_operand:SI 1 "" ""))
14013 (set (reg:SI 7) (plus:SI (reg:SI 7)
14014 (match_operand:SI 2 "immediate_operand" "")))]
14015 "!TARGET_64BIT"
14016 {
14017 if (SIBLING_CALL_P (insn))
14018 return "jmp\t%P0";
14019 else
14020 return "call\t%P0";
14021 }
14022 [(set_attr "type" "call")])
14023
14024 (define_insn "*call_pop_1"
14025 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14026 (match_operand:SI 1 "" ""))
14027 (set (reg:SI 7) (plus:SI (reg:SI 7)
14028 (match_operand:SI 2 "immediate_operand" "i")))]
14029 "!TARGET_64BIT"
14030 {
14031 if (constant_call_address_operand (operands[0], Pmode))
14032 {
14033 if (SIBLING_CALL_P (insn))
14034 return "jmp\t%P0";
14035 else
14036 return "call\t%P0";
14037 }
14038 if (SIBLING_CALL_P (insn))
14039 return "jmp\t%A0";
14040 else
14041 return "call\t%A0";
14042 }
14043 [(set_attr "type" "call")])
14044
14045 (define_expand "call"
14046 [(call (match_operand:QI 0 "" "")
14047 (match_operand 1 "" ""))
14048 (use (match_operand 2 "" ""))]
14049 ""
14050 {
14051 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14052 DONE;
14053 })
14054
14055 (define_expand "sibcall"
14056 [(call (match_operand:QI 0 "" "")
14057 (match_operand 1 "" ""))
14058 (use (match_operand 2 "" ""))]
14059 ""
14060 {
14061 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14062 DONE;
14063 })
14064
14065 (define_insn "*call_0"
14066 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14067 (match_operand 1 "" ""))]
14068 ""
14069 {
14070 if (SIBLING_CALL_P (insn))
14071 return "jmp\t%P0";
14072 else
14073 return "call\t%P0";
14074 }
14075 [(set_attr "type" "call")])
14076
14077 (define_insn "*call_1"
14078 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14079 (match_operand 1 "" ""))]
14080 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14081 {
14082 if (constant_call_address_operand (operands[0], QImode))
14083 return "call\t%P0";
14084 return "call\t%A0";
14085 }
14086 [(set_attr "type" "call")])
14087
14088 (define_insn "*sibcall_1"
14089 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14090 (match_operand 1 "" ""))]
14091 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14092 {
14093 if (constant_call_address_operand (operands[0], QImode))
14094 return "jmp\t%P0";
14095 return "jmp\t%A0";
14096 }
14097 [(set_attr "type" "call")])
14098
14099 (define_insn "*call_1_rex64"
14100 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14101 (match_operand 1 "" ""))]
14102 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14103 {
14104 if (constant_call_address_operand (operands[0], QImode))
14105 return "call\t%P0";
14106 return "call\t%A0";
14107 }
14108 [(set_attr "type" "call")])
14109
14110 (define_insn "*sibcall_1_rex64"
14111 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14112 (match_operand 1 "" ""))]
14113 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14114 "jmp\t%P0"
14115 [(set_attr "type" "call")])
14116
14117 (define_insn "*sibcall_1_rex64_v"
14118 [(call (mem:QI (reg:DI 40))
14119 (match_operand 0 "" ""))]
14120 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14121 "jmp\t*%%r11"
14122 [(set_attr "type" "call")])
14123
14124
14125 ;; Call subroutine, returning value in operand 0
14126
14127 (define_expand "call_value_pop"
14128 [(parallel [(set (match_operand 0 "" "")
14129 (call (match_operand:QI 1 "" "")
14130 (match_operand:SI 2 "" "")))
14131 (set (reg:SI 7)
14132 (plus:SI (reg:SI 7)
14133 (match_operand:SI 4 "" "")))])]
14134 "!TARGET_64BIT"
14135 {
14136 ix86_expand_call (operands[0], operands[1], operands[2],
14137 operands[3], operands[4], 0);
14138 DONE;
14139 })
14140
14141 (define_expand "call_value"
14142 [(set (match_operand 0 "" "")
14143 (call (match_operand:QI 1 "" "")
14144 (match_operand:SI 2 "" "")))
14145 (use (match_operand:SI 3 "" ""))]
14146 ;; Operand 2 not used on the i386.
14147 ""
14148 {
14149 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14150 DONE;
14151 })
14152
14153 (define_expand "sibcall_value"
14154 [(set (match_operand 0 "" "")
14155 (call (match_operand:QI 1 "" "")
14156 (match_operand:SI 2 "" "")))
14157 (use (match_operand:SI 3 "" ""))]
14158 ;; Operand 2 not used on the i386.
14159 ""
14160 {
14161 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14162 DONE;
14163 })
14164
14165 ;; Call subroutine returning any type.
14166
14167 (define_expand "untyped_call"
14168 [(parallel [(call (match_operand 0 "" "")
14169 (const_int 0))
14170 (match_operand 1 "" "")
14171 (match_operand 2 "" "")])]
14172 ""
14173 {
14174 int i;
14175
14176 /* In order to give reg-stack an easier job in validating two
14177 coprocessor registers as containing a possible return value,
14178 simply pretend the untyped call returns a complex long double
14179 value. */
14180
14181 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14182 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14183 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14184 NULL, 0);
14185
14186 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14187 {
14188 rtx set = XVECEXP (operands[2], 0, i);
14189 emit_move_insn (SET_DEST (set), SET_SRC (set));
14190 }
14191
14192 /* The optimizer does not know that the call sets the function value
14193 registers we stored in the result block. We avoid problems by
14194 claiming that all hard registers are used and clobbered at this
14195 point. */
14196 emit_insn (gen_blockage (const0_rtx));
14197
14198 DONE;
14199 })
14200 \f
14201 ;; Prologue and epilogue instructions
14202
14203 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14204 ;; all of memory. This blocks insns from being moved across this point.
14205
14206 (define_insn "blockage"
14207 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14208 ""
14209 ""
14210 [(set_attr "length" "0")])
14211
14212 ;; Insn emitted into the body of a function to return from a function.
14213 ;; This is only done if the function's epilogue is known to be simple.
14214 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14215
14216 (define_expand "return"
14217 [(return)]
14218 "ix86_can_use_return_insn_p ()"
14219 {
14220 if (current_function_pops_args)
14221 {
14222 rtx popc = GEN_INT (current_function_pops_args);
14223 emit_jump_insn (gen_return_pop_internal (popc));
14224 DONE;
14225 }
14226 })
14227
14228 (define_insn "return_internal"
14229 [(return)]
14230 "reload_completed"
14231 "ret"
14232 [(set_attr "length" "1")
14233 (set_attr "length_immediate" "0")
14234 (set_attr "modrm" "0")])
14235
14236 (define_insn "return_pop_internal"
14237 [(return)
14238 (use (match_operand:SI 0 "const_int_operand" ""))]
14239 "reload_completed"
14240 "ret\t%0"
14241 [(set_attr "length" "3")
14242 (set_attr "length_immediate" "2")
14243 (set_attr "modrm" "0")])
14244
14245 (define_insn "return_indirect_internal"
14246 [(return)
14247 (use (match_operand:SI 0 "register_operand" "r"))]
14248 "reload_completed"
14249 "jmp\t%A0"
14250 [(set_attr "type" "ibr")
14251 (set_attr "length_immediate" "0")])
14252
14253 (define_insn "nop"
14254 [(const_int 0)]
14255 ""
14256 "nop"
14257 [(set_attr "length" "1")
14258 (set_attr "length_immediate" "0")
14259 (set_attr "modrm" "0")
14260 (set_attr "ppro_uops" "one")])
14261
14262 (define_expand "prologue"
14263 [(const_int 1)]
14264 ""
14265 "ix86_expand_prologue (); DONE;")
14266
14267 (define_insn "set_got"
14268 [(set (match_operand:SI 0 "register_operand" "=r")
14269 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14270 (clobber (reg:CC 17))]
14271 "!TARGET_64BIT"
14272 { return output_set_got (operands[0]); }
14273 [(set_attr "type" "multi")
14274 (set_attr "length" "12")])
14275
14276 (define_expand "epilogue"
14277 [(const_int 1)]
14278 ""
14279 "ix86_expand_epilogue (1); DONE;")
14280
14281 (define_expand "sibcall_epilogue"
14282 [(const_int 1)]
14283 ""
14284 "ix86_expand_epilogue (0); DONE;")
14285
14286 (define_expand "eh_return"
14287 [(use (match_operand 0 "register_operand" ""))]
14288 ""
14289 {
14290 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14291
14292 /* Tricky bit: we write the address of the handler to which we will
14293 be returning into someone else's stack frame, one word below the
14294 stack address we wish to restore. */
14295 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14296 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14297 tmp = gen_rtx_MEM (Pmode, tmp);
14298 emit_move_insn (tmp, ra);
14299
14300 if (Pmode == SImode)
14301 emit_insn (gen_eh_return_si (sa));
14302 else
14303 emit_insn (gen_eh_return_di (sa));
14304 emit_barrier ();
14305 DONE;
14306 })
14307
14308 (define_insn_and_split "eh_return_si"
14309 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14310 UNSPECV_EH_RETURN)]
14311 "!TARGET_64BIT"
14312 "#"
14313 "reload_completed"
14314 [(const_int 1)]
14315 "ix86_expand_epilogue (2); DONE;")
14316
14317 (define_insn_and_split "eh_return_di"
14318 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14319 UNSPECV_EH_RETURN)]
14320 "TARGET_64BIT"
14321 "#"
14322 "reload_completed"
14323 [(const_int 1)]
14324 "ix86_expand_epilogue (2); DONE;")
14325
14326 (define_insn "leave"
14327 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14328 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14329 (clobber (mem:BLK (scratch)))]
14330 "!TARGET_64BIT"
14331 "leave"
14332 [(set_attr "type" "leave")])
14333
14334 (define_insn "leave_rex64"
14335 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14336 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14337 (clobber (mem:BLK (scratch)))]
14338 "TARGET_64BIT"
14339 "leave"
14340 [(set_attr "type" "leave")])
14341 \f
14342 (define_expand "ffssi2"
14343 [(parallel
14344 [(set (match_operand:SI 0 "register_operand" "")
14345 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14346 (clobber (match_scratch:SI 2 ""))
14347 (clobber (reg:CC 17))])]
14348 ""
14349 "")
14350
14351 (define_insn_and_split "*ffs_cmove"
14352 [(set (match_operand:SI 0 "register_operand" "=r")
14353 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14354 (clobber (match_scratch:SI 2 "=&r"))
14355 (clobber (reg:CC 17))]
14356 "TARGET_CMOVE"
14357 "#"
14358 "&& reload_completed"
14359 [(set (match_dup 2) (const_int -1))
14360 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14361 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14362 (set (match_dup 0) (if_then_else:SI
14363 (eq (reg:CCZ 17) (const_int 0))
14364 (match_dup 2)
14365 (match_dup 0)))
14366 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14367 (clobber (reg:CC 17))])]
14368 "")
14369
14370 (define_insn_and_split "*ffs_no_cmove"
14371 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14372 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14373 (clobber (match_scratch:SI 2 "=&r"))
14374 (clobber (reg:CC 17))]
14375 ""
14376 "#"
14377 "reload_completed"
14378 [(parallel [(set (match_dup 2) (const_int 0))
14379 (clobber (reg:CC 17))])
14380 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14381 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14382 (set (strict_low_part (match_dup 3))
14383 (eq:QI (reg:CCZ 17) (const_int 0)))
14384 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14385 (clobber (reg:CC 17))])
14386 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14387 (clobber (reg:CC 17))])
14388 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14389 (clobber (reg:CC 17))])]
14390 {
14391 operands[3] = gen_lowpart (QImode, operands[2]);
14392 })
14393
14394 (define_insn "*ffssi_1"
14395 [(set (reg:CCZ 17)
14396 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14397 (const_int 0)))
14398 (set (match_operand:SI 0 "register_operand" "=r")
14399 (ctz:SI (match_dup 1)))]
14400 ""
14401 "bsf{l}\t{%1, %0|%0, %1}"
14402 [(set_attr "prefix_0f" "1")
14403 (set_attr "ppro_uops" "few")])
14404
14405 (define_insn "ctzsi2"
14406 [(set (match_operand:SI 0 "register_operand" "=r")
14407 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14408 (clobber (reg:CC 17))]
14409 ""
14410 "bsf{l}\t{%1, %0|%0, %1}"
14411 [(set_attr "prefix_0f" "1")
14412 (set_attr "ppro_uops" "few")])
14413
14414 (define_expand "clzsi2"
14415 [(parallel
14416 [(set (match_operand:SI 0 "register_operand" "")
14417 (minus:SI (const_int 31)
14418 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14419 (clobber (reg:CC 17))])
14420 (parallel
14421 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14422 (clobber (reg:CC 17))])]
14423 ""
14424 "")
14425
14426 (define_insn "*bsr"
14427 [(set (match_operand:SI 0 "register_operand" "=r")
14428 (minus:SI (const_int 31)
14429 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14430 (clobber (reg:CC 17))]
14431 ""
14432 "bsr{l}\t{%1, %0|%0, %1}"
14433 [(set_attr "prefix_0f" "1")
14434 (set_attr "ppro_uops" "few")])
14435 \f
14436 ;; Thread-local storage patterns for ELF.
14437 ;;
14438 ;; Note that these code sequences must appear exactly as shown
14439 ;; in order to allow linker relaxation.
14440
14441 (define_insn "*tls_global_dynamic_32_gnu"
14442 [(set (match_operand:SI 0 "register_operand" "=a")
14443 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14444 (match_operand:SI 2 "tls_symbolic_operand" "")
14445 (match_operand:SI 3 "call_insn_operand" "")]
14446 UNSPEC_TLS_GD))
14447 (clobber (match_scratch:SI 4 "=d"))
14448 (clobber (match_scratch:SI 5 "=c"))
14449 (clobber (reg:CC 17))]
14450 "!TARGET_64BIT && TARGET_GNU_TLS"
14451 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14452 [(set_attr "type" "multi")
14453 (set_attr "length" "12")])
14454
14455 (define_insn "*tls_global_dynamic_32_sun"
14456 [(set (match_operand:SI 0 "register_operand" "=a")
14457 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14458 (match_operand:SI 2 "tls_symbolic_operand" "")
14459 (match_operand:SI 3 "call_insn_operand" "")]
14460 UNSPEC_TLS_GD))
14461 (clobber (match_scratch:SI 4 "=d"))
14462 (clobber (match_scratch:SI 5 "=c"))
14463 (clobber (reg:CC 17))]
14464 "!TARGET_64BIT && TARGET_SUN_TLS"
14465 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14466 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14467 [(set_attr "type" "multi")
14468 (set_attr "length" "14")])
14469
14470 (define_expand "tls_global_dynamic_32"
14471 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14472 (unspec:SI
14473 [(match_dup 2)
14474 (match_operand:SI 1 "tls_symbolic_operand" "")
14475 (match_dup 3)]
14476 UNSPEC_TLS_GD))
14477 (clobber (match_scratch:SI 4 ""))
14478 (clobber (match_scratch:SI 5 ""))
14479 (clobber (reg:CC 17))])]
14480 ""
14481 {
14482 if (flag_pic)
14483 operands[2] = pic_offset_table_rtx;
14484 else
14485 {
14486 operands[2] = gen_reg_rtx (Pmode);
14487 emit_insn (gen_set_got (operands[2]));
14488 }
14489 operands[3] = ix86_tls_get_addr ();
14490 })
14491
14492 (define_insn "*tls_global_dynamic_64"
14493 [(set (match_operand:DI 0 "register_operand" "=a")
14494 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14495 (match_operand:DI 3 "" "")))
14496 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14497 UNSPEC_TLS_GD)]
14498 "TARGET_64BIT"
14499 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14500 [(set_attr "type" "multi")
14501 (set_attr "length" "16")])
14502
14503 (define_expand "tls_global_dynamic_64"
14504 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14505 (call (mem:QI (match_dup 2)) (const_int 0)))
14506 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14507 UNSPEC_TLS_GD)])]
14508 ""
14509 {
14510 operands[2] = ix86_tls_get_addr ();
14511 })
14512
14513 (define_insn "*tls_local_dynamic_base_32_gnu"
14514 [(set (match_operand:SI 0 "register_operand" "=a")
14515 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14516 (match_operand:SI 2 "call_insn_operand" "")]
14517 UNSPEC_TLS_LD_BASE))
14518 (clobber (match_scratch:SI 3 "=d"))
14519 (clobber (match_scratch:SI 4 "=c"))
14520 (clobber (reg:CC 17))]
14521 "!TARGET_64BIT && TARGET_GNU_TLS"
14522 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14523 [(set_attr "type" "multi")
14524 (set_attr "length" "11")])
14525
14526 (define_insn "*tls_local_dynamic_base_32_sun"
14527 [(set (match_operand:SI 0 "register_operand" "=a")
14528 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14529 (match_operand:SI 2 "call_insn_operand" "")]
14530 UNSPEC_TLS_LD_BASE))
14531 (clobber (match_scratch:SI 3 "=d"))
14532 (clobber (match_scratch:SI 4 "=c"))
14533 (clobber (reg:CC 17))]
14534 "!TARGET_64BIT && TARGET_SUN_TLS"
14535 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14536 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14537 [(set_attr "type" "multi")
14538 (set_attr "length" "13")])
14539
14540 (define_expand "tls_local_dynamic_base_32"
14541 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14542 (unspec:SI [(match_dup 1) (match_dup 2)]
14543 UNSPEC_TLS_LD_BASE))
14544 (clobber (match_scratch:SI 3 ""))
14545 (clobber (match_scratch:SI 4 ""))
14546 (clobber (reg:CC 17))])]
14547 ""
14548 {
14549 if (flag_pic)
14550 operands[1] = pic_offset_table_rtx;
14551 else
14552 {
14553 operands[1] = gen_reg_rtx (Pmode);
14554 emit_insn (gen_set_got (operands[1]));
14555 }
14556 operands[2] = ix86_tls_get_addr ();
14557 })
14558
14559 (define_insn "*tls_local_dynamic_base_64"
14560 [(set (match_operand:DI 0 "register_operand" "=a")
14561 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14562 (match_operand:DI 2 "" "")))
14563 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14564 "TARGET_64BIT"
14565 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14566 [(set_attr "type" "multi")
14567 (set_attr "length" "12")])
14568
14569 (define_expand "tls_local_dynamic_base_64"
14570 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14571 (call (mem:QI (match_dup 1)) (const_int 0)))
14572 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14573 ""
14574 {
14575 operands[1] = ix86_tls_get_addr ();
14576 })
14577
14578 ;; Local dynamic of a single variable is a lose. Show combine how
14579 ;; to convert that back to global dynamic.
14580
14581 (define_insn_and_split "*tls_local_dynamic_32_once"
14582 [(set (match_operand:SI 0 "register_operand" "=a")
14583 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14584 (match_operand:SI 2 "call_insn_operand" "")]
14585 UNSPEC_TLS_LD_BASE)
14586 (const:SI (unspec:SI
14587 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14588 UNSPEC_DTPOFF))))
14589 (clobber (match_scratch:SI 4 "=d"))
14590 (clobber (match_scratch:SI 5 "=c"))
14591 (clobber (reg:CC 17))]
14592 ""
14593 "#"
14594 ""
14595 [(parallel [(set (match_dup 0)
14596 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14597 UNSPEC_TLS_GD))
14598 (clobber (match_dup 4))
14599 (clobber (match_dup 5))
14600 (clobber (reg:CC 17))])]
14601 "")
14602 \f
14603 ;; These patterns match the binary 387 instructions for addM3, subM3,
14604 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14605 ;; SFmode. The first is the normal insn, the second the same insn but
14606 ;; with one operand a conversion, and the third the same insn but with
14607 ;; the other operand a conversion. The conversion may be SFmode or
14608 ;; SImode if the target mode DFmode, but only SImode if the target mode
14609 ;; is SFmode.
14610
14611 ;; Gcc is slightly more smart about handling normal two address instructions
14612 ;; so use special patterns for add and mull.
14613 (define_insn "*fop_sf_comm_nosse"
14614 [(set (match_operand:SF 0 "register_operand" "=f")
14615 (match_operator:SF 3 "binary_fp_operator"
14616 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14617 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14618 "TARGET_80387 && !TARGET_SSE_MATH
14619 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14620 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14621 "* return output_387_binary_op (insn, operands);"
14622 [(set (attr "type")
14623 (if_then_else (match_operand:SF 3 "mult_operator" "")
14624 (const_string "fmul")
14625 (const_string "fop")))
14626 (set_attr "mode" "SF")])
14627
14628 (define_insn "*fop_sf_comm"
14629 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14630 (match_operator:SF 3 "binary_fp_operator"
14631 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14632 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14633 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14634 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14635 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14636 "* return output_387_binary_op (insn, operands);"
14637 [(set (attr "type")
14638 (if_then_else (eq_attr "alternative" "1")
14639 (if_then_else (match_operand:SF 3 "mult_operator" "")
14640 (const_string "ssemul")
14641 (const_string "sseadd"))
14642 (if_then_else (match_operand:SF 3 "mult_operator" "")
14643 (const_string "fmul")
14644 (const_string "fop"))))
14645 (set_attr "mode" "SF")])
14646
14647 (define_insn "*fop_sf_comm_sse"
14648 [(set (match_operand:SF 0 "register_operand" "=x")
14649 (match_operator:SF 3 "binary_fp_operator"
14650 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14651 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14652 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14653 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14654 "* return output_387_binary_op (insn, operands);"
14655 [(set (attr "type")
14656 (if_then_else (match_operand:SF 3 "mult_operator" "")
14657 (const_string "ssemul")
14658 (const_string "sseadd")))
14659 (set_attr "mode" "SF")])
14660
14661 (define_insn "*fop_df_comm_nosse"
14662 [(set (match_operand:DF 0 "register_operand" "=f")
14663 (match_operator:DF 3 "binary_fp_operator"
14664 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14665 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14666 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14667 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14668 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14669 "* return output_387_binary_op (insn, operands);"
14670 [(set (attr "type")
14671 (if_then_else (match_operand:SF 3 "mult_operator" "")
14672 (const_string "fmul")
14673 (const_string "fop")))
14674 (set_attr "mode" "DF")])
14675
14676 (define_insn "*fop_df_comm"
14677 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14678 (match_operator:DF 3 "binary_fp_operator"
14679 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14680 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14681 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14682 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14683 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14684 "* return output_387_binary_op (insn, operands);"
14685 [(set (attr "type")
14686 (if_then_else (eq_attr "alternative" "1")
14687 (if_then_else (match_operand:SF 3 "mult_operator" "")
14688 (const_string "ssemul")
14689 (const_string "sseadd"))
14690 (if_then_else (match_operand:SF 3 "mult_operator" "")
14691 (const_string "fmul")
14692 (const_string "fop"))))
14693 (set_attr "mode" "DF")])
14694
14695 (define_insn "*fop_df_comm_sse"
14696 [(set (match_operand:DF 0 "register_operand" "=Y")
14697 (match_operator:DF 3 "binary_fp_operator"
14698 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14699 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14700 "TARGET_SSE2 && TARGET_SSE_MATH
14701 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14702 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14703 "* return output_387_binary_op (insn, operands);"
14704 [(set (attr "type")
14705 (if_then_else (match_operand:SF 3 "mult_operator" "")
14706 (const_string "ssemul")
14707 (const_string "sseadd")))
14708 (set_attr "mode" "DF")])
14709
14710 (define_insn "*fop_xf_comm"
14711 [(set (match_operand:XF 0 "register_operand" "=f")
14712 (match_operator:XF 3 "binary_fp_operator"
14713 [(match_operand:XF 1 "register_operand" "%0")
14714 (match_operand:XF 2 "register_operand" "f")]))]
14715 "!TARGET_64BIT && TARGET_80387
14716 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14717 "* return output_387_binary_op (insn, operands);"
14718 [(set (attr "type")
14719 (if_then_else (match_operand:XF 3 "mult_operator" "")
14720 (const_string "fmul")
14721 (const_string "fop")))
14722 (set_attr "mode" "XF")])
14723
14724 (define_insn "*fop_tf_comm"
14725 [(set (match_operand:TF 0 "register_operand" "=f")
14726 (match_operator:TF 3 "binary_fp_operator"
14727 [(match_operand:TF 1 "register_operand" "%0")
14728 (match_operand:TF 2 "register_operand" "f")]))]
14729 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14730 "* return output_387_binary_op (insn, operands);"
14731 [(set (attr "type")
14732 (if_then_else (match_operand:TF 3 "mult_operator" "")
14733 (const_string "fmul")
14734 (const_string "fop")))
14735 (set_attr "mode" "XF")])
14736
14737 (define_insn "*fop_sf_1_nosse"
14738 [(set (match_operand:SF 0 "register_operand" "=f,f")
14739 (match_operator:SF 3 "binary_fp_operator"
14740 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14741 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14742 "TARGET_80387 && !TARGET_SSE_MATH
14743 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14744 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14745 "* return output_387_binary_op (insn, operands);"
14746 [(set (attr "type")
14747 (cond [(match_operand:SF 3 "mult_operator" "")
14748 (const_string "fmul")
14749 (match_operand:SF 3 "div_operator" "")
14750 (const_string "fdiv")
14751 ]
14752 (const_string "fop")))
14753 (set_attr "mode" "SF")])
14754
14755 (define_insn "*fop_sf_1"
14756 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14757 (match_operator:SF 3 "binary_fp_operator"
14758 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14759 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14760 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14761 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14762 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14763 "* return output_387_binary_op (insn, operands);"
14764 [(set (attr "type")
14765 (cond [(and (eq_attr "alternative" "2")
14766 (match_operand:SF 3 "mult_operator" ""))
14767 (const_string "ssemul")
14768 (and (eq_attr "alternative" "2")
14769 (match_operand:SF 3 "div_operator" ""))
14770 (const_string "ssediv")
14771 (eq_attr "alternative" "2")
14772 (const_string "sseadd")
14773 (match_operand:SF 3 "mult_operator" "")
14774 (const_string "fmul")
14775 (match_operand:SF 3 "div_operator" "")
14776 (const_string "fdiv")
14777 ]
14778 (const_string "fop")))
14779 (set_attr "mode" "SF")])
14780
14781 (define_insn "*fop_sf_1_sse"
14782 [(set (match_operand:SF 0 "register_operand" "=x")
14783 (match_operator:SF 3 "binary_fp_operator"
14784 [(match_operand:SF 1 "register_operand" "0")
14785 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14786 "TARGET_SSE_MATH
14787 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14788 "* return output_387_binary_op (insn, operands);"
14789 [(set (attr "type")
14790 (cond [(match_operand:SF 3 "mult_operator" "")
14791 (const_string "ssemul")
14792 (match_operand:SF 3 "div_operator" "")
14793 (const_string "ssediv")
14794 ]
14795 (const_string "sseadd")))
14796 (set_attr "mode" "SF")])
14797
14798 ;; ??? Add SSE splitters for these!
14799 (define_insn "*fop_sf_2"
14800 [(set (match_operand:SF 0 "register_operand" "=f,f")
14801 (match_operator:SF 3 "binary_fp_operator"
14802 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14803 (match_operand:SF 2 "register_operand" "0,0")]))]
14804 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14805 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14806 [(set (attr "type")
14807 (cond [(match_operand:SF 3 "mult_operator" "")
14808 (const_string "fmul")
14809 (match_operand:SF 3 "div_operator" "")
14810 (const_string "fdiv")
14811 ]
14812 (const_string "fop")))
14813 (set_attr "fp_int_src" "true")
14814 (set_attr "ppro_uops" "many")
14815 (set_attr "mode" "SI")])
14816
14817 (define_insn "*fop_sf_3"
14818 [(set (match_operand:SF 0 "register_operand" "=f,f")
14819 (match_operator:SF 3 "binary_fp_operator"
14820 [(match_operand:SF 1 "register_operand" "0,0")
14821 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14822 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14823 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14824 [(set (attr "type")
14825 (cond [(match_operand:SF 3 "mult_operator" "")
14826 (const_string "fmul")
14827 (match_operand:SF 3 "div_operator" "")
14828 (const_string "fdiv")
14829 ]
14830 (const_string "fop")))
14831 (set_attr "fp_int_src" "true")
14832 (set_attr "ppro_uops" "many")
14833 (set_attr "mode" "SI")])
14834
14835 (define_insn "*fop_df_1_nosse"
14836 [(set (match_operand:DF 0 "register_operand" "=f,f")
14837 (match_operator:DF 3 "binary_fp_operator"
14838 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14839 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14840 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14841 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14842 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14843 "* return output_387_binary_op (insn, operands);"
14844 [(set (attr "type")
14845 (cond [(match_operand:DF 3 "mult_operator" "")
14846 (const_string "fmul")
14847 (match_operand:DF 3 "div_operator" "")
14848 (const_string "fdiv")
14849 ]
14850 (const_string "fop")))
14851 (set_attr "mode" "DF")])
14852
14853
14854 (define_insn "*fop_df_1"
14855 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14856 (match_operator:DF 3 "binary_fp_operator"
14857 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14858 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14859 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14860 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14861 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14862 "* return output_387_binary_op (insn, operands);"
14863 [(set (attr "type")
14864 (cond [(and (eq_attr "alternative" "2")
14865 (match_operand:SF 3 "mult_operator" ""))
14866 (const_string "ssemul")
14867 (and (eq_attr "alternative" "2")
14868 (match_operand:SF 3 "div_operator" ""))
14869 (const_string "ssediv")
14870 (eq_attr "alternative" "2")
14871 (const_string "sseadd")
14872 (match_operand:DF 3 "mult_operator" "")
14873 (const_string "fmul")
14874 (match_operand:DF 3 "div_operator" "")
14875 (const_string "fdiv")
14876 ]
14877 (const_string "fop")))
14878 (set_attr "mode" "DF")])
14879
14880 (define_insn "*fop_df_1_sse"
14881 [(set (match_operand:DF 0 "register_operand" "=Y")
14882 (match_operator:DF 3 "binary_fp_operator"
14883 [(match_operand:DF 1 "register_operand" "0")
14884 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14885 "TARGET_SSE2 && TARGET_SSE_MATH
14886 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14887 "* return output_387_binary_op (insn, operands);"
14888 [(set_attr "mode" "DF")
14889 (set (attr "type")
14890 (cond [(match_operand:SF 3 "mult_operator" "")
14891 (const_string "ssemul")
14892 (match_operand:SF 3 "div_operator" "")
14893 (const_string "ssediv")
14894 ]
14895 (const_string "sseadd")))])
14896
14897 ;; ??? Add SSE splitters for these!
14898 (define_insn "*fop_df_2"
14899 [(set (match_operand:DF 0 "register_operand" "=f,f")
14900 (match_operator:DF 3 "binary_fp_operator"
14901 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14902 (match_operand:DF 2 "register_operand" "0,0")]))]
14903 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14904 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14905 [(set (attr "type")
14906 (cond [(match_operand:DF 3 "mult_operator" "")
14907 (const_string "fmul")
14908 (match_operand:DF 3 "div_operator" "")
14909 (const_string "fdiv")
14910 ]
14911 (const_string "fop")))
14912 (set_attr "fp_int_src" "true")
14913 (set_attr "ppro_uops" "many")
14914 (set_attr "mode" "SI")])
14915
14916 (define_insn "*fop_df_3"
14917 [(set (match_operand:DF 0 "register_operand" "=f,f")
14918 (match_operator:DF 3 "binary_fp_operator"
14919 [(match_operand:DF 1 "register_operand" "0,0")
14920 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14921 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14922 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14923 [(set (attr "type")
14924 (cond [(match_operand:DF 3 "mult_operator" "")
14925 (const_string "fmul")
14926 (match_operand:DF 3 "div_operator" "")
14927 (const_string "fdiv")
14928 ]
14929 (const_string "fop")))
14930 (set_attr "fp_int_src" "true")
14931 (set_attr "ppro_uops" "many")
14932 (set_attr "mode" "SI")])
14933
14934 (define_insn "*fop_df_4"
14935 [(set (match_operand:DF 0 "register_operand" "=f,f")
14936 (match_operator:DF 3 "binary_fp_operator"
14937 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14938 (match_operand:DF 2 "register_operand" "0,f")]))]
14939 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
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_5"
14952 [(set (match_operand:DF 0 "register_operand" "=f,f")
14953 (match_operator:DF 3 "binary_fp_operator"
14954 [(match_operand:DF 1 "register_operand" "0,f")
14955 (float_extend:DF
14956 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14957 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14958 "* return output_387_binary_op (insn, operands);"
14959 [(set (attr "type")
14960 (cond [(match_operand:DF 3 "mult_operator" "")
14961 (const_string "fmul")
14962 (match_operand:DF 3 "div_operator" "")
14963 (const_string "fdiv")
14964 ]
14965 (const_string "fop")))
14966 (set_attr "mode" "SF")])
14967
14968 (define_insn "*fop_df_6"
14969 [(set (match_operand:DF 0 "register_operand" "=f,f")
14970 (match_operator:DF 3 "binary_fp_operator"
14971 [(float_extend:DF
14972 (match_operand:SF 1 "register_operand" "0,f"))
14973 (float_extend:DF
14974 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14975 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14976 "* return output_387_binary_op (insn, operands);"
14977 [(set (attr "type")
14978 (cond [(match_operand:DF 3 "mult_operator" "")
14979 (const_string "fmul")
14980 (match_operand:DF 3 "div_operator" "")
14981 (const_string "fdiv")
14982 ]
14983 (const_string "fop")))
14984 (set_attr "mode" "SF")])
14985
14986 (define_insn "*fop_xf_1"
14987 [(set (match_operand:XF 0 "register_operand" "=f,f")
14988 (match_operator:XF 3 "binary_fp_operator"
14989 [(match_operand:XF 1 "register_operand" "0,f")
14990 (match_operand:XF 2 "register_operand" "f,0")]))]
14991 "!TARGET_64BIT && 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:XF 3 "mult_operator" "")
14996 (const_string "fmul")
14997 (match_operand:XF 3 "div_operator" "")
14998 (const_string "fdiv")
14999 ]
15000 (const_string "fop")))
15001 (set_attr "mode" "XF")])
15002
15003 (define_insn "*fop_tf_1"
15004 [(set (match_operand:TF 0 "register_operand" "=f,f")
15005 (match_operator:TF 3 "binary_fp_operator"
15006 [(match_operand:TF 1 "register_operand" "0,f")
15007 (match_operand:TF 2 "register_operand" "f,0")]))]
15008 "TARGET_80387
15009 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15010 "* return output_387_binary_op (insn, operands);"
15011 [(set (attr "type")
15012 (cond [(match_operand:TF 3 "mult_operator" "")
15013 (const_string "fmul")
15014 (match_operand:TF 3 "div_operator" "")
15015 (const_string "fdiv")
15016 ]
15017 (const_string "fop")))
15018 (set_attr "mode" "XF")])
15019
15020 (define_insn "*fop_xf_2"
15021 [(set (match_operand:XF 0 "register_operand" "=f,f")
15022 (match_operator:XF 3 "binary_fp_operator"
15023 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15024 (match_operand:XF 2 "register_operand" "0,0")]))]
15025 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
15026 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15027 [(set (attr "type")
15028 (cond [(match_operand:XF 3 "mult_operator" "")
15029 (const_string "fmul")
15030 (match_operand:XF 3 "div_operator" "")
15031 (const_string "fdiv")
15032 ]
15033 (const_string "fop")))
15034 (set_attr "fp_int_src" "true")
15035 (set_attr "mode" "SI")
15036 (set_attr "ppro_uops" "many")])
15037
15038 (define_insn "*fop_tf_2"
15039 [(set (match_operand:TF 0 "register_operand" "=f,f")
15040 (match_operator:TF 3 "binary_fp_operator"
15041 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15042 (match_operand:TF 2 "register_operand" "0,0")]))]
15043 "TARGET_80387 && TARGET_USE_FIOP"
15044 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15045 [(set (attr "type")
15046 (cond [(match_operand:TF 3 "mult_operator" "")
15047 (const_string "fmul")
15048 (match_operand:TF 3 "div_operator" "")
15049 (const_string "fdiv")
15050 ]
15051 (const_string "fop")))
15052 (set_attr "fp_int_src" "true")
15053 (set_attr "mode" "SI")
15054 (set_attr "ppro_uops" "many")])
15055
15056 (define_insn "*fop_xf_3"
15057 [(set (match_operand:XF 0 "register_operand" "=f,f")
15058 (match_operator:XF 3 "binary_fp_operator"
15059 [(match_operand:XF 1 "register_operand" "0,0")
15060 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15061 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
15062 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15063 [(set (attr "type")
15064 (cond [(match_operand:XF 3 "mult_operator" "")
15065 (const_string "fmul")
15066 (match_operand:XF 3 "div_operator" "")
15067 (const_string "fdiv")
15068 ]
15069 (const_string "fop")))
15070 (set_attr "fp_int_src" "true")
15071 (set_attr "mode" "SI")
15072 (set_attr "ppro_uops" "many")])
15073
15074 (define_insn "*fop_tf_3"
15075 [(set (match_operand:TF 0 "register_operand" "=f,f")
15076 (match_operator:TF 3 "binary_fp_operator"
15077 [(match_operand:TF 1 "register_operand" "0,0")
15078 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15079 "TARGET_80387 && TARGET_USE_FIOP"
15080 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15081 [(set (attr "type")
15082 (cond [(match_operand:TF 3 "mult_operator" "")
15083 (const_string "fmul")
15084 (match_operand:TF 3 "div_operator" "")
15085 (const_string "fdiv")
15086 ]
15087 (const_string "fop")))
15088 (set_attr "fp_int_src" "true")
15089 (set_attr "mode" "SI")
15090 (set_attr "ppro_uops" "many")])
15091
15092 (define_insn "*fop_xf_4"
15093 [(set (match_operand:XF 0 "register_operand" "=f,f")
15094 (match_operator:XF 3 "binary_fp_operator"
15095 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15096 (match_operand:XF 2 "register_operand" "0,f")]))]
15097 "!TARGET_64BIT && TARGET_80387"
15098 "* return output_387_binary_op (insn, operands);"
15099 [(set (attr "type")
15100 (cond [(match_operand:XF 3 "mult_operator" "")
15101 (const_string "fmul")
15102 (match_operand:XF 3 "div_operator" "")
15103 (const_string "fdiv")
15104 ]
15105 (const_string "fop")))
15106 (set_attr "mode" "SF")])
15107
15108 (define_insn "*fop_tf_4"
15109 [(set (match_operand:TF 0 "register_operand" "=f,f")
15110 (match_operator:TF 3 "binary_fp_operator"
15111 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15112 (match_operand:TF 2 "register_operand" "0,f")]))]
15113 "TARGET_80387"
15114 "* return output_387_binary_op (insn, operands);"
15115 [(set (attr "type")
15116 (cond [(match_operand:TF 3 "mult_operator" "")
15117 (const_string "fmul")
15118 (match_operand:TF 3 "div_operator" "")
15119 (const_string "fdiv")
15120 ]
15121 (const_string "fop")))
15122 (set_attr "mode" "SF")])
15123
15124 (define_insn "*fop_xf_5"
15125 [(set (match_operand:XF 0 "register_operand" "=f,f")
15126 (match_operator:XF 3 "binary_fp_operator"
15127 [(match_operand:XF 1 "register_operand" "0,f")
15128 (float_extend:XF
15129 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15130 "!TARGET_64BIT && TARGET_80387"
15131 "* return output_387_binary_op (insn, operands);"
15132 [(set (attr "type")
15133 (cond [(match_operand:XF 3 "mult_operator" "")
15134 (const_string "fmul")
15135 (match_operand:XF 3 "div_operator" "")
15136 (const_string "fdiv")
15137 ]
15138 (const_string "fop")))
15139 (set_attr "mode" "SF")])
15140
15141 (define_insn "*fop_tf_5"
15142 [(set (match_operand:TF 0 "register_operand" "=f,f")
15143 (match_operator:TF 3 "binary_fp_operator"
15144 [(match_operand:TF 1 "register_operand" "0,f")
15145 (float_extend:TF
15146 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15147 "TARGET_80387"
15148 "* return output_387_binary_op (insn, operands);"
15149 [(set (attr "type")
15150 (cond [(match_operand:TF 3 "mult_operator" "")
15151 (const_string "fmul")
15152 (match_operand:TF 3 "div_operator" "")
15153 (const_string "fdiv")
15154 ]
15155 (const_string "fop")))
15156 (set_attr "mode" "SF")])
15157
15158 (define_insn "*fop_xf_6"
15159 [(set (match_operand:XF 0 "register_operand" "=f,f")
15160 (match_operator:XF 3 "binary_fp_operator"
15161 [(float_extend:XF
15162 (match_operand 1 "register_operand" "0,f"))
15163 (float_extend:XF
15164 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15165 "!TARGET_64BIT && TARGET_80387"
15166 "* return output_387_binary_op (insn, operands);"
15167 [(set (attr "type")
15168 (cond [(match_operand:XF 3 "mult_operator" "")
15169 (const_string "fmul")
15170 (match_operand:XF 3 "div_operator" "")
15171 (const_string "fdiv")
15172 ]
15173 (const_string "fop")))
15174 (set_attr "mode" "SF")])
15175
15176 (define_insn "*fop_tf_6"
15177 [(set (match_operand:TF 0 "register_operand" "=f,f")
15178 (match_operator:TF 3 "binary_fp_operator"
15179 [(float_extend:TF
15180 (match_operand 1 "register_operand" "0,f"))
15181 (float_extend:TF
15182 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15183 "TARGET_80387"
15184 "* return output_387_binary_op (insn, operands);"
15185 [(set (attr "type")
15186 (cond [(match_operand:TF 3 "mult_operator" "")
15187 (const_string "fmul")
15188 (match_operand:TF 3 "div_operator" "")
15189 (const_string "fdiv")
15190 ]
15191 (const_string "fop")))
15192 (set_attr "mode" "SF")])
15193
15194 (define_split
15195 [(set (match_operand 0 "register_operand" "")
15196 (match_operator 3 "binary_fp_operator"
15197 [(float (match_operand:SI 1 "register_operand" ""))
15198 (match_operand 2 "register_operand" "")]))]
15199 "TARGET_80387 && reload_completed
15200 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15201 [(const_int 0)]
15202 {
15203 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15204 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15205 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15206 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15207 GET_MODE (operands[3]),
15208 operands[4],
15209 operands[2])));
15210 ix86_free_from_memory (GET_MODE (operands[1]));
15211 DONE;
15212 })
15213
15214 (define_split
15215 [(set (match_operand 0 "register_operand" "")
15216 (match_operator 3 "binary_fp_operator"
15217 [(match_operand 1 "register_operand" "")
15218 (float (match_operand:SI 2 "register_operand" ""))]))]
15219 "TARGET_80387 && reload_completed
15220 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15221 [(const_int 0)]
15222 {
15223 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15224 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15225 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15226 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15227 GET_MODE (operands[3]),
15228 operands[1],
15229 operands[4])));
15230 ix86_free_from_memory (GET_MODE (operands[2]));
15231 DONE;
15232 })
15233 \f
15234 ;; FPU special functions.
15235
15236 (define_expand "sqrtsf2"
15237 [(set (match_operand:SF 0 "register_operand" "")
15238 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15239 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15240 {
15241 if (!TARGET_SSE_MATH)
15242 operands[1] = force_reg (SFmode, operands[1]);
15243 })
15244
15245 (define_insn "sqrtsf2_1"
15246 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15247 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15248 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15249 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15250 "@
15251 fsqrt
15252 sqrtss\t{%1, %0|%0, %1}"
15253 [(set_attr "type" "fpspc,sse")
15254 (set_attr "mode" "SF,SF")
15255 (set_attr "athlon_decode" "direct,*")])
15256
15257 (define_insn "sqrtsf2_1_sse_only"
15258 [(set (match_operand:SF 0 "register_operand" "=x")
15259 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15260 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15261 "sqrtss\t{%1, %0|%0, %1}"
15262 [(set_attr "type" "sse")
15263 (set_attr "mode" "SF")
15264 (set_attr "athlon_decode" "*")])
15265
15266 (define_insn "sqrtsf2_i387"
15267 [(set (match_operand:SF 0 "register_operand" "=f")
15268 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15269 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15270 && !TARGET_SSE_MATH"
15271 "fsqrt"
15272 [(set_attr "type" "fpspc")
15273 (set_attr "mode" "SF")
15274 (set_attr "athlon_decode" "direct")])
15275
15276 (define_expand "sqrtdf2"
15277 [(set (match_operand:DF 0 "register_operand" "")
15278 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15279 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15280 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15281 {
15282 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15283 operands[1] = force_reg (DFmode, operands[1]);
15284 })
15285
15286 (define_insn "sqrtdf2_1"
15287 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15288 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15289 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15290 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15291 "@
15292 fsqrt
15293 sqrtsd\t{%1, %0|%0, %1}"
15294 [(set_attr "type" "fpspc,sse")
15295 (set_attr "mode" "DF,DF")
15296 (set_attr "athlon_decode" "direct,*")])
15297
15298 (define_insn "sqrtdf2_1_sse_only"
15299 [(set (match_operand:DF 0 "register_operand" "=Y")
15300 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15301 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15302 "sqrtsd\t{%1, %0|%0, %1}"
15303 [(set_attr "type" "sse")
15304 (set_attr "mode" "DF")
15305 (set_attr "athlon_decode" "*")])
15306
15307 (define_insn "sqrtdf2_i387"
15308 [(set (match_operand:DF 0 "register_operand" "=f")
15309 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15310 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15311 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15312 "fsqrt"
15313 [(set_attr "type" "fpspc")
15314 (set_attr "mode" "DF")
15315 (set_attr "athlon_decode" "direct")])
15316
15317 (define_insn "*sqrtextendsfdf2"
15318 [(set (match_operand:DF 0 "register_operand" "=f")
15319 (sqrt:DF (float_extend:DF
15320 (match_operand:SF 1 "register_operand" "0"))))]
15321 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15322 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15323 "fsqrt"
15324 [(set_attr "type" "fpspc")
15325 (set_attr "mode" "DF")
15326 (set_attr "athlon_decode" "direct")])
15327
15328 (define_insn "sqrtxf2"
15329 [(set (match_operand:XF 0 "register_operand" "=f")
15330 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15331 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15332 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15333 "fsqrt"
15334 [(set_attr "type" "fpspc")
15335 (set_attr "mode" "XF")
15336 (set_attr "athlon_decode" "direct")])
15337
15338 (define_insn "sqrttf2"
15339 [(set (match_operand:TF 0 "register_operand" "=f")
15340 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15341 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15342 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15343 "fsqrt"
15344 [(set_attr "type" "fpspc")
15345 (set_attr "mode" "XF")
15346 (set_attr "athlon_decode" "direct")])
15347
15348 (define_insn "*sqrtextenddfxf2"
15349 [(set (match_operand:XF 0 "register_operand" "=f")
15350 (sqrt:XF (float_extend:XF
15351 (match_operand:DF 1 "register_operand" "0"))))]
15352 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15353 "fsqrt"
15354 [(set_attr "type" "fpspc")
15355 (set_attr "mode" "XF")
15356 (set_attr "athlon_decode" "direct")])
15357
15358 (define_insn "*sqrtextenddftf2"
15359 [(set (match_operand:TF 0 "register_operand" "=f")
15360 (sqrt:TF (float_extend:TF
15361 (match_operand:DF 1 "register_operand" "0"))))]
15362 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15363 "fsqrt"
15364 [(set_attr "type" "fpspc")
15365 (set_attr "mode" "XF")
15366 (set_attr "athlon_decode" "direct")])
15367
15368 (define_insn "*sqrtextendsfxf2"
15369 [(set (match_operand:XF 0 "register_operand" "=f")
15370 (sqrt:XF (float_extend:XF
15371 (match_operand:SF 1 "register_operand" "0"))))]
15372 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15373 "fsqrt"
15374 [(set_attr "type" "fpspc")
15375 (set_attr "mode" "XF")
15376 (set_attr "athlon_decode" "direct")])
15377
15378 (define_insn "*sqrtextendsftf2"
15379 [(set (match_operand:TF 0 "register_operand" "=f")
15380 (sqrt:TF (float_extend:TF
15381 (match_operand:SF 1 "register_operand" "0"))))]
15382 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15383 "fsqrt"
15384 [(set_attr "type" "fpspc")
15385 (set_attr "mode" "XF")
15386 (set_attr "athlon_decode" "direct")])
15387
15388 (define_insn "sindf2"
15389 [(set (match_operand:DF 0 "register_operand" "=f")
15390 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15391 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15392 && flag_unsafe_math_optimizations"
15393 "fsin"
15394 [(set_attr "type" "fpspc")
15395 (set_attr "mode" "DF")])
15396
15397 (define_insn "sinsf2"
15398 [(set (match_operand:SF 0 "register_operand" "=f")
15399 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15400 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15401 && flag_unsafe_math_optimizations"
15402 "fsin"
15403 [(set_attr "type" "fpspc")
15404 (set_attr "mode" "SF")])
15405
15406 (define_insn "*sinextendsfdf2"
15407 [(set (match_operand:DF 0 "register_operand" "=f")
15408 (unspec:DF [(float_extend:DF
15409 (match_operand:SF 1 "register_operand" "0"))]
15410 UNSPEC_SIN))]
15411 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15412 && flag_unsafe_math_optimizations"
15413 "fsin"
15414 [(set_attr "type" "fpspc")
15415 (set_attr "mode" "DF")])
15416
15417 (define_insn "sinxf2"
15418 [(set (match_operand:XF 0 "register_operand" "=f")
15419 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15420 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15421 && flag_unsafe_math_optimizations"
15422 "fsin"
15423 [(set_attr "type" "fpspc")
15424 (set_attr "mode" "XF")])
15425
15426 (define_insn "sintf2"
15427 [(set (match_operand:TF 0 "register_operand" "=f")
15428 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15429 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15430 && flag_unsafe_math_optimizations"
15431 "fsin"
15432 [(set_attr "type" "fpspc")
15433 (set_attr "mode" "XF")])
15434
15435 (define_insn "cosdf2"
15436 [(set (match_operand:DF 0 "register_operand" "=f")
15437 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15438 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15439 && flag_unsafe_math_optimizations"
15440 "fcos"
15441 [(set_attr "type" "fpspc")
15442 (set_attr "mode" "DF")])
15443
15444 (define_insn "cossf2"
15445 [(set (match_operand:SF 0 "register_operand" "=f")
15446 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15447 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15448 && flag_unsafe_math_optimizations"
15449 "fcos"
15450 [(set_attr "type" "fpspc")
15451 (set_attr "mode" "SF")])
15452
15453 (define_insn "*cosextendsfdf2"
15454 [(set (match_operand:DF 0 "register_operand" "=f")
15455 (unspec:DF [(float_extend:DF
15456 (match_operand:SF 1 "register_operand" "0"))]
15457 UNSPEC_COS))]
15458 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15459 && flag_unsafe_math_optimizations"
15460 "fcos"
15461 [(set_attr "type" "fpspc")
15462 (set_attr "mode" "DF")])
15463
15464 (define_insn "cosxf2"
15465 [(set (match_operand:XF 0 "register_operand" "=f")
15466 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15467 "!TARGET_64BIT && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15468 && flag_unsafe_math_optimizations"
15469 "fcos"
15470 [(set_attr "type" "fpspc")
15471 (set_attr "mode" "XF")])
15472
15473 (define_insn "costf2"
15474 [(set (match_operand:TF 0 "register_operand" "=f")
15475 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15476 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15477 && flag_unsafe_math_optimizations"
15478 "fcos"
15479 [(set_attr "type" "fpspc")
15480 (set_attr "mode" "XF")])
15481
15482 (define_insn "atan2df3"
15483 [(set (match_operand:DF 0 "register_operand" "=f")
15484 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15485 (match_operand:DF 1 "register_operand" "u")]
15486 UNSPEC_FPATAN))]
15487 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15488 && flag_unsafe_math_optimizations"
15489 "fpatan"
15490 [(set_attr "type" "fpspc")
15491 (set_attr "mode" "DF")])
15492
15493 (define_insn "atan2sf3"
15494 [(set (match_operand:SF 0 "register_operand" "=f")
15495 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15496 (match_operand:SF 1 "register_operand" "u")]
15497 UNSPEC_FPATAN))]
15498 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15499 && flag_unsafe_math_optimizations"
15500 "fpatan"
15501 [(set_attr "type" "fpspc")
15502 (set_attr "mode" "SF")])
15503
15504 (define_insn "atan2xf3"
15505 [(set (match_operand:XF 0 "register_operand" "=f")
15506 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15507 (match_operand:XF 1 "register_operand" "u")]
15508 UNSPEC_FPATAN))]
15509 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15510 && flag_unsafe_math_optimizations"
15511 "fpatan"
15512 [(set_attr "type" "fpspc")
15513 (set_attr "mode" "XF")])
15514
15515 (define_insn "atan2tf3"
15516 [(set (match_operand:TF 0 "register_operand" "=f")
15517 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15518 (match_operand:TF 1 "register_operand" "u")]
15519 UNSPEC_FPATAN))]
15520 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15521 && flag_unsafe_math_optimizations"
15522 "fpatan"
15523 [(set_attr "type" "fpspc")
15524 (set_attr "mode" "XF")])
15525 \f
15526 ;; Block operation instructions
15527
15528 (define_insn "cld"
15529 [(set (reg:SI 19) (const_int 0))]
15530 ""
15531 "cld"
15532 [(set_attr "type" "cld")])
15533
15534 (define_expand "movstrsi"
15535 [(use (match_operand:BLK 0 "memory_operand" ""))
15536 (use (match_operand:BLK 1 "memory_operand" ""))
15537 (use (match_operand:SI 2 "nonmemory_operand" ""))
15538 (use (match_operand:SI 3 "const_int_operand" ""))]
15539 ""
15540 {
15541 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15542 DONE;
15543 else
15544 FAIL;
15545 })
15546
15547 (define_expand "movstrdi"
15548 [(use (match_operand:BLK 0 "memory_operand" ""))
15549 (use (match_operand:BLK 1 "memory_operand" ""))
15550 (use (match_operand:DI 2 "nonmemory_operand" ""))
15551 (use (match_operand:DI 3 "const_int_operand" ""))]
15552 "TARGET_64BIT"
15553 {
15554 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15555 DONE;
15556 else
15557 FAIL;
15558 })
15559
15560 ;; Most CPUs don't like single string operations
15561 ;; Handle this case here to simplify previous expander.
15562
15563 (define_expand "strmovdi_rex64"
15564 [(set (match_dup 2)
15565 (mem:DI (match_operand:DI 1 "register_operand" "")))
15566 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15567 (match_dup 2))
15568 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15569 (clobber (reg:CC 17))])
15570 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15571 (clobber (reg:CC 17))])]
15572 "TARGET_64BIT"
15573 {
15574 if (TARGET_SINGLE_STRINGOP || optimize_size)
15575 {
15576 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15577 operands[1]));
15578 DONE;
15579 }
15580 else
15581 operands[2] = gen_reg_rtx (DImode);
15582 })
15583
15584
15585 (define_expand "strmovsi"
15586 [(set (match_dup 2)
15587 (mem:SI (match_operand:SI 1 "register_operand" "")))
15588 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15589 (match_dup 2))
15590 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15591 (clobber (reg:CC 17))])
15592 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15593 (clobber (reg:CC 17))])]
15594 ""
15595 {
15596 if (TARGET_64BIT)
15597 {
15598 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15599 DONE;
15600 }
15601 if (TARGET_SINGLE_STRINGOP || optimize_size)
15602 {
15603 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15604 operands[1]));
15605 DONE;
15606 }
15607 else
15608 operands[2] = gen_reg_rtx (SImode);
15609 })
15610
15611 (define_expand "strmovsi_rex64"
15612 [(set (match_dup 2)
15613 (mem:SI (match_operand:DI 1 "register_operand" "")))
15614 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15615 (match_dup 2))
15616 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15617 (clobber (reg:CC 17))])
15618 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15619 (clobber (reg:CC 17))])]
15620 "TARGET_64BIT"
15621 {
15622 if (TARGET_SINGLE_STRINGOP || optimize_size)
15623 {
15624 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15625 operands[1]));
15626 DONE;
15627 }
15628 else
15629 operands[2] = gen_reg_rtx (SImode);
15630 })
15631
15632 (define_expand "strmovhi"
15633 [(set (match_dup 2)
15634 (mem:HI (match_operand:SI 1 "register_operand" "")))
15635 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15636 (match_dup 2))
15637 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15638 (clobber (reg:CC 17))])
15639 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15640 (clobber (reg:CC 17))])]
15641 ""
15642 {
15643 if (TARGET_64BIT)
15644 {
15645 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15646 DONE;
15647 }
15648 if (TARGET_SINGLE_STRINGOP || optimize_size)
15649 {
15650 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15651 operands[1]));
15652 DONE;
15653 }
15654 else
15655 operands[2] = gen_reg_rtx (HImode);
15656 })
15657
15658 (define_expand "strmovhi_rex64"
15659 [(set (match_dup 2)
15660 (mem:HI (match_operand:DI 1 "register_operand" "")))
15661 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15662 (match_dup 2))
15663 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15664 (clobber (reg:CC 17))])
15665 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15666 (clobber (reg:CC 17))])]
15667 "TARGET_64BIT"
15668 {
15669 if (TARGET_SINGLE_STRINGOP || optimize_size)
15670 {
15671 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15672 operands[1]));
15673 DONE;
15674 }
15675 else
15676 operands[2] = gen_reg_rtx (HImode);
15677 })
15678
15679 (define_expand "strmovqi"
15680 [(set (match_dup 2)
15681 (mem:QI (match_operand:SI 1 "register_operand" "")))
15682 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15683 (match_dup 2))
15684 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15685 (clobber (reg:CC 17))])
15686 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15687 (clobber (reg:CC 17))])]
15688 ""
15689 {
15690 if (TARGET_64BIT)
15691 {
15692 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15693 DONE;
15694 }
15695 if (TARGET_SINGLE_STRINGOP || optimize_size)
15696 {
15697 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15698 operands[1]));
15699 DONE;
15700 }
15701 else
15702 operands[2] = gen_reg_rtx (QImode);
15703 })
15704
15705 (define_expand "strmovqi_rex64"
15706 [(set (match_dup 2)
15707 (mem:QI (match_operand:DI 1 "register_operand" "")))
15708 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15709 (match_dup 2))
15710 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15711 (clobber (reg:CC 17))])
15712 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15713 (clobber (reg:CC 17))])]
15714 "TARGET_64BIT"
15715 {
15716 if (TARGET_SINGLE_STRINGOP || optimize_size)
15717 {
15718 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15719 operands[1]));
15720 DONE;
15721 }
15722 else
15723 operands[2] = gen_reg_rtx (QImode);
15724 })
15725
15726 (define_insn "strmovdi_rex_1"
15727 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15728 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15729 (set (match_operand:DI 0 "register_operand" "=D")
15730 (plus:DI (match_dup 2)
15731 (const_int 8)))
15732 (set (match_operand:DI 1 "register_operand" "=S")
15733 (plus:DI (match_dup 3)
15734 (const_int 8)))
15735 (use (reg:SI 19))]
15736 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15737 "movsq"
15738 [(set_attr "type" "str")
15739 (set_attr "mode" "DI")
15740 (set_attr "memory" "both")])
15741
15742 (define_insn "strmovsi_1"
15743 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15744 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15745 (set (match_operand:SI 0 "register_operand" "=D")
15746 (plus:SI (match_dup 2)
15747 (const_int 4)))
15748 (set (match_operand:SI 1 "register_operand" "=S")
15749 (plus:SI (match_dup 3)
15750 (const_int 4)))
15751 (use (reg:SI 19))]
15752 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15753 "{movsl|movsd}"
15754 [(set_attr "type" "str")
15755 (set_attr "mode" "SI")
15756 (set_attr "memory" "both")])
15757
15758 (define_insn "strmovsi_rex_1"
15759 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15760 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15761 (set (match_operand:DI 0 "register_operand" "=D")
15762 (plus:DI (match_dup 2)
15763 (const_int 4)))
15764 (set (match_operand:DI 1 "register_operand" "=S")
15765 (plus:DI (match_dup 3)
15766 (const_int 4)))
15767 (use (reg:SI 19))]
15768 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15769 "{movsl|movsd}"
15770 [(set_attr "type" "str")
15771 (set_attr "mode" "SI")
15772 (set_attr "memory" "both")])
15773
15774 (define_insn "strmovhi_1"
15775 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15776 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15777 (set (match_operand:SI 0 "register_operand" "=D")
15778 (plus:SI (match_dup 2)
15779 (const_int 2)))
15780 (set (match_operand:SI 1 "register_operand" "=S")
15781 (plus:SI (match_dup 3)
15782 (const_int 2)))
15783 (use (reg:SI 19))]
15784 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15785 "movsw"
15786 [(set_attr "type" "str")
15787 (set_attr "memory" "both")
15788 (set_attr "mode" "HI")])
15789
15790 (define_insn "strmovhi_rex_1"
15791 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15792 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15793 (set (match_operand:DI 0 "register_operand" "=D")
15794 (plus:DI (match_dup 2)
15795 (const_int 2)))
15796 (set (match_operand:DI 1 "register_operand" "=S")
15797 (plus:DI (match_dup 3)
15798 (const_int 2)))
15799 (use (reg:SI 19))]
15800 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15801 "movsw"
15802 [(set_attr "type" "str")
15803 (set_attr "memory" "both")
15804 (set_attr "mode" "HI")])
15805
15806 (define_insn "strmovqi_1"
15807 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15808 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15809 (set (match_operand:SI 0 "register_operand" "=D")
15810 (plus:SI (match_dup 2)
15811 (const_int 1)))
15812 (set (match_operand:SI 1 "register_operand" "=S")
15813 (plus:SI (match_dup 3)
15814 (const_int 1)))
15815 (use (reg:SI 19))]
15816 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15817 "movsb"
15818 [(set_attr "type" "str")
15819 (set_attr "memory" "both")
15820 (set_attr "mode" "QI")])
15821
15822 (define_insn "strmovqi_rex_1"
15823 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15824 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15825 (set (match_operand:DI 0 "register_operand" "=D")
15826 (plus:DI (match_dup 2)
15827 (const_int 1)))
15828 (set (match_operand:DI 1 "register_operand" "=S")
15829 (plus:DI (match_dup 3)
15830 (const_int 1)))
15831 (use (reg:SI 19))]
15832 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15833 "movsb"
15834 [(set_attr "type" "str")
15835 (set_attr "memory" "both")
15836 (set_attr "mode" "QI")])
15837
15838 (define_insn "rep_movdi_rex64"
15839 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15840 (set (match_operand:DI 0 "register_operand" "=D")
15841 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15842 (const_int 3))
15843 (match_operand:DI 3 "register_operand" "0")))
15844 (set (match_operand:DI 1 "register_operand" "=S")
15845 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15846 (match_operand:DI 4 "register_operand" "1")))
15847 (set (mem:BLK (match_dup 3))
15848 (mem:BLK (match_dup 4)))
15849 (use (match_dup 5))
15850 (use (reg:SI 19))]
15851 "TARGET_64BIT"
15852 "{rep\;movsq|rep movsq}"
15853 [(set_attr "type" "str")
15854 (set_attr "prefix_rep" "1")
15855 (set_attr "memory" "both")
15856 (set_attr "mode" "DI")])
15857
15858 (define_insn "rep_movsi"
15859 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15860 (set (match_operand:SI 0 "register_operand" "=D")
15861 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15862 (const_int 2))
15863 (match_operand:SI 3 "register_operand" "0")))
15864 (set (match_operand:SI 1 "register_operand" "=S")
15865 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15866 (match_operand:SI 4 "register_operand" "1")))
15867 (set (mem:BLK (match_dup 3))
15868 (mem:BLK (match_dup 4)))
15869 (use (match_dup 5))
15870 (use (reg:SI 19))]
15871 "!TARGET_64BIT"
15872 "{rep\;movsl|rep movsd}"
15873 [(set_attr "type" "str")
15874 (set_attr "prefix_rep" "1")
15875 (set_attr "memory" "both")
15876 (set_attr "mode" "SI")])
15877
15878 (define_insn "rep_movsi_rex64"
15879 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15880 (set (match_operand:DI 0 "register_operand" "=D")
15881 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15882 (const_int 2))
15883 (match_operand:DI 3 "register_operand" "0")))
15884 (set (match_operand:DI 1 "register_operand" "=S")
15885 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15886 (match_operand:DI 4 "register_operand" "1")))
15887 (set (mem:BLK (match_dup 3))
15888 (mem:BLK (match_dup 4)))
15889 (use (match_dup 5))
15890 (use (reg:SI 19))]
15891 "TARGET_64BIT"
15892 "{rep\;movsl|rep movsd}"
15893 [(set_attr "type" "str")
15894 (set_attr "prefix_rep" "1")
15895 (set_attr "memory" "both")
15896 (set_attr "mode" "SI")])
15897
15898 (define_insn "rep_movqi"
15899 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15900 (set (match_operand:SI 0 "register_operand" "=D")
15901 (plus:SI (match_operand:SI 3 "register_operand" "0")
15902 (match_operand:SI 5 "register_operand" "2")))
15903 (set (match_operand:SI 1 "register_operand" "=S")
15904 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15905 (set (mem:BLK (match_dup 3))
15906 (mem:BLK (match_dup 4)))
15907 (use (match_dup 5))
15908 (use (reg:SI 19))]
15909 "!TARGET_64BIT"
15910 "{rep\;movsb|rep movsb}"
15911 [(set_attr "type" "str")
15912 (set_attr "prefix_rep" "1")
15913 (set_attr "memory" "both")
15914 (set_attr "mode" "SI")])
15915
15916 (define_insn "rep_movqi_rex64"
15917 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15918 (set (match_operand:DI 0 "register_operand" "=D")
15919 (plus:DI (match_operand:DI 3 "register_operand" "0")
15920 (match_operand:DI 5 "register_operand" "2")))
15921 (set (match_operand:DI 1 "register_operand" "=S")
15922 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15923 (set (mem:BLK (match_dup 3))
15924 (mem:BLK (match_dup 4)))
15925 (use (match_dup 5))
15926 (use (reg:SI 19))]
15927 "TARGET_64BIT"
15928 "{rep\;movsb|rep movsb}"
15929 [(set_attr "type" "str")
15930 (set_attr "prefix_rep" "1")
15931 (set_attr "memory" "both")
15932 (set_attr "mode" "SI")])
15933
15934 (define_expand "clrstrsi"
15935 [(use (match_operand:BLK 0 "memory_operand" ""))
15936 (use (match_operand:SI 1 "nonmemory_operand" ""))
15937 (use (match_operand 2 "const_int_operand" ""))]
15938 ""
15939 {
15940 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15941 DONE;
15942 else
15943 FAIL;
15944 })
15945
15946 (define_expand "clrstrdi"
15947 [(use (match_operand:BLK 0 "memory_operand" ""))
15948 (use (match_operand:DI 1 "nonmemory_operand" ""))
15949 (use (match_operand 2 "const_int_operand" ""))]
15950 "TARGET_64BIT"
15951 {
15952 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15953 DONE;
15954 else
15955 FAIL;
15956 })
15957
15958 ;; Most CPUs don't like single string operations
15959 ;; Handle this case here to simplify previous expander.
15960
15961 (define_expand "strsetdi_rex64"
15962 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15963 (match_operand:DI 1 "register_operand" ""))
15964 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15965 (clobber (reg:CC 17))])]
15966 "TARGET_64BIT"
15967 {
15968 if (TARGET_SINGLE_STRINGOP || optimize_size)
15969 {
15970 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15971 DONE;
15972 }
15973 })
15974
15975 (define_expand "strsetsi"
15976 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15977 (match_operand:SI 1 "register_operand" ""))
15978 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15979 (clobber (reg:CC 17))])]
15980 ""
15981 {
15982 if (TARGET_64BIT)
15983 {
15984 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15985 DONE;
15986 }
15987 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15988 {
15989 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15990 DONE;
15991 }
15992 })
15993
15994 (define_expand "strsetsi_rex64"
15995 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15996 (match_operand:SI 1 "register_operand" ""))
15997 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15998 (clobber (reg:CC 17))])]
15999 "TARGET_64BIT"
16000 {
16001 if (TARGET_SINGLE_STRINGOP || optimize_size)
16002 {
16003 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16004 DONE;
16005 }
16006 })
16007
16008 (define_expand "strsethi"
16009 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16010 (match_operand:HI 1 "register_operand" ""))
16011 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16012 (clobber (reg:CC 17))])]
16013 ""
16014 {
16015 if (TARGET_64BIT)
16016 {
16017 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16018 DONE;
16019 }
16020 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16021 {
16022 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16023 DONE;
16024 }
16025 })
16026
16027 (define_expand "strsethi_rex64"
16028 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16029 (match_operand:HI 1 "register_operand" ""))
16030 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16031 (clobber (reg:CC 17))])]
16032 "TARGET_64BIT"
16033 {
16034 if (TARGET_SINGLE_STRINGOP || optimize_size)
16035 {
16036 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16037 DONE;
16038 }
16039 })
16040
16041 (define_expand "strsetqi"
16042 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16043 (match_operand:QI 1 "register_operand" ""))
16044 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16045 (clobber (reg:CC 17))])]
16046 ""
16047 {
16048 if (TARGET_64BIT)
16049 {
16050 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16051 DONE;
16052 }
16053 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16054 {
16055 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16056 DONE;
16057 }
16058 })
16059
16060 (define_expand "strsetqi_rex64"
16061 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16062 (match_operand:QI 1 "register_operand" ""))
16063 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16064 (clobber (reg:CC 17))])]
16065 "TARGET_64BIT"
16066 {
16067 if (TARGET_SINGLE_STRINGOP || optimize_size)
16068 {
16069 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16070 DONE;
16071 }
16072 })
16073
16074 (define_insn "strsetdi_rex_1"
16075 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16076 (match_operand:SI 2 "register_operand" "a"))
16077 (set (match_operand:DI 0 "register_operand" "=D")
16078 (plus:DI (match_dup 1)
16079 (const_int 8)))
16080 (use (reg:SI 19))]
16081 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16082 "stosq"
16083 [(set_attr "type" "str")
16084 (set_attr "memory" "store")
16085 (set_attr "mode" "DI")])
16086
16087 (define_insn "strsetsi_1"
16088 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16089 (match_operand:SI 2 "register_operand" "a"))
16090 (set (match_operand:SI 0 "register_operand" "=D")
16091 (plus:SI (match_dup 1)
16092 (const_int 4)))
16093 (use (reg:SI 19))]
16094 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16095 "{stosl|stosd}"
16096 [(set_attr "type" "str")
16097 (set_attr "memory" "store")
16098 (set_attr "mode" "SI")])
16099
16100 (define_insn "strsetsi_rex_1"
16101 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16102 (match_operand:SI 2 "register_operand" "a"))
16103 (set (match_operand:DI 0 "register_operand" "=D")
16104 (plus:DI (match_dup 1)
16105 (const_int 4)))
16106 (use (reg:SI 19))]
16107 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16108 "{stosl|stosd}"
16109 [(set_attr "type" "str")
16110 (set_attr "memory" "store")
16111 (set_attr "mode" "SI")])
16112
16113 (define_insn "strsethi_1"
16114 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16115 (match_operand:HI 2 "register_operand" "a"))
16116 (set (match_operand:SI 0 "register_operand" "=D")
16117 (plus:SI (match_dup 1)
16118 (const_int 2)))
16119 (use (reg:SI 19))]
16120 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16121 "stosw"
16122 [(set_attr "type" "str")
16123 (set_attr "memory" "store")
16124 (set_attr "mode" "HI")])
16125
16126 (define_insn "strsethi_rex_1"
16127 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16128 (match_operand:HI 2 "register_operand" "a"))
16129 (set (match_operand:DI 0 "register_operand" "=D")
16130 (plus:DI (match_dup 1)
16131 (const_int 2)))
16132 (use (reg:SI 19))]
16133 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16134 "stosw"
16135 [(set_attr "type" "str")
16136 (set_attr "memory" "store")
16137 (set_attr "mode" "HI")])
16138
16139 (define_insn "strsetqi_1"
16140 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16141 (match_operand:QI 2 "register_operand" "a"))
16142 (set (match_operand:SI 0 "register_operand" "=D")
16143 (plus:SI (match_dup 1)
16144 (const_int 1)))
16145 (use (reg:SI 19))]
16146 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16147 "stosb"
16148 [(set_attr "type" "str")
16149 (set_attr "memory" "store")
16150 (set_attr "mode" "QI")])
16151
16152 (define_insn "strsetqi_rex_1"
16153 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16154 (match_operand:QI 2 "register_operand" "a"))
16155 (set (match_operand:DI 0 "register_operand" "=D")
16156 (plus:DI (match_dup 1)
16157 (const_int 1)))
16158 (use (reg:SI 19))]
16159 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16160 "stosb"
16161 [(set_attr "type" "str")
16162 (set_attr "memory" "store")
16163 (set_attr "mode" "QI")])
16164
16165 (define_insn "rep_stosdi_rex64"
16166 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16167 (set (match_operand:DI 0 "register_operand" "=D")
16168 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16169 (const_int 3))
16170 (match_operand:DI 3 "register_operand" "0")))
16171 (set (mem:BLK (match_dup 3))
16172 (const_int 0))
16173 (use (match_operand:DI 2 "register_operand" "a"))
16174 (use (match_dup 4))
16175 (use (reg:SI 19))]
16176 "TARGET_64BIT"
16177 "{rep\;stosq|rep stosq}"
16178 [(set_attr "type" "str")
16179 (set_attr "prefix_rep" "1")
16180 (set_attr "memory" "store")
16181 (set_attr "mode" "DI")])
16182
16183 (define_insn "rep_stossi"
16184 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16185 (set (match_operand:SI 0 "register_operand" "=D")
16186 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16187 (const_int 2))
16188 (match_operand:SI 3 "register_operand" "0")))
16189 (set (mem:BLK (match_dup 3))
16190 (const_int 0))
16191 (use (match_operand:SI 2 "register_operand" "a"))
16192 (use (match_dup 4))
16193 (use (reg:SI 19))]
16194 "!TARGET_64BIT"
16195 "{rep\;stosl|rep stosd}"
16196 [(set_attr "type" "str")
16197 (set_attr "prefix_rep" "1")
16198 (set_attr "memory" "store")
16199 (set_attr "mode" "SI")])
16200
16201 (define_insn "rep_stossi_rex64"
16202 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16203 (set (match_operand:DI 0 "register_operand" "=D")
16204 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16205 (const_int 2))
16206 (match_operand:DI 3 "register_operand" "0")))
16207 (set (mem:BLK (match_dup 3))
16208 (const_int 0))
16209 (use (match_operand:SI 2 "register_operand" "a"))
16210 (use (match_dup 4))
16211 (use (reg:SI 19))]
16212 "TARGET_64BIT"
16213 "{rep\;stosl|rep stosd}"
16214 [(set_attr "type" "str")
16215 (set_attr "prefix_rep" "1")
16216 (set_attr "memory" "store")
16217 (set_attr "mode" "SI")])
16218
16219 (define_insn "rep_stosqi"
16220 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16221 (set (match_operand:SI 0 "register_operand" "=D")
16222 (plus:SI (match_operand:SI 3 "register_operand" "0")
16223 (match_operand:SI 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:SI 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_insn "rep_stosqi_rex64"
16237 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16238 (set (match_operand:DI 0 "register_operand" "=D")
16239 (plus:DI (match_operand:DI 3 "register_operand" "0")
16240 (match_operand:DI 4 "register_operand" "1")))
16241 (set (mem:BLK (match_dup 3))
16242 (const_int 0))
16243 (use (match_operand:QI 2 "register_operand" "a"))
16244 (use (match_dup 4))
16245 (use (reg:DI 19))]
16246 "TARGET_64BIT"
16247 "{rep\;stosb|rep stosb}"
16248 [(set_attr "type" "str")
16249 (set_attr "prefix_rep" "1")
16250 (set_attr "memory" "store")
16251 (set_attr "mode" "QI")])
16252
16253 (define_expand "cmpstrsi"
16254 [(set (match_operand:SI 0 "register_operand" "")
16255 (compare:SI (match_operand:BLK 1 "general_operand" "")
16256 (match_operand:BLK 2 "general_operand" "")))
16257 (use (match_operand 3 "general_operand" ""))
16258 (use (match_operand 4 "immediate_operand" ""))]
16259 ""
16260 {
16261 rtx addr1, addr2, out, outlow, count, countreg, align;
16262
16263 /* Can't use this if the user has appropriated esi or edi. */
16264 if (global_regs[4] || global_regs[5])
16265 FAIL;
16266
16267 out = operands[0];
16268 if (GET_CODE (out) != REG)
16269 out = gen_reg_rtx (SImode);
16270
16271 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16272 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16273
16274 count = operands[3];
16275 countreg = ix86_zero_extend_to_Pmode (count);
16276
16277 /* %%% Iff we are testing strict equality, we can use known alignment
16278 to good advantage. This may be possible with combine, particularly
16279 once cc0 is dead. */
16280 align = operands[4];
16281
16282 emit_insn (gen_cld ());
16283 if (GET_CODE (count) == CONST_INT)
16284 {
16285 if (INTVAL (count) == 0)
16286 {
16287 emit_move_insn (operands[0], const0_rtx);
16288 DONE;
16289 }
16290 if (TARGET_64BIT)
16291 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16292 addr1, addr2, countreg));
16293 else
16294 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16295 addr1, addr2, countreg));
16296 }
16297 else
16298 {
16299 if (TARGET_64BIT)
16300 {
16301 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16302 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16303 addr1, addr2, countreg));
16304 }
16305 else
16306 {
16307 emit_insn (gen_cmpsi_1 (countreg, countreg));
16308 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16309 addr1, addr2, countreg));
16310 }
16311 }
16312
16313 outlow = gen_lowpart (QImode, out);
16314 emit_insn (gen_cmpintqi (outlow));
16315 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16316
16317 if (operands[0] != out)
16318 emit_move_insn (operands[0], out);
16319
16320 DONE;
16321 })
16322
16323 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16324
16325 (define_expand "cmpintqi"
16326 [(set (match_dup 1)
16327 (gtu:QI (reg:CC 17) (const_int 0)))
16328 (set (match_dup 2)
16329 (ltu:QI (reg:CC 17) (const_int 0)))
16330 (parallel [(set (match_operand:QI 0 "register_operand" "")
16331 (minus:QI (match_dup 1)
16332 (match_dup 2)))
16333 (clobber (reg:CC 17))])]
16334 ""
16335 "operands[1] = gen_reg_rtx (QImode);
16336 operands[2] = gen_reg_rtx (QImode);")
16337
16338 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16339 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16340
16341 (define_insn "cmpstrqi_nz_1"
16342 [(set (reg:CC 17)
16343 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16344 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16345 (use (match_operand:SI 6 "register_operand" "2"))
16346 (use (match_operand:SI 3 "immediate_operand" "i"))
16347 (use (reg:SI 19))
16348 (clobber (match_operand:SI 0 "register_operand" "=S"))
16349 (clobber (match_operand:SI 1 "register_operand" "=D"))
16350 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16351 "!TARGET_64BIT"
16352 "repz{\;| }cmpsb"
16353 [(set_attr "type" "str")
16354 (set_attr "mode" "QI")
16355 (set_attr "prefix_rep" "1")])
16356
16357 (define_insn "cmpstrqi_nz_rex_1"
16358 [(set (reg:CC 17)
16359 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16360 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16361 (use (match_operand:DI 6 "register_operand" "2"))
16362 (use (match_operand:SI 3 "immediate_operand" "i"))
16363 (use (reg:SI 19))
16364 (clobber (match_operand:DI 0 "register_operand" "=S"))
16365 (clobber (match_operand:DI 1 "register_operand" "=D"))
16366 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16367 "TARGET_64BIT"
16368 "repz{\;| }cmpsb"
16369 [(set_attr "type" "str")
16370 (set_attr "mode" "QI")
16371 (set_attr "prefix_rep" "1")])
16372
16373 ;; The same, but the count is not known to not be zero.
16374
16375 (define_insn "cmpstrqi_1"
16376 [(set (reg:CC 17)
16377 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16378 (const_int 0))
16379 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16380 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16381 (const_int 0)))
16382 (use (match_operand:SI 3 "immediate_operand" "i"))
16383 (use (reg:CC 17))
16384 (use (reg:SI 19))
16385 (clobber (match_operand:SI 0 "register_operand" "=S"))
16386 (clobber (match_operand:SI 1 "register_operand" "=D"))
16387 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16388 "!TARGET_64BIT"
16389 "repz{\;| }cmpsb"
16390 [(set_attr "type" "str")
16391 (set_attr "mode" "QI")
16392 (set_attr "prefix_rep" "1")])
16393
16394 (define_insn "cmpstrqi_rex_1"
16395 [(set (reg:CC 17)
16396 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16397 (const_int 0))
16398 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16399 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16400 (const_int 0)))
16401 (use (match_operand:SI 3 "immediate_operand" "i"))
16402 (use (reg:CC 17))
16403 (use (reg:SI 19))
16404 (clobber (match_operand:DI 0 "register_operand" "=S"))
16405 (clobber (match_operand:DI 1 "register_operand" "=D"))
16406 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16407 "TARGET_64BIT"
16408 "repz{\;| }cmpsb"
16409 [(set_attr "type" "str")
16410 (set_attr "mode" "QI")
16411 (set_attr "prefix_rep" "1")])
16412
16413 (define_expand "strlensi"
16414 [(set (match_operand:SI 0 "register_operand" "")
16415 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16416 (match_operand:QI 2 "immediate_operand" "")
16417 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16418 ""
16419 {
16420 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16421 DONE;
16422 else
16423 FAIL;
16424 })
16425
16426 (define_expand "strlendi"
16427 [(set (match_operand:DI 0 "register_operand" "")
16428 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16429 (match_operand:QI 2 "immediate_operand" "")
16430 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16431 ""
16432 {
16433 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16434 DONE;
16435 else
16436 FAIL;
16437 })
16438
16439 (define_insn "strlenqi_1"
16440 [(set (match_operand:SI 0 "register_operand" "=&c")
16441 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16442 (match_operand:QI 2 "register_operand" "a")
16443 (match_operand:SI 3 "immediate_operand" "i")
16444 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16445 (use (reg:SI 19))
16446 (clobber (match_operand:SI 1 "register_operand" "=D"))
16447 (clobber (reg:CC 17))]
16448 "!TARGET_64BIT"
16449 "repnz{\;| }scasb"
16450 [(set_attr "type" "str")
16451 (set_attr "mode" "QI")
16452 (set_attr "prefix_rep" "1")])
16453
16454 (define_insn "strlenqi_rex_1"
16455 [(set (match_operand:DI 0 "register_operand" "=&c")
16456 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16457 (match_operand:QI 2 "register_operand" "a")
16458 (match_operand:DI 3 "immediate_operand" "i")
16459 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16460 (use (reg:SI 19))
16461 (clobber (match_operand:DI 1 "register_operand" "=D"))
16462 (clobber (reg:CC 17))]
16463 "TARGET_64BIT"
16464 "repnz{\;| }scasb"
16465 [(set_attr "type" "str")
16466 (set_attr "mode" "QI")
16467 (set_attr "prefix_rep" "1")])
16468
16469 ;; Peephole optimizations to clean up after cmpstr*. This should be
16470 ;; handled in combine, but it is not currently up to the task.
16471 ;; When used for their truth value, the cmpstr* expanders generate
16472 ;; code like this:
16473 ;;
16474 ;; repz cmpsb
16475 ;; seta %al
16476 ;; setb %dl
16477 ;; cmpb %al, %dl
16478 ;; jcc label
16479 ;;
16480 ;; The intermediate three instructions are unnecessary.
16481
16482 ;; This one handles cmpstr*_nz_1...
16483 (define_peephole2
16484 [(parallel[
16485 (set (reg:CC 17)
16486 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16487 (mem:BLK (match_operand 5 "register_operand" ""))))
16488 (use (match_operand 6 "register_operand" ""))
16489 (use (match_operand:SI 3 "immediate_operand" ""))
16490 (use (reg:SI 19))
16491 (clobber (match_operand 0 "register_operand" ""))
16492 (clobber (match_operand 1 "register_operand" ""))
16493 (clobber (match_operand 2 "register_operand" ""))])
16494 (set (match_operand:QI 7 "register_operand" "")
16495 (gtu:QI (reg:CC 17) (const_int 0)))
16496 (set (match_operand:QI 8 "register_operand" "")
16497 (ltu:QI (reg:CC 17) (const_int 0)))
16498 (set (reg 17)
16499 (compare (match_dup 7) (match_dup 8)))
16500 ]
16501 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16502 [(parallel[
16503 (set (reg:CC 17)
16504 (compare:CC (mem:BLK (match_dup 4))
16505 (mem:BLK (match_dup 5))))
16506 (use (match_dup 6))
16507 (use (match_dup 3))
16508 (use (reg:SI 19))
16509 (clobber (match_dup 0))
16510 (clobber (match_dup 1))
16511 (clobber (match_dup 2))])]
16512 "")
16513
16514 ;; ...and this one handles cmpstr*_1.
16515 (define_peephole2
16516 [(parallel[
16517 (set (reg:CC 17)
16518 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16519 (const_int 0))
16520 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16521 (mem:BLK (match_operand 5 "register_operand" "")))
16522 (const_int 0)))
16523 (use (match_operand:SI 3 "immediate_operand" ""))
16524 (use (reg:CC 17))
16525 (use (reg:SI 19))
16526 (clobber (match_operand 0 "register_operand" ""))
16527 (clobber (match_operand 1 "register_operand" ""))
16528 (clobber (match_operand 2 "register_operand" ""))])
16529 (set (match_operand:QI 7 "register_operand" "")
16530 (gtu:QI (reg:CC 17) (const_int 0)))
16531 (set (match_operand:QI 8 "register_operand" "")
16532 (ltu:QI (reg:CC 17) (const_int 0)))
16533 (set (reg 17)
16534 (compare (match_dup 7) (match_dup 8)))
16535 ]
16536 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16537 [(parallel[
16538 (set (reg:CC 17)
16539 (if_then_else:CC (ne (match_dup 6)
16540 (const_int 0))
16541 (compare:CC (mem:BLK (match_dup 4))
16542 (mem:BLK (match_dup 5)))
16543 (const_int 0)))
16544 (use (match_dup 3))
16545 (use (reg:CC 17))
16546 (use (reg:SI 19))
16547 (clobber (match_dup 0))
16548 (clobber (match_dup 1))
16549 (clobber (match_dup 2))])]
16550 "")
16551
16552
16553 \f
16554 ;; Conditional move instructions.
16555
16556 (define_expand "movdicc"
16557 [(set (match_operand:DI 0 "register_operand" "")
16558 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16559 (match_operand:DI 2 "general_operand" "")
16560 (match_operand:DI 3 "general_operand" "")))]
16561 "TARGET_64BIT"
16562 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16563
16564 (define_insn "x86_movdicc_0_m1_rex64"
16565 [(set (match_operand:DI 0 "register_operand" "=r")
16566 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16567 (const_int -1)
16568 (const_int 0)))
16569 (clobber (reg:CC 17))]
16570 "TARGET_64BIT"
16571 "sbb{q}\t%0, %0"
16572 ; Since we don't have the proper number of operands for an alu insn,
16573 ; fill in all the blanks.
16574 [(set_attr "type" "alu")
16575 (set_attr "pent_pair" "pu")
16576 (set_attr "memory" "none")
16577 (set_attr "imm_disp" "false")
16578 (set_attr "mode" "DI")
16579 (set_attr "length_immediate" "0")])
16580
16581 (define_insn "movdicc_c_rex64"
16582 [(set (match_operand:DI 0 "register_operand" "=r,r")
16583 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16584 [(reg 17) (const_int 0)])
16585 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16586 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16587 "TARGET_64BIT && TARGET_CMOVE
16588 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16589 "@
16590 cmov%O2%C1\t{%2, %0|%0, %2}
16591 cmov%O2%c1\t{%3, %0|%0, %3}"
16592 [(set_attr "type" "icmov")
16593 (set_attr "mode" "DI")])
16594
16595 (define_expand "movsicc"
16596 [(set (match_operand:SI 0 "register_operand" "")
16597 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16598 (match_operand:SI 2 "general_operand" "")
16599 (match_operand:SI 3 "general_operand" "")))]
16600 ""
16601 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16602
16603 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16604 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16605 ;; So just document what we're doing explicitly.
16606
16607 (define_insn "x86_movsicc_0_m1"
16608 [(set (match_operand:SI 0 "register_operand" "=r")
16609 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16610 (const_int -1)
16611 (const_int 0)))
16612 (clobber (reg:CC 17))]
16613 ""
16614 "sbb{l}\t%0, %0"
16615 ; Since we don't have the proper number of operands for an alu insn,
16616 ; fill in all the blanks.
16617 [(set_attr "type" "alu")
16618 (set_attr "pent_pair" "pu")
16619 (set_attr "memory" "none")
16620 (set_attr "imm_disp" "false")
16621 (set_attr "mode" "SI")
16622 (set_attr "length_immediate" "0")])
16623
16624 (define_insn "*movsicc_noc"
16625 [(set (match_operand:SI 0 "register_operand" "=r,r")
16626 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16627 [(reg 17) (const_int 0)])
16628 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16629 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16630 "TARGET_CMOVE
16631 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16632 "@
16633 cmov%O2%C1\t{%2, %0|%0, %2}
16634 cmov%O2%c1\t{%3, %0|%0, %3}"
16635 [(set_attr "type" "icmov")
16636 (set_attr "mode" "SI")])
16637
16638 (define_expand "movhicc"
16639 [(set (match_operand:HI 0 "register_operand" "")
16640 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16641 (match_operand:HI 2 "general_operand" "")
16642 (match_operand:HI 3 "general_operand" "")))]
16643 "TARGET_HIMODE_MATH"
16644 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16645
16646 (define_insn "*movhicc_noc"
16647 [(set (match_operand:HI 0 "register_operand" "=r,r")
16648 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16649 [(reg 17) (const_int 0)])
16650 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16651 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16652 "TARGET_CMOVE
16653 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16654 "@
16655 cmov%O2%C1\t{%2, %0|%0, %2}
16656 cmov%O2%c1\t{%3, %0|%0, %3}"
16657 [(set_attr "type" "icmov")
16658 (set_attr "mode" "HI")])
16659
16660 (define_expand "movqicc"
16661 [(set (match_operand:QI 0 "register_operand" "")
16662 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16663 (match_operand:QI 2 "general_operand" "")
16664 (match_operand:QI 3 "general_operand" "")))]
16665 "TARGET_QIMODE_MATH"
16666 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16667
16668 (define_insn_and_split "*movqicc_noc"
16669 [(set (match_operand:QI 0 "register_operand" "=r,r")
16670 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16671 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16672 (match_operand:QI 2 "register_operand" "r,0")
16673 (match_operand:QI 3 "register_operand" "0,r")))]
16674 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16675 "#"
16676 "&& reload_completed"
16677 [(set (match_dup 0)
16678 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16679 (match_dup 2)
16680 (match_dup 3)))]
16681 "operands[0] = gen_lowpart (SImode, operands[0]);
16682 operands[2] = gen_lowpart (SImode, operands[2]);
16683 operands[3] = gen_lowpart (SImode, operands[3]);"
16684 [(set_attr "type" "icmov")
16685 (set_attr "mode" "SI")])
16686
16687 (define_expand "movsfcc"
16688 [(set (match_operand:SF 0 "register_operand" "")
16689 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16690 (match_operand:SF 2 "register_operand" "")
16691 (match_operand:SF 3 "register_operand" "")))]
16692 "TARGET_CMOVE"
16693 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16694
16695 (define_insn "*movsfcc_1"
16696 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16697 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16698 [(reg 17) (const_int 0)])
16699 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16700 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16701 "TARGET_CMOVE
16702 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16703 "@
16704 fcmov%F1\t{%2, %0|%0, %2}
16705 fcmov%f1\t{%3, %0|%0, %3}
16706 cmov%O2%C1\t{%2, %0|%0, %2}
16707 cmov%O2%c1\t{%3, %0|%0, %3}"
16708 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16709 (set_attr "mode" "SF,SF,SI,SI")])
16710
16711 (define_expand "movdfcc"
16712 [(set (match_operand:DF 0 "register_operand" "")
16713 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16714 (match_operand:DF 2 "register_operand" "")
16715 (match_operand:DF 3 "register_operand" "")))]
16716 "TARGET_CMOVE"
16717 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16718
16719 (define_insn "*movdfcc_1"
16720 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16721 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16722 [(reg 17) (const_int 0)])
16723 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16724 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16725 "!TARGET_64BIT && TARGET_CMOVE
16726 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16727 "@
16728 fcmov%F1\t{%2, %0|%0, %2}
16729 fcmov%f1\t{%3, %0|%0, %3}
16730 #
16731 #"
16732 [(set_attr "type" "fcmov,fcmov,multi,multi")
16733 (set_attr "mode" "DF")])
16734
16735 (define_insn "*movdfcc_1_rex64"
16736 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16737 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16738 [(reg 17) (const_int 0)])
16739 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16740 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16741 "TARGET_64BIT && TARGET_CMOVE
16742 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16743 "@
16744 fcmov%F1\t{%2, %0|%0, %2}
16745 fcmov%f1\t{%3, %0|%0, %3}
16746 cmov%O2%C1\t{%2, %0|%0, %2}
16747 cmov%O2%c1\t{%3, %0|%0, %3}"
16748 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16749 (set_attr "mode" "DF")])
16750
16751 (define_split
16752 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16753 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16754 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16755 (match_operand:DF 2 "nonimmediate_operand" "")
16756 (match_operand:DF 3 "nonimmediate_operand" "")))]
16757 "!TARGET_64BIT && reload_completed"
16758 [(set (match_dup 2)
16759 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16760 (match_dup 5)
16761 (match_dup 7)))
16762 (set (match_dup 3)
16763 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16764 (match_dup 6)
16765 (match_dup 8)))]
16766 "split_di (operands+2, 1, operands+5, operands+6);
16767 split_di (operands+3, 1, operands+7, operands+8);
16768 split_di (operands, 1, operands+2, operands+3);")
16769
16770 (define_expand "movxfcc"
16771 [(set (match_operand:XF 0 "register_operand" "")
16772 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16773 (match_operand:XF 2 "register_operand" "")
16774 (match_operand:XF 3 "register_operand" "")))]
16775 "!TARGET_64BIT && TARGET_CMOVE"
16776 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16777
16778 (define_expand "movtfcc"
16779 [(set (match_operand:TF 0 "register_operand" "")
16780 (if_then_else:TF (match_operand 1 "comparison_operator" "")
16781 (match_operand:TF 2 "register_operand" "")
16782 (match_operand:TF 3 "register_operand" "")))]
16783 "TARGET_CMOVE"
16784 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16785
16786 (define_insn "*movxfcc_1"
16787 [(set (match_operand:XF 0 "register_operand" "=f,f")
16788 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16789 [(reg 17) (const_int 0)])
16790 (match_operand:XF 2 "register_operand" "f,0")
16791 (match_operand:XF 3 "register_operand" "0,f")))]
16792 "!TARGET_64BIT && TARGET_CMOVE"
16793 "@
16794 fcmov%F1\t{%2, %0|%0, %2}
16795 fcmov%f1\t{%3, %0|%0, %3}"
16796 [(set_attr "type" "fcmov")
16797 (set_attr "mode" "XF")])
16798
16799 (define_insn "*movtfcc_1"
16800 [(set (match_operand:TF 0 "register_operand" "=f,f")
16801 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
16802 [(reg 17) (const_int 0)])
16803 (match_operand:TF 2 "register_operand" "f,0")
16804 (match_operand:TF 3 "register_operand" "0,f")))]
16805 "TARGET_CMOVE"
16806 "@
16807 fcmov%F1\t{%2, %0|%0, %2}
16808 fcmov%f1\t{%3, %0|%0, %3}"
16809 [(set_attr "type" "fcmov")
16810 (set_attr "mode" "XF")])
16811
16812 (define_expand "minsf3"
16813 [(parallel [
16814 (set (match_operand:SF 0 "register_operand" "")
16815 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16816 (match_operand:SF 2 "nonimmediate_operand" ""))
16817 (match_dup 1)
16818 (match_dup 2)))
16819 (clobber (reg:CC 17))])]
16820 "TARGET_SSE"
16821 "")
16822
16823 (define_insn "*minsf"
16824 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16825 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16826 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16827 (match_dup 1)
16828 (match_dup 2)))
16829 (clobber (reg:CC 17))]
16830 "TARGET_SSE && TARGET_IEEE_FP"
16831 "#")
16832
16833 (define_insn "*minsf_nonieee"
16834 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16835 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16836 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16837 (match_dup 1)
16838 (match_dup 2)))
16839 (clobber (reg:CC 17))]
16840 "TARGET_SSE && !TARGET_IEEE_FP
16841 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16842 "#")
16843
16844 (define_split
16845 [(set (match_operand:SF 0 "register_operand" "")
16846 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16847 (match_operand:SF 2 "nonimmediate_operand" ""))
16848 (match_operand:SF 3 "register_operand" "")
16849 (match_operand:SF 4 "nonimmediate_operand" "")))
16850 (clobber (reg:CC 17))]
16851 "SSE_REG_P (operands[0]) && reload_completed
16852 && ((operands_match_p (operands[1], operands[3])
16853 && operands_match_p (operands[2], operands[4]))
16854 || (operands_match_p (operands[1], operands[4])
16855 && operands_match_p (operands[2], operands[3])))"
16856 [(set (match_dup 0)
16857 (if_then_else:SF (lt (match_dup 1)
16858 (match_dup 2))
16859 (match_dup 1)
16860 (match_dup 2)))])
16861
16862 ;; Conditional addition patterns
16863 (define_expand "addqicc"
16864 [(match_operand:QI 0 "register_operand" "")
16865 (match_operand 1 "comparison_operator" "")
16866 (match_operand:QI 2 "register_operand" "")
16867 (match_operand:QI 3 "const_int_operand" "")]
16868 ""
16869 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16870
16871 (define_expand "addhicc"
16872 [(match_operand:HI 0 "register_operand" "")
16873 (match_operand 1 "comparison_operator" "")
16874 (match_operand:HI 2 "register_operand" "")
16875 (match_operand:HI 3 "const_int_operand" "")]
16876 ""
16877 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16878
16879 (define_expand "addsicc"
16880 [(match_operand:SI 0 "register_operand" "")
16881 (match_operand 1 "comparison_operator" "")
16882 (match_operand:SI 2 "register_operand" "")
16883 (match_operand:SI 3 "const_int_operand" "")]
16884 ""
16885 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16886
16887 (define_expand "adddicc"
16888 [(match_operand:DI 0 "register_operand" "")
16889 (match_operand 1 "comparison_operator" "")
16890 (match_operand:DI 2 "register_operand" "")
16891 (match_operand:DI 3 "const_int_operand" "")]
16892 "TARGET_64BIT"
16893 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16894
16895 ;; We can't represent the LT test directly. Do this by swapping the operands.
16896
16897 (define_split
16898 [(set (match_operand:SF 0 "fp_register_operand" "")
16899 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16900 (match_operand:SF 2 "register_operand" ""))
16901 (match_operand:SF 3 "register_operand" "")
16902 (match_operand:SF 4 "register_operand" "")))
16903 (clobber (reg:CC 17))]
16904 "reload_completed
16905 && ((operands_match_p (operands[1], operands[3])
16906 && operands_match_p (operands[2], operands[4]))
16907 || (operands_match_p (operands[1], operands[4])
16908 && operands_match_p (operands[2], operands[3])))"
16909 [(set (reg:CCFP 17)
16910 (compare:CCFP (match_dup 2)
16911 (match_dup 1)))
16912 (set (match_dup 0)
16913 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16914 (match_dup 1)
16915 (match_dup 2)))])
16916
16917 (define_insn "*minsf_sse"
16918 [(set (match_operand:SF 0 "register_operand" "=x")
16919 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16920 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16921 (match_dup 1)
16922 (match_dup 2)))]
16923 "TARGET_SSE && reload_completed"
16924 "minss\t{%2, %0|%0, %2}"
16925 [(set_attr "type" "sse")
16926 (set_attr "mode" "SF")])
16927
16928 (define_expand "mindf3"
16929 [(parallel [
16930 (set (match_operand:DF 0 "register_operand" "")
16931 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16932 (match_operand:DF 2 "nonimmediate_operand" ""))
16933 (match_dup 1)
16934 (match_dup 2)))
16935 (clobber (reg:CC 17))])]
16936 "TARGET_SSE2 && TARGET_SSE_MATH"
16937 "#")
16938
16939 (define_insn "*mindf"
16940 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16941 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16942 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16943 (match_dup 1)
16944 (match_dup 2)))
16945 (clobber (reg:CC 17))]
16946 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16947 "#")
16948
16949 (define_insn "*mindf_nonieee"
16950 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16951 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16952 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16953 (match_dup 1)
16954 (match_dup 2)))
16955 (clobber (reg:CC 17))]
16956 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16957 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16958 "#")
16959
16960 (define_split
16961 [(set (match_operand:DF 0 "register_operand" "")
16962 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16963 (match_operand:DF 2 "nonimmediate_operand" ""))
16964 (match_operand:DF 3 "register_operand" "")
16965 (match_operand:DF 4 "nonimmediate_operand" "")))
16966 (clobber (reg:CC 17))]
16967 "SSE_REG_P (operands[0]) && reload_completed
16968 && ((operands_match_p (operands[1], operands[3])
16969 && operands_match_p (operands[2], operands[4]))
16970 || (operands_match_p (operands[1], operands[4])
16971 && operands_match_p (operands[2], operands[3])))"
16972 [(set (match_dup 0)
16973 (if_then_else:DF (lt (match_dup 1)
16974 (match_dup 2))
16975 (match_dup 1)
16976 (match_dup 2)))])
16977
16978 ;; We can't represent the LT test directly. Do this by swapping the operands.
16979 (define_split
16980 [(set (match_operand:DF 0 "fp_register_operand" "")
16981 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16982 (match_operand:DF 2 "register_operand" ""))
16983 (match_operand:DF 3 "register_operand" "")
16984 (match_operand:DF 4 "register_operand" "")))
16985 (clobber (reg:CC 17))]
16986 "reload_completed
16987 && ((operands_match_p (operands[1], operands[3])
16988 && operands_match_p (operands[2], operands[4]))
16989 || (operands_match_p (operands[1], operands[4])
16990 && operands_match_p (operands[2], operands[3])))"
16991 [(set (reg:CCFP 17)
16992 (compare:CCFP (match_dup 2)
16993 (match_dup 2)))
16994 (set (match_dup 0)
16995 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16996 (match_dup 1)
16997 (match_dup 2)))])
16998
16999 (define_insn "*mindf_sse"
17000 [(set (match_operand:DF 0 "register_operand" "=Y")
17001 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17002 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17003 (match_dup 1)
17004 (match_dup 2)))]
17005 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17006 "minsd\t{%2, %0|%0, %2}"
17007 [(set_attr "type" "sse")
17008 (set_attr "mode" "DF")])
17009
17010 (define_expand "maxsf3"
17011 [(parallel [
17012 (set (match_operand:SF 0 "register_operand" "")
17013 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17014 (match_operand:SF 2 "nonimmediate_operand" ""))
17015 (match_dup 1)
17016 (match_dup 2)))
17017 (clobber (reg:CC 17))])]
17018 "TARGET_SSE"
17019 "#")
17020
17021 (define_insn "*maxsf"
17022 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17023 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17024 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17025 (match_dup 1)
17026 (match_dup 2)))
17027 (clobber (reg:CC 17))]
17028 "TARGET_SSE && TARGET_IEEE_FP"
17029 "#")
17030
17031 (define_insn "*maxsf_nonieee"
17032 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17033 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17034 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17035 (match_dup 1)
17036 (match_dup 2)))
17037 (clobber (reg:CC 17))]
17038 "TARGET_SSE && !TARGET_IEEE_FP
17039 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17040 "#")
17041
17042 (define_split
17043 [(set (match_operand:SF 0 "register_operand" "")
17044 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17045 (match_operand:SF 2 "nonimmediate_operand" ""))
17046 (match_operand:SF 3 "register_operand" "")
17047 (match_operand:SF 4 "nonimmediate_operand" "")))
17048 (clobber (reg:CC 17))]
17049 "SSE_REG_P (operands[0]) && reload_completed
17050 && ((operands_match_p (operands[1], operands[3])
17051 && operands_match_p (operands[2], operands[4]))
17052 || (operands_match_p (operands[1], operands[4])
17053 && operands_match_p (operands[2], operands[3])))"
17054 [(set (match_dup 0)
17055 (if_then_else:SF (gt (match_dup 1)
17056 (match_dup 2))
17057 (match_dup 1)
17058 (match_dup 2)))])
17059
17060 (define_split
17061 [(set (match_operand:SF 0 "fp_register_operand" "")
17062 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17063 (match_operand:SF 2 "register_operand" ""))
17064 (match_operand:SF 3 "register_operand" "")
17065 (match_operand:SF 4 "register_operand" "")))
17066 (clobber (reg:CC 17))]
17067 "reload_completed
17068 && ((operands_match_p (operands[1], operands[3])
17069 && operands_match_p (operands[2], operands[4]))
17070 || (operands_match_p (operands[1], operands[4])
17071 && operands_match_p (operands[2], operands[3])))"
17072 [(set (reg:CCFP 17)
17073 (compare:CCFP (match_dup 1)
17074 (match_dup 2)))
17075 (set (match_dup 0)
17076 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17077 (match_dup 1)
17078 (match_dup 2)))])
17079
17080 (define_insn "*maxsf_sse"
17081 [(set (match_operand:SF 0 "register_operand" "=x")
17082 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17083 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17084 (match_dup 1)
17085 (match_dup 2)))]
17086 "TARGET_SSE && reload_completed"
17087 "maxss\t{%2, %0|%0, %2}"
17088 [(set_attr "type" "sse")
17089 (set_attr "mode" "SF")])
17090
17091 (define_expand "maxdf3"
17092 [(parallel [
17093 (set (match_operand:DF 0 "register_operand" "")
17094 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17095 (match_operand:DF 2 "nonimmediate_operand" ""))
17096 (match_dup 1)
17097 (match_dup 2)))
17098 (clobber (reg:CC 17))])]
17099 "TARGET_SSE2 && TARGET_SSE_MATH"
17100 "#")
17101
17102 (define_insn "*maxdf"
17103 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17104 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17105 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17106 (match_dup 1)
17107 (match_dup 2)))
17108 (clobber (reg:CC 17))]
17109 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17110 "#")
17111
17112 (define_insn "*maxdf_nonieee"
17113 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17114 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17115 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17116 (match_dup 1)
17117 (match_dup 2)))
17118 (clobber (reg:CC 17))]
17119 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17120 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17121 "#")
17122
17123 (define_split
17124 [(set (match_operand:DF 0 "register_operand" "")
17125 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17126 (match_operand:DF 2 "nonimmediate_operand" ""))
17127 (match_operand:DF 3 "register_operand" "")
17128 (match_operand:DF 4 "nonimmediate_operand" "")))
17129 (clobber (reg:CC 17))]
17130 "SSE_REG_P (operands[0]) && reload_completed
17131 && ((operands_match_p (operands[1], operands[3])
17132 && operands_match_p (operands[2], operands[4]))
17133 || (operands_match_p (operands[1], operands[4])
17134 && operands_match_p (operands[2], operands[3])))"
17135 [(set (match_dup 0)
17136 (if_then_else:DF (gt (match_dup 1)
17137 (match_dup 2))
17138 (match_dup 1)
17139 (match_dup 2)))])
17140
17141 (define_split
17142 [(set (match_operand:DF 0 "fp_register_operand" "")
17143 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17144 (match_operand:DF 2 "register_operand" ""))
17145 (match_operand:DF 3 "register_operand" "")
17146 (match_operand:DF 4 "register_operand" "")))
17147 (clobber (reg:CC 17))]
17148 "reload_completed
17149 && ((operands_match_p (operands[1], operands[3])
17150 && operands_match_p (operands[2], operands[4]))
17151 || (operands_match_p (operands[1], operands[4])
17152 && operands_match_p (operands[2], operands[3])))"
17153 [(set (reg:CCFP 17)
17154 (compare:CCFP (match_dup 1)
17155 (match_dup 2)))
17156 (set (match_dup 0)
17157 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17158 (match_dup 1)
17159 (match_dup 2)))])
17160
17161 (define_insn "*maxdf_sse"
17162 [(set (match_operand:DF 0 "register_operand" "=Y")
17163 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17164 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17165 (match_dup 1)
17166 (match_dup 2)))]
17167 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17168 "maxsd\t{%2, %0|%0, %2}"
17169 [(set_attr "type" "sse")
17170 (set_attr "mode" "DF")])
17171 \f
17172 ;; Misc patterns (?)
17173
17174 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17175 ;; Otherwise there will be nothing to keep
17176 ;;
17177 ;; [(set (reg ebp) (reg esp))]
17178 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17179 ;; (clobber (eflags)]
17180 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17181 ;;
17182 ;; in proper program order.
17183 (define_expand "pro_epilogue_adjust_stack"
17184 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17185 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17186 (match_operand:SI 2 "immediate_operand" "i,i")))
17187 (clobber (reg:CC 17))
17188 (clobber (mem:BLK (scratch)))])]
17189 ""
17190 {
17191 if (TARGET_64BIT)
17192 {
17193 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17194 (operands[0], operands[1], operands[2]));
17195 DONE;
17196 }
17197 })
17198
17199 (define_insn "*pro_epilogue_adjust_stack_1"
17200 [(set (match_operand:SI 0 "register_operand" "=r,r")
17201 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17202 (match_operand:SI 2 "immediate_operand" "i,i")))
17203 (clobber (reg:CC 17))
17204 (clobber (mem:BLK (scratch)))]
17205 "!TARGET_64BIT"
17206 {
17207 switch (get_attr_type (insn))
17208 {
17209 case TYPE_IMOV:
17210 return "mov{l}\t{%1, %0|%0, %1}";
17211
17212 case TYPE_ALU:
17213 if (GET_CODE (operands[2]) == CONST_INT
17214 && (INTVAL (operands[2]) == 128
17215 || (INTVAL (operands[2]) < 0
17216 && INTVAL (operands[2]) != -128)))
17217 {
17218 operands[2] = GEN_INT (-INTVAL (operands[2]));
17219 return "sub{l}\t{%2, %0|%0, %2}";
17220 }
17221 return "add{l}\t{%2, %0|%0, %2}";
17222
17223 case TYPE_LEA:
17224 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17225 return "lea{l}\t{%a2, %0|%0, %a2}";
17226
17227 default:
17228 abort ();
17229 }
17230 }
17231 [(set (attr "type")
17232 (cond [(eq_attr "alternative" "0")
17233 (const_string "alu")
17234 (match_operand:SI 2 "const0_operand" "")
17235 (const_string "imov")
17236 ]
17237 (const_string "lea")))
17238 (set_attr "mode" "SI")])
17239
17240 (define_insn "pro_epilogue_adjust_stack_rex64"
17241 [(set (match_operand:DI 0 "register_operand" "=r,r")
17242 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17243 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17244 (clobber (reg:CC 17))
17245 (clobber (mem:BLK (scratch)))]
17246 "TARGET_64BIT"
17247 {
17248 switch (get_attr_type (insn))
17249 {
17250 case TYPE_IMOV:
17251 return "mov{q}\t{%1, %0|%0, %1}";
17252
17253 case TYPE_ALU:
17254 if (GET_CODE (operands[2]) == CONST_INT
17255 && (INTVAL (operands[2]) == 128
17256 || (INTVAL (operands[2]) < 0
17257 && INTVAL (operands[2]) != -128)))
17258 {
17259 operands[2] = GEN_INT (-INTVAL (operands[2]));
17260 return "sub{q}\t{%2, %0|%0, %2}";
17261 }
17262 return "add{q}\t{%2, %0|%0, %2}";
17263
17264 case TYPE_LEA:
17265 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17266 return "lea{q}\t{%a2, %0|%0, %a2}";
17267
17268 default:
17269 abort ();
17270 }
17271 }
17272 [(set (attr "type")
17273 (cond [(eq_attr "alternative" "0")
17274 (const_string "alu")
17275 (match_operand:DI 2 "const0_operand" "")
17276 (const_string "imov")
17277 ]
17278 (const_string "lea")))
17279 (set_attr "mode" "DI")])
17280
17281
17282 ;; Placeholder for the conditional moves. This one is split either to SSE
17283 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17284 ;; fact is that compares supported by the cmp??ss instructions are exactly
17285 ;; swapped of those supported by cmove sequence.
17286 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17287 ;; supported by i387 comparisons and we do need to emit two conditional moves
17288 ;; in tandem.
17289
17290 (define_insn "sse_movsfcc"
17291 [(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")
17292 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17293 [(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")
17294 (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")])
17295 (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")
17296 (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")))
17297 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17298 (clobber (reg:CC 17))]
17299 "TARGET_SSE
17300 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17301 /* Avoid combine from being smart and converting min/max
17302 instruction patterns into conditional moves. */
17303 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17304 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17305 || !rtx_equal_p (operands[4], operands[2])
17306 || !rtx_equal_p (operands[5], operands[3]))
17307 && (!TARGET_IEEE_FP
17308 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17309 "#")
17310
17311 (define_insn "sse_movsfcc_eq"
17312 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17313 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17314 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17315 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17316 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17317 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17318 (clobber (reg:CC 17))]
17319 "TARGET_SSE
17320 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17321 "#")
17322
17323 (define_insn "sse_movdfcc"
17324 [(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")
17325 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17326 [(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")
17327 (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")])
17328 (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")
17329 (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")))
17330 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17331 (clobber (reg:CC 17))]
17332 "TARGET_SSE2
17333 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17334 /* Avoid combine from being smart and converting min/max
17335 instruction patterns into conditional moves. */
17336 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17337 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17338 || !rtx_equal_p (operands[4], operands[2])
17339 || !rtx_equal_p (operands[5], operands[3]))
17340 && (!TARGET_IEEE_FP
17341 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17342 "#")
17343
17344 (define_insn "sse_movdfcc_eq"
17345 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17346 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17347 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17348 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17349 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17350 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17351 (clobber (reg:CC 17))]
17352 "TARGET_SSE
17353 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17354 "#")
17355
17356 ;; For non-sse moves just expand the usual cmove sequence.
17357 (define_split
17358 [(set (match_operand 0 "register_operand" "")
17359 (if_then_else (match_operator 1 "comparison_operator"
17360 [(match_operand 4 "nonimmediate_operand" "")
17361 (match_operand 5 "register_operand" "")])
17362 (match_operand 2 "nonimmediate_operand" "")
17363 (match_operand 3 "nonimmediate_operand" "")))
17364 (clobber (match_operand 6 "" ""))
17365 (clobber (reg:CC 17))]
17366 "!SSE_REG_P (operands[0]) && reload_completed
17367 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17368 [(const_int 0)]
17369 {
17370 ix86_compare_op0 = operands[5];
17371 ix86_compare_op1 = operands[4];
17372 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17373 VOIDmode, operands[5], operands[4]);
17374 ix86_expand_fp_movcc (operands);
17375 DONE;
17376 })
17377
17378 ;; Split SSE based conditional move into sequence:
17379 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17380 ;; and op2, op0 - zero op2 if comparison was false
17381 ;; nand op0, op3 - load op3 to op0 if comparison was false
17382 ;; or op2, op0 - get the nonzero one into the result.
17383 (define_split
17384 [(set (match_operand 0 "register_operand" "")
17385 (if_then_else (match_operator 1 "sse_comparison_operator"
17386 [(match_operand 4 "register_operand" "")
17387 (match_operand 5 "nonimmediate_operand" "")])
17388 (match_operand 2 "register_operand" "")
17389 (match_operand 3 "register_operand" "")))
17390 (clobber (match_operand 6 "" ""))
17391 (clobber (reg:CC 17))]
17392 "SSE_REG_P (operands[0]) && reload_completed"
17393 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17394 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17395 (subreg:TI (match_dup 4) 0)))
17396 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17397 (subreg:TI (match_dup 3) 0)))
17398 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17399 (subreg:TI (match_dup 7) 0)))]
17400 {
17401 if (GET_MODE (operands[2]) == DFmode
17402 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17403 {
17404 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17405 emit_insn (gen_sse2_unpcklpd (op, op, op));
17406 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17407 emit_insn (gen_sse2_unpcklpd (op, op, op));
17408 }
17409
17410 /* If op2 == op3, op3 would be clobbered before it is used. */
17411 if (operands_match_p (operands[2], operands[3]))
17412 {
17413 emit_move_insn (operands[0], operands[2]);
17414 DONE;
17415 }
17416
17417 PUT_MODE (operands[1], GET_MODE (operands[0]));
17418 if (operands_match_p (operands[0], operands[4]))
17419 operands[6] = operands[4], operands[7] = operands[2];
17420 else
17421 operands[6] = operands[2], operands[7] = operands[4];
17422 })
17423
17424 ;; Special case of conditional move we can handle effectively.
17425 ;; Do not brother with the integer/floating point case, since these are
17426 ;; bot considerably slower, unlike in the generic case.
17427 (define_insn "*sse_movsfcc_const0_1"
17428 [(set (match_operand:SF 0 "register_operand" "=&x")
17429 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17430 [(match_operand:SF 4 "register_operand" "0")
17431 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17432 (match_operand:SF 2 "register_operand" "x")
17433 (match_operand:SF 3 "const0_operand" "X")))]
17434 "TARGET_SSE"
17435 "#")
17436
17437 (define_insn "*sse_movsfcc_const0_2"
17438 [(set (match_operand:SF 0 "register_operand" "=&x")
17439 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17440 [(match_operand:SF 4 "register_operand" "0")
17441 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17442 (match_operand:SF 2 "const0_operand" "X")
17443 (match_operand:SF 3 "register_operand" "x")))]
17444 "TARGET_SSE"
17445 "#")
17446
17447 (define_insn "*sse_movsfcc_const0_3"
17448 [(set (match_operand:SF 0 "register_operand" "=&x")
17449 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17450 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17451 (match_operand:SF 5 "register_operand" "0")])
17452 (match_operand:SF 2 "register_operand" "x")
17453 (match_operand:SF 3 "const0_operand" "X")))]
17454 "TARGET_SSE"
17455 "#")
17456
17457 (define_insn "*sse_movsfcc_const0_4"
17458 [(set (match_operand:SF 0 "register_operand" "=&x")
17459 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17460 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17461 (match_operand:SF 5 "register_operand" "0")])
17462 (match_operand:SF 2 "const0_operand" "X")
17463 (match_operand:SF 3 "register_operand" "x")))]
17464 "TARGET_SSE"
17465 "#")
17466
17467 (define_insn "*sse_movdfcc_const0_1"
17468 [(set (match_operand:DF 0 "register_operand" "=&Y")
17469 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17470 [(match_operand:DF 4 "register_operand" "0")
17471 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17472 (match_operand:DF 2 "register_operand" "Y")
17473 (match_operand:DF 3 "const0_operand" "X")))]
17474 "TARGET_SSE2"
17475 "#")
17476
17477 (define_insn "*sse_movdfcc_const0_2"
17478 [(set (match_operand:DF 0 "register_operand" "=&Y")
17479 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17480 [(match_operand:DF 4 "register_operand" "0")
17481 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17482 (match_operand:DF 2 "const0_operand" "X")
17483 (match_operand:DF 3 "register_operand" "Y")))]
17484 "TARGET_SSE2"
17485 "#")
17486
17487 (define_insn "*sse_movdfcc_const0_3"
17488 [(set (match_operand:DF 0 "register_operand" "=&Y")
17489 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17490 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17491 (match_operand:DF 5 "register_operand" "0")])
17492 (match_operand:DF 2 "register_operand" "Y")
17493 (match_operand:DF 3 "const0_operand" "X")))]
17494 "TARGET_SSE2"
17495 "#")
17496
17497 (define_insn "*sse_movdfcc_const0_4"
17498 [(set (match_operand:DF 0 "register_operand" "=&Y")
17499 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17500 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17501 (match_operand:DF 5 "register_operand" "0")])
17502 (match_operand:DF 2 "const0_operand" "X")
17503 (match_operand:DF 3 "register_operand" "Y")))]
17504 "TARGET_SSE2"
17505 "#")
17506
17507 (define_split
17508 [(set (match_operand 0 "register_operand" "")
17509 (if_then_else (match_operator 1 "comparison_operator"
17510 [(match_operand 4 "nonimmediate_operand" "")
17511 (match_operand 5 "nonimmediate_operand" "")])
17512 (match_operand 2 "nonmemory_operand" "")
17513 (match_operand 3 "nonmemory_operand" "")))]
17514 "SSE_REG_P (operands[0]) && reload_completed
17515 && (const0_operand (operands[2], GET_MODE (operands[0]))
17516 || const0_operand (operands[3], GET_MODE (operands[0])))"
17517 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17518 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17519 (match_dup 7)))]
17520 {
17521 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17522 && GET_MODE (operands[2]) == DFmode)
17523 {
17524 if (REG_P (operands[2]))
17525 {
17526 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17527 emit_insn (gen_sse2_unpcklpd (op, op, op));
17528 }
17529 if (REG_P (operands[3]))
17530 {
17531 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17532 emit_insn (gen_sse2_unpcklpd (op, op, op));
17533 }
17534 }
17535 PUT_MODE (operands[1], GET_MODE (operands[0]));
17536 if (!sse_comparison_operator (operands[1], VOIDmode)
17537 || !rtx_equal_p (operands[0], operands[4]))
17538 {
17539 rtx tmp = operands[5];
17540 operands[5] = operands[4];
17541 operands[4] = tmp;
17542 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17543 }
17544 if (!rtx_equal_p (operands[0], operands[4]))
17545 abort ();
17546 if (const0_operand (operands[2], GET_MODE (operands[0])))
17547 {
17548 operands[7] = operands[3];
17549 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17550 0));
17551 }
17552 else
17553 {
17554 operands[7] = operands[2];
17555 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17556 }
17557 operands[7] = simplify_gen_subreg (TImode, operands[7],
17558 GET_MODE (operands[7]), 0);
17559 })
17560
17561 (define_expand "allocate_stack_worker"
17562 [(match_operand:SI 0 "register_operand" "")]
17563 "TARGET_STACK_PROBE"
17564 {
17565 if (TARGET_64BIT)
17566 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17567 else
17568 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17569 DONE;
17570 })
17571
17572 (define_insn "allocate_stack_worker_1"
17573 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17574 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17575 (clobber (match_dup 0))
17576 (clobber (reg:CC 17))]
17577 "!TARGET_64BIT && TARGET_STACK_PROBE"
17578 "call\t__alloca"
17579 [(set_attr "type" "multi")
17580 (set_attr "length" "5")])
17581
17582 (define_insn "allocate_stack_worker_rex64"
17583 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17584 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17585 (clobber (match_dup 0))
17586 (clobber (reg:CC 17))]
17587 "TARGET_64BIT && TARGET_STACK_PROBE"
17588 "call\t__alloca"
17589 [(set_attr "type" "multi")
17590 (set_attr "length" "5")])
17591
17592 (define_expand "allocate_stack"
17593 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17594 (minus:SI (reg:SI 7)
17595 (match_operand:SI 1 "general_operand" "")))
17596 (clobber (reg:CC 17))])
17597 (parallel [(set (reg:SI 7)
17598 (minus:SI (reg:SI 7) (match_dup 1)))
17599 (clobber (reg:CC 17))])]
17600 "TARGET_STACK_PROBE"
17601 {
17602 #ifdef CHECK_STACK_LIMIT
17603 if (GET_CODE (operands[1]) == CONST_INT
17604 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17605 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17606 operands[1]));
17607 else
17608 #endif
17609 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17610 operands[1])));
17611
17612 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17613 DONE;
17614 })
17615
17616 (define_expand "builtin_setjmp_receiver"
17617 [(label_ref (match_operand 0 "" ""))]
17618 "!TARGET_64BIT && flag_pic"
17619 {
17620 emit_insn (gen_set_got (pic_offset_table_rtx));
17621 DONE;
17622 })
17623 \f
17624 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17625
17626 (define_split
17627 [(set (match_operand 0 "register_operand" "")
17628 (match_operator 3 "promotable_binary_operator"
17629 [(match_operand 1 "register_operand" "")
17630 (match_operand 2 "aligned_operand" "")]))
17631 (clobber (reg:CC 17))]
17632 "! TARGET_PARTIAL_REG_STALL && reload_completed
17633 && ((GET_MODE (operands[0]) == HImode
17634 && ((!optimize_size && !TARGET_FAST_PREFIX)
17635 || GET_CODE (operands[2]) != CONST_INT
17636 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17637 || (GET_MODE (operands[0]) == QImode
17638 && (TARGET_PROMOTE_QImode || optimize_size)))"
17639 [(parallel [(set (match_dup 0)
17640 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17641 (clobber (reg:CC 17))])]
17642 "operands[0] = gen_lowpart (SImode, operands[0]);
17643 operands[1] = gen_lowpart (SImode, operands[1]);
17644 if (GET_CODE (operands[3]) != ASHIFT)
17645 operands[2] = gen_lowpart (SImode, operands[2]);
17646 PUT_MODE (operands[3], SImode);")
17647
17648 ; Promote the QImode tests, as i386 has encoding of the AND
17649 ; instruction with 32-bit sign-extended immediate and thus the
17650 ; instruction size is unchanged, except in the %eax case for
17651 ; which it is increased by one byte, hence the ! optimize_size.
17652 (define_split
17653 [(set (reg 17)
17654 (compare (and (match_operand 1 "aligned_operand" "")
17655 (match_operand 2 "const_int_operand" ""))
17656 (const_int 0)))
17657 (set (match_operand 0 "register_operand" "")
17658 (and (match_dup 1) (match_dup 2)))]
17659 "! TARGET_PARTIAL_REG_STALL && reload_completed
17660 /* Ensure that the operand will remain sign-extended immediate. */
17661 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17662 && ! optimize_size
17663 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17664 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17665 [(parallel [(set (reg:CCNO 17)
17666 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17667 (const_int 0)))
17668 (set (match_dup 0)
17669 (and:SI (match_dup 1) (match_dup 2)))])]
17670 "operands[2]
17671 = gen_int_mode (INTVAL (operands[2])
17672 & GET_MODE_MASK (GET_MODE (operands[0])),
17673 SImode);
17674 operands[0] = gen_lowpart (SImode, operands[0]);
17675 operands[1] = gen_lowpart (SImode, operands[1]);")
17676
17677 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17678 ; the TEST instruction with 32-bit sign-extended immediate and thus
17679 ; the instruction size would at least double, which is not what we
17680 ; want even with ! optimize_size.
17681 (define_split
17682 [(set (reg 17)
17683 (compare (and (match_operand:HI 0 "aligned_operand" "")
17684 (match_operand:HI 1 "const_int_operand" ""))
17685 (const_int 0)))]
17686 "! TARGET_PARTIAL_REG_STALL && reload_completed
17687 /* Ensure that the operand will remain sign-extended immediate. */
17688 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17689 && ! TARGET_FAST_PREFIX
17690 && ! optimize_size"
17691 [(set (reg:CCNO 17)
17692 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17693 (const_int 0)))]
17694 "operands[1]
17695 = gen_int_mode (INTVAL (operands[1])
17696 & GET_MODE_MASK (GET_MODE (operands[0])),
17697 SImode);
17698 operands[0] = gen_lowpart (SImode, operands[0]);")
17699
17700 (define_split
17701 [(set (match_operand 0 "register_operand" "")
17702 (neg (match_operand 1 "register_operand" "")))
17703 (clobber (reg:CC 17))]
17704 "! TARGET_PARTIAL_REG_STALL && reload_completed
17705 && (GET_MODE (operands[0]) == HImode
17706 || (GET_MODE (operands[0]) == QImode
17707 && (TARGET_PROMOTE_QImode || optimize_size)))"
17708 [(parallel [(set (match_dup 0)
17709 (neg:SI (match_dup 1)))
17710 (clobber (reg:CC 17))])]
17711 "operands[0] = gen_lowpart (SImode, operands[0]);
17712 operands[1] = gen_lowpart (SImode, operands[1]);")
17713
17714 (define_split
17715 [(set (match_operand 0 "register_operand" "")
17716 (not (match_operand 1 "register_operand" "")))]
17717 "! TARGET_PARTIAL_REG_STALL && reload_completed
17718 && (GET_MODE (operands[0]) == HImode
17719 || (GET_MODE (operands[0]) == QImode
17720 && (TARGET_PROMOTE_QImode || optimize_size)))"
17721 [(set (match_dup 0)
17722 (not:SI (match_dup 1)))]
17723 "operands[0] = gen_lowpart (SImode, operands[0]);
17724 operands[1] = gen_lowpart (SImode, operands[1]);")
17725
17726 (define_split
17727 [(set (match_operand 0 "register_operand" "")
17728 (if_then_else (match_operator 1 "comparison_operator"
17729 [(reg 17) (const_int 0)])
17730 (match_operand 2 "register_operand" "")
17731 (match_operand 3 "register_operand" "")))]
17732 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17733 && (GET_MODE (operands[0]) == HImode
17734 || (GET_MODE (operands[0]) == QImode
17735 && (TARGET_PROMOTE_QImode || optimize_size)))"
17736 [(set (match_dup 0)
17737 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17738 "operands[0] = gen_lowpart (SImode, operands[0]);
17739 operands[2] = gen_lowpart (SImode, operands[2]);
17740 operands[3] = gen_lowpart (SImode, operands[3]);")
17741
17742 \f
17743 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17744 ;; transform a complex memory operation into two memory to register operations.
17745
17746 ;; Don't push memory operands
17747 (define_peephole2
17748 [(set (match_operand:SI 0 "push_operand" "")
17749 (match_operand:SI 1 "memory_operand" ""))
17750 (match_scratch:SI 2 "r")]
17751 "! optimize_size && ! TARGET_PUSH_MEMORY"
17752 [(set (match_dup 2) (match_dup 1))
17753 (set (match_dup 0) (match_dup 2))]
17754 "")
17755
17756 (define_peephole2
17757 [(set (match_operand:DI 0 "push_operand" "")
17758 (match_operand:DI 1 "memory_operand" ""))
17759 (match_scratch:DI 2 "r")]
17760 "! optimize_size && ! TARGET_PUSH_MEMORY"
17761 [(set (match_dup 2) (match_dup 1))
17762 (set (match_dup 0) (match_dup 2))]
17763 "")
17764
17765 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17766 ;; SImode pushes.
17767 (define_peephole2
17768 [(set (match_operand:SF 0 "push_operand" "")
17769 (match_operand:SF 1 "memory_operand" ""))
17770 (match_scratch:SF 2 "r")]
17771 "! optimize_size && ! TARGET_PUSH_MEMORY"
17772 [(set (match_dup 2) (match_dup 1))
17773 (set (match_dup 0) (match_dup 2))]
17774 "")
17775
17776 (define_peephole2
17777 [(set (match_operand:HI 0 "push_operand" "")
17778 (match_operand:HI 1 "memory_operand" ""))
17779 (match_scratch:HI 2 "r")]
17780 "! optimize_size && ! TARGET_PUSH_MEMORY"
17781 [(set (match_dup 2) (match_dup 1))
17782 (set (match_dup 0) (match_dup 2))]
17783 "")
17784
17785 (define_peephole2
17786 [(set (match_operand:QI 0 "push_operand" "")
17787 (match_operand:QI 1 "memory_operand" ""))
17788 (match_scratch:QI 2 "q")]
17789 "! optimize_size && ! TARGET_PUSH_MEMORY"
17790 [(set (match_dup 2) (match_dup 1))
17791 (set (match_dup 0) (match_dup 2))]
17792 "")
17793
17794 ;; Don't move an immediate directly to memory when the instruction
17795 ;; gets too big.
17796 (define_peephole2
17797 [(match_scratch:SI 1 "r")
17798 (set (match_operand:SI 0 "memory_operand" "")
17799 (const_int 0))]
17800 "! optimize_size
17801 && ! TARGET_USE_MOV0
17802 && TARGET_SPLIT_LONG_MOVES
17803 && get_attr_length (insn) >= ix86_cost->large_insn
17804 && peep2_regno_dead_p (0, FLAGS_REG)"
17805 [(parallel [(set (match_dup 1) (const_int 0))
17806 (clobber (reg:CC 17))])
17807 (set (match_dup 0) (match_dup 1))]
17808 "")
17809
17810 (define_peephole2
17811 [(match_scratch:HI 1 "r")
17812 (set (match_operand:HI 0 "memory_operand" "")
17813 (const_int 0))]
17814 "! optimize_size
17815 && ! TARGET_USE_MOV0
17816 && TARGET_SPLIT_LONG_MOVES
17817 && get_attr_length (insn) >= ix86_cost->large_insn
17818 && peep2_regno_dead_p (0, FLAGS_REG)"
17819 [(parallel [(set (match_dup 2) (const_int 0))
17820 (clobber (reg:CC 17))])
17821 (set (match_dup 0) (match_dup 1))]
17822 "operands[2] = gen_lowpart (SImode, operands[1]);")
17823
17824 (define_peephole2
17825 [(match_scratch:QI 1 "q")
17826 (set (match_operand:QI 0 "memory_operand" "")
17827 (const_int 0))]
17828 "! optimize_size
17829 && ! TARGET_USE_MOV0
17830 && TARGET_SPLIT_LONG_MOVES
17831 && get_attr_length (insn) >= ix86_cost->large_insn
17832 && peep2_regno_dead_p (0, FLAGS_REG)"
17833 [(parallel [(set (match_dup 2) (const_int 0))
17834 (clobber (reg:CC 17))])
17835 (set (match_dup 0) (match_dup 1))]
17836 "operands[2] = gen_lowpart (SImode, operands[1]);")
17837
17838 (define_peephole2
17839 [(match_scratch:SI 2 "r")
17840 (set (match_operand:SI 0 "memory_operand" "")
17841 (match_operand:SI 1 "immediate_operand" ""))]
17842 "! optimize_size
17843 && get_attr_length (insn) >= ix86_cost->large_insn
17844 && TARGET_SPLIT_LONG_MOVES"
17845 [(set (match_dup 2) (match_dup 1))
17846 (set (match_dup 0) (match_dup 2))]
17847 "")
17848
17849 (define_peephole2
17850 [(match_scratch:HI 2 "r")
17851 (set (match_operand:HI 0 "memory_operand" "")
17852 (match_operand:HI 1 "immediate_operand" ""))]
17853 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17854 && TARGET_SPLIT_LONG_MOVES"
17855 [(set (match_dup 2) (match_dup 1))
17856 (set (match_dup 0) (match_dup 2))]
17857 "")
17858
17859 (define_peephole2
17860 [(match_scratch:QI 2 "q")
17861 (set (match_operand:QI 0 "memory_operand" "")
17862 (match_operand:QI 1 "immediate_operand" ""))]
17863 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17864 && TARGET_SPLIT_LONG_MOVES"
17865 [(set (match_dup 2) (match_dup 1))
17866 (set (match_dup 0) (match_dup 2))]
17867 "")
17868
17869 ;; Don't compare memory with zero, load and use a test instead.
17870 (define_peephole2
17871 [(set (reg 17)
17872 (compare (match_operand:SI 0 "memory_operand" "")
17873 (const_int 0)))
17874 (match_scratch:SI 3 "r")]
17875 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17876 [(set (match_dup 3) (match_dup 0))
17877 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17878 "")
17879
17880 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17881 ;; Don't split NOTs with a displacement operand, because resulting XOR
17882 ;; will not be pairable anyway.
17883 ;;
17884 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17885 ;; represented using a modRM byte. The XOR replacement is long decoded,
17886 ;; so this split helps here as well.
17887 ;;
17888 ;; Note: Can't do this as a regular split because we can't get proper
17889 ;; lifetime information then.
17890
17891 (define_peephole2
17892 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17893 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17894 "!optimize_size
17895 && peep2_regno_dead_p (0, FLAGS_REG)
17896 && ((TARGET_PENTIUM
17897 && (GET_CODE (operands[0]) != MEM
17898 || !memory_displacement_operand (operands[0], SImode)))
17899 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17900 [(parallel [(set (match_dup 0)
17901 (xor:SI (match_dup 1) (const_int -1)))
17902 (clobber (reg:CC 17))])]
17903 "")
17904
17905 (define_peephole2
17906 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17907 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17908 "!optimize_size
17909 && peep2_regno_dead_p (0, FLAGS_REG)
17910 && ((TARGET_PENTIUM
17911 && (GET_CODE (operands[0]) != MEM
17912 || !memory_displacement_operand (operands[0], HImode)))
17913 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17914 [(parallel [(set (match_dup 0)
17915 (xor:HI (match_dup 1) (const_int -1)))
17916 (clobber (reg:CC 17))])]
17917 "")
17918
17919 (define_peephole2
17920 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17921 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17922 "!optimize_size
17923 && peep2_regno_dead_p (0, FLAGS_REG)
17924 && ((TARGET_PENTIUM
17925 && (GET_CODE (operands[0]) != MEM
17926 || !memory_displacement_operand (operands[0], QImode)))
17927 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17928 [(parallel [(set (match_dup 0)
17929 (xor:QI (match_dup 1) (const_int -1)))
17930 (clobber (reg:CC 17))])]
17931 "")
17932
17933 ;; Non pairable "test imm, reg" instructions can be translated to
17934 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17935 ;; byte opcode instead of two, have a short form for byte operands),
17936 ;; so do it for other CPUs as well. Given that the value was dead,
17937 ;; this should not create any new dependencies. Pass on the sub-word
17938 ;; versions if we're concerned about partial register stalls.
17939
17940 (define_peephole2
17941 [(set (reg 17)
17942 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17943 (match_operand:SI 1 "immediate_operand" ""))
17944 (const_int 0)))]
17945 "ix86_match_ccmode (insn, CCNOmode)
17946 && (true_regnum (operands[0]) != 0
17947 || (GET_CODE (operands[1]) == CONST_INT
17948 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17949 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17950 [(parallel
17951 [(set (reg:CCNO 17)
17952 (compare:CCNO (and:SI (match_dup 0)
17953 (match_dup 1))
17954 (const_int 0)))
17955 (set (match_dup 0)
17956 (and:SI (match_dup 0) (match_dup 1)))])]
17957 "")
17958
17959 ;; We don't need to handle HImode case, because it will be promoted to SImode
17960 ;; on ! TARGET_PARTIAL_REG_STALL
17961
17962 (define_peephole2
17963 [(set (reg 17)
17964 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17965 (match_operand:QI 1 "immediate_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
17972 [(set (reg:CCNO 17)
17973 (compare:CCNO (and:QI (match_dup 0)
17974 (match_dup 1))
17975 (const_int 0)))
17976 (set (match_dup 0)
17977 (and:QI (match_dup 0) (match_dup 1)))])]
17978 "")
17979
17980 (define_peephole2
17981 [(set (reg 17)
17982 (compare
17983 (and:SI
17984 (zero_extract:SI
17985 (match_operand 0 "ext_register_operand" "")
17986 (const_int 8)
17987 (const_int 8))
17988 (match_operand 1 "const_int_operand" ""))
17989 (const_int 0)))]
17990 "! TARGET_PARTIAL_REG_STALL
17991 && ix86_match_ccmode (insn, CCNOmode)
17992 && true_regnum (operands[0]) != 0
17993 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17994 [(parallel [(set (reg:CCNO 17)
17995 (compare:CCNO
17996 (and:SI
17997 (zero_extract:SI
17998 (match_dup 0)
17999 (const_int 8)
18000 (const_int 8))
18001 (match_dup 1))
18002 (const_int 0)))
18003 (set (zero_extract:SI (match_dup 0)
18004 (const_int 8)
18005 (const_int 8))
18006 (and:SI
18007 (zero_extract:SI
18008 (match_dup 0)
18009 (const_int 8)
18010 (const_int 8))
18011 (match_dup 1)))])]
18012 "")
18013
18014 ;; Don't do logical operations with memory inputs.
18015 (define_peephole2
18016 [(match_scratch:SI 2 "r")
18017 (parallel [(set (match_operand:SI 0 "register_operand" "")
18018 (match_operator:SI 3 "arith_or_logical_operator"
18019 [(match_dup 0)
18020 (match_operand:SI 1 "memory_operand" "")]))
18021 (clobber (reg:CC 17))])]
18022 "! optimize_size && ! TARGET_READ_MODIFY"
18023 [(set (match_dup 2) (match_dup 1))
18024 (parallel [(set (match_dup 0)
18025 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18026 (clobber (reg:CC 17))])]
18027 "")
18028
18029 (define_peephole2
18030 [(match_scratch:SI 2 "r")
18031 (parallel [(set (match_operand:SI 0 "register_operand" "")
18032 (match_operator:SI 3 "arith_or_logical_operator"
18033 [(match_operand:SI 1 "memory_operand" "")
18034 (match_dup 0)]))
18035 (clobber (reg:CC 17))])]
18036 "! optimize_size && ! TARGET_READ_MODIFY"
18037 [(set (match_dup 2) (match_dup 1))
18038 (parallel [(set (match_dup 0)
18039 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18040 (clobber (reg:CC 17))])]
18041 "")
18042
18043 ; Don't do logical operations with memory outputs
18044 ;
18045 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18046 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18047 ; the same decoder scheduling characteristics as the original.
18048
18049 (define_peephole2
18050 [(match_scratch:SI 2 "r")
18051 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18052 (match_operator:SI 3 "arith_or_logical_operator"
18053 [(match_dup 0)
18054 (match_operand:SI 1 "nonmemory_operand" "")]))
18055 (clobber (reg:CC 17))])]
18056 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18057 [(set (match_dup 2) (match_dup 0))
18058 (parallel [(set (match_dup 2)
18059 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18060 (clobber (reg:CC 17))])
18061 (set (match_dup 0) (match_dup 2))]
18062 "")
18063
18064 (define_peephole2
18065 [(match_scratch:SI 2 "r")
18066 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18067 (match_operator:SI 3 "arith_or_logical_operator"
18068 [(match_operand:SI 1 "nonmemory_operand" "")
18069 (match_dup 0)]))
18070 (clobber (reg:CC 17))])]
18071 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18072 [(set (match_dup 2) (match_dup 0))
18073 (parallel [(set (match_dup 2)
18074 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18075 (clobber (reg:CC 17))])
18076 (set (match_dup 0) (match_dup 2))]
18077 "")
18078
18079 ;; Attempt to always use XOR for zeroing registers.
18080 (define_peephole2
18081 [(set (match_operand 0 "register_operand" "")
18082 (const_int 0))]
18083 "(GET_MODE (operands[0]) == QImode
18084 || GET_MODE (operands[0]) == HImode
18085 || GET_MODE (operands[0]) == SImode
18086 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18087 && (! TARGET_USE_MOV0 || optimize_size)
18088 && peep2_regno_dead_p (0, FLAGS_REG)"
18089 [(parallel [(set (match_dup 0) (const_int 0))
18090 (clobber (reg:CC 17))])]
18091 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18092 operands[0]);")
18093
18094 (define_peephole2
18095 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18096 (const_int 0))]
18097 "(GET_MODE (operands[0]) == QImode
18098 || GET_MODE (operands[0]) == HImode)
18099 && (! TARGET_USE_MOV0 || optimize_size)
18100 && peep2_regno_dead_p (0, FLAGS_REG)"
18101 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18102 (clobber (reg:CC 17))])])
18103
18104 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18105 (define_peephole2
18106 [(set (match_operand 0 "register_operand" "")
18107 (const_int -1))]
18108 "(GET_MODE (operands[0]) == HImode
18109 || GET_MODE (operands[0]) == SImode
18110 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18111 && (optimize_size || TARGET_PENTIUM)
18112 && peep2_regno_dead_p (0, FLAGS_REG)"
18113 [(parallel [(set (match_dup 0) (const_int -1))
18114 (clobber (reg:CC 17))])]
18115 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18116 operands[0]);")
18117
18118 ;; Attempt to convert simple leas to adds. These can be created by
18119 ;; move expanders.
18120 (define_peephole2
18121 [(set (match_operand:SI 0 "register_operand" "")
18122 (plus:SI (match_dup 0)
18123 (match_operand:SI 1 "nonmemory_operand" "")))]
18124 "peep2_regno_dead_p (0, FLAGS_REG)"
18125 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18126 (clobber (reg:CC 17))])]
18127 "")
18128
18129 (define_peephole2
18130 [(set (match_operand:SI 0 "register_operand" "")
18131 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18132 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18133 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18134 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18135 (clobber (reg:CC 17))])]
18136 "operands[2] = gen_lowpart (SImode, operands[2]);")
18137
18138 (define_peephole2
18139 [(set (match_operand:DI 0 "register_operand" "")
18140 (plus:DI (match_dup 0)
18141 (match_operand:DI 1 "x86_64_general_operand" "")))]
18142 "peep2_regno_dead_p (0, FLAGS_REG)"
18143 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18144 (clobber (reg:CC 17))])]
18145 "")
18146
18147 (define_peephole2
18148 [(set (match_operand:SI 0 "register_operand" "")
18149 (mult:SI (match_dup 0)
18150 (match_operand:SI 1 "const_int_operand" "")))]
18151 "exact_log2 (INTVAL (operands[1])) >= 0
18152 && peep2_regno_dead_p (0, FLAGS_REG)"
18153 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18154 (clobber (reg:CC 17))])]
18155 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18156
18157 (define_peephole2
18158 [(set (match_operand:DI 0 "register_operand" "")
18159 (mult:DI (match_dup 0)
18160 (match_operand:DI 1 "const_int_operand" "")))]
18161 "exact_log2 (INTVAL (operands[1])) >= 0
18162 && peep2_regno_dead_p (0, FLAGS_REG)"
18163 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18164 (clobber (reg:CC 17))])]
18165 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18166
18167 (define_peephole2
18168 [(set (match_operand:SI 0 "register_operand" "")
18169 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18170 (match_operand:DI 2 "const_int_operand" "")) 0))]
18171 "exact_log2 (INTVAL (operands[2])) >= 0
18172 && REGNO (operands[0]) == REGNO (operands[1])
18173 && peep2_regno_dead_p (0, FLAGS_REG)"
18174 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18175 (clobber (reg:CC 17))])]
18176 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18177
18178 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18179 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18180 ;; many CPUs it is also faster, since special hardware to avoid esp
18181 ;; dependencies is present.
18182
18183 ;; While some of these conversions may be done using splitters, we use peepholes
18184 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18185
18186 ;; Convert prologue esp subtractions to push.
18187 ;; We need register to push. In order to keep verify_flow_info happy we have
18188 ;; two choices
18189 ;; - use scratch and clobber it in order to avoid dependencies
18190 ;; - use already live register
18191 ;; We can't use the second way right now, since there is no reliable way how to
18192 ;; verify that given register is live. First choice will also most likely in
18193 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18194 ;; call clobbered registers are dead. We may want to use base pointer as an
18195 ;; alternative when no register is available later.
18196
18197 (define_peephole2
18198 [(match_scratch:SI 0 "r")
18199 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18200 (clobber (reg:CC 17))
18201 (clobber (mem:BLK (scratch)))])]
18202 "optimize_size || !TARGET_SUB_ESP_4"
18203 [(clobber (match_dup 0))
18204 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18205 (clobber (mem:BLK (scratch)))])])
18206
18207 (define_peephole2
18208 [(match_scratch:SI 0 "r")
18209 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18210 (clobber (reg:CC 17))
18211 (clobber (mem:BLK (scratch)))])]
18212 "optimize_size || !TARGET_SUB_ESP_8"
18213 [(clobber (match_dup 0))
18214 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18215 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18216 (clobber (mem:BLK (scratch)))])])
18217
18218 ;; Convert esp subtractions to push.
18219 (define_peephole2
18220 [(match_scratch:SI 0 "r")
18221 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18222 (clobber (reg:CC 17))])]
18223 "optimize_size || !TARGET_SUB_ESP_4"
18224 [(clobber (match_dup 0))
18225 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18226
18227 (define_peephole2
18228 [(match_scratch:SI 0 "r")
18229 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18230 (clobber (reg:CC 17))])]
18231 "optimize_size || !TARGET_SUB_ESP_8"
18232 [(clobber (match_dup 0))
18233 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18234 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18235
18236 ;; Convert epilogue deallocator to pop.
18237 (define_peephole2
18238 [(match_scratch:SI 0 "r")
18239 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18240 (clobber (reg:CC 17))
18241 (clobber (mem:BLK (scratch)))])]
18242 "optimize_size || !TARGET_ADD_ESP_4"
18243 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18244 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18245 (clobber (mem:BLK (scratch)))])]
18246 "")
18247
18248 ;; Two pops case is tricky, since pop causes dependency on destination register.
18249 ;; We use two registers if available.
18250 (define_peephole2
18251 [(match_scratch:SI 0 "r")
18252 (match_scratch:SI 1 "r")
18253 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18254 (clobber (reg:CC 17))
18255 (clobber (mem:BLK (scratch)))])]
18256 "optimize_size || !TARGET_ADD_ESP_8"
18257 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18258 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18259 (clobber (mem:BLK (scratch)))])
18260 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18261 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18262 "")
18263
18264 (define_peephole2
18265 [(match_scratch:SI 0 "r")
18266 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18267 (clobber (reg:CC 17))
18268 (clobber (mem:BLK (scratch)))])]
18269 "optimize_size"
18270 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18271 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18272 (clobber (mem:BLK (scratch)))])
18273 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18274 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18275 "")
18276
18277 ;; Convert esp additions to pop.
18278 (define_peephole2
18279 [(match_scratch:SI 0 "r")
18280 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18281 (clobber (reg:CC 17))])]
18282 ""
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 "")
18286
18287 ;; Two pops case is tricky, since pop causes dependency on destination register.
18288 ;; We use two registers if available.
18289 (define_peephole2
18290 [(match_scratch:SI 0 "r")
18291 (match_scratch:SI 1 "r")
18292 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18293 (clobber (reg:CC 17))])]
18294 ""
18295 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18296 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18297 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18298 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18299 "")
18300
18301 (define_peephole2
18302 [(match_scratch:SI 0 "r")
18303 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18304 (clobber (reg:CC 17))])]
18305 "optimize_size"
18306 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18307 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18308 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18309 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18310 "")
18311 \f
18312 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18313 ;; required and register dies.
18314 (define_peephole2
18315 [(set (reg 17)
18316 (compare (match_operand:SI 0 "register_operand" "")
18317 (match_operand:SI 1 "incdec_operand" "")))]
18318 "ix86_match_ccmode (insn, CCGCmode)
18319 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18320 [(parallel [(set (reg:CCGC 17)
18321 (compare:CCGC (match_dup 0)
18322 (match_dup 1)))
18323 (clobber (match_dup 0))])]
18324 "")
18325
18326 (define_peephole2
18327 [(set (reg 17)
18328 (compare (match_operand:HI 0 "register_operand" "")
18329 (match_operand:HI 1 "incdec_operand" "")))]
18330 "ix86_match_ccmode (insn, CCGCmode)
18331 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18332 [(parallel [(set (reg:CCGC 17)
18333 (compare:CCGC (match_dup 0)
18334 (match_dup 1)))
18335 (clobber (match_dup 0))])]
18336 "")
18337
18338 (define_peephole2
18339 [(set (reg 17)
18340 (compare (match_operand:QI 0 "register_operand" "")
18341 (match_operand:QI 1 "incdec_operand" "")))]
18342 "ix86_match_ccmode (insn, CCGCmode)
18343 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18344 [(parallel [(set (reg:CCGC 17)
18345 (compare:CCGC (match_dup 0)
18346 (match_dup 1)))
18347 (clobber (match_dup 0))])]
18348 "")
18349
18350 ;; Convert compares with 128 to shorter add -128
18351 (define_peephole2
18352 [(set (reg 17)
18353 (compare (match_operand:SI 0 "register_operand" "")
18354 (const_int 128)))]
18355 "ix86_match_ccmode (insn, CCGCmode)
18356 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18357 [(parallel [(set (reg:CCGC 17)
18358 (compare:CCGC (match_dup 0)
18359 (const_int 128)))
18360 (clobber (match_dup 0))])]
18361 "")
18362
18363 (define_peephole2
18364 [(set (reg 17)
18365 (compare (match_operand:HI 0 "register_operand" "")
18366 (const_int 128)))]
18367 "ix86_match_ccmode (insn, CCGCmode)
18368 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18369 [(parallel [(set (reg:CCGC 17)
18370 (compare:CCGC (match_dup 0)
18371 (const_int 128)))
18372 (clobber (match_dup 0))])]
18373 "")
18374 \f
18375 (define_peephole2
18376 [(match_scratch:DI 0 "r")
18377 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18378 (clobber (reg:CC 17))
18379 (clobber (mem:BLK (scratch)))])]
18380 "optimize_size || !TARGET_SUB_ESP_4"
18381 [(clobber (match_dup 0))
18382 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18383 (clobber (mem:BLK (scratch)))])])
18384
18385 (define_peephole2
18386 [(match_scratch:DI 0 "r")
18387 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18388 (clobber (reg:CC 17))
18389 (clobber (mem:BLK (scratch)))])]
18390 "optimize_size || !TARGET_SUB_ESP_8"
18391 [(clobber (match_dup 0))
18392 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18393 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18394 (clobber (mem:BLK (scratch)))])])
18395
18396 ;; Convert esp subtractions to push.
18397 (define_peephole2
18398 [(match_scratch:DI 0 "r")
18399 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18400 (clobber (reg:CC 17))])]
18401 "optimize_size || !TARGET_SUB_ESP_4"
18402 [(clobber (match_dup 0))
18403 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18404
18405 (define_peephole2
18406 [(match_scratch:DI 0 "r")
18407 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18408 (clobber (reg:CC 17))])]
18409 "optimize_size || !TARGET_SUB_ESP_8"
18410 [(clobber (match_dup 0))
18411 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18412 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18413
18414 ;; Convert epilogue deallocator to pop.
18415 (define_peephole2
18416 [(match_scratch:DI 0 "r")
18417 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18418 (clobber (reg:CC 17))
18419 (clobber (mem:BLK (scratch)))])]
18420 "optimize_size || !TARGET_ADD_ESP_4"
18421 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18422 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18423 (clobber (mem:BLK (scratch)))])]
18424 "")
18425
18426 ;; Two pops case is tricky, since pop causes dependency on destination register.
18427 ;; We use two registers if available.
18428 (define_peephole2
18429 [(match_scratch:DI 0 "r")
18430 (match_scratch:DI 1 "r")
18431 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18432 (clobber (reg:CC 17))
18433 (clobber (mem:BLK (scratch)))])]
18434 "optimize_size || !TARGET_ADD_ESP_8"
18435 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18436 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18437 (clobber (mem:BLK (scratch)))])
18438 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18439 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18440 "")
18441
18442 (define_peephole2
18443 [(match_scratch:DI 0 "r")
18444 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18445 (clobber (reg:CC 17))
18446 (clobber (mem:BLK (scratch)))])]
18447 "optimize_size"
18448 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18449 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18450 (clobber (mem:BLK (scratch)))])
18451 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18452 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18453 "")
18454
18455 ;; Convert esp additions to pop.
18456 (define_peephole2
18457 [(match_scratch:DI 0 "r")
18458 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18459 (clobber (reg:CC 17))])]
18460 ""
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 "")
18464
18465 ;; Two pops case is tricky, since pop causes dependency on destination register.
18466 ;; We use two registers if available.
18467 (define_peephole2
18468 [(match_scratch:DI 0 "r")
18469 (match_scratch:DI 1 "r")
18470 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18471 (clobber (reg:CC 17))])]
18472 ""
18473 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18474 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18475 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18476 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18477 "")
18478
18479 (define_peephole2
18480 [(match_scratch:DI 0 "r")
18481 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18482 (clobber (reg:CC 17))])]
18483 "optimize_size"
18484 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18485 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18486 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18487 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18488 "")
18489 \f
18490 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18491 ;; imul $32bit_imm, reg, reg is direct decoded.
18492 (define_peephole2
18493 [(match_scratch:DI 3 "r")
18494 (parallel [(set (match_operand:DI 0 "register_operand" "")
18495 (mult:DI (match_operand:DI 1 "memory_operand" "")
18496 (match_operand:DI 2 "immediate_operand" "")))
18497 (clobber (reg:CC 17))])]
18498 "TARGET_K8 && !optimize_size
18499 && (GET_CODE (operands[2]) != CONST_INT
18500 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18501 [(set (match_dup 3) (match_dup 1))
18502 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18503 (clobber (reg:CC 17))])]
18504 "")
18505
18506 (define_peephole2
18507 [(match_scratch:SI 3 "r")
18508 (parallel [(set (match_operand:SI 0 "register_operand" "")
18509 (mult:SI (match_operand:SI 1 "memory_operand" "")
18510 (match_operand:SI 2 "immediate_operand" "")))
18511 (clobber (reg:CC 17))])]
18512 "TARGET_K8 && !optimize_size
18513 && (GET_CODE (operands[2]) != CONST_INT
18514 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18515 [(set (match_dup 3) (match_dup 1))
18516 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18517 (clobber (reg:CC 17))])]
18518 "")
18519
18520 (define_peephole2
18521 [(match_scratch:SI 3 "r")
18522 (parallel [(set (match_operand:DI 0 "register_operand" "")
18523 (zero_extend:DI
18524 (mult:SI (match_operand:SI 1 "memory_operand" "")
18525 (match_operand:SI 2 "immediate_operand" ""))))
18526 (clobber (reg:CC 17))])]
18527 "TARGET_K8 && !optimize_size
18528 && (GET_CODE (operands[2]) != CONST_INT
18529 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18530 [(set (match_dup 3) (match_dup 1))
18531 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18532 (clobber (reg:CC 17))])]
18533 "")
18534
18535 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18536 ;; Convert it into imul reg, reg
18537 ;; It would be better to force assembler to encode instruction using long
18538 ;; immediate, but there is apparently no way to do so.
18539 (define_peephole2
18540 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18541 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18542 (match_operand:DI 2 "const_int_operand" "")))
18543 (clobber (reg:CC 17))])
18544 (match_scratch:DI 3 "r")]
18545 "TARGET_K8 && !optimize_size
18546 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18547 [(set (match_dup 3) (match_dup 2))
18548 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18549 (clobber (reg:CC 17))])]
18550 {
18551 if (!rtx_equal_p (operands[0], operands[1]))
18552 emit_move_insn (operands[0], operands[1]);
18553 })
18554
18555 (define_peephole2
18556 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18557 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18558 (match_operand:SI 2 "const_int_operand" "")))
18559 (clobber (reg:CC 17))])
18560 (match_scratch:SI 3 "r")]
18561 "TARGET_K8 && !optimize_size
18562 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18563 [(set (match_dup 3) (match_dup 2))
18564 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18565 (clobber (reg:CC 17))])]
18566 {
18567 if (!rtx_equal_p (operands[0], operands[1]))
18568 emit_move_insn (operands[0], operands[1]);
18569 })
18570
18571 (define_peephole2
18572 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18573 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18574 (match_operand:HI 2 "immediate_operand" "")))
18575 (clobber (reg:CC 17))])
18576 (match_scratch:HI 3 "r")]
18577 "TARGET_K8 && !optimize_size"
18578 [(set (match_dup 3) (match_dup 2))
18579 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18580 (clobber (reg:CC 17))])]
18581 {
18582 if (!rtx_equal_p (operands[0], operands[1]))
18583 emit_move_insn (operands[0], operands[1]);
18584 })
18585 \f
18586 ;; Call-value patterns last so that the wildcard operand does not
18587 ;; disrupt insn-recog's switch tables.
18588
18589 (define_insn "*call_value_pop_0"
18590 [(set (match_operand 0 "" "")
18591 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18592 (match_operand:SI 2 "" "")))
18593 (set (reg:SI 7) (plus:SI (reg:SI 7)
18594 (match_operand:SI 3 "immediate_operand" "")))]
18595 "!TARGET_64BIT"
18596 {
18597 if (SIBLING_CALL_P (insn))
18598 return "jmp\t%P1";
18599 else
18600 return "call\t%P1";
18601 }
18602 [(set_attr "type" "callv")])
18603
18604 (define_insn "*call_value_pop_1"
18605 [(set (match_operand 0 "" "")
18606 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18607 (match_operand:SI 2 "" "")))
18608 (set (reg:SI 7) (plus:SI (reg:SI 7)
18609 (match_operand:SI 3 "immediate_operand" "i")))]
18610 "!TARGET_64BIT"
18611 {
18612 if (constant_call_address_operand (operands[1], QImode))
18613 {
18614 if (SIBLING_CALL_P (insn))
18615 return "jmp\t%P1";
18616 else
18617 return "call\t%P1";
18618 }
18619 if (SIBLING_CALL_P (insn))
18620 return "jmp\t%A1";
18621 else
18622 return "call\t%A1";
18623 }
18624 [(set_attr "type" "callv")])
18625
18626 (define_insn "*call_value_0"
18627 [(set (match_operand 0 "" "")
18628 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18629 (match_operand:SI 2 "" "")))]
18630 "!TARGET_64BIT"
18631 {
18632 if (SIBLING_CALL_P (insn))
18633 return "jmp\t%P1";
18634 else
18635 return "call\t%P1";
18636 }
18637 [(set_attr "type" "callv")])
18638
18639 (define_insn "*call_value_0_rex64"
18640 [(set (match_operand 0 "" "")
18641 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18642 (match_operand:DI 2 "const_int_operand" "")))]
18643 "TARGET_64BIT"
18644 {
18645 if (SIBLING_CALL_P (insn))
18646 return "jmp\t%P1";
18647 else
18648 return "call\t%P1";
18649 }
18650 [(set_attr "type" "callv")])
18651
18652 (define_insn "*call_value_1"
18653 [(set (match_operand 0 "" "")
18654 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18655 (match_operand:SI 2 "" "")))]
18656 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18657 {
18658 if (constant_call_address_operand (operands[1], QImode))
18659 return "call\t%P1";
18660 return "call\t%*%1";
18661 }
18662 [(set_attr "type" "callv")])
18663
18664 (define_insn "*sibcall_value_1"
18665 [(set (match_operand 0 "" "")
18666 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18667 (match_operand:SI 2 "" "")))]
18668 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18669 {
18670 if (constant_call_address_operand (operands[1], QImode))
18671 return "jmp\t%P1";
18672 return "jmp\t%*%1";
18673 }
18674 [(set_attr "type" "callv")])
18675
18676 (define_insn "*call_value_1_rex64"
18677 [(set (match_operand 0 "" "")
18678 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18679 (match_operand:DI 2 "" "")))]
18680 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18681 {
18682 if (constant_call_address_operand (operands[1], QImode))
18683 return "call\t%P1";
18684 return "call\t%A1";
18685 }
18686 [(set_attr "type" "callv")])
18687
18688 (define_insn "*sibcall_value_1_rex64"
18689 [(set (match_operand 0 "" "")
18690 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18691 (match_operand:DI 2 "" "")))]
18692 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18693 "jmp\t%P1"
18694 [(set_attr "type" "callv")])
18695
18696 (define_insn "*sibcall_value_1_rex64_v"
18697 [(set (match_operand 0 "" "")
18698 (call (mem:QI (reg:DI 40))
18699 (match_operand:DI 1 "" "")))]
18700 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18701 "jmp\t*%%r11"
18702 [(set_attr "type" "callv")])
18703 \f
18704 (define_insn "trap"
18705 [(trap_if (const_int 1) (const_int 5))]
18706 ""
18707 "int\t$5")
18708
18709 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18710 ;;; for the sake of bounds checking. By emitting bounds checks as
18711 ;;; conditional traps rather than as conditional jumps around
18712 ;;; unconditional traps we avoid introducing spurious basic-block
18713 ;;; boundaries and facilitate elimination of redundant checks. In
18714 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18715 ;;; interrupt 5.
18716 ;;;
18717 ;;; FIXME: Static branch prediction rules for ix86 are such that
18718 ;;; forward conditional branches predict as untaken. As implemented
18719 ;;; below, pseudo conditional traps violate that rule. We should use
18720 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18721 ;;; section loaded at the end of the text segment and branch forward
18722 ;;; there on bounds-failure, and then jump back immediately (in case
18723 ;;; the system chooses to ignore bounds violations, or to report
18724 ;;; violations and continue execution).
18725
18726 (define_expand "conditional_trap"
18727 [(trap_if (match_operator 0 "comparison_operator"
18728 [(match_dup 2) (const_int 0)])
18729 (match_operand 1 "const_int_operand" ""))]
18730 ""
18731 {
18732 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18733 ix86_expand_compare (GET_CODE (operands[0]),
18734 NULL, NULL),
18735 operands[1]));
18736 DONE;
18737 })
18738
18739 (define_insn "*conditional_trap_1"
18740 [(trap_if (match_operator 0 "comparison_operator"
18741 [(reg 17) (const_int 0)])
18742 (match_operand 1 "const_int_operand" ""))]
18743 ""
18744 {
18745 operands[2] = gen_label_rtx ();
18746 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18747 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18748 CODE_LABEL_NUMBER (operands[2]));
18749 RET;
18750 })
18751
18752 ;; Pentium III SIMD instructions.
18753
18754 ;; Moves for SSE/MMX regs.
18755
18756 (define_insn "movv4sf_internal"
18757 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18758 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18759 "TARGET_SSE"
18760 "@
18761 xorps\t%0, %0
18762 movaps\t{%1, %0|%0, %1}
18763 movaps\t{%1, %0|%0, %1}"
18764 [(set_attr "type" "ssemov")
18765 (set_attr "mode" "V4SF")])
18766
18767 (define_split
18768 [(set (match_operand:V4SF 0 "register_operand" "")
18769 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18770 "TARGET_SSE"
18771 [(set (match_dup 0)
18772 (vec_merge:V4SF
18773 (vec_duplicate:V4SF (match_dup 1))
18774 (match_dup 2)
18775 (const_int 1)))]
18776 {
18777 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18778 operands[2] = CONST0_RTX (V4SFmode);
18779 })
18780
18781 (define_insn "movv4si_internal"
18782 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18783 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18784 "TARGET_SSE"
18785 {
18786 switch (which_alternative)
18787 {
18788 case 0:
18789 if (get_attr_mode (insn) == MODE_V4SF)
18790 return "xorps\t%0, %0";
18791 else
18792 return "pxor\t%0, %0";
18793 case 1:
18794 case 2:
18795 if (get_attr_mode (insn) == MODE_V4SF)
18796 return "movaps\t{%1, %0|%0, %1}";
18797 else
18798 return "movdqa\t{%1, %0|%0, %1}";
18799 default:
18800 abort ();
18801 }
18802 }
18803 [(set_attr "type" "ssemov")
18804 (set (attr "mode")
18805 (cond [(eq_attr "alternative" "0,1")
18806 (if_then_else
18807 (ne (symbol_ref "optimize_size")
18808 (const_int 0))
18809 (const_string "V4SF")
18810 (const_string "TI"))
18811 (eq_attr "alternative" "2")
18812 (if_then_else
18813 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18814 (const_int 0))
18815 (ne (symbol_ref "optimize_size")
18816 (const_int 0)))
18817 (const_string "V4SF")
18818 (const_string "TI"))]
18819 (const_string "TI")))])
18820
18821 (define_insn "movv2di_internal"
18822 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18823 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18824 "TARGET_SSE2"
18825 {
18826 switch (which_alternative)
18827 {
18828 case 0:
18829 if (get_attr_mode (insn) == MODE_V4SF)
18830 return "xorps\t%0, %0";
18831 else
18832 return "pxor\t%0, %0";
18833 case 1:
18834 case 2:
18835 if (get_attr_mode (insn) == MODE_V4SF)
18836 return "movaps\t{%1, %0|%0, %1}";
18837 else
18838 return "movdqa\t{%1, %0|%0, %1}";
18839 default:
18840 abort ();
18841 }
18842 }
18843 [(set_attr "type" "ssemov")
18844 (set (attr "mode")
18845 (cond [(eq_attr "alternative" "0,1")
18846 (if_then_else
18847 (ne (symbol_ref "optimize_size")
18848 (const_int 0))
18849 (const_string "V4SF")
18850 (const_string "TI"))
18851 (eq_attr "alternative" "2")
18852 (if_then_else
18853 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18854 (const_int 0))
18855 (ne (symbol_ref "optimize_size")
18856 (const_int 0)))
18857 (const_string "V4SF")
18858 (const_string "TI"))]
18859 (const_string "TI")))])
18860
18861 (define_split
18862 [(set (match_operand:V2DF 0 "register_operand" "")
18863 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18864 "TARGET_SSE2"
18865 [(set (match_dup 0)
18866 (vec_merge:V2DF
18867 (vec_duplicate:V2DF (match_dup 1))
18868 (match_dup 2)
18869 (const_int 1)))]
18870 {
18871 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18872 operands[2] = CONST0_RTX (V2DFmode);
18873 })
18874
18875 (define_insn "movv8qi_internal"
18876 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18877 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18878 "TARGET_MMX
18879 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18880 "@
18881 pxor\t%0, %0
18882 movq\t{%1, %0|%0, %1}
18883 movq\t{%1, %0|%0, %1}"
18884 [(set_attr "type" "mmxmov")
18885 (set_attr "mode" "DI")])
18886
18887 (define_insn "movv4hi_internal"
18888 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18889 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18890 "TARGET_MMX
18891 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18892 "@
18893 pxor\t%0, %0
18894 movq\t{%1, %0|%0, %1}
18895 movq\t{%1, %0|%0, %1}"
18896 [(set_attr "type" "mmxmov")
18897 (set_attr "mode" "DI")])
18898
18899 (define_insn "movv2si_internal"
18900 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18901 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18902 "TARGET_MMX
18903 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18904 "@
18905 pxor\t%0, %0
18906 movq\t{%1, %0|%0, %1}
18907 movq\t{%1, %0|%0, %1}"
18908 [(set_attr "type" "mmxcvt")
18909 (set_attr "mode" "DI")])
18910
18911 (define_insn "movv2sf_internal"
18912 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18913 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18914 "TARGET_3DNOW
18915 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18916 "@
18917 pxor\t%0, %0
18918 movq\t{%1, %0|%0, %1}
18919 movq\t{%1, %0|%0, %1}"
18920 [(set_attr "type" "mmxcvt")
18921 (set_attr "mode" "DI")])
18922
18923 (define_expand "movti"
18924 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18925 (match_operand:TI 1 "nonimmediate_operand" ""))]
18926 "TARGET_SSE || TARGET_64BIT"
18927 {
18928 if (TARGET_64BIT)
18929 ix86_expand_move (TImode, operands);
18930 else
18931 ix86_expand_vector_move (TImode, operands);
18932 DONE;
18933 })
18934
18935 (define_insn "movv2df_internal"
18936 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18937 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18938 "TARGET_SSE2
18939 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18940 {
18941 switch (which_alternative)
18942 {
18943 case 0:
18944 if (get_attr_mode (insn) == MODE_V4SF)
18945 return "xorps\t%0, %0";
18946 else
18947 return "xorpd\t%0, %0";
18948 case 1:
18949 case 2:
18950 if (get_attr_mode (insn) == MODE_V4SF)
18951 return "movaps\t{%1, %0|%0, %1}";
18952 else
18953 return "movapd\t{%1, %0|%0, %1}";
18954 default:
18955 abort ();
18956 }
18957 }
18958 [(set_attr "type" "ssemov")
18959 (set (attr "mode")
18960 (cond [(eq_attr "alternative" "0,1")
18961 (if_then_else
18962 (ne (symbol_ref "optimize_size")
18963 (const_int 0))
18964 (const_string "V4SF")
18965 (const_string "V2DF"))
18966 (eq_attr "alternative" "2")
18967 (if_then_else
18968 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18969 (const_int 0))
18970 (ne (symbol_ref "optimize_size")
18971 (const_int 0)))
18972 (const_string "V4SF")
18973 (const_string "V2DF"))]
18974 (const_string "V2DF")))])
18975
18976 (define_insn "movv8hi_internal"
18977 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18978 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18979 "TARGET_SSE2
18980 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18981 {
18982 switch (which_alternative)
18983 {
18984 case 0:
18985 if (get_attr_mode (insn) == MODE_V4SF)
18986 return "xorps\t%0, %0";
18987 else
18988 return "pxor\t%0, %0";
18989 case 1:
18990 case 2:
18991 if (get_attr_mode (insn) == MODE_V4SF)
18992 return "movaps\t{%1, %0|%0, %1}";
18993 else
18994 return "movdqa\t{%1, %0|%0, %1}";
18995 default:
18996 abort ();
18997 }
18998 }
18999 [(set_attr "type" "ssemov")
19000 (set (attr "mode")
19001 (cond [(eq_attr "alternative" "0,1")
19002 (if_then_else
19003 (ne (symbol_ref "optimize_size")
19004 (const_int 0))
19005 (const_string "V4SF")
19006 (const_string "TI"))
19007 (eq_attr "alternative" "2")
19008 (if_then_else
19009 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19010 (const_int 0))
19011 (ne (symbol_ref "optimize_size")
19012 (const_int 0)))
19013 (const_string "V4SF")
19014 (const_string "TI"))]
19015 (const_string "TI")))])
19016
19017 (define_insn "movv16qi_internal"
19018 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19019 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19020 "TARGET_SSE2
19021 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19022 {
19023 switch (which_alternative)
19024 {
19025 case 0:
19026 if (get_attr_mode (insn) == MODE_V4SF)
19027 return "xorps\t%0, %0";
19028 else
19029 return "pxor\t%0, %0";
19030 case 1:
19031 case 2:
19032 if (get_attr_mode (insn) == MODE_V4SF)
19033 return "movaps\t{%1, %0|%0, %1}";
19034 else
19035 return "movdqa\t{%1, %0|%0, %1}";
19036 default:
19037 abort ();
19038 }
19039 }
19040 [(set_attr "type" "ssemov")
19041 (set (attr "mode")
19042 (cond [(eq_attr "alternative" "0,1")
19043 (if_then_else
19044 (ne (symbol_ref "optimize_size")
19045 (const_int 0))
19046 (const_string "V4SF")
19047 (const_string "TI"))
19048 (eq_attr "alternative" "2")
19049 (if_then_else
19050 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19051 (const_int 0))
19052 (ne (symbol_ref "optimize_size")
19053 (const_int 0)))
19054 (const_string "V4SF")
19055 (const_string "TI"))]
19056 (const_string "TI")))])
19057
19058 (define_expand "movv2df"
19059 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19060 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19061 "TARGET_SSE2"
19062 {
19063 ix86_expand_vector_move (V2DFmode, operands);
19064 DONE;
19065 })
19066
19067 (define_expand "movv8hi"
19068 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19069 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19070 "TARGET_SSE2"
19071 {
19072 ix86_expand_vector_move (V8HImode, operands);
19073 DONE;
19074 })
19075
19076 (define_expand "movv16qi"
19077 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19078 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19079 "TARGET_SSE2"
19080 {
19081 ix86_expand_vector_move (V16QImode, operands);
19082 DONE;
19083 })
19084
19085 (define_expand "movv4sf"
19086 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19087 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19088 "TARGET_SSE"
19089 {
19090 ix86_expand_vector_move (V4SFmode, operands);
19091 DONE;
19092 })
19093
19094 (define_expand "movv4si"
19095 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19096 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19097 "TARGET_SSE"
19098 {
19099 ix86_expand_vector_move (V4SImode, operands);
19100 DONE;
19101 })
19102
19103 (define_expand "movv2di"
19104 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19105 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19106 "TARGET_SSE"
19107 {
19108 ix86_expand_vector_move (V2DImode, operands);
19109 DONE;
19110 })
19111
19112 (define_expand "movv2si"
19113 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19114 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19115 "TARGET_MMX"
19116 {
19117 ix86_expand_vector_move (V2SImode, operands);
19118 DONE;
19119 })
19120
19121 (define_expand "movv4hi"
19122 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19123 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19124 "TARGET_MMX"
19125 {
19126 ix86_expand_vector_move (V4HImode, operands);
19127 DONE;
19128 })
19129
19130 (define_expand "movv8qi"
19131 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19132 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19133 "TARGET_MMX"
19134 {
19135 ix86_expand_vector_move (V8QImode, operands);
19136 DONE;
19137 })
19138
19139 (define_expand "movv2sf"
19140 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19141 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19142 "TARGET_3DNOW"
19143 {
19144 ix86_expand_vector_move (V2SFmode, operands);
19145 DONE;
19146 })
19147
19148 (define_insn "*pushti"
19149 [(set (match_operand:TI 0 "push_operand" "=<")
19150 (match_operand:TI 1 "register_operand" "x"))]
19151 "TARGET_SSE"
19152 "#")
19153
19154 (define_insn "*pushv2df"
19155 [(set (match_operand:V2DF 0 "push_operand" "=<")
19156 (match_operand:V2DF 1 "register_operand" "x"))]
19157 "TARGET_SSE"
19158 "#")
19159
19160 (define_insn "*pushv2di"
19161 [(set (match_operand:V2DI 0 "push_operand" "=<")
19162 (match_operand:V2DI 1 "register_operand" "x"))]
19163 "TARGET_SSE2"
19164 "#")
19165
19166 (define_insn "*pushv8hi"
19167 [(set (match_operand:V8HI 0 "push_operand" "=<")
19168 (match_operand:V8HI 1 "register_operand" "x"))]
19169 "TARGET_SSE2"
19170 "#")
19171
19172 (define_insn "*pushv16qi"
19173 [(set (match_operand:V16QI 0 "push_operand" "=<")
19174 (match_operand:V16QI 1 "register_operand" "x"))]
19175 "TARGET_SSE2"
19176 "#")
19177
19178 (define_insn "*pushv4sf"
19179 [(set (match_operand:V4SF 0 "push_operand" "=<")
19180 (match_operand:V4SF 1 "register_operand" "x"))]
19181 "TARGET_SSE"
19182 "#")
19183
19184 (define_insn "*pushv4si"
19185 [(set (match_operand:V4SI 0 "push_operand" "=<")
19186 (match_operand:V4SI 1 "register_operand" "x"))]
19187 "TARGET_SSE2"
19188 "#")
19189
19190 (define_insn "*pushv2si"
19191 [(set (match_operand:V2SI 0 "push_operand" "=<")
19192 (match_operand:V2SI 1 "register_operand" "y"))]
19193 "TARGET_MMX"
19194 "#")
19195
19196 (define_insn "*pushv4hi"
19197 [(set (match_operand:V4HI 0 "push_operand" "=<")
19198 (match_operand:V4HI 1 "register_operand" "y"))]
19199 "TARGET_MMX"
19200 "#")
19201
19202 (define_insn "*pushv8qi"
19203 [(set (match_operand:V8QI 0 "push_operand" "=<")
19204 (match_operand:V8QI 1 "register_operand" "y"))]
19205 "TARGET_MMX"
19206 "#")
19207
19208 (define_insn "*pushv2sf"
19209 [(set (match_operand:V2SF 0 "push_operand" "=<")
19210 (match_operand:V2SF 1 "register_operand" "y"))]
19211 "TARGET_3DNOW"
19212 "#")
19213
19214 (define_split
19215 [(set (match_operand 0 "push_operand" "")
19216 (match_operand 1 "register_operand" ""))]
19217 "!TARGET_64BIT && reload_completed
19218 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19219 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19220 (set (match_dup 2) (match_dup 1))]
19221 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19222 stack_pointer_rtx);
19223 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19224
19225 (define_split
19226 [(set (match_operand 0 "push_operand" "")
19227 (match_operand 1 "register_operand" ""))]
19228 "TARGET_64BIT && reload_completed
19229 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19230 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19231 (set (match_dup 2) (match_dup 1))]
19232 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19233 stack_pointer_rtx);
19234 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19235
19236
19237 (define_insn "movti_internal"
19238 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19239 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19240 "TARGET_SSE && !TARGET_64BIT
19241 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19242 {
19243 switch (which_alternative)
19244 {
19245 case 0:
19246 if (get_attr_mode (insn) == MODE_V4SF)
19247 return "xorps\t%0, %0";
19248 else
19249 return "pxor\t%0, %0";
19250 case 1:
19251 case 2:
19252 if (get_attr_mode (insn) == MODE_V4SF)
19253 return "movaps\t{%1, %0|%0, %1}";
19254 else
19255 return "movdqa\t{%1, %0|%0, %1}";
19256 default:
19257 abort ();
19258 }
19259 }
19260 [(set_attr "type" "ssemov,ssemov,ssemov")
19261 (set (attr "mode")
19262 (cond [(eq_attr "alternative" "0,1")
19263 (if_then_else
19264 (ne (symbol_ref "optimize_size")
19265 (const_int 0))
19266 (const_string "V4SF")
19267 (const_string "TI"))
19268 (eq_attr "alternative" "2")
19269 (if_then_else
19270 (ne (symbol_ref "optimize_size")
19271 (const_int 0))
19272 (const_string "V4SF")
19273 (const_string "TI"))]
19274 (const_string "TI")))])
19275
19276 (define_insn "*movti_rex64"
19277 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19278 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19279 "TARGET_64BIT
19280 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19281 {
19282 switch (which_alternative)
19283 {
19284 case 0:
19285 case 1:
19286 return "#";
19287 case 2:
19288 if (get_attr_mode (insn) == MODE_V4SF)
19289 return "xorps\t%0, %0";
19290 else
19291 return "pxor\t%0, %0";
19292 case 3:
19293 case 4:
19294 if (get_attr_mode (insn) == MODE_V4SF)
19295 return "movaps\t{%1, %0|%0, %1}";
19296 else
19297 return "movdqa\t{%1, %0|%0, %1}";
19298 default:
19299 abort ();
19300 }
19301 }
19302 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19303 (set (attr "mode")
19304 (cond [(eq_attr "alternative" "2,3")
19305 (if_then_else
19306 (ne (symbol_ref "optimize_size")
19307 (const_int 0))
19308 (const_string "V4SF")
19309 (const_string "TI"))
19310 (eq_attr "alternative" "4")
19311 (if_then_else
19312 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19313 (const_int 0))
19314 (ne (symbol_ref "optimize_size")
19315 (const_int 0)))
19316 (const_string "V4SF")
19317 (const_string "TI"))]
19318 (const_string "DI")))])
19319
19320 (define_split
19321 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19322 (match_operand:TI 1 "general_operand" ""))]
19323 "reload_completed && !SSE_REG_P (operands[0])
19324 && !SSE_REG_P (operands[1])"
19325 [(const_int 0)]
19326 "ix86_split_long_move (operands); DONE;")
19327
19328 ;; These two patterns are useful for specifying exactly whether to use
19329 ;; movaps or movups
19330 (define_insn "sse_movaps"
19331 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19332 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19333 UNSPEC_MOVA))]
19334 "TARGET_SSE
19335 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19336 "movaps\t{%1, %0|%0, %1}"
19337 [(set_attr "type" "ssemov,ssemov")
19338 (set_attr "mode" "V4SF")])
19339
19340 (define_insn "sse_movups"
19341 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19342 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19343 UNSPEC_MOVU))]
19344 "TARGET_SSE
19345 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19346 "movups\t{%1, %0|%0, %1}"
19347 [(set_attr "type" "ssecvt,ssecvt")
19348 (set_attr "mode" "V4SF")])
19349
19350
19351 ;; SSE Strange Moves.
19352
19353 (define_insn "sse_movmskps"
19354 [(set (match_operand:SI 0 "register_operand" "=r")
19355 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19356 UNSPEC_MOVMSK))]
19357 "TARGET_SSE"
19358 "movmskps\t{%1, %0|%0, %1}"
19359 [(set_attr "type" "ssecvt")
19360 (set_attr "mode" "V4SF")])
19361
19362 (define_insn "mmx_pmovmskb"
19363 [(set (match_operand:SI 0 "register_operand" "=r")
19364 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19365 UNSPEC_MOVMSK))]
19366 "TARGET_SSE || TARGET_3DNOW_A"
19367 "pmovmskb\t{%1, %0|%0, %1}"
19368 [(set_attr "type" "ssecvt")
19369 (set_attr "mode" "V4SF")])
19370
19371
19372 (define_insn "mmx_maskmovq"
19373 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19374 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19375 (match_operand:V8QI 2 "register_operand" "y")]
19376 UNSPEC_MASKMOV))]
19377 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19378 ;; @@@ check ordering of operands in intel/nonintel syntax
19379 "maskmovq\t{%2, %1|%1, %2}"
19380 [(set_attr "type" "mmxcvt")
19381 (set_attr "mode" "DI")])
19382
19383 (define_insn "mmx_maskmovq_rex"
19384 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19385 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19386 (match_operand:V8QI 2 "register_operand" "y")]
19387 UNSPEC_MASKMOV))]
19388 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19389 ;; @@@ check ordering of operands in intel/nonintel syntax
19390 "maskmovq\t{%2, %1|%1, %2}"
19391 [(set_attr "type" "mmxcvt")
19392 (set_attr "mode" "DI")])
19393
19394 (define_insn "sse_movntv4sf"
19395 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19396 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19397 UNSPEC_MOVNT))]
19398 "TARGET_SSE"
19399 "movntps\t{%1, %0|%0, %1}"
19400 [(set_attr "type" "ssemov")
19401 (set_attr "mode" "V4SF")])
19402
19403 (define_insn "sse_movntdi"
19404 [(set (match_operand:DI 0 "memory_operand" "=m")
19405 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19406 UNSPEC_MOVNT))]
19407 "TARGET_SSE || TARGET_3DNOW_A"
19408 "movntq\t{%1, %0|%0, %1}"
19409 [(set_attr "type" "mmxmov")
19410 (set_attr "mode" "DI")])
19411
19412 (define_insn "sse_movhlps"
19413 [(set (match_operand:V4SF 0 "register_operand" "=x")
19414 (vec_merge:V4SF
19415 (match_operand:V4SF 1 "register_operand" "0")
19416 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19417 (parallel [(const_int 2)
19418 (const_int 3)
19419 (const_int 0)
19420 (const_int 1)]))
19421 (const_int 3)))]
19422 "TARGET_SSE"
19423 "movhlps\t{%2, %0|%0, %2}"
19424 [(set_attr "type" "ssecvt")
19425 (set_attr "mode" "V4SF")])
19426
19427 (define_insn "sse_movlhps"
19428 [(set (match_operand:V4SF 0 "register_operand" "=x")
19429 (vec_merge:V4SF
19430 (match_operand:V4SF 1 "register_operand" "0")
19431 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19432 (parallel [(const_int 2)
19433 (const_int 3)
19434 (const_int 0)
19435 (const_int 1)]))
19436 (const_int 12)))]
19437 "TARGET_SSE"
19438 "movlhps\t{%2, %0|%0, %2}"
19439 [(set_attr "type" "ssecvt")
19440 (set_attr "mode" "V4SF")])
19441
19442 (define_insn "sse_movhps"
19443 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19444 (vec_merge:V4SF
19445 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19446 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19447 (const_int 12)))]
19448 "TARGET_SSE
19449 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19450 "movhps\t{%2, %0|%0, %2}"
19451 [(set_attr "type" "ssecvt")
19452 (set_attr "mode" "V4SF")])
19453
19454 (define_insn "sse_movlps"
19455 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19456 (vec_merge:V4SF
19457 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19458 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19459 (const_int 3)))]
19460 "TARGET_SSE
19461 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19462 "movlps\t{%2, %0|%0, %2}"
19463 [(set_attr "type" "ssecvt")
19464 (set_attr "mode" "V4SF")])
19465
19466 (define_expand "sse_loadss"
19467 [(match_operand:V4SF 0 "register_operand" "")
19468 (match_operand:SF 1 "memory_operand" "")]
19469 "TARGET_SSE"
19470 {
19471 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19472 CONST0_RTX (V4SFmode)));
19473 DONE;
19474 })
19475
19476 (define_insn "sse_loadss_1"
19477 [(set (match_operand:V4SF 0 "register_operand" "=x")
19478 (vec_merge:V4SF
19479 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19480 (match_operand:V4SF 2 "const0_operand" "X")
19481 (const_int 1)))]
19482 "TARGET_SSE"
19483 "movss\t{%1, %0|%0, %1}"
19484 [(set_attr "type" "ssemov")
19485 (set_attr "mode" "SF")])
19486
19487 (define_insn "sse_movss"
19488 [(set (match_operand:V4SF 0 "register_operand" "=x")
19489 (vec_merge:V4SF
19490 (match_operand:V4SF 1 "register_operand" "0")
19491 (match_operand:V4SF 2 "register_operand" "x")
19492 (const_int 1)))]
19493 "TARGET_SSE"
19494 "movss\t{%2, %0|%0, %2}"
19495 [(set_attr "type" "ssemov")
19496 (set_attr "mode" "SF")])
19497
19498 (define_insn "sse_storess"
19499 [(set (match_operand:SF 0 "memory_operand" "=m")
19500 (vec_select:SF
19501 (match_operand:V4SF 1 "register_operand" "x")
19502 (parallel [(const_int 0)])))]
19503 "TARGET_SSE"
19504 "movss\t{%1, %0|%0, %1}"
19505 [(set_attr "type" "ssemov")
19506 (set_attr "mode" "SF")])
19507
19508 (define_insn "sse_shufps"
19509 [(set (match_operand:V4SF 0 "register_operand" "=x")
19510 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19511 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19512 (match_operand:SI 3 "immediate_operand" "i")]
19513 UNSPEC_SHUFFLE))]
19514 "TARGET_SSE"
19515 ;; @@@ check operand order for intel/nonintel syntax
19516 "shufps\t{%3, %2, %0|%0, %2, %3}"
19517 [(set_attr "type" "ssecvt")
19518 (set_attr "mode" "V4SF")])
19519
19520
19521 ;; SSE arithmetic
19522
19523 (define_insn "addv4sf3"
19524 [(set (match_operand:V4SF 0 "register_operand" "=x")
19525 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19526 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19527 "TARGET_SSE"
19528 "addps\t{%2, %0|%0, %2}"
19529 [(set_attr "type" "sseadd")
19530 (set_attr "mode" "V4SF")])
19531
19532 (define_insn "vmaddv4sf3"
19533 [(set (match_operand:V4SF 0 "register_operand" "=x")
19534 (vec_merge:V4SF
19535 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19536 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19537 (match_dup 1)
19538 (const_int 1)))]
19539 "TARGET_SSE"
19540 "addss\t{%2, %0|%0, %2}"
19541 [(set_attr "type" "sseadd")
19542 (set_attr "mode" "SF")])
19543
19544 (define_insn "subv4sf3"
19545 [(set (match_operand:V4SF 0 "register_operand" "=x")
19546 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19547 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19548 "TARGET_SSE"
19549 "subps\t{%2, %0|%0, %2}"
19550 [(set_attr "type" "sseadd")
19551 (set_attr "mode" "V4SF")])
19552
19553 (define_insn "vmsubv4sf3"
19554 [(set (match_operand:V4SF 0 "register_operand" "=x")
19555 (vec_merge:V4SF
19556 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19557 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19558 (match_dup 1)
19559 (const_int 1)))]
19560 "TARGET_SSE"
19561 "subss\t{%2, %0|%0, %2}"
19562 [(set_attr "type" "sseadd")
19563 (set_attr "mode" "SF")])
19564
19565 (define_insn "mulv4sf3"
19566 [(set (match_operand:V4SF 0 "register_operand" "=x")
19567 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19568 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19569 "TARGET_SSE"
19570 "mulps\t{%2, %0|%0, %2}"
19571 [(set_attr "type" "ssemul")
19572 (set_attr "mode" "V4SF")])
19573
19574 (define_insn "vmmulv4sf3"
19575 [(set (match_operand:V4SF 0 "register_operand" "=x")
19576 (vec_merge:V4SF
19577 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19578 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19579 (match_dup 1)
19580 (const_int 1)))]
19581 "TARGET_SSE"
19582 "mulss\t{%2, %0|%0, %2}"
19583 [(set_attr "type" "ssemul")
19584 (set_attr "mode" "SF")])
19585
19586 (define_insn "divv4sf3"
19587 [(set (match_operand:V4SF 0 "register_operand" "=x")
19588 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19589 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19590 "TARGET_SSE"
19591 "divps\t{%2, %0|%0, %2}"
19592 [(set_attr "type" "ssediv")
19593 (set_attr "mode" "V4SF")])
19594
19595 (define_insn "vmdivv4sf3"
19596 [(set (match_operand:V4SF 0 "register_operand" "=x")
19597 (vec_merge:V4SF
19598 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19599 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19600 (match_dup 1)
19601 (const_int 1)))]
19602 "TARGET_SSE"
19603 "divss\t{%2, %0|%0, %2}"
19604 [(set_attr "type" "ssediv")
19605 (set_attr "mode" "SF")])
19606
19607
19608 ;; SSE square root/reciprocal
19609
19610 (define_insn "rcpv4sf2"
19611 [(set (match_operand:V4SF 0 "register_operand" "=x")
19612 (unspec:V4SF
19613 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19614 "TARGET_SSE"
19615 "rcpps\t{%1, %0|%0, %1}"
19616 [(set_attr "type" "sse")
19617 (set_attr "mode" "V4SF")])
19618
19619 (define_insn "vmrcpv4sf2"
19620 [(set (match_operand:V4SF 0 "register_operand" "=x")
19621 (vec_merge:V4SF
19622 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19623 UNSPEC_RCP)
19624 (match_operand:V4SF 2 "register_operand" "0")
19625 (const_int 1)))]
19626 "TARGET_SSE"
19627 "rcpss\t{%1, %0|%0, %1}"
19628 [(set_attr "type" "sse")
19629 (set_attr "mode" "SF")])
19630
19631 (define_insn "rsqrtv4sf2"
19632 [(set (match_operand:V4SF 0 "register_operand" "=x")
19633 (unspec:V4SF
19634 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19635 "TARGET_SSE"
19636 "rsqrtps\t{%1, %0|%0, %1}"
19637 [(set_attr "type" "sse")
19638 (set_attr "mode" "V4SF")])
19639
19640 (define_insn "vmrsqrtv4sf2"
19641 [(set (match_operand:V4SF 0 "register_operand" "=x")
19642 (vec_merge:V4SF
19643 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19644 UNSPEC_RSQRT)
19645 (match_operand:V4SF 2 "register_operand" "0")
19646 (const_int 1)))]
19647 "TARGET_SSE"
19648 "rsqrtss\t{%1, %0|%0, %1}"
19649 [(set_attr "type" "sse")
19650 (set_attr "mode" "SF")])
19651
19652 (define_insn "sqrtv4sf2"
19653 [(set (match_operand:V4SF 0 "register_operand" "=x")
19654 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19655 "TARGET_SSE"
19656 "sqrtps\t{%1, %0|%0, %1}"
19657 [(set_attr "type" "sse")
19658 (set_attr "mode" "V4SF")])
19659
19660 (define_insn "vmsqrtv4sf2"
19661 [(set (match_operand:V4SF 0 "register_operand" "=x")
19662 (vec_merge:V4SF
19663 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19664 (match_operand:V4SF 2 "register_operand" "0")
19665 (const_int 1)))]
19666 "TARGET_SSE"
19667 "sqrtss\t{%1, %0|%0, %1}"
19668 [(set_attr "type" "sse")
19669 (set_attr "mode" "SF")])
19670
19671 ;; SSE logical operations.
19672
19673 ;; SSE defines logical operations on floating point values. This brings
19674 ;; interesting challenge to RTL representation where logicals are only valid
19675 ;; on integral types. We deal with this by representing the floating point
19676 ;; logical as logical on arguments casted to TImode as this is what hardware
19677 ;; really does. Unfortunately hardware requires the type information to be
19678 ;; present and thus we must avoid subregs from being simplified and eliminated
19679 ;; in later compilation phases.
19680 ;;
19681 ;; We have following variants from each instruction:
19682 ;; sse_andsf3 - the operation taking V4SF vector operands
19683 ;; and doing TImode cast on them
19684 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19685 ;; TImode, since backend insist on eliminating casts
19686 ;; on memory operands
19687 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19688 ;; We can not accept memory operand here as instruction reads
19689 ;; whole scalar. This is generated only post reload by GCC
19690 ;; scalar float operations that expands to logicals (fabs)
19691 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19692 ;; memory operand. Eventually combine can be able
19693 ;; to synthesize these using splitter.
19694 ;; sse2_anddf3, *sse2_anddf3_memory
19695 ;;
19696 ;;
19697 ;; These are not called andti3 etc. because we really really don't want
19698 ;; the compiler to widen DImode ands to TImode ands and then try to move
19699 ;; into DImode subregs of SSE registers, and them together, and move out
19700 ;; of DImode subregs again!
19701 ;; SSE1 single precision floating point logical operation
19702 (define_expand "sse_andv4sf3"
19703 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19704 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19705 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19706 "TARGET_SSE"
19707 "")
19708
19709 (define_insn "*sse_andv4sf3"
19710 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19711 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19712 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19713 "TARGET_SSE
19714 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19715 "andps\t{%2, %0|%0, %2}"
19716 [(set_attr "type" "sselog")
19717 (set_attr "mode" "V4SF")])
19718
19719 (define_insn "*sse_andsf3"
19720 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19721 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19722 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19723 "TARGET_SSE
19724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19725 "andps\t{%2, %0|%0, %2}"
19726 [(set_attr "type" "sselog")
19727 (set_attr "mode" "V4SF")])
19728
19729 (define_expand "sse_nandv4sf3"
19730 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19731 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19732 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19733 "TARGET_SSE"
19734 "")
19735
19736 (define_insn "*sse_nandv4sf3"
19737 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19738 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19739 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19740 "TARGET_SSE"
19741 "andnps\t{%2, %0|%0, %2}"
19742 [(set_attr "type" "sselog")
19743 (set_attr "mode" "V4SF")])
19744
19745 (define_insn "*sse_nandsf3"
19746 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19747 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19748 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19749 "TARGET_SSE"
19750 "andnps\t{%2, %0|%0, %2}"
19751 [(set_attr "type" "sselog")
19752 (set_attr "mode" "V4SF")])
19753
19754 (define_expand "sse_iorv4sf3"
19755 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19756 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19757 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19758 "TARGET_SSE"
19759 "")
19760
19761 (define_insn "*sse_iorv4sf3"
19762 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19763 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19764 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19765 "TARGET_SSE
19766 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19767 "orps\t{%2, %0|%0, %2}"
19768 [(set_attr "type" "sselog")
19769 (set_attr "mode" "V4SF")])
19770
19771 (define_insn "*sse_iorsf3"
19772 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19773 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19774 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19775 "TARGET_SSE
19776 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19777 "orps\t{%2, %0|%0, %2}"
19778 [(set_attr "type" "sselog")
19779 (set_attr "mode" "V4SF")])
19780
19781 (define_expand "sse_xorv4sf3"
19782 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19783 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19784 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19785 "TARGET_SSE
19786 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19787 "")
19788
19789 (define_insn "*sse_xorv4sf3"
19790 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19791 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19792 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19793 "TARGET_SSE
19794 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19795 "xorps\t{%2, %0|%0, %2}"
19796 [(set_attr "type" "sselog")
19797 (set_attr "mode" "V4SF")])
19798
19799 (define_insn "*sse_xorsf3"
19800 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19801 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19802 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19803 "TARGET_SSE
19804 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19805 "xorps\t{%2, %0|%0, %2}"
19806 [(set_attr "type" "sselog")
19807 (set_attr "mode" "V4SF")])
19808
19809 ;; SSE2 double precision floating point logical operation
19810
19811 (define_expand "sse2_andv2df3"
19812 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19813 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19814 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19815 "TARGET_SSE2"
19816 "")
19817
19818 (define_insn "*sse2_andv2df3"
19819 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19820 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19821 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19822 "TARGET_SSE2
19823 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19824 "andpd\t{%2, %0|%0, %2}"
19825 [(set_attr "type" "sselog")
19826 (set_attr "mode" "V2DF")])
19827
19828 (define_insn "*sse2_andv2df3"
19829 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19830 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19831 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19832 "TARGET_SSE2
19833 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19834 "andpd\t{%2, %0|%0, %2}"
19835 [(set_attr "type" "sselog")
19836 (set_attr "mode" "V2DF")])
19837
19838 (define_expand "sse2_nandv2df3"
19839 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19840 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19841 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19842 "TARGET_SSE2"
19843 "")
19844
19845 (define_insn "*sse2_nandv2df3"
19846 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19847 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19848 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19849 "TARGET_SSE2"
19850 "andnpd\t{%2, %0|%0, %2}"
19851 [(set_attr "type" "sselog")
19852 (set_attr "mode" "V2DF")])
19853
19854 (define_insn "*sse_nandti3_df"
19855 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19856 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19857 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19858 "TARGET_SSE2"
19859 "andnpd\t{%2, %0|%0, %2}"
19860 [(set_attr "type" "sselog")
19861 (set_attr "mode" "V2DF")])
19862
19863 (define_expand "sse2_iorv2df3"
19864 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19865 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19866 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19867 "TARGET_SSE2"
19868 "")
19869
19870 (define_insn "*sse2_iorv2df3"
19871 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19872 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19873 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19874 "TARGET_SSE2
19875 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19876 "orpd\t{%2, %0|%0, %2}"
19877 [(set_attr "type" "sselog")
19878 (set_attr "mode" "V2DF")])
19879
19880 (define_insn "*sse2_iordf3"
19881 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19882 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19883 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19884 "TARGET_SSE2
19885 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19886 "orpd\t{%2, %0|%0, %2}"
19887 [(set_attr "type" "sselog")
19888 (set_attr "mode" "V2DF")])
19889
19890 (define_expand "sse2_xorv2df3"
19891 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19892 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19893 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19894 "TARGET_SSE2"
19895 "")
19896
19897 (define_insn "*sse2_xorv2df3"
19898 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19899 (xor: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 "xorpd\t{%2, %0|%0, %2}"
19904 [(set_attr "type" "sselog")
19905 (set_attr "mode" "V2DF")])
19906
19907 (define_insn "*sse2_xordf3"
19908 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19909 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19910 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19911 "TARGET_SSE2
19912 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19913 "xorpd\t{%2, %0|%0, %2}"
19914 [(set_attr "type" "sselog")
19915 (set_attr "mode" "V2DF")])
19916
19917 ;; SSE2 integral logicals. These patterns must always come after floating
19918 ;; point ones since we don't want compiler to use integer opcodes on floating
19919 ;; point SSE values to avoid matching of subregs in the match_operand.
19920 (define_insn "*sse2_andti3"
19921 [(set (match_operand:TI 0 "register_operand" "=x")
19922 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19923 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19924 "TARGET_SSE2
19925 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19926 "pand\t{%2, %0|%0, %2}"
19927 [(set_attr "type" "sselog")
19928 (set_attr "mode" "TI")])
19929
19930 (define_insn "sse2_andv2di3"
19931 [(set (match_operand:V2DI 0 "register_operand" "=x")
19932 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19933 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19934 "TARGET_SSE2
19935 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19936 "pand\t{%2, %0|%0, %2}"
19937 [(set_attr "type" "sselog")
19938 (set_attr "mode" "TI")])
19939
19940 (define_insn "*sse2_nandti3"
19941 [(set (match_operand:TI 0 "register_operand" "=x")
19942 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19943 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19944 "TARGET_SSE2"
19945 "pandn\t{%2, %0|%0, %2}"
19946 [(set_attr "type" "sselog")
19947 (set_attr "mode" "TI")])
19948
19949 (define_insn "sse2_nandv2di3"
19950 [(set (match_operand:V2DI 0 "register_operand" "=x")
19951 (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "0"))
19952 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19953 "TARGET_SSE2
19954 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19955 "pandn\t{%2, %0|%0, %2}"
19956 [(set_attr "type" "sselog")
19957 (set_attr "mode" "TI")])
19958
19959 (define_insn "*sse2_iorti3"
19960 [(set (match_operand:TI 0 "register_operand" "=x")
19961 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19962 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19963 "TARGET_SSE2
19964 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19965 "por\t{%2, %0|%0, %2}"
19966 [(set_attr "type" "sselog")
19967 (set_attr "mode" "TI")])
19968
19969 (define_insn "sse2_iorv2di3"
19970 [(set (match_operand:V2DI 0 "register_operand" "=x")
19971 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19972 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19973 "TARGET_SSE2
19974 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19975 "por\t{%2, %0|%0, %2}"
19976 [(set_attr "type" "sselog")
19977 (set_attr "mode" "TI")])
19978
19979 (define_insn "*sse2_xorti3"
19980 [(set (match_operand:TI 0 "register_operand" "=x")
19981 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19982 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19983 "TARGET_SSE2
19984 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19985 "pxor\t{%2, %0|%0, %2}"
19986 [(set_attr "type" "sselog")
19987 (set_attr "mode" "TI")])
19988
19989 (define_insn "sse2_xorv2di3"
19990 [(set (match_operand:V2DI 0 "register_operand" "=x")
19991 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19992 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19993 "TARGET_SSE2
19994 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19995 "pxor\t{%2, %0|%0, %2}"
19996 [(set_attr "type" "sselog")
19997 (set_attr "mode" "TI")])
19998
19999 ;; Use xor, but don't show input operands so they aren't live before
20000 ;; this insn.
20001 (define_insn "sse_clrv4sf"
20002 [(set (match_operand:V4SF 0 "register_operand" "=x")
20003 (match_operand:V4SF 1 "const0_operand" "X"))]
20004 "TARGET_SSE"
20005 {
20006 if (get_attr_mode (insn) == MODE_TI)
20007 return "pxor\t{%0, %0|%0, %0}";
20008 else
20009 return "xorps\t{%0, %0|%0, %0}";
20010 }
20011 [(set_attr "type" "sselog")
20012 (set_attr "memory" "none")
20013 (set (attr "mode")
20014 (if_then_else
20015 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20016 (const_int 0))
20017 (ne (symbol_ref "TARGET_SSE2")
20018 (const_int 0)))
20019 (eq (symbol_ref "optimize_size")
20020 (const_int 0)))
20021 (const_string "TI")
20022 (const_string "V4SF")))])
20023
20024 ;; Use xor, but don't show input operands so they aren't live before
20025 ;; this insn.
20026 (define_insn "sse_clrv2df"
20027 [(set (match_operand:V2DF 0 "register_operand" "=x")
20028 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20029 "TARGET_SSE2"
20030 "xorpd\t{%0, %0|%0, %0}"
20031 [(set_attr "type" "sselog")
20032 (set_attr "memory" "none")
20033 (set_attr "mode" "V4SF")])
20034
20035 ;; SSE mask-generating compares
20036
20037 (define_insn "maskcmpv4sf3"
20038 [(set (match_operand:V4SI 0 "register_operand" "=x")
20039 (match_operator:V4SI 3 "sse_comparison_operator"
20040 [(match_operand:V4SF 1 "register_operand" "0")
20041 (match_operand:V4SF 2 "register_operand" "x")]))]
20042 "TARGET_SSE"
20043 "cmp%D3ps\t{%2, %0|%0, %2}"
20044 [(set_attr "type" "ssecmp")
20045 (set_attr "mode" "V4SF")])
20046
20047 (define_insn "maskncmpv4sf3"
20048 [(set (match_operand:V4SI 0 "register_operand" "=x")
20049 (not:V4SI
20050 (match_operator:V4SI 3 "sse_comparison_operator"
20051 [(match_operand:V4SF 1 "register_operand" "0")
20052 (match_operand:V4SF 2 "register_operand" "x")])))]
20053 "TARGET_SSE"
20054 {
20055 if (GET_CODE (operands[3]) == UNORDERED)
20056 return "cmpordps\t{%2, %0|%0, %2}";
20057 else
20058 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20059 }
20060 [(set_attr "type" "ssecmp")
20061 (set_attr "mode" "V4SF")])
20062
20063 (define_insn "vmmaskcmpv4sf3"
20064 [(set (match_operand:V4SI 0 "register_operand" "=x")
20065 (vec_merge:V4SI
20066 (match_operator:V4SI 3 "sse_comparison_operator"
20067 [(match_operand:V4SF 1 "register_operand" "0")
20068 (match_operand:V4SF 2 "register_operand" "x")])
20069 (subreg:V4SI (match_dup 1) 0)
20070 (const_int 1)))]
20071 "TARGET_SSE"
20072 "cmp%D3ss\t{%2, %0|%0, %2}"
20073 [(set_attr "type" "ssecmp")
20074 (set_attr "mode" "SF")])
20075
20076 (define_insn "vmmaskncmpv4sf3"
20077 [(set (match_operand:V4SI 0 "register_operand" "=x")
20078 (vec_merge:V4SI
20079 (not:V4SI
20080 (match_operator:V4SI 3 "sse_comparison_operator"
20081 [(match_operand:V4SF 1 "register_operand" "0")
20082 (match_operand:V4SF 2 "register_operand" "x")]))
20083 (subreg:V4SI (match_dup 1) 0)
20084 (const_int 1)))]
20085 "TARGET_SSE"
20086 {
20087 if (GET_CODE (operands[3]) == UNORDERED)
20088 return "cmpordss\t{%2, %0|%0, %2}";
20089 else
20090 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20091 }
20092 [(set_attr "type" "ssecmp")
20093 (set_attr "mode" "SF")])
20094
20095 (define_insn "sse_comi"
20096 [(set (reg:CCFP 17)
20097 (compare:CCFP (vec_select:SF
20098 (match_operand:V4SF 0 "register_operand" "x")
20099 (parallel [(const_int 0)]))
20100 (vec_select:SF
20101 (match_operand:V4SF 1 "register_operand" "x")
20102 (parallel [(const_int 0)]))))]
20103 "TARGET_SSE"
20104 "comiss\t{%1, %0|%0, %1}"
20105 [(set_attr "type" "ssecomi")
20106 (set_attr "mode" "SF")])
20107
20108 (define_insn "sse_ucomi"
20109 [(set (reg:CCFPU 17)
20110 (compare:CCFPU (vec_select:SF
20111 (match_operand:V4SF 0 "register_operand" "x")
20112 (parallel [(const_int 0)]))
20113 (vec_select:SF
20114 (match_operand:V4SF 1 "register_operand" "x")
20115 (parallel [(const_int 0)]))))]
20116 "TARGET_SSE"
20117 "ucomiss\t{%1, %0|%0, %1}"
20118 [(set_attr "type" "ssecomi")
20119 (set_attr "mode" "SF")])
20120
20121
20122 ;; SSE unpack
20123
20124 (define_insn "sse_unpckhps"
20125 [(set (match_operand:V4SF 0 "register_operand" "=x")
20126 (vec_merge:V4SF
20127 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20128 (parallel [(const_int 2)
20129 (const_int 0)
20130 (const_int 3)
20131 (const_int 1)]))
20132 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20133 (parallel [(const_int 0)
20134 (const_int 2)
20135 (const_int 1)
20136 (const_int 3)]))
20137 (const_int 5)))]
20138 "TARGET_SSE"
20139 "unpckhps\t{%2, %0|%0, %2}"
20140 [(set_attr "type" "ssecvt")
20141 (set_attr "mode" "V4SF")])
20142
20143 (define_insn "sse_unpcklps"
20144 [(set (match_operand:V4SF 0 "register_operand" "=x")
20145 (vec_merge:V4SF
20146 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20147 (parallel [(const_int 0)
20148 (const_int 2)
20149 (const_int 1)
20150 (const_int 3)]))
20151 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20152 (parallel [(const_int 2)
20153 (const_int 0)
20154 (const_int 3)
20155 (const_int 1)]))
20156 (const_int 5)))]
20157 "TARGET_SSE"
20158 "unpcklps\t{%2, %0|%0, %2}"
20159 [(set_attr "type" "ssecvt")
20160 (set_attr "mode" "V4SF")])
20161
20162
20163 ;; SSE min/max
20164
20165 (define_insn "smaxv4sf3"
20166 [(set (match_operand:V4SF 0 "register_operand" "=x")
20167 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20168 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20169 "TARGET_SSE"
20170 "maxps\t{%2, %0|%0, %2}"
20171 [(set_attr "type" "sse")
20172 (set_attr "mode" "V4SF")])
20173
20174 (define_insn "vmsmaxv4sf3"
20175 [(set (match_operand:V4SF 0 "register_operand" "=x")
20176 (vec_merge:V4SF
20177 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20178 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20179 (match_dup 1)
20180 (const_int 1)))]
20181 "TARGET_SSE"
20182 "maxss\t{%2, %0|%0, %2}"
20183 [(set_attr "type" "sse")
20184 (set_attr "mode" "SF")])
20185
20186 (define_insn "sminv4sf3"
20187 [(set (match_operand:V4SF 0 "register_operand" "=x")
20188 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20189 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20190 "TARGET_SSE"
20191 "minps\t{%2, %0|%0, %2}"
20192 [(set_attr "type" "sse")
20193 (set_attr "mode" "V4SF")])
20194
20195 (define_insn "vmsminv4sf3"
20196 [(set (match_operand:V4SF 0 "register_operand" "=x")
20197 (vec_merge:V4SF
20198 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20199 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20200 (match_dup 1)
20201 (const_int 1)))]
20202 "TARGET_SSE"
20203 "minss\t{%2, %0|%0, %2}"
20204 [(set_attr "type" "sse")
20205 (set_attr "mode" "SF")])
20206
20207 ;; SSE <-> integer/MMX conversions
20208
20209 (define_insn "cvtpi2ps"
20210 [(set (match_operand:V4SF 0 "register_operand" "=x")
20211 (vec_merge:V4SF
20212 (match_operand:V4SF 1 "register_operand" "0")
20213 (vec_duplicate:V4SF
20214 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20215 (const_int 12)))]
20216 "TARGET_SSE"
20217 "cvtpi2ps\t{%2, %0|%0, %2}"
20218 [(set_attr "type" "ssecvt")
20219 (set_attr "mode" "V4SF")])
20220
20221 (define_insn "cvtps2pi"
20222 [(set (match_operand:V2SI 0 "register_operand" "=y")
20223 (vec_select:V2SI
20224 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20225 (parallel [(const_int 0) (const_int 1)])))]
20226 "TARGET_SSE"
20227 "cvtps2pi\t{%1, %0|%0, %1}"
20228 [(set_attr "type" "ssecvt")
20229 (set_attr "mode" "V4SF")])
20230
20231 (define_insn "cvttps2pi"
20232 [(set (match_operand:V2SI 0 "register_operand" "=y")
20233 (vec_select:V2SI
20234 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20235 UNSPEC_FIX)
20236 (parallel [(const_int 0) (const_int 1)])))]
20237 "TARGET_SSE"
20238 "cvttps2pi\t{%1, %0|%0, %1}"
20239 [(set_attr "type" "ssecvt")
20240 (set_attr "mode" "SF")])
20241
20242 (define_insn "cvtsi2ss"
20243 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20244 (vec_merge:V4SF
20245 (match_operand:V4SF 1 "register_operand" "0,0")
20246 (vec_duplicate:V4SF
20247 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20248 (const_int 14)))]
20249 "TARGET_SSE"
20250 "cvtsi2ss\t{%2, %0|%0, %2}"
20251 [(set_attr "type" "sseicvt")
20252 (set_attr "athlon_decode" "vector,double")
20253 (set_attr "mode" "SF")])
20254
20255 (define_insn "cvtsi2ssq"
20256 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20257 (vec_merge:V4SF
20258 (match_operand:V4SF 1 "register_operand" "0,0")
20259 (vec_duplicate:V4SF
20260 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20261 (const_int 14)))]
20262 "TARGET_SSE && TARGET_64BIT"
20263 "cvtsi2ssq\t{%2, %0|%0, %2}"
20264 [(set_attr "type" "sseicvt")
20265 (set_attr "athlon_decode" "vector,double")
20266 (set_attr "mode" "SF")])
20267
20268 (define_insn "cvtss2si"
20269 [(set (match_operand:SI 0 "register_operand" "=r,r")
20270 (vec_select:SI
20271 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20272 (parallel [(const_int 0)])))]
20273 "TARGET_SSE"
20274 "cvtss2si\t{%1, %0|%0, %1}"
20275 [(set_attr "type" "sseicvt")
20276 (set_attr "athlon_decode" "double,vector")
20277 (set_attr "mode" "SI")])
20278
20279 (define_insn "cvtss2siq"
20280 [(set (match_operand:DI 0 "register_operand" "=r,r")
20281 (vec_select:DI
20282 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20283 (parallel [(const_int 0)])))]
20284 "TARGET_SSE"
20285 "cvtss2siq\t{%1, %0|%0, %1}"
20286 [(set_attr "type" "sseicvt")
20287 (set_attr "athlon_decode" "double,vector")
20288 (set_attr "mode" "DI")])
20289
20290 (define_insn "cvttss2si"
20291 [(set (match_operand:SI 0 "register_operand" "=r,r")
20292 (vec_select:SI
20293 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20294 UNSPEC_FIX)
20295 (parallel [(const_int 0)])))]
20296 "TARGET_SSE"
20297 "cvttss2si\t{%1, %0|%0, %1}"
20298 [(set_attr "type" "sseicvt")
20299 (set_attr "mode" "SF")
20300 (set_attr "athlon_decode" "double,vector")])
20301
20302 (define_insn "cvttss2siq"
20303 [(set (match_operand:DI 0 "register_operand" "=r,r")
20304 (vec_select:DI
20305 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20306 UNSPEC_FIX)
20307 (parallel [(const_int 0)])))]
20308 "TARGET_SSE && TARGET_64BIT"
20309 "cvttss2siq\t{%1, %0|%0, %1}"
20310 [(set_attr "type" "sseicvt")
20311 (set_attr "mode" "SF")
20312 (set_attr "athlon_decode" "double,vector")])
20313
20314
20315 ;; MMX insns
20316
20317 ;; MMX arithmetic
20318
20319 (define_insn "addv8qi3"
20320 [(set (match_operand:V8QI 0 "register_operand" "=y")
20321 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20322 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20323 "TARGET_MMX"
20324 "paddb\t{%2, %0|%0, %2}"
20325 [(set_attr "type" "mmxadd")
20326 (set_attr "mode" "DI")])
20327
20328 (define_insn "addv4hi3"
20329 [(set (match_operand:V4HI 0 "register_operand" "=y")
20330 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20331 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20332 "TARGET_MMX"
20333 "paddw\t{%2, %0|%0, %2}"
20334 [(set_attr "type" "mmxadd")
20335 (set_attr "mode" "DI")])
20336
20337 (define_insn "addv2si3"
20338 [(set (match_operand:V2SI 0 "register_operand" "=y")
20339 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20340 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20341 "TARGET_MMX"
20342 "paddd\t{%2, %0|%0, %2}"
20343 [(set_attr "type" "mmxadd")
20344 (set_attr "mode" "DI")])
20345
20346 (define_insn "mmx_adddi3"
20347 [(set (match_operand:DI 0 "register_operand" "=y")
20348 (unspec:DI
20349 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20350 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20351 UNSPEC_NOP))]
20352 "TARGET_MMX"
20353 "paddq\t{%2, %0|%0, %2}"
20354 [(set_attr "type" "mmxadd")
20355 (set_attr "mode" "DI")])
20356
20357 (define_insn "ssaddv8qi3"
20358 [(set (match_operand:V8QI 0 "register_operand" "=y")
20359 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20360 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20361 "TARGET_MMX"
20362 "paddsb\t{%2, %0|%0, %2}"
20363 [(set_attr "type" "mmxadd")
20364 (set_attr "mode" "DI")])
20365
20366 (define_insn "ssaddv4hi3"
20367 [(set (match_operand:V4HI 0 "register_operand" "=y")
20368 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20369 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20370 "TARGET_MMX"
20371 "paddsw\t{%2, %0|%0, %2}"
20372 [(set_attr "type" "mmxadd")
20373 (set_attr "mode" "DI")])
20374
20375 (define_insn "usaddv8qi3"
20376 [(set (match_operand:V8QI 0 "register_operand" "=y")
20377 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20378 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20379 "TARGET_MMX"
20380 "paddusb\t{%2, %0|%0, %2}"
20381 [(set_attr "type" "mmxadd")
20382 (set_attr "mode" "DI")])
20383
20384 (define_insn "usaddv4hi3"
20385 [(set (match_operand:V4HI 0 "register_operand" "=y")
20386 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20387 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20388 "TARGET_MMX"
20389 "paddusw\t{%2, %0|%0, %2}"
20390 [(set_attr "type" "mmxadd")
20391 (set_attr "mode" "DI")])
20392
20393 (define_insn "subv8qi3"
20394 [(set (match_operand:V8QI 0 "register_operand" "=y")
20395 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20396 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20397 "TARGET_MMX"
20398 "psubb\t{%2, %0|%0, %2}"
20399 [(set_attr "type" "mmxadd")
20400 (set_attr "mode" "DI")])
20401
20402 (define_insn "subv4hi3"
20403 [(set (match_operand:V4HI 0 "register_operand" "=y")
20404 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20405 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20406 "TARGET_MMX"
20407 "psubw\t{%2, %0|%0, %2}"
20408 [(set_attr "type" "mmxadd")
20409 (set_attr "mode" "DI")])
20410
20411 (define_insn "subv2si3"
20412 [(set (match_operand:V2SI 0 "register_operand" "=y")
20413 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20414 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20415 "TARGET_MMX"
20416 "psubd\t{%2, %0|%0, %2}"
20417 [(set_attr "type" "mmxadd")
20418 (set_attr "mode" "DI")])
20419
20420 (define_insn "mmx_subdi3"
20421 [(set (match_operand:DI 0 "register_operand" "=y")
20422 (unspec:DI
20423 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20424 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20425 UNSPEC_NOP))]
20426 "TARGET_MMX"
20427 "psubq\t{%2, %0|%0, %2}"
20428 [(set_attr "type" "mmxadd")
20429 (set_attr "mode" "DI")])
20430
20431 (define_insn "sssubv8qi3"
20432 [(set (match_operand:V8QI 0 "register_operand" "=y")
20433 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20434 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20435 "TARGET_MMX"
20436 "psubsb\t{%2, %0|%0, %2}"
20437 [(set_attr "type" "mmxadd")
20438 (set_attr "mode" "DI")])
20439
20440 (define_insn "sssubv4hi3"
20441 [(set (match_operand:V4HI 0 "register_operand" "=y")
20442 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20443 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20444 "TARGET_MMX"
20445 "psubsw\t{%2, %0|%0, %2}"
20446 [(set_attr "type" "mmxadd")
20447 (set_attr "mode" "DI")])
20448
20449 (define_insn "ussubv8qi3"
20450 [(set (match_operand:V8QI 0 "register_operand" "=y")
20451 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20452 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20453 "TARGET_MMX"
20454 "psubusb\t{%2, %0|%0, %2}"
20455 [(set_attr "type" "mmxadd")
20456 (set_attr "mode" "DI")])
20457
20458 (define_insn "ussubv4hi3"
20459 [(set (match_operand:V4HI 0 "register_operand" "=y")
20460 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20461 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20462 "TARGET_MMX"
20463 "psubusw\t{%2, %0|%0, %2}"
20464 [(set_attr "type" "mmxadd")
20465 (set_attr "mode" "DI")])
20466
20467 (define_insn "mulv4hi3"
20468 [(set (match_operand:V4HI 0 "register_operand" "=y")
20469 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20470 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20471 "TARGET_MMX"
20472 "pmullw\t{%2, %0|%0, %2}"
20473 [(set_attr "type" "mmxmul")
20474 (set_attr "mode" "DI")])
20475
20476 (define_insn "smulv4hi3_highpart"
20477 [(set (match_operand:V4HI 0 "register_operand" "=y")
20478 (truncate:V4HI
20479 (lshiftrt:V4SI
20480 (mult:V4SI (sign_extend:V4SI
20481 (match_operand:V4HI 1 "register_operand" "0"))
20482 (sign_extend:V4SI
20483 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20484 (const_int 16))))]
20485 "TARGET_MMX"
20486 "pmulhw\t{%2, %0|%0, %2}"
20487 [(set_attr "type" "mmxmul")
20488 (set_attr "mode" "DI")])
20489
20490 (define_insn "umulv4hi3_highpart"
20491 [(set (match_operand:V4HI 0 "register_operand" "=y")
20492 (truncate:V4HI
20493 (lshiftrt:V4SI
20494 (mult:V4SI (zero_extend:V4SI
20495 (match_operand:V4HI 1 "register_operand" "0"))
20496 (zero_extend:V4SI
20497 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20498 (const_int 16))))]
20499 "TARGET_SSE || TARGET_3DNOW_A"
20500 "pmulhuw\t{%2, %0|%0, %2}"
20501 [(set_attr "type" "mmxmul")
20502 (set_attr "mode" "DI")])
20503
20504 (define_insn "mmx_pmaddwd"
20505 [(set (match_operand:V2SI 0 "register_operand" "=y")
20506 (plus:V2SI
20507 (mult:V2SI
20508 (sign_extend:V2SI
20509 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20510 (parallel [(const_int 0) (const_int 2)])))
20511 (sign_extend:V2SI
20512 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20513 (parallel [(const_int 0) (const_int 2)]))))
20514 (mult:V2SI
20515 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20516 (parallel [(const_int 1)
20517 (const_int 3)])))
20518 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20519 (parallel [(const_int 1)
20520 (const_int 3)]))))))]
20521 "TARGET_MMX"
20522 "pmaddwd\t{%2, %0|%0, %2}"
20523 [(set_attr "type" "mmxmul")
20524 (set_attr "mode" "DI")])
20525
20526
20527 ;; MMX logical operations
20528 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20529 ;; normal code that also wants to use the FPU from getting broken.
20530 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20531 (define_insn "mmx_iordi3"
20532 [(set (match_operand:DI 0 "register_operand" "=y")
20533 (unspec:DI
20534 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20535 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20536 UNSPEC_NOP))]
20537 "TARGET_MMX"
20538 "por\t{%2, %0|%0, %2}"
20539 [(set_attr "type" "mmxadd")
20540 (set_attr "mode" "DI")])
20541
20542 (define_insn "mmx_xordi3"
20543 [(set (match_operand:DI 0 "register_operand" "=y")
20544 (unspec:DI
20545 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20546 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20547 UNSPEC_NOP))]
20548 "TARGET_MMX"
20549 "pxor\t{%2, %0|%0, %2}"
20550 [(set_attr "type" "mmxadd")
20551 (set_attr "mode" "DI")
20552 (set_attr "memory" "none")])
20553
20554 ;; Same as pxor, but don't show input operands so that we don't think
20555 ;; they are live.
20556 (define_insn "mmx_clrdi"
20557 [(set (match_operand:DI 0 "register_operand" "=y")
20558 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20559 "TARGET_MMX"
20560 "pxor\t{%0, %0|%0, %0}"
20561 [(set_attr "type" "mmxadd")
20562 (set_attr "mode" "DI")
20563 (set_attr "memory" "none")])
20564
20565 (define_insn "mmx_anddi3"
20566 [(set (match_operand:DI 0 "register_operand" "=y")
20567 (unspec:DI
20568 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20569 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20570 UNSPEC_NOP))]
20571 "TARGET_MMX"
20572 "pand\t{%2, %0|%0, %2}"
20573 [(set_attr "type" "mmxadd")
20574 (set_attr "mode" "DI")])
20575
20576 (define_insn "mmx_nanddi3"
20577 [(set (match_operand:DI 0 "register_operand" "=y")
20578 (unspec:DI
20579 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20580 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20581 UNSPEC_NOP))]
20582 "TARGET_MMX"
20583 "pandn\t{%2, %0|%0, %2}"
20584 [(set_attr "type" "mmxadd")
20585 (set_attr "mode" "DI")])
20586
20587
20588 ;; MMX unsigned averages/sum of absolute differences
20589
20590 (define_insn "mmx_uavgv8qi3"
20591 [(set (match_operand:V8QI 0 "register_operand" "=y")
20592 (ashiftrt:V8QI
20593 (plus:V8QI (plus:V8QI
20594 (match_operand:V8QI 1 "register_operand" "0")
20595 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20596 (const_vector:V8QI [(const_int 1)
20597 (const_int 1)
20598 (const_int 1)
20599 (const_int 1)
20600 (const_int 1)
20601 (const_int 1)
20602 (const_int 1)
20603 (const_int 1)]))
20604 (const_int 1)))]
20605 "TARGET_SSE || TARGET_3DNOW_A"
20606 "pavgb\t{%2, %0|%0, %2}"
20607 [(set_attr "type" "mmxshft")
20608 (set_attr "mode" "DI")])
20609
20610 (define_insn "mmx_uavgv4hi3"
20611 [(set (match_operand:V4HI 0 "register_operand" "=y")
20612 (ashiftrt:V4HI
20613 (plus:V4HI (plus:V4HI
20614 (match_operand:V4HI 1 "register_operand" "0")
20615 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20616 (const_vector:V4HI [(const_int 1)
20617 (const_int 1)
20618 (const_int 1)
20619 (const_int 1)]))
20620 (const_int 1)))]
20621 "TARGET_SSE || TARGET_3DNOW_A"
20622 "pavgw\t{%2, %0|%0, %2}"
20623 [(set_attr "type" "mmxshft")
20624 (set_attr "mode" "DI")])
20625
20626 (define_insn "mmx_psadbw"
20627 [(set (match_operand:DI 0 "register_operand" "=y")
20628 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20629 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20630 UNSPEC_PSADBW))]
20631 "TARGET_SSE || TARGET_3DNOW_A"
20632 "psadbw\t{%2, %0|%0, %2}"
20633 [(set_attr "type" "mmxshft")
20634 (set_attr "mode" "DI")])
20635
20636
20637 ;; MMX insert/extract/shuffle
20638
20639 (define_insn "mmx_pinsrw"
20640 [(set (match_operand:V4HI 0 "register_operand" "=y")
20641 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20642 (vec_duplicate:V4HI
20643 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20644 (match_operand:SI 3 "immediate_operand" "i")))]
20645 "TARGET_SSE || TARGET_3DNOW_A"
20646 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20647 [(set_attr "type" "mmxcvt")
20648 (set_attr "mode" "DI")])
20649
20650 (define_insn "mmx_pextrw"
20651 [(set (match_operand:SI 0 "register_operand" "=r")
20652 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20653 (parallel
20654 [(match_operand:SI 2 "immediate_operand" "i")]))))]
20655 "TARGET_SSE || TARGET_3DNOW_A"
20656 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20657 [(set_attr "type" "mmxcvt")
20658 (set_attr "mode" "DI")])
20659
20660 (define_insn "mmx_pshufw"
20661 [(set (match_operand:V4HI 0 "register_operand" "=y")
20662 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20663 (match_operand:SI 2 "immediate_operand" "i")]
20664 UNSPEC_SHUFFLE))]
20665 "TARGET_SSE || TARGET_3DNOW_A"
20666 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20667 [(set_attr "type" "mmxcvt")
20668 (set_attr "mode" "DI")])
20669
20670
20671 ;; MMX mask-generating comparisons
20672
20673 (define_insn "eqv8qi3"
20674 [(set (match_operand:V8QI 0 "register_operand" "=y")
20675 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20676 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20677 "TARGET_MMX"
20678 "pcmpeqb\t{%2, %0|%0, %2}"
20679 [(set_attr "type" "mmxcmp")
20680 (set_attr "mode" "DI")])
20681
20682 (define_insn "eqv4hi3"
20683 [(set (match_operand:V4HI 0 "register_operand" "=y")
20684 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20685 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20686 "TARGET_MMX"
20687 "pcmpeqw\t{%2, %0|%0, %2}"
20688 [(set_attr "type" "mmxcmp")
20689 (set_attr "mode" "DI")])
20690
20691 (define_insn "eqv2si3"
20692 [(set (match_operand:V2SI 0 "register_operand" "=y")
20693 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20694 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20695 "TARGET_MMX"
20696 "pcmpeqd\t{%2, %0|%0, %2}"
20697 [(set_attr "type" "mmxcmp")
20698 (set_attr "mode" "DI")])
20699
20700 (define_insn "gtv8qi3"
20701 [(set (match_operand:V8QI 0 "register_operand" "=y")
20702 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20703 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20704 "TARGET_MMX"
20705 "pcmpgtb\t{%2, %0|%0, %2}"
20706 [(set_attr "type" "mmxcmp")
20707 (set_attr "mode" "DI")])
20708
20709 (define_insn "gtv4hi3"
20710 [(set (match_operand:V4HI 0 "register_operand" "=y")
20711 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20712 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20713 "TARGET_MMX"
20714 "pcmpgtw\t{%2, %0|%0, %2}"
20715 [(set_attr "type" "mmxcmp")
20716 (set_attr "mode" "DI")])
20717
20718 (define_insn "gtv2si3"
20719 [(set (match_operand:V2SI 0 "register_operand" "=y")
20720 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20721 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20722 "TARGET_MMX"
20723 "pcmpgtd\t{%2, %0|%0, %2}"
20724 [(set_attr "type" "mmxcmp")
20725 (set_attr "mode" "DI")])
20726
20727
20728 ;; MMX max/min insns
20729
20730 (define_insn "umaxv8qi3"
20731 [(set (match_operand:V8QI 0 "register_operand" "=y")
20732 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20733 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20734 "TARGET_SSE || TARGET_3DNOW_A"
20735 "pmaxub\t{%2, %0|%0, %2}"
20736 [(set_attr "type" "mmxadd")
20737 (set_attr "mode" "DI")])
20738
20739 (define_insn "smaxv4hi3"
20740 [(set (match_operand:V4HI 0 "register_operand" "=y")
20741 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20742 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20743 "TARGET_SSE || TARGET_3DNOW_A"
20744 "pmaxsw\t{%2, %0|%0, %2}"
20745 [(set_attr "type" "mmxadd")
20746 (set_attr "mode" "DI")])
20747
20748 (define_insn "uminv8qi3"
20749 [(set (match_operand:V8QI 0 "register_operand" "=y")
20750 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20751 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20752 "TARGET_SSE || TARGET_3DNOW_A"
20753 "pminub\t{%2, %0|%0, %2}"
20754 [(set_attr "type" "mmxadd")
20755 (set_attr "mode" "DI")])
20756
20757 (define_insn "sminv4hi3"
20758 [(set (match_operand:V4HI 0 "register_operand" "=y")
20759 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20760 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20761 "TARGET_SSE || TARGET_3DNOW_A"
20762 "pminsw\t{%2, %0|%0, %2}"
20763 [(set_attr "type" "mmxadd")
20764 (set_attr "mode" "DI")])
20765
20766
20767 ;; MMX shifts
20768
20769 (define_insn "ashrv4hi3"
20770 [(set (match_operand:V4HI 0 "register_operand" "=y")
20771 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20772 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20773 "TARGET_MMX"
20774 "psraw\t{%2, %0|%0, %2}"
20775 [(set_attr "type" "mmxshft")
20776 (set_attr "mode" "DI")])
20777
20778 (define_insn "ashrv2si3"
20779 [(set (match_operand:V2SI 0 "register_operand" "=y")
20780 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20781 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20782 "TARGET_MMX"
20783 "psrad\t{%2, %0|%0, %2}"
20784 [(set_attr "type" "mmxshft")
20785 (set_attr "mode" "DI")])
20786
20787 (define_insn "lshrv4hi3"
20788 [(set (match_operand:V4HI 0 "register_operand" "=y")
20789 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20790 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20791 "TARGET_MMX"
20792 "psrlw\t{%2, %0|%0, %2}"
20793 [(set_attr "type" "mmxshft")
20794 (set_attr "mode" "DI")])
20795
20796 (define_insn "lshrv2si3"
20797 [(set (match_operand:V2SI 0 "register_operand" "=y")
20798 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20799 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20800 "TARGET_MMX"
20801 "psrld\t{%2, %0|%0, %2}"
20802 [(set_attr "type" "mmxshft")
20803 (set_attr "mode" "DI")])
20804
20805 ;; See logical MMX insns.
20806 (define_insn "mmx_lshrdi3"
20807 [(set (match_operand:DI 0 "register_operand" "=y")
20808 (unspec:DI
20809 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20810 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20811 UNSPEC_NOP))]
20812 "TARGET_MMX"
20813 "psrlq\t{%2, %0|%0, %2}"
20814 [(set_attr "type" "mmxshft")
20815 (set_attr "mode" "DI")])
20816
20817 (define_insn "ashlv4hi3"
20818 [(set (match_operand:V4HI 0 "register_operand" "=y")
20819 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20820 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20821 "TARGET_MMX"
20822 "psllw\t{%2, %0|%0, %2}"
20823 [(set_attr "type" "mmxshft")
20824 (set_attr "mode" "DI")])
20825
20826 (define_insn "ashlv2si3"
20827 [(set (match_operand:V2SI 0 "register_operand" "=y")
20828 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20829 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20830 "TARGET_MMX"
20831 "pslld\t{%2, %0|%0, %2}"
20832 [(set_attr "type" "mmxshft")
20833 (set_attr "mode" "DI")])
20834
20835 ;; See logical MMX insns.
20836 (define_insn "mmx_ashldi3"
20837 [(set (match_operand:DI 0 "register_operand" "=y")
20838 (unspec:DI
20839 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20840 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20841 UNSPEC_NOP))]
20842 "TARGET_MMX"
20843 "psllq\t{%2, %0|%0, %2}"
20844 [(set_attr "type" "mmxshft")
20845 (set_attr "mode" "DI")])
20846
20847
20848 ;; MMX pack/unpack insns.
20849
20850 (define_insn "mmx_packsswb"
20851 [(set (match_operand:V8QI 0 "register_operand" "=y")
20852 (vec_concat:V8QI
20853 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20854 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20855 "TARGET_MMX"
20856 "packsswb\t{%2, %0|%0, %2}"
20857 [(set_attr "type" "mmxshft")
20858 (set_attr "mode" "DI")])
20859
20860 (define_insn "mmx_packssdw"
20861 [(set (match_operand:V4HI 0 "register_operand" "=y")
20862 (vec_concat:V4HI
20863 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20864 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20865 "TARGET_MMX"
20866 "packssdw\t{%2, %0|%0, %2}"
20867 [(set_attr "type" "mmxshft")
20868 (set_attr "mode" "DI")])
20869
20870 (define_insn "mmx_packuswb"
20871 [(set (match_operand:V8QI 0 "register_operand" "=y")
20872 (vec_concat:V8QI
20873 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20874 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20875 "TARGET_MMX"
20876 "packuswb\t{%2, %0|%0, %2}"
20877 [(set_attr "type" "mmxshft")
20878 (set_attr "mode" "DI")])
20879
20880 (define_insn "mmx_punpckhbw"
20881 [(set (match_operand:V8QI 0 "register_operand" "=y")
20882 (vec_merge:V8QI
20883 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20884 (parallel [(const_int 4)
20885 (const_int 0)
20886 (const_int 5)
20887 (const_int 1)
20888 (const_int 6)
20889 (const_int 2)
20890 (const_int 7)
20891 (const_int 3)]))
20892 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20893 (parallel [(const_int 0)
20894 (const_int 4)
20895 (const_int 1)
20896 (const_int 5)
20897 (const_int 2)
20898 (const_int 6)
20899 (const_int 3)
20900 (const_int 7)]))
20901 (const_int 85)))]
20902 "TARGET_MMX"
20903 "punpckhbw\t{%2, %0|%0, %2}"
20904 [(set_attr "type" "mmxcvt")
20905 (set_attr "mode" "DI")])
20906
20907 (define_insn "mmx_punpckhwd"
20908 [(set (match_operand:V4HI 0 "register_operand" "=y")
20909 (vec_merge:V4HI
20910 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20911 (parallel [(const_int 0)
20912 (const_int 2)
20913 (const_int 1)
20914 (const_int 3)]))
20915 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20916 (parallel [(const_int 2)
20917 (const_int 0)
20918 (const_int 3)
20919 (const_int 1)]))
20920 (const_int 5)))]
20921 "TARGET_MMX"
20922 "punpckhwd\t{%2, %0|%0, %2}"
20923 [(set_attr "type" "mmxcvt")
20924 (set_attr "mode" "DI")])
20925
20926 (define_insn "mmx_punpckhdq"
20927 [(set (match_operand:V2SI 0 "register_operand" "=y")
20928 (vec_merge:V2SI
20929 (match_operand:V2SI 1 "register_operand" "0")
20930 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20931 (parallel [(const_int 1)
20932 (const_int 0)]))
20933 (const_int 1)))]
20934 "TARGET_MMX"
20935 "punpckhdq\t{%2, %0|%0, %2}"
20936 [(set_attr "type" "mmxcvt")
20937 (set_attr "mode" "DI")])
20938
20939 (define_insn "mmx_punpcklbw"
20940 [(set (match_operand:V8QI 0 "register_operand" "=y")
20941 (vec_merge:V8QI
20942 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20943 (parallel [(const_int 0)
20944 (const_int 4)
20945 (const_int 1)
20946 (const_int 5)
20947 (const_int 2)
20948 (const_int 6)
20949 (const_int 3)
20950 (const_int 7)]))
20951 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20952 (parallel [(const_int 4)
20953 (const_int 0)
20954 (const_int 5)
20955 (const_int 1)
20956 (const_int 6)
20957 (const_int 2)
20958 (const_int 7)
20959 (const_int 3)]))
20960 (const_int 85)))]
20961 "TARGET_MMX"
20962 "punpcklbw\t{%2, %0|%0, %2}"
20963 [(set_attr "type" "mmxcvt")
20964 (set_attr "mode" "DI")])
20965
20966 (define_insn "mmx_punpcklwd"
20967 [(set (match_operand:V4HI 0 "register_operand" "=y")
20968 (vec_merge:V4HI
20969 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20970 (parallel [(const_int 2)
20971 (const_int 0)
20972 (const_int 3)
20973 (const_int 1)]))
20974 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20975 (parallel [(const_int 0)
20976 (const_int 2)
20977 (const_int 1)
20978 (const_int 3)]))
20979 (const_int 5)))]
20980 "TARGET_MMX"
20981 "punpcklwd\t{%2, %0|%0, %2}"
20982 [(set_attr "type" "mmxcvt")
20983 (set_attr "mode" "DI")])
20984
20985 (define_insn "mmx_punpckldq"
20986 [(set (match_operand:V2SI 0 "register_operand" "=y")
20987 (vec_merge:V2SI
20988 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20989 (parallel [(const_int 1)
20990 (const_int 0)]))
20991 (match_operand:V2SI 2 "register_operand" "y")
20992 (const_int 1)))]
20993 "TARGET_MMX"
20994 "punpckldq\t{%2, %0|%0, %2}"
20995 [(set_attr "type" "mmxcvt")
20996 (set_attr "mode" "DI")])
20997
20998
20999 ;; Miscellaneous stuff
21000
21001 (define_insn "emms"
21002 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21003 (clobber (reg:XF 8))
21004 (clobber (reg:XF 9))
21005 (clobber (reg:XF 10))
21006 (clobber (reg:XF 11))
21007 (clobber (reg:XF 12))
21008 (clobber (reg:XF 13))
21009 (clobber (reg:XF 14))
21010 (clobber (reg:XF 15))
21011 (clobber (reg:DI 29))
21012 (clobber (reg:DI 30))
21013 (clobber (reg:DI 31))
21014 (clobber (reg:DI 32))
21015 (clobber (reg:DI 33))
21016 (clobber (reg:DI 34))
21017 (clobber (reg:DI 35))
21018 (clobber (reg:DI 36))]
21019 "TARGET_MMX"
21020 "emms"
21021 [(set_attr "type" "mmx")
21022 (set_attr "memory" "unknown")])
21023
21024 (define_insn "ldmxcsr"
21025 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21026 UNSPECV_LDMXCSR)]
21027 "TARGET_SSE"
21028 "ldmxcsr\t%0"
21029 [(set_attr "type" "sse")
21030 (set_attr "memory" "load")])
21031
21032 (define_insn "stmxcsr"
21033 [(set (match_operand:SI 0 "memory_operand" "=m")
21034 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21035 "TARGET_SSE"
21036 "stmxcsr\t%0"
21037 [(set_attr "type" "sse")
21038 (set_attr "memory" "store")])
21039
21040 (define_expand "sfence"
21041 [(set (match_dup 0)
21042 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21043 "TARGET_SSE || TARGET_3DNOW_A"
21044 {
21045 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21046 MEM_VOLATILE_P (operands[0]) = 1;
21047 })
21048
21049 (define_insn "*sfence_insn"
21050 [(set (match_operand:BLK 0 "" "")
21051 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21052 "TARGET_SSE || TARGET_3DNOW_A"
21053 "sfence"
21054 [(set_attr "type" "sse")
21055 (set_attr "memory" "unknown")])
21056
21057 (define_expand "sse_prologue_save"
21058 [(parallel [(set (match_operand:BLK 0 "" "")
21059 (unspec:BLK [(reg:DI 21)
21060 (reg:DI 22)
21061 (reg:DI 23)
21062 (reg:DI 24)
21063 (reg:DI 25)
21064 (reg:DI 26)
21065 (reg:DI 27)
21066 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21067 (use (match_operand:DI 1 "register_operand" ""))
21068 (use (match_operand:DI 2 "immediate_operand" ""))
21069 (use (label_ref:DI (match_operand 3 "" "")))])]
21070 "TARGET_64BIT"
21071 "")
21072
21073 (define_insn "*sse_prologue_save_insn"
21074 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21075 (match_operand:DI 4 "const_int_operand" "n")))
21076 (unspec:BLK [(reg:DI 21)
21077 (reg:DI 22)
21078 (reg:DI 23)
21079 (reg:DI 24)
21080 (reg:DI 25)
21081 (reg:DI 26)
21082 (reg:DI 27)
21083 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21084 (use (match_operand:DI 1 "register_operand" "r"))
21085 (use (match_operand:DI 2 "const_int_operand" "i"))
21086 (use (label_ref:DI (match_operand 3 "" "X")))]
21087 "TARGET_64BIT
21088 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21089 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21090 "*
21091 {
21092 int i;
21093 operands[0] = gen_rtx_MEM (Pmode,
21094 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21095 output_asm_insn (\"jmp\\t%A1\", operands);
21096 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21097 {
21098 operands[4] = adjust_address (operands[0], DImode, i*16);
21099 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21100 PUT_MODE (operands[4], TImode);
21101 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21102 output_asm_insn (\"rex\", operands);
21103 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21104 }
21105 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21106 CODE_LABEL_NUMBER (operands[3]));
21107 RET;
21108 }
21109 "
21110 [(set_attr "type" "other")
21111 (set_attr "length_immediate" "0")
21112 (set_attr "length_address" "0")
21113 (set_attr "length" "135")
21114 (set_attr "memory" "store")
21115 (set_attr "modrm" "0")
21116 (set_attr "mode" "DI")])
21117
21118 ;; 3Dnow! instructions
21119
21120 (define_insn "addv2sf3"
21121 [(set (match_operand:V2SF 0 "register_operand" "=y")
21122 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21123 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21124 "TARGET_3DNOW"
21125 "pfadd\\t{%2, %0|%0, %2}"
21126 [(set_attr "type" "mmxadd")
21127 (set_attr "mode" "V2SF")])
21128
21129 (define_insn "subv2sf3"
21130 [(set (match_operand:V2SF 0 "register_operand" "=y")
21131 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21132 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21133 "TARGET_3DNOW"
21134 "pfsub\\t{%2, %0|%0, %2}"
21135 [(set_attr "type" "mmxadd")
21136 (set_attr "mode" "V2SF")])
21137
21138 (define_insn "subrv2sf3"
21139 [(set (match_operand:V2SF 0 "register_operand" "=y")
21140 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21141 (match_operand:V2SF 1 "register_operand" "0")))]
21142 "TARGET_3DNOW"
21143 "pfsubr\\t{%2, %0|%0, %2}"
21144 [(set_attr "type" "mmxadd")
21145 (set_attr "mode" "V2SF")])
21146
21147 (define_insn "gtv2sf3"
21148 [(set (match_operand:V2SI 0 "register_operand" "=y")
21149 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21150 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21151 "TARGET_3DNOW"
21152 "pfcmpgt\\t{%2, %0|%0, %2}"
21153 [(set_attr "type" "mmxcmp")
21154 (set_attr "mode" "V2SF")])
21155
21156 (define_insn "gev2sf3"
21157 [(set (match_operand:V2SI 0 "register_operand" "=y")
21158 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21159 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21160 "TARGET_3DNOW"
21161 "pfcmpge\\t{%2, %0|%0, %2}"
21162 [(set_attr "type" "mmxcmp")
21163 (set_attr "mode" "V2SF")])
21164
21165 (define_insn "eqv2sf3"
21166 [(set (match_operand:V2SI 0 "register_operand" "=y")
21167 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21168 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21169 "TARGET_3DNOW"
21170 "pfcmpeq\\t{%2, %0|%0, %2}"
21171 [(set_attr "type" "mmxcmp")
21172 (set_attr "mode" "V2SF")])
21173
21174 (define_insn "pfmaxv2sf3"
21175 [(set (match_operand:V2SF 0 "register_operand" "=y")
21176 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21177 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21178 "TARGET_3DNOW"
21179 "pfmax\\t{%2, %0|%0, %2}"
21180 [(set_attr "type" "mmxadd")
21181 (set_attr "mode" "V2SF")])
21182
21183 (define_insn "pfminv2sf3"
21184 [(set (match_operand:V2SF 0 "register_operand" "=y")
21185 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21186 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21187 "TARGET_3DNOW"
21188 "pfmin\\t{%2, %0|%0, %2}"
21189 [(set_attr "type" "mmxadd")
21190 (set_attr "mode" "V2SF")])
21191
21192 (define_insn "mulv2sf3"
21193 [(set (match_operand:V2SF 0 "register_operand" "=y")
21194 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21195 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21196 "TARGET_3DNOW"
21197 "pfmul\\t{%2, %0|%0, %2}"
21198 [(set_attr "type" "mmxmul")
21199 (set_attr "mode" "V2SF")])
21200
21201 (define_insn "femms"
21202 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21203 (clobber (reg:XF 8))
21204 (clobber (reg:XF 9))
21205 (clobber (reg:XF 10))
21206 (clobber (reg:XF 11))
21207 (clobber (reg:XF 12))
21208 (clobber (reg:XF 13))
21209 (clobber (reg:XF 14))
21210 (clobber (reg:XF 15))
21211 (clobber (reg:DI 29))
21212 (clobber (reg:DI 30))
21213 (clobber (reg:DI 31))
21214 (clobber (reg:DI 32))
21215 (clobber (reg:DI 33))
21216 (clobber (reg:DI 34))
21217 (clobber (reg:DI 35))
21218 (clobber (reg:DI 36))]
21219 "TARGET_3DNOW"
21220 "femms"
21221 [(set_attr "type" "mmx")
21222 (set_attr "memory" "none")])
21223
21224 (define_insn "pf2id"
21225 [(set (match_operand:V2SI 0 "register_operand" "=y")
21226 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21227 "TARGET_3DNOW"
21228 "pf2id\\t{%1, %0|%0, %1}"
21229 [(set_attr "type" "mmxcvt")
21230 (set_attr "mode" "V2SF")])
21231
21232 (define_insn "pf2iw"
21233 [(set (match_operand:V2SI 0 "register_operand" "=y")
21234 (sign_extend:V2SI
21235 (ss_truncate:V2HI
21236 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21237 "TARGET_3DNOW_A"
21238 "pf2iw\\t{%1, %0|%0, %1}"
21239 [(set_attr "type" "mmxcvt")
21240 (set_attr "mode" "V2SF")])
21241
21242 (define_insn "pfacc"
21243 [(set (match_operand:V2SF 0 "register_operand" "=y")
21244 (vec_concat:V2SF
21245 (plus:SF
21246 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21247 (parallel [(const_int 0)]))
21248 (vec_select:SF (match_dup 1)
21249 (parallel [(const_int 1)])))
21250 (plus:SF
21251 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21252 (parallel [(const_int 0)]))
21253 (vec_select:SF (match_dup 2)
21254 (parallel [(const_int 1)])))))]
21255 "TARGET_3DNOW"
21256 "pfacc\\t{%2, %0|%0, %2}"
21257 [(set_attr "type" "mmxadd")
21258 (set_attr "mode" "V2SF")])
21259
21260 (define_insn "pfnacc"
21261 [(set (match_operand:V2SF 0 "register_operand" "=y")
21262 (vec_concat:V2SF
21263 (minus:SF
21264 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21265 (parallel [(const_int 0)]))
21266 (vec_select:SF (match_dup 1)
21267 (parallel [(const_int 1)])))
21268 (minus:SF
21269 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21270 (parallel [(const_int 0)]))
21271 (vec_select:SF (match_dup 2)
21272 (parallel [(const_int 1)])))))]
21273 "TARGET_3DNOW_A"
21274 "pfnacc\\t{%2, %0|%0, %2}"
21275 [(set_attr "type" "mmxadd")
21276 (set_attr "mode" "V2SF")])
21277
21278 (define_insn "pfpnacc"
21279 [(set (match_operand:V2SF 0 "register_operand" "=y")
21280 (vec_concat:V2SF
21281 (minus:SF
21282 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21283 (parallel [(const_int 0)]))
21284 (vec_select:SF (match_dup 1)
21285 (parallel [(const_int 1)])))
21286 (plus:SF
21287 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21288 (parallel [(const_int 0)]))
21289 (vec_select:SF (match_dup 2)
21290 (parallel [(const_int 1)])))))]
21291 "TARGET_3DNOW_A"
21292 "pfpnacc\\t{%2, %0|%0, %2}"
21293 [(set_attr "type" "mmxadd")
21294 (set_attr "mode" "V2SF")])
21295
21296 (define_insn "pi2fw"
21297 [(set (match_operand:V2SF 0 "register_operand" "=y")
21298 (float:V2SF
21299 (vec_concat:V2SI
21300 (sign_extend:SI
21301 (truncate:HI
21302 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21303 (parallel [(const_int 0)]))))
21304 (sign_extend:SI
21305 (truncate:HI
21306 (vec_select:SI (match_dup 1)
21307 (parallel [(const_int 1)])))))))]
21308 "TARGET_3DNOW_A"
21309 "pi2fw\\t{%1, %0|%0, %1}"
21310 [(set_attr "type" "mmxcvt")
21311 (set_attr "mode" "V2SF")])
21312
21313 (define_insn "floatv2si2"
21314 [(set (match_operand:V2SF 0 "register_operand" "=y")
21315 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21316 "TARGET_3DNOW"
21317 "pi2fd\\t{%1, %0|%0, %1}"
21318 [(set_attr "type" "mmxcvt")
21319 (set_attr "mode" "V2SF")])
21320
21321 ;; This insn is identical to pavgb in operation, but the opcode is
21322 ;; different. To avoid accidentally matching pavgb, use an unspec.
21323
21324 (define_insn "pavgusb"
21325 [(set (match_operand:V8QI 0 "register_operand" "=y")
21326 (unspec:V8QI
21327 [(match_operand:V8QI 1 "register_operand" "0")
21328 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21329 UNSPEC_PAVGUSB))]
21330 "TARGET_3DNOW"
21331 "pavgusb\\t{%2, %0|%0, %2}"
21332 [(set_attr "type" "mmxshft")
21333 (set_attr "mode" "TI")])
21334
21335 ;; 3DNow reciprocal and sqrt
21336
21337 (define_insn "pfrcpv2sf2"
21338 [(set (match_operand:V2SF 0 "register_operand" "=y")
21339 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21340 UNSPEC_PFRCP))]
21341 "TARGET_3DNOW"
21342 "pfrcp\\t{%1, %0|%0, %1}"
21343 [(set_attr "type" "mmx")
21344 (set_attr "mode" "TI")])
21345
21346 (define_insn "pfrcpit1v2sf3"
21347 [(set (match_operand:V2SF 0 "register_operand" "=y")
21348 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21349 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21350 UNSPEC_PFRCPIT1))]
21351 "TARGET_3DNOW"
21352 "pfrcpit1\\t{%2, %0|%0, %2}"
21353 [(set_attr "type" "mmx")
21354 (set_attr "mode" "TI")])
21355
21356 (define_insn "pfrcpit2v2sf3"
21357 [(set (match_operand:V2SF 0 "register_operand" "=y")
21358 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21359 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21360 UNSPEC_PFRCPIT2))]
21361 "TARGET_3DNOW"
21362 "pfrcpit2\\t{%2, %0|%0, %2}"
21363 [(set_attr "type" "mmx")
21364 (set_attr "mode" "TI")])
21365
21366 (define_insn "pfrsqrtv2sf2"
21367 [(set (match_operand:V2SF 0 "register_operand" "=y")
21368 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21369 UNSPEC_PFRSQRT))]
21370 "TARGET_3DNOW"
21371 "pfrsqrt\\t{%1, %0|%0, %1}"
21372 [(set_attr "type" "mmx")
21373 (set_attr "mode" "TI")])
21374
21375 (define_insn "pfrsqit1v2sf3"
21376 [(set (match_operand:V2SF 0 "register_operand" "=y")
21377 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21378 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21379 UNSPEC_PFRSQIT1))]
21380 "TARGET_3DNOW"
21381 "pfrsqit1\\t{%2, %0|%0, %2}"
21382 [(set_attr "type" "mmx")
21383 (set_attr "mode" "TI")])
21384
21385 (define_insn "pmulhrwv4hi3"
21386 [(set (match_operand:V4HI 0 "register_operand" "=y")
21387 (truncate:V4HI
21388 (lshiftrt:V4SI
21389 (plus:V4SI
21390 (mult:V4SI
21391 (sign_extend:V4SI
21392 (match_operand:V4HI 1 "register_operand" "0"))
21393 (sign_extend:V4SI
21394 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21395 (const_vector:V4SI [(const_int 32768)
21396 (const_int 32768)
21397 (const_int 32768)
21398 (const_int 32768)]))
21399 (const_int 16))))]
21400 "TARGET_3DNOW"
21401 "pmulhrw\\t{%2, %0|%0, %2}"
21402 [(set_attr "type" "mmxmul")
21403 (set_attr "mode" "TI")])
21404
21405 (define_insn "pswapdv2si2"
21406 [(set (match_operand:V2SI 0 "register_operand" "=y")
21407 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21408 (parallel [(const_int 1) (const_int 0)])))]
21409 "TARGET_3DNOW_A"
21410 "pswapd\\t{%1, %0|%0, %1}"
21411 [(set_attr "type" "mmxcvt")
21412 (set_attr "mode" "TI")])
21413
21414 (define_insn "pswapdv2sf2"
21415 [(set (match_operand:V2SF 0 "register_operand" "=y")
21416 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21417 (parallel [(const_int 1) (const_int 0)])))]
21418 "TARGET_3DNOW_A"
21419 "pswapd\\t{%1, %0|%0, %1}"
21420 [(set_attr "type" "mmxcvt")
21421 (set_attr "mode" "TI")])
21422
21423 (define_expand "prefetch"
21424 [(prefetch (match_operand 0 "address_operand" "")
21425 (match_operand:SI 1 "const_int_operand" "")
21426 (match_operand:SI 2 "const_int_operand" ""))]
21427 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21428 {
21429 int rw = INTVAL (operands[1]);
21430 int locality = INTVAL (operands[2]);
21431
21432 if (rw != 0 && rw != 1)
21433 abort ();
21434 if (locality < 0 || locality > 3)
21435 abort ();
21436 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21437 abort ();
21438
21439 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21440 suported by SSE counterpart or the SSE prefetch is not available
21441 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21442 of locality. */
21443 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21444 operands[2] = GEN_INT (3);
21445 else
21446 operands[1] = const0_rtx;
21447 })
21448
21449 (define_insn "*prefetch_sse"
21450 [(prefetch (match_operand:SI 0 "address_operand" "p")
21451 (const_int 0)
21452 (match_operand:SI 1 "const_int_operand" ""))]
21453 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21454 {
21455 static const char * const patterns[4] = {
21456 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21457 };
21458
21459 int locality = INTVAL (operands[1]);
21460 if (locality < 0 || locality > 3)
21461 abort ();
21462
21463 return patterns[locality];
21464 }
21465 [(set_attr "type" "sse")
21466 (set_attr "memory" "none")])
21467
21468 (define_insn "*prefetch_sse_rex"
21469 [(prefetch (match_operand:DI 0 "address_operand" "p")
21470 (const_int 0)
21471 (match_operand:SI 1 "const_int_operand" ""))]
21472 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21473 {
21474 static const char * const patterns[4] = {
21475 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21476 };
21477
21478 int locality = INTVAL (operands[1]);
21479 if (locality < 0 || locality > 3)
21480 abort ();
21481
21482 return patterns[locality];
21483 }
21484 [(set_attr "type" "sse")
21485 (set_attr "memory" "none")])
21486
21487 (define_insn "*prefetch_3dnow"
21488 [(prefetch (match_operand:SI 0 "address_operand" "p")
21489 (match_operand:SI 1 "const_int_operand" "n")
21490 (const_int 3))]
21491 "TARGET_3DNOW && !TARGET_64BIT"
21492 {
21493 if (INTVAL (operands[1]) == 0)
21494 return "prefetch\t%a0";
21495 else
21496 return "prefetchw\t%a0";
21497 }
21498 [(set_attr "type" "mmx")
21499 (set_attr "memory" "none")])
21500
21501 (define_insn "*prefetch_3dnow_rex"
21502 [(prefetch (match_operand:DI 0 "address_operand" "p")
21503 (match_operand:SI 1 "const_int_operand" "n")
21504 (const_int 3))]
21505 "TARGET_3DNOW && TARGET_64BIT"
21506 {
21507 if (INTVAL (operands[1]) == 0)
21508 return "prefetch\t%a0";
21509 else
21510 return "prefetchw\t%a0";
21511 }
21512 [(set_attr "type" "mmx")
21513 (set_attr "memory" "none")])
21514
21515 ;; SSE2 support
21516
21517 (define_insn "addv2df3"
21518 [(set (match_operand:V2DF 0 "register_operand" "=x")
21519 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21520 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21521 "TARGET_SSE2"
21522 "addpd\t{%2, %0|%0, %2}"
21523 [(set_attr "type" "sseadd")
21524 (set_attr "mode" "V2DF")])
21525
21526 (define_insn "vmaddv2df3"
21527 [(set (match_operand:V2DF 0 "register_operand" "=x")
21528 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21529 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21530 (match_dup 1)
21531 (const_int 1)))]
21532 "TARGET_SSE2"
21533 "addsd\t{%2, %0|%0, %2}"
21534 [(set_attr "type" "sseadd")
21535 (set_attr "mode" "DF")])
21536
21537 (define_insn "subv2df3"
21538 [(set (match_operand:V2DF 0 "register_operand" "=x")
21539 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21540 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21541 "TARGET_SSE2"
21542 "subpd\t{%2, %0|%0, %2}"
21543 [(set_attr "type" "sseadd")
21544 (set_attr "mode" "V2DF")])
21545
21546 (define_insn "vmsubv2df3"
21547 [(set (match_operand:V2DF 0 "register_operand" "=x")
21548 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21549 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21550 (match_dup 1)
21551 (const_int 1)))]
21552 "TARGET_SSE2"
21553 "subsd\t{%2, %0|%0, %2}"
21554 [(set_attr "type" "sseadd")
21555 (set_attr "mode" "DF")])
21556
21557 (define_insn "mulv2df3"
21558 [(set (match_operand:V2DF 0 "register_operand" "=x")
21559 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21560 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21561 "TARGET_SSE2"
21562 "mulpd\t{%2, %0|%0, %2}"
21563 [(set_attr "type" "ssemul")
21564 (set_attr "mode" "V2DF")])
21565
21566 (define_insn "vmmulv2df3"
21567 [(set (match_operand:V2DF 0 "register_operand" "=x")
21568 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21569 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21570 (match_dup 1)
21571 (const_int 1)))]
21572 "TARGET_SSE2"
21573 "mulsd\t{%2, %0|%0, %2}"
21574 [(set_attr "type" "ssemul")
21575 (set_attr "mode" "DF")])
21576
21577 (define_insn "divv2df3"
21578 [(set (match_operand:V2DF 0 "register_operand" "=x")
21579 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21580 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21581 "TARGET_SSE2"
21582 "divpd\t{%2, %0|%0, %2}"
21583 [(set_attr "type" "ssediv")
21584 (set_attr "mode" "V2DF")])
21585
21586 (define_insn "vmdivv2df3"
21587 [(set (match_operand:V2DF 0 "register_operand" "=x")
21588 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21589 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21590 (match_dup 1)
21591 (const_int 1)))]
21592 "TARGET_SSE2"
21593 "divsd\t{%2, %0|%0, %2}"
21594 [(set_attr "type" "ssediv")
21595 (set_attr "mode" "DF")])
21596
21597 ;; SSE min/max
21598
21599 (define_insn "smaxv2df3"
21600 [(set (match_operand:V2DF 0 "register_operand" "=x")
21601 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21602 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21603 "TARGET_SSE2"
21604 "maxpd\t{%2, %0|%0, %2}"
21605 [(set_attr "type" "sseadd")
21606 (set_attr "mode" "V2DF")])
21607
21608 (define_insn "vmsmaxv2df3"
21609 [(set (match_operand:V2DF 0 "register_operand" "=x")
21610 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21611 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21612 (match_dup 1)
21613 (const_int 1)))]
21614 "TARGET_SSE2"
21615 "maxsd\t{%2, %0|%0, %2}"
21616 [(set_attr "type" "sseadd")
21617 (set_attr "mode" "DF")])
21618
21619 (define_insn "sminv2df3"
21620 [(set (match_operand:V2DF 0 "register_operand" "=x")
21621 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21622 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21623 "TARGET_SSE2"
21624 "minpd\t{%2, %0|%0, %2}"
21625 [(set_attr "type" "sseadd")
21626 (set_attr "mode" "V2DF")])
21627
21628 (define_insn "vmsminv2df3"
21629 [(set (match_operand:V2DF 0 "register_operand" "=x")
21630 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21631 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21632 (match_dup 1)
21633 (const_int 1)))]
21634 "TARGET_SSE2"
21635 "minsd\t{%2, %0|%0, %2}"
21636 [(set_attr "type" "sseadd")
21637 (set_attr "mode" "DF")])
21638 ;; SSE2 square root. There doesn't appear to be an extension for the
21639 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21640
21641 (define_insn "sqrtv2df2"
21642 [(set (match_operand:V2DF 0 "register_operand" "=x")
21643 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21644 "TARGET_SSE2"
21645 "sqrtpd\t{%1, %0|%0, %1}"
21646 [(set_attr "type" "sse")
21647 (set_attr "mode" "V2DF")])
21648
21649 (define_insn "vmsqrtv2df2"
21650 [(set (match_operand:V2DF 0 "register_operand" "=x")
21651 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21652 (match_operand:V2DF 2 "register_operand" "0")
21653 (const_int 1)))]
21654 "TARGET_SSE2"
21655 "sqrtsd\t{%1, %0|%0, %1}"
21656 [(set_attr "type" "sse")
21657 (set_attr "mode" "SF")])
21658
21659 ;; SSE mask-generating compares
21660
21661 (define_insn "maskcmpv2df3"
21662 [(set (match_operand:V2DI 0 "register_operand" "=x")
21663 (match_operator:V2DI 3 "sse_comparison_operator"
21664 [(match_operand:V2DF 1 "register_operand" "0")
21665 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21666 "TARGET_SSE2"
21667 "cmp%D3pd\t{%2, %0|%0, %2}"
21668 [(set_attr "type" "ssecmp")
21669 (set_attr "mode" "V2DF")])
21670
21671 (define_insn "maskncmpv2df3"
21672 [(set (match_operand:V2DI 0 "register_operand" "=x")
21673 (not:V2DI
21674 (match_operator:V2DI 3 "sse_comparison_operator"
21675 [(match_operand:V2DF 1 "register_operand" "0")
21676 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21677 "TARGET_SSE2"
21678 {
21679 if (GET_CODE (operands[3]) == UNORDERED)
21680 return "cmpordps\t{%2, %0|%0, %2}";
21681 else
21682 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21683 }
21684 [(set_attr "type" "ssecmp")
21685 (set_attr "mode" "V2DF")])
21686
21687 (define_insn "vmmaskcmpv2df3"
21688 [(set (match_operand:V2DI 0 "register_operand" "=x")
21689 (vec_merge:V2DI
21690 (match_operator:V2DI 3 "sse_comparison_operator"
21691 [(match_operand:V2DF 1 "register_operand" "0")
21692 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21693 (subreg:V2DI (match_dup 1) 0)
21694 (const_int 1)))]
21695 "TARGET_SSE2"
21696 "cmp%D3sd\t{%2, %0|%0, %2}"
21697 [(set_attr "type" "ssecmp")
21698 (set_attr "mode" "DF")])
21699
21700 (define_insn "vmmaskncmpv2df3"
21701 [(set (match_operand:V2DI 0 "register_operand" "=x")
21702 (vec_merge:V2DI
21703 (not:V2DI
21704 (match_operator:V2DI 3 "sse_comparison_operator"
21705 [(match_operand:V2DF 1 "register_operand" "0")
21706 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21707 (subreg:V2DI (match_dup 1) 0)
21708 (const_int 1)))]
21709 "TARGET_SSE2"
21710 {
21711 if (GET_CODE (operands[3]) == UNORDERED)
21712 return "cmpordsd\t{%2, %0|%0, %2}";
21713 else
21714 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21715 }
21716 [(set_attr "type" "ssecmp")
21717 (set_attr "mode" "DF")])
21718
21719 (define_insn "sse2_comi"
21720 [(set (reg:CCFP 17)
21721 (compare:CCFP (vec_select:DF
21722 (match_operand:V2DF 0 "register_operand" "x")
21723 (parallel [(const_int 0)]))
21724 (vec_select:DF
21725 (match_operand:V2DF 1 "register_operand" "x")
21726 (parallel [(const_int 0)]))))]
21727 "TARGET_SSE2"
21728 "comisd\t{%1, %0|%0, %1}"
21729 [(set_attr "type" "ssecomi")
21730 (set_attr "mode" "DF")])
21731
21732 (define_insn "sse2_ucomi"
21733 [(set (reg:CCFPU 17)
21734 (compare:CCFPU (vec_select:DF
21735 (match_operand:V2DF 0 "register_operand" "x")
21736 (parallel [(const_int 0)]))
21737 (vec_select:DF
21738 (match_operand:V2DF 1 "register_operand" "x")
21739 (parallel [(const_int 0)]))))]
21740 "TARGET_SSE2"
21741 "ucomisd\t{%1, %0|%0, %1}"
21742 [(set_attr "type" "ssecomi")
21743 (set_attr "mode" "DF")])
21744
21745 ;; SSE Strange Moves.
21746
21747 (define_insn "sse2_movmskpd"
21748 [(set (match_operand:SI 0 "register_operand" "=r")
21749 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21750 UNSPEC_MOVMSK))]
21751 "TARGET_SSE2"
21752 "movmskpd\t{%1, %0|%0, %1}"
21753 [(set_attr "type" "ssecvt")
21754 (set_attr "mode" "V2DF")])
21755
21756 (define_insn "sse2_pmovmskb"
21757 [(set (match_operand:SI 0 "register_operand" "=r")
21758 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21759 UNSPEC_MOVMSK))]
21760 "TARGET_SSE2"
21761 "pmovmskb\t{%1, %0|%0, %1}"
21762 [(set_attr "type" "ssecvt")
21763 (set_attr "mode" "V2DF")])
21764
21765 (define_insn "sse2_maskmovdqu"
21766 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21767 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21768 (match_operand:V16QI 2 "register_operand" "x")]
21769 UNSPEC_MASKMOV))]
21770 "TARGET_SSE2"
21771 ;; @@@ check ordering of operands in intel/nonintel syntax
21772 "maskmovdqu\t{%2, %1|%1, %2}"
21773 [(set_attr "type" "ssecvt")
21774 (set_attr "mode" "TI")])
21775
21776 (define_insn "sse2_maskmovdqu_rex64"
21777 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21778 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21779 (match_operand:V16QI 2 "register_operand" "x")]
21780 UNSPEC_MASKMOV))]
21781 "TARGET_SSE2"
21782 ;; @@@ check ordering of operands in intel/nonintel syntax
21783 "maskmovdqu\t{%2, %1|%1, %2}"
21784 [(set_attr "type" "ssecvt")
21785 (set_attr "mode" "TI")])
21786
21787 (define_insn "sse2_movntv2df"
21788 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21789 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21790 UNSPEC_MOVNT))]
21791 "TARGET_SSE2"
21792 "movntpd\t{%1, %0|%0, %1}"
21793 [(set_attr "type" "ssecvt")
21794 (set_attr "mode" "V2DF")])
21795
21796 (define_insn "sse2_movntv2di"
21797 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21798 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21799 UNSPEC_MOVNT))]
21800 "TARGET_SSE2"
21801 "movntdq\t{%1, %0|%0, %1}"
21802 [(set_attr "type" "ssecvt")
21803 (set_attr "mode" "TI")])
21804
21805 (define_insn "sse2_movntsi"
21806 [(set (match_operand:SI 0 "memory_operand" "=m")
21807 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21808 UNSPEC_MOVNT))]
21809 "TARGET_SSE2"
21810 "movnti\t{%1, %0|%0, %1}"
21811 [(set_attr "type" "ssecvt")
21812 (set_attr "mode" "V2DF")])
21813
21814 ;; SSE <-> integer/MMX conversions
21815
21816 ;; Conversions between SI and SF
21817
21818 (define_insn "cvtdq2ps"
21819 [(set (match_operand:V4SF 0 "register_operand" "=x")
21820 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21821 "TARGET_SSE2"
21822 "cvtdq2ps\t{%1, %0|%0, %1}"
21823 [(set_attr "type" "ssecvt")
21824 (set_attr "mode" "V2DF")])
21825
21826 (define_insn "cvtps2dq"
21827 [(set (match_operand:V4SI 0 "register_operand" "=x")
21828 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21829 "TARGET_SSE2"
21830 "cvtps2dq\t{%1, %0|%0, %1}"
21831 [(set_attr "type" "ssecvt")
21832 (set_attr "mode" "TI")])
21833
21834 (define_insn "cvttps2dq"
21835 [(set (match_operand:V4SI 0 "register_operand" "=x")
21836 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21837 UNSPEC_FIX))]
21838 "TARGET_SSE2"
21839 "cvttps2dq\t{%1, %0|%0, %1}"
21840 [(set_attr "type" "ssecvt")
21841 (set_attr "mode" "TI")])
21842
21843 ;; Conversions between SI and DF
21844
21845 (define_insn "cvtdq2pd"
21846 [(set (match_operand:V2DF 0 "register_operand" "=x")
21847 (float:V2DF (vec_select:V2SI
21848 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21849 (parallel
21850 [(const_int 0)
21851 (const_int 1)]))))]
21852 "TARGET_SSE2"
21853 "cvtdq2pd\t{%1, %0|%0, %1}"
21854 [(set_attr "type" "ssecvt")
21855 (set_attr "mode" "V2DF")])
21856
21857 (define_insn "cvtpd2dq"
21858 [(set (match_operand:V4SI 0 "register_operand" "=x")
21859 (vec_concat:V4SI
21860 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21861 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21862 "TARGET_SSE2"
21863 "cvtpd2dq\t{%1, %0|%0, %1}"
21864 [(set_attr "type" "ssecvt")
21865 (set_attr "mode" "TI")])
21866
21867 (define_insn "cvttpd2dq"
21868 [(set (match_operand:V4SI 0 "register_operand" "=x")
21869 (vec_concat:V4SI
21870 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21871 UNSPEC_FIX)
21872 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21873 "TARGET_SSE2"
21874 "cvttpd2dq\t{%1, %0|%0, %1}"
21875 [(set_attr "type" "ssecvt")
21876 (set_attr "mode" "TI")])
21877
21878 (define_insn "cvtpd2pi"
21879 [(set (match_operand:V2SI 0 "register_operand" "=y")
21880 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21881 "TARGET_SSE2"
21882 "cvtpd2pi\t{%1, %0|%0, %1}"
21883 [(set_attr "type" "ssecvt")
21884 (set_attr "mode" "TI")])
21885
21886 (define_insn "cvttpd2pi"
21887 [(set (match_operand:V2SI 0 "register_operand" "=y")
21888 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21889 UNSPEC_FIX))]
21890 "TARGET_SSE2"
21891 "cvttpd2pi\t{%1, %0|%0, %1}"
21892 [(set_attr "type" "ssecvt")
21893 (set_attr "mode" "TI")])
21894
21895 (define_insn "cvtpi2pd"
21896 [(set (match_operand:V2DF 0 "register_operand" "=x")
21897 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21898 "TARGET_SSE2"
21899 "cvtpi2pd\t{%1, %0|%0, %1}"
21900 [(set_attr "type" "ssecvt")
21901 (set_attr "mode" "TI")])
21902
21903 ;; Conversions between SI and DF
21904
21905 (define_insn "cvtsd2si"
21906 [(set (match_operand:SI 0 "register_operand" "=r,r")
21907 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21908 (parallel [(const_int 0)]))))]
21909 "TARGET_SSE2"
21910 "cvtsd2si\t{%1, %0|%0, %1}"
21911 [(set_attr "type" "sseicvt")
21912 (set_attr "athlon_decode" "double,vector")
21913 (set_attr "mode" "SI")])
21914
21915 (define_insn "cvtsd2siq"
21916 [(set (match_operand:DI 0 "register_operand" "=r,r")
21917 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21918 (parallel [(const_int 0)]))))]
21919 "TARGET_SSE2 && TARGET_64BIT"
21920 "cvtsd2siq\t{%1, %0|%0, %1}"
21921 [(set_attr "type" "sseicvt")
21922 (set_attr "athlon_decode" "double,vector")
21923 (set_attr "mode" "DI")])
21924
21925 (define_insn "cvttsd2si"
21926 [(set (match_operand:SI 0 "register_operand" "=r,r")
21927 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21928 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21929 "TARGET_SSE2"
21930 "cvttsd2si\t{%1, %0|%0, %1}"
21931 [(set_attr "type" "sseicvt")
21932 (set_attr "mode" "SI")
21933 (set_attr "athlon_decode" "double,vector")])
21934
21935 (define_insn "cvttsd2siq"
21936 [(set (match_operand:DI 0 "register_operand" "=r,r")
21937 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21938 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21939 "TARGET_SSE2 && TARGET_64BIT"
21940 "cvttsd2siq\t{%1, %0|%0, %1}"
21941 [(set_attr "type" "sseicvt")
21942 (set_attr "mode" "DI")
21943 (set_attr "athlon_decode" "double,vector")])
21944
21945 (define_insn "cvtsi2sd"
21946 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21947 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21948 (vec_duplicate:V2DF
21949 (float:DF
21950 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21951 (const_int 2)))]
21952 "TARGET_SSE2"
21953 "cvtsi2sd\t{%2, %0|%0, %2}"
21954 [(set_attr "type" "sseicvt")
21955 (set_attr "mode" "DF")
21956 (set_attr "athlon_decode" "double,direct")])
21957
21958 (define_insn "cvtsi2sdq"
21959 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21960 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21961 (vec_duplicate:V2DF
21962 (float:DF
21963 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21964 (const_int 2)))]
21965 "TARGET_SSE2 && TARGET_64BIT"
21966 "cvtsi2sdq\t{%2, %0|%0, %2}"
21967 [(set_attr "type" "sseicvt")
21968 (set_attr "mode" "DF")
21969 (set_attr "athlon_decode" "double,direct")])
21970
21971 ;; Conversions between SF and DF
21972
21973 (define_insn "cvtsd2ss"
21974 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21975 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21976 (vec_duplicate:V4SF
21977 (float_truncate:V2SF
21978 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21979 (const_int 14)))]
21980 "TARGET_SSE2"
21981 "cvtsd2ss\t{%2, %0|%0, %2}"
21982 [(set_attr "type" "ssecvt")
21983 (set_attr "athlon_decode" "vector,double")
21984 (set_attr "mode" "SF")])
21985
21986 (define_insn "cvtss2sd"
21987 [(set (match_operand:V2DF 0 "register_operand" "=x")
21988 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21989 (float_extend:V2DF
21990 (vec_select:V2SF
21991 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21992 (parallel [(const_int 0)
21993 (const_int 1)])))
21994 (const_int 2)))]
21995 "TARGET_SSE2"
21996 "cvtss2sd\t{%2, %0|%0, %2}"
21997 [(set_attr "type" "ssecvt")
21998 (set_attr "mode" "DF")])
21999
22000 (define_insn "cvtpd2ps"
22001 [(set (match_operand:V4SF 0 "register_operand" "=x")
22002 (subreg:V4SF
22003 (vec_concat:V4SI
22004 (subreg:V2SI (float_truncate:V2SF
22005 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22006 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22007 "TARGET_SSE2"
22008 "cvtpd2ps\t{%1, %0|%0, %1}"
22009 [(set_attr "type" "ssecvt")
22010 (set_attr "mode" "V4SF")])
22011
22012 (define_insn "cvtps2pd"
22013 [(set (match_operand:V2DF 0 "register_operand" "=x")
22014 (float_extend:V2DF
22015 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22016 (parallel [(const_int 0)
22017 (const_int 1)]))))]
22018 "TARGET_SSE2"
22019 "cvtps2pd\t{%1, %0|%0, %1}"
22020 [(set_attr "type" "ssecvt")
22021 (set_attr "mode" "V2DF")])
22022
22023 ;; SSE2 variants of MMX insns
22024
22025 ;; MMX arithmetic
22026
22027 (define_insn "addv16qi3"
22028 [(set (match_operand:V16QI 0 "register_operand" "=x")
22029 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22030 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22031 "TARGET_SSE2"
22032 "paddb\t{%2, %0|%0, %2}"
22033 [(set_attr "type" "sseiadd")
22034 (set_attr "mode" "TI")])
22035
22036 (define_insn "addv8hi3"
22037 [(set (match_operand:V8HI 0 "register_operand" "=x")
22038 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22039 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22040 "TARGET_SSE2"
22041 "paddw\t{%2, %0|%0, %2}"
22042 [(set_attr "type" "sseiadd")
22043 (set_attr "mode" "TI")])
22044
22045 (define_insn "addv4si3"
22046 [(set (match_operand:V4SI 0 "register_operand" "=x")
22047 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22048 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22049 "TARGET_SSE2"
22050 "paddd\t{%2, %0|%0, %2}"
22051 [(set_attr "type" "sseiadd")
22052 (set_attr "mode" "TI")])
22053
22054 (define_insn "addv2di3"
22055 [(set (match_operand:V2DI 0 "register_operand" "=x")
22056 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22057 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22058 "TARGET_SSE2"
22059 "paddq\t{%2, %0|%0, %2}"
22060 [(set_attr "type" "sseiadd")
22061 (set_attr "mode" "TI")])
22062
22063 (define_insn "ssaddv16qi3"
22064 [(set (match_operand:V16QI 0 "register_operand" "=x")
22065 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22066 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22067 "TARGET_SSE2"
22068 "paddsb\t{%2, %0|%0, %2}"
22069 [(set_attr "type" "sseiadd")
22070 (set_attr "mode" "TI")])
22071
22072 (define_insn "ssaddv8hi3"
22073 [(set (match_operand:V8HI 0 "register_operand" "=x")
22074 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22075 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22076 "TARGET_SSE2"
22077 "paddsw\t{%2, %0|%0, %2}"
22078 [(set_attr "type" "sseiadd")
22079 (set_attr "mode" "TI")])
22080
22081 (define_insn "usaddv16qi3"
22082 [(set (match_operand:V16QI 0 "register_operand" "=x")
22083 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22084 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22085 "TARGET_SSE2"
22086 "paddusb\t{%2, %0|%0, %2}"
22087 [(set_attr "type" "sseiadd")
22088 (set_attr "mode" "TI")])
22089
22090 (define_insn "usaddv8hi3"
22091 [(set (match_operand:V8HI 0 "register_operand" "=x")
22092 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22093 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22094 "TARGET_SSE2"
22095 "paddusw\t{%2, %0|%0, %2}"
22096 [(set_attr "type" "sseiadd")
22097 (set_attr "mode" "TI")])
22098
22099 (define_insn "subv16qi3"
22100 [(set (match_operand:V16QI 0 "register_operand" "=x")
22101 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22102 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22103 "TARGET_SSE2"
22104 "psubb\t{%2, %0|%0, %2}"
22105 [(set_attr "type" "sseiadd")
22106 (set_attr "mode" "TI")])
22107
22108 (define_insn "subv8hi3"
22109 [(set (match_operand:V8HI 0 "register_operand" "=x")
22110 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22111 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22112 "TARGET_SSE2"
22113 "psubw\t{%2, %0|%0, %2}"
22114 [(set_attr "type" "sseiadd")
22115 (set_attr "mode" "TI")])
22116
22117 (define_insn "subv4si3"
22118 [(set (match_operand:V4SI 0 "register_operand" "=x")
22119 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22120 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22121 "TARGET_SSE2"
22122 "psubd\t{%2, %0|%0, %2}"
22123 [(set_attr "type" "sseiadd")
22124 (set_attr "mode" "TI")])
22125
22126 (define_insn "subv2di3"
22127 [(set (match_operand:V2DI 0 "register_operand" "=x")
22128 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22129 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22130 "TARGET_SSE2"
22131 "psubq\t{%2, %0|%0, %2}"
22132 [(set_attr "type" "sseiadd")
22133 (set_attr "mode" "TI")])
22134
22135 (define_insn "sssubv16qi3"
22136 [(set (match_operand:V16QI 0 "register_operand" "=x")
22137 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22138 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22139 "TARGET_SSE2"
22140 "psubsb\t{%2, %0|%0, %2}"
22141 [(set_attr "type" "sseiadd")
22142 (set_attr "mode" "TI")])
22143
22144 (define_insn "sssubv8hi3"
22145 [(set (match_operand:V8HI 0 "register_operand" "=x")
22146 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22147 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22148 "TARGET_SSE2"
22149 "psubsw\t{%2, %0|%0, %2}"
22150 [(set_attr "type" "sseiadd")
22151 (set_attr "mode" "TI")])
22152
22153 (define_insn "ussubv16qi3"
22154 [(set (match_operand:V16QI 0 "register_operand" "=x")
22155 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22156 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22157 "TARGET_SSE2"
22158 "psubusb\t{%2, %0|%0, %2}"
22159 [(set_attr "type" "sseiadd")
22160 (set_attr "mode" "TI")])
22161
22162 (define_insn "ussubv8hi3"
22163 [(set (match_operand:V8HI 0 "register_operand" "=x")
22164 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22165 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22166 "TARGET_SSE2"
22167 "psubusw\t{%2, %0|%0, %2}"
22168 [(set_attr "type" "sseiadd")
22169 (set_attr "mode" "TI")])
22170
22171 (define_insn "mulv8hi3"
22172 [(set (match_operand:V8HI 0 "register_operand" "=x")
22173 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22174 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22175 "TARGET_SSE2"
22176 "pmullw\t{%2, %0|%0, %2}"
22177 [(set_attr "type" "sseimul")
22178 (set_attr "mode" "TI")])
22179
22180 (define_insn "smulv8hi3_highpart"
22181 [(set (match_operand:V8HI 0 "register_operand" "=x")
22182 (truncate:V8HI
22183 (lshiftrt:V8SI
22184 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22185 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22186 (const_int 16))))]
22187 "TARGET_SSE2"
22188 "pmulhw\t{%2, %0|%0, %2}"
22189 [(set_attr "type" "sseimul")
22190 (set_attr "mode" "TI")])
22191
22192 (define_insn "umulv8hi3_highpart"
22193 [(set (match_operand:V8HI 0 "register_operand" "=x")
22194 (truncate:V8HI
22195 (lshiftrt:V8SI
22196 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22197 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22198 (const_int 16))))]
22199 "TARGET_SSE2"
22200 "pmulhuw\t{%2, %0|%0, %2}"
22201 [(set_attr "type" "sseimul")
22202 (set_attr "mode" "TI")])
22203
22204 (define_insn "sse2_umulsidi3"
22205 [(set (match_operand:DI 0 "register_operand" "=y")
22206 (mult:DI (zero_extend:DI (vec_select:SI
22207 (match_operand:V2SI 1 "register_operand" "0")
22208 (parallel [(const_int 0)])))
22209 (zero_extend:DI (vec_select:SI
22210 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22211 (parallel [(const_int 0)])))))]
22212 "TARGET_SSE2"
22213 "pmuludq\t{%2, %0|%0, %2}"
22214 [(set_attr "type" "sseimul")
22215 (set_attr "mode" "TI")])
22216
22217 (define_insn "sse2_umulv2siv2di3"
22218 [(set (match_operand:V2DI 0 "register_operand" "=x")
22219 (mult:V2DI (zero_extend:V2DI
22220 (vec_select:V2SI
22221 (match_operand:V4SI 1 "register_operand" "0")
22222 (parallel [(const_int 0) (const_int 2)])))
22223 (zero_extend:V2DI
22224 (vec_select:V2SI
22225 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22226 (parallel [(const_int 0) (const_int 2)])))))]
22227 "TARGET_SSE2"
22228 "pmuludq\t{%2, %0|%0, %2}"
22229 [(set_attr "type" "sseimul")
22230 (set_attr "mode" "TI")])
22231
22232 (define_insn "sse2_pmaddwd"
22233 [(set (match_operand:V4SI 0 "register_operand" "=x")
22234 (plus:V4SI
22235 (mult:V4SI
22236 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22237 (parallel [(const_int 0)
22238 (const_int 2)
22239 (const_int 4)
22240 (const_int 6)])))
22241 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22242 (parallel [(const_int 0)
22243 (const_int 2)
22244 (const_int 4)
22245 (const_int 6)]))))
22246 (mult:V4SI
22247 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22248 (parallel [(const_int 1)
22249 (const_int 3)
22250 (const_int 5)
22251 (const_int 7)])))
22252 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22253 (parallel [(const_int 1)
22254 (const_int 3)
22255 (const_int 5)
22256 (const_int 7)]))))))]
22257 "TARGET_SSE2"
22258 "pmaddwd\t{%2, %0|%0, %2}"
22259 [(set_attr "type" "sseiadd")
22260 (set_attr "mode" "TI")])
22261
22262 ;; Same as pxor, but don't show input operands so that we don't think
22263 ;; they are live.
22264 (define_insn "sse2_clrti"
22265 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22266 "TARGET_SSE2"
22267 {
22268 if (get_attr_mode (insn) == MODE_TI)
22269 return "pxor\t%0, %0";
22270 else
22271 return "xorps\t%0, %0";
22272 }
22273 [(set_attr "type" "ssemov")
22274 (set_attr "memory" "none")
22275 (set (attr "mode")
22276 (if_then_else
22277 (ne (symbol_ref "optimize_size")
22278 (const_int 0))
22279 (const_string "V4SF")
22280 (const_string "TI")))])
22281
22282 ;; MMX unsigned averages/sum of absolute differences
22283
22284 (define_insn "sse2_uavgv16qi3"
22285 [(set (match_operand:V16QI 0 "register_operand" "=x")
22286 (ashiftrt:V16QI
22287 (plus:V16QI (plus:V16QI
22288 (match_operand:V16QI 1 "register_operand" "0")
22289 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22290 (const_vector:V16QI [(const_int 1) (const_int 1)
22291 (const_int 1) (const_int 1)
22292 (const_int 1) (const_int 1)
22293 (const_int 1) (const_int 1)
22294 (const_int 1) (const_int 1)
22295 (const_int 1) (const_int 1)
22296 (const_int 1) (const_int 1)
22297 (const_int 1) (const_int 1)]))
22298 (const_int 1)))]
22299 "TARGET_SSE2"
22300 "pavgb\t{%2, %0|%0, %2}"
22301 [(set_attr "type" "sseiadd")
22302 (set_attr "mode" "TI")])
22303
22304 (define_insn "sse2_uavgv8hi3"
22305 [(set (match_operand:V8HI 0 "register_operand" "=x")
22306 (ashiftrt:V8HI
22307 (plus:V8HI (plus:V8HI
22308 (match_operand:V8HI 1 "register_operand" "0")
22309 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22310 (const_vector:V8HI [(const_int 1) (const_int 1)
22311 (const_int 1) (const_int 1)
22312 (const_int 1) (const_int 1)
22313 (const_int 1) (const_int 1)]))
22314 (const_int 1)))]
22315 "TARGET_SSE2"
22316 "pavgw\t{%2, %0|%0, %2}"
22317 [(set_attr "type" "sseiadd")
22318 (set_attr "mode" "TI")])
22319
22320 ;; @@@ this isn't the right representation.
22321 (define_insn "sse2_psadbw"
22322 [(set (match_operand:V2DI 0 "register_operand" "=x")
22323 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22324 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22325 UNSPEC_PSADBW))]
22326 "TARGET_SSE2"
22327 "psadbw\t{%2, %0|%0, %2}"
22328 [(set_attr "type" "sseiadd")
22329 (set_attr "mode" "TI")])
22330
22331
22332 ;; MMX insert/extract/shuffle
22333
22334 (define_insn "sse2_pinsrw"
22335 [(set (match_operand:V8HI 0 "register_operand" "=x")
22336 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22337 (vec_duplicate:V8HI
22338 (truncate:HI
22339 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22340 (match_operand:SI 3 "immediate_operand" "i")))]
22341 "TARGET_SSE2"
22342 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22343 [(set_attr "type" "ssecvt")
22344 (set_attr "mode" "TI")])
22345
22346 (define_insn "sse2_pextrw"
22347 [(set (match_operand:SI 0 "register_operand" "=r")
22348 (zero_extend:SI
22349 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22350 (parallel
22351 [(match_operand:SI 2 "immediate_operand" "i")]))))]
22352 "TARGET_SSE2"
22353 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22354 [(set_attr "type" "ssecvt")
22355 (set_attr "mode" "TI")])
22356
22357 (define_insn "sse2_pshufd"
22358 [(set (match_operand:V4SI 0 "register_operand" "=x")
22359 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22360 (match_operand:SI 2 "immediate_operand" "i")]
22361 UNSPEC_SHUFFLE))]
22362 "TARGET_SSE2"
22363 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22364 [(set_attr "type" "ssecvt")
22365 (set_attr "mode" "TI")])
22366
22367 (define_insn "sse2_pshuflw"
22368 [(set (match_operand:V8HI 0 "register_operand" "=x")
22369 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22370 (match_operand:SI 2 "immediate_operand" "i")]
22371 UNSPEC_PSHUFLW))]
22372 "TARGET_SSE2"
22373 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22374 [(set_attr "type" "ssecvt")
22375 (set_attr "mode" "TI")])
22376
22377 (define_insn "sse2_pshufhw"
22378 [(set (match_operand:V8HI 0 "register_operand" "=x")
22379 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22380 (match_operand:SI 2 "immediate_operand" "i")]
22381 UNSPEC_PSHUFHW))]
22382 "TARGET_SSE2"
22383 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22384 [(set_attr "type" "ssecvt")
22385 (set_attr "mode" "TI")])
22386
22387 ;; MMX mask-generating comparisons
22388
22389 (define_insn "eqv16qi3"
22390 [(set (match_operand:V16QI 0 "register_operand" "=x")
22391 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22392 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22393 "TARGET_SSE2"
22394 "pcmpeqb\t{%2, %0|%0, %2}"
22395 [(set_attr "type" "ssecmp")
22396 (set_attr "mode" "TI")])
22397
22398 (define_insn "eqv8hi3"
22399 [(set (match_operand:V8HI 0 "register_operand" "=x")
22400 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22401 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22402 "TARGET_SSE2"
22403 "pcmpeqw\t{%2, %0|%0, %2}"
22404 [(set_attr "type" "ssecmp")
22405 (set_attr "mode" "TI")])
22406
22407 (define_insn "eqv4si3"
22408 [(set (match_operand:V4SI 0 "register_operand" "=x")
22409 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22410 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22411 "TARGET_SSE2"
22412 "pcmpeqd\t{%2, %0|%0, %2}"
22413 [(set_attr "type" "ssecmp")
22414 (set_attr "mode" "TI")])
22415
22416 (define_insn "gtv16qi3"
22417 [(set (match_operand:V16QI 0 "register_operand" "=x")
22418 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22419 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22420 "TARGET_SSE2"
22421 "pcmpgtb\t{%2, %0|%0, %2}"
22422 [(set_attr "type" "ssecmp")
22423 (set_attr "mode" "TI")])
22424
22425 (define_insn "gtv8hi3"
22426 [(set (match_operand:V8HI 0 "register_operand" "=x")
22427 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22428 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22429 "TARGET_SSE2"
22430 "pcmpgtw\t{%2, %0|%0, %2}"
22431 [(set_attr "type" "ssecmp")
22432 (set_attr "mode" "TI")])
22433
22434 (define_insn "gtv4si3"
22435 [(set (match_operand:V4SI 0 "register_operand" "=x")
22436 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22437 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22438 "TARGET_SSE2"
22439 "pcmpgtd\t{%2, %0|%0, %2}"
22440 [(set_attr "type" "ssecmp")
22441 (set_attr "mode" "TI")])
22442
22443
22444 ;; MMX max/min insns
22445
22446 (define_insn "umaxv16qi3"
22447 [(set (match_operand:V16QI 0 "register_operand" "=x")
22448 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22449 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22450 "TARGET_SSE2"
22451 "pmaxub\t{%2, %0|%0, %2}"
22452 [(set_attr "type" "sseiadd")
22453 (set_attr "mode" "TI")])
22454
22455 (define_insn "smaxv8hi3"
22456 [(set (match_operand:V8HI 0 "register_operand" "=x")
22457 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22458 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22459 "TARGET_SSE2"
22460 "pmaxsw\t{%2, %0|%0, %2}"
22461 [(set_attr "type" "sseiadd")
22462 (set_attr "mode" "TI")])
22463
22464 (define_insn "uminv16qi3"
22465 [(set (match_operand:V16QI 0 "register_operand" "=x")
22466 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22467 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22468 "TARGET_SSE2"
22469 "pminub\t{%2, %0|%0, %2}"
22470 [(set_attr "type" "sseiadd")
22471 (set_attr "mode" "TI")])
22472
22473 (define_insn "sminv8hi3"
22474 [(set (match_operand:V8HI 0 "register_operand" "=x")
22475 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22476 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22477 "TARGET_SSE2"
22478 "pminsw\t{%2, %0|%0, %2}"
22479 [(set_attr "type" "sseiadd")
22480 (set_attr "mode" "TI")])
22481
22482
22483 ;; MMX shifts
22484
22485 (define_insn "ashrv8hi3"
22486 [(set (match_operand:V8HI 0 "register_operand" "=x")
22487 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22488 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22489 "TARGET_SSE2"
22490 "psraw\t{%2, %0|%0, %2}"
22491 [(set_attr "type" "sseishft")
22492 (set_attr "mode" "TI")])
22493
22494 (define_insn "ashrv4si3"
22495 [(set (match_operand:V4SI 0 "register_operand" "=x")
22496 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22497 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22498 "TARGET_SSE2"
22499 "psrad\t{%2, %0|%0, %2}"
22500 [(set_attr "type" "sseishft")
22501 (set_attr "mode" "TI")])
22502
22503 (define_insn "lshrv8hi3"
22504 [(set (match_operand:V8HI 0 "register_operand" "=x")
22505 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22506 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22507 "TARGET_SSE2"
22508 "psrlw\t{%2, %0|%0, %2}"
22509 [(set_attr "type" "sseishft")
22510 (set_attr "mode" "TI")])
22511
22512 (define_insn "lshrv4si3"
22513 [(set (match_operand:V4SI 0 "register_operand" "=x")
22514 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22515 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22516 "TARGET_SSE2"
22517 "psrld\t{%2, %0|%0, %2}"
22518 [(set_attr "type" "sseishft")
22519 (set_attr "mode" "TI")])
22520
22521 (define_insn "lshrv2di3"
22522 [(set (match_operand:V2DI 0 "register_operand" "=x")
22523 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22524 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22525 "TARGET_SSE2"
22526 "psrlq\t{%2, %0|%0, %2}"
22527 [(set_attr "type" "sseishft")
22528 (set_attr "mode" "TI")])
22529
22530 (define_insn "ashlv8hi3"
22531 [(set (match_operand:V8HI 0 "register_operand" "=x")
22532 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22533 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22534 "TARGET_SSE2"
22535 "psllw\t{%2, %0|%0, %2}"
22536 [(set_attr "type" "sseishft")
22537 (set_attr "mode" "TI")])
22538
22539 (define_insn "ashlv4si3"
22540 [(set (match_operand:V4SI 0 "register_operand" "=x")
22541 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22542 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22543 "TARGET_SSE2"
22544 "pslld\t{%2, %0|%0, %2}"
22545 [(set_attr "type" "sseishft")
22546 (set_attr "mode" "TI")])
22547
22548 (define_insn "ashlv2di3"
22549 [(set (match_operand:V2DI 0 "register_operand" "=x")
22550 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22551 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22552 "TARGET_SSE2"
22553 "psllq\t{%2, %0|%0, %2}"
22554 [(set_attr "type" "sseishft")
22555 (set_attr "mode" "TI")])
22556
22557 (define_insn "ashrv8hi3_ti"
22558 [(set (match_operand:V8HI 0 "register_operand" "=x")
22559 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22560 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22561 "TARGET_SSE2"
22562 "psraw\t{%2, %0|%0, %2}"
22563 [(set_attr "type" "sseishft")
22564 (set_attr "mode" "TI")])
22565
22566 (define_insn "ashrv4si3_ti"
22567 [(set (match_operand:V4SI 0 "register_operand" "=x")
22568 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22569 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22570 "TARGET_SSE2"
22571 "psrad\t{%2, %0|%0, %2}"
22572 [(set_attr "type" "sseishft")
22573 (set_attr "mode" "TI")])
22574
22575 (define_insn "lshrv8hi3_ti"
22576 [(set (match_operand:V8HI 0 "register_operand" "=x")
22577 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22578 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22579 "TARGET_SSE2"
22580 "psrlw\t{%2, %0|%0, %2}"
22581 [(set_attr "type" "sseishft")
22582 (set_attr "mode" "TI")])
22583
22584 (define_insn "lshrv4si3_ti"
22585 [(set (match_operand:V4SI 0 "register_operand" "=x")
22586 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22587 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22588 "TARGET_SSE2"
22589 "psrld\t{%2, %0|%0, %2}"
22590 [(set_attr "type" "sseishft")
22591 (set_attr "mode" "TI")])
22592
22593 (define_insn "lshrv2di3_ti"
22594 [(set (match_operand:V2DI 0 "register_operand" "=x")
22595 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22596 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22597 "TARGET_SSE2"
22598 "psrlq\t{%2, %0|%0, %2}"
22599 [(set_attr "type" "sseishft")
22600 (set_attr "mode" "TI")])
22601
22602 (define_insn "ashlv8hi3_ti"
22603 [(set (match_operand:V8HI 0 "register_operand" "=x")
22604 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22605 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22606 "TARGET_SSE2"
22607 "psllw\t{%2, %0|%0, %2}"
22608 [(set_attr "type" "sseishft")
22609 (set_attr "mode" "TI")])
22610
22611 (define_insn "ashlv4si3_ti"
22612 [(set (match_operand:V4SI 0 "register_operand" "=x")
22613 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22614 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22615 "TARGET_SSE2"
22616 "pslld\t{%2, %0|%0, %2}"
22617 [(set_attr "type" "sseishft")
22618 (set_attr "mode" "TI")])
22619
22620 (define_insn "ashlv2di3_ti"
22621 [(set (match_operand:V2DI 0 "register_operand" "=x")
22622 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22623 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22624 "TARGET_SSE2"
22625 "psllq\t{%2, %0|%0, %2}"
22626 [(set_attr "type" "sseishft")
22627 (set_attr "mode" "TI")])
22628
22629 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22630 ;; we wouldn't need here it since we never generate TImode arithmetic.
22631
22632 ;; There has to be some kind of prize for the weirdest new instruction...
22633 (define_insn "sse2_ashlti3"
22634 [(set (match_operand:TI 0 "register_operand" "=x")
22635 (unspec:TI
22636 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22637 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22638 (const_int 8)))] UNSPEC_NOP))]
22639 "TARGET_SSE2"
22640 "pslldq\t{%2, %0|%0, %2}"
22641 [(set_attr "type" "sseishft")
22642 (set_attr "mode" "TI")])
22643
22644 (define_insn "sse2_lshrti3"
22645 [(set (match_operand:TI 0 "register_operand" "=x")
22646 (unspec:TI
22647 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22648 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22649 (const_int 8)))] UNSPEC_NOP))]
22650 "TARGET_SSE2"
22651 "psrldq\t{%2, %0|%0, %2}"
22652 [(set_attr "type" "sseishft")
22653 (set_attr "mode" "TI")])
22654
22655 ;; SSE unpack
22656
22657 (define_insn "sse2_unpckhpd"
22658 [(set (match_operand:V2DF 0 "register_operand" "=x")
22659 (vec_concat:V2DF
22660 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22661 (parallel [(const_int 1)]))
22662 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22663 (parallel [(const_int 0)]))))]
22664 "TARGET_SSE2"
22665 "unpckhpd\t{%2, %0|%0, %2}"
22666 [(set_attr "type" "ssecvt")
22667 (set_attr "mode" "TI")])
22668
22669 (define_insn "sse2_unpcklpd"
22670 [(set (match_operand:V2DF 0 "register_operand" "=x")
22671 (vec_concat:V2DF
22672 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22673 (parallel [(const_int 0)]))
22674 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22675 (parallel [(const_int 1)]))))]
22676 "TARGET_SSE2"
22677 "unpcklpd\t{%2, %0|%0, %2}"
22678 [(set_attr "type" "ssecvt")
22679 (set_attr "mode" "TI")])
22680
22681 ;; MMX pack/unpack insns.
22682
22683 (define_insn "sse2_packsswb"
22684 [(set (match_operand:V16QI 0 "register_operand" "=x")
22685 (vec_concat:V16QI
22686 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22687 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22688 "TARGET_SSE2"
22689 "packsswb\t{%2, %0|%0, %2}"
22690 [(set_attr "type" "ssecvt")
22691 (set_attr "mode" "TI")])
22692
22693 (define_insn "sse2_packssdw"
22694 [(set (match_operand:V8HI 0 "register_operand" "=x")
22695 (vec_concat:V8HI
22696 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22697 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22698 "TARGET_SSE2"
22699 "packssdw\t{%2, %0|%0, %2}"
22700 [(set_attr "type" "ssecvt")
22701 (set_attr "mode" "TI")])
22702
22703 (define_insn "sse2_packuswb"
22704 [(set (match_operand:V16QI 0 "register_operand" "=x")
22705 (vec_concat:V16QI
22706 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22707 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22708 "TARGET_SSE2"
22709 "packuswb\t{%2, %0|%0, %2}"
22710 [(set_attr "type" "ssecvt")
22711 (set_attr "mode" "TI")])
22712
22713 (define_insn "sse2_punpckhbw"
22714 [(set (match_operand:V16QI 0 "register_operand" "=x")
22715 (vec_merge:V16QI
22716 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22717 (parallel [(const_int 8) (const_int 0)
22718 (const_int 9) (const_int 1)
22719 (const_int 10) (const_int 2)
22720 (const_int 11) (const_int 3)
22721 (const_int 12) (const_int 4)
22722 (const_int 13) (const_int 5)
22723 (const_int 14) (const_int 6)
22724 (const_int 15) (const_int 7)]))
22725 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22726 (parallel [(const_int 0) (const_int 8)
22727 (const_int 1) (const_int 9)
22728 (const_int 2) (const_int 10)
22729 (const_int 3) (const_int 11)
22730 (const_int 4) (const_int 12)
22731 (const_int 5) (const_int 13)
22732 (const_int 6) (const_int 14)
22733 (const_int 7) (const_int 15)]))
22734 (const_int 21845)))]
22735 "TARGET_SSE2"
22736 "punpckhbw\t{%2, %0|%0, %2}"
22737 [(set_attr "type" "ssecvt")
22738 (set_attr "mode" "TI")])
22739
22740 (define_insn "sse2_punpckhwd"
22741 [(set (match_operand:V8HI 0 "register_operand" "=x")
22742 (vec_merge:V8HI
22743 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22744 (parallel [(const_int 4) (const_int 0)
22745 (const_int 5) (const_int 1)
22746 (const_int 6) (const_int 2)
22747 (const_int 7) (const_int 3)]))
22748 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22749 (parallel [(const_int 0) (const_int 4)
22750 (const_int 1) (const_int 5)
22751 (const_int 2) (const_int 6)
22752 (const_int 3) (const_int 7)]))
22753 (const_int 85)))]
22754 "TARGET_SSE2"
22755 "punpckhwd\t{%2, %0|%0, %2}"
22756 [(set_attr "type" "ssecvt")
22757 (set_attr "mode" "TI")])
22758
22759 (define_insn "sse2_punpckhdq"
22760 [(set (match_operand:V4SI 0 "register_operand" "=x")
22761 (vec_merge:V4SI
22762 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22763 (parallel [(const_int 2) (const_int 0)
22764 (const_int 3) (const_int 1)]))
22765 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22766 (parallel [(const_int 0) (const_int 2)
22767 (const_int 1) (const_int 3)]))
22768 (const_int 5)))]
22769 "TARGET_SSE2"
22770 "punpckhdq\t{%2, %0|%0, %2}"
22771 [(set_attr "type" "ssecvt")
22772 (set_attr "mode" "TI")])
22773
22774 (define_insn "sse2_punpcklbw"
22775 [(set (match_operand:V16QI 0 "register_operand" "=x")
22776 (vec_merge:V16QI
22777 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22778 (parallel [(const_int 0) (const_int 8)
22779 (const_int 1) (const_int 9)
22780 (const_int 2) (const_int 10)
22781 (const_int 3) (const_int 11)
22782 (const_int 4) (const_int 12)
22783 (const_int 5) (const_int 13)
22784 (const_int 6) (const_int 14)
22785 (const_int 7) (const_int 15)]))
22786 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22787 (parallel [(const_int 8) (const_int 0)
22788 (const_int 9) (const_int 1)
22789 (const_int 10) (const_int 2)
22790 (const_int 11) (const_int 3)
22791 (const_int 12) (const_int 4)
22792 (const_int 13) (const_int 5)
22793 (const_int 14) (const_int 6)
22794 (const_int 15) (const_int 7)]))
22795 (const_int 21845)))]
22796 "TARGET_SSE2"
22797 "punpcklbw\t{%2, %0|%0, %2}"
22798 [(set_attr "type" "ssecvt")
22799 (set_attr "mode" "TI")])
22800
22801 (define_insn "sse2_punpcklwd"
22802 [(set (match_operand:V8HI 0 "register_operand" "=x")
22803 (vec_merge:V8HI
22804 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22805 (parallel [(const_int 0) (const_int 4)
22806 (const_int 1) (const_int 5)
22807 (const_int 2) (const_int 6)
22808 (const_int 3) (const_int 7)]))
22809 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22810 (parallel [(const_int 4) (const_int 0)
22811 (const_int 5) (const_int 1)
22812 (const_int 6) (const_int 2)
22813 (const_int 7) (const_int 3)]))
22814 (const_int 85)))]
22815 "TARGET_SSE2"
22816 "punpcklwd\t{%2, %0|%0, %2}"
22817 [(set_attr "type" "ssecvt")
22818 (set_attr "mode" "TI")])
22819
22820 (define_insn "sse2_punpckldq"
22821 [(set (match_operand:V4SI 0 "register_operand" "=x")
22822 (vec_merge:V4SI
22823 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22824 (parallel [(const_int 0) (const_int 2)
22825 (const_int 1) (const_int 3)]))
22826 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22827 (parallel [(const_int 2) (const_int 0)
22828 (const_int 3) (const_int 1)]))
22829 (const_int 5)))]
22830 "TARGET_SSE2"
22831 "punpckldq\t{%2, %0|%0, %2}"
22832 [(set_attr "type" "ssecvt")
22833 (set_attr "mode" "TI")])
22834
22835 (define_insn "sse2_punpcklqdq"
22836 [(set (match_operand:V2DI 0 "register_operand" "=x")
22837 (vec_merge:V2DI
22838 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22839 (parallel [(const_int 1)
22840 (const_int 0)]))
22841 (match_operand:V2DI 1 "register_operand" "0")
22842 (const_int 1)))]
22843 "TARGET_SSE2"
22844 "punpcklqdq\t{%2, %0|%0, %2}"
22845 [(set_attr "type" "ssecvt")
22846 (set_attr "mode" "TI")])
22847
22848 (define_insn "sse2_punpckhqdq"
22849 [(set (match_operand:V2DI 0 "register_operand" "=x")
22850 (vec_merge:V2DI
22851 (match_operand:V2DI 1 "register_operand" "0")
22852 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22853 (parallel [(const_int 1)
22854 (const_int 0)]))
22855 (const_int 1)))]
22856 "TARGET_SSE2"
22857 "punpckhqdq\t{%2, %0|%0, %2}"
22858 [(set_attr "type" "ssecvt")
22859 (set_attr "mode" "TI")])
22860
22861 ;; SSE2 moves
22862
22863 (define_insn "sse2_movapd"
22864 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22865 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22866 UNSPEC_MOVA))]
22867 "TARGET_SSE2
22868 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22869 "movapd\t{%1, %0|%0, %1}"
22870 [(set_attr "type" "ssemov")
22871 (set_attr "mode" "V2DF")])
22872
22873 (define_insn "sse2_movupd"
22874 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22875 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22876 UNSPEC_MOVU))]
22877 "TARGET_SSE2
22878 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22879 "movupd\t{%1, %0|%0, %1}"
22880 [(set_attr "type" "ssecvt")
22881 (set_attr "mode" "V2DF")])
22882
22883 (define_insn "sse2_movdqa"
22884 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22885 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22886 UNSPEC_MOVA))]
22887 "TARGET_SSE2
22888 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22889 "movdqa\t{%1, %0|%0, %1}"
22890 [(set_attr "type" "ssemov")
22891 (set_attr "mode" "TI")])
22892
22893 (define_insn "sse2_movdqu"
22894 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22895 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22896 UNSPEC_MOVU))]
22897 "TARGET_SSE2
22898 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22899 "movdqu\t{%1, %0|%0, %1}"
22900 [(set_attr "type" "ssecvt")
22901 (set_attr "mode" "TI")])
22902
22903 (define_insn "sse2_movdq2q"
22904 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22905 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22906 (parallel [(const_int 0)])))]
22907 "TARGET_SSE2 && !TARGET_64BIT"
22908 "@
22909 movq\t{%1, %0|%0, %1}
22910 movdq2q\t{%1, %0|%0, %1}"
22911 [(set_attr "type" "ssecvt")
22912 (set_attr "mode" "TI")])
22913
22914 (define_insn "sse2_movdq2q_rex64"
22915 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22916 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22917 (parallel [(const_int 0)])))]
22918 "TARGET_SSE2 && TARGET_64BIT"
22919 "@
22920 movq\t{%1, %0|%0, %1}
22921 movdq2q\t{%1, %0|%0, %1}
22922 movd\t{%1, %0|%0, %1}"
22923 [(set_attr "type" "ssecvt")
22924 (set_attr "mode" "TI")])
22925
22926 (define_insn "sse2_movq2dq"
22927 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22928 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22929 (const_int 0)))]
22930 "TARGET_SSE2 && !TARGET_64BIT"
22931 "@
22932 movq\t{%1, %0|%0, %1}
22933 movq2dq\t{%1, %0|%0, %1}"
22934 [(set_attr "type" "ssecvt,ssemov")
22935 (set_attr "mode" "TI")])
22936
22937 (define_insn "sse2_movq2dq_rex64"
22938 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22939 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22940 (const_int 0)))]
22941 "TARGET_SSE2 && TARGET_64BIT"
22942 "@
22943 movq\t{%1, %0|%0, %1}
22944 movq2dq\t{%1, %0|%0, %1}
22945 movd\t{%1, %0|%0, %1}"
22946 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22947 (set_attr "mode" "TI")])
22948
22949 (define_insn "sse2_movq"
22950 [(set (match_operand:V2DI 0 "register_operand" "=x")
22951 (vec_concat:V2DI (vec_select:DI
22952 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22953 (parallel [(const_int 0)]))
22954 (const_int 0)))]
22955 "TARGET_SSE2"
22956 "movq\t{%1, %0|%0, %1}"
22957 [(set_attr "type" "ssemov")
22958 (set_attr "mode" "TI")])
22959
22960 (define_insn "sse2_loadd"
22961 [(set (match_operand:V4SI 0 "register_operand" "=x")
22962 (vec_merge:V4SI
22963 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22964 (const_vector:V4SI [(const_int 0)
22965 (const_int 0)
22966 (const_int 0)
22967 (const_int 0)])
22968 (const_int 1)))]
22969 "TARGET_SSE2"
22970 "movd\t{%1, %0|%0, %1}"
22971 [(set_attr "type" "ssemov")
22972 (set_attr "mode" "TI")])
22973
22974 (define_insn "sse2_stored"
22975 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22976 (vec_select:SI
22977 (match_operand:V4SI 1 "register_operand" "x")
22978 (parallel [(const_int 0)])))]
22979 "TARGET_SSE2"
22980 "movd\t{%1, %0|%0, %1}"
22981 [(set_attr "type" "ssemov")
22982 (set_attr "mode" "TI")])
22983
22984 (define_insn "sse2_movhpd"
22985 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22986 (vec_merge:V2DF
22987 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22988 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22989 (const_int 2)))]
22990 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22991 "movhpd\t{%2, %0|%0, %2}"
22992 [(set_attr "type" "ssecvt")
22993 (set_attr "mode" "V2DF")])
22994
22995 (define_insn "sse2_movlpd"
22996 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22997 (vec_merge:V2DF
22998 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22999 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23000 (const_int 1)))]
23001 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23002 "movlpd\t{%2, %0|%0, %2}"
23003 [(set_attr "type" "ssecvt")
23004 (set_attr "mode" "V2DF")])
23005
23006 (define_expand "sse2_loadsd"
23007 [(match_operand:V2DF 0 "register_operand" "")
23008 (match_operand:DF 1 "memory_operand" "")]
23009 "TARGET_SSE2"
23010 {
23011 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23012 CONST0_RTX (V2DFmode)));
23013 DONE;
23014 })
23015
23016 (define_insn "sse2_loadsd_1"
23017 [(set (match_operand:V2DF 0 "register_operand" "=x")
23018 (vec_merge:V2DF
23019 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23020 (match_operand:V2DF 2 "const0_operand" "X")
23021 (const_int 1)))]
23022 "TARGET_SSE2"
23023 "movsd\t{%1, %0|%0, %1}"
23024 [(set_attr "type" "ssecvt")
23025 (set_attr "mode" "DF")])
23026
23027 (define_insn "sse2_movsd"
23028 [(set (match_operand:V2DF 0 "register_operand" "=x")
23029 (vec_merge:V2DF
23030 (match_operand:V2DF 1 "register_operand" "0")
23031 (match_operand:V2DF 2 "register_operand" "x")
23032 (const_int 1)))]
23033 "TARGET_SSE2"
23034 "movsd\t{%2, %0|%0, %2}"
23035 [(set_attr "type" "ssecvt")
23036 (set_attr "mode" "DF")])
23037
23038 (define_insn "sse2_storesd"
23039 [(set (match_operand:DF 0 "memory_operand" "=m")
23040 (vec_select:DF
23041 (match_operand:V2DF 1 "register_operand" "x")
23042 (parallel [(const_int 0)])))]
23043 "TARGET_SSE2"
23044 "movsd\t{%1, %0|%0, %1}"
23045 [(set_attr "type" "ssecvt")
23046 (set_attr "mode" "DF")])
23047
23048 (define_insn "sse2_shufpd"
23049 [(set (match_operand:V2DF 0 "register_operand" "=x")
23050 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23051 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23052 (match_operand:SI 3 "immediate_operand" "i")]
23053 UNSPEC_SHUFFLE))]
23054 "TARGET_SSE2"
23055 ;; @@@ check operand order for intel/nonintel syntax
23056 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23057 [(set_attr "type" "ssecvt")
23058 (set_attr "mode" "V2DF")])
23059
23060 (define_insn "sse2_clflush"
23061 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23062 UNSPECV_CLFLUSH)]
23063 "TARGET_SSE2"
23064 "clflush %0"
23065 [(set_attr "type" "sse")
23066 (set_attr "memory" "unknown")])
23067
23068 (define_expand "sse2_mfence"
23069 [(set (match_dup 0)
23070 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23071 "TARGET_SSE2"
23072 {
23073 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23074 MEM_VOLATILE_P (operands[0]) = 1;
23075 })
23076
23077 (define_insn "*mfence_insn"
23078 [(set (match_operand:BLK 0 "" "")
23079 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23080 "TARGET_SSE2"
23081 "mfence"
23082 [(set_attr "type" "sse")
23083 (set_attr "memory" "unknown")])
23084
23085 (define_expand "sse2_lfence"
23086 [(set (match_dup 0)
23087 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23088 "TARGET_SSE2"
23089 {
23090 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23091 MEM_VOLATILE_P (operands[0]) = 1;
23092 })
23093
23094 (define_insn "*lfence_insn"
23095 [(set (match_operand:BLK 0 "" "")
23096 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23097 "TARGET_SSE2"
23098 "lfence"
23099 [(set_attr "type" "sse")
23100 (set_attr "memory" "unknown")])