(fyl2x_sfxf3, fyl2x_dfxf3, fscale_sfxf3, fscale_dfxf3): Fix condition.
[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 (UNSPEC_ADDSUB 71)
113 (UNSPEC_HADD 72)
114 (UNSPEC_HSUB 73)
115 (UNSPEC_MOVSHDUP 74)
116 (UNSPEC_MOVSLDUP 75)
117 (UNSPEC_LDQQU 76)
118 (UNSPEC_MOVDDUP 77)
119
120 ; x87 Floating point
121 (UNSPEC_FPATAN 65)
122 (UNSPEC_FYL2X 66)
123 (UNSPEC_FSCALE 67)
124 (UNSPEC_FRNDINT 68)
125 (UNSPEC_F2XM1 69)
126
127 ; REP instruction
128 (UNSPEC_REP 75)
129 ])
130
131 (define_constants
132 [(UNSPECV_BLOCKAGE 0)
133 (UNSPECV_EH_RETURN 13)
134 (UNSPECV_EMMS 31)
135 (UNSPECV_LDMXCSR 37)
136 (UNSPECV_STMXCSR 40)
137 (UNSPECV_FEMMS 46)
138 (UNSPECV_CLFLUSH 57)
139 (UNSPECV_ALIGN 68)
140 (UNSPECV_MONITOR 69)
141 (UNSPECV_MWAIT 70)
142 ])
143
144 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
145 ;; from i386.c.
146
147 ;; In C guard expressions, put expressions which may be compile-time
148 ;; constants first. This allows for better optimization. For
149 ;; example, write "TARGET_64BIT && reload_completed", not
150 ;; "reload_completed && TARGET_64BIT".
151
152 \f
153 ;; Processor type. This attribute must exactly match the processor_type
154 ;; enumeration in i386.h.
155 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
156 (const (symbol_ref "ix86_tune")))
157
158 ;; A basic instruction type. Refinements due to arguments to be
159 ;; provided in other attributes.
160 (define_attr "type"
161 "other,multi,
162 alu,alu1,negnot,imov,imovx,lea,
163 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
164 icmp,test,ibr,setcc,icmov,
165 push,pop,call,callv,leave,
166 str,cld,
167 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
168 sselog,sseiadd,sseishft,sseimul,
169 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
170 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
171 (const_string "other"))
172
173 ;; Main data type used by the insn
174 (define_attr "mode"
175 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
176 (const_string "unknown"))
177
178 ;; The CPU unit operations uses.
179 (define_attr "unit" "integer,i387,sse,mmx,unknown"
180 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
181 (const_string "i387")
182 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
183 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
184 (const_string "sse")
185 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
186 (const_string "mmx")
187 (eq_attr "type" "other")
188 (const_string "unknown")]
189 (const_string "integer")))
190
191 ;; The (bounding maximum) length of an instruction immediate.
192 (define_attr "length_immediate" ""
193 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
194 (const_int 0)
195 (eq_attr "unit" "i387,sse,mmx")
196 (const_int 0)
197 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
198 imul,icmp,push,pop")
199 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
200 (eq_attr "type" "imov,test")
201 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
202 (eq_attr "type" "call")
203 (if_then_else (match_operand 0 "constant_call_address_operand" "")
204 (const_int 4)
205 (const_int 0))
206 (eq_attr "type" "callv")
207 (if_then_else (match_operand 1 "constant_call_address_operand" "")
208 (const_int 4)
209 (const_int 0))
210 ;; We don't know the size before shorten_branches. Expect
211 ;; the instruction to fit for better scheduling.
212 (eq_attr "type" "ibr")
213 (const_int 1)
214 ]
215 (symbol_ref "/* Update immediate_length and other attributes! */
216 abort(),1")))
217
218 ;; The (bounding maximum) length of an instruction address.
219 (define_attr "length_address" ""
220 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
221 (const_int 0)
222 (and (eq_attr "type" "call")
223 (match_operand 0 "constant_call_address_operand" ""))
224 (const_int 0)
225 (and (eq_attr "type" "callv")
226 (match_operand 1 "constant_call_address_operand" ""))
227 (const_int 0)
228 ]
229 (symbol_ref "ix86_attr_length_address_default (insn)")))
230
231 ;; Set when length prefix is used.
232 (define_attr "prefix_data16" ""
233 (if_then_else (ior (eq_attr "mode" "HI")
234 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
235 (const_int 1)
236 (const_int 0)))
237
238 ;; Set when string REP prefix is used.
239 (define_attr "prefix_rep" ""
240 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
241 (const_int 1)
242 (const_int 0)))
243
244 ;; Set when 0f opcode prefix is used.
245 (define_attr "prefix_0f" ""
246 (if_then_else
247 (ior (eq_attr "type" "imovx,setcc,icmov")
248 (eq_attr "unit" "sse,mmx"))
249 (const_int 1)
250 (const_int 0)))
251
252 ;; Set when 0f opcode prefix is used.
253 (define_attr "prefix_rex" ""
254 (cond [(and (eq_attr "mode" "DI")
255 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
256 (const_int 1)
257 (and (eq_attr "mode" "QI")
258 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
259 (const_int 0)))
260 (const_int 1)
261 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
262 (const_int 0))
263 (const_int 1)
264 ]
265 (const_int 0)))
266
267 ;; Set when modrm byte is used.
268 (define_attr "modrm" ""
269 (cond [(eq_attr "type" "str,cld,leave")
270 (const_int 0)
271 (eq_attr "unit" "i387")
272 (const_int 0)
273 (and (eq_attr "type" "incdec")
274 (ior (match_operand:SI 1 "register_operand" "")
275 (match_operand:HI 1 "register_operand" "")))
276 (const_int 0)
277 (and (eq_attr "type" "push")
278 (not (match_operand 1 "memory_operand" "")))
279 (const_int 0)
280 (and (eq_attr "type" "pop")
281 (not (match_operand 0 "memory_operand" "")))
282 (const_int 0)
283 (and (eq_attr "type" "imov")
284 (and (match_operand 0 "register_operand" "")
285 (match_operand 1 "immediate_operand" "")))
286 (const_int 0)
287 (and (eq_attr "type" "call")
288 (match_operand 0 "constant_call_address_operand" ""))
289 (const_int 0)
290 (and (eq_attr "type" "callv")
291 (match_operand 1 "constant_call_address_operand" ""))
292 (const_int 0)
293 ]
294 (const_int 1)))
295
296 ;; The (bounding maximum) length of an instruction in bytes.
297 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
298 ;; to split it and compute proper length as for other insns.
299 (define_attr "length" ""
300 (cond [(eq_attr "type" "other,multi,fistp")
301 (const_int 16)
302 (eq_attr "type" "fcmp")
303 (const_int 4)
304 (eq_attr "unit" "i387")
305 (plus (const_int 2)
306 (plus (attr "prefix_data16")
307 (attr "length_address")))]
308 (plus (plus (attr "modrm")
309 (plus (attr "prefix_0f")
310 (plus (attr "prefix_rex")
311 (const_int 1))))
312 (plus (attr "prefix_rep")
313 (plus (attr "prefix_data16")
314 (plus (attr "length_immediate")
315 (attr "length_address")))))))
316
317 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
318 ;; `store' if there is a simple memory reference therein, or `unknown'
319 ;; if the instruction is complex.
320
321 (define_attr "memory" "none,load,store,both,unknown"
322 (cond [(eq_attr "type" "other,multi,str")
323 (const_string "unknown")
324 (eq_attr "type" "lea,fcmov,fpspc,cld")
325 (const_string "none")
326 (eq_attr "type" "fistp,leave")
327 (const_string "both")
328 (eq_attr "type" "push")
329 (if_then_else (match_operand 1 "memory_operand" "")
330 (const_string "both")
331 (const_string "store"))
332 (eq_attr "type" "pop")
333 (if_then_else (match_operand 0 "memory_operand" "")
334 (const_string "both")
335 (const_string "load"))
336 (eq_attr "type" "setcc")
337 (if_then_else (match_operand 0 "memory_operand" "")
338 (const_string "store")
339 (const_string "none"))
340 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
341 (if_then_else (ior (match_operand 0 "memory_operand" "")
342 (match_operand 1 "memory_operand" ""))
343 (const_string "load")
344 (const_string "none"))
345 (eq_attr "type" "ibr")
346 (if_then_else (match_operand 0 "memory_operand" "")
347 (const_string "load")
348 (const_string "none"))
349 (eq_attr "type" "call")
350 (if_then_else (match_operand 0 "constant_call_address_operand" "")
351 (const_string "none")
352 (const_string "load"))
353 (eq_attr "type" "callv")
354 (if_then_else (match_operand 1 "constant_call_address_operand" "")
355 (const_string "none")
356 (const_string "load"))
357 (and (eq_attr "type" "alu1,negnot")
358 (match_operand 1 "memory_operand" ""))
359 (const_string "both")
360 (and (match_operand 0 "memory_operand" "")
361 (match_operand 1 "memory_operand" ""))
362 (const_string "both")
363 (match_operand 0 "memory_operand" "")
364 (const_string "store")
365 (match_operand 1 "memory_operand" "")
366 (const_string "load")
367 (and (eq_attr "type"
368 "!alu1,negnot,
369 imov,imovx,icmp,test,
370 fmov,fcmp,fsgn,
371 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
372 mmx,mmxmov,mmxcmp,mmxcvt")
373 (match_operand 2 "memory_operand" ""))
374 (const_string "load")
375 (and (eq_attr "type" "icmov")
376 (match_operand 3 "memory_operand" ""))
377 (const_string "load")
378 ]
379 (const_string "none")))
380
381 ;; Indicates if an instruction has both an immediate and a displacement.
382
383 (define_attr "imm_disp" "false,true,unknown"
384 (cond [(eq_attr "type" "other,multi")
385 (const_string "unknown")
386 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
387 (and (match_operand 0 "memory_displacement_operand" "")
388 (match_operand 1 "immediate_operand" "")))
389 (const_string "true")
390 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
391 (and (match_operand 0 "memory_displacement_operand" "")
392 (match_operand 2 "immediate_operand" "")))
393 (const_string "true")
394 ]
395 (const_string "false")))
396
397 ;; Indicates if an FP operation has an integer source.
398
399 (define_attr "fp_int_src" "false,true"
400 (const_string "false"))
401
402 ;; Describe a user's asm statement.
403 (define_asm_attributes
404 [(set_attr "length" "128")
405 (set_attr "type" "multi")])
406 \f
407 (include "pentium.md")
408 (include "ppro.md")
409 (include "k6.md")
410 (include "athlon.md")
411 \f
412 ;; Compare instructions.
413
414 ;; All compare insns have expanders that save the operands away without
415 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
416 ;; after the cmp) will actually emit the cmpM.
417
418 (define_expand "cmpdi"
419 [(set (reg:CC 17)
420 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
421 (match_operand:DI 1 "x86_64_general_operand" "")))]
422 ""
423 {
424 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
425 operands[0] = force_reg (DImode, operands[0]);
426 ix86_compare_op0 = operands[0];
427 ix86_compare_op1 = operands[1];
428 DONE;
429 })
430
431 (define_expand "cmpsi"
432 [(set (reg:CC 17)
433 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
434 (match_operand:SI 1 "general_operand" "")))]
435 ""
436 {
437 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
438 operands[0] = force_reg (SImode, operands[0]);
439 ix86_compare_op0 = operands[0];
440 ix86_compare_op1 = operands[1];
441 DONE;
442 })
443
444 (define_expand "cmphi"
445 [(set (reg:CC 17)
446 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
447 (match_operand:HI 1 "general_operand" "")))]
448 ""
449 {
450 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
451 operands[0] = force_reg (HImode, operands[0]);
452 ix86_compare_op0 = operands[0];
453 ix86_compare_op1 = operands[1];
454 DONE;
455 })
456
457 (define_expand "cmpqi"
458 [(set (reg:CC 17)
459 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
460 (match_operand:QI 1 "general_operand" "")))]
461 "TARGET_QIMODE_MATH"
462 {
463 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
464 operands[0] = force_reg (QImode, operands[0]);
465 ix86_compare_op0 = operands[0];
466 ix86_compare_op1 = operands[1];
467 DONE;
468 })
469
470 (define_insn "cmpdi_ccno_1_rex64"
471 [(set (reg 17)
472 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
473 (match_operand:DI 1 "const0_operand" "n,n")))]
474 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
475 "@
476 test{q}\t{%0, %0|%0, %0}
477 cmp{q}\t{%1, %0|%0, %1}"
478 [(set_attr "type" "test,icmp")
479 (set_attr "length_immediate" "0,1")
480 (set_attr "mode" "DI")])
481
482 (define_insn "*cmpdi_minus_1_rex64"
483 [(set (reg 17)
484 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
485 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
486 (const_int 0)))]
487 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
488 "cmp{q}\t{%1, %0|%0, %1}"
489 [(set_attr "type" "icmp")
490 (set_attr "mode" "DI")])
491
492 (define_expand "cmpdi_1_rex64"
493 [(set (reg:CC 17)
494 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
495 (match_operand:DI 1 "general_operand" "")))]
496 "TARGET_64BIT"
497 "")
498
499 (define_insn "cmpdi_1_insn_rex64"
500 [(set (reg 17)
501 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
502 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
503 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
504 "cmp{q}\t{%1, %0|%0, %1}"
505 [(set_attr "type" "icmp")
506 (set_attr "mode" "DI")])
507
508
509 (define_insn "*cmpsi_ccno_1"
510 [(set (reg 17)
511 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
512 (match_operand:SI 1 "const0_operand" "n,n")))]
513 "ix86_match_ccmode (insn, CCNOmode)"
514 "@
515 test{l}\t{%0, %0|%0, %0}
516 cmp{l}\t{%1, %0|%0, %1}"
517 [(set_attr "type" "test,icmp")
518 (set_attr "length_immediate" "0,1")
519 (set_attr "mode" "SI")])
520
521 (define_insn "*cmpsi_minus_1"
522 [(set (reg 17)
523 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
524 (match_operand:SI 1 "general_operand" "ri,mr"))
525 (const_int 0)))]
526 "ix86_match_ccmode (insn, CCGOCmode)"
527 "cmp{l}\t{%1, %0|%0, %1}"
528 [(set_attr "type" "icmp")
529 (set_attr "mode" "SI")])
530
531 (define_expand "cmpsi_1"
532 [(set (reg:CC 17)
533 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
534 (match_operand:SI 1 "general_operand" "ri,mr")))]
535 ""
536 "")
537
538 (define_insn "*cmpsi_1_insn"
539 [(set (reg 17)
540 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
541 (match_operand:SI 1 "general_operand" "ri,mr")))]
542 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
543 && ix86_match_ccmode (insn, CCmode)"
544 "cmp{l}\t{%1, %0|%0, %1}"
545 [(set_attr "type" "icmp")
546 (set_attr "mode" "SI")])
547
548 (define_insn "*cmphi_ccno_1"
549 [(set (reg 17)
550 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
551 (match_operand:HI 1 "const0_operand" "n,n")))]
552 "ix86_match_ccmode (insn, CCNOmode)"
553 "@
554 test{w}\t{%0, %0|%0, %0}
555 cmp{w}\t{%1, %0|%0, %1}"
556 [(set_attr "type" "test,icmp")
557 (set_attr "length_immediate" "0,1")
558 (set_attr "mode" "HI")])
559
560 (define_insn "*cmphi_minus_1"
561 [(set (reg 17)
562 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
563 (match_operand:HI 1 "general_operand" "ri,mr"))
564 (const_int 0)))]
565 "ix86_match_ccmode (insn, CCGOCmode)"
566 "cmp{w}\t{%1, %0|%0, %1}"
567 [(set_attr "type" "icmp")
568 (set_attr "mode" "HI")])
569
570 (define_insn "*cmphi_1"
571 [(set (reg 17)
572 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
573 (match_operand:HI 1 "general_operand" "ri,mr")))]
574 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
575 && ix86_match_ccmode (insn, CCmode)"
576 "cmp{w}\t{%1, %0|%0, %1}"
577 [(set_attr "type" "icmp")
578 (set_attr "mode" "HI")])
579
580 (define_insn "*cmpqi_ccno_1"
581 [(set (reg 17)
582 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
583 (match_operand:QI 1 "const0_operand" "n,n")))]
584 "ix86_match_ccmode (insn, CCNOmode)"
585 "@
586 test{b}\t{%0, %0|%0, %0}
587 cmp{b}\t{$0, %0|%0, 0}"
588 [(set_attr "type" "test,icmp")
589 (set_attr "length_immediate" "0,1")
590 (set_attr "mode" "QI")])
591
592 (define_insn "*cmpqi_1"
593 [(set (reg 17)
594 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
595 (match_operand:QI 1 "general_operand" "qi,mq")))]
596 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
597 && ix86_match_ccmode (insn, CCmode)"
598 "cmp{b}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "icmp")
600 (set_attr "mode" "QI")])
601
602 (define_insn "*cmpqi_minus_1"
603 [(set (reg 17)
604 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
605 (match_operand:QI 1 "general_operand" "qi,mq"))
606 (const_int 0)))]
607 "ix86_match_ccmode (insn, CCGOCmode)"
608 "cmp{b}\t{%1, %0|%0, %1}"
609 [(set_attr "type" "icmp")
610 (set_attr "mode" "QI")])
611
612 (define_insn "*cmpqi_ext_1"
613 [(set (reg 17)
614 (compare
615 (match_operand:QI 0 "general_operand" "Qm")
616 (subreg:QI
617 (zero_extract:SI
618 (match_operand 1 "ext_register_operand" "Q")
619 (const_int 8)
620 (const_int 8)) 0)))]
621 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
622 "cmp{b}\t{%h1, %0|%0, %h1}"
623 [(set_attr "type" "icmp")
624 (set_attr "mode" "QI")])
625
626 (define_insn "*cmpqi_ext_1_rex64"
627 [(set (reg 17)
628 (compare
629 (match_operand:QI 0 "register_operand" "Q")
630 (subreg:QI
631 (zero_extract:SI
632 (match_operand 1 "ext_register_operand" "Q")
633 (const_int 8)
634 (const_int 8)) 0)))]
635 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
636 "cmp{b}\t{%h1, %0|%0, %h1}"
637 [(set_attr "type" "icmp")
638 (set_attr "mode" "QI")])
639
640 (define_insn "*cmpqi_ext_2"
641 [(set (reg 17)
642 (compare
643 (subreg:QI
644 (zero_extract:SI
645 (match_operand 0 "ext_register_operand" "Q")
646 (const_int 8)
647 (const_int 8)) 0)
648 (match_operand:QI 1 "const0_operand" "n")))]
649 "ix86_match_ccmode (insn, CCNOmode)"
650 "test{b}\t%h0, %h0"
651 [(set_attr "type" "test")
652 (set_attr "length_immediate" "0")
653 (set_attr "mode" "QI")])
654
655 (define_expand "cmpqi_ext_3"
656 [(set (reg:CC 17)
657 (compare:CC
658 (subreg:QI
659 (zero_extract:SI
660 (match_operand 0 "ext_register_operand" "")
661 (const_int 8)
662 (const_int 8)) 0)
663 (match_operand:QI 1 "general_operand" "")))]
664 ""
665 "")
666
667 (define_insn "cmpqi_ext_3_insn"
668 [(set (reg 17)
669 (compare
670 (subreg:QI
671 (zero_extract:SI
672 (match_operand 0 "ext_register_operand" "Q")
673 (const_int 8)
674 (const_int 8)) 0)
675 (match_operand:QI 1 "general_operand" "Qmn")))]
676 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
677 "cmp{b}\t{%1, %h0|%h0, %1}"
678 [(set_attr "type" "icmp")
679 (set_attr "mode" "QI")])
680
681 (define_insn "cmpqi_ext_3_insn_rex64"
682 [(set (reg 17)
683 (compare
684 (subreg:QI
685 (zero_extract:SI
686 (match_operand 0 "ext_register_operand" "Q")
687 (const_int 8)
688 (const_int 8)) 0)
689 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
691 "cmp{b}\t{%1, %h0|%h0, %1}"
692 [(set_attr "type" "icmp")
693 (set_attr "mode" "QI")])
694
695 (define_insn "*cmpqi_ext_4"
696 [(set (reg 17)
697 (compare
698 (subreg:QI
699 (zero_extract:SI
700 (match_operand 0 "ext_register_operand" "Q")
701 (const_int 8)
702 (const_int 8)) 0)
703 (subreg:QI
704 (zero_extract:SI
705 (match_operand 1 "ext_register_operand" "Q")
706 (const_int 8)
707 (const_int 8)) 0)))]
708 "ix86_match_ccmode (insn, CCmode)"
709 "cmp{b}\t{%h1, %h0|%h0, %h1}"
710 [(set_attr "type" "icmp")
711 (set_attr "mode" "QI")])
712
713 ;; These implement float point compares.
714 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
715 ;; which would allow mix and match FP modes on the compares. Which is what
716 ;; the old patterns did, but with many more of them.
717
718 (define_expand "cmpxf"
719 [(set (reg:CC 17)
720 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
721 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
722 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
723 {
724 ix86_compare_op0 = operands[0];
725 ix86_compare_op1 = operands[1];
726 DONE;
727 })
728
729 (define_expand "cmptf"
730 [(set (reg:CC 17)
731 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
732 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
733 "TARGET_80387"
734 {
735 ix86_compare_op0 = operands[0];
736 ix86_compare_op1 = operands[1];
737 DONE;
738 })
739
740 (define_expand "cmpdf"
741 [(set (reg:CC 17)
742 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
743 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
744 "TARGET_80387 || TARGET_SSE2"
745 {
746 ix86_compare_op0 = operands[0];
747 ix86_compare_op1 = operands[1];
748 DONE;
749 })
750
751 (define_expand "cmpsf"
752 [(set (reg:CC 17)
753 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
754 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
755 "TARGET_80387 || TARGET_SSE"
756 {
757 ix86_compare_op0 = operands[0];
758 ix86_compare_op1 = operands[1];
759 DONE;
760 })
761
762 ;; FP compares, step 1:
763 ;; Set the FP condition codes.
764 ;;
765 ;; CCFPmode compare with exceptions
766 ;; CCFPUmode compare with no exceptions
767
768 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
769 ;; and that fp moves clobber the condition codes, and that there is
770 ;; currently no way to describe this fact to reg-stack. So there are
771 ;; no splitters yet for this.
772
773 ;; %%% YIKES! This scheme does not retain a strong connection between
774 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
775 ;; work! Only allow tos/mem with tos in op 0.
776 ;;
777 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
778 ;; things aren't as bad as they sound...
779
780 (define_insn "*cmpfp_0"
781 [(set (match_operand:HI 0 "register_operand" "=a")
782 (unspec:HI
783 [(compare:CCFP (match_operand 1 "register_operand" "f")
784 (match_operand 2 "const0_operand" "X"))]
785 UNSPEC_FNSTSW))]
786 "TARGET_80387
787 && FLOAT_MODE_P (GET_MODE (operands[1]))
788 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
789 {
790 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
791 return "ftst\;fnstsw\t%0\;fstp\t%y0";
792 else
793 return "ftst\;fnstsw\t%0";
794 }
795 [(set_attr "type" "multi")
796 (set (attr "mode")
797 (cond [(match_operand:SF 1 "" "")
798 (const_string "SF")
799 (match_operand:DF 1 "" "")
800 (const_string "DF")
801 ]
802 (const_string "XF")))])
803
804 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
805 ;; used to manage the reg stack popping would not be preserved.
806
807 (define_insn "*cmpfp_2_sf"
808 [(set (reg:CCFP 18)
809 (compare:CCFP
810 (match_operand:SF 0 "register_operand" "f")
811 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
812 "TARGET_80387"
813 "* return output_fp_compare (insn, operands, 0, 0);"
814 [(set_attr "type" "fcmp")
815 (set_attr "mode" "SF")])
816
817 (define_insn "*cmpfp_2_sf_1"
818 [(set (match_operand:HI 0 "register_operand" "=a")
819 (unspec:HI
820 [(compare:CCFP
821 (match_operand:SF 1 "register_operand" "f")
822 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
823 UNSPEC_FNSTSW))]
824 "TARGET_80387"
825 "* return output_fp_compare (insn, operands, 2, 0);"
826 [(set_attr "type" "fcmp")
827 (set_attr "mode" "SF")])
828
829 (define_insn "*cmpfp_2_df"
830 [(set (reg:CCFP 18)
831 (compare:CCFP
832 (match_operand:DF 0 "register_operand" "f")
833 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
834 "TARGET_80387"
835 "* return output_fp_compare (insn, operands, 0, 0);"
836 [(set_attr "type" "fcmp")
837 (set_attr "mode" "DF")])
838
839 (define_insn "*cmpfp_2_df_1"
840 [(set (match_operand:HI 0 "register_operand" "=a")
841 (unspec:HI
842 [(compare:CCFP
843 (match_operand:DF 1 "register_operand" "f")
844 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
845 UNSPEC_FNSTSW))]
846 "TARGET_80387"
847 "* return output_fp_compare (insn, operands, 2, 0);"
848 [(set_attr "type" "multi")
849 (set_attr "mode" "DF")])
850
851 (define_insn "*cmpfp_2_xf"
852 [(set (reg:CCFP 18)
853 (compare:CCFP
854 (match_operand:XF 0 "register_operand" "f")
855 (match_operand:XF 1 "register_operand" "f")))]
856 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
857 "* return output_fp_compare (insn, operands, 0, 0);"
858 [(set_attr "type" "fcmp")
859 (set_attr "mode" "XF")])
860
861 (define_insn "*cmpfp_2_tf"
862 [(set (reg:CCFP 18)
863 (compare:CCFP
864 (match_operand:TF 0 "register_operand" "f")
865 (match_operand:TF 1 "register_operand" "f")))]
866 "TARGET_80387"
867 "* return output_fp_compare (insn, operands, 0, 0);"
868 [(set_attr "type" "fcmp")
869 (set_attr "mode" "XF")])
870
871 (define_insn "*cmpfp_2_xf_1"
872 [(set (match_operand:HI 0 "register_operand" "=a")
873 (unspec:HI
874 [(compare:CCFP
875 (match_operand:XF 1 "register_operand" "f")
876 (match_operand:XF 2 "register_operand" "f"))]
877 UNSPEC_FNSTSW))]
878 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
879 "* return output_fp_compare (insn, operands, 2, 0);"
880 [(set_attr "type" "multi")
881 (set_attr "mode" "XF")])
882
883 (define_insn "*cmpfp_2_tf_1"
884 [(set (match_operand:HI 0 "register_operand" "=a")
885 (unspec:HI
886 [(compare:CCFP
887 (match_operand:TF 1 "register_operand" "f")
888 (match_operand:TF 2 "register_operand" "f"))]
889 UNSPEC_FNSTSW))]
890 "TARGET_80387"
891 "* return output_fp_compare (insn, operands, 2, 0);"
892 [(set_attr "type" "multi")
893 (set_attr "mode" "XF")])
894
895 (define_insn "*cmpfp_2u"
896 [(set (reg:CCFPU 18)
897 (compare:CCFPU
898 (match_operand 0 "register_operand" "f")
899 (match_operand 1 "register_operand" "f")))]
900 "TARGET_80387
901 && FLOAT_MODE_P (GET_MODE (operands[0]))
902 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
903 "* return output_fp_compare (insn, operands, 0, 1);"
904 [(set_attr "type" "fcmp")
905 (set (attr "mode")
906 (cond [(match_operand:SF 1 "" "")
907 (const_string "SF")
908 (match_operand:DF 1 "" "")
909 (const_string "DF")
910 ]
911 (const_string "XF")))])
912
913 (define_insn "*cmpfp_2u_1"
914 [(set (match_operand:HI 0 "register_operand" "=a")
915 (unspec:HI
916 [(compare:CCFPU
917 (match_operand 1 "register_operand" "f")
918 (match_operand 2 "register_operand" "f"))]
919 UNSPEC_FNSTSW))]
920 "TARGET_80387
921 && FLOAT_MODE_P (GET_MODE (operands[1]))
922 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
923 "* return output_fp_compare (insn, operands, 2, 1);"
924 [(set_attr "type" "multi")
925 (set (attr "mode")
926 (cond [(match_operand:SF 1 "" "")
927 (const_string "SF")
928 (match_operand:DF 1 "" "")
929 (const_string "DF")
930 ]
931 (const_string "XF")))])
932
933 ;; Patterns to match the SImode-in-memory ficom instructions.
934 ;;
935 ;; %%% Play games with accepting gp registers, as otherwise we have to
936 ;; force them to memory during rtl generation, which is no good. We
937 ;; can get rid of this once we teach reload to do memory input reloads
938 ;; via pushes.
939
940 (define_insn "*ficom_1"
941 [(set (reg:CCFP 18)
942 (compare:CCFP
943 (match_operand 0 "register_operand" "f,f")
944 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
945 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
946 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
947 "#")
948
949 ;; Split the not-really-implemented gp register case into a
950 ;; push-op-pop sequence.
951 ;;
952 ;; %%% This is most efficient, but am I gonna get in trouble
953 ;; for separating cc0_setter and cc0_user?
954
955 (define_split
956 [(set (reg:CCFP 18)
957 (compare:CCFP
958 (match_operand:SF 0 "register_operand" "")
959 (float (match_operand:SI 1 "register_operand" ""))))]
960 "0 && TARGET_80387 && reload_completed"
961 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
962 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
963 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
964 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
965 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
966 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
967
968 ;; FP compares, step 2
969 ;; Move the fpsw to ax.
970
971 (define_insn "*x86_fnstsw_1"
972 [(set (match_operand:HI 0 "register_operand" "=a")
973 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
974 "TARGET_80387"
975 "fnstsw\t%0"
976 [(set_attr "length" "2")
977 (set_attr "mode" "SI")
978 (set_attr "unit" "i387")
979 (set_attr "ppro_uops" "few")])
980
981 ;; FP compares, step 3
982 ;; Get ax into flags, general case.
983
984 (define_insn "x86_sahf_1"
985 [(set (reg:CC 17)
986 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
987 "!TARGET_64BIT"
988 "sahf"
989 [(set_attr "length" "1")
990 (set_attr "athlon_decode" "vector")
991 (set_attr "mode" "SI")
992 (set_attr "ppro_uops" "one")])
993
994 ;; Pentium Pro can do steps 1 through 3 in one go.
995
996 (define_insn "*cmpfp_i"
997 [(set (reg:CCFP 17)
998 (compare:CCFP (match_operand 0 "register_operand" "f")
999 (match_operand 1 "register_operand" "f")))]
1000 "TARGET_80387 && TARGET_CMOVE
1001 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002 && FLOAT_MODE_P (GET_MODE (operands[0]))
1003 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1004 "* return output_fp_compare (insn, operands, 1, 0);"
1005 [(set_attr "type" "fcmp")
1006 (set (attr "mode")
1007 (cond [(match_operand:SF 1 "" "")
1008 (const_string "SF")
1009 (match_operand:DF 1 "" "")
1010 (const_string "DF")
1011 ]
1012 (const_string "XF")))
1013 (set_attr "athlon_decode" "vector")])
1014
1015 (define_insn "*cmpfp_i_sse"
1016 [(set (reg:CCFP 17)
1017 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1018 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019 "TARGET_80387
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "fcmp,ssecomi")
1024 (set (attr "mode")
1025 (if_then_else (match_operand:SF 1 "" "")
1026 (const_string "SF")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")])
1029
1030 (define_insn "*cmpfp_i_sse_only"
1031 [(set (reg:CCFP 17)
1032 (compare:CCFP (match_operand 0 "register_operand" "x")
1033 (match_operand 1 "nonimmediate_operand" "xm")))]
1034 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1035 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1036 "* return output_fp_compare (insn, operands, 1, 0);"
1037 [(set_attr "type" "ssecomi")
1038 (set (attr "mode")
1039 (if_then_else (match_operand:SF 1 "" "")
1040 (const_string "SF")
1041 (const_string "DF")))
1042 (set_attr "athlon_decode" "vector")])
1043
1044 (define_insn "*cmpfp_iu"
1045 [(set (reg:CCFPU 17)
1046 (compare:CCFPU (match_operand 0 "register_operand" "f")
1047 (match_operand 1 "register_operand" "f")))]
1048 "TARGET_80387 && TARGET_CMOVE
1049 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1050 && FLOAT_MODE_P (GET_MODE (operands[0]))
1051 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052 "* return output_fp_compare (insn, operands, 1, 1);"
1053 [(set_attr "type" "fcmp")
1054 (set (attr "mode")
1055 (cond [(match_operand:SF 1 "" "")
1056 (const_string "SF")
1057 (match_operand:DF 1 "" "")
1058 (const_string "DF")
1059 ]
1060 (const_string "XF")))
1061 (set_attr "athlon_decode" "vector")])
1062
1063 (define_insn "*cmpfp_iu_sse"
1064 [(set (reg:CCFPU 17)
1065 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1066 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1067 "TARGET_80387
1068 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1069 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1070 "* return output_fp_compare (insn, operands, 1, 1);"
1071 [(set_attr "type" "fcmp,ssecomi")
1072 (set (attr "mode")
1073 (if_then_else (match_operand:SF 1 "" "")
1074 (const_string "SF")
1075 (const_string "DF")))
1076 (set_attr "athlon_decode" "vector")])
1077
1078 (define_insn "*cmpfp_iu_sse_only"
1079 [(set (reg:CCFPU 17)
1080 (compare:CCFPU (match_operand 0 "register_operand" "x")
1081 (match_operand 1 "nonimmediate_operand" "xm")))]
1082 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1083 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1084 "* return output_fp_compare (insn, operands, 1, 1);"
1085 [(set_attr "type" "ssecomi")
1086 (set (attr "mode")
1087 (if_then_else (match_operand:SF 1 "" "")
1088 (const_string "SF")
1089 (const_string "DF")))
1090 (set_attr "athlon_decode" "vector")])
1091 \f
1092 ;; Move instructions.
1093
1094 ;; General case of fullword move.
1095
1096 (define_expand "movsi"
1097 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1098 (match_operand:SI 1 "general_operand" ""))]
1099 ""
1100 "ix86_expand_move (SImode, operands); DONE;")
1101
1102 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1103 ;; general_operand.
1104 ;;
1105 ;; %%% We don't use a post-inc memory reference because x86 is not a
1106 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1107 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1108 ;; targets without our curiosities, and it is just as easy to represent
1109 ;; this differently.
1110
1111 (define_insn "*pushsi2"
1112 [(set (match_operand:SI 0 "push_operand" "=<")
1113 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1114 "!TARGET_64BIT"
1115 "push{l}\t%1"
1116 [(set_attr "type" "push")
1117 (set_attr "mode" "SI")])
1118
1119 ;; For 64BIT abi we always round up to 8 bytes.
1120 (define_insn "*pushsi2_rex64"
1121 [(set (match_operand:SI 0 "push_operand" "=X")
1122 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1123 "TARGET_64BIT"
1124 "push{q}\t%q1"
1125 [(set_attr "type" "push")
1126 (set_attr "mode" "SI")])
1127
1128 (define_insn "*pushsi2_prologue"
1129 [(set (match_operand:SI 0 "push_operand" "=<")
1130 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1131 (clobber (mem:BLK (scratch)))]
1132 "!TARGET_64BIT"
1133 "push{l}\t%1"
1134 [(set_attr "type" "push")
1135 (set_attr "mode" "SI")])
1136
1137 (define_insn "*popsi1_epilogue"
1138 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1139 (mem:SI (reg:SI 7)))
1140 (set (reg:SI 7)
1141 (plus:SI (reg:SI 7) (const_int 4)))
1142 (clobber (mem:BLK (scratch)))]
1143 "!TARGET_64BIT"
1144 "pop{l}\t%0"
1145 [(set_attr "type" "pop")
1146 (set_attr "mode" "SI")])
1147
1148 (define_insn "popsi1"
1149 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1150 (mem:SI (reg:SI 7)))
1151 (set (reg:SI 7)
1152 (plus:SI (reg:SI 7) (const_int 4)))]
1153 "!TARGET_64BIT"
1154 "pop{l}\t%0"
1155 [(set_attr "type" "pop")
1156 (set_attr "mode" "SI")])
1157
1158 (define_insn "*movsi_xor"
1159 [(set (match_operand:SI 0 "register_operand" "=r")
1160 (match_operand:SI 1 "const0_operand" "i"))
1161 (clobber (reg:CC 17))]
1162 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1163 "xor{l}\t{%0, %0|%0, %0}"
1164 [(set_attr "type" "alu1")
1165 (set_attr "mode" "SI")
1166 (set_attr "length_immediate" "0")])
1167
1168 (define_insn "*movsi_or"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (match_operand:SI 1 "immediate_operand" "i"))
1171 (clobber (reg:CC 17))]
1172 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1173 && INTVAL (operands[1]) == -1
1174 && (TARGET_PENTIUM || optimize_size)"
1175 {
1176 operands[1] = constm1_rtx;
1177 return "or{l}\t{%1, %0|%0, %1}";
1178 }
1179 [(set_attr "type" "alu1")
1180 (set_attr "mode" "SI")
1181 (set_attr "length_immediate" "1")])
1182
1183 (define_insn "*movsi_1"
1184 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1185 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1186 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1187 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1188 {
1189 switch (get_attr_type (insn))
1190 {
1191 case TYPE_SSEMOV:
1192 if (get_attr_mode (insn) == MODE_TI)
1193 return "movdqa\t{%1, %0|%0, %1}";
1194 return "movd\t{%1, %0|%0, %1}";
1195
1196 case TYPE_MMXMOV:
1197 if (get_attr_mode (insn) == MODE_DI)
1198 return "movq\t{%1, %0|%0, %1}";
1199 return "movd\t{%1, %0|%0, %1}";
1200
1201 case TYPE_LEA:
1202 return "lea{l}\t{%1, %0|%0, %1}";
1203
1204 default:
1205 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1206 abort();
1207 return "mov{l}\t{%1, %0|%0, %1}";
1208 }
1209 }
1210 [(set (attr "type")
1211 (cond [(eq_attr "alternative" "2,3,4")
1212 (const_string "mmxmov")
1213 (eq_attr "alternative" "5,6,7")
1214 (const_string "ssemov")
1215 (and (ne (symbol_ref "flag_pic") (const_int 0))
1216 (match_operand:SI 1 "symbolic_operand" ""))
1217 (const_string "lea")
1218 ]
1219 (const_string "imov")))
1220 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1221
1222 (define_insn "*movsi_1_nointernunit"
1223 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1224 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1225 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1226 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1227 {
1228 switch (get_attr_type (insn))
1229 {
1230 case TYPE_SSEMOV:
1231 if (get_attr_mode (insn) == MODE_TI)
1232 return "movdqa\t{%1, %0|%0, %1}";
1233 return "movd\t{%1, %0|%0, %1}";
1234
1235 case TYPE_MMXMOV:
1236 if (get_attr_mode (insn) == MODE_DI)
1237 return "movq\t{%1, %0|%0, %1}";
1238 return "movd\t{%1, %0|%0, %1}";
1239
1240 case TYPE_LEA:
1241 return "lea{l}\t{%1, %0|%0, %1}";
1242
1243 default:
1244 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1245 abort();
1246 return "mov{l}\t{%1, %0|%0, %1}";
1247 }
1248 }
1249 [(set (attr "type")
1250 (cond [(eq_attr "alternative" "2,3,4")
1251 (const_string "mmxmov")
1252 (eq_attr "alternative" "5,6,7")
1253 (const_string "ssemov")
1254 (and (ne (symbol_ref "flag_pic") (const_int 0))
1255 (match_operand:SI 1 "symbolic_operand" ""))
1256 (const_string "lea")
1257 ]
1258 (const_string "imov")))
1259 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1260
1261 ;; Stores and loads of ax to arbitrary constant address.
1262 ;; We fake an second form of instruction to force reload to load address
1263 ;; into register when rax is not available
1264 (define_insn "*movabssi_1_rex64"
1265 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1266 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1267 "TARGET_64BIT"
1268 "@
1269 movabs{l}\t{%1, %P0|%P0, %1}
1270 mov{l}\t{%1, %a0|%a0, %1}
1271 movabs{l}\t{%1, %a0|%a0, %1}"
1272 [(set_attr "type" "imov")
1273 (set_attr "modrm" "0,*,*")
1274 (set_attr "length_address" "8,0,0")
1275 (set_attr "length_immediate" "0,*,*")
1276 (set_attr "memory" "store")
1277 (set_attr "mode" "SI")])
1278
1279 (define_insn "*movabssi_2_rex64"
1280 [(set (match_operand:SI 0 "register_operand" "=a,r")
1281 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1282 "TARGET_64BIT"
1283 "@
1284 movabs{l}\t{%P1, %0|%0, %P1}
1285 mov{l}\t{%a1, %0|%0, %a1}"
1286 [(set_attr "type" "imov")
1287 (set_attr "modrm" "0,*")
1288 (set_attr "length_address" "8,0")
1289 (set_attr "length_immediate" "0")
1290 (set_attr "memory" "load")
1291 (set_attr "mode" "SI")])
1292
1293 (define_insn "*swapsi"
1294 [(set (match_operand:SI 0 "register_operand" "+r")
1295 (match_operand:SI 1 "register_operand" "+r"))
1296 (set (match_dup 1)
1297 (match_dup 0))]
1298 ""
1299 "xchg{l}\t%1, %0"
1300 [(set_attr "type" "imov")
1301 (set_attr "pent_pair" "np")
1302 (set_attr "athlon_decode" "vector")
1303 (set_attr "mode" "SI")
1304 (set_attr "modrm" "0")
1305 (set_attr "ppro_uops" "few")])
1306
1307 (define_expand "movhi"
1308 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1309 (match_operand:HI 1 "general_operand" ""))]
1310 ""
1311 "ix86_expand_move (HImode, operands); DONE;")
1312
1313 (define_insn "*pushhi2"
1314 [(set (match_operand:HI 0 "push_operand" "=<,<")
1315 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1316 "!TARGET_64BIT"
1317 "@
1318 push{w}\t{|WORD PTR }%1
1319 push{w}\t%1"
1320 [(set_attr "type" "push")
1321 (set_attr "mode" "HI")])
1322
1323 ;; For 64BIT abi we always round up to 8 bytes.
1324 (define_insn "*pushhi2_rex64"
1325 [(set (match_operand:HI 0 "push_operand" "=X")
1326 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1327 "TARGET_64BIT"
1328 "push{q}\t%q1"
1329 [(set_attr "type" "push")
1330 (set_attr "mode" "QI")])
1331
1332 (define_insn "*movhi_1"
1333 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1334 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1335 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1336 {
1337 switch (get_attr_type (insn))
1338 {
1339 case TYPE_IMOVX:
1340 /* movzwl is faster than movw on p2 due to partial word stalls,
1341 though not as fast as an aligned movl. */
1342 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1343 default:
1344 if (get_attr_mode (insn) == MODE_SI)
1345 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1346 else
1347 return "mov{w}\t{%1, %0|%0, %1}";
1348 }
1349 }
1350 [(set (attr "type")
1351 (cond [(and (eq_attr "alternative" "0")
1352 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1353 (const_int 0))
1354 (eq (symbol_ref "TARGET_HIMODE_MATH")
1355 (const_int 0))))
1356 (const_string "imov")
1357 (and (eq_attr "alternative" "1,2")
1358 (match_operand:HI 1 "aligned_operand" ""))
1359 (const_string "imov")
1360 (and (ne (symbol_ref "TARGET_MOVX")
1361 (const_int 0))
1362 (eq_attr "alternative" "0,2"))
1363 (const_string "imovx")
1364 ]
1365 (const_string "imov")))
1366 (set (attr "mode")
1367 (cond [(eq_attr "type" "imovx")
1368 (const_string "SI")
1369 (and (eq_attr "alternative" "1,2")
1370 (match_operand:HI 1 "aligned_operand" ""))
1371 (const_string "SI")
1372 (and (eq_attr "alternative" "0")
1373 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1374 (const_int 0))
1375 (eq (symbol_ref "TARGET_HIMODE_MATH")
1376 (const_int 0))))
1377 (const_string "SI")
1378 ]
1379 (const_string "HI")))])
1380
1381 ;; Stores and loads of ax to arbitrary constant address.
1382 ;; We fake an second form of instruction to force reload to load address
1383 ;; into register when rax is not available
1384 (define_insn "*movabshi_1_rex64"
1385 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1386 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1387 "TARGET_64BIT"
1388 "@
1389 movabs{w}\t{%1, %P0|%P0, %1}
1390 mov{w}\t{%1, %a0|%a0, %1}
1391 movabs{w}\t{%1, %a0|%a0, %1}"
1392 [(set_attr "type" "imov")
1393 (set_attr "modrm" "0,*,*")
1394 (set_attr "length_address" "8,0,0")
1395 (set_attr "length_immediate" "0,*,*")
1396 (set_attr "memory" "store")
1397 (set_attr "mode" "HI")])
1398
1399 (define_insn "*movabshi_2_rex64"
1400 [(set (match_operand:HI 0 "register_operand" "=a,r")
1401 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1402 "TARGET_64BIT"
1403 "@
1404 movabs{w}\t{%P1, %0|%0, %P1}
1405 mov{w}\t{%a1, %0|%0, %a1}"
1406 [(set_attr "type" "imov")
1407 (set_attr "modrm" "0,*")
1408 (set_attr "length_address" "8,0")
1409 (set_attr "length_immediate" "0")
1410 (set_attr "memory" "load")
1411 (set_attr "mode" "HI")])
1412
1413 (define_insn "*swaphi_1"
1414 [(set (match_operand:HI 0 "register_operand" "+r")
1415 (match_operand:HI 1 "register_operand" "+r"))
1416 (set (match_dup 1)
1417 (match_dup 0))]
1418 "TARGET_PARTIAL_REG_STALL"
1419 "xchg{w}\t%1, %0"
1420 [(set_attr "type" "imov")
1421 (set_attr "pent_pair" "np")
1422 (set_attr "mode" "HI")
1423 (set_attr "modrm" "0")
1424 (set_attr "ppro_uops" "few")])
1425
1426 (define_insn "*swaphi_2"
1427 [(set (match_operand:HI 0 "register_operand" "+r")
1428 (match_operand:HI 1 "register_operand" "+r"))
1429 (set (match_dup 1)
1430 (match_dup 0))]
1431 "! TARGET_PARTIAL_REG_STALL"
1432 "xchg{l}\t%k1, %k0"
1433 [(set_attr "type" "imov")
1434 (set_attr "pent_pair" "np")
1435 (set_attr "mode" "SI")
1436 (set_attr "modrm" "0")
1437 (set_attr "ppro_uops" "few")])
1438
1439 (define_expand "movstricthi"
1440 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1441 (match_operand:HI 1 "general_operand" ""))]
1442 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1443 {
1444 /* Don't generate memory->memory moves, go through a register */
1445 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1446 operands[1] = force_reg (HImode, operands[1]);
1447 })
1448
1449 (define_insn "*movstricthi_1"
1450 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1451 (match_operand:HI 1 "general_operand" "rn,m"))]
1452 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1453 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1454 "mov{w}\t{%1, %0|%0, %1}"
1455 [(set_attr "type" "imov")
1456 (set_attr "mode" "HI")])
1457
1458 (define_insn "*movstricthi_xor"
1459 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1460 (match_operand:HI 1 "const0_operand" "i"))
1461 (clobber (reg:CC 17))]
1462 "reload_completed
1463 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1464 "xor{w}\t{%0, %0|%0, %0}"
1465 [(set_attr "type" "alu1")
1466 (set_attr "mode" "HI")
1467 (set_attr "length_immediate" "0")])
1468
1469 (define_expand "movqi"
1470 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1471 (match_operand:QI 1 "general_operand" ""))]
1472 ""
1473 "ix86_expand_move (QImode, operands); DONE;")
1474
1475 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1476 ;; "push a byte". But actually we use pushw, which has the effect
1477 ;; of rounding the amount pushed up to a halfword.
1478
1479 (define_insn "*pushqi2"
1480 [(set (match_operand:QI 0 "push_operand" "=X,X")
1481 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1482 "!TARGET_64BIT"
1483 "@
1484 push{w}\t{|word ptr }%1
1485 push{w}\t%w1"
1486 [(set_attr "type" "push")
1487 (set_attr "mode" "HI")])
1488
1489 ;; For 64BIT abi we always round up to 8 bytes.
1490 (define_insn "*pushqi2_rex64"
1491 [(set (match_operand:QI 0 "push_operand" "=X")
1492 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1493 "TARGET_64BIT"
1494 "push{q}\t%q1"
1495 [(set_attr "type" "push")
1496 (set_attr "mode" "QI")])
1497
1498 ;; Situation is quite tricky about when to choose full sized (SImode) move
1499 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1500 ;; partial register dependency machines (such as AMD Athlon), where QImode
1501 ;; moves issue extra dependency and for partial register stalls machines
1502 ;; that don't use QImode patterns (and QImode move cause stall on the next
1503 ;; instruction).
1504 ;;
1505 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1506 ;; register stall machines with, where we use QImode instructions, since
1507 ;; partial register stall can be caused there. Then we use movzx.
1508 (define_insn "*movqi_1"
1509 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1510 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1511 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1512 {
1513 switch (get_attr_type (insn))
1514 {
1515 case TYPE_IMOVX:
1516 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1517 abort ();
1518 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1519 default:
1520 if (get_attr_mode (insn) == MODE_SI)
1521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1522 else
1523 return "mov{b}\t{%1, %0|%0, %1}";
1524 }
1525 }
1526 [(set (attr "type")
1527 (cond [(and (eq_attr "alternative" "3")
1528 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1529 (const_int 0))
1530 (eq (symbol_ref "TARGET_QIMODE_MATH")
1531 (const_int 0))))
1532 (const_string "imov")
1533 (eq_attr "alternative" "3,5")
1534 (const_string "imovx")
1535 (and (ne (symbol_ref "TARGET_MOVX")
1536 (const_int 0))
1537 (eq_attr "alternative" "2"))
1538 (const_string "imovx")
1539 ]
1540 (const_string "imov")))
1541 (set (attr "mode")
1542 (cond [(eq_attr "alternative" "3,4,5")
1543 (const_string "SI")
1544 (eq_attr "alternative" "6")
1545 (const_string "QI")
1546 (eq_attr "type" "imovx")
1547 (const_string "SI")
1548 (and (eq_attr "type" "imov")
1549 (and (eq_attr "alternative" "0,1,2")
1550 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1551 (const_int 0))))
1552 (const_string "SI")
1553 ;; Avoid partial register stalls when not using QImode arithmetic
1554 (and (eq_attr "type" "imov")
1555 (and (eq_attr "alternative" "0,1,2")
1556 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1557 (const_int 0))
1558 (eq (symbol_ref "TARGET_QIMODE_MATH")
1559 (const_int 0)))))
1560 (const_string "SI")
1561 ]
1562 (const_string "QI")))])
1563
1564 (define_expand "reload_outqi"
1565 [(parallel [(match_operand:QI 0 "" "=m")
1566 (match_operand:QI 1 "register_operand" "r")
1567 (match_operand:QI 2 "register_operand" "=&q")])]
1568 ""
1569 {
1570 rtx op0, op1, op2;
1571 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1572
1573 if (reg_overlap_mentioned_p (op2, op0))
1574 abort ();
1575 if (! q_regs_operand (op1, QImode))
1576 {
1577 emit_insn (gen_movqi (op2, op1));
1578 op1 = op2;
1579 }
1580 emit_insn (gen_movqi (op0, op1));
1581 DONE;
1582 })
1583
1584 (define_insn "*swapqi"
1585 [(set (match_operand:QI 0 "register_operand" "+r")
1586 (match_operand:QI 1 "register_operand" "+r"))
1587 (set (match_dup 1)
1588 (match_dup 0))]
1589 ""
1590 "xchg{b}\t%1, %0"
1591 [(set_attr "type" "imov")
1592 (set_attr "pent_pair" "np")
1593 (set_attr "mode" "QI")
1594 (set_attr "modrm" "0")
1595 (set_attr "ppro_uops" "few")])
1596
1597 (define_expand "movstrictqi"
1598 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1599 (match_operand:QI 1 "general_operand" ""))]
1600 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1601 {
1602 /* Don't generate memory->memory moves, go through a register. */
1603 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1604 operands[1] = force_reg (QImode, operands[1]);
1605 })
1606
1607 (define_insn "*movstrictqi_1"
1608 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1609 (match_operand:QI 1 "general_operand" "*qn,m"))]
1610 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1611 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1612 "mov{b}\t{%1, %0|%0, %1}"
1613 [(set_attr "type" "imov")
1614 (set_attr "mode" "QI")])
1615
1616 (define_insn "*movstrictqi_xor"
1617 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1618 (match_operand:QI 1 "const0_operand" "i"))
1619 (clobber (reg:CC 17))]
1620 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1621 "xor{b}\t{%0, %0|%0, %0}"
1622 [(set_attr "type" "alu1")
1623 (set_attr "mode" "QI")
1624 (set_attr "length_immediate" "0")])
1625
1626 (define_insn "*movsi_extv_1"
1627 [(set (match_operand:SI 0 "register_operand" "=R")
1628 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1629 (const_int 8)
1630 (const_int 8)))]
1631 ""
1632 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1633 [(set_attr "type" "imovx")
1634 (set_attr "mode" "SI")])
1635
1636 (define_insn "*movhi_extv_1"
1637 [(set (match_operand:HI 0 "register_operand" "=R")
1638 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1639 (const_int 8)
1640 (const_int 8)))]
1641 ""
1642 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1643 [(set_attr "type" "imovx")
1644 (set_attr "mode" "SI")])
1645
1646 (define_insn "*movqi_extv_1"
1647 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1648 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1649 (const_int 8)
1650 (const_int 8)))]
1651 "!TARGET_64BIT"
1652 {
1653 switch (get_attr_type (insn))
1654 {
1655 case TYPE_IMOVX:
1656 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1657 default:
1658 return "mov{b}\t{%h1, %0|%0, %h1}";
1659 }
1660 }
1661 [(set (attr "type")
1662 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1663 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1664 (ne (symbol_ref "TARGET_MOVX")
1665 (const_int 0))))
1666 (const_string "imovx")
1667 (const_string "imov")))
1668 (set (attr "mode")
1669 (if_then_else (eq_attr "type" "imovx")
1670 (const_string "SI")
1671 (const_string "QI")))])
1672
1673 (define_insn "*movqi_extv_1_rex64"
1674 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1675 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1676 (const_int 8)
1677 (const_int 8)))]
1678 "TARGET_64BIT"
1679 {
1680 switch (get_attr_type (insn))
1681 {
1682 case TYPE_IMOVX:
1683 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1684 default:
1685 return "mov{b}\t{%h1, %0|%0, %h1}";
1686 }
1687 }
1688 [(set (attr "type")
1689 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1690 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1691 (ne (symbol_ref "TARGET_MOVX")
1692 (const_int 0))))
1693 (const_string "imovx")
1694 (const_string "imov")))
1695 (set (attr "mode")
1696 (if_then_else (eq_attr "type" "imovx")
1697 (const_string "SI")
1698 (const_string "QI")))])
1699
1700 ;; Stores and loads of ax to arbitrary constant address.
1701 ;; We fake an second form of instruction to force reload to load address
1702 ;; into register when rax is not available
1703 (define_insn "*movabsqi_1_rex64"
1704 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1705 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1706 "TARGET_64BIT"
1707 "@
1708 movabs{b}\t{%1, %P0|%P0, %1}
1709 mov{b}\t{%1, %a0|%a0, %1}
1710 movabs{b}\t{%1, %a0|%a0, %1}"
1711 [(set_attr "type" "imov")
1712 (set_attr "modrm" "0,*,*")
1713 (set_attr "length_address" "8,0,0")
1714 (set_attr "length_immediate" "0,*,*")
1715 (set_attr "memory" "store")
1716 (set_attr "mode" "QI")])
1717
1718 (define_insn "*movabsqi_2_rex64"
1719 [(set (match_operand:QI 0 "register_operand" "=a,r")
1720 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1721 "TARGET_64BIT"
1722 "@
1723 movabs{b}\t{%P1, %0|%0, %P1}
1724 mov{b}\t{%a1, %0|%0, %a1}"
1725 [(set_attr "type" "imov")
1726 (set_attr "modrm" "0,*")
1727 (set_attr "length_address" "8,0")
1728 (set_attr "length_immediate" "0")
1729 (set_attr "memory" "load")
1730 (set_attr "mode" "QI")])
1731
1732 (define_insn "*movsi_extzv_1"
1733 [(set (match_operand:SI 0 "register_operand" "=R")
1734 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1735 (const_int 8)
1736 (const_int 8)))]
1737 ""
1738 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1739 [(set_attr "type" "imovx")
1740 (set_attr "mode" "SI")])
1741
1742 (define_insn "*movqi_extzv_2"
1743 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1744 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1745 (const_int 8)
1746 (const_int 8)) 0))]
1747 "!TARGET_64BIT"
1748 {
1749 switch (get_attr_type (insn))
1750 {
1751 case TYPE_IMOVX:
1752 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1753 default:
1754 return "mov{b}\t{%h1, %0|%0, %h1}";
1755 }
1756 }
1757 [(set (attr "type")
1758 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1759 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1760 (ne (symbol_ref "TARGET_MOVX")
1761 (const_int 0))))
1762 (const_string "imovx")
1763 (const_string "imov")))
1764 (set (attr "mode")
1765 (if_then_else (eq_attr "type" "imovx")
1766 (const_string "SI")
1767 (const_string "QI")))])
1768
1769 (define_insn "*movqi_extzv_2_rex64"
1770 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1771 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1772 (const_int 8)
1773 (const_int 8)) 0))]
1774 "TARGET_64BIT"
1775 {
1776 switch (get_attr_type (insn))
1777 {
1778 case TYPE_IMOVX:
1779 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1780 default:
1781 return "mov{b}\t{%h1, %0|%0, %h1}";
1782 }
1783 }
1784 [(set (attr "type")
1785 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1786 (ne (symbol_ref "TARGET_MOVX")
1787 (const_int 0)))
1788 (const_string "imovx")
1789 (const_string "imov")))
1790 (set (attr "mode")
1791 (if_then_else (eq_attr "type" "imovx")
1792 (const_string "SI")
1793 (const_string "QI")))])
1794
1795 (define_insn "movsi_insv_1"
1796 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1797 (const_int 8)
1798 (const_int 8))
1799 (match_operand:SI 1 "general_operand" "Qmn"))]
1800 "!TARGET_64BIT"
1801 "mov{b}\t{%b1, %h0|%h0, %b1}"
1802 [(set_attr "type" "imov")
1803 (set_attr "mode" "QI")])
1804
1805 (define_insn "*movsi_insv_1_rex64"
1806 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1807 (const_int 8)
1808 (const_int 8))
1809 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1810 "TARGET_64BIT"
1811 "mov{b}\t{%b1, %h0|%h0, %b1}"
1812 [(set_attr "type" "imov")
1813 (set_attr "mode" "QI")])
1814
1815 (define_insn "*movqi_insv_2"
1816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1817 (const_int 8)
1818 (const_int 8))
1819 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1820 (const_int 8))
1821 (const_int 255)))]
1822 ""
1823 "mov{b}\t{%h1, %h0|%h0, %h1}"
1824 [(set_attr "type" "imov")
1825 (set_attr "mode" "QI")])
1826
1827 (define_expand "movdi"
1828 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1829 (match_operand:DI 1 "general_operand" ""))]
1830 ""
1831 "ix86_expand_move (DImode, operands); DONE;")
1832
1833 (define_insn "*pushdi"
1834 [(set (match_operand:DI 0 "push_operand" "=<")
1835 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1836 "!TARGET_64BIT"
1837 "#")
1838
1839 (define_insn "pushdi2_rex64"
1840 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1841 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1842 "TARGET_64BIT"
1843 "@
1844 push{q}\t%1
1845 #"
1846 [(set_attr "type" "push,multi")
1847 (set_attr "mode" "DI")])
1848
1849 ;; Convert impossible pushes of immediate to existing instructions.
1850 ;; First try to get scratch register and go through it. In case this
1851 ;; fails, push sign extended lower part first and then overwrite
1852 ;; upper part by 32bit move.
1853 (define_peephole2
1854 [(match_scratch:DI 2 "r")
1855 (set (match_operand:DI 0 "push_operand" "")
1856 (match_operand:DI 1 "immediate_operand" ""))]
1857 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1858 && !x86_64_immediate_operand (operands[1], DImode)"
1859 [(set (match_dup 2) (match_dup 1))
1860 (set (match_dup 0) (match_dup 2))]
1861 "")
1862
1863 ;; We need to define this as both peepholer and splitter for case
1864 ;; peephole2 pass is not run.
1865 (define_peephole2
1866 [(set (match_operand:DI 0 "push_operand" "")
1867 (match_operand:DI 1 "immediate_operand" ""))]
1868 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1869 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1870 [(set (match_dup 0) (match_dup 1))
1871 (set (match_dup 2) (match_dup 3))]
1872 "split_di (operands + 1, 1, operands + 2, operands + 3);
1873 operands[1] = gen_lowpart (DImode, operands[2]);
1874 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1875 GEN_INT (4)));
1876 ")
1877
1878 (define_split
1879 [(set (match_operand:DI 0 "push_operand" "")
1880 (match_operand:DI 1 "immediate_operand" ""))]
1881 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1882 && !symbolic_operand (operands[1], DImode)
1883 && !x86_64_immediate_operand (operands[1], DImode)"
1884 [(set (match_dup 0) (match_dup 1))
1885 (set (match_dup 2) (match_dup 3))]
1886 "split_di (operands + 1, 1, operands + 2, operands + 3);
1887 operands[1] = gen_lowpart (DImode, operands[2]);
1888 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889 GEN_INT (4)));
1890 ")
1891
1892 (define_insn "*pushdi2_prologue_rex64"
1893 [(set (match_operand:DI 0 "push_operand" "=<")
1894 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1895 (clobber (mem:BLK (scratch)))]
1896 "TARGET_64BIT"
1897 "push{q}\t%1"
1898 [(set_attr "type" "push")
1899 (set_attr "mode" "DI")])
1900
1901 (define_insn "*popdi1_epilogue_rex64"
1902 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903 (mem:DI (reg:DI 7)))
1904 (set (reg:DI 7)
1905 (plus:DI (reg:DI 7) (const_int 8)))
1906 (clobber (mem:BLK (scratch)))]
1907 "TARGET_64BIT"
1908 "pop{q}\t%0"
1909 [(set_attr "type" "pop")
1910 (set_attr "mode" "DI")])
1911
1912 (define_insn "popdi1"
1913 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1914 (mem:DI (reg:DI 7)))
1915 (set (reg:DI 7)
1916 (plus:DI (reg:DI 7) (const_int 8)))]
1917 "TARGET_64BIT"
1918 "pop{q}\t%0"
1919 [(set_attr "type" "pop")
1920 (set_attr "mode" "DI")])
1921
1922 (define_insn "*movdi_xor_rex64"
1923 [(set (match_operand:DI 0 "register_operand" "=r")
1924 (match_operand:DI 1 "const0_operand" "i"))
1925 (clobber (reg:CC 17))]
1926 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1927 && reload_completed"
1928 "xor{l}\t{%k0, %k0|%k0, %k0}"
1929 [(set_attr "type" "alu1")
1930 (set_attr "mode" "SI")
1931 (set_attr "length_immediate" "0")])
1932
1933 (define_insn "*movdi_or_rex64"
1934 [(set (match_operand:DI 0 "register_operand" "=r")
1935 (match_operand:DI 1 "const_int_operand" "i"))
1936 (clobber (reg:CC 17))]
1937 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1938 && reload_completed
1939 && GET_CODE (operands[1]) == CONST_INT
1940 && INTVAL (operands[1]) == -1"
1941 {
1942 operands[1] = constm1_rtx;
1943 return "or{q}\t{%1, %0|%0, %1}";
1944 }
1945 [(set_attr "type" "alu1")
1946 (set_attr "mode" "DI")
1947 (set_attr "length_immediate" "1")])
1948
1949 (define_insn "*movdi_2"
1950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1951 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1952 "!TARGET_64BIT
1953 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1954 "@
1955 #
1956 #
1957 movq\t{%1, %0|%0, %1}
1958 movq\t{%1, %0|%0, %1}
1959 movq\t{%1, %0|%0, %1}
1960 movdqa\t{%1, %0|%0, %1}
1961 movq\t{%1, %0|%0, %1}"
1962 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1963 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1964
1965 (define_split
1966 [(set (match_operand:DI 0 "push_operand" "")
1967 (match_operand:DI 1 "general_operand" ""))]
1968 "!TARGET_64BIT && reload_completed
1969 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1970 [(const_int 0)]
1971 "ix86_split_long_move (operands); DONE;")
1972
1973 ;; %%% This multiword shite has got to go.
1974 (define_split
1975 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1976 (match_operand:DI 1 "general_operand" ""))]
1977 "!TARGET_64BIT && reload_completed
1978 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1979 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1980 [(const_int 0)]
1981 "ix86_split_long_move (operands); DONE;")
1982
1983 (define_insn "*movdi_1_rex64"
1984 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1985 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1986 "TARGET_64BIT
1987 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1988 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1989 {
1990 switch (get_attr_type (insn))
1991 {
1992 case TYPE_SSEMOV:
1993 if (get_attr_mode (insn) == MODE_TI)
1994 return "movdqa\t{%1, %0|%0, %1}";
1995 /* FALLTHRU */
1996 case TYPE_MMXMOV:
1997 /* Moves from and into integer register is done using movd opcode with
1998 REX prefix. */
1999 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000 return "movd\t{%1, %0|%0, %1}";
2001 return "movq\t{%1, %0|%0, %1}";
2002 case TYPE_MULTI:
2003 return "#";
2004 case TYPE_LEA:
2005 return "lea{q}\t{%a1, %0|%0, %a1}";
2006 default:
2007 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2008 abort ();
2009 if (get_attr_mode (insn) == MODE_SI)
2010 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011 else if (which_alternative == 2)
2012 return "movabs{q}\t{%1, %0|%0, %1}";
2013 else
2014 return "mov{q}\t{%1, %0|%0, %1}";
2015 }
2016 }
2017 [(set (attr "type")
2018 (cond [(eq_attr "alternative" "5,6,7")
2019 (const_string "mmxmov")
2020 (eq_attr "alternative" "8,9,10")
2021 (const_string "ssemov")
2022 (eq_attr "alternative" "4")
2023 (const_string "multi")
2024 (and (ne (symbol_ref "flag_pic") (const_int 0))
2025 (match_operand:DI 1 "symbolic_operand" ""))
2026 (const_string "lea")
2027 ]
2028 (const_string "imov")))
2029 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2030 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2031 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2032
2033 (define_insn "*movdi_1_rex64_nointerunit"
2034 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2035 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2036 "TARGET_64BIT
2037 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2038 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2039 {
2040 switch (get_attr_type (insn))
2041 {
2042 case TYPE_SSEMOV:
2043 if (get_attr_mode (insn) == MODE_TI)
2044 return "movdqa\t{%1, %0|%0, %1}";
2045 /* FALLTHRU */
2046 case TYPE_MMXMOV:
2047 return "movq\t{%1, %0|%0, %1}";
2048 case TYPE_MULTI:
2049 return "#";
2050 case TYPE_LEA:
2051 return "lea{q}\t{%a1, %0|%0, %a1}";
2052 default:
2053 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2054 abort ();
2055 if (get_attr_mode (insn) == MODE_SI)
2056 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2057 else if (which_alternative == 2)
2058 return "movabs{q}\t{%1, %0|%0, %1}";
2059 else
2060 return "mov{q}\t{%1, %0|%0, %1}";
2061 }
2062 }
2063 [(set (attr "type")
2064 (cond [(eq_attr "alternative" "5,6,7")
2065 (const_string "mmxmov")
2066 (eq_attr "alternative" "8,9,10")
2067 (const_string "ssemov")
2068 (eq_attr "alternative" "4")
2069 (const_string "multi")
2070 (and (ne (symbol_ref "flag_pic") (const_int 0))
2071 (match_operand:DI 1 "symbolic_operand" ""))
2072 (const_string "lea")
2073 ]
2074 (const_string "imov")))
2075 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2076 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2077 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2078
2079 ;; Stores and loads of ax to arbitrary constant address.
2080 ;; We fake an second form of instruction to force reload to load address
2081 ;; into register when rax is not available
2082 (define_insn "*movabsdi_1_rex64"
2083 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2084 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2085 "TARGET_64BIT"
2086 "@
2087 movabs{q}\t{%1, %P0|%P0, %1}
2088 mov{q}\t{%1, %a0|%a0, %1}
2089 movabs{q}\t{%1, %a0|%a0, %1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "modrm" "0,*,*")
2092 (set_attr "length_address" "8,0,0")
2093 (set_attr "length_immediate" "0,*,*")
2094 (set_attr "memory" "store")
2095 (set_attr "mode" "DI")])
2096
2097 (define_insn "*movabsdi_2_rex64"
2098 [(set (match_operand:DI 0 "register_operand" "=a,r")
2099 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2100 "TARGET_64BIT"
2101 "@
2102 movabs{q}\t{%P1, %0|%0, %P1}
2103 mov{q}\t{%a1, %0|%0, %a1}"
2104 [(set_attr "type" "imov")
2105 (set_attr "modrm" "0,*")
2106 (set_attr "length_address" "8,0")
2107 (set_attr "length_immediate" "0")
2108 (set_attr "memory" "load")
2109 (set_attr "mode" "DI")])
2110
2111 ;; Convert impossible stores of immediate to existing instructions.
2112 ;; First try to get scratch register and go through it. In case this
2113 ;; fails, move by 32bit parts.
2114 (define_peephole2
2115 [(match_scratch:DI 2 "r")
2116 (set (match_operand:DI 0 "memory_operand" "")
2117 (match_operand:DI 1 "immediate_operand" ""))]
2118 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2119 && !x86_64_immediate_operand (operands[1], DImode)"
2120 [(set (match_dup 2) (match_dup 1))
2121 (set (match_dup 0) (match_dup 2))]
2122 "")
2123
2124 ;; We need to define this as both peepholer and splitter for case
2125 ;; peephole2 pass is not run.
2126 (define_peephole2
2127 [(set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2131 [(set (match_dup 2) (match_dup 3))
2132 (set (match_dup 4) (match_dup 5))]
2133 "split_di (operands, 2, operands + 2, operands + 4);")
2134
2135 (define_split
2136 [(set (match_operand:DI 0 "memory_operand" "")
2137 (match_operand:DI 1 "immediate_operand" ""))]
2138 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2139 && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 3))
2142 (set (match_dup 4) (match_dup 5))]
2143 "split_di (operands, 2, operands + 2, operands + 4);")
2144
2145 (define_insn "*swapdi_rex64"
2146 [(set (match_operand:DI 0 "register_operand" "+r")
2147 (match_operand:DI 1 "register_operand" "+r"))
2148 (set (match_dup 1)
2149 (match_dup 0))]
2150 "TARGET_64BIT"
2151 "xchg{q}\t%1, %0"
2152 [(set_attr "type" "imov")
2153 (set_attr "pent_pair" "np")
2154 (set_attr "athlon_decode" "vector")
2155 (set_attr "mode" "DI")
2156 (set_attr "modrm" "0")
2157 (set_attr "ppro_uops" "few")])
2158
2159
2160 (define_expand "movsf"
2161 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2162 (match_operand:SF 1 "general_operand" ""))]
2163 ""
2164 "ix86_expand_move (SFmode, operands); DONE;")
2165
2166 (define_insn "*pushsf"
2167 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2168 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2169 "!TARGET_64BIT"
2170 {
2171 switch (which_alternative)
2172 {
2173 case 1:
2174 return "push{l}\t%1";
2175
2176 default:
2177 /* This insn should be already splitted before reg-stack. */
2178 abort ();
2179 }
2180 }
2181 [(set_attr "type" "multi,push,multi")
2182 (set_attr "mode" "SF,SI,SF")])
2183
2184 (define_insn "*pushsf_rex64"
2185 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2186 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2187 "TARGET_64BIT"
2188 {
2189 switch (which_alternative)
2190 {
2191 case 1:
2192 return "push{q}\t%q1";
2193
2194 default:
2195 /* This insn should be already splitted before reg-stack. */
2196 abort ();
2197 }
2198 }
2199 [(set_attr "type" "multi,push,multi")
2200 (set_attr "mode" "SF,DI,SF")])
2201
2202 (define_split
2203 [(set (match_operand:SF 0 "push_operand" "")
2204 (match_operand:SF 1 "memory_operand" ""))]
2205 "reload_completed
2206 && GET_CODE (operands[1]) == MEM
2207 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2208 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2209 [(set (match_dup 0)
2210 (match_dup 1))]
2211 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2212
2213
2214 ;; %%% Kill this when call knows how to work this out.
2215 (define_split
2216 [(set (match_operand:SF 0 "push_operand" "")
2217 (match_operand:SF 1 "any_fp_register_operand" ""))]
2218 "!TARGET_64BIT"
2219 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2220 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2221
2222 (define_split
2223 [(set (match_operand:SF 0 "push_operand" "")
2224 (match_operand:SF 1 "any_fp_register_operand" ""))]
2225 "TARGET_64BIT"
2226 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2227 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2228
2229 (define_insn "*movsf_1"
2230 [(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")
2231 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2232 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2233 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2234 && (reload_in_progress || reload_completed
2235 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2236 || GET_CODE (operands[1]) != CONST_DOUBLE
2237 || memory_operand (operands[0], SFmode))"
2238 {
2239 switch (which_alternative)
2240 {
2241 case 0:
2242 if (REG_P (operands[1])
2243 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2244 return "fstp\t%y0";
2245 else if (STACK_TOP_P (operands[0]))
2246 return "fld%z1\t%y1";
2247 else
2248 return "fst\t%y0";
2249
2250 case 1:
2251 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2252 return "fstp%z0\t%y0";
2253 else
2254 return "fst%z0\t%y0";
2255
2256 case 2:
2257 return standard_80387_constant_opcode (operands[1]);
2258
2259 case 3:
2260 case 4:
2261 return "mov{l}\t{%1, %0|%0, %1}";
2262 case 5:
2263 if (get_attr_mode (insn) == MODE_TI)
2264 return "pxor\t%0, %0";
2265 else
2266 return "xorps\t%0, %0";
2267 case 6:
2268 if (get_attr_mode (insn) == MODE_V4SF)
2269 return "movaps\t{%1, %0|%0, %1}";
2270 else
2271 return "movss\t{%1, %0|%0, %1}";
2272 case 7:
2273 case 8:
2274 return "movss\t{%1, %0|%0, %1}";
2275
2276 case 9:
2277 case 10:
2278 return "movd\t{%1, %0|%0, %1}";
2279
2280 case 11:
2281 return "movq\t{%1, %0|%0, %1}";
2282
2283 default:
2284 abort();
2285 }
2286 }
2287 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2288 (set (attr "mode")
2289 (cond [(eq_attr "alternative" "3,4,9,10")
2290 (const_string "SI")
2291 (eq_attr "alternative" "5")
2292 (if_then_else
2293 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2294 (const_int 0))
2295 (ne (symbol_ref "TARGET_SSE2")
2296 (const_int 0)))
2297 (eq (symbol_ref "optimize_size")
2298 (const_int 0)))
2299 (const_string "TI")
2300 (const_string "V4SF"))
2301 /* For architectures resolving dependencies on
2302 whole SSE registers use APS move to break dependency
2303 chains, otherwise use short move to avoid extra work.
2304
2305 Do the same for architectures resolving dependencies on
2306 the parts. While in DF mode it is better to always handle
2307 just register parts, the SF mode is different due to lack
2308 of instructions to load just part of the register. It is
2309 better to maintain the whole registers in single format
2310 to avoid problems on using packed logical operations. */
2311 (eq_attr "alternative" "6")
2312 (if_then_else
2313 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2314 (const_int 0))
2315 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2316 (const_int 0)))
2317 (const_string "V4SF")
2318 (const_string "SF"))
2319 (eq_attr "alternative" "11")
2320 (const_string "DI")]
2321 (const_string "SF")))])
2322
2323 (define_insn "*movsf_1_nointerunit"
2324 [(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")
2325 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2326 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2327 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2328 && (reload_in_progress || reload_completed
2329 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2330 || GET_CODE (operands[1]) != CONST_DOUBLE
2331 || memory_operand (operands[0], SFmode))"
2332 {
2333 switch (which_alternative)
2334 {
2335 case 0:
2336 if (REG_P (operands[1])
2337 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2338 {
2339 if (REGNO (operands[0]) == FIRST_STACK_REG
2340 && TARGET_USE_FFREEP)
2341 return "ffreep\t%y0";
2342 return "fstp\t%y0";
2343 }
2344 else if (STACK_TOP_P (operands[0]))
2345 return "fld%z1\t%y1";
2346 else
2347 return "fst\t%y0";
2348
2349 case 1:
2350 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2351 return "fstp%z0\t%y0";
2352 else
2353 return "fst%z0\t%y0";
2354
2355 case 2:
2356 return standard_80387_constant_opcode (operands[1]);
2357
2358 case 3:
2359 case 4:
2360 return "mov{l}\t{%1, %0|%0, %1}";
2361 case 5:
2362 if (get_attr_mode (insn) == MODE_TI)
2363 return "pxor\t%0, %0";
2364 else
2365 return "xorps\t%0, %0";
2366 case 6:
2367 if (get_attr_mode (insn) == MODE_V4SF)
2368 return "movaps\t{%1, %0|%0, %1}";
2369 else
2370 return "movss\t{%1, %0|%0, %1}";
2371 case 7:
2372 case 8:
2373 return "movss\t{%1, %0|%0, %1}";
2374
2375 case 9:
2376 case 10:
2377 return "movd\t{%1, %0|%0, %1}";
2378
2379 case 11:
2380 return "movq\t{%1, %0|%0, %1}";
2381
2382 default:
2383 abort();
2384 }
2385 }
2386 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2387 (set (attr "mode")
2388 (cond [(eq_attr "alternative" "3,4,9,10")
2389 (const_string "SI")
2390 (eq_attr "alternative" "5")
2391 (if_then_else
2392 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2393 (const_int 0))
2394 (ne (symbol_ref "TARGET_SSE2")
2395 (const_int 0)))
2396 (eq (symbol_ref "optimize_size")
2397 (const_int 0)))
2398 (const_string "TI")
2399 (const_string "V4SF"))
2400 /* For architectures resolving dependencies on
2401 whole SSE registers use APS move to break dependency
2402 chains, otherwise use short move to avoid extra work.
2403
2404 Do the same for architectures resolving dependencies on
2405 the parts. While in DF mode it is better to always handle
2406 just register parts, the SF mode is different due to lack
2407 of instructions to load just part of the register. It is
2408 better to maintain the whole registers in single format
2409 to avoid problems on using packed logical operations. */
2410 (eq_attr "alternative" "6")
2411 (if_then_else
2412 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2413 (const_int 0))
2414 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2415 (const_int 0)))
2416 (const_string "V4SF")
2417 (const_string "SF"))
2418 (eq_attr "alternative" "11")
2419 (const_string "DI")]
2420 (const_string "SF")))])
2421
2422 (define_insn "*swapsf"
2423 [(set (match_operand:SF 0 "register_operand" "+f")
2424 (match_operand:SF 1 "register_operand" "+f"))
2425 (set (match_dup 1)
2426 (match_dup 0))]
2427 "reload_completed || !TARGET_SSE"
2428 {
2429 if (STACK_TOP_P (operands[0]))
2430 return "fxch\t%1";
2431 else
2432 return "fxch\t%0";
2433 }
2434 [(set_attr "type" "fxch")
2435 (set_attr "mode" "SF")])
2436
2437 (define_expand "movdf"
2438 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2439 (match_operand:DF 1 "general_operand" ""))]
2440 ""
2441 "ix86_expand_move (DFmode, operands); DONE;")
2442
2443 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2444 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2445 ;; On the average, pushdf using integers can be still shorter. Allow this
2446 ;; pattern for optimize_size too.
2447
2448 (define_insn "*pushdf_nointeger"
2449 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2450 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2451 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2452 {
2453 /* This insn should be already splitted before reg-stack. */
2454 abort ();
2455 }
2456 [(set_attr "type" "multi")
2457 (set_attr "mode" "DF,SI,SI,DF")])
2458
2459 (define_insn "*pushdf_integer"
2460 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2461 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2462 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2463 {
2464 /* This insn should be already splitted before reg-stack. */
2465 abort ();
2466 }
2467 [(set_attr "type" "multi")
2468 (set_attr "mode" "DF,SI,DF")])
2469
2470 ;; %%% Kill this when call knows how to work this out.
2471 (define_split
2472 [(set (match_operand:DF 0 "push_operand" "")
2473 (match_operand:DF 1 "any_fp_register_operand" ""))]
2474 "!TARGET_64BIT && reload_completed"
2475 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2476 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2477 "")
2478
2479 (define_split
2480 [(set (match_operand:DF 0 "push_operand" "")
2481 (match_operand:DF 1 "any_fp_register_operand" ""))]
2482 "TARGET_64BIT && reload_completed"
2483 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2484 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2485 "")
2486
2487 (define_split
2488 [(set (match_operand:DF 0 "push_operand" "")
2489 (match_operand:DF 1 "general_operand" ""))]
2490 "reload_completed"
2491 [(const_int 0)]
2492 "ix86_split_long_move (operands); DONE;")
2493
2494 ;; Moving is usually shorter when only FP registers are used. This separate
2495 ;; movdf pattern avoids the use of integer registers for FP operations
2496 ;; when optimizing for size.
2497
2498 (define_insn "*movdf_nointeger"
2499 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2500 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2501 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2502 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2503 && (reload_in_progress || reload_completed
2504 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2505 || GET_CODE (operands[1]) != CONST_DOUBLE
2506 || memory_operand (operands[0], DFmode))"
2507 {
2508 switch (which_alternative)
2509 {
2510 case 0:
2511 if (REG_P (operands[1])
2512 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2513 {
2514 if (REGNO (operands[0]) == FIRST_STACK_REG
2515 && TARGET_USE_FFREEP)
2516 return "ffreep\t%y0";
2517 return "fstp\t%y0";
2518 }
2519 else if (STACK_TOP_P (operands[0]))
2520 return "fld%z1\t%y1";
2521 else
2522 return "fst\t%y0";
2523
2524 case 1:
2525 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2526 return "fstp%z0\t%y0";
2527 else
2528 return "fst%z0\t%y0";
2529
2530 case 2:
2531 return standard_80387_constant_opcode (operands[1]);
2532
2533 case 3:
2534 case 4:
2535 return "#";
2536 case 5:
2537 switch (get_attr_mode (insn))
2538 {
2539 case MODE_V4SF:
2540 return "xorps\t%0, %0";
2541 case MODE_V2DF:
2542 return "xorpd\t%0, %0";
2543 case MODE_TI:
2544 return "pxor\t%0, %0";
2545 default:
2546 abort ();
2547 }
2548 case 6:
2549 switch (get_attr_mode (insn))
2550 {
2551 case MODE_V4SF:
2552 return "movaps\t{%1, %0|%0, %1}";
2553 case MODE_V2DF:
2554 return "movapd\t{%1, %0|%0, %1}";
2555 case MODE_DF:
2556 return "movsd\t{%1, %0|%0, %1}";
2557 default:
2558 abort ();
2559 }
2560 case 7:
2561 if (get_attr_mode (insn) == MODE_V2DF)
2562 return "movlpd\t{%1, %0|%0, %1}";
2563 else
2564 return "movsd\t{%1, %0|%0, %1}";
2565 case 8:
2566 return "movsd\t{%1, %0|%0, %1}";
2567
2568 default:
2569 abort();
2570 }
2571 }
2572 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2573 (set (attr "mode")
2574 (cond [(eq_attr "alternative" "3,4")
2575 (const_string "SI")
2576 /* xorps is one byte shorter. */
2577 (eq_attr "alternative" "5")
2578 (cond [(ne (symbol_ref "optimize_size")
2579 (const_int 0))
2580 (const_string "V4SF")
2581 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2582 (const_int 0))
2583 (const_string "TI")]
2584 (const_string "V2DF"))
2585 /* For architectures resolving dependencies on
2586 whole SSE registers use APD move to break dependency
2587 chains, otherwise use short move to avoid extra work.
2588
2589 movaps encodes one byte shorter. */
2590 (eq_attr "alternative" "6")
2591 (cond
2592 [(ne (symbol_ref "optimize_size")
2593 (const_int 0))
2594 (const_string "V4SF")
2595 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2596 (const_int 0))
2597 (const_string "V2DF")]
2598 (const_string "DF"))
2599 /* For architectures resolving dependencies on register
2600 parts we may avoid extra work to zero out upper part
2601 of register. */
2602 (eq_attr "alternative" "7")
2603 (if_then_else
2604 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2605 (const_int 0))
2606 (const_string "V2DF")
2607 (const_string "DF"))]
2608 (const_string "DF")))])
2609
2610 (define_insn "*movdf_integer"
2611 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2612 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2613 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2614 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2615 && (reload_in_progress || reload_completed
2616 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2617 || GET_CODE (operands[1]) != CONST_DOUBLE
2618 || memory_operand (operands[0], DFmode))"
2619 {
2620 switch (which_alternative)
2621 {
2622 case 0:
2623 if (REG_P (operands[1])
2624 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2625 {
2626 if (REGNO (operands[0]) == FIRST_STACK_REG
2627 && TARGET_USE_FFREEP)
2628 return "ffreep\t%y0";
2629 return "fstp\t%y0";
2630 }
2631 else if (STACK_TOP_P (operands[0]))
2632 return "fld%z1\t%y1";
2633 else
2634 return "fst\t%y0";
2635
2636 case 1:
2637 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2638 return "fstp%z0\t%y0";
2639 else
2640 return "fst%z0\t%y0";
2641
2642 case 2:
2643 return standard_80387_constant_opcode (operands[1]);
2644
2645 case 3:
2646 case 4:
2647 return "#";
2648
2649 case 5:
2650 switch (get_attr_mode (insn))
2651 {
2652 case MODE_V4SF:
2653 return "xorps\t%0, %0";
2654 case MODE_V2DF:
2655 return "xorpd\t%0, %0";
2656 case MODE_TI:
2657 return "pxor\t%0, %0";
2658 default:
2659 abort ();
2660 }
2661 case 6:
2662 switch (get_attr_mode (insn))
2663 {
2664 case MODE_V4SF:
2665 return "movaps\t{%1, %0|%0, %1}";
2666 case MODE_V2DF:
2667 return "movapd\t{%1, %0|%0, %1}";
2668 case MODE_DF:
2669 return "movsd\t{%1, %0|%0, %1}";
2670 default:
2671 abort ();
2672 }
2673 case 7:
2674 if (get_attr_mode (insn) == MODE_V2DF)
2675 return "movlpd\t{%1, %0|%0, %1}";
2676 else
2677 return "movsd\t{%1, %0|%0, %1}";
2678 case 8:
2679 return "movsd\t{%1, %0|%0, %1}";
2680
2681 default:
2682 abort();
2683 }
2684 }
2685 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2686 (set (attr "mode")
2687 (cond [(eq_attr "alternative" "3,4")
2688 (const_string "SI")
2689 /* xorps is one byte shorter. */
2690 (eq_attr "alternative" "5")
2691 (cond [(ne (symbol_ref "optimize_size")
2692 (const_int 0))
2693 (const_string "V4SF")
2694 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2695 (const_int 0))
2696 (const_string "TI")]
2697 (const_string "V2DF"))
2698 /* For architectures resolving dependencies on
2699 whole SSE registers use APD move to break dependency
2700 chains, otherwise use short move to avoid extra work.
2701
2702 movaps encodes one byte shorter. */
2703 (eq_attr "alternative" "6")
2704 (cond
2705 [(ne (symbol_ref "optimize_size")
2706 (const_int 0))
2707 (const_string "V4SF")
2708 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2709 (const_int 0))
2710 (const_string "V2DF")]
2711 (const_string "DF"))
2712 /* For architectures resolving dependencies on register
2713 parts we may avoid extra work to zero out upper part
2714 of register. */
2715 (eq_attr "alternative" "7")
2716 (if_then_else
2717 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2718 (const_int 0))
2719 (const_string "V2DF")
2720 (const_string "DF"))]
2721 (const_string "DF")))])
2722
2723 (define_split
2724 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2725 (match_operand:DF 1 "general_operand" ""))]
2726 "reload_completed
2727 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2728 && ! (ANY_FP_REG_P (operands[0]) ||
2729 (GET_CODE (operands[0]) == SUBREG
2730 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2731 && ! (ANY_FP_REG_P (operands[1]) ||
2732 (GET_CODE (operands[1]) == SUBREG
2733 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2734 [(const_int 0)]
2735 "ix86_split_long_move (operands); DONE;")
2736
2737 (define_insn "*swapdf"
2738 [(set (match_operand:DF 0 "register_operand" "+f")
2739 (match_operand:DF 1 "register_operand" "+f"))
2740 (set (match_dup 1)
2741 (match_dup 0))]
2742 "reload_completed || !TARGET_SSE2"
2743 {
2744 if (STACK_TOP_P (operands[0]))
2745 return "fxch\t%1";
2746 else
2747 return "fxch\t%0";
2748 }
2749 [(set_attr "type" "fxch")
2750 (set_attr "mode" "DF")])
2751
2752 (define_expand "movxf"
2753 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2754 (match_operand:XF 1 "general_operand" ""))]
2755 "!TARGET_128BIT_LONG_DOUBLE"
2756 "ix86_expand_move (XFmode, operands); DONE;")
2757
2758 (define_expand "movtf"
2759 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2760 (match_operand:TF 1 "general_operand" ""))]
2761 ""
2762 "ix86_expand_move (TFmode, operands); DONE;")
2763
2764 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2765 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2766 ;; Pushing using integer instructions is longer except for constants
2767 ;; and direct memory references.
2768 ;; (assuming that any given constant is pushed only once, but this ought to be
2769 ;; handled elsewhere).
2770
2771 (define_insn "*pushxf_nointeger"
2772 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2773 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2774 "!TARGET_128BIT_LONG_DOUBLE && optimize_size"
2775 {
2776 /* This insn should be already splitted before reg-stack. */
2777 abort ();
2778 }
2779 [(set_attr "type" "multi")
2780 (set_attr "mode" "XF,SI,SI")])
2781
2782 (define_insn "*pushtf_nointeger"
2783 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2784 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2785 "optimize_size"
2786 {
2787 /* This insn should be already splitted before reg-stack. */
2788 abort ();
2789 }
2790 [(set_attr "type" "multi")
2791 (set_attr "mode" "XF,SI,SI")])
2792
2793 (define_insn "*pushxf_integer"
2794 [(set (match_operand:XF 0 "push_operand" "=<,<")
2795 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2796 "!TARGET_128BIT_LONG_DOUBLE && !optimize_size"
2797 {
2798 /* This insn should be already splitted before reg-stack. */
2799 abort ();
2800 }
2801 [(set_attr "type" "multi")
2802 (set_attr "mode" "XF,SI")])
2803
2804 (define_insn "*pushtf_integer"
2805 [(set (match_operand:TF 0 "push_operand" "=<,<")
2806 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2807 "!optimize_size"
2808 {
2809 /* This insn should be already splitted before reg-stack. */
2810 abort ();
2811 }
2812 [(set_attr "type" "multi")
2813 (set_attr "mode" "XF,SI")])
2814
2815 (define_split
2816 [(set (match_operand 0 "push_operand" "")
2817 (match_operand 1 "general_operand" ""))]
2818 "reload_completed
2819 && (GET_MODE (operands[0]) == XFmode
2820 || GET_MODE (operands[0]) == TFmode
2821 || GET_MODE (operands[0]) == DFmode)
2822 && !ANY_FP_REG_P (operands[1])"
2823 [(const_int 0)]
2824 "ix86_split_long_move (operands); DONE;")
2825
2826 (define_split
2827 [(set (match_operand:XF 0 "push_operand" "")
2828 (match_operand:XF 1 "any_fp_register_operand" ""))]
2829 "!TARGET_128BIT_LONG_DOUBLE"
2830 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2831 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2832
2833 (define_split
2834 [(set (match_operand:TF 0 "push_operand" "")
2835 (match_operand:TF 1 "any_fp_register_operand" ""))]
2836 "!TARGET_64BIT"
2837 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2838 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2839
2840 (define_split
2841 [(set (match_operand:TF 0 "push_operand" "")
2842 (match_operand:TF 1 "any_fp_register_operand" ""))]
2843 "TARGET_64BIT"
2844 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2845 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2846
2847 ;; Do not use integer registers when optimizing for size
2848 (define_insn "*movxf_nointeger"
2849 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2850 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2851 "!TARGET_128BIT_LONG_DOUBLE
2852 && optimize_size
2853 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2854 && (reload_in_progress || reload_completed
2855 || GET_CODE (operands[1]) != CONST_DOUBLE
2856 || memory_operand (operands[0], XFmode))"
2857 {
2858 switch (which_alternative)
2859 {
2860 case 0:
2861 if (REG_P (operands[1])
2862 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2863 {
2864 if (REGNO (operands[0]) == FIRST_STACK_REG
2865 && TARGET_USE_FFREEP)
2866 return "ffreep\t%y0";
2867 return "fstp\t%y0";
2868 }
2869 else if (STACK_TOP_P (operands[0]))
2870 return "fld%z1\t%y1";
2871 else
2872 return "fst\t%y0";
2873
2874 case 1:
2875 /* There is no non-popping store to memory for XFmode. So if
2876 we need one, follow the store with a load. */
2877 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2878 return "fstp%z0\t%y0\;fld%z0\t%y0";
2879 else
2880 return "fstp%z0\t%y0";
2881
2882 case 2:
2883 return standard_80387_constant_opcode (operands[1]);
2884
2885 case 3: case 4:
2886 return "#";
2887 }
2888 abort();
2889 }
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2892
2893 (define_insn "*movtf_nointeger"
2894 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2895 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2896 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2897 && optimize_size
2898 && (reload_in_progress || reload_completed
2899 || GET_CODE (operands[1]) != CONST_DOUBLE
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || memory_operand (operands[0], TFmode))"
2902 {
2903 switch (which_alternative)
2904 {
2905 case 0:
2906 if (REG_P (operands[1])
2907 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2908 {
2909 if (REGNO (operands[0]) == FIRST_STACK_REG
2910 && TARGET_USE_FFREEP)
2911 return "ffreep\t%y0";
2912 return "fstp\t%y0";
2913 }
2914 else if (STACK_TOP_P (operands[0]))
2915 return "fld%z1\t%y1";
2916 else
2917 return "fst\t%y0";
2918
2919 case 1:
2920 /* There is no non-popping store to memory for XFmode. So if
2921 we need one, follow the store with a load. */
2922 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2923 return "fstp%z0\t%y0\;fld%z0\t%y0";
2924 else
2925 return "fstp%z0\t%y0";
2926
2927 case 2:
2928 return standard_80387_constant_opcode (operands[1]);
2929
2930 case 3: case 4:
2931 return "#";
2932 }
2933 abort();
2934 }
2935 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2936 (set_attr "mode" "XF,XF,XF,SI,SI")])
2937
2938 (define_insn "*movxf_integer"
2939 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2940 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2941 "!TARGET_128BIT_LONG_DOUBLE
2942 && !optimize_size
2943 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2944 && (reload_in_progress || reload_completed
2945 || GET_CODE (operands[1]) != CONST_DOUBLE
2946 || memory_operand (operands[0], XFmode))"
2947 {
2948 switch (which_alternative)
2949 {
2950 case 0:
2951 if (REG_P (operands[1])
2952 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2953 {
2954 if (REGNO (operands[0]) == FIRST_STACK_REG
2955 && TARGET_USE_FFREEP)
2956 return "ffreep\t%y0";
2957 return "fstp\t%y0";
2958 }
2959 else if (STACK_TOP_P (operands[0]))
2960 return "fld%z1\t%y1";
2961 else
2962 return "fst\t%y0";
2963
2964 case 1:
2965 /* There is no non-popping store to memory for XFmode. So if
2966 we need one, follow the store with a load. */
2967 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2968 return "fstp%z0\t%y0\;fld%z0\t%y0";
2969 else
2970 return "fstp%z0\t%y0";
2971
2972 case 2:
2973 return standard_80387_constant_opcode (operands[1]);
2974
2975 case 3: case 4:
2976 return "#";
2977 }
2978 abort();
2979 }
2980 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2981 (set_attr "mode" "XF,XF,XF,SI,SI")])
2982
2983 (define_insn "*movtf_integer"
2984 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2985 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2986 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2987 && !optimize_size
2988 && (reload_in_progress || reload_completed
2989 || GET_CODE (operands[1]) != CONST_DOUBLE
2990 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2991 || memory_operand (operands[0], TFmode))"
2992 {
2993 switch (which_alternative)
2994 {
2995 case 0:
2996 if (REG_P (operands[1])
2997 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2998 {
2999 if (REGNO (operands[0]) == FIRST_STACK_REG
3000 && TARGET_USE_FFREEP)
3001 return "ffreep\t%y0";
3002 return "fstp\t%y0";
3003 }
3004 else if (STACK_TOP_P (operands[0]))
3005 return "fld%z1\t%y1";
3006 else
3007 return "fst\t%y0";
3008
3009 case 1:
3010 /* There is no non-popping store to memory for XFmode. So if
3011 we need one, follow the store with a load. */
3012 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013 return "fstp%z0\t%y0\;fld%z0\t%y0";
3014 else
3015 return "fstp%z0\t%y0";
3016
3017 case 2:
3018 return standard_80387_constant_opcode (operands[1]);
3019
3020 case 3: case 4:
3021 return "#";
3022 }
3023 abort();
3024 }
3025 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3026 (set_attr "mode" "XF,XF,XF,SI,SI")])
3027
3028 (define_split
3029 [(set (match_operand 0 "nonimmediate_operand" "")
3030 (match_operand 1 "general_operand" ""))]
3031 "reload_completed
3032 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3033 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3034 && ! (ANY_FP_REG_P (operands[0]) ||
3035 (GET_CODE (operands[0]) == SUBREG
3036 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3037 && ! (ANY_FP_REG_P (operands[1]) ||
3038 (GET_CODE (operands[1]) == SUBREG
3039 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3040 [(const_int 0)]
3041 "ix86_split_long_move (operands); DONE;")
3042
3043 (define_split
3044 [(set (match_operand 0 "register_operand" "")
3045 (match_operand 1 "memory_operand" ""))]
3046 "reload_completed
3047 && GET_CODE (operands[1]) == MEM
3048 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3049 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3050 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3051 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3052 && (!(SSE_REG_P (operands[0]) ||
3053 (GET_CODE (operands[0]) == SUBREG
3054 && SSE_REG_P (SUBREG_REG (operands[0]))))
3055 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3056 && (!(FP_REG_P (operands[0]) ||
3057 (GET_CODE (operands[0]) == SUBREG
3058 && FP_REG_P (SUBREG_REG (operands[0]))))
3059 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3060 [(set (match_dup 0)
3061 (match_dup 1))]
3062 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3063
3064 (define_insn "swapxf"
3065 [(set (match_operand:XF 0 "register_operand" "+f")
3066 (match_operand:XF 1 "register_operand" "+f"))
3067 (set (match_dup 1)
3068 (match_dup 0))]
3069 ""
3070 {
3071 if (STACK_TOP_P (operands[0]))
3072 return "fxch\t%1";
3073 else
3074 return "fxch\t%0";
3075 }
3076 [(set_attr "type" "fxch")
3077 (set_attr "mode" "XF")])
3078
3079 (define_insn "swaptf"
3080 [(set (match_operand:TF 0 "register_operand" "+f")
3081 (match_operand:TF 1 "register_operand" "+f"))
3082 (set (match_dup 1)
3083 (match_dup 0))]
3084 ""
3085 {
3086 if (STACK_TOP_P (operands[0]))
3087 return "fxch\t%1";
3088 else
3089 return "fxch\t%0";
3090 }
3091 [(set_attr "type" "fxch")
3092 (set_attr "mode" "XF")])
3093 \f
3094 ;; Zero extension instructions
3095
3096 (define_expand "zero_extendhisi2"
3097 [(set (match_operand:SI 0 "register_operand" "")
3098 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3099 ""
3100 {
3101 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3102 {
3103 operands[1] = force_reg (HImode, operands[1]);
3104 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3105 DONE;
3106 }
3107 })
3108
3109 (define_insn "zero_extendhisi2_and"
3110 [(set (match_operand:SI 0 "register_operand" "=r")
3111 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3112 (clobber (reg:CC 17))]
3113 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3114 "#"
3115 [(set_attr "type" "alu1")
3116 (set_attr "mode" "SI")])
3117
3118 (define_split
3119 [(set (match_operand:SI 0 "register_operand" "")
3120 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3121 (clobber (reg:CC 17))]
3122 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3123 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3124 (clobber (reg:CC 17))])]
3125 "")
3126
3127 (define_insn "*zero_extendhisi2_movzwl"
3128 [(set (match_operand:SI 0 "register_operand" "=r")
3129 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3130 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3131 "movz{wl|x}\t{%1, %0|%0, %1}"
3132 [(set_attr "type" "imovx")
3133 (set_attr "mode" "SI")])
3134
3135 (define_expand "zero_extendqihi2"
3136 [(parallel
3137 [(set (match_operand:HI 0 "register_operand" "")
3138 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3139 (clobber (reg:CC 17))])]
3140 ""
3141 "")
3142
3143 (define_insn "*zero_extendqihi2_and"
3144 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3145 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3146 (clobber (reg:CC 17))]
3147 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3148 "#"
3149 [(set_attr "type" "alu1")
3150 (set_attr "mode" "HI")])
3151
3152 (define_insn "*zero_extendqihi2_movzbw_and"
3153 [(set (match_operand:HI 0 "register_operand" "=r,r")
3154 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3155 (clobber (reg:CC 17))]
3156 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3157 "#"
3158 [(set_attr "type" "imovx,alu1")
3159 (set_attr "mode" "HI")])
3160
3161 (define_insn "*zero_extendqihi2_movzbw"
3162 [(set (match_operand:HI 0 "register_operand" "=r")
3163 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3164 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3165 "movz{bw|x}\t{%1, %0|%0, %1}"
3166 [(set_attr "type" "imovx")
3167 (set_attr "mode" "HI")])
3168
3169 ;; For the movzbw case strip only the clobber
3170 (define_split
3171 [(set (match_operand:HI 0 "register_operand" "")
3172 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3173 (clobber (reg:CC 17))]
3174 "reload_completed
3175 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3176 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3177 [(set (match_operand:HI 0 "register_operand" "")
3178 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3179
3180 ;; When source and destination does not overlap, clear destination
3181 ;; first and then do the movb
3182 (define_split
3183 [(set (match_operand:HI 0 "register_operand" "")
3184 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3185 (clobber (reg:CC 17))]
3186 "reload_completed
3187 && ANY_QI_REG_P (operands[0])
3188 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3189 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3190 [(set (match_dup 0) (const_int 0))
3191 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3192 "operands[2] = gen_lowpart (QImode, operands[0]);")
3193
3194 ;; Rest is handled by single and.
3195 (define_split
3196 [(set (match_operand:HI 0 "register_operand" "")
3197 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3198 (clobber (reg:CC 17))]
3199 "reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3202 (clobber (reg:CC 17))])]
3203 "")
3204
3205 (define_expand "zero_extendqisi2"
3206 [(parallel
3207 [(set (match_operand:SI 0 "register_operand" "")
3208 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3209 (clobber (reg:CC 17))])]
3210 ""
3211 "")
3212
3213 (define_insn "*zero_extendqisi2_and"
3214 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3215 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3216 (clobber (reg:CC 17))]
3217 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3218 "#"
3219 [(set_attr "type" "alu1")
3220 (set_attr "mode" "SI")])
3221
3222 (define_insn "*zero_extendqisi2_movzbw_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r,r")
3224 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3225 (clobber (reg:CC 17))]
3226 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3227 "#"
3228 [(set_attr "type" "imovx,alu1")
3229 (set_attr "mode" "SI")])
3230
3231 (define_insn "*zero_extendqisi2_movzbw"
3232 [(set (match_operand:SI 0 "register_operand" "=r")
3233 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3234 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3235 "movz{bl|x}\t{%1, %0|%0, %1}"
3236 [(set_attr "type" "imovx")
3237 (set_attr "mode" "SI")])
3238
3239 ;; For the movzbl case strip only the clobber
3240 (define_split
3241 [(set (match_operand:SI 0 "register_operand" "")
3242 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3243 (clobber (reg:CC 17))]
3244 "reload_completed
3245 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3246 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3247 [(set (match_dup 0)
3248 (zero_extend:SI (match_dup 1)))])
3249
3250 ;; When source and destination does not overlap, clear destination
3251 ;; first and then do the movb
3252 (define_split
3253 [(set (match_operand:SI 0 "register_operand" "")
3254 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3255 (clobber (reg:CC 17))]
3256 "reload_completed
3257 && ANY_QI_REG_P (operands[0])
3258 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3259 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3260 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3261 [(set (match_dup 0) (const_int 0))
3262 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3263 "operands[2] = gen_lowpart (QImode, operands[0]);")
3264
3265 ;; Rest is handled by single and.
3266 (define_split
3267 [(set (match_operand:SI 0 "register_operand" "")
3268 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3269 (clobber (reg:CC 17))]
3270 "reload_completed
3271 && true_regnum (operands[0]) == true_regnum (operands[1])"
3272 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3273 (clobber (reg:CC 17))])]
3274 "")
3275
3276 ;; %%% Kill me once multi-word ops are sane.
3277 (define_expand "zero_extendsidi2"
3278 [(set (match_operand:DI 0 "register_operand" "=r")
3279 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3280 ""
3281 "if (!TARGET_64BIT)
3282 {
3283 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3284 DONE;
3285 }
3286 ")
3287
3288 (define_insn "zero_extendsidi2_32"
3289 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3290 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3291 (clobber (reg:CC 17))]
3292 "!TARGET_64BIT"
3293 "#"
3294 [(set_attr "mode" "SI")])
3295
3296 (define_insn "zero_extendsidi2_rex64"
3297 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3298 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3299 "TARGET_64BIT"
3300 "@
3301 mov\t{%k1, %k0|%k0, %k1}
3302 #"
3303 [(set_attr "type" "imovx,imov")
3304 (set_attr "mode" "SI,DI")])
3305
3306 (define_split
3307 [(set (match_operand:DI 0 "memory_operand" "")
3308 (zero_extend:DI (match_dup 0)))]
3309 "TARGET_64BIT"
3310 [(set (match_dup 4) (const_int 0))]
3311 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3312
3313 (define_split
3314 [(set (match_operand:DI 0 "register_operand" "")
3315 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3316 (clobber (reg:CC 17))]
3317 "!TARGET_64BIT && reload_completed
3318 && true_regnum (operands[0]) == true_regnum (operands[1])"
3319 [(set (match_dup 4) (const_int 0))]
3320 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3321
3322 (define_split
3323 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3324 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3325 (clobber (reg:CC 17))]
3326 "!TARGET_64BIT && reload_completed"
3327 [(set (match_dup 3) (match_dup 1))
3328 (set (match_dup 4) (const_int 0))]
3329 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3330
3331 (define_insn "zero_extendhidi2"
3332 [(set (match_operand:DI 0 "register_operand" "=r,r")
3333 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3334 "TARGET_64BIT"
3335 "@
3336 movz{wl|x}\t{%1, %k0|%k0, %1}
3337 movz{wq|x}\t{%1, %0|%0, %1}"
3338 [(set_attr "type" "imovx")
3339 (set_attr "mode" "SI,DI")])
3340
3341 (define_insn "zero_extendqidi2"
3342 [(set (match_operand:DI 0 "register_operand" "=r,r")
3343 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3344 "TARGET_64BIT"
3345 "@
3346 movz{bl|x}\t{%1, %k0|%k0, %1}
3347 movz{bq|x}\t{%1, %0|%0, %1}"
3348 [(set_attr "type" "imovx")
3349 (set_attr "mode" "SI,DI")])
3350 \f
3351 ;; Sign extension instructions
3352
3353 (define_expand "extendsidi2"
3354 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3355 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3356 (clobber (reg:CC 17))
3357 (clobber (match_scratch:SI 2 ""))])]
3358 ""
3359 {
3360 if (TARGET_64BIT)
3361 {
3362 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3363 DONE;
3364 }
3365 })
3366
3367 (define_insn "*extendsidi2_1"
3368 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3369 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3370 (clobber (reg:CC 17))
3371 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3372 "!TARGET_64BIT"
3373 "#")
3374
3375 (define_insn "extendsidi2_rex64"
3376 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3377 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3378 "TARGET_64BIT"
3379 "@
3380 {cltq|cdqe}
3381 movs{lq|x}\t{%1,%0|%0, %1}"
3382 [(set_attr "type" "imovx")
3383 (set_attr "mode" "DI")
3384 (set_attr "prefix_0f" "0")
3385 (set_attr "modrm" "0,1")])
3386
3387 (define_insn "extendhidi2"
3388 [(set (match_operand:DI 0 "register_operand" "=r")
3389 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3390 "TARGET_64BIT"
3391 "movs{wq|x}\t{%1,%0|%0, %1}"
3392 [(set_attr "type" "imovx")
3393 (set_attr "mode" "DI")])
3394
3395 (define_insn "extendqidi2"
3396 [(set (match_operand:DI 0 "register_operand" "=r")
3397 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3398 "TARGET_64BIT"
3399 "movs{bq|x}\t{%1,%0|%0, %1}"
3400 [(set_attr "type" "imovx")
3401 (set_attr "mode" "DI")])
3402
3403 ;; Extend to memory case when source register does die.
3404 (define_split
3405 [(set (match_operand:DI 0 "memory_operand" "")
3406 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3407 (clobber (reg:CC 17))
3408 (clobber (match_operand:SI 2 "register_operand" ""))]
3409 "(reload_completed
3410 && dead_or_set_p (insn, operands[1])
3411 && !reg_mentioned_p (operands[1], operands[0]))"
3412 [(set (match_dup 3) (match_dup 1))
3413 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3414 (clobber (reg:CC 17))])
3415 (set (match_dup 4) (match_dup 1))]
3416 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3417
3418 ;; Extend to memory case when source register does not die.
3419 (define_split
3420 [(set (match_operand:DI 0 "memory_operand" "")
3421 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3422 (clobber (reg:CC 17))
3423 (clobber (match_operand:SI 2 "register_operand" ""))]
3424 "reload_completed"
3425 [(const_int 0)]
3426 {
3427 split_di (&operands[0], 1, &operands[3], &operands[4]);
3428
3429 emit_move_insn (operands[3], operands[1]);
3430
3431 /* Generate a cltd if possible and doing so it profitable. */
3432 if (true_regnum (operands[1]) == 0
3433 && true_regnum (operands[2]) == 1
3434 && (optimize_size || TARGET_USE_CLTD))
3435 {
3436 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3437 }
3438 else
3439 {
3440 emit_move_insn (operands[2], operands[1]);
3441 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3442 }
3443 emit_move_insn (operands[4], operands[2]);
3444 DONE;
3445 })
3446
3447 ;; Extend to register case. Optimize case where source and destination
3448 ;; registers match and cases where we can use cltd.
3449 (define_split
3450 [(set (match_operand:DI 0 "register_operand" "")
3451 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3452 (clobber (reg:CC 17))
3453 (clobber (match_scratch:SI 2 ""))]
3454 "reload_completed"
3455 [(const_int 0)]
3456 {
3457 split_di (&operands[0], 1, &operands[3], &operands[4]);
3458
3459 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3460 emit_move_insn (operands[3], operands[1]);
3461
3462 /* Generate a cltd if possible and doing so it profitable. */
3463 if (true_regnum (operands[3]) == 0
3464 && (optimize_size || TARGET_USE_CLTD))
3465 {
3466 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3467 DONE;
3468 }
3469
3470 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3471 emit_move_insn (operands[4], operands[1]);
3472
3473 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3474 DONE;
3475 })
3476
3477 (define_insn "extendhisi2"
3478 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3479 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3480 ""
3481 {
3482 switch (get_attr_prefix_0f (insn))
3483 {
3484 case 0:
3485 return "{cwtl|cwde}";
3486 default:
3487 return "movs{wl|x}\t{%1,%0|%0, %1}";
3488 }
3489 }
3490 [(set_attr "type" "imovx")
3491 (set_attr "mode" "SI")
3492 (set (attr "prefix_0f")
3493 ;; movsx is short decodable while cwtl is vector decoded.
3494 (if_then_else (and (eq_attr "cpu" "!k6")
3495 (eq_attr "alternative" "0"))
3496 (const_string "0")
3497 (const_string "1")))
3498 (set (attr "modrm")
3499 (if_then_else (eq_attr "prefix_0f" "0")
3500 (const_string "0")
3501 (const_string "1")))])
3502
3503 (define_insn "*extendhisi2_zext"
3504 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3505 (zero_extend:DI
3506 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3507 "TARGET_64BIT"
3508 {
3509 switch (get_attr_prefix_0f (insn))
3510 {
3511 case 0:
3512 return "{cwtl|cwde}";
3513 default:
3514 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3515 }
3516 }
3517 [(set_attr "type" "imovx")
3518 (set_attr "mode" "SI")
3519 (set (attr "prefix_0f")
3520 ;; movsx is short decodable while cwtl is vector decoded.
3521 (if_then_else (and (eq_attr "cpu" "!k6")
3522 (eq_attr "alternative" "0"))
3523 (const_string "0")
3524 (const_string "1")))
3525 (set (attr "modrm")
3526 (if_then_else (eq_attr "prefix_0f" "0")
3527 (const_string "0")
3528 (const_string "1")))])
3529
3530 (define_insn "extendqihi2"
3531 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3532 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3533 ""
3534 {
3535 switch (get_attr_prefix_0f (insn))
3536 {
3537 case 0:
3538 return "{cbtw|cbw}";
3539 default:
3540 return "movs{bw|x}\t{%1,%0|%0, %1}";
3541 }
3542 }
3543 [(set_attr "type" "imovx")
3544 (set_attr "mode" "HI")
3545 (set (attr "prefix_0f")
3546 ;; movsx is short decodable while cwtl is vector decoded.
3547 (if_then_else (and (eq_attr "cpu" "!k6")
3548 (eq_attr "alternative" "0"))
3549 (const_string "0")
3550 (const_string "1")))
3551 (set (attr "modrm")
3552 (if_then_else (eq_attr "prefix_0f" "0")
3553 (const_string "0")
3554 (const_string "1")))])
3555
3556 (define_insn "extendqisi2"
3557 [(set (match_operand:SI 0 "register_operand" "=r")
3558 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3559 ""
3560 "movs{bl|x}\t{%1,%0|%0, %1}"
3561 [(set_attr "type" "imovx")
3562 (set_attr "mode" "SI")])
3563
3564 (define_insn "*extendqisi2_zext"
3565 [(set (match_operand:DI 0 "register_operand" "=r")
3566 (zero_extend:DI
3567 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3568 "TARGET_64BIT"
3569 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3570 [(set_attr "type" "imovx")
3571 (set_attr "mode" "SI")])
3572 \f
3573 ;; Conversions between float and double.
3574
3575 ;; These are all no-ops in the model used for the 80387. So just
3576 ;; emit moves.
3577
3578 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3579 (define_insn "*dummy_extendsfdf2"
3580 [(set (match_operand:DF 0 "push_operand" "=<")
3581 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3582 "0"
3583 "#")
3584
3585 (define_split
3586 [(set (match_operand:DF 0 "push_operand" "")
3587 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3588 "!TARGET_64BIT"
3589 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3590 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3591
3592 (define_split
3593 [(set (match_operand:DF 0 "push_operand" "")
3594 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3595 "TARGET_64BIT"
3596 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3597 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3598
3599 (define_insn "*dummy_extendsfxf2"
3600 [(set (match_operand:XF 0 "push_operand" "=<")
3601 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3602 "0"
3603 "#")
3604
3605 (define_split
3606 [(set (match_operand:XF 0 "push_operand" "")
3607 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3608 "!TARGET_128BIT_LONG_DOUBLE"
3609 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3610 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3611
3612 (define_insn "*dummy_extendsftf2"
3613 [(set (match_operand:TF 0 "push_operand" "=<")
3614 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3615 "0"
3616 "#")
3617
3618 (define_split
3619 [(set (match_operand:TF 0 "push_operand" "")
3620 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3621 "!TARGET_64BIT"
3622 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3623 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3624
3625 (define_split
3626 [(set (match_operand:TF 0 "push_operand" "")
3627 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3628 "TARGET_64BIT"
3629 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3630 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3631
3632 (define_insn "*dummy_extenddfxf2"
3633 [(set (match_operand:XF 0 "push_operand" "=<")
3634 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3635 "0"
3636 "#")
3637
3638 (define_split
3639 [(set (match_operand:XF 0 "push_operand" "")
3640 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3641 "!TARGET_128BIT_LONG_DOUBLE"
3642 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3643 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3644
3645 (define_insn "*dummy_extenddftf2"
3646 [(set (match_operand:TF 0 "push_operand" "=<")
3647 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3648 "0"
3649 "#")
3650
3651 (define_split
3652 [(set (match_operand:TF 0 "push_operand" "")
3653 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3654 "!TARGET_64BIT"
3655 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3656 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3657
3658 (define_split
3659 [(set (match_operand:TF 0 "push_operand" "")
3660 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3661 "TARGET_64BIT"
3662 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3663 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3664
3665 (define_expand "extendsfdf2"
3666 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3667 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3668 "TARGET_80387 || TARGET_SSE2"
3669 {
3670 /* ??? Needed for compress_float_constant since all fp constants
3671 are LEGITIMATE_CONSTANT_P. */
3672 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3673 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3674 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3675 operands[1] = force_reg (SFmode, operands[1]);
3676 })
3677
3678 (define_insn "*extendsfdf2_1"
3679 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3680 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3681 "(TARGET_80387 || TARGET_SSE2)
3682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3683 {
3684 switch (which_alternative)
3685 {
3686 case 0:
3687 if (REG_P (operands[1])
3688 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689 return "fstp\t%y0";
3690 else if (STACK_TOP_P (operands[0]))
3691 return "fld%z1\t%y1";
3692 else
3693 return "fst\t%y0";
3694
3695 case 1:
3696 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697 return "fstp%z0\t%y0";
3698
3699 else
3700 return "fst%z0\t%y0";
3701 case 2:
3702 return "cvtss2sd\t{%1, %0|%0, %1}";
3703
3704 default:
3705 abort ();
3706 }
3707 }
3708 [(set_attr "type" "fmov,fmov,ssecvt")
3709 (set_attr "mode" "SF,XF,DF")])
3710
3711 (define_insn "*extendsfdf2_1_sse_only"
3712 [(set (match_operand:DF 0 "register_operand" "=Y")
3713 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3714 "!TARGET_80387 && TARGET_SSE2
3715 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3716 "cvtss2sd\t{%1, %0|%0, %1}"
3717 [(set_attr "type" "ssecvt")
3718 (set_attr "mode" "DF")])
3719
3720 (define_expand "extendsfxf2"
3721 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3722 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3723 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3724 {
3725 /* ??? Needed for compress_float_constant since all fp constants
3726 are LEGITIMATE_CONSTANT_P. */
3727 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3728 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3729 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3730 operands[1] = force_reg (SFmode, operands[1]);
3731 })
3732
3733 (define_insn "*extendsfxf2_1"
3734 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3735 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3736 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3737 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3738 {
3739 switch (which_alternative)
3740 {
3741 case 0:
3742 if (REG_P (operands[1])
3743 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3744 return "fstp\t%y0";
3745 else if (STACK_TOP_P (operands[0]))
3746 return "fld%z1\t%y1";
3747 else
3748 return "fst\t%y0";
3749
3750 case 1:
3751 /* There is no non-popping store to memory for XFmode. So if
3752 we need one, follow the store with a load. */
3753 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3754 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3755 else
3756 return "fstp%z0\t%y0";
3757
3758 default:
3759 abort ();
3760 }
3761 }
3762 [(set_attr "type" "fmov")
3763 (set_attr "mode" "SF,XF")])
3764
3765 (define_expand "extendsftf2"
3766 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3767 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3768 "TARGET_80387"
3769 {
3770 /* ??? Needed for compress_float_constant since all fp constants
3771 are LEGITIMATE_CONSTANT_P. */
3772 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3773 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3774 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3775 operands[1] = force_reg (SFmode, operands[1]);
3776 })
3777
3778 (define_insn "*extendsftf2_1"
3779 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3780 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3781 "TARGET_80387
3782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3783 {
3784 switch (which_alternative)
3785 {
3786 case 0:
3787 if (REG_P (operands[1])
3788 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789 return "fstp\t%y0";
3790 else if (STACK_TOP_P (operands[0]))
3791 return "fld%z1\t%y1";
3792 else
3793 return "fst\t%y0";
3794
3795 case 1:
3796 /* There is no non-popping store to memory for XFmode. So if
3797 we need one, follow the store with a load. */
3798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3800 else
3801 return "fstp%z0\t%y0";
3802
3803 default:
3804 abort ();
3805 }
3806 }
3807 [(set_attr "type" "fmov")
3808 (set_attr "mode" "SF,XF")])
3809
3810 (define_expand "extenddfxf2"
3811 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3812 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3813 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3814 {
3815 /* ??? Needed for compress_float_constant since all fp constants
3816 are LEGITIMATE_CONSTANT_P. */
3817 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3818 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3819 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3820 operands[1] = force_reg (DFmode, operands[1]);
3821 })
3822
3823 (define_insn "*extenddfxf2_1"
3824 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3825 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3826 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3827 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3828 {
3829 switch (which_alternative)
3830 {
3831 case 0:
3832 if (REG_P (operands[1])
3833 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834 return "fstp\t%y0";
3835 else if (STACK_TOP_P (operands[0]))
3836 return "fld%z1\t%y1";
3837 else
3838 return "fst\t%y0";
3839
3840 case 1:
3841 /* There is no non-popping store to memory for XFmode. So if
3842 we need one, follow the store with a load. */
3843 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3844 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3845 else
3846 return "fstp%z0\t%y0";
3847
3848 default:
3849 abort ();
3850 }
3851 }
3852 [(set_attr "type" "fmov")
3853 (set_attr "mode" "DF,XF")])
3854
3855 (define_expand "extenddftf2"
3856 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3857 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3858 "TARGET_80387"
3859 {
3860 /* ??? Needed for compress_float_constant since all fp constants
3861 are LEGITIMATE_CONSTANT_P. */
3862 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3863 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3864 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3865 operands[1] = force_reg (DFmode, operands[1]);
3866 })
3867
3868 (define_insn "*extenddftf2_1"
3869 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3870 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3871 "TARGET_80387
3872 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3873 {
3874 switch (which_alternative)
3875 {
3876 case 0:
3877 if (REG_P (operands[1])
3878 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3879 return "fstp\t%y0";
3880 else if (STACK_TOP_P (operands[0]))
3881 return "fld%z1\t%y1";
3882 else
3883 return "fst\t%y0";
3884
3885 case 1:
3886 /* There is no non-popping store to memory for XFmode. So if
3887 we need one, follow the store with a load. */
3888 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3890 else
3891 return "fstp%z0\t%y0";
3892
3893 default:
3894 abort ();
3895 }
3896 }
3897 [(set_attr "type" "fmov")
3898 (set_attr "mode" "DF,XF")])
3899
3900 ;; %%% This seems bad bad news.
3901 ;; This cannot output into an f-reg because there is no way to be sure
3902 ;; of truncating in that case. Otherwise this is just like a simple move
3903 ;; insn. So we pretend we can output to a reg in order to get better
3904 ;; register preferencing, but we really use a stack slot.
3905
3906 (define_expand "truncdfsf2"
3907 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3908 (float_truncate:SF
3909 (match_operand:DF 1 "register_operand" "")))
3910 (clobber (match_dup 2))])]
3911 "TARGET_80387 || TARGET_SSE2"
3912 "
3913 if (TARGET_80387)
3914 operands[2] = assign_386_stack_local (SFmode, 0);
3915 else
3916 {
3917 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3918 DONE;
3919 }
3920 ")
3921
3922 (define_insn "*truncdfsf2_1"
3923 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3924 (float_truncate:SF
3925 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3926 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3927 "TARGET_80387 && !TARGET_SSE2"
3928 {
3929 switch (which_alternative)
3930 {
3931 case 0:
3932 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933 return "fstp%z0\t%y0";
3934 else
3935 return "fst%z0\t%y0";
3936 default:
3937 abort ();
3938 }
3939 }
3940 [(set_attr "type" "fmov,multi,multi,multi")
3941 (set_attr "mode" "SF,SF,SF,SF")])
3942
3943 (define_insn "*truncdfsf2_1_sse"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3945 (float_truncate:SF
3946 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3947 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3948 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3949 {
3950 switch (which_alternative)
3951 {
3952 case 0:
3953 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3954 return "fstp%z0\t%y0";
3955 else
3956 return "fst%z0\t%y0";
3957 case 4:
3958 return "#";
3959 default:
3960 abort ();
3961 }
3962 }
3963 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3964 (set_attr "mode" "SF,SF,SF,SF,DF")])
3965
3966 (define_insn "*truncdfsf2_1_sse_nooverlap"
3967 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3968 (float_truncate:SF
3969 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3970 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3971 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3972 {
3973 switch (which_alternative)
3974 {
3975 case 0:
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3978 else
3979 return "fst%z0\t%y0";
3980 case 4:
3981 return "#";
3982 default:
3983 abort ();
3984 }
3985 }
3986 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3987 (set_attr "mode" "SF,SF,SF,SF,DF")])
3988
3989 (define_insn "*truncdfsf2_2"
3990 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3991 (float_truncate:SF
3992 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3993 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3994 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3995 {
3996 switch (which_alternative)
3997 {
3998 case 0:
3999 case 1:
4000 return "cvtsd2ss\t{%1, %0|%0, %1}";
4001 case 2:
4002 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4003 return "fstp%z0\t%y0";
4004 else
4005 return "fst%z0\t%y0";
4006 default:
4007 abort ();
4008 }
4009 }
4010 [(set_attr "type" "ssecvt,ssecvt,fmov")
4011 (set_attr "athlon_decode" "vector,double,*")
4012 (set_attr "mode" "SF,SF,SF")])
4013
4014 (define_insn "*truncdfsf2_2_nooverlap"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
4016 (float_truncate:SF
4017 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4018 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4019 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4020 {
4021 switch (which_alternative)
4022 {
4023 case 0:
4024 return "#";
4025 case 1:
4026 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4027 return "fstp%z0\t%y0";
4028 else
4029 return "fst%z0\t%y0";
4030 default:
4031 abort ();
4032 }
4033 }
4034 [(set_attr "type" "ssecvt,fmov")
4035 (set_attr "mode" "DF,SF")])
4036
4037 (define_insn "*truncdfsf2_3"
4038 [(set (match_operand:SF 0 "memory_operand" "=m")
4039 (float_truncate:SF
4040 (match_operand:DF 1 "register_operand" "f")))]
4041 "TARGET_80387"
4042 {
4043 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4044 return "fstp%z0\t%y0";
4045 else
4046 return "fst%z0\t%y0";
4047 }
4048 [(set_attr "type" "fmov")
4049 (set_attr "mode" "SF")])
4050
4051 (define_insn "truncdfsf2_sse_only"
4052 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4053 (float_truncate:SF
4054 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4055 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4056 "cvtsd2ss\t{%1, %0|%0, %1}"
4057 [(set_attr "type" "ssecvt")
4058 (set_attr "athlon_decode" "vector,double")
4059 (set_attr "mode" "SF")])
4060
4061 (define_insn "*truncdfsf2_sse_only_nooverlap"
4062 [(set (match_operand:SF 0 "register_operand" "=&Y")
4063 (float_truncate:SF
4064 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4065 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4066 "#"
4067 [(set_attr "type" "ssecvt")
4068 (set_attr "mode" "DF")])
4069
4070 (define_split
4071 [(set (match_operand:SF 0 "memory_operand" "")
4072 (float_truncate:SF
4073 (match_operand:DF 1 "register_operand" "")))
4074 (clobber (match_operand:SF 2 "memory_operand" ""))]
4075 "TARGET_80387"
4076 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4077 "")
4078
4079 ; Avoid possible reformatting penalty on the destination by first
4080 ; zeroing it out
4081 (define_split
4082 [(set (match_operand:SF 0 "register_operand" "")
4083 (float_truncate:SF
4084 (match_operand:DF 1 "nonimmediate_operand" "")))
4085 (clobber (match_operand 2 "" ""))]
4086 "TARGET_80387 && reload_completed
4087 && SSE_REG_P (operands[0])
4088 && !STACK_REG_P (operands[1])"
4089 [(const_int 0)]
4090 {
4091 rtx src, dest;
4092 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4093 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4094 else
4095 {
4096 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4097 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4098 /* simplify_gen_subreg refuses to widen memory references. */
4099 if (GET_CODE (src) == SUBREG)
4100 alter_subreg (&src);
4101 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4102 abort ();
4103 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4104 emit_insn (gen_cvtsd2ss (dest, dest, src));
4105 }
4106 DONE;
4107 })
4108
4109 (define_split
4110 [(set (match_operand:SF 0 "register_operand" "")
4111 (float_truncate:SF
4112 (match_operand:DF 1 "nonimmediate_operand" "")))]
4113 "TARGET_80387 && reload_completed
4114 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4115 [(const_int 0)]
4116 {
4117 rtx src, dest;
4118 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4119 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4120 /* simplify_gen_subreg refuses to widen memory references. */
4121 if (GET_CODE (src) == SUBREG)
4122 alter_subreg (&src);
4123 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4124 abort ();
4125 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4126 emit_insn (gen_cvtsd2ss (dest, dest, src));
4127 DONE;
4128 })
4129
4130 (define_split
4131 [(set (match_operand:SF 0 "register_operand" "")
4132 (float_truncate:SF
4133 (match_operand:DF 1 "fp_register_operand" "")))
4134 (clobber (match_operand:SF 2 "memory_operand" ""))]
4135 "TARGET_80387 && reload_completed"
4136 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4137 (set (match_dup 0) (match_dup 2))]
4138 "")
4139
4140 (define_expand "truncxfsf2"
4141 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4142 (float_truncate:SF
4143 (match_operand:XF 1 "register_operand" "")))
4144 (clobber (match_dup 2))])]
4145 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4146 "operands[2] = assign_386_stack_local (SFmode, 0);")
4147
4148 (define_insn "*truncxfsf2_1"
4149 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4150 (float_truncate:SF
4151 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4152 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4153 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4154 {
4155 switch (which_alternative)
4156 {
4157 case 0:
4158 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4159 return "fstp%z0\t%y0";
4160 else
4161 return "fst%z0\t%y0";
4162 default:
4163 abort();
4164 }
4165 }
4166 [(set_attr "type" "fmov,multi,multi,multi")
4167 (set_attr "mode" "SF")])
4168
4169 (define_insn "*truncxfsf2_2"
4170 [(set (match_operand:SF 0 "memory_operand" "=m")
4171 (float_truncate:SF
4172 (match_operand:XF 1 "register_operand" "f")))]
4173 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4174 {
4175 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4176 return "fstp%z0\t%y0";
4177 else
4178 return "fst%z0\t%y0";
4179 }
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "SF")])
4182
4183 (define_split
4184 [(set (match_operand:SF 0 "memory_operand" "")
4185 (float_truncate:SF
4186 (match_operand:XF 1 "register_operand" "")))
4187 (clobber (match_operand:SF 2 "memory_operand" ""))]
4188 "TARGET_80387"
4189 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4190 "")
4191
4192 (define_split
4193 [(set (match_operand:SF 0 "register_operand" "")
4194 (float_truncate:SF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_operand:SF 2 "memory_operand" ""))]
4197 "TARGET_80387 && reload_completed"
4198 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4199 (set (match_dup 0) (match_dup 2))]
4200 "")
4201
4202 (define_expand "trunctfsf2"
4203 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4204 (float_truncate:SF
4205 (match_operand:TF 1 "register_operand" "")))
4206 (clobber (match_dup 2))])]
4207 "TARGET_80387"
4208 "operands[2] = assign_386_stack_local (SFmode, 0);")
4209
4210 (define_insn "*trunctfsf2_1"
4211 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4212 (float_truncate:SF
4213 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4214 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4215 "TARGET_80387"
4216 {
4217 switch (which_alternative)
4218 {
4219 case 0:
4220 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4221 return "fstp%z0\t%y0";
4222 else
4223 return "fst%z0\t%y0";
4224 default:
4225 abort();
4226 }
4227 }
4228 [(set_attr "type" "fmov,multi,multi,multi")
4229 (set_attr "mode" "SF")])
4230
4231 (define_insn "*trunctfsf2_2"
4232 [(set (match_operand:SF 0 "memory_operand" "=m")
4233 (float_truncate:SF
4234 (match_operand:TF 1 "register_operand" "f")))]
4235 "TARGET_80387"
4236 {
4237 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4238 return "fstp%z0\t%y0";
4239 else
4240 return "fst%z0\t%y0";
4241 }
4242 [(set_attr "type" "fmov")
4243 (set_attr "mode" "SF")])
4244
4245 (define_split
4246 [(set (match_operand:SF 0 "memory_operand" "")
4247 (float_truncate:SF
4248 (match_operand:TF 1 "register_operand" "")))
4249 (clobber (match_operand:SF 2 "memory_operand" ""))]
4250 "TARGET_80387"
4251 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4252 "")
4253
4254 (define_split
4255 [(set (match_operand:SF 0 "register_operand" "")
4256 (float_truncate:SF
4257 (match_operand:TF 1 "register_operand" "")))
4258 (clobber (match_operand:SF 2 "memory_operand" ""))]
4259 "TARGET_80387 && reload_completed"
4260 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4261 (set (match_dup 0) (match_dup 2))]
4262 "")
4263
4264
4265 (define_expand "truncxfdf2"
4266 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4267 (float_truncate:DF
4268 (match_operand:XF 1 "register_operand" "")))
4269 (clobber (match_dup 2))])]
4270 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4271 "operands[2] = assign_386_stack_local (DFmode, 0);")
4272
4273 (define_insn "*truncxfdf2_1"
4274 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4275 (float_truncate:DF
4276 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4277 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4278 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4279 {
4280 switch (which_alternative)
4281 {
4282 case 0:
4283 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4284 return "fstp%z0\t%y0";
4285 else
4286 return "fst%z0\t%y0";
4287 default:
4288 abort();
4289 }
4290 abort ();
4291 }
4292 [(set_attr "type" "fmov,multi,multi,multi")
4293 (set_attr "mode" "DF")])
4294
4295 (define_insn "*truncxfdf2_2"
4296 [(set (match_operand:DF 0 "memory_operand" "=m")
4297 (float_truncate:DF
4298 (match_operand:XF 1 "register_operand" "f")))]
4299 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4300 {
4301 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4302 return "fstp%z0\t%y0";
4303 else
4304 return "fst%z0\t%y0";
4305 }
4306 [(set_attr "type" "fmov")
4307 (set_attr "mode" "DF")])
4308
4309 (define_split
4310 [(set (match_operand:DF 0 "memory_operand" "")
4311 (float_truncate:DF
4312 (match_operand:XF 1 "register_operand" "")))
4313 (clobber (match_operand:DF 2 "memory_operand" ""))]
4314 "TARGET_80387"
4315 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4316 "")
4317
4318 (define_split
4319 [(set (match_operand:DF 0 "register_operand" "")
4320 (float_truncate:DF
4321 (match_operand:XF 1 "register_operand" "")))
4322 (clobber (match_operand:DF 2 "memory_operand" ""))]
4323 "TARGET_80387 && reload_completed"
4324 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4325 (set (match_dup 0) (match_dup 2))]
4326 "")
4327
4328 (define_expand "trunctfdf2"
4329 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4330 (float_truncate:DF
4331 (match_operand:TF 1 "register_operand" "")))
4332 (clobber (match_dup 2))])]
4333 "TARGET_80387"
4334 "operands[2] = assign_386_stack_local (DFmode, 0);")
4335
4336 (define_insn "*trunctfdf2_1"
4337 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4338 (float_truncate:DF
4339 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4340 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4341 "TARGET_80387"
4342 {
4343 switch (which_alternative)
4344 {
4345 case 0:
4346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4347 return "fstp%z0\t%y0";
4348 else
4349 return "fst%z0\t%y0";
4350 default:
4351 abort();
4352 }
4353 abort ();
4354 }
4355 [(set_attr "type" "fmov,multi,multi,multi")
4356 (set_attr "mode" "DF")])
4357
4358 (define_insn "*trunctfdf2_2"
4359 [(set (match_operand:DF 0 "memory_operand" "=m")
4360 (float_truncate:DF
4361 (match_operand:TF 1 "register_operand" "f")))]
4362 "TARGET_80387"
4363 {
4364 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4365 return "fstp%z0\t%y0";
4366 else
4367 return "fst%z0\t%y0";
4368 }
4369 [(set_attr "type" "fmov")
4370 (set_attr "mode" "DF")])
4371
4372 (define_split
4373 [(set (match_operand:DF 0 "memory_operand" "")
4374 (float_truncate:DF
4375 (match_operand:TF 1 "register_operand" "")))
4376 (clobber (match_operand:DF 2 "memory_operand" ""))]
4377 "TARGET_80387"
4378 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4379 "")
4380
4381 (define_split
4382 [(set (match_operand:DF 0 "register_operand" "")
4383 (float_truncate:DF
4384 (match_operand:TF 1 "register_operand" "")))
4385 (clobber (match_operand:DF 2 "memory_operand" ""))]
4386 "TARGET_80387 && reload_completed"
4387 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4388 (set (match_dup 0) (match_dup 2))]
4389 "")
4390
4391 \f
4392 ;; %%% Break up all these bad boys.
4393
4394 ;; Signed conversion to DImode.
4395
4396 (define_expand "fix_truncxfdi2"
4397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4398 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4399 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4400 "")
4401
4402 (define_expand "fix_trunctfdi2"
4403 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4404 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4405 "TARGET_80387"
4406 "")
4407
4408 (define_expand "fix_truncdfdi2"
4409 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4410 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4411 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4412 {
4413 if (TARGET_64BIT && TARGET_SSE2)
4414 {
4415 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4416 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4417 if (out != operands[0])
4418 emit_move_insn (operands[0], out);
4419 DONE;
4420 }
4421 })
4422
4423 (define_expand "fix_truncsfdi2"
4424 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4425 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4426 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4427 {
4428 if (TARGET_SSE && TARGET_64BIT)
4429 {
4430 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4431 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4432 if (out != operands[0])
4433 emit_move_insn (operands[0], out);
4434 DONE;
4435 }
4436 })
4437
4438 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4439 ;; of the machinery.
4440 (define_insn_and_split "*fix_truncdi_1"
4441 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4442 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4443 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !reload_completed && !reload_in_progress
4445 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4446 "#"
4447 "&& 1"
4448 [(const_int 0)]
4449 {
4450 ix86_optimize_mode_switching = 1;
4451 operands[2] = assign_386_stack_local (HImode, 1);
4452 operands[3] = assign_386_stack_local (HImode, 2);
4453 if (memory_operand (operands[0], VOIDmode))
4454 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4455 operands[2], operands[3]));
4456 else
4457 {
4458 operands[4] = assign_386_stack_local (DImode, 0);
4459 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4460 operands[2], operands[3],
4461 operands[4]));
4462 }
4463 DONE;
4464 }
4465 [(set_attr "type" "fistp")
4466 (set_attr "mode" "DI")])
4467
4468 (define_insn "fix_truncdi_nomemory"
4469 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4470 (fix:DI (match_operand 1 "register_operand" "f,f")))
4471 (use (match_operand:HI 2 "memory_operand" "m,m"))
4472 (use (match_operand:HI 3 "memory_operand" "m,m"))
4473 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4474 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4475 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4476 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4477 "#"
4478 [(set_attr "type" "fistp")
4479 (set_attr "mode" "DI")])
4480
4481 (define_insn "fix_truncdi_memory"
4482 [(set (match_operand:DI 0 "memory_operand" "=m")
4483 (fix:DI (match_operand 1 "register_operand" "f")))
4484 (use (match_operand:HI 2 "memory_operand" "m"))
4485 (use (match_operand:HI 3 "memory_operand" "m"))
4486 (clobber (match_scratch:DF 4 "=&1f"))]
4487 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4489 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4490 [(set_attr "type" "fistp")
4491 (set_attr "mode" "DI")])
4492
4493 (define_split
4494 [(set (match_operand:DI 0 "register_operand" "")
4495 (fix:DI (match_operand 1 "register_operand" "")))
4496 (use (match_operand:HI 2 "memory_operand" ""))
4497 (use (match_operand:HI 3 "memory_operand" ""))
4498 (clobber (match_operand:DI 4 "memory_operand" ""))
4499 (clobber (match_scratch 5 ""))]
4500 "reload_completed"
4501 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4502 (use (match_dup 2))
4503 (use (match_dup 3))
4504 (clobber (match_dup 5))])
4505 (set (match_dup 0) (match_dup 4))]
4506 "")
4507
4508 (define_split
4509 [(set (match_operand:DI 0 "memory_operand" "")
4510 (fix:DI (match_operand 1 "register_operand" "")))
4511 (use (match_operand:HI 2 "memory_operand" ""))
4512 (use (match_operand:HI 3 "memory_operand" ""))
4513 (clobber (match_operand:DI 4 "memory_operand" ""))
4514 (clobber (match_scratch 5 ""))]
4515 "reload_completed"
4516 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4517 (use (match_dup 2))
4518 (use (match_dup 3))
4519 (clobber (match_dup 5))])]
4520 "")
4521
4522 ;; When SSE available, it is always faster to use it!
4523 (define_insn "fix_truncsfdi_sse"
4524 [(set (match_operand:DI 0 "register_operand" "=r,r")
4525 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4526 "TARGET_64BIT && TARGET_SSE"
4527 "cvttss2si{q}\t{%1, %0|%0, %1}"
4528 [(set_attr "type" "sseicvt")
4529 (set_attr "mode" "SF")
4530 (set_attr "athlon_decode" "double,vector")])
4531
4532 ;; Avoid vector decoded form of the instruction.
4533 (define_peephole2
4534 [(match_scratch:SF 2 "x")
4535 (set (match_operand:DI 0 "register_operand" "")
4536 (fix:DI (match_operand:SF 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 (define_insn "fix_truncdfdi_sse"
4543 [(set (match_operand:DI 0 "register_operand" "=r,r")
4544 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4545 "TARGET_64BIT && TARGET_SSE2"
4546 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4547 [(set_attr "type" "sseicvt,sseicvt")
4548 (set_attr "mode" "DF")
4549 (set_attr "athlon_decode" "double,vector")])
4550
4551 ;; Avoid vector decoded form of the instruction.
4552 (define_peephole2
4553 [(match_scratch:DF 2 "Y")
4554 (set (match_operand:DI 0 "register_operand" "")
4555 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4556 "TARGET_K8 && !optimize_size"
4557 [(set (match_dup 2) (match_dup 1))
4558 (set (match_dup 0) (fix:DI (match_dup 2)))]
4559 "")
4560
4561 ;; Signed conversion to SImode.
4562
4563 (define_expand "fix_truncxfsi2"
4564 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4565 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4566 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4567 "")
4568
4569 (define_expand "fix_trunctfsi2"
4570 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4571 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4572 "TARGET_80387"
4573 "")
4574
4575 (define_expand "fix_truncdfsi2"
4576 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4577 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4578 "TARGET_80387 || TARGET_SSE2"
4579 {
4580 if (TARGET_SSE2)
4581 {
4582 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4583 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4584 if (out != operands[0])
4585 emit_move_insn (operands[0], out);
4586 DONE;
4587 }
4588 })
4589
4590 (define_expand "fix_truncsfsi2"
4591 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4592 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4593 "TARGET_80387 || TARGET_SSE"
4594 {
4595 if (TARGET_SSE)
4596 {
4597 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4598 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4599 if (out != operands[0])
4600 emit_move_insn (operands[0], out);
4601 DONE;
4602 }
4603 })
4604
4605 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4606 ;; of the machinery.
4607 (define_insn_and_split "*fix_truncsi_1"
4608 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4609 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4610 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4611 && !reload_completed && !reload_in_progress
4612 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4613 "#"
4614 "&& 1"
4615 [(const_int 0)]
4616 {
4617 ix86_optimize_mode_switching = 1;
4618 operands[2] = assign_386_stack_local (HImode, 1);
4619 operands[3] = assign_386_stack_local (HImode, 2);
4620 if (memory_operand (operands[0], VOIDmode))
4621 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4622 operands[2], operands[3]));
4623 else
4624 {
4625 operands[4] = assign_386_stack_local (SImode, 0);
4626 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4627 operands[2], operands[3],
4628 operands[4]));
4629 }
4630 DONE;
4631 }
4632 [(set_attr "type" "fistp")
4633 (set_attr "mode" "SI")])
4634
4635 (define_insn "fix_truncsi_nomemory"
4636 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4637 (fix:SI (match_operand 1 "register_operand" "f,f")))
4638 (use (match_operand:HI 2 "memory_operand" "m,m"))
4639 (use (match_operand:HI 3 "memory_operand" "m,m"))
4640 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4641 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4642 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4643 "#"
4644 [(set_attr "type" "fistp")
4645 (set_attr "mode" "SI")])
4646
4647 (define_insn "fix_truncsi_memory"
4648 [(set (match_operand:SI 0 "memory_operand" "=m")
4649 (fix:SI (match_operand 1 "register_operand" "f")))
4650 (use (match_operand:HI 2 "memory_operand" "m"))
4651 (use (match_operand:HI 3 "memory_operand" "m"))]
4652 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4653 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654 "* return output_fix_trunc (insn, operands);"
4655 [(set_attr "type" "fistp")
4656 (set_attr "mode" "SI")])
4657
4658 ;; When SSE available, it is always faster to use it!
4659 (define_insn "fix_truncsfsi_sse"
4660 [(set (match_operand:SI 0 "register_operand" "=r,r")
4661 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4662 "TARGET_SSE"
4663 "cvttss2si\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:SF 2 "x")
4671 (set (match_operand:SI 0 "register_operand" "")
4672 (fix:SI (match_operand:SF 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_insn "fix_truncdfsi_sse"
4679 [(set (match_operand:SI 0 "register_operand" "=r,r")
4680 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4681 "TARGET_SSE2"
4682 "cvttsd2si\t{%1, %0|%0, %1}"
4683 [(set_attr "type" "sseicvt")
4684 (set_attr "mode" "DF")
4685 (set_attr "athlon_decode" "double,vector")])
4686
4687 ;; Avoid vector decoded form of the instruction.
4688 (define_peephole2
4689 [(match_scratch:DF 2 "Y")
4690 (set (match_operand:SI 0 "register_operand" "")
4691 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4692 "TARGET_K8 && !optimize_size"
4693 [(set (match_dup 2) (match_dup 1))
4694 (set (match_dup 0) (fix:SI (match_dup 2)))]
4695 "")
4696
4697 (define_split
4698 [(set (match_operand:SI 0 "register_operand" "")
4699 (fix:SI (match_operand 1 "register_operand" "")))
4700 (use (match_operand:HI 2 "memory_operand" ""))
4701 (use (match_operand:HI 3 "memory_operand" ""))
4702 (clobber (match_operand:SI 4 "memory_operand" ""))]
4703 "reload_completed"
4704 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4705 (use (match_dup 2))
4706 (use (match_dup 3))])
4707 (set (match_dup 0) (match_dup 4))]
4708 "")
4709
4710 (define_split
4711 [(set (match_operand:SI 0 "memory_operand" "")
4712 (fix:SI (match_operand 1 "register_operand" "")))
4713 (use (match_operand:HI 2 "memory_operand" ""))
4714 (use (match_operand:HI 3 "memory_operand" ""))
4715 (clobber (match_operand:SI 4 "memory_operand" ""))]
4716 "reload_completed"
4717 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4718 (use (match_dup 2))
4719 (use (match_dup 3))])]
4720 "")
4721
4722 ;; Signed conversion to HImode.
4723
4724 (define_expand "fix_truncxfhi2"
4725 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4726 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4727 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4728 "")
4729
4730 (define_expand "fix_trunctfhi2"
4731 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4732 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4733 "TARGET_80387"
4734 "")
4735
4736 (define_expand "fix_truncdfhi2"
4737 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4738 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4739 "TARGET_80387 && !TARGET_SSE2"
4740 "")
4741
4742 (define_expand "fix_truncsfhi2"
4743 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4744 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4745 "TARGET_80387 && !TARGET_SSE"
4746 "")
4747
4748 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4749 ;; of the machinery.
4750 (define_insn_and_split "*fix_trunchi_1"
4751 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4752 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4753 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4754 && !reload_completed && !reload_in_progress
4755 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4756 "#"
4757 ""
4758 [(const_int 0)]
4759 {
4760 ix86_optimize_mode_switching = 1;
4761 operands[2] = assign_386_stack_local (HImode, 1);
4762 operands[3] = assign_386_stack_local (HImode, 2);
4763 if (memory_operand (operands[0], VOIDmode))
4764 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4765 operands[2], operands[3]));
4766 else
4767 {
4768 operands[4] = assign_386_stack_local (HImode, 0);
4769 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4770 operands[2], operands[3],
4771 operands[4]));
4772 }
4773 DONE;
4774 }
4775 [(set_attr "type" "fistp")
4776 (set_attr "mode" "HI")])
4777
4778 (define_insn "fix_trunchi_nomemory"
4779 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4780 (fix:HI (match_operand 1 "register_operand" "f,f")))
4781 (use (match_operand:HI 2 "memory_operand" "m,m"))
4782 (use (match_operand:HI 3 "memory_operand" "m,m"))
4783 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4784 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4785 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4786 "#"
4787 [(set_attr "type" "fistp")
4788 (set_attr "mode" "HI")])
4789
4790 (define_insn "fix_trunchi_memory"
4791 [(set (match_operand:HI 0 "memory_operand" "=m")
4792 (fix:HI (match_operand 1 "register_operand" "f")))
4793 (use (match_operand:HI 2 "memory_operand" "m"))
4794 (use (match_operand:HI 3 "memory_operand" "m"))]
4795 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4796 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4797 "* return output_fix_trunc (insn, operands);"
4798 [(set_attr "type" "fistp")
4799 (set_attr "mode" "HI")])
4800
4801 (define_split
4802 [(set (match_operand:HI 0 "memory_operand" "")
4803 (fix:HI (match_operand 1 "register_operand" "")))
4804 (use (match_operand:HI 2 "memory_operand" ""))
4805 (use (match_operand:HI 3 "memory_operand" ""))
4806 (clobber (match_operand:HI 4 "memory_operand" ""))]
4807 "reload_completed"
4808 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4809 (use (match_dup 2))
4810 (use (match_dup 3))])]
4811 "")
4812
4813 (define_split
4814 [(set (match_operand:HI 0 "register_operand" "")
4815 (fix:HI (match_operand 1 "register_operand" "")))
4816 (use (match_operand:HI 2 "memory_operand" ""))
4817 (use (match_operand:HI 3 "memory_operand" ""))
4818 (clobber (match_operand:HI 4 "memory_operand" ""))]
4819 "reload_completed"
4820 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4821 (use (match_dup 2))
4822 (use (match_dup 3))
4823 (clobber (match_dup 4))])
4824 (set (match_dup 0) (match_dup 4))]
4825 "")
4826
4827 ;; %% Not used yet.
4828 (define_insn "x86_fnstcw_1"
4829 [(set (match_operand:HI 0 "memory_operand" "=m")
4830 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4831 "TARGET_80387"
4832 "fnstcw\t%0"
4833 [(set_attr "length" "2")
4834 (set_attr "mode" "HI")
4835 (set_attr "unit" "i387")
4836 (set_attr "ppro_uops" "few")])
4837
4838 (define_insn "x86_fldcw_1"
4839 [(set (reg:HI 18)
4840 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4841 "TARGET_80387"
4842 "fldcw\t%0"
4843 [(set_attr "length" "2")
4844 (set_attr "mode" "HI")
4845 (set_attr "unit" "i387")
4846 (set_attr "athlon_decode" "vector")
4847 (set_attr "ppro_uops" "few")])
4848 \f
4849 ;; Conversion between fixed point and floating point.
4850
4851 ;; Even though we only accept memory inputs, the backend _really_
4852 ;; wants to be able to do this between registers.
4853
4854 (define_expand "floathisf2"
4855 [(set (match_operand:SF 0 "register_operand" "")
4856 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4857 "TARGET_SSE || TARGET_80387"
4858 {
4859 if (TARGET_SSE && TARGET_SSE_MATH)
4860 {
4861 emit_insn (gen_floatsisf2 (operands[0],
4862 convert_to_mode (SImode, operands[1], 0)));
4863 DONE;
4864 }
4865 })
4866
4867 (define_insn "*floathisf2_1"
4868 [(set (match_operand:SF 0 "register_operand" "=f,f")
4869 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4870 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4871 "@
4872 fild%z1\t%1
4873 #"
4874 [(set_attr "type" "fmov,multi")
4875 (set_attr "mode" "SF")
4876 (set_attr "fp_int_src" "true")])
4877
4878 (define_expand "floatsisf2"
4879 [(set (match_operand:SF 0 "register_operand" "")
4880 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4881 "TARGET_SSE || TARGET_80387"
4882 "")
4883
4884 (define_insn "*floatsisf2_i387"
4885 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4886 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4887 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4888 "@
4889 fild%z1\t%1
4890 #
4891 cvtsi2ss\t{%1, %0|%0, %1}
4892 cvtsi2ss\t{%1, %0|%0, %1}"
4893 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4894 (set_attr "mode" "SF")
4895 (set_attr "athlon_decode" "*,*,vector,double")
4896 (set_attr "fp_int_src" "true")])
4897
4898 (define_insn "*floatsisf2_sse"
4899 [(set (match_operand:SF 0 "register_operand" "=x,x")
4900 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4901 "TARGET_SSE"
4902 "cvtsi2ss\t{%1, %0|%0, %1}"
4903 [(set_attr "type" "sseicvt")
4904 (set_attr "mode" "SF")
4905 (set_attr "athlon_decode" "vector,double")
4906 (set_attr "fp_int_src" "true")])
4907
4908 ; Avoid possible reformatting penalty on the destination by first
4909 ; zeroing it out
4910 (define_split
4911 [(set (match_operand:SF 0 "register_operand" "")
4912 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4913 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4914 && SSE_REG_P (operands[0])"
4915 [(const_int 0)]
4916 {
4917 rtx dest;
4918 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4919 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4920 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4921 DONE;
4922 })
4923
4924 (define_expand "floatdisf2"
4925 [(set (match_operand:SF 0 "register_operand" "")
4926 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4927 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4928 "")
4929
4930 (define_insn "*floatdisf2_i387_only"
4931 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4932 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4933 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4934 "@
4935 fild%z1\t%1
4936 #"
4937 [(set_attr "type" "fmov,multi")
4938 (set_attr "mode" "SF")
4939 (set_attr "fp_int_src" "true")])
4940
4941 (define_insn "*floatdisf2_i387"
4942 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4943 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4944 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4945 "@
4946 fild%z1\t%1
4947 #
4948 cvtsi2ss{q}\t{%1, %0|%0, %1}
4949 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4950 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4951 (set_attr "mode" "SF")
4952 (set_attr "athlon_decode" "*,*,vector,double")
4953 (set_attr "fp_int_src" "true")])
4954
4955 (define_insn "*floatdisf2_sse"
4956 [(set (match_operand:SF 0 "register_operand" "=x,x")
4957 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4958 "TARGET_64BIT && TARGET_SSE"
4959 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4960 [(set_attr "type" "sseicvt")
4961 (set_attr "mode" "SF")
4962 (set_attr "athlon_decode" "vector,double")
4963 (set_attr "fp_int_src" "true")])
4964
4965 ; Avoid possible reformatting penalty on the destination by first
4966 ; zeroing it out
4967 (define_split
4968 [(set (match_operand:SF 0 "register_operand" "")
4969 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4970 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4971 && SSE_REG_P (operands[0])"
4972 [(const_int 0)]
4973 {
4974 rtx dest;
4975 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4976 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4977 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4978 DONE;
4979 })
4980
4981 (define_expand "floathidf2"
4982 [(set (match_operand:DF 0 "register_operand" "")
4983 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4984 "TARGET_SSE2 || TARGET_80387"
4985 {
4986 if (TARGET_SSE && TARGET_SSE_MATH)
4987 {
4988 emit_insn (gen_floatsidf2 (operands[0],
4989 convert_to_mode (SImode, operands[1], 0)));
4990 DONE;
4991 }
4992 })
4993
4994 (define_insn "*floathidf2_1"
4995 [(set (match_operand:DF 0 "register_operand" "=f,f")
4996 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4997 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4998 "@
4999 fild%z1\t%1
5000 #"
5001 [(set_attr "type" "fmov,multi")
5002 (set_attr "mode" "DF")
5003 (set_attr "fp_int_src" "true")])
5004
5005 (define_expand "floatsidf2"
5006 [(set (match_operand:DF 0 "register_operand" "")
5007 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5008 "TARGET_80387 || TARGET_SSE2"
5009 "")
5010
5011 (define_insn "*floatsidf2_i387"
5012 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5013 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
5014 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5015 "@
5016 fild%z1\t%1
5017 #
5018 cvtsi2sd\t{%1, %0|%0, %1}
5019 cvtsi2sd\t{%1, %0|%0, %1}"
5020 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5021 (set_attr "mode" "DF")
5022 (set_attr "athlon_decode" "*,*,double,direct")
5023 (set_attr "fp_int_src" "true")])
5024
5025 (define_insn "*floatsidf2_sse"
5026 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5027 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
5028 "TARGET_SSE2"
5029 "cvtsi2sd\t{%1, %0|%0, %1}"
5030 [(set_attr "type" "sseicvt")
5031 (set_attr "mode" "DF")
5032 (set_attr "athlon_decode" "double,direct")
5033 (set_attr "fp_int_src" "true")])
5034
5035 (define_expand "floatdidf2"
5036 [(set (match_operand:DF 0 "register_operand" "")
5037 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5038 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5039 "")
5040
5041 (define_insn "*floatdidf2_i387_only"
5042 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5043 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5044 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5045 "@
5046 fild%z1\t%1
5047 #"
5048 [(set_attr "type" "fmov,multi")
5049 (set_attr "mode" "DF")
5050 (set_attr "fp_int_src" "true")])
5051
5052 (define_insn "*floatdidf2_i387"
5053 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5054 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5055 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5056 "@
5057 fild%z1\t%1
5058 #
5059 cvtsi2sd{q}\t{%1, %0|%0, %1}
5060 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5061 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5062 (set_attr "mode" "DF")
5063 (set_attr "athlon_decode" "*,*,double,direct")
5064 (set_attr "fp_int_src" "true")])
5065
5066 (define_insn "*floatdidf2_sse"
5067 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5068 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5069 "TARGET_SSE2"
5070 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5071 [(set_attr "type" "sseicvt")
5072 (set_attr "mode" "DF")
5073 (set_attr "athlon_decode" "double,direct")
5074 (set_attr "fp_int_src" "true")])
5075
5076 (define_insn "floathixf2"
5077 [(set (match_operand:XF 0 "register_operand" "=f,f")
5078 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5079 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5080 "@
5081 fild%z1\t%1
5082 #"
5083 [(set_attr "type" "fmov,multi")
5084 (set_attr "mode" "XF")
5085 (set_attr "fp_int_src" "true")])
5086
5087 (define_insn "floathitf2"
5088 [(set (match_operand:TF 0 "register_operand" "=f,f")
5089 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5090 "TARGET_80387"
5091 "@
5092 fild%z1\t%1
5093 #"
5094 [(set_attr "type" "fmov,multi")
5095 (set_attr "mode" "XF")
5096 (set_attr "fp_int_src" "true")])
5097
5098 (define_insn "floatsixf2"
5099 [(set (match_operand:XF 0 "register_operand" "=f,f")
5100 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5101 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5102 "@
5103 fild%z1\t%1
5104 #"
5105 [(set_attr "type" "fmov,multi")
5106 (set_attr "mode" "XF")
5107 (set_attr "fp_int_src" "true")])
5108
5109 (define_insn "floatsitf2"
5110 [(set (match_operand:TF 0 "register_operand" "=f,f")
5111 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5112 "TARGET_80387"
5113 "@
5114 fild%z1\t%1
5115 #"
5116 [(set_attr "type" "fmov,multi")
5117 (set_attr "mode" "XF")
5118 (set_attr "fp_int_src" "true")])
5119
5120 (define_insn "floatdixf2"
5121 [(set (match_operand:XF 0 "register_operand" "=f,f")
5122 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5123 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5124 "@
5125 fild%z1\t%1
5126 #"
5127 [(set_attr "type" "fmov,multi")
5128 (set_attr "mode" "XF")
5129 (set_attr "fp_int_src" "true")])
5130
5131 (define_insn "floatditf2"
5132 [(set (match_operand:TF 0 "register_operand" "=f,f")
5133 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5134 "TARGET_80387"
5135 "@
5136 fild%z1\t%1
5137 #"
5138 [(set_attr "type" "fmov,multi")
5139 (set_attr "mode" "XF")
5140 (set_attr "fp_int_src" "true")])
5141
5142 ;; %%% Kill these when reload knows how to do it.
5143 (define_split
5144 [(set (match_operand 0 "fp_register_operand" "")
5145 (float (match_operand 1 "register_operand" "")))]
5146 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5147 [(const_int 0)]
5148 {
5149 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5150 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5151 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5152 ix86_free_from_memory (GET_MODE (operands[1]));
5153 DONE;
5154 })
5155
5156 (define_expand "floatunssisf2"
5157 [(use (match_operand:SF 0 "register_operand" ""))
5158 (use (match_operand:SI 1 "register_operand" ""))]
5159 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5160 "x86_emit_floatuns (operands); DONE;")
5161
5162 (define_expand "floatunsdisf2"
5163 [(use (match_operand:SF 0 "register_operand" ""))
5164 (use (match_operand:DI 1 "register_operand" ""))]
5165 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5166 "x86_emit_floatuns (operands); DONE;")
5167
5168 (define_expand "floatunsdidf2"
5169 [(use (match_operand:DF 0 "register_operand" ""))
5170 (use (match_operand:DI 1 "register_operand" ""))]
5171 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5172 "x86_emit_floatuns (operands); DONE;")
5173 \f
5174 ;; Add instructions
5175
5176 ;; %%% splits for addsidi3
5177 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5178 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5179 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5180
5181 (define_expand "adddi3"
5182 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5183 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5184 (match_operand:DI 2 "x86_64_general_operand" "")))
5185 (clobber (reg:CC 17))]
5186 ""
5187 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5188
5189 (define_insn "*adddi3_1"
5190 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5191 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5192 (match_operand:DI 2 "general_operand" "roiF,riF")))
5193 (clobber (reg:CC 17))]
5194 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5195 "#")
5196
5197 (define_split
5198 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5199 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5200 (match_operand:DI 2 "general_operand" "")))
5201 (clobber (reg:CC 17))]
5202 "!TARGET_64BIT && reload_completed"
5203 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5204 UNSPEC_ADD_CARRY))
5205 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5206 (parallel [(set (match_dup 3)
5207 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5208 (match_dup 4))
5209 (match_dup 5)))
5210 (clobber (reg:CC 17))])]
5211 "split_di (operands+0, 1, operands+0, operands+3);
5212 split_di (operands+1, 1, operands+1, operands+4);
5213 split_di (operands+2, 1, operands+2, operands+5);")
5214
5215 (define_insn "adddi3_carry_rex64"
5216 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5217 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5218 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5219 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5220 (clobber (reg:CC 17))]
5221 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5222 "adc{q}\t{%2, %0|%0, %2}"
5223 [(set_attr "type" "alu")
5224 (set_attr "pent_pair" "pu")
5225 (set_attr "mode" "DI")
5226 (set_attr "ppro_uops" "few")])
5227
5228 (define_insn "*adddi3_cc_rex64"
5229 [(set (reg:CC 17)
5230 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5231 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5232 UNSPEC_ADD_CARRY))
5233 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5234 (plus:DI (match_dup 1) (match_dup 2)))]
5235 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5236 "add{q}\t{%2, %0|%0, %2}"
5237 [(set_attr "type" "alu")
5238 (set_attr "mode" "DI")])
5239
5240 (define_insn "addqi3_carry"
5241 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5242 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5243 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5244 (match_operand:QI 2 "general_operand" "ri,rm")))
5245 (clobber (reg:CC 17))]
5246 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5247 "adc{b}\t{%2, %0|%0, %2}"
5248 [(set_attr "type" "alu")
5249 (set_attr "pent_pair" "pu")
5250 (set_attr "mode" "QI")
5251 (set_attr "ppro_uops" "few")])
5252
5253 (define_insn "addhi3_carry"
5254 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5255 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5256 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5257 (match_operand:HI 2 "general_operand" "ri,rm")))
5258 (clobber (reg:CC 17))]
5259 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5260 "adc{w}\t{%2, %0|%0, %2}"
5261 [(set_attr "type" "alu")
5262 (set_attr "pent_pair" "pu")
5263 (set_attr "mode" "HI")
5264 (set_attr "ppro_uops" "few")])
5265
5266 (define_insn "addsi3_carry"
5267 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5268 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5269 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5270 (match_operand:SI 2 "general_operand" "ri,rm")))
5271 (clobber (reg:CC 17))]
5272 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5273 "adc{l}\t{%2, %0|%0, %2}"
5274 [(set_attr "type" "alu")
5275 (set_attr "pent_pair" "pu")
5276 (set_attr "mode" "SI")
5277 (set_attr "ppro_uops" "few")])
5278
5279 (define_insn "*addsi3_carry_zext"
5280 [(set (match_operand:DI 0 "register_operand" "=r")
5281 (zero_extend:DI
5282 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5283 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5284 (match_operand:SI 2 "general_operand" "rim"))))
5285 (clobber (reg:CC 17))]
5286 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5287 "adc{l}\t{%2, %k0|%k0, %2}"
5288 [(set_attr "type" "alu")
5289 (set_attr "pent_pair" "pu")
5290 (set_attr "mode" "SI")
5291 (set_attr "ppro_uops" "few")])
5292
5293 (define_insn "*addsi3_cc"
5294 [(set (reg:CC 17)
5295 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5296 (match_operand:SI 2 "general_operand" "ri,rm")]
5297 UNSPEC_ADD_CARRY))
5298 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5299 (plus:SI (match_dup 1) (match_dup 2)))]
5300 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5301 "add{l}\t{%2, %0|%0, %2}"
5302 [(set_attr "type" "alu")
5303 (set_attr "mode" "SI")])
5304
5305 (define_insn "addqi3_cc"
5306 [(set (reg:CC 17)
5307 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5308 (match_operand:QI 2 "general_operand" "qi,qm")]
5309 UNSPEC_ADD_CARRY))
5310 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5311 (plus:QI (match_dup 1) (match_dup 2)))]
5312 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5313 "add{b}\t{%2, %0|%0, %2}"
5314 [(set_attr "type" "alu")
5315 (set_attr "mode" "QI")])
5316
5317 (define_expand "addsi3"
5318 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5319 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5320 (match_operand:SI 2 "general_operand" "")))
5321 (clobber (reg:CC 17))])]
5322 ""
5323 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5324
5325 (define_insn "*lea_1"
5326 [(set (match_operand:SI 0 "register_operand" "=r")
5327 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5328 "!TARGET_64BIT"
5329 "lea{l}\t{%a1, %0|%0, %a1}"
5330 [(set_attr "type" "lea")
5331 (set_attr "mode" "SI")])
5332
5333 (define_insn "*lea_1_rex64"
5334 [(set (match_operand:SI 0 "register_operand" "=r")
5335 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5336 "TARGET_64BIT"
5337 "lea{l}\t{%a1, %0|%0, %a1}"
5338 [(set_attr "type" "lea")
5339 (set_attr "mode" "SI")])
5340
5341 (define_insn "*lea_1_zext"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (zero_extend:DI
5344 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5345 "TARGET_64BIT"
5346 "lea{l}\t{%a1, %k0|%k0, %a1}"
5347 [(set_attr "type" "lea")
5348 (set_attr "mode" "SI")])
5349
5350 (define_insn "*lea_2_rex64"
5351 [(set (match_operand:DI 0 "register_operand" "=r")
5352 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5353 "TARGET_64BIT"
5354 "lea{q}\t{%a1, %0|%0, %a1}"
5355 [(set_attr "type" "lea")
5356 (set_attr "mode" "DI")])
5357
5358 ;; The lea patterns for non-Pmodes needs to be matched by several
5359 ;; insns converted to real lea by splitters.
5360
5361 (define_insn_and_split "*lea_general_1"
5362 [(set (match_operand 0 "register_operand" "=r")
5363 (plus (plus (match_operand 1 "index_register_operand" "r")
5364 (match_operand 2 "register_operand" "r"))
5365 (match_operand 3 "immediate_operand" "i")))]
5366 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5367 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5368 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5369 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5370 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5371 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5372 || GET_MODE (operands[3]) == VOIDmode)"
5373 "#"
5374 "&& reload_completed"
5375 [(const_int 0)]
5376 {
5377 rtx pat;
5378 operands[0] = gen_lowpart (SImode, operands[0]);
5379 operands[1] = gen_lowpart (Pmode, operands[1]);
5380 operands[2] = gen_lowpart (Pmode, operands[2]);
5381 operands[3] = gen_lowpart (Pmode, operands[3]);
5382 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5383 operands[3]);
5384 if (Pmode != SImode)
5385 pat = gen_rtx_SUBREG (SImode, pat, 0);
5386 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5387 DONE;
5388 }
5389 [(set_attr "type" "lea")
5390 (set_attr "mode" "SI")])
5391
5392 (define_insn_and_split "*lea_general_1_zext"
5393 [(set (match_operand:DI 0 "register_operand" "=r")
5394 (zero_extend:DI
5395 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5396 (match_operand:SI 2 "register_operand" "r"))
5397 (match_operand:SI 3 "immediate_operand" "i"))))]
5398 "TARGET_64BIT"
5399 "#"
5400 "&& reload_completed"
5401 [(set (match_dup 0)
5402 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5403 (match_dup 2))
5404 (match_dup 3)) 0)))]
5405 {
5406 operands[1] = gen_lowpart (Pmode, operands[1]);
5407 operands[2] = gen_lowpart (Pmode, operands[2]);
5408 operands[3] = gen_lowpart (Pmode, operands[3]);
5409 }
5410 [(set_attr "type" "lea")
5411 (set_attr "mode" "SI")])
5412
5413 (define_insn_and_split "*lea_general_2"
5414 [(set (match_operand 0 "register_operand" "=r")
5415 (plus (mult (match_operand 1 "index_register_operand" "r")
5416 (match_operand 2 "const248_operand" "i"))
5417 (match_operand 3 "nonmemory_operand" "ri")))]
5418 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5419 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5420 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5421 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5422 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5423 || GET_MODE (operands[3]) == VOIDmode)"
5424 "#"
5425 "&& reload_completed"
5426 [(const_int 0)]
5427 {
5428 rtx pat;
5429 operands[0] = gen_lowpart (SImode, operands[0]);
5430 operands[1] = gen_lowpart (Pmode, operands[1]);
5431 operands[3] = gen_lowpart (Pmode, operands[3]);
5432 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5433 operands[3]);
5434 if (Pmode != SImode)
5435 pat = gen_rtx_SUBREG (SImode, pat, 0);
5436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5437 DONE;
5438 }
5439 [(set_attr "type" "lea")
5440 (set_attr "mode" "SI")])
5441
5442 (define_insn_and_split "*lea_general_2_zext"
5443 [(set (match_operand:DI 0 "register_operand" "=r")
5444 (zero_extend:DI
5445 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5446 (match_operand:SI 2 "const248_operand" "n"))
5447 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5448 "TARGET_64BIT"
5449 "#"
5450 "&& reload_completed"
5451 [(set (match_dup 0)
5452 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5453 (match_dup 2))
5454 (match_dup 3)) 0)))]
5455 {
5456 operands[1] = gen_lowpart (Pmode, operands[1]);
5457 operands[3] = gen_lowpart (Pmode, operands[3]);
5458 }
5459 [(set_attr "type" "lea")
5460 (set_attr "mode" "SI")])
5461
5462 (define_insn_and_split "*lea_general_3"
5463 [(set (match_operand 0 "register_operand" "=r")
5464 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5465 (match_operand 2 "const248_operand" "i"))
5466 (match_operand 3 "register_operand" "r"))
5467 (match_operand 4 "immediate_operand" "i")))]
5468 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5469 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5470 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5471 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5472 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5473 "#"
5474 "&& reload_completed"
5475 [(const_int 0)]
5476 {
5477 rtx pat;
5478 operands[0] = gen_lowpart (SImode, operands[0]);
5479 operands[1] = gen_lowpart (Pmode, operands[1]);
5480 operands[3] = gen_lowpart (Pmode, operands[3]);
5481 operands[4] = gen_lowpart (Pmode, operands[4]);
5482 pat = gen_rtx_PLUS (Pmode,
5483 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5484 operands[2]),
5485 operands[3]),
5486 operands[4]);
5487 if (Pmode != SImode)
5488 pat = gen_rtx_SUBREG (SImode, pat, 0);
5489 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5490 DONE;
5491 }
5492 [(set_attr "type" "lea")
5493 (set_attr "mode" "SI")])
5494
5495 (define_insn_and_split "*lea_general_3_zext"
5496 [(set (match_operand:DI 0 "register_operand" "=r")
5497 (zero_extend:DI
5498 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5499 (match_operand:SI 2 "const248_operand" "n"))
5500 (match_operand:SI 3 "register_operand" "r"))
5501 (match_operand:SI 4 "immediate_operand" "i"))))]
5502 "TARGET_64BIT"
5503 "#"
5504 "&& reload_completed"
5505 [(set (match_dup 0)
5506 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5507 (match_dup 2))
5508 (match_dup 3))
5509 (match_dup 4)) 0)))]
5510 {
5511 operands[1] = gen_lowpart (Pmode, operands[1]);
5512 operands[3] = gen_lowpart (Pmode, operands[3]);
5513 operands[4] = gen_lowpart (Pmode, operands[4]);
5514 }
5515 [(set_attr "type" "lea")
5516 (set_attr "mode" "SI")])
5517
5518 (define_insn "*adddi_1_rex64"
5519 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5520 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5521 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5522 (clobber (reg:CC 17))]
5523 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5524 {
5525 switch (get_attr_type (insn))
5526 {
5527 case TYPE_LEA:
5528 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5529 return "lea{q}\t{%a2, %0|%0, %a2}";
5530
5531 case TYPE_INCDEC:
5532 if (! rtx_equal_p (operands[0], operands[1]))
5533 abort ();
5534 if (operands[2] == const1_rtx)
5535 return "inc{q}\t%0";
5536 else if (operands[2] == constm1_rtx)
5537 return "dec{q}\t%0";
5538 else
5539 abort ();
5540
5541 default:
5542 if (! rtx_equal_p (operands[0], operands[1]))
5543 abort ();
5544
5545 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5547 if (GET_CODE (operands[2]) == CONST_INT
5548 /* Avoid overflows. */
5549 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550 && (INTVAL (operands[2]) == 128
5551 || (INTVAL (operands[2]) < 0
5552 && INTVAL (operands[2]) != -128)))
5553 {
5554 operands[2] = GEN_INT (-INTVAL (operands[2]));
5555 return "sub{q}\t{%2, %0|%0, %2}";
5556 }
5557 return "add{q}\t{%2, %0|%0, %2}";
5558 }
5559 }
5560 [(set (attr "type")
5561 (cond [(eq_attr "alternative" "2")
5562 (const_string "lea")
5563 ; Current assemblers are broken and do not allow @GOTOFF in
5564 ; ought but a memory context.
5565 (match_operand:DI 2 "pic_symbolic_operand" "")
5566 (const_string "lea")
5567 (match_operand:DI 2 "incdec_operand" "")
5568 (const_string "incdec")
5569 ]
5570 (const_string "alu")))
5571 (set_attr "mode" "DI")])
5572
5573 ;; Convert lea to the lea pattern to avoid flags dependency.
5574 (define_split
5575 [(set (match_operand:DI 0 "register_operand" "")
5576 (plus:DI (match_operand:DI 1 "register_operand" "")
5577 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5578 (clobber (reg:CC 17))]
5579 "TARGET_64BIT && reload_completed
5580 && true_regnum (operands[0]) != true_regnum (operands[1])"
5581 [(set (match_dup 0)
5582 (plus:DI (match_dup 1)
5583 (match_dup 2)))]
5584 "")
5585
5586 (define_insn "*adddi_2_rex64"
5587 [(set (reg 17)
5588 (compare
5589 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5590 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5591 (const_int 0)))
5592 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5593 (plus:DI (match_dup 1) (match_dup 2)))]
5594 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5595 && ix86_binary_operator_ok (PLUS, DImode, operands)
5596 /* Current assemblers are broken and do not allow @GOTOFF in
5597 ought but a memory context. */
5598 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5599 {
5600 switch (get_attr_type (insn))
5601 {
5602 case TYPE_INCDEC:
5603 if (! rtx_equal_p (operands[0], operands[1]))
5604 abort ();
5605 if (operands[2] == const1_rtx)
5606 return "inc{q}\t%0";
5607 else if (operands[2] == constm1_rtx)
5608 return "dec{q}\t%0";
5609 else
5610 abort ();
5611
5612 default:
5613 if (! rtx_equal_p (operands[0], operands[1]))
5614 abort ();
5615 /* ???? We ought to handle there the 32bit case too
5616 - do we need new constraint? */
5617 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5618 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5619 if (GET_CODE (operands[2]) == CONST_INT
5620 /* Avoid overflows. */
5621 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5622 && (INTVAL (operands[2]) == 128
5623 || (INTVAL (operands[2]) < 0
5624 && INTVAL (operands[2]) != -128)))
5625 {
5626 operands[2] = GEN_INT (-INTVAL (operands[2]));
5627 return "sub{q}\t{%2, %0|%0, %2}";
5628 }
5629 return "add{q}\t{%2, %0|%0, %2}";
5630 }
5631 }
5632 [(set (attr "type")
5633 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5634 (const_string "incdec")
5635 (const_string "alu")))
5636 (set_attr "mode" "DI")])
5637
5638 (define_insn "*adddi_3_rex64"
5639 [(set (reg 17)
5640 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5641 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5642 (clobber (match_scratch:DI 0 "=r"))]
5643 "TARGET_64BIT
5644 && ix86_match_ccmode (insn, CCZmode)
5645 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5646 /* Current assemblers are broken and do not allow @GOTOFF in
5647 ought but a memory context. */
5648 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5649 {
5650 switch (get_attr_type (insn))
5651 {
5652 case TYPE_INCDEC:
5653 if (! rtx_equal_p (operands[0], operands[1]))
5654 abort ();
5655 if (operands[2] == const1_rtx)
5656 return "inc{q}\t%0";
5657 else if (operands[2] == constm1_rtx)
5658 return "dec{q}\t%0";
5659 else
5660 abort ();
5661
5662 default:
5663 if (! rtx_equal_p (operands[0], operands[1]))
5664 abort ();
5665 /* ???? We ought to handle there the 32bit case too
5666 - do we need new constraint? */
5667 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5668 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5669 if (GET_CODE (operands[2]) == CONST_INT
5670 /* Avoid overflows. */
5671 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5672 && (INTVAL (operands[2]) == 128
5673 || (INTVAL (operands[2]) < 0
5674 && INTVAL (operands[2]) != -128)))
5675 {
5676 operands[2] = GEN_INT (-INTVAL (operands[2]));
5677 return "sub{q}\t{%2, %0|%0, %2}";
5678 }
5679 return "add{q}\t{%2, %0|%0, %2}";
5680 }
5681 }
5682 [(set (attr "type")
5683 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5684 (const_string "incdec")
5685 (const_string "alu")))
5686 (set_attr "mode" "DI")])
5687
5688 ; For comparisons against 1, -1 and 128, we may generate better code
5689 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5690 ; is matched then. We can't accept general immediate, because for
5691 ; case of overflows, the result is messed up.
5692 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5693 ; when negated.
5694 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5695 ; only for comparisons not depending on it.
5696 (define_insn "*adddi_4_rex64"
5697 [(set (reg 17)
5698 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5699 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5700 (clobber (match_scratch:DI 0 "=rm"))]
5701 "TARGET_64BIT
5702 && ix86_match_ccmode (insn, CCGCmode)"
5703 {
5704 switch (get_attr_type (insn))
5705 {
5706 case TYPE_INCDEC:
5707 if (operands[2] == constm1_rtx)
5708 return "inc{q}\t%0";
5709 else if (operands[2] == const1_rtx)
5710 return "dec{q}\t%0";
5711 else
5712 abort();
5713
5714 default:
5715 if (! rtx_equal_p (operands[0], operands[1]))
5716 abort ();
5717 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5718 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5719 if ((INTVAL (operands[2]) == -128
5720 || (INTVAL (operands[2]) > 0
5721 && INTVAL (operands[2]) != 128))
5722 /* Avoid overflows. */
5723 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5724 return "sub{q}\t{%2, %0|%0, %2}";
5725 operands[2] = GEN_INT (-INTVAL (operands[2]));
5726 return "add{q}\t{%2, %0|%0, %2}";
5727 }
5728 }
5729 [(set (attr "type")
5730 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5731 (const_string "incdec")
5732 (const_string "alu")))
5733 (set_attr "mode" "DI")])
5734
5735 (define_insn "*adddi_5_rex64"
5736 [(set (reg 17)
5737 (compare
5738 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5739 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5740 (const_int 0)))
5741 (clobber (match_scratch:DI 0 "=r"))]
5742 "TARGET_64BIT
5743 && ix86_match_ccmode (insn, CCGOCmode)
5744 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5745 /* Current assemblers are broken and do not allow @GOTOFF in
5746 ought but a memory context. */
5747 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5748 {
5749 switch (get_attr_type (insn))
5750 {
5751 case TYPE_INCDEC:
5752 if (! rtx_equal_p (operands[0], operands[1]))
5753 abort ();
5754 if (operands[2] == const1_rtx)
5755 return "inc{q}\t%0";
5756 else if (operands[2] == constm1_rtx)
5757 return "dec{q}\t%0";
5758 else
5759 abort();
5760
5761 default:
5762 if (! rtx_equal_p (operands[0], operands[1]))
5763 abort ();
5764 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5765 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5766 if (GET_CODE (operands[2]) == CONST_INT
5767 /* Avoid overflows. */
5768 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5769 && (INTVAL (operands[2]) == 128
5770 || (INTVAL (operands[2]) < 0
5771 && INTVAL (operands[2]) != -128)))
5772 {
5773 operands[2] = GEN_INT (-INTVAL (operands[2]));
5774 return "sub{q}\t{%2, %0|%0, %2}";
5775 }
5776 return "add{q}\t{%2, %0|%0, %2}";
5777 }
5778 }
5779 [(set (attr "type")
5780 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5781 (const_string "incdec")
5782 (const_string "alu")))
5783 (set_attr "mode" "DI")])
5784
5785
5786 (define_insn "*addsi_1"
5787 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5788 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5789 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5790 (clobber (reg:CC 17))]
5791 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5792 {
5793 switch (get_attr_type (insn))
5794 {
5795 case TYPE_LEA:
5796 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5797 return "lea{l}\t{%a2, %0|%0, %a2}";
5798
5799 case TYPE_INCDEC:
5800 if (! rtx_equal_p (operands[0], operands[1]))
5801 abort ();
5802 if (operands[2] == const1_rtx)
5803 return "inc{l}\t%0";
5804 else if (operands[2] == constm1_rtx)
5805 return "dec{l}\t%0";
5806 else
5807 abort();
5808
5809 default:
5810 if (! rtx_equal_p (operands[0], operands[1]))
5811 abort ();
5812
5813 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5814 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5815 if (GET_CODE (operands[2]) == CONST_INT
5816 && (INTVAL (operands[2]) == 128
5817 || (INTVAL (operands[2]) < 0
5818 && INTVAL (operands[2]) != -128)))
5819 {
5820 operands[2] = GEN_INT (-INTVAL (operands[2]));
5821 return "sub{l}\t{%2, %0|%0, %2}";
5822 }
5823 return "add{l}\t{%2, %0|%0, %2}";
5824 }
5825 }
5826 [(set (attr "type")
5827 (cond [(eq_attr "alternative" "2")
5828 (const_string "lea")
5829 ; Current assemblers are broken and do not allow @GOTOFF in
5830 ; ought but a memory context.
5831 (match_operand:SI 2 "pic_symbolic_operand" "")
5832 (const_string "lea")
5833 (match_operand:SI 2 "incdec_operand" "")
5834 (const_string "incdec")
5835 ]
5836 (const_string "alu")))
5837 (set_attr "mode" "SI")])
5838
5839 ;; Convert lea to the lea pattern to avoid flags dependency.
5840 (define_split
5841 [(set (match_operand 0 "register_operand" "")
5842 (plus (match_operand 1 "register_operand" "")
5843 (match_operand 2 "nonmemory_operand" "")))
5844 (clobber (reg:CC 17))]
5845 "reload_completed
5846 && true_regnum (operands[0]) != true_regnum (operands[1])"
5847 [(const_int 0)]
5848 {
5849 rtx pat;
5850 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5851 may confuse gen_lowpart. */
5852 if (GET_MODE (operands[0]) != Pmode)
5853 {
5854 operands[1] = gen_lowpart (Pmode, operands[1]);
5855 operands[2] = gen_lowpart (Pmode, operands[2]);
5856 }
5857 operands[0] = gen_lowpart (SImode, operands[0]);
5858 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5859 if (Pmode != SImode)
5860 pat = gen_rtx_SUBREG (SImode, pat, 0);
5861 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5862 DONE;
5863 })
5864
5865 ;; It may seem that nonimmediate operand is proper one for operand 1.
5866 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5867 ;; we take care in ix86_binary_operator_ok to not allow two memory
5868 ;; operands so proper swapping will be done in reload. This allow
5869 ;; patterns constructed from addsi_1 to match.
5870 (define_insn "addsi_1_zext"
5871 [(set (match_operand:DI 0 "register_operand" "=r,r")
5872 (zero_extend:DI
5873 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5874 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5875 (clobber (reg:CC 17))]
5876 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5877 {
5878 switch (get_attr_type (insn))
5879 {
5880 case TYPE_LEA:
5881 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5882 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5883
5884 case TYPE_INCDEC:
5885 if (operands[2] == const1_rtx)
5886 return "inc{l}\t%k0";
5887 else if (operands[2] == constm1_rtx)
5888 return "dec{l}\t%k0";
5889 else
5890 abort();
5891
5892 default:
5893 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5894 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5895 if (GET_CODE (operands[2]) == CONST_INT
5896 && (INTVAL (operands[2]) == 128
5897 || (INTVAL (operands[2]) < 0
5898 && INTVAL (operands[2]) != -128)))
5899 {
5900 operands[2] = GEN_INT (-INTVAL (operands[2]));
5901 return "sub{l}\t{%2, %k0|%k0, %2}";
5902 }
5903 return "add{l}\t{%2, %k0|%k0, %2}";
5904 }
5905 }
5906 [(set (attr "type")
5907 (cond [(eq_attr "alternative" "1")
5908 (const_string "lea")
5909 ; Current assemblers are broken and do not allow @GOTOFF in
5910 ; ought but a memory context.
5911 (match_operand:SI 2 "pic_symbolic_operand" "")
5912 (const_string "lea")
5913 (match_operand:SI 2 "incdec_operand" "")
5914 (const_string "incdec")
5915 ]
5916 (const_string "alu")))
5917 (set_attr "mode" "SI")])
5918
5919 ;; Convert lea to the lea pattern to avoid flags dependency.
5920 (define_split
5921 [(set (match_operand:DI 0 "register_operand" "")
5922 (zero_extend:DI
5923 (plus:SI (match_operand:SI 1 "register_operand" "")
5924 (match_operand:SI 2 "nonmemory_operand" ""))))
5925 (clobber (reg:CC 17))]
5926 "TARGET_64BIT && reload_completed
5927 && true_regnum (operands[0]) != true_regnum (operands[1])"
5928 [(set (match_dup 0)
5929 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5930 {
5931 operands[1] = gen_lowpart (Pmode, operands[1]);
5932 operands[2] = gen_lowpart (Pmode, operands[2]);
5933 })
5934
5935 (define_insn "*addsi_2"
5936 [(set (reg 17)
5937 (compare
5938 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5939 (match_operand:SI 2 "general_operand" "rmni,rni"))
5940 (const_int 0)))
5941 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5942 (plus:SI (match_dup 1) (match_dup 2)))]
5943 "ix86_match_ccmode (insn, CCGOCmode)
5944 && ix86_binary_operator_ok (PLUS, SImode, operands)
5945 /* Current assemblers are broken and do not allow @GOTOFF in
5946 ought but a memory context. */
5947 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5948 {
5949 switch (get_attr_type (insn))
5950 {
5951 case TYPE_INCDEC:
5952 if (! rtx_equal_p (operands[0], operands[1]))
5953 abort ();
5954 if (operands[2] == const1_rtx)
5955 return "inc{l}\t%0";
5956 else if (operands[2] == constm1_rtx)
5957 return "dec{l}\t%0";
5958 else
5959 abort();
5960
5961 default:
5962 if (! rtx_equal_p (operands[0], operands[1]))
5963 abort ();
5964 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5965 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5966 if (GET_CODE (operands[2]) == CONST_INT
5967 && (INTVAL (operands[2]) == 128
5968 || (INTVAL (operands[2]) < 0
5969 && INTVAL (operands[2]) != -128)))
5970 {
5971 operands[2] = GEN_INT (-INTVAL (operands[2]));
5972 return "sub{l}\t{%2, %0|%0, %2}";
5973 }
5974 return "add{l}\t{%2, %0|%0, %2}";
5975 }
5976 }
5977 [(set (attr "type")
5978 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5979 (const_string "incdec")
5980 (const_string "alu")))
5981 (set_attr "mode" "SI")])
5982
5983 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5984 (define_insn "*addsi_2_zext"
5985 [(set (reg 17)
5986 (compare
5987 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5988 (match_operand:SI 2 "general_operand" "rmni"))
5989 (const_int 0)))
5990 (set (match_operand:DI 0 "register_operand" "=r")
5991 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5992 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5993 && ix86_binary_operator_ok (PLUS, SImode, operands)
5994 /* Current assemblers are broken and do not allow @GOTOFF in
5995 ought but a memory context. */
5996 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5997 {
5998 switch (get_attr_type (insn))
5999 {
6000 case TYPE_INCDEC:
6001 if (operands[2] == const1_rtx)
6002 return "inc{l}\t%k0";
6003 else if (operands[2] == constm1_rtx)
6004 return "dec{l}\t%k0";
6005 else
6006 abort();
6007
6008 default:
6009 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6011 if (GET_CODE (operands[2]) == CONST_INT
6012 && (INTVAL (operands[2]) == 128
6013 || (INTVAL (operands[2]) < 0
6014 && INTVAL (operands[2]) != -128)))
6015 {
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "sub{l}\t{%2, %k0|%k0, %2}";
6018 }
6019 return "add{l}\t{%2, %k0|%k0, %2}";
6020 }
6021 }
6022 [(set (attr "type")
6023 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6024 (const_string "incdec")
6025 (const_string "alu")))
6026 (set_attr "mode" "SI")])
6027
6028 (define_insn "*addsi_3"
6029 [(set (reg 17)
6030 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6031 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6032 (clobber (match_scratch:SI 0 "=r"))]
6033 "ix86_match_ccmode (insn, CCZmode)
6034 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6035 /* Current assemblers are broken and do not allow @GOTOFF in
6036 ought but a memory context. */
6037 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6038 {
6039 switch (get_attr_type (insn))
6040 {
6041 case TYPE_INCDEC:
6042 if (! rtx_equal_p (operands[0], operands[1]))
6043 abort ();
6044 if (operands[2] == const1_rtx)
6045 return "inc{l}\t%0";
6046 else if (operands[2] == constm1_rtx)
6047 return "dec{l}\t%0";
6048 else
6049 abort();
6050
6051 default:
6052 if (! rtx_equal_p (operands[0], operands[1]))
6053 abort ();
6054 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6055 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6056 if (GET_CODE (operands[2]) == CONST_INT
6057 && (INTVAL (operands[2]) == 128
6058 || (INTVAL (operands[2]) < 0
6059 && INTVAL (operands[2]) != -128)))
6060 {
6061 operands[2] = GEN_INT (-INTVAL (operands[2]));
6062 return "sub{l}\t{%2, %0|%0, %2}";
6063 }
6064 return "add{l}\t{%2, %0|%0, %2}";
6065 }
6066 }
6067 [(set (attr "type")
6068 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6069 (const_string "incdec")
6070 (const_string "alu")))
6071 (set_attr "mode" "SI")])
6072
6073 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6074 (define_insn "*addsi_3_zext"
6075 [(set (reg 17)
6076 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6077 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6078 (set (match_operand:DI 0 "register_operand" "=r")
6079 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6080 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6081 && ix86_binary_operator_ok (PLUS, SImode, operands)
6082 /* Current assemblers are broken and do not allow @GOTOFF in
6083 ought but a memory context. */
6084 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6085 {
6086 switch (get_attr_type (insn))
6087 {
6088 case TYPE_INCDEC:
6089 if (operands[2] == const1_rtx)
6090 return "inc{l}\t%k0";
6091 else if (operands[2] == constm1_rtx)
6092 return "dec{l}\t%k0";
6093 else
6094 abort();
6095
6096 default:
6097 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6098 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6099 if (GET_CODE (operands[2]) == CONST_INT
6100 && (INTVAL (operands[2]) == 128
6101 || (INTVAL (operands[2]) < 0
6102 && INTVAL (operands[2]) != -128)))
6103 {
6104 operands[2] = GEN_INT (-INTVAL (operands[2]));
6105 return "sub{l}\t{%2, %k0|%k0, %2}";
6106 }
6107 return "add{l}\t{%2, %k0|%k0, %2}";
6108 }
6109 }
6110 [(set (attr "type")
6111 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6112 (const_string "incdec")
6113 (const_string "alu")))
6114 (set_attr "mode" "SI")])
6115
6116 ; For comparisons against 1, -1 and 128, we may generate better code
6117 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6118 ; is matched then. We can't accept general immediate, because for
6119 ; case of overflows, the result is messed up.
6120 ; This pattern also don't hold of 0x80000000, since the value overflows
6121 ; when negated.
6122 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6123 ; only for comparisons not depending on it.
6124 (define_insn "*addsi_4"
6125 [(set (reg 17)
6126 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6127 (match_operand:SI 2 "const_int_operand" "n")))
6128 (clobber (match_scratch:SI 0 "=rm"))]
6129 "ix86_match_ccmode (insn, CCGCmode)
6130 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6131 {
6132 switch (get_attr_type (insn))
6133 {
6134 case TYPE_INCDEC:
6135 if (operands[2] == constm1_rtx)
6136 return "inc{l}\t%0";
6137 else if (operands[2] == const1_rtx)
6138 return "dec{l}\t%0";
6139 else
6140 abort();
6141
6142 default:
6143 if (! rtx_equal_p (operands[0], operands[1]))
6144 abort ();
6145 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6146 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6147 if ((INTVAL (operands[2]) == -128
6148 || (INTVAL (operands[2]) > 0
6149 && INTVAL (operands[2]) != 128)))
6150 return "sub{l}\t{%2, %0|%0, %2}";
6151 operands[2] = GEN_INT (-INTVAL (operands[2]));
6152 return "add{l}\t{%2, %0|%0, %2}";
6153 }
6154 }
6155 [(set (attr "type")
6156 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6157 (const_string "incdec")
6158 (const_string "alu")))
6159 (set_attr "mode" "SI")])
6160
6161 (define_insn "*addsi_5"
6162 [(set (reg 17)
6163 (compare
6164 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6165 (match_operand:SI 2 "general_operand" "rmni"))
6166 (const_int 0)))
6167 (clobber (match_scratch:SI 0 "=r"))]
6168 "ix86_match_ccmode (insn, CCGOCmode)
6169 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6170 /* Current assemblers are broken and do not allow @GOTOFF in
6171 ought but a memory context. */
6172 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6173 {
6174 switch (get_attr_type (insn))
6175 {
6176 case TYPE_INCDEC:
6177 if (! rtx_equal_p (operands[0], operands[1]))
6178 abort ();
6179 if (operands[2] == const1_rtx)
6180 return "inc{l}\t%0";
6181 else if (operands[2] == constm1_rtx)
6182 return "dec{l}\t%0";
6183 else
6184 abort();
6185
6186 default:
6187 if (! rtx_equal_p (operands[0], operands[1]))
6188 abort ();
6189 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6190 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6191 if (GET_CODE (operands[2]) == CONST_INT
6192 && (INTVAL (operands[2]) == 128
6193 || (INTVAL (operands[2]) < 0
6194 && INTVAL (operands[2]) != -128)))
6195 {
6196 operands[2] = GEN_INT (-INTVAL (operands[2]));
6197 return "sub{l}\t{%2, %0|%0, %2}";
6198 }
6199 return "add{l}\t{%2, %0|%0, %2}";
6200 }
6201 }
6202 [(set (attr "type")
6203 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6204 (const_string "incdec")
6205 (const_string "alu")))
6206 (set_attr "mode" "SI")])
6207
6208 (define_expand "addhi3"
6209 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6210 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6211 (match_operand:HI 2 "general_operand" "")))
6212 (clobber (reg:CC 17))])]
6213 "TARGET_HIMODE_MATH"
6214 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6215
6216 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6217 ;; type optimizations enabled by define-splits. This is not important
6218 ;; for PII, and in fact harmful because of partial register stalls.
6219
6220 (define_insn "*addhi_1_lea"
6221 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6222 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6223 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6224 (clobber (reg:CC 17))]
6225 "!TARGET_PARTIAL_REG_STALL
6226 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6227 {
6228 switch (get_attr_type (insn))
6229 {
6230 case TYPE_LEA:
6231 return "#";
6232 case TYPE_INCDEC:
6233 if (operands[2] == const1_rtx)
6234 return "inc{w}\t%0";
6235 else if (operands[2] == constm1_rtx)
6236 return "dec{w}\t%0";
6237 abort();
6238
6239 default:
6240 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6242 if (GET_CODE (operands[2]) == CONST_INT
6243 && (INTVAL (operands[2]) == 128
6244 || (INTVAL (operands[2]) < 0
6245 && INTVAL (operands[2]) != -128)))
6246 {
6247 operands[2] = GEN_INT (-INTVAL (operands[2]));
6248 return "sub{w}\t{%2, %0|%0, %2}";
6249 }
6250 return "add{w}\t{%2, %0|%0, %2}";
6251 }
6252 }
6253 [(set (attr "type")
6254 (if_then_else (eq_attr "alternative" "2")
6255 (const_string "lea")
6256 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu"))))
6259 (set_attr "mode" "HI,HI,SI")])
6260
6261 (define_insn "*addhi_1"
6262 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6263 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6264 (match_operand:HI 2 "general_operand" "ri,rm")))
6265 (clobber (reg:CC 17))]
6266 "TARGET_PARTIAL_REG_STALL
6267 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6268 {
6269 switch (get_attr_type (insn))
6270 {
6271 case TYPE_INCDEC:
6272 if (operands[2] == const1_rtx)
6273 return "inc{w}\t%0";
6274 else if (operands[2] == constm1_rtx)
6275 return "dec{w}\t%0";
6276 abort();
6277
6278 default:
6279 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6280 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6281 if (GET_CODE (operands[2]) == CONST_INT
6282 && (INTVAL (operands[2]) == 128
6283 || (INTVAL (operands[2]) < 0
6284 && INTVAL (operands[2]) != -128)))
6285 {
6286 operands[2] = GEN_INT (-INTVAL (operands[2]));
6287 return "sub{w}\t{%2, %0|%0, %2}";
6288 }
6289 return "add{w}\t{%2, %0|%0, %2}";
6290 }
6291 }
6292 [(set (attr "type")
6293 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set_attr "mode" "HI")])
6297
6298 (define_insn "*addhi_2"
6299 [(set (reg 17)
6300 (compare
6301 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6302 (match_operand:HI 2 "general_operand" "rmni,rni"))
6303 (const_int 0)))
6304 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6305 (plus:HI (match_dup 1) (match_dup 2)))]
6306 "ix86_match_ccmode (insn, CCGOCmode)
6307 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6308 {
6309 switch (get_attr_type (insn))
6310 {
6311 case TYPE_INCDEC:
6312 if (operands[2] == const1_rtx)
6313 return "inc{w}\t%0";
6314 else if (operands[2] == constm1_rtx)
6315 return "dec{w}\t%0";
6316 abort();
6317
6318 default:
6319 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6320 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6321 if (GET_CODE (operands[2]) == CONST_INT
6322 && (INTVAL (operands[2]) == 128
6323 || (INTVAL (operands[2]) < 0
6324 && INTVAL (operands[2]) != -128)))
6325 {
6326 operands[2] = GEN_INT (-INTVAL (operands[2]));
6327 return "sub{w}\t{%2, %0|%0, %2}";
6328 }
6329 return "add{w}\t{%2, %0|%0, %2}";
6330 }
6331 }
6332 [(set (attr "type")
6333 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6334 (const_string "incdec")
6335 (const_string "alu")))
6336 (set_attr "mode" "HI")])
6337
6338 (define_insn "*addhi_3"
6339 [(set (reg 17)
6340 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6341 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6342 (clobber (match_scratch:HI 0 "=r"))]
6343 "ix86_match_ccmode (insn, CCZmode)
6344 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6345 {
6346 switch (get_attr_type (insn))
6347 {
6348 case TYPE_INCDEC:
6349 if (operands[2] == const1_rtx)
6350 return "inc{w}\t%0";
6351 else if (operands[2] == constm1_rtx)
6352 return "dec{w}\t%0";
6353 abort();
6354
6355 default:
6356 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6357 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6358 if (GET_CODE (operands[2]) == CONST_INT
6359 && (INTVAL (operands[2]) == 128
6360 || (INTVAL (operands[2]) < 0
6361 && INTVAL (operands[2]) != -128)))
6362 {
6363 operands[2] = GEN_INT (-INTVAL (operands[2]));
6364 return "sub{w}\t{%2, %0|%0, %2}";
6365 }
6366 return "add{w}\t{%2, %0|%0, %2}";
6367 }
6368 }
6369 [(set (attr "type")
6370 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6371 (const_string "incdec")
6372 (const_string "alu")))
6373 (set_attr "mode" "HI")])
6374
6375 ; See comments above addsi_3_imm for details.
6376 (define_insn "*addhi_4"
6377 [(set (reg 17)
6378 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6379 (match_operand:HI 2 "const_int_operand" "n")))
6380 (clobber (match_scratch:HI 0 "=rm"))]
6381 "ix86_match_ccmode (insn, CCGCmode)
6382 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6383 {
6384 switch (get_attr_type (insn))
6385 {
6386 case TYPE_INCDEC:
6387 if (operands[2] == constm1_rtx)
6388 return "inc{w}\t%0";
6389 else if (operands[2] == const1_rtx)
6390 return "dec{w}\t%0";
6391 else
6392 abort();
6393
6394 default:
6395 if (! rtx_equal_p (operands[0], operands[1]))
6396 abort ();
6397 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6398 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6399 if ((INTVAL (operands[2]) == -128
6400 || (INTVAL (operands[2]) > 0
6401 && INTVAL (operands[2]) != 128)))
6402 return "sub{w}\t{%2, %0|%0, %2}";
6403 operands[2] = GEN_INT (-INTVAL (operands[2]));
6404 return "add{w}\t{%2, %0|%0, %2}";
6405 }
6406 }
6407 [(set (attr "type")
6408 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6409 (const_string "incdec")
6410 (const_string "alu")))
6411 (set_attr "mode" "SI")])
6412
6413
6414 (define_insn "*addhi_5"
6415 [(set (reg 17)
6416 (compare
6417 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6418 (match_operand:HI 2 "general_operand" "rmni"))
6419 (const_int 0)))
6420 (clobber (match_scratch:HI 0 "=r"))]
6421 "ix86_match_ccmode (insn, CCGOCmode)
6422 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6423 {
6424 switch (get_attr_type (insn))
6425 {
6426 case TYPE_INCDEC:
6427 if (operands[2] == const1_rtx)
6428 return "inc{w}\t%0";
6429 else if (operands[2] == constm1_rtx)
6430 return "dec{w}\t%0";
6431 abort();
6432
6433 default:
6434 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6435 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6436 if (GET_CODE (operands[2]) == CONST_INT
6437 && (INTVAL (operands[2]) == 128
6438 || (INTVAL (operands[2]) < 0
6439 && INTVAL (operands[2]) != -128)))
6440 {
6441 operands[2] = GEN_INT (-INTVAL (operands[2]));
6442 return "sub{w}\t{%2, %0|%0, %2}";
6443 }
6444 return "add{w}\t{%2, %0|%0, %2}";
6445 }
6446 }
6447 [(set (attr "type")
6448 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6449 (const_string "incdec")
6450 (const_string "alu")))
6451 (set_attr "mode" "HI")])
6452
6453 (define_expand "addqi3"
6454 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6455 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6456 (match_operand:QI 2 "general_operand" "")))
6457 (clobber (reg:CC 17))])]
6458 "TARGET_QIMODE_MATH"
6459 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6460
6461 ;; %%% Potential partial reg stall on alternative 2. What to do?
6462 (define_insn "*addqi_1_lea"
6463 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6464 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6465 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6466 (clobber (reg:CC 17))]
6467 "!TARGET_PARTIAL_REG_STALL
6468 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6469 {
6470 int widen = (which_alternative == 2);
6471 switch (get_attr_type (insn))
6472 {
6473 case TYPE_LEA:
6474 return "#";
6475 case TYPE_INCDEC:
6476 if (operands[2] == const1_rtx)
6477 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6478 else if (operands[2] == constm1_rtx)
6479 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6480 abort();
6481
6482 default:
6483 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6484 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6485 if (GET_CODE (operands[2]) == CONST_INT
6486 && (INTVAL (operands[2]) == 128
6487 || (INTVAL (operands[2]) < 0
6488 && INTVAL (operands[2]) != -128)))
6489 {
6490 operands[2] = GEN_INT (-INTVAL (operands[2]));
6491 if (widen)
6492 return "sub{l}\t{%2, %k0|%k0, %2}";
6493 else
6494 return "sub{b}\t{%2, %0|%0, %2}";
6495 }
6496 if (widen)
6497 return "add{l}\t{%k2, %k0|%k0, %k2}";
6498 else
6499 return "add{b}\t{%2, %0|%0, %2}";
6500 }
6501 }
6502 [(set (attr "type")
6503 (if_then_else (eq_attr "alternative" "3")
6504 (const_string "lea")
6505 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6506 (const_string "incdec")
6507 (const_string "alu"))))
6508 (set_attr "mode" "QI,QI,SI,SI")])
6509
6510 (define_insn "*addqi_1"
6511 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6512 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6513 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6514 (clobber (reg:CC 17))]
6515 "TARGET_PARTIAL_REG_STALL
6516 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6517 {
6518 int widen = (which_alternative == 2);
6519 switch (get_attr_type (insn))
6520 {
6521 case TYPE_INCDEC:
6522 if (operands[2] == const1_rtx)
6523 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6524 else if (operands[2] == constm1_rtx)
6525 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6526 abort();
6527
6528 default:
6529 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6530 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6531 if (GET_CODE (operands[2]) == CONST_INT
6532 && (INTVAL (operands[2]) == 128
6533 || (INTVAL (operands[2]) < 0
6534 && INTVAL (operands[2]) != -128)))
6535 {
6536 operands[2] = GEN_INT (-INTVAL (operands[2]));
6537 if (widen)
6538 return "sub{l}\t{%2, %k0|%k0, %2}";
6539 else
6540 return "sub{b}\t{%2, %0|%0, %2}";
6541 }
6542 if (widen)
6543 return "add{l}\t{%k2, %k0|%k0, %k2}";
6544 else
6545 return "add{b}\t{%2, %0|%0, %2}";
6546 }
6547 }
6548 [(set (attr "type")
6549 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6550 (const_string "incdec")
6551 (const_string "alu")))
6552 (set_attr "mode" "QI,QI,SI")])
6553
6554 (define_insn "*addqi_1_slp"
6555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6556 (plus:QI (match_dup 0)
6557 (match_operand:QI 1 "general_operand" "qn,qnm")))
6558 (clobber (reg:CC 17))]
6559 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6561 {
6562 switch (get_attr_type (insn))
6563 {
6564 case TYPE_INCDEC:
6565 if (operands[1] == const1_rtx)
6566 return "inc{b}\t%0";
6567 else if (operands[1] == constm1_rtx)
6568 return "dec{b}\t%0";
6569 abort();
6570
6571 default:
6572 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6573 if (GET_CODE (operands[1]) == CONST_INT
6574 && INTVAL (operands[1]) < 0)
6575 {
6576 operands[2] = GEN_INT (-INTVAL (operands[2]));
6577 return "sub{b}\t{%1, %0|%0, %1}";
6578 }
6579 return "add{b}\t{%1, %0|%0, %1}";
6580 }
6581 }
6582 [(set (attr "type")
6583 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6584 (const_string "incdec")
6585 (const_string "alu1")))
6586 (set_attr "mode" "QI")])
6587
6588 (define_insn "*addqi_2"
6589 [(set (reg 17)
6590 (compare
6591 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6592 (match_operand:QI 2 "general_operand" "qmni,qni"))
6593 (const_int 0)))
6594 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6595 (plus:QI (match_dup 1) (match_dup 2)))]
6596 "ix86_match_ccmode (insn, CCGOCmode)
6597 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6598 {
6599 switch (get_attr_type (insn))
6600 {
6601 case TYPE_INCDEC:
6602 if (operands[2] == const1_rtx)
6603 return "inc{b}\t%0";
6604 else if (operands[2] == constm1_rtx
6605 || (GET_CODE (operands[2]) == CONST_INT
6606 && INTVAL (operands[2]) == 255))
6607 return "dec{b}\t%0";
6608 abort();
6609
6610 default:
6611 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6612 if (GET_CODE (operands[2]) == CONST_INT
6613 && INTVAL (operands[2]) < 0)
6614 {
6615 operands[2] = GEN_INT (-INTVAL (operands[2]));
6616 return "sub{b}\t{%2, %0|%0, %2}";
6617 }
6618 return "add{b}\t{%2, %0|%0, %2}";
6619 }
6620 }
6621 [(set (attr "type")
6622 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6623 (const_string "incdec")
6624 (const_string "alu")))
6625 (set_attr "mode" "QI")])
6626
6627 (define_insn "*addqi_3"
6628 [(set (reg 17)
6629 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6630 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6631 (clobber (match_scratch:QI 0 "=q"))]
6632 "ix86_match_ccmode (insn, CCZmode)
6633 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6634 {
6635 switch (get_attr_type (insn))
6636 {
6637 case TYPE_INCDEC:
6638 if (operands[2] == const1_rtx)
6639 return "inc{b}\t%0";
6640 else if (operands[2] == constm1_rtx
6641 || (GET_CODE (operands[2]) == CONST_INT
6642 && INTVAL (operands[2]) == 255))
6643 return "dec{b}\t%0";
6644 abort();
6645
6646 default:
6647 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6648 if (GET_CODE (operands[2]) == CONST_INT
6649 && INTVAL (operands[2]) < 0)
6650 {
6651 operands[2] = GEN_INT (-INTVAL (operands[2]));
6652 return "sub{b}\t{%2, %0|%0, %2}";
6653 }
6654 return "add{b}\t{%2, %0|%0, %2}";
6655 }
6656 }
6657 [(set (attr "type")
6658 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6659 (const_string "incdec")
6660 (const_string "alu")))
6661 (set_attr "mode" "QI")])
6662
6663 ; See comments above addsi_3_imm for details.
6664 (define_insn "*addqi_4"
6665 [(set (reg 17)
6666 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6667 (match_operand:QI 2 "const_int_operand" "n")))
6668 (clobber (match_scratch:QI 0 "=qm"))]
6669 "ix86_match_ccmode (insn, CCGCmode)
6670 && (INTVAL (operands[2]) & 0xff) != 0x80"
6671 {
6672 switch (get_attr_type (insn))
6673 {
6674 case TYPE_INCDEC:
6675 if (operands[2] == constm1_rtx
6676 || (GET_CODE (operands[2]) == CONST_INT
6677 && INTVAL (operands[2]) == 255))
6678 return "inc{b}\t%0";
6679 else if (operands[2] == const1_rtx)
6680 return "dec{b}\t%0";
6681 else
6682 abort();
6683
6684 default:
6685 if (! rtx_equal_p (operands[0], operands[1]))
6686 abort ();
6687 if (INTVAL (operands[2]) < 0)
6688 {
6689 operands[2] = GEN_INT (-INTVAL (operands[2]));
6690 return "add{b}\t{%2, %0|%0, %2}";
6691 }
6692 return "sub{b}\t{%2, %0|%0, %2}";
6693 }
6694 }
6695 [(set (attr "type")
6696 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6697 (const_string "incdec")
6698 (const_string "alu")))
6699 (set_attr "mode" "QI")])
6700
6701
6702 (define_insn "*addqi_5"
6703 [(set (reg 17)
6704 (compare
6705 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6706 (match_operand:QI 2 "general_operand" "qmni"))
6707 (const_int 0)))
6708 (clobber (match_scratch:QI 0 "=q"))]
6709 "ix86_match_ccmode (insn, CCGOCmode)
6710 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6711 {
6712 switch (get_attr_type (insn))
6713 {
6714 case TYPE_INCDEC:
6715 if (operands[2] == const1_rtx)
6716 return "inc{b}\t%0";
6717 else if (operands[2] == constm1_rtx
6718 || (GET_CODE (operands[2]) == CONST_INT
6719 && INTVAL (operands[2]) == 255))
6720 return "dec{b}\t%0";
6721 abort();
6722
6723 default:
6724 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6725 if (GET_CODE (operands[2]) == CONST_INT
6726 && INTVAL (operands[2]) < 0)
6727 {
6728 operands[2] = GEN_INT (-INTVAL (operands[2]));
6729 return "sub{b}\t{%2, %0|%0, %2}";
6730 }
6731 return "add{b}\t{%2, %0|%0, %2}";
6732 }
6733 }
6734 [(set (attr "type")
6735 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6736 (const_string "incdec")
6737 (const_string "alu")))
6738 (set_attr "mode" "QI")])
6739
6740
6741 (define_insn "addqi_ext_1"
6742 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6743 (const_int 8)
6744 (const_int 8))
6745 (plus:SI
6746 (zero_extract:SI
6747 (match_operand 1 "ext_register_operand" "0")
6748 (const_int 8)
6749 (const_int 8))
6750 (match_operand:QI 2 "general_operand" "Qmn")))
6751 (clobber (reg:CC 17))]
6752 "!TARGET_64BIT"
6753 {
6754 switch (get_attr_type (insn))
6755 {
6756 case TYPE_INCDEC:
6757 if (operands[2] == const1_rtx)
6758 return "inc{b}\t%h0";
6759 else if (operands[2] == constm1_rtx
6760 || (GET_CODE (operands[2]) == CONST_INT
6761 && INTVAL (operands[2]) == 255))
6762 return "dec{b}\t%h0";
6763 abort();
6764
6765 default:
6766 return "add{b}\t{%2, %h0|%h0, %2}";
6767 }
6768 }
6769 [(set (attr "type")
6770 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6771 (const_string "incdec")
6772 (const_string "alu")))
6773 (set_attr "mode" "QI")])
6774
6775 (define_insn "*addqi_ext_1_rex64"
6776 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6777 (const_int 8)
6778 (const_int 8))
6779 (plus:SI
6780 (zero_extract:SI
6781 (match_operand 1 "ext_register_operand" "0")
6782 (const_int 8)
6783 (const_int 8))
6784 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6785 (clobber (reg:CC 17))]
6786 "TARGET_64BIT"
6787 {
6788 switch (get_attr_type (insn))
6789 {
6790 case TYPE_INCDEC:
6791 if (operands[2] == const1_rtx)
6792 return "inc{b}\t%h0";
6793 else if (operands[2] == constm1_rtx
6794 || (GET_CODE (operands[2]) == CONST_INT
6795 && INTVAL (operands[2]) == 255))
6796 return "dec{b}\t%h0";
6797 abort();
6798
6799 default:
6800 return "add{b}\t{%2, %h0|%h0, %2}";
6801 }
6802 }
6803 [(set (attr "type")
6804 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6805 (const_string "incdec")
6806 (const_string "alu")))
6807 (set_attr "mode" "QI")])
6808
6809 (define_insn "*addqi_ext_2"
6810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6811 (const_int 8)
6812 (const_int 8))
6813 (plus:SI
6814 (zero_extract:SI
6815 (match_operand 1 "ext_register_operand" "%0")
6816 (const_int 8)
6817 (const_int 8))
6818 (zero_extract:SI
6819 (match_operand 2 "ext_register_operand" "Q")
6820 (const_int 8)
6821 (const_int 8))))
6822 (clobber (reg:CC 17))]
6823 ""
6824 "add{b}\t{%h2, %h0|%h0, %h2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "QI")])
6827
6828 ;; The patterns that match these are at the end of this file.
6829
6830 (define_expand "addxf3"
6831 [(set (match_operand:XF 0 "register_operand" "")
6832 (plus:XF (match_operand:XF 1 "register_operand" "")
6833 (match_operand:XF 2 "register_operand" "")))]
6834 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
6835 "")
6836
6837 (define_expand "addtf3"
6838 [(set (match_operand:TF 0 "register_operand" "")
6839 (plus:TF (match_operand:TF 1 "register_operand" "")
6840 (match_operand:TF 2 "register_operand" "")))]
6841 "TARGET_80387"
6842 "")
6843
6844 (define_expand "adddf3"
6845 [(set (match_operand:DF 0 "register_operand" "")
6846 (plus:DF (match_operand:DF 1 "register_operand" "")
6847 (match_operand:DF 2 "nonimmediate_operand" "")))]
6848 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6849 "")
6850
6851 (define_expand "addsf3"
6852 [(set (match_operand:SF 0 "register_operand" "")
6853 (plus:SF (match_operand:SF 1 "register_operand" "")
6854 (match_operand:SF 2 "nonimmediate_operand" "")))]
6855 "TARGET_80387 || TARGET_SSE_MATH"
6856 "")
6857 \f
6858 ;; Subtract instructions
6859
6860 ;; %%% splits for subsidi3
6861
6862 (define_expand "subdi3"
6863 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6864 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6865 (match_operand:DI 2 "x86_64_general_operand" "")))
6866 (clobber (reg:CC 17))])]
6867 ""
6868 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6869
6870 (define_insn "*subdi3_1"
6871 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6872 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6873 (match_operand:DI 2 "general_operand" "roiF,riF")))
6874 (clobber (reg:CC 17))]
6875 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6876 "#")
6877
6878 (define_split
6879 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6880 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6881 (match_operand:DI 2 "general_operand" "")))
6882 (clobber (reg:CC 17))]
6883 "!TARGET_64BIT && reload_completed"
6884 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6885 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6886 (parallel [(set (match_dup 3)
6887 (minus:SI (match_dup 4)
6888 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6889 (match_dup 5))))
6890 (clobber (reg:CC 17))])]
6891 "split_di (operands+0, 1, operands+0, operands+3);
6892 split_di (operands+1, 1, operands+1, operands+4);
6893 split_di (operands+2, 1, operands+2, operands+5);")
6894
6895 (define_insn "subdi3_carry_rex64"
6896 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6897 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6898 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6899 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6900 (clobber (reg:CC 17))]
6901 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6902 "sbb{q}\t{%2, %0|%0, %2}"
6903 [(set_attr "type" "alu")
6904 (set_attr "pent_pair" "pu")
6905 (set_attr "ppro_uops" "few")
6906 (set_attr "mode" "DI")])
6907
6908 (define_insn "*subdi_1_rex64"
6909 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6910 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6911 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6912 (clobber (reg:CC 17))]
6913 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6914 "sub{q}\t{%2, %0|%0, %2}"
6915 [(set_attr "type" "alu")
6916 (set_attr "mode" "DI")])
6917
6918 (define_insn "*subdi_2_rex64"
6919 [(set (reg 17)
6920 (compare
6921 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6922 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6923 (const_int 0)))
6924 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6925 (minus:DI (match_dup 1) (match_dup 2)))]
6926 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6927 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6928 "sub{q}\t{%2, %0|%0, %2}"
6929 [(set_attr "type" "alu")
6930 (set_attr "mode" "DI")])
6931
6932 (define_insn "*subdi_3_rex63"
6933 [(set (reg 17)
6934 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6935 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6936 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6937 (minus:DI (match_dup 1) (match_dup 2)))]
6938 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6939 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6940 "sub{q}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "alu")
6942 (set_attr "mode" "DI")])
6943
6944 (define_insn "subqi3_carry"
6945 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6946 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6947 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6948 (match_operand:QI 2 "general_operand" "ri,rm"))))
6949 (clobber (reg:CC 17))]
6950 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6951 "sbb{b}\t{%2, %0|%0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "pent_pair" "pu")
6954 (set_attr "ppro_uops" "few")
6955 (set_attr "mode" "QI")])
6956
6957 (define_insn "subhi3_carry"
6958 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6959 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6960 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6961 (match_operand:HI 2 "general_operand" "ri,rm"))))
6962 (clobber (reg:CC 17))]
6963 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6964 "sbb{w}\t{%2, %0|%0, %2}"
6965 [(set_attr "type" "alu")
6966 (set_attr "pent_pair" "pu")
6967 (set_attr "ppro_uops" "few")
6968 (set_attr "mode" "HI")])
6969
6970 (define_insn "subsi3_carry"
6971 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6972 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6973 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6974 (match_operand:SI 2 "general_operand" "ri,rm"))))
6975 (clobber (reg:CC 17))]
6976 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6977 "sbb{l}\t{%2, %0|%0, %2}"
6978 [(set_attr "type" "alu")
6979 (set_attr "pent_pair" "pu")
6980 (set_attr "ppro_uops" "few")
6981 (set_attr "mode" "SI")])
6982
6983 (define_insn "subsi3_carry_zext"
6984 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6985 (zero_extend:DI
6986 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6987 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6988 (match_operand:SI 2 "general_operand" "ri,rm")))))
6989 (clobber (reg:CC 17))]
6990 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6991 "sbb{l}\t{%2, %k0|%k0, %2}"
6992 [(set_attr "type" "alu")
6993 (set_attr "pent_pair" "pu")
6994 (set_attr "ppro_uops" "few")
6995 (set_attr "mode" "SI")])
6996
6997 (define_expand "subsi3"
6998 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6999 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7000 (match_operand:SI 2 "general_operand" "")))
7001 (clobber (reg:CC 17))])]
7002 ""
7003 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7004
7005 (define_insn "*subsi_1"
7006 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7007 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7008 (match_operand:SI 2 "general_operand" "ri,rm")))
7009 (clobber (reg:CC 17))]
7010 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7011 "sub{l}\t{%2, %0|%0, %2}"
7012 [(set_attr "type" "alu")
7013 (set_attr "mode" "SI")])
7014
7015 (define_insn "*subsi_1_zext"
7016 [(set (match_operand:DI 0 "register_operand" "=r")
7017 (zero_extend:DI
7018 (minus:SI (match_operand:SI 1 "register_operand" "0")
7019 (match_operand:SI 2 "general_operand" "rim"))))
7020 (clobber (reg:CC 17))]
7021 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7022 "sub{l}\t{%2, %k0|%k0, %2}"
7023 [(set_attr "type" "alu")
7024 (set_attr "mode" "SI")])
7025
7026 (define_insn "*subsi_2"
7027 [(set (reg 17)
7028 (compare
7029 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7030 (match_operand:SI 2 "general_operand" "ri,rm"))
7031 (const_int 0)))
7032 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7033 (minus:SI (match_dup 1) (match_dup 2)))]
7034 "ix86_match_ccmode (insn, CCGOCmode)
7035 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7036 "sub{l}\t{%2, %0|%0, %2}"
7037 [(set_attr "type" "alu")
7038 (set_attr "mode" "SI")])
7039
7040 (define_insn "*subsi_2_zext"
7041 [(set (reg 17)
7042 (compare
7043 (minus:SI (match_operand:SI 1 "register_operand" "0")
7044 (match_operand:SI 2 "general_operand" "rim"))
7045 (const_int 0)))
7046 (set (match_operand:DI 0 "register_operand" "=r")
7047 (zero_extend:DI
7048 (minus:SI (match_dup 1)
7049 (match_dup 2))))]
7050 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7051 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7052 "sub{l}\t{%2, %k0|%k0, %2}"
7053 [(set_attr "type" "alu")
7054 (set_attr "mode" "SI")])
7055
7056 (define_insn "*subsi_3"
7057 [(set (reg 17)
7058 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7059 (match_operand:SI 2 "general_operand" "ri,rm")))
7060 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7061 (minus:SI (match_dup 1) (match_dup 2)))]
7062 "ix86_match_ccmode (insn, CCmode)
7063 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7064 "sub{l}\t{%2, %0|%0, %2}"
7065 [(set_attr "type" "alu")
7066 (set_attr "mode" "SI")])
7067
7068 (define_insn "*subsi_3_zext"
7069 [(set (reg 17)
7070 (compare (match_operand:SI 1 "register_operand" "0")
7071 (match_operand:SI 2 "general_operand" "rim")))
7072 (set (match_operand:DI 0 "register_operand" "=r")
7073 (zero_extend:DI
7074 (minus:SI (match_dup 1)
7075 (match_dup 2))))]
7076 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7077 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7078 "sub{q}\t{%2, %0|%0, %2}"
7079 [(set_attr "type" "alu")
7080 (set_attr "mode" "DI")])
7081
7082 (define_expand "subhi3"
7083 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7084 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7085 (match_operand:HI 2 "general_operand" "")))
7086 (clobber (reg:CC 17))])]
7087 "TARGET_HIMODE_MATH"
7088 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7089
7090 (define_insn "*subhi_1"
7091 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7092 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7093 (match_operand:HI 2 "general_operand" "ri,rm")))
7094 (clobber (reg:CC 17))]
7095 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7096 "sub{w}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "alu")
7098 (set_attr "mode" "HI")])
7099
7100 (define_insn "*subhi_2"
7101 [(set (reg 17)
7102 (compare
7103 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7104 (match_operand:HI 2 "general_operand" "ri,rm"))
7105 (const_int 0)))
7106 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7107 (minus:HI (match_dup 1) (match_dup 2)))]
7108 "ix86_match_ccmode (insn, CCGOCmode)
7109 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7110 "sub{w}\t{%2, %0|%0, %2}"
7111 [(set_attr "type" "alu")
7112 (set_attr "mode" "HI")])
7113
7114 (define_insn "*subhi_3"
7115 [(set (reg 17)
7116 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7117 (match_operand:HI 2 "general_operand" "ri,rm")))
7118 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7119 (minus:HI (match_dup 1) (match_dup 2)))]
7120 "ix86_match_ccmode (insn, CCmode)
7121 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7122 "sub{w}\t{%2, %0|%0, %2}"
7123 [(set_attr "type" "alu")
7124 (set_attr "mode" "HI")])
7125
7126 (define_expand "subqi3"
7127 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7128 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7129 (match_operand:QI 2 "general_operand" "")))
7130 (clobber (reg:CC 17))])]
7131 "TARGET_QIMODE_MATH"
7132 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7133
7134 (define_insn "*subqi_1"
7135 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7136 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7137 (match_operand:QI 2 "general_operand" "qn,qmn")))
7138 (clobber (reg:CC 17))]
7139 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7140 "sub{b}\t{%2, %0|%0, %2}"
7141 [(set_attr "type" "alu")
7142 (set_attr "mode" "QI")])
7143
7144 (define_insn "*subqi_1_slp"
7145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7146 (minus:QI (match_dup 0)
7147 (match_operand:QI 1 "general_operand" "qn,qmn")))
7148 (clobber (reg:CC 17))]
7149 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7150 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7151 "sub{b}\t{%1, %0|%0, %1}"
7152 [(set_attr "type" "alu1")
7153 (set_attr "mode" "QI")])
7154
7155 (define_insn "*subqi_2"
7156 [(set (reg 17)
7157 (compare
7158 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7159 (match_operand:QI 2 "general_operand" "qi,qm"))
7160 (const_int 0)))
7161 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7162 (minus:HI (match_dup 1) (match_dup 2)))]
7163 "ix86_match_ccmode (insn, CCGOCmode)
7164 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7165 "sub{b}\t{%2, %0|%0, %2}"
7166 [(set_attr "type" "alu")
7167 (set_attr "mode" "QI")])
7168
7169 (define_insn "*subqi_3"
7170 [(set (reg 17)
7171 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7172 (match_operand:QI 2 "general_operand" "qi,qm")))
7173 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7174 (minus:HI (match_dup 1) (match_dup 2)))]
7175 "ix86_match_ccmode (insn, CCmode)
7176 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7177 "sub{b}\t{%2, %0|%0, %2}"
7178 [(set_attr "type" "alu")
7179 (set_attr "mode" "QI")])
7180
7181 ;; The patterns that match these are at the end of this file.
7182
7183 (define_expand "subxf3"
7184 [(set (match_operand:XF 0 "register_operand" "")
7185 (minus:XF (match_operand:XF 1 "register_operand" "")
7186 (match_operand:XF 2 "register_operand" "")))]
7187 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7188 "")
7189
7190 (define_expand "subtf3"
7191 [(set (match_operand:TF 0 "register_operand" "")
7192 (minus:TF (match_operand:TF 1 "register_operand" "")
7193 (match_operand:TF 2 "register_operand" "")))]
7194 "TARGET_80387"
7195 "")
7196
7197 (define_expand "subdf3"
7198 [(set (match_operand:DF 0 "register_operand" "")
7199 (minus:DF (match_operand:DF 1 "register_operand" "")
7200 (match_operand:DF 2 "nonimmediate_operand" "")))]
7201 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7202 "")
7203
7204 (define_expand "subsf3"
7205 [(set (match_operand:SF 0 "register_operand" "")
7206 (minus:SF (match_operand:SF 1 "register_operand" "")
7207 (match_operand:SF 2 "nonimmediate_operand" "")))]
7208 "TARGET_80387 || TARGET_SSE_MATH"
7209 "")
7210 \f
7211 ;; Multiply instructions
7212
7213 (define_expand "muldi3"
7214 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7215 (mult:DI (match_operand:DI 1 "register_operand" "")
7216 (match_operand:DI 2 "x86_64_general_operand" "")))
7217 (clobber (reg:CC 17))])]
7218 "TARGET_64BIT"
7219 "")
7220
7221 (define_insn "*muldi3_1_rex64"
7222 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7223 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7224 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7225 (clobber (reg:CC 17))]
7226 "TARGET_64BIT
7227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7228 "@
7229 imul{q}\t{%2, %1, %0|%0, %1, %2}
7230 imul{q}\t{%2, %1, %0|%0, %1, %2}
7231 imul{q}\t{%2, %0|%0, %2}"
7232 [(set_attr "type" "imul")
7233 (set_attr "prefix_0f" "0,0,1")
7234 (set (attr "athlon_decode")
7235 (cond [(eq_attr "cpu" "athlon")
7236 (const_string "vector")
7237 (eq_attr "alternative" "1")
7238 (const_string "vector")
7239 (and (eq_attr "alternative" "2")
7240 (match_operand 1 "memory_operand" ""))
7241 (const_string "vector")]
7242 (const_string "direct")))
7243 (set_attr "mode" "DI")])
7244
7245 (define_expand "mulsi3"
7246 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7247 (mult:SI (match_operand:SI 1 "register_operand" "")
7248 (match_operand:SI 2 "general_operand" "")))
7249 (clobber (reg:CC 17))])]
7250 ""
7251 "")
7252
7253 (define_insn "*mulsi3_1"
7254 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7255 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7256 (match_operand:SI 2 "general_operand" "K,i,mr")))
7257 (clobber (reg:CC 17))]
7258 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7259 "@
7260 imul{l}\t{%2, %1, %0|%0, %1, %2}
7261 imul{l}\t{%2, %1, %0|%0, %1, %2}
7262 imul{l}\t{%2, %0|%0, %2}"
7263 [(set_attr "type" "imul")
7264 (set_attr "prefix_0f" "0,0,1")
7265 (set (attr "athlon_decode")
7266 (cond [(eq_attr "cpu" "athlon")
7267 (const_string "vector")
7268 (eq_attr "alternative" "1")
7269 (const_string "vector")
7270 (and (eq_attr "alternative" "2")
7271 (match_operand 1 "memory_operand" ""))
7272 (const_string "vector")]
7273 (const_string "direct")))
7274 (set_attr "mode" "SI")])
7275
7276 (define_insn "*mulsi3_1_zext"
7277 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7278 (zero_extend:DI
7279 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7280 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7281 (clobber (reg:CC 17))]
7282 "TARGET_64BIT
7283 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7284 "@
7285 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7286 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7287 imul{l}\t{%2, %k0|%k0, %2}"
7288 [(set_attr "type" "imul")
7289 (set_attr "prefix_0f" "0,0,1")
7290 (set (attr "athlon_decode")
7291 (cond [(eq_attr "cpu" "athlon")
7292 (const_string "vector")
7293 (eq_attr "alternative" "1")
7294 (const_string "vector")
7295 (and (eq_attr "alternative" "2")
7296 (match_operand 1 "memory_operand" ""))
7297 (const_string "vector")]
7298 (const_string "direct")))
7299 (set_attr "mode" "SI")])
7300
7301 (define_expand "mulhi3"
7302 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7303 (mult:HI (match_operand:HI 1 "register_operand" "")
7304 (match_operand:HI 2 "general_operand" "")))
7305 (clobber (reg:CC 17))])]
7306 "TARGET_HIMODE_MATH"
7307 "")
7308
7309 (define_insn "*mulhi3_1"
7310 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7311 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7312 (match_operand:HI 2 "general_operand" "K,i,mr")))
7313 (clobber (reg:CC 17))]
7314 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7315 "@
7316 imul{w}\t{%2, %1, %0|%0, %1, %2}
7317 imul{w}\t{%2, %1, %0|%0, %1, %2}
7318 imul{w}\t{%2, %0|%0, %2}"
7319 [(set_attr "type" "imul")
7320 (set_attr "prefix_0f" "0,0,1")
7321 (set (attr "athlon_decode")
7322 (cond [(eq_attr "cpu" "athlon")
7323 (const_string "vector")
7324 (eq_attr "alternative" "1,2")
7325 (const_string "vector")]
7326 (const_string "direct")))
7327 (set_attr "mode" "HI")])
7328
7329 (define_expand "mulqi3"
7330 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7331 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7332 (match_operand:QI 2 "register_operand" "")))
7333 (clobber (reg:CC 17))])]
7334 "TARGET_QIMODE_MATH"
7335 "")
7336
7337 (define_insn "*mulqi3_1"
7338 [(set (match_operand:QI 0 "register_operand" "=a")
7339 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7340 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7341 (clobber (reg:CC 17))]
7342 "TARGET_QIMODE_MATH
7343 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7344 "mul{b}\t%2"
7345 [(set_attr "type" "imul")
7346 (set_attr "length_immediate" "0")
7347 (set (attr "athlon_decode")
7348 (if_then_else (eq_attr "cpu" "athlon")
7349 (const_string "vector")
7350 (const_string "direct")))
7351 (set_attr "mode" "QI")])
7352
7353 (define_expand "umulqihi3"
7354 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7355 (mult:HI (zero_extend:HI
7356 (match_operand:QI 1 "nonimmediate_operand" ""))
7357 (zero_extend:HI
7358 (match_operand:QI 2 "register_operand" ""))))
7359 (clobber (reg:CC 17))])]
7360 "TARGET_QIMODE_MATH"
7361 "")
7362
7363 (define_insn "*umulqihi3_1"
7364 [(set (match_operand:HI 0 "register_operand" "=a")
7365 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7366 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7367 (clobber (reg:CC 17))]
7368 "TARGET_QIMODE_MATH
7369 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7370 "mul{b}\t%2"
7371 [(set_attr "type" "imul")
7372 (set_attr "length_immediate" "0")
7373 (set (attr "athlon_decode")
7374 (if_then_else (eq_attr "cpu" "athlon")
7375 (const_string "vector")
7376 (const_string "direct")))
7377 (set_attr "mode" "QI")])
7378
7379 (define_expand "mulqihi3"
7380 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7381 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7382 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7383 (clobber (reg:CC 17))])]
7384 "TARGET_QIMODE_MATH"
7385 "")
7386
7387 (define_insn "*mulqihi3_insn"
7388 [(set (match_operand:HI 0 "register_operand" "=a")
7389 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7390 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7391 (clobber (reg:CC 17))]
7392 "TARGET_QIMODE_MATH
7393 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7394 "imul{b}\t%2"
7395 [(set_attr "type" "imul")
7396 (set_attr "length_immediate" "0")
7397 (set (attr "athlon_decode")
7398 (if_then_else (eq_attr "cpu" "athlon")
7399 (const_string "vector")
7400 (const_string "direct")))
7401 (set_attr "mode" "QI")])
7402
7403 (define_expand "umulditi3"
7404 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7405 (mult:TI (zero_extend:TI
7406 (match_operand:DI 1 "nonimmediate_operand" ""))
7407 (zero_extend:TI
7408 (match_operand:DI 2 "register_operand" ""))))
7409 (clobber (reg:CC 17))])]
7410 "TARGET_64BIT"
7411 "")
7412
7413 (define_insn "*umulditi3_insn"
7414 [(set (match_operand:TI 0 "register_operand" "=A")
7415 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7416 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7417 (clobber (reg:CC 17))]
7418 "TARGET_64BIT
7419 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7420 "mul{q}\t%2"
7421 [(set_attr "type" "imul")
7422 (set_attr "ppro_uops" "few")
7423 (set_attr "length_immediate" "0")
7424 (set (attr "athlon_decode")
7425 (if_then_else (eq_attr "cpu" "athlon")
7426 (const_string "vector")
7427 (const_string "double")))
7428 (set_attr "mode" "DI")])
7429
7430 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7431 (define_expand "umulsidi3"
7432 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7433 (mult:DI (zero_extend:DI
7434 (match_operand:SI 1 "nonimmediate_operand" ""))
7435 (zero_extend:DI
7436 (match_operand:SI 2 "register_operand" ""))))
7437 (clobber (reg:CC 17))])]
7438 "!TARGET_64BIT"
7439 "")
7440
7441 (define_insn "*umulsidi3_insn"
7442 [(set (match_operand:DI 0 "register_operand" "=A")
7443 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7444 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7445 (clobber (reg:CC 17))]
7446 "!TARGET_64BIT
7447 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7448 "mul{l}\t%2"
7449 [(set_attr "type" "imul")
7450 (set_attr "ppro_uops" "few")
7451 (set_attr "length_immediate" "0")
7452 (set (attr "athlon_decode")
7453 (if_then_else (eq_attr "cpu" "athlon")
7454 (const_string "vector")
7455 (const_string "double")))
7456 (set_attr "mode" "SI")])
7457
7458 (define_expand "mulditi3"
7459 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7460 (mult:TI (sign_extend:TI
7461 (match_operand:DI 1 "nonimmediate_operand" ""))
7462 (sign_extend:TI
7463 (match_operand:DI 2 "register_operand" ""))))
7464 (clobber (reg:CC 17))])]
7465 "TARGET_64BIT"
7466 "")
7467
7468 (define_insn "*mulditi3_insn"
7469 [(set (match_operand:TI 0 "register_operand" "=A")
7470 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7471 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7472 (clobber (reg:CC 17))]
7473 "TARGET_64BIT
7474 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7475 "imul{q}\t%2"
7476 [(set_attr "type" "imul")
7477 (set_attr "length_immediate" "0")
7478 (set (attr "athlon_decode")
7479 (if_then_else (eq_attr "cpu" "athlon")
7480 (const_string "vector")
7481 (const_string "double")))
7482 (set_attr "mode" "DI")])
7483
7484 (define_expand "mulsidi3"
7485 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7486 (mult:DI (sign_extend:DI
7487 (match_operand:SI 1 "nonimmediate_operand" ""))
7488 (sign_extend:DI
7489 (match_operand:SI 2 "register_operand" ""))))
7490 (clobber (reg:CC 17))])]
7491 "!TARGET_64BIT"
7492 "")
7493
7494 (define_insn "*mulsidi3_insn"
7495 [(set (match_operand:DI 0 "register_operand" "=A")
7496 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7497 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7498 (clobber (reg:CC 17))]
7499 "!TARGET_64BIT
7500 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7501 "imul{l}\t%2"
7502 [(set_attr "type" "imul")
7503 (set_attr "length_immediate" "0")
7504 (set (attr "athlon_decode")
7505 (if_then_else (eq_attr "cpu" "athlon")
7506 (const_string "vector")
7507 (const_string "double")))
7508 (set_attr "mode" "SI")])
7509
7510 (define_expand "umuldi3_highpart"
7511 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7512 (truncate:DI
7513 (lshiftrt:TI
7514 (mult:TI (zero_extend:TI
7515 (match_operand:DI 1 "nonimmediate_operand" ""))
7516 (zero_extend:TI
7517 (match_operand:DI 2 "register_operand" "")))
7518 (const_int 64))))
7519 (clobber (match_scratch:DI 3 ""))
7520 (clobber (reg:CC 17))])]
7521 "TARGET_64BIT"
7522 "")
7523
7524 (define_insn "*umuldi3_highpart_rex64"
7525 [(set (match_operand:DI 0 "register_operand" "=d")
7526 (truncate:DI
7527 (lshiftrt:TI
7528 (mult:TI (zero_extend:TI
7529 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7530 (zero_extend:TI
7531 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7532 (const_int 64))))
7533 (clobber (match_scratch:DI 3 "=1"))
7534 (clobber (reg:CC 17))]
7535 "TARGET_64BIT
7536 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7537 "mul{q}\t%2"
7538 [(set_attr "type" "imul")
7539 (set_attr "ppro_uops" "few")
7540 (set_attr "length_immediate" "0")
7541 (set (attr "athlon_decode")
7542 (if_then_else (eq_attr "cpu" "athlon")
7543 (const_string "vector")
7544 (const_string "double")))
7545 (set_attr "mode" "DI")])
7546
7547 (define_expand "umulsi3_highpart"
7548 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7549 (truncate:SI
7550 (lshiftrt:DI
7551 (mult:DI (zero_extend:DI
7552 (match_operand:SI 1 "nonimmediate_operand" ""))
7553 (zero_extend:DI
7554 (match_operand:SI 2 "register_operand" "")))
7555 (const_int 32))))
7556 (clobber (match_scratch:SI 3 ""))
7557 (clobber (reg:CC 17))])]
7558 ""
7559 "")
7560
7561 (define_insn "*umulsi3_highpart_insn"
7562 [(set (match_operand:SI 0 "register_operand" "=d")
7563 (truncate:SI
7564 (lshiftrt:DI
7565 (mult:DI (zero_extend:DI
7566 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7567 (zero_extend:DI
7568 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7569 (const_int 32))))
7570 (clobber (match_scratch:SI 3 "=1"))
7571 (clobber (reg:CC 17))]
7572 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7573 "mul{l}\t%2"
7574 [(set_attr "type" "imul")
7575 (set_attr "ppro_uops" "few")
7576 (set_attr "length_immediate" "0")
7577 (set (attr "athlon_decode")
7578 (if_then_else (eq_attr "cpu" "athlon")
7579 (const_string "vector")
7580 (const_string "double")))
7581 (set_attr "mode" "SI")])
7582
7583 (define_insn "*umulsi3_highpart_zext"
7584 [(set (match_operand:DI 0 "register_operand" "=d")
7585 (zero_extend:DI (truncate:SI
7586 (lshiftrt:DI
7587 (mult:DI (zero_extend:DI
7588 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7589 (zero_extend:DI
7590 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591 (const_int 32)))))
7592 (clobber (match_scratch:SI 3 "=1"))
7593 (clobber (reg:CC 17))]
7594 "TARGET_64BIT
7595 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7596 "mul{l}\t%2"
7597 [(set_attr "type" "imul")
7598 (set_attr "ppro_uops" "few")
7599 (set_attr "length_immediate" "0")
7600 (set (attr "athlon_decode")
7601 (if_then_else (eq_attr "cpu" "athlon")
7602 (const_string "vector")
7603 (const_string "double")))
7604 (set_attr "mode" "SI")])
7605
7606 (define_expand "smuldi3_highpart"
7607 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7608 (truncate:DI
7609 (lshiftrt:TI
7610 (mult:TI (sign_extend:TI
7611 (match_operand:DI 1 "nonimmediate_operand" ""))
7612 (sign_extend:TI
7613 (match_operand:DI 2 "register_operand" "")))
7614 (const_int 64))))
7615 (clobber (match_scratch:DI 3 ""))
7616 (clobber (reg:CC 17))])]
7617 "TARGET_64BIT"
7618 "")
7619
7620 (define_insn "*smuldi3_highpart_rex64"
7621 [(set (match_operand:DI 0 "register_operand" "=d")
7622 (truncate:DI
7623 (lshiftrt:TI
7624 (mult:TI (sign_extend:TI
7625 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7626 (sign_extend:TI
7627 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7628 (const_int 64))))
7629 (clobber (match_scratch:DI 3 "=1"))
7630 (clobber (reg:CC 17))]
7631 "TARGET_64BIT
7632 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7633 "imul{q}\t%2"
7634 [(set_attr "type" "imul")
7635 (set_attr "ppro_uops" "few")
7636 (set (attr "athlon_decode")
7637 (if_then_else (eq_attr "cpu" "athlon")
7638 (const_string "vector")
7639 (const_string "double")))
7640 (set_attr "mode" "DI")])
7641
7642 (define_expand "smulsi3_highpart"
7643 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7644 (truncate:SI
7645 (lshiftrt:DI
7646 (mult:DI (sign_extend:DI
7647 (match_operand:SI 1 "nonimmediate_operand" ""))
7648 (sign_extend:DI
7649 (match_operand:SI 2 "register_operand" "")))
7650 (const_int 32))))
7651 (clobber (match_scratch:SI 3 ""))
7652 (clobber (reg:CC 17))])]
7653 ""
7654 "")
7655
7656 (define_insn "*smulsi3_highpart_insn"
7657 [(set (match_operand:SI 0 "register_operand" "=d")
7658 (truncate:SI
7659 (lshiftrt:DI
7660 (mult:DI (sign_extend:DI
7661 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7662 (sign_extend:DI
7663 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7664 (const_int 32))))
7665 (clobber (match_scratch:SI 3 "=1"))
7666 (clobber (reg:CC 17))]
7667 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7668 "imul{l}\t%2"
7669 [(set_attr "type" "imul")
7670 (set_attr "ppro_uops" "few")
7671 (set (attr "athlon_decode")
7672 (if_then_else (eq_attr "cpu" "athlon")
7673 (const_string "vector")
7674 (const_string "double")))
7675 (set_attr "mode" "SI")])
7676
7677 (define_insn "*smulsi3_highpart_zext"
7678 [(set (match_operand:DI 0 "register_operand" "=d")
7679 (zero_extend:DI (truncate:SI
7680 (lshiftrt:DI
7681 (mult:DI (sign_extend:DI
7682 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7683 (sign_extend:DI
7684 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7685 (const_int 32)))))
7686 (clobber (match_scratch:SI 3 "=1"))
7687 (clobber (reg:CC 17))]
7688 "TARGET_64BIT
7689 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7690 "imul{l}\t%2"
7691 [(set_attr "type" "imul")
7692 (set_attr "ppro_uops" "few")
7693 (set (attr "athlon_decode")
7694 (if_then_else (eq_attr "cpu" "athlon")
7695 (const_string "vector")
7696 (const_string "double")))
7697 (set_attr "mode" "SI")])
7698
7699 ;; The patterns that match these are at the end of this file.
7700
7701 (define_expand "mulxf3"
7702 [(set (match_operand:XF 0 "register_operand" "")
7703 (mult:XF (match_operand:XF 1 "register_operand" "")
7704 (match_operand:XF 2 "register_operand" "")))]
7705 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7706 "")
7707
7708 (define_expand "multf3"
7709 [(set (match_operand:TF 0 "register_operand" "")
7710 (mult:TF (match_operand:TF 1 "register_operand" "")
7711 (match_operand:TF 2 "register_operand" "")))]
7712 "TARGET_80387"
7713 "")
7714
7715 (define_expand "muldf3"
7716 [(set (match_operand:DF 0 "register_operand" "")
7717 (mult:DF (match_operand:DF 1 "register_operand" "")
7718 (match_operand:DF 2 "nonimmediate_operand" "")))]
7719 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7720 "")
7721
7722 (define_expand "mulsf3"
7723 [(set (match_operand:SF 0 "register_operand" "")
7724 (mult:SF (match_operand:SF 1 "register_operand" "")
7725 (match_operand:SF 2 "nonimmediate_operand" "")))]
7726 "TARGET_80387 || TARGET_SSE_MATH"
7727 "")
7728 \f
7729 ;; Divide instructions
7730
7731 (define_insn "divqi3"
7732 [(set (match_operand:QI 0 "register_operand" "=a")
7733 (div:QI (match_operand:HI 1 "register_operand" "0")
7734 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7735 (clobber (reg:CC 17))]
7736 "TARGET_QIMODE_MATH"
7737 "idiv{b}\t%2"
7738 [(set_attr "type" "idiv")
7739 (set_attr "mode" "QI")
7740 (set_attr "ppro_uops" "few")])
7741
7742 (define_insn "udivqi3"
7743 [(set (match_operand:QI 0 "register_operand" "=a")
7744 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7745 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7746 (clobber (reg:CC 17))]
7747 "TARGET_QIMODE_MATH"
7748 "div{b}\t%2"
7749 [(set_attr "type" "idiv")
7750 (set_attr "mode" "QI")
7751 (set_attr "ppro_uops" "few")])
7752
7753 ;; The patterns that match these are at the end of this file.
7754
7755 (define_expand "divxf3"
7756 [(set (match_operand:XF 0 "register_operand" "")
7757 (div:XF (match_operand:XF 1 "register_operand" "")
7758 (match_operand:XF 2 "register_operand" "")))]
7759 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7760 "")
7761
7762 (define_expand "divtf3"
7763 [(set (match_operand:TF 0 "register_operand" "")
7764 (div:TF (match_operand:TF 1 "register_operand" "")
7765 (match_operand:TF 2 "register_operand" "")))]
7766 "TARGET_80387"
7767 "")
7768
7769 (define_expand "divdf3"
7770 [(set (match_operand:DF 0 "register_operand" "")
7771 (div:DF (match_operand:DF 1 "register_operand" "")
7772 (match_operand:DF 2 "nonimmediate_operand" "")))]
7773 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7774 "")
7775
7776 (define_expand "divsf3"
7777 [(set (match_operand:SF 0 "register_operand" "")
7778 (div:SF (match_operand:SF 1 "register_operand" "")
7779 (match_operand:SF 2 "nonimmediate_operand" "")))]
7780 "TARGET_80387 || TARGET_SSE_MATH"
7781 "")
7782 \f
7783 ;; Remainder instructions.
7784
7785 (define_expand "divmoddi4"
7786 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7787 (div:DI (match_operand:DI 1 "register_operand" "")
7788 (match_operand:DI 2 "nonimmediate_operand" "")))
7789 (set (match_operand:DI 3 "register_operand" "")
7790 (mod:DI (match_dup 1) (match_dup 2)))
7791 (clobber (reg:CC 17))])]
7792 "TARGET_64BIT"
7793 "")
7794
7795 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7796 ;; Penalize eax case slightly because it results in worse scheduling
7797 ;; of code.
7798 (define_insn "*divmoddi4_nocltd_rex64"
7799 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7800 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7801 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7802 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7803 (mod:DI (match_dup 2) (match_dup 3)))
7804 (clobber (reg:CC 17))]
7805 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7806 "#"
7807 [(set_attr "type" "multi")])
7808
7809 (define_insn "*divmoddi4_cltd_rex64"
7810 [(set (match_operand:DI 0 "register_operand" "=a")
7811 (div:DI (match_operand:DI 2 "register_operand" "a")
7812 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7813 (set (match_operand:DI 1 "register_operand" "=&d")
7814 (mod:DI (match_dup 2) (match_dup 3)))
7815 (clobber (reg:CC 17))]
7816 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7817 "#"
7818 [(set_attr "type" "multi")])
7819
7820 (define_insn "*divmoddi_noext_rex64"
7821 [(set (match_operand:DI 0 "register_operand" "=a")
7822 (div:DI (match_operand:DI 1 "register_operand" "0")
7823 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7824 (set (match_operand:DI 3 "register_operand" "=d")
7825 (mod:DI (match_dup 1) (match_dup 2)))
7826 (use (match_operand:DI 4 "register_operand" "3"))
7827 (clobber (reg:CC 17))]
7828 "TARGET_64BIT"
7829 "idiv{q}\t%2"
7830 [(set_attr "type" "idiv")
7831 (set_attr "mode" "DI")
7832 (set_attr "ppro_uops" "few")])
7833
7834 (define_split
7835 [(set (match_operand:DI 0 "register_operand" "")
7836 (div:DI (match_operand:DI 1 "register_operand" "")
7837 (match_operand:DI 2 "nonimmediate_operand" "")))
7838 (set (match_operand:DI 3 "register_operand" "")
7839 (mod:DI (match_dup 1) (match_dup 2)))
7840 (clobber (reg:CC 17))]
7841 "TARGET_64BIT && reload_completed"
7842 [(parallel [(set (match_dup 3)
7843 (ashiftrt:DI (match_dup 4) (const_int 63)))
7844 (clobber (reg:CC 17))])
7845 (parallel [(set (match_dup 0)
7846 (div:DI (reg:DI 0) (match_dup 2)))
7847 (set (match_dup 3)
7848 (mod:DI (reg:DI 0) (match_dup 2)))
7849 (use (match_dup 3))
7850 (clobber (reg:CC 17))])]
7851 {
7852 /* Avoid use of cltd in favor of a mov+shift. */
7853 if (!TARGET_USE_CLTD && !optimize_size)
7854 {
7855 if (true_regnum (operands[1]))
7856 emit_move_insn (operands[0], operands[1]);
7857 else
7858 emit_move_insn (operands[3], operands[1]);
7859 operands[4] = operands[3];
7860 }
7861 else
7862 {
7863 if (true_regnum (operands[1]))
7864 abort();
7865 operands[4] = operands[1];
7866 }
7867 })
7868
7869
7870 (define_expand "divmodsi4"
7871 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7872 (div:SI (match_operand:SI 1 "register_operand" "")
7873 (match_operand:SI 2 "nonimmediate_operand" "")))
7874 (set (match_operand:SI 3 "register_operand" "")
7875 (mod:SI (match_dup 1) (match_dup 2)))
7876 (clobber (reg:CC 17))])]
7877 ""
7878 "")
7879
7880 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7881 ;; Penalize eax case slightly because it results in worse scheduling
7882 ;; of code.
7883 (define_insn "*divmodsi4_nocltd"
7884 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7885 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7886 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7887 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7888 (mod:SI (match_dup 2) (match_dup 3)))
7889 (clobber (reg:CC 17))]
7890 "!optimize_size && !TARGET_USE_CLTD"
7891 "#"
7892 [(set_attr "type" "multi")])
7893
7894 (define_insn "*divmodsi4_cltd"
7895 [(set (match_operand:SI 0 "register_operand" "=a")
7896 (div:SI (match_operand:SI 2 "register_operand" "a")
7897 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7898 (set (match_operand:SI 1 "register_operand" "=&d")
7899 (mod:SI (match_dup 2) (match_dup 3)))
7900 (clobber (reg:CC 17))]
7901 "optimize_size || TARGET_USE_CLTD"
7902 "#"
7903 [(set_attr "type" "multi")])
7904
7905 (define_insn "*divmodsi_noext"
7906 [(set (match_operand:SI 0 "register_operand" "=a")
7907 (div:SI (match_operand:SI 1 "register_operand" "0")
7908 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7909 (set (match_operand:SI 3 "register_operand" "=d")
7910 (mod:SI (match_dup 1) (match_dup 2)))
7911 (use (match_operand:SI 4 "register_operand" "3"))
7912 (clobber (reg:CC 17))]
7913 ""
7914 "idiv{l}\t%2"
7915 [(set_attr "type" "idiv")
7916 (set_attr "mode" "SI")
7917 (set_attr "ppro_uops" "few")])
7918
7919 (define_split
7920 [(set (match_operand:SI 0 "register_operand" "")
7921 (div:SI (match_operand:SI 1 "register_operand" "")
7922 (match_operand:SI 2 "nonimmediate_operand" "")))
7923 (set (match_operand:SI 3 "register_operand" "")
7924 (mod:SI (match_dup 1) (match_dup 2)))
7925 (clobber (reg:CC 17))]
7926 "reload_completed"
7927 [(parallel [(set (match_dup 3)
7928 (ashiftrt:SI (match_dup 4) (const_int 31)))
7929 (clobber (reg:CC 17))])
7930 (parallel [(set (match_dup 0)
7931 (div:SI (reg:SI 0) (match_dup 2)))
7932 (set (match_dup 3)
7933 (mod:SI (reg:SI 0) (match_dup 2)))
7934 (use (match_dup 3))
7935 (clobber (reg:CC 17))])]
7936 {
7937 /* Avoid use of cltd in favor of a mov+shift. */
7938 if (!TARGET_USE_CLTD && !optimize_size)
7939 {
7940 if (true_regnum (operands[1]))
7941 emit_move_insn (operands[0], operands[1]);
7942 else
7943 emit_move_insn (operands[3], operands[1]);
7944 operands[4] = operands[3];
7945 }
7946 else
7947 {
7948 if (true_regnum (operands[1]))
7949 abort();
7950 operands[4] = operands[1];
7951 }
7952 })
7953 ;; %%% Split me.
7954 (define_insn "divmodhi4"
7955 [(set (match_operand:HI 0 "register_operand" "=a")
7956 (div:HI (match_operand:HI 1 "register_operand" "0")
7957 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7958 (set (match_operand:HI 3 "register_operand" "=&d")
7959 (mod:HI (match_dup 1) (match_dup 2)))
7960 (clobber (reg:CC 17))]
7961 "TARGET_HIMODE_MATH"
7962 "cwtd\;idiv{w}\t%2"
7963 [(set_attr "type" "multi")
7964 (set_attr "length_immediate" "0")
7965 (set_attr "mode" "SI")])
7966
7967 (define_insn "udivmoddi4"
7968 [(set (match_operand:DI 0 "register_operand" "=a")
7969 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7970 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7971 (set (match_operand:DI 3 "register_operand" "=&d")
7972 (umod:DI (match_dup 1) (match_dup 2)))
7973 (clobber (reg:CC 17))]
7974 "TARGET_64BIT"
7975 "xor{q}\t%3, %3\;div{q}\t%2"
7976 [(set_attr "type" "multi")
7977 (set_attr "length_immediate" "0")
7978 (set_attr "mode" "DI")])
7979
7980 (define_insn "*udivmoddi4_noext"
7981 [(set (match_operand:DI 0 "register_operand" "=a")
7982 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7983 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7984 (set (match_operand:DI 3 "register_operand" "=d")
7985 (umod:DI (match_dup 1) (match_dup 2)))
7986 (use (match_dup 3))
7987 (clobber (reg:CC 17))]
7988 "TARGET_64BIT"
7989 "div{q}\t%2"
7990 [(set_attr "type" "idiv")
7991 (set_attr "ppro_uops" "few")
7992 (set_attr "mode" "DI")])
7993
7994 (define_split
7995 [(set (match_operand:DI 0 "register_operand" "")
7996 (udiv:DI (match_operand:DI 1 "register_operand" "")
7997 (match_operand:DI 2 "nonimmediate_operand" "")))
7998 (set (match_operand:DI 3 "register_operand" "")
7999 (umod:DI (match_dup 1) (match_dup 2)))
8000 (clobber (reg:CC 17))]
8001 "TARGET_64BIT && reload_completed"
8002 [(set (match_dup 3) (const_int 0))
8003 (parallel [(set (match_dup 0)
8004 (udiv:DI (match_dup 1) (match_dup 2)))
8005 (set (match_dup 3)
8006 (umod:DI (match_dup 1) (match_dup 2)))
8007 (use (match_dup 3))
8008 (clobber (reg:CC 17))])]
8009 "")
8010
8011 (define_insn "udivmodsi4"
8012 [(set (match_operand:SI 0 "register_operand" "=a")
8013 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8014 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8015 (set (match_operand:SI 3 "register_operand" "=&d")
8016 (umod:SI (match_dup 1) (match_dup 2)))
8017 (clobber (reg:CC 17))]
8018 ""
8019 "xor{l}\t%3, %3\;div{l}\t%2"
8020 [(set_attr "type" "multi")
8021 (set_attr "length_immediate" "0")
8022 (set_attr "mode" "SI")])
8023
8024 (define_insn "*udivmodsi4_noext"
8025 [(set (match_operand:SI 0 "register_operand" "=a")
8026 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8027 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8028 (set (match_operand:SI 3 "register_operand" "=d")
8029 (umod:SI (match_dup 1) (match_dup 2)))
8030 (use (match_dup 3))
8031 (clobber (reg:CC 17))]
8032 ""
8033 "div{l}\t%2"
8034 [(set_attr "type" "idiv")
8035 (set_attr "ppro_uops" "few")
8036 (set_attr "mode" "SI")])
8037
8038 (define_split
8039 [(set (match_operand:SI 0 "register_operand" "")
8040 (udiv:SI (match_operand:SI 1 "register_operand" "")
8041 (match_operand:SI 2 "nonimmediate_operand" "")))
8042 (set (match_operand:SI 3 "register_operand" "")
8043 (umod:SI (match_dup 1) (match_dup 2)))
8044 (clobber (reg:CC 17))]
8045 "reload_completed"
8046 [(set (match_dup 3) (const_int 0))
8047 (parallel [(set (match_dup 0)
8048 (udiv:SI (match_dup 1) (match_dup 2)))
8049 (set (match_dup 3)
8050 (umod:SI (match_dup 1) (match_dup 2)))
8051 (use (match_dup 3))
8052 (clobber (reg:CC 17))])]
8053 "")
8054
8055 (define_expand "udivmodhi4"
8056 [(set (match_dup 4) (const_int 0))
8057 (parallel [(set (match_operand:HI 0 "register_operand" "")
8058 (udiv:HI (match_operand:HI 1 "register_operand" "")
8059 (match_operand:HI 2 "nonimmediate_operand" "")))
8060 (set (match_operand:HI 3 "register_operand" "")
8061 (umod:HI (match_dup 1) (match_dup 2)))
8062 (use (match_dup 4))
8063 (clobber (reg:CC 17))])]
8064 "TARGET_HIMODE_MATH"
8065 "operands[4] = gen_reg_rtx (HImode);")
8066
8067 (define_insn "*udivmodhi_noext"
8068 [(set (match_operand:HI 0 "register_operand" "=a")
8069 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8070 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8071 (set (match_operand:HI 3 "register_operand" "=d")
8072 (umod:HI (match_dup 1) (match_dup 2)))
8073 (use (match_operand:HI 4 "register_operand" "3"))
8074 (clobber (reg:CC 17))]
8075 ""
8076 "div{w}\t%2"
8077 [(set_attr "type" "idiv")
8078 (set_attr "mode" "HI")
8079 (set_attr "ppro_uops" "few")])
8080
8081 ;; We can not use div/idiv for double division, because it causes
8082 ;; "division by zero" on the overflow and that's not what we expect
8083 ;; from truncate. Because true (non truncating) double division is
8084 ;; never generated, we can't create this insn anyway.
8085 ;
8086 ;(define_insn ""
8087 ; [(set (match_operand:SI 0 "register_operand" "=a")
8088 ; (truncate:SI
8089 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8090 ; (zero_extend:DI
8091 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8092 ; (set (match_operand:SI 3 "register_operand" "=d")
8093 ; (truncate:SI
8094 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8095 ; (clobber (reg:CC 17))]
8096 ; ""
8097 ; "div{l}\t{%2, %0|%0, %2}"
8098 ; [(set_attr "type" "idiv")
8099 ; (set_attr "ppro_uops" "few")])
8100 \f
8101 ;;- Logical AND instructions
8102
8103 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8104 ;; Note that this excludes ah.
8105
8106 (define_insn "*testdi_1_rex64"
8107 [(set (reg 17)
8108 (compare
8109 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8110 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8111 (const_int 0)))]
8112 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8113 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8114 "@
8115 test{l}\t{%k1, %k0|%k0, %k1}
8116 test{l}\t{%k1, %k0|%k0, %k1}
8117 test{q}\t{%1, %0|%0, %1}
8118 test{q}\t{%1, %0|%0, %1}
8119 test{q}\t{%1, %0|%0, %1}"
8120 [(set_attr "type" "test")
8121 (set_attr "modrm" "0,1,0,1,1")
8122 (set_attr "mode" "SI,SI,DI,DI,DI")
8123 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8124
8125 (define_insn "testsi_1"
8126 [(set (reg 17)
8127 (compare
8128 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8129 (match_operand:SI 1 "general_operand" "in,in,rin"))
8130 (const_int 0)))]
8131 "ix86_match_ccmode (insn, CCNOmode)
8132 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8133 "test{l}\t{%1, %0|%0, %1}"
8134 [(set_attr "type" "test")
8135 (set_attr "modrm" "0,1,1")
8136 (set_attr "mode" "SI")
8137 (set_attr "pent_pair" "uv,np,uv")])
8138
8139 (define_expand "testsi_ccno_1"
8140 [(set (reg:CCNO 17)
8141 (compare:CCNO
8142 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8143 (match_operand:SI 1 "nonmemory_operand" ""))
8144 (const_int 0)))]
8145 ""
8146 "")
8147
8148 (define_insn "*testhi_1"
8149 [(set (reg 17)
8150 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8151 (match_operand:HI 1 "general_operand" "n,n,rn"))
8152 (const_int 0)))]
8153 "ix86_match_ccmode (insn, CCNOmode)
8154 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8155 "test{w}\t{%1, %0|%0, %1}"
8156 [(set_attr "type" "test")
8157 (set_attr "modrm" "0,1,1")
8158 (set_attr "mode" "HI")
8159 (set_attr "pent_pair" "uv,np,uv")])
8160
8161 (define_expand "testqi_ccz_1"
8162 [(set (reg:CCZ 17)
8163 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8164 (match_operand:QI 1 "nonmemory_operand" ""))
8165 (const_int 0)))]
8166 ""
8167 "")
8168
8169 (define_insn "*testqi_1"
8170 [(set (reg 17)
8171 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8172 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8173 (const_int 0)))]
8174 "ix86_match_ccmode (insn, CCNOmode)
8175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8176 {
8177 if (which_alternative == 3)
8178 {
8179 if (GET_CODE (operands[1]) == CONST_INT
8180 && (INTVAL (operands[1]) & 0xffffff00))
8181 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8182 return "test{l}\t{%1, %k0|%k0, %1}";
8183 }
8184 return "test{b}\t{%1, %0|%0, %1}";
8185 }
8186 [(set_attr "type" "test")
8187 (set_attr "modrm" "0,1,1,1")
8188 (set_attr "mode" "QI,QI,QI,SI")
8189 (set_attr "pent_pair" "uv,np,uv,np")])
8190
8191 (define_expand "testqi_ext_ccno_0"
8192 [(set (reg:CCNO 17)
8193 (compare:CCNO
8194 (and:SI
8195 (zero_extract:SI
8196 (match_operand 0 "ext_register_operand" "")
8197 (const_int 8)
8198 (const_int 8))
8199 (match_operand 1 "const_int_operand" ""))
8200 (const_int 0)))]
8201 ""
8202 "")
8203
8204 (define_insn "*testqi_ext_0"
8205 [(set (reg 17)
8206 (compare
8207 (and:SI
8208 (zero_extract:SI
8209 (match_operand 0 "ext_register_operand" "Q")
8210 (const_int 8)
8211 (const_int 8))
8212 (match_operand 1 "const_int_operand" "n"))
8213 (const_int 0)))]
8214 "ix86_match_ccmode (insn, CCNOmode)"
8215 "test{b}\t{%1, %h0|%h0, %1}"
8216 [(set_attr "type" "test")
8217 (set_attr "mode" "QI")
8218 (set_attr "length_immediate" "1")
8219 (set_attr "pent_pair" "np")])
8220
8221 (define_insn "*testqi_ext_1"
8222 [(set (reg 17)
8223 (compare
8224 (and:SI
8225 (zero_extract:SI
8226 (match_operand 0 "ext_register_operand" "Q")
8227 (const_int 8)
8228 (const_int 8))
8229 (zero_extend:SI
8230 (match_operand:QI 1 "general_operand" "Qm")))
8231 (const_int 0)))]
8232 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8233 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8234 "test{b}\t{%1, %h0|%h0, %1}"
8235 [(set_attr "type" "test")
8236 (set_attr "mode" "QI")])
8237
8238 (define_insn "*testqi_ext_1_rex64"
8239 [(set (reg 17)
8240 (compare
8241 (and:SI
8242 (zero_extract:SI
8243 (match_operand 0 "ext_register_operand" "Q")
8244 (const_int 8)
8245 (const_int 8))
8246 (zero_extend:SI
8247 (match_operand:QI 1 "register_operand" "Q")))
8248 (const_int 0)))]
8249 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8250 "test{b}\t{%1, %h0|%h0, %1}"
8251 [(set_attr "type" "test")
8252 (set_attr "mode" "QI")])
8253
8254 (define_insn "*testqi_ext_2"
8255 [(set (reg 17)
8256 (compare
8257 (and:SI
8258 (zero_extract:SI
8259 (match_operand 0 "ext_register_operand" "Q")
8260 (const_int 8)
8261 (const_int 8))
8262 (zero_extract:SI
8263 (match_operand 1 "ext_register_operand" "Q")
8264 (const_int 8)
8265 (const_int 8)))
8266 (const_int 0)))]
8267 "ix86_match_ccmode (insn, CCNOmode)"
8268 "test{b}\t{%h1, %h0|%h0, %h1}"
8269 [(set_attr "type" "test")
8270 (set_attr "mode" "QI")])
8271
8272 ;; Combine likes to form bit extractions for some tests. Humor it.
8273 (define_insn "*testqi_ext_3"
8274 [(set (reg 17)
8275 (compare (zero_extract:SI
8276 (match_operand 0 "nonimmediate_operand" "rm")
8277 (match_operand:SI 1 "const_int_operand" "")
8278 (match_operand:SI 2 "const_int_operand" ""))
8279 (const_int 0)))]
8280 "ix86_match_ccmode (insn, CCNOmode)
8281 && (GET_MODE (operands[0]) == SImode
8282 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8283 || GET_MODE (operands[0]) == HImode
8284 || GET_MODE (operands[0]) == QImode)"
8285 "#")
8286
8287 (define_insn "*testqi_ext_3_rex64"
8288 [(set (reg 17)
8289 (compare (zero_extract:DI
8290 (match_operand 0 "nonimmediate_operand" "rm")
8291 (match_operand:DI 1 "const_int_operand" "")
8292 (match_operand:DI 2 "const_int_operand" ""))
8293 (const_int 0)))]
8294 "TARGET_64BIT
8295 && ix86_match_ccmode (insn, CCNOmode)
8296 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8297 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8298 /* Ensure that resulting mask is zero or sign extended operand. */
8299 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8300 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8301 && INTVAL (operands[1]) > 32))
8302 && (GET_MODE (operands[0]) == SImode
8303 || GET_MODE (operands[0]) == DImode
8304 || GET_MODE (operands[0]) == HImode
8305 || GET_MODE (operands[0]) == QImode)"
8306 "#")
8307
8308 (define_split
8309 [(set (reg 17)
8310 (compare (zero_extract
8311 (match_operand 0 "nonimmediate_operand" "")
8312 (match_operand 1 "const_int_operand" "")
8313 (match_operand 2 "const_int_operand" ""))
8314 (const_int 0)))]
8315 "ix86_match_ccmode (insn, CCNOmode)"
8316 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8317 {
8318 HOST_WIDE_INT len = INTVAL (operands[1]);
8319 HOST_WIDE_INT pos = INTVAL (operands[2]);
8320 HOST_WIDE_INT mask;
8321 enum machine_mode mode, submode;
8322
8323 mode = GET_MODE (operands[0]);
8324 if (GET_CODE (operands[0]) == MEM)
8325 {
8326 /* ??? Combine likes to put non-volatile mem extractions in QImode
8327 no matter the size of the test. So find a mode that works. */
8328 if (! MEM_VOLATILE_P (operands[0]))
8329 {
8330 mode = smallest_mode_for_size (pos + len, MODE_INT);
8331 operands[0] = adjust_address (operands[0], mode, 0);
8332 }
8333 }
8334 else if (GET_CODE (operands[0]) == SUBREG
8335 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8336 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8337 && pos + len <= GET_MODE_BITSIZE (submode))
8338 {
8339 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8340 mode = submode;
8341 operands[0] = SUBREG_REG (operands[0]);
8342 }
8343 else if (mode == HImode && pos + len <= 8)
8344 {
8345 /* Small HImode tests can be converted to QImode. */
8346 mode = QImode;
8347 operands[0] = gen_lowpart (QImode, operands[0]);
8348 }
8349
8350 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8351 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8352
8353 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8354 })
8355
8356 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8357 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8358 ;; this is relatively important trick.
8359 ;; Do the conversion only post-reload to avoid limiting of the register class
8360 ;; to QI regs.
8361 (define_split
8362 [(set (reg 17)
8363 (compare
8364 (and (match_operand 0 "register_operand" "")
8365 (match_operand 1 "const_int_operand" ""))
8366 (const_int 0)))]
8367 "reload_completed
8368 && QI_REG_P (operands[0])
8369 && ((ix86_match_ccmode (insn, CCZmode)
8370 && !(INTVAL (operands[1]) & ~(255 << 8)))
8371 || (ix86_match_ccmode (insn, CCNOmode)
8372 && !(INTVAL (operands[1]) & ~(127 << 8))))
8373 && GET_MODE (operands[0]) != QImode"
8374 [(set (reg:CCNO 17)
8375 (compare:CCNO
8376 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8377 (match_dup 1))
8378 (const_int 0)))]
8379 "operands[0] = gen_lowpart (SImode, operands[0]);
8380 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8381
8382 (define_split
8383 [(set (reg 17)
8384 (compare
8385 (and (match_operand 0 "nonimmediate_operand" "")
8386 (match_operand 1 "const_int_operand" ""))
8387 (const_int 0)))]
8388 "reload_completed
8389 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8390 && ((ix86_match_ccmode (insn, CCZmode)
8391 && !(INTVAL (operands[1]) & ~255))
8392 || (ix86_match_ccmode (insn, CCNOmode)
8393 && !(INTVAL (operands[1]) & ~127)))
8394 && GET_MODE (operands[0]) != QImode"
8395 [(set (reg:CCNO 17)
8396 (compare:CCNO
8397 (and:QI (match_dup 0)
8398 (match_dup 1))
8399 (const_int 0)))]
8400 "operands[0] = gen_lowpart (QImode, operands[0]);
8401 operands[1] = gen_lowpart (QImode, operands[1]);")
8402
8403
8404 ;; %%% This used to optimize known byte-wide and operations to memory,
8405 ;; and sometimes to QImode registers. If this is considered useful,
8406 ;; it should be done with splitters.
8407
8408 (define_expand "anddi3"
8409 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8410 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8411 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8412 (clobber (reg:CC 17))]
8413 "TARGET_64BIT"
8414 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8415
8416 (define_insn "*anddi_1_rex64"
8417 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8418 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8419 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8420 (clobber (reg:CC 17))]
8421 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8422 {
8423 switch (get_attr_type (insn))
8424 {
8425 case TYPE_IMOVX:
8426 {
8427 enum machine_mode mode;
8428
8429 if (GET_CODE (operands[2]) != CONST_INT)
8430 abort ();
8431 if (INTVAL (operands[2]) == 0xff)
8432 mode = QImode;
8433 else if (INTVAL (operands[2]) == 0xffff)
8434 mode = HImode;
8435 else
8436 abort ();
8437
8438 operands[1] = gen_lowpart (mode, operands[1]);
8439 if (mode == QImode)
8440 return "movz{bq|x}\t{%1,%0|%0, %1}";
8441 else
8442 return "movz{wq|x}\t{%1,%0|%0, %1}";
8443 }
8444
8445 default:
8446 if (! rtx_equal_p (operands[0], operands[1]))
8447 abort ();
8448 if (get_attr_mode (insn) == MODE_SI)
8449 return "and{l}\t{%k2, %k0|%k0, %k2}";
8450 else
8451 return "and{q}\t{%2, %0|%0, %2}";
8452 }
8453 }
8454 [(set_attr "type" "alu,alu,alu,imovx")
8455 (set_attr "length_immediate" "*,*,*,0")
8456 (set_attr "mode" "SI,DI,DI,DI")])
8457
8458 (define_insn "*anddi_2"
8459 [(set (reg 17)
8460 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8461 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8462 (const_int 0)))
8463 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8464 (and:DI (match_dup 1) (match_dup 2)))]
8465 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8466 && ix86_binary_operator_ok (AND, DImode, operands)"
8467 "@
8468 and{l}\t{%k2, %k0|%k0, %k2}
8469 and{q}\t{%2, %0|%0, %2}
8470 and{q}\t{%2, %0|%0, %2}"
8471 [(set_attr "type" "alu")
8472 (set_attr "mode" "SI,DI,DI")])
8473
8474 (define_expand "andsi3"
8475 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8476 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8477 (match_operand:SI 2 "general_operand" "")))
8478 (clobber (reg:CC 17))]
8479 ""
8480 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8481
8482 (define_insn "*andsi_1"
8483 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8484 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8485 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8486 (clobber (reg:CC 17))]
8487 "ix86_binary_operator_ok (AND, SImode, operands)"
8488 {
8489 switch (get_attr_type (insn))
8490 {
8491 case TYPE_IMOVX:
8492 {
8493 enum machine_mode mode;
8494
8495 if (GET_CODE (operands[2]) != CONST_INT)
8496 abort ();
8497 if (INTVAL (operands[2]) == 0xff)
8498 mode = QImode;
8499 else if (INTVAL (operands[2]) == 0xffff)
8500 mode = HImode;
8501 else
8502 abort ();
8503
8504 operands[1] = gen_lowpart (mode, operands[1]);
8505 if (mode == QImode)
8506 return "movz{bl|x}\t{%1,%0|%0, %1}";
8507 else
8508 return "movz{wl|x}\t{%1,%0|%0, %1}";
8509 }
8510
8511 default:
8512 if (! rtx_equal_p (operands[0], operands[1]))
8513 abort ();
8514 return "and{l}\t{%2, %0|%0, %2}";
8515 }
8516 }
8517 [(set_attr "type" "alu,alu,imovx")
8518 (set_attr "length_immediate" "*,*,0")
8519 (set_attr "mode" "SI")])
8520
8521 (define_split
8522 [(set (match_operand 0 "register_operand" "")
8523 (and (match_dup 0)
8524 (const_int -65536)))
8525 (clobber (reg:CC 17))]
8526 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8527 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8528 "operands[1] = gen_lowpart (HImode, operands[0]);")
8529
8530 (define_split
8531 [(set (match_operand 0 "ext_register_operand" "")
8532 (and (match_dup 0)
8533 (const_int -256)))
8534 (clobber (reg:CC 17))]
8535 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8536 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8537 "operands[1] = gen_lowpart (QImode, operands[0]);")
8538
8539 (define_split
8540 [(set (match_operand 0 "ext_register_operand" "")
8541 (and (match_dup 0)
8542 (const_int -65281)))
8543 (clobber (reg:CC 17))]
8544 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8545 [(parallel [(set (zero_extract:SI (match_dup 0)
8546 (const_int 8)
8547 (const_int 8))
8548 (xor:SI
8549 (zero_extract:SI (match_dup 0)
8550 (const_int 8)
8551 (const_int 8))
8552 (zero_extract:SI (match_dup 0)
8553 (const_int 8)
8554 (const_int 8))))
8555 (clobber (reg:CC 17))])]
8556 "operands[0] = gen_lowpart (SImode, operands[0]);")
8557
8558 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8559 (define_insn "*andsi_1_zext"
8560 [(set (match_operand:DI 0 "register_operand" "=r")
8561 (zero_extend:DI
8562 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8563 (match_operand:SI 2 "general_operand" "rim"))))
8564 (clobber (reg:CC 17))]
8565 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8566 "and{l}\t{%2, %k0|%k0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "mode" "SI")])
8569
8570 (define_insn "*andsi_2"
8571 [(set (reg 17)
8572 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8573 (match_operand:SI 2 "general_operand" "rim,ri"))
8574 (const_int 0)))
8575 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8576 (and:SI (match_dup 1) (match_dup 2)))]
8577 "ix86_match_ccmode (insn, CCNOmode)
8578 && ix86_binary_operator_ok (AND, SImode, operands)"
8579 "and{l}\t{%2, %0|%0, %2}"
8580 [(set_attr "type" "alu")
8581 (set_attr "mode" "SI")])
8582
8583 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8584 (define_insn "*andsi_2_zext"
8585 [(set (reg 17)
8586 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8587 (match_operand:SI 2 "general_operand" "rim"))
8588 (const_int 0)))
8589 (set (match_operand:DI 0 "register_operand" "=r")
8590 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8591 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8592 && ix86_binary_operator_ok (AND, SImode, operands)"
8593 "and{l}\t{%2, %k0|%k0, %2}"
8594 [(set_attr "type" "alu")
8595 (set_attr "mode" "SI")])
8596
8597 (define_expand "andhi3"
8598 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8599 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8600 (match_operand:HI 2 "general_operand" "")))
8601 (clobber (reg:CC 17))]
8602 "TARGET_HIMODE_MATH"
8603 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8604
8605 (define_insn "*andhi_1"
8606 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8607 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8608 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8609 (clobber (reg:CC 17))]
8610 "ix86_binary_operator_ok (AND, HImode, operands)"
8611 {
8612 switch (get_attr_type (insn))
8613 {
8614 case TYPE_IMOVX:
8615 if (GET_CODE (operands[2]) != CONST_INT)
8616 abort ();
8617 if (INTVAL (operands[2]) == 0xff)
8618 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8619 abort ();
8620
8621 default:
8622 if (! rtx_equal_p (operands[0], operands[1]))
8623 abort ();
8624
8625 return "and{w}\t{%2, %0|%0, %2}";
8626 }
8627 }
8628 [(set_attr "type" "alu,alu,imovx")
8629 (set_attr "length_immediate" "*,*,0")
8630 (set_attr "mode" "HI,HI,SI")])
8631
8632 (define_insn "*andhi_2"
8633 [(set (reg 17)
8634 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:HI 2 "general_operand" "rim,ri"))
8636 (const_int 0)))
8637 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638 (and:HI (match_dup 1) (match_dup 2)))]
8639 "ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (AND, HImode, operands)"
8641 "and{w}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "HI")])
8644
8645 (define_expand "andqi3"
8646 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8647 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8648 (match_operand:QI 2 "general_operand" "")))
8649 (clobber (reg:CC 17))]
8650 "TARGET_QIMODE_MATH"
8651 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8652
8653 ;; %%% Potential partial reg stall on alternative 2. What to do?
8654 (define_insn "*andqi_1"
8655 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8656 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8657 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8658 (clobber (reg:CC 17))]
8659 "ix86_binary_operator_ok (AND, QImode, operands)"
8660 "@
8661 and{b}\t{%2, %0|%0, %2}
8662 and{b}\t{%2, %0|%0, %2}
8663 and{l}\t{%k2, %k0|%k0, %k2}"
8664 [(set_attr "type" "alu")
8665 (set_attr "mode" "QI,QI,SI")])
8666
8667 (define_insn "*andqi_1_slp"
8668 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8669 (and:QI (match_dup 0)
8670 (match_operand:QI 1 "general_operand" "qi,qmi")))
8671 (clobber (reg:CC 17))]
8672 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8673 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8674 "and{b}\t{%1, %0|%0, %1}"
8675 [(set_attr "type" "alu1")
8676 (set_attr "mode" "QI")])
8677
8678 (define_insn "*andqi_2"
8679 [(set (reg 17)
8680 (compare (and:QI
8681 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8682 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8683 (const_int 0)))
8684 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8685 (and:QI (match_dup 1) (match_dup 2)))]
8686 "ix86_match_ccmode (insn, CCNOmode)
8687 && ix86_binary_operator_ok (AND, QImode, operands)"
8688 {
8689 if (which_alternative == 2)
8690 {
8691 if (GET_CODE (operands[2]) == CONST_INT
8692 && (INTVAL (operands[2]) & 0xffffff00))
8693 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8694 return "and{l}\t{%2, %k0|%k0, %2}";
8695 }
8696 return "and{b}\t{%2, %0|%0, %2}";
8697 }
8698 [(set_attr "type" "alu")
8699 (set_attr "mode" "QI,QI,SI")])
8700
8701 (define_insn "*andqi_2_slp"
8702 [(set (reg 17)
8703 (compare (and:QI
8704 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8705 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8706 (const_int 0)))
8707 (set (strict_low_part (match_dup 0))
8708 (and:QI (match_dup 0) (match_dup 1)))]
8709 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8710 && ix86_match_ccmode (insn, CCNOmode)
8711 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8712 "and{b}\t{%1, %0|%0, %1}"
8713 [(set_attr "type" "alu1")
8714 (set_attr "mode" "QI")])
8715
8716 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8717 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8718 ;; for a QImode operand, which of course failed.
8719
8720 (define_insn "andqi_ext_0"
8721 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8722 (const_int 8)
8723 (const_int 8))
8724 (and:SI
8725 (zero_extract:SI
8726 (match_operand 1 "ext_register_operand" "0")
8727 (const_int 8)
8728 (const_int 8))
8729 (match_operand 2 "const_int_operand" "n")))
8730 (clobber (reg:CC 17))]
8731 ""
8732 "and{b}\t{%2, %h0|%h0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "length_immediate" "1")
8735 (set_attr "mode" "QI")])
8736
8737 ;; Generated by peephole translating test to and. This shows up
8738 ;; often in fp comparisons.
8739
8740 (define_insn "*andqi_ext_0_cc"
8741 [(set (reg 17)
8742 (compare
8743 (and:SI
8744 (zero_extract:SI
8745 (match_operand 1 "ext_register_operand" "0")
8746 (const_int 8)
8747 (const_int 8))
8748 (match_operand 2 "const_int_operand" "n"))
8749 (const_int 0)))
8750 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8751 (const_int 8)
8752 (const_int 8))
8753 (and:SI
8754 (zero_extract:SI
8755 (match_dup 1)
8756 (const_int 8)
8757 (const_int 8))
8758 (match_dup 2)))]
8759 "ix86_match_ccmode (insn, CCNOmode)"
8760 "and{b}\t{%2, %h0|%h0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "length_immediate" "1")
8763 (set_attr "mode" "QI")])
8764
8765 (define_insn "*andqi_ext_1"
8766 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767 (const_int 8)
8768 (const_int 8))
8769 (and:SI
8770 (zero_extract:SI
8771 (match_operand 1 "ext_register_operand" "0")
8772 (const_int 8)
8773 (const_int 8))
8774 (zero_extend:SI
8775 (match_operand:QI 2 "general_operand" "Qm"))))
8776 (clobber (reg:CC 17))]
8777 "!TARGET_64BIT"
8778 "and{b}\t{%2, %h0|%h0, %2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "length_immediate" "0")
8781 (set_attr "mode" "QI")])
8782
8783 (define_insn "*andqi_ext_1_rex64"
8784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8785 (const_int 8)
8786 (const_int 8))
8787 (and:SI
8788 (zero_extract:SI
8789 (match_operand 1 "ext_register_operand" "0")
8790 (const_int 8)
8791 (const_int 8))
8792 (zero_extend:SI
8793 (match_operand 2 "ext_register_operand" "Q"))))
8794 (clobber (reg:CC 17))]
8795 "TARGET_64BIT"
8796 "and{b}\t{%2, %h0|%h0, %2}"
8797 [(set_attr "type" "alu")
8798 (set_attr "length_immediate" "0")
8799 (set_attr "mode" "QI")])
8800
8801 (define_insn "*andqi_ext_2"
8802 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803 (const_int 8)
8804 (const_int 8))
8805 (and:SI
8806 (zero_extract:SI
8807 (match_operand 1 "ext_register_operand" "%0")
8808 (const_int 8)
8809 (const_int 8))
8810 (zero_extract:SI
8811 (match_operand 2 "ext_register_operand" "Q")
8812 (const_int 8)
8813 (const_int 8))))
8814 (clobber (reg:CC 17))]
8815 ""
8816 "and{b}\t{%h2, %h0|%h0, %h2}"
8817 [(set_attr "type" "alu")
8818 (set_attr "length_immediate" "0")
8819 (set_attr "mode" "QI")])
8820
8821 ;; Convert wide AND instructions with immediate operand to shorter QImode
8822 ;; equivalents when possible.
8823 ;; Don't do the splitting with memory operands, since it introduces risk
8824 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8825 ;; for size, but that can (should?) be handled by generic code instead.
8826 (define_split
8827 [(set (match_operand 0 "register_operand" "")
8828 (and (match_operand 1 "register_operand" "")
8829 (match_operand 2 "const_int_operand" "")))
8830 (clobber (reg:CC 17))]
8831 "reload_completed
8832 && QI_REG_P (operands[0])
8833 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8834 && !(~INTVAL (operands[2]) & ~(255 << 8))
8835 && GET_MODE (operands[0]) != QImode"
8836 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8837 (and:SI (zero_extract:SI (match_dup 1)
8838 (const_int 8) (const_int 8))
8839 (match_dup 2)))
8840 (clobber (reg:CC 17))])]
8841 "operands[0] = gen_lowpart (SImode, operands[0]);
8842 operands[1] = gen_lowpart (SImode, operands[1]);
8843 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8844
8845 ;; Since AND can be encoded with sign extended immediate, this is only
8846 ;; profitable when 7th bit is not set.
8847 (define_split
8848 [(set (match_operand 0 "register_operand" "")
8849 (and (match_operand 1 "general_operand" "")
8850 (match_operand 2 "const_int_operand" "")))
8851 (clobber (reg:CC 17))]
8852 "reload_completed
8853 && ANY_QI_REG_P (operands[0])
8854 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8855 && !(~INTVAL (operands[2]) & ~255)
8856 && !(INTVAL (operands[2]) & 128)
8857 && GET_MODE (operands[0]) != QImode"
8858 [(parallel [(set (strict_low_part (match_dup 0))
8859 (and:QI (match_dup 1)
8860 (match_dup 2)))
8861 (clobber (reg:CC 17))])]
8862 "operands[0] = gen_lowpart (QImode, operands[0]);
8863 operands[1] = gen_lowpart (QImode, operands[1]);
8864 operands[2] = gen_lowpart (QImode, operands[2]);")
8865 \f
8866 ;; Logical inclusive OR instructions
8867
8868 ;; %%% This used to optimize known byte-wide and operations to memory.
8869 ;; If this is considered useful, it should be done with splitters.
8870
8871 (define_expand "iordi3"
8872 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8873 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8874 (match_operand:DI 2 "x86_64_general_operand" "")))
8875 (clobber (reg:CC 17))]
8876 "TARGET_64BIT"
8877 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8878
8879 (define_insn "*iordi_1_rex64"
8880 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8881 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8882 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8883 (clobber (reg:CC 17))]
8884 "TARGET_64BIT
8885 && ix86_binary_operator_ok (IOR, DImode, operands)"
8886 "or{q}\t{%2, %0|%0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "mode" "DI")])
8889
8890 (define_insn "*iordi_2_rex64"
8891 [(set (reg 17)
8892 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8894 (const_int 0)))
8895 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8896 (ior:DI (match_dup 1) (match_dup 2)))]
8897 "TARGET_64BIT
8898 && ix86_match_ccmode (insn, CCNOmode)
8899 && ix86_binary_operator_ok (IOR, DImode, operands)"
8900 "or{q}\t{%2, %0|%0, %2}"
8901 [(set_attr "type" "alu")
8902 (set_attr "mode" "DI")])
8903
8904 (define_insn "*iordi_3_rex64"
8905 [(set (reg 17)
8906 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8907 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8908 (const_int 0)))
8909 (clobber (match_scratch:DI 0 "=r"))]
8910 "TARGET_64BIT
8911 && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_binary_operator_ok (IOR, DImode, operands)"
8913 "or{q}\t{%2, %0|%0, %2}"
8914 [(set_attr "type" "alu")
8915 (set_attr "mode" "DI")])
8916
8917
8918 (define_expand "iorsi3"
8919 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8920 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8921 (match_operand:SI 2 "general_operand" "")))
8922 (clobber (reg:CC 17))]
8923 ""
8924 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8925
8926 (define_insn "*iorsi_1"
8927 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8928 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8929 (match_operand:SI 2 "general_operand" "ri,rmi")))
8930 (clobber (reg:CC 17))]
8931 "ix86_binary_operator_ok (IOR, SImode, operands)"
8932 "or{l}\t{%2, %0|%0, %2}"
8933 [(set_attr "type" "alu")
8934 (set_attr "mode" "SI")])
8935
8936 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8937 (define_insn "*iorsi_1_zext"
8938 [(set (match_operand:DI 0 "register_operand" "=rm")
8939 (zero_extend:DI
8940 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8941 (match_operand:SI 2 "general_operand" "rim"))))
8942 (clobber (reg:CC 17))]
8943 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8944 "or{l}\t{%2, %k0|%k0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "SI")])
8947
8948 (define_insn "*iorsi_1_zext_imm"
8949 [(set (match_operand:DI 0 "register_operand" "=rm")
8950 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8951 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8952 (clobber (reg:CC 17))]
8953 "TARGET_64BIT"
8954 "or{l}\t{%2, %k0|%k0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "SI")])
8957
8958 (define_insn "*iorsi_2"
8959 [(set (reg 17)
8960 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8961 (match_operand:SI 2 "general_operand" "rim,ri"))
8962 (const_int 0)))
8963 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8964 (ior:SI (match_dup 1) (match_dup 2)))]
8965 "ix86_match_ccmode (insn, CCNOmode)
8966 && ix86_binary_operator_ok (IOR, SImode, operands)"
8967 "or{l}\t{%2, %0|%0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "SI")])
8970
8971 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8972 ;; ??? Special case for immediate operand is missing - it is tricky.
8973 (define_insn "*iorsi_2_zext"
8974 [(set (reg 17)
8975 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8976 (match_operand:SI 2 "general_operand" "rim"))
8977 (const_int 0)))
8978 (set (match_operand:DI 0 "register_operand" "=r")
8979 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8980 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8981 && ix86_binary_operator_ok (IOR, SImode, operands)"
8982 "or{l}\t{%2, %k0|%k0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "SI")])
8985
8986 (define_insn "*iorsi_2_zext_imm"
8987 [(set (reg 17)
8988 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8990 (const_int 0)))
8991 (set (match_operand:DI 0 "register_operand" "=r")
8992 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8994 && ix86_binary_operator_ok (IOR, SImode, operands)"
8995 "or{l}\t{%2, %k0|%k0, %2}"
8996 [(set_attr "type" "alu")
8997 (set_attr "mode" "SI")])
8998
8999 (define_insn "*iorsi_3"
9000 [(set (reg 17)
9001 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002 (match_operand:SI 2 "general_operand" "rim"))
9003 (const_int 0)))
9004 (clobber (match_scratch:SI 0 "=r"))]
9005 "ix86_match_ccmode (insn, CCNOmode)
9006 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9007 "or{l}\t{%2, %0|%0, %2}"
9008 [(set_attr "type" "alu")
9009 (set_attr "mode" "SI")])
9010
9011 (define_expand "iorhi3"
9012 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9013 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9014 (match_operand:HI 2 "general_operand" "")))
9015 (clobber (reg:CC 17))]
9016 "TARGET_HIMODE_MATH"
9017 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9018
9019 (define_insn "*iorhi_1"
9020 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9021 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9022 (match_operand:HI 2 "general_operand" "rmi,ri")))
9023 (clobber (reg:CC 17))]
9024 "ix86_binary_operator_ok (IOR, HImode, operands)"
9025 "or{w}\t{%2, %0|%0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "HI")])
9028
9029 (define_insn "*iorhi_2"
9030 [(set (reg 17)
9031 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9032 (match_operand:HI 2 "general_operand" "rim,ri"))
9033 (const_int 0)))
9034 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9035 (ior:HI (match_dup 1) (match_dup 2)))]
9036 "ix86_match_ccmode (insn, CCNOmode)
9037 && ix86_binary_operator_ok (IOR, HImode, operands)"
9038 "or{w}\t{%2, %0|%0, %2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "HI")])
9041
9042 (define_insn "*iorhi_3"
9043 [(set (reg 17)
9044 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9045 (match_operand:HI 2 "general_operand" "rim"))
9046 (const_int 0)))
9047 (clobber (match_scratch:HI 0 "=r"))]
9048 "ix86_match_ccmode (insn, CCNOmode)
9049 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9050 "or{w}\t{%2, %0|%0, %2}"
9051 [(set_attr "type" "alu")
9052 (set_attr "mode" "HI")])
9053
9054 (define_expand "iorqi3"
9055 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9056 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9057 (match_operand:QI 2 "general_operand" "")))
9058 (clobber (reg:CC 17))]
9059 "TARGET_QIMODE_MATH"
9060 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9061
9062 ;; %%% Potential partial reg stall on alternative 2. What to do?
9063 (define_insn "*iorqi_1"
9064 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9065 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9066 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9067 (clobber (reg:CC 17))]
9068 "ix86_binary_operator_ok (IOR, QImode, operands)"
9069 "@
9070 or{b}\t{%2, %0|%0, %2}
9071 or{b}\t{%2, %0|%0, %2}
9072 or{l}\t{%k2, %k0|%k0, %k2}"
9073 [(set_attr "type" "alu")
9074 (set_attr "mode" "QI,QI,SI")])
9075
9076 (define_insn "*iorqi_1_slp"
9077 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9078 (ior:QI (match_dup 0)
9079 (match_operand:QI 1 "general_operand" "qmi,qi")))
9080 (clobber (reg:CC 17))]
9081 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9082 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9083 "or{b}\t{%1, %0|%0, %1}"
9084 [(set_attr "type" "alu1")
9085 (set_attr "mode" "QI")])
9086
9087 (define_insn "*iorqi_2"
9088 [(set (reg 17)
9089 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9090 (match_operand:QI 2 "general_operand" "qim,qi"))
9091 (const_int 0)))
9092 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9093 (ior:QI (match_dup 1) (match_dup 2)))]
9094 "ix86_match_ccmode (insn, CCNOmode)
9095 && ix86_binary_operator_ok (IOR, QImode, operands)"
9096 "or{b}\t{%2, %0|%0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "QI")])
9099
9100 (define_insn "*iorqi_2_slp"
9101 [(set (reg 17)
9102 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9103 (match_operand:QI 1 "general_operand" "qim,qi"))
9104 (const_int 0)))
9105 (set (strict_low_part (match_dup 0))
9106 (ior:QI (match_dup 0) (match_dup 1)))]
9107 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9108 && ix86_match_ccmode (insn, CCNOmode)
9109 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9110 "or{b}\t{%1, %0|%0, %1}"
9111 [(set_attr "type" "alu1")
9112 (set_attr "mode" "QI")])
9113
9114 (define_insn "*iorqi_3"
9115 [(set (reg 17)
9116 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9117 (match_operand:QI 2 "general_operand" "qim"))
9118 (const_int 0)))
9119 (clobber (match_scratch:QI 0 "=q"))]
9120 "ix86_match_ccmode (insn, CCNOmode)
9121 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9122 "or{b}\t{%2, %0|%0, %2}"
9123 [(set_attr "type" "alu")
9124 (set_attr "mode" "QI")])
9125
9126 (define_insn "iorqi_ext_0"
9127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128 (const_int 8)
9129 (const_int 8))
9130 (ior:SI
9131 (zero_extract:SI
9132 (match_operand 1 "ext_register_operand" "0")
9133 (const_int 8)
9134 (const_int 8))
9135 (match_operand 2 "const_int_operand" "n")))
9136 (clobber (reg:CC 17))]
9137 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138 "or{b}\t{%2, %h0|%h0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "length_immediate" "1")
9141 (set_attr "mode" "QI")])
9142
9143 (define_insn "*iorqi_ext_1"
9144 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (const_int 8)
9146 (const_int 8))
9147 (ior:SI
9148 (zero_extract:SI
9149 (match_operand 1 "ext_register_operand" "0")
9150 (const_int 8)
9151 (const_int 8))
9152 (zero_extend:SI
9153 (match_operand:QI 2 "general_operand" "Qm"))))
9154 (clobber (reg:CC 17))]
9155 "!TARGET_64BIT
9156 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9157 "or{b}\t{%2, %h0|%h0, %2}"
9158 [(set_attr "type" "alu")
9159 (set_attr "length_immediate" "0")
9160 (set_attr "mode" "QI")])
9161
9162 (define_insn "*iorqi_ext_1_rex64"
9163 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9164 (const_int 8)
9165 (const_int 8))
9166 (ior:SI
9167 (zero_extract:SI
9168 (match_operand 1 "ext_register_operand" "0")
9169 (const_int 8)
9170 (const_int 8))
9171 (zero_extend:SI
9172 (match_operand 2 "ext_register_operand" "Q"))))
9173 (clobber (reg:CC 17))]
9174 "TARGET_64BIT
9175 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9176 "or{b}\t{%2, %h0|%h0, %2}"
9177 [(set_attr "type" "alu")
9178 (set_attr "length_immediate" "0")
9179 (set_attr "mode" "QI")])
9180
9181 (define_insn "*iorqi_ext_2"
9182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9183 (const_int 8)
9184 (const_int 8))
9185 (ior:SI
9186 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9187 (const_int 8)
9188 (const_int 8))
9189 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9190 (const_int 8)
9191 (const_int 8))))
9192 (clobber (reg:CC 17))]
9193 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9194 "ior{b}\t{%h2, %h0|%h0, %h2}"
9195 [(set_attr "type" "alu")
9196 (set_attr "length_immediate" "0")
9197 (set_attr "mode" "QI")])
9198
9199 (define_split
9200 [(set (match_operand 0 "register_operand" "")
9201 (ior (match_operand 1 "register_operand" "")
9202 (match_operand 2 "const_int_operand" "")))
9203 (clobber (reg:CC 17))]
9204 "reload_completed
9205 && QI_REG_P (operands[0])
9206 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9207 && !(INTVAL (operands[2]) & ~(255 << 8))
9208 && GET_MODE (operands[0]) != QImode"
9209 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9210 (ior:SI (zero_extract:SI (match_dup 1)
9211 (const_int 8) (const_int 8))
9212 (match_dup 2)))
9213 (clobber (reg:CC 17))])]
9214 "operands[0] = gen_lowpart (SImode, operands[0]);
9215 operands[1] = gen_lowpart (SImode, operands[1]);
9216 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9217
9218 ;; Since OR can be encoded with sign extended immediate, this is only
9219 ;; profitable when 7th bit is set.
9220 (define_split
9221 [(set (match_operand 0 "register_operand" "")
9222 (ior (match_operand 1 "general_operand" "")
9223 (match_operand 2 "const_int_operand" "")))
9224 (clobber (reg:CC 17))]
9225 "reload_completed
9226 && ANY_QI_REG_P (operands[0])
9227 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9228 && !(INTVAL (operands[2]) & ~255)
9229 && (INTVAL (operands[2]) & 128)
9230 && GET_MODE (operands[0]) != QImode"
9231 [(parallel [(set (strict_low_part (match_dup 0))
9232 (ior:QI (match_dup 1)
9233 (match_dup 2)))
9234 (clobber (reg:CC 17))])]
9235 "operands[0] = gen_lowpart (QImode, operands[0]);
9236 operands[1] = gen_lowpart (QImode, operands[1]);
9237 operands[2] = gen_lowpart (QImode, operands[2]);")
9238 \f
9239 ;; Logical XOR instructions
9240
9241 ;; %%% This used to optimize known byte-wide and operations to memory.
9242 ;; If this is considered useful, it should be done with splitters.
9243
9244 (define_expand "xordi3"
9245 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9246 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9247 (match_operand:DI 2 "x86_64_general_operand" "")))
9248 (clobber (reg:CC 17))]
9249 "TARGET_64BIT"
9250 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9251
9252 (define_insn "*xordi_1_rex64"
9253 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9254 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9255 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9256 (clobber (reg:CC 17))]
9257 "TARGET_64BIT
9258 && ix86_binary_operator_ok (XOR, DImode, operands)"
9259 "@
9260 xor{q}\t{%2, %0|%0, %2}
9261 xor{q}\t{%2, %0|%0, %2}"
9262 [(set_attr "type" "alu")
9263 (set_attr "mode" "DI,DI")])
9264
9265 (define_insn "*xordi_2_rex64"
9266 [(set (reg 17)
9267 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9268 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9269 (const_int 0)))
9270 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9271 (xor:DI (match_dup 1) (match_dup 2)))]
9272 "TARGET_64BIT
9273 && ix86_match_ccmode (insn, CCNOmode)
9274 && ix86_binary_operator_ok (XOR, DImode, operands)"
9275 "@
9276 xor{q}\t{%2, %0|%0, %2}
9277 xor{q}\t{%2, %0|%0, %2}"
9278 [(set_attr "type" "alu")
9279 (set_attr "mode" "DI,DI")])
9280
9281 (define_insn "*xordi_3_rex64"
9282 [(set (reg 17)
9283 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9284 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9285 (const_int 0)))
9286 (clobber (match_scratch:DI 0 "=r"))]
9287 "TARGET_64BIT
9288 && ix86_match_ccmode (insn, CCNOmode)
9289 && ix86_binary_operator_ok (XOR, DImode, operands)"
9290 "xor{q}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "DI")])
9293
9294 (define_expand "xorsi3"
9295 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9296 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9297 (match_operand:SI 2 "general_operand" "")))
9298 (clobber (reg:CC 17))]
9299 ""
9300 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9301
9302 (define_insn "*xorsi_1"
9303 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9304 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9305 (match_operand:SI 2 "general_operand" "ri,rm")))
9306 (clobber (reg:CC 17))]
9307 "ix86_binary_operator_ok (XOR, SImode, operands)"
9308 "xor{l}\t{%2, %0|%0, %2}"
9309 [(set_attr "type" "alu")
9310 (set_attr "mode" "SI")])
9311
9312 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9313 ;; Add speccase for immediates
9314 (define_insn "*xorsi_1_zext"
9315 [(set (match_operand:DI 0 "register_operand" "=r")
9316 (zero_extend:DI
9317 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9318 (match_operand:SI 2 "general_operand" "rim"))))
9319 (clobber (reg:CC 17))]
9320 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9321 "xor{l}\t{%2, %k0|%k0, %2}"
9322 [(set_attr "type" "alu")
9323 (set_attr "mode" "SI")])
9324
9325 (define_insn "*xorsi_1_zext_imm"
9326 [(set (match_operand:DI 0 "register_operand" "=r")
9327 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9328 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9329 (clobber (reg:CC 17))]
9330 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9331 "xor{l}\t{%2, %k0|%k0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "SI")])
9334
9335 (define_insn "*xorsi_2"
9336 [(set (reg 17)
9337 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9338 (match_operand:SI 2 "general_operand" "rim,ri"))
9339 (const_int 0)))
9340 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9341 (xor:SI (match_dup 1) (match_dup 2)))]
9342 "ix86_match_ccmode (insn, CCNOmode)
9343 && ix86_binary_operator_ok (XOR, SImode, operands)"
9344 "xor{l}\t{%2, %0|%0, %2}"
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "SI")])
9347
9348 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9349 ;; ??? Special case for immediate operand is missing - it is tricky.
9350 (define_insn "*xorsi_2_zext"
9351 [(set (reg 17)
9352 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9353 (match_operand:SI 2 "general_operand" "rim"))
9354 (const_int 0)))
9355 (set (match_operand:DI 0 "register_operand" "=r")
9356 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9357 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9358 && ix86_binary_operator_ok (XOR, SImode, operands)"
9359 "xor{l}\t{%2, %k0|%k0, %2}"
9360 [(set_attr "type" "alu")
9361 (set_attr "mode" "SI")])
9362
9363 (define_insn "*xorsi_2_zext_imm"
9364 [(set (reg 17)
9365 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9366 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9367 (const_int 0)))
9368 (set (match_operand:DI 0 "register_operand" "=r")
9369 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9371 && ix86_binary_operator_ok (XOR, SImode, operands)"
9372 "xor{l}\t{%2, %k0|%k0, %2}"
9373 [(set_attr "type" "alu")
9374 (set_attr "mode" "SI")])
9375
9376 (define_insn "*xorsi_3"
9377 [(set (reg 17)
9378 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9379 (match_operand:SI 2 "general_operand" "rim"))
9380 (const_int 0)))
9381 (clobber (match_scratch:SI 0 "=r"))]
9382 "ix86_match_ccmode (insn, CCNOmode)
9383 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9384 "xor{l}\t{%2, %0|%0, %2}"
9385 [(set_attr "type" "alu")
9386 (set_attr "mode" "SI")])
9387
9388 (define_expand "xorhi3"
9389 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9390 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9391 (match_operand:HI 2 "general_operand" "")))
9392 (clobber (reg:CC 17))]
9393 "TARGET_HIMODE_MATH"
9394 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9395
9396 (define_insn "*xorhi_1"
9397 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9398 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9399 (match_operand:HI 2 "general_operand" "rmi,ri")))
9400 (clobber (reg:CC 17))]
9401 "ix86_binary_operator_ok (XOR, HImode, operands)"
9402 "xor{w}\t{%2, %0|%0, %2}"
9403 [(set_attr "type" "alu")
9404 (set_attr "mode" "HI")])
9405
9406 (define_insn "*xorhi_2"
9407 [(set (reg 17)
9408 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9409 (match_operand:HI 2 "general_operand" "rim,ri"))
9410 (const_int 0)))
9411 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9412 (xor:HI (match_dup 1) (match_dup 2)))]
9413 "ix86_match_ccmode (insn, CCNOmode)
9414 && ix86_binary_operator_ok (XOR, HImode, operands)"
9415 "xor{w}\t{%2, %0|%0, %2}"
9416 [(set_attr "type" "alu")
9417 (set_attr "mode" "HI")])
9418
9419 (define_insn "*xorhi_3"
9420 [(set (reg 17)
9421 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9422 (match_operand:HI 2 "general_operand" "rim"))
9423 (const_int 0)))
9424 (clobber (match_scratch:HI 0 "=r"))]
9425 "ix86_match_ccmode (insn, CCNOmode)
9426 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9427 "xor{w}\t{%2, %0|%0, %2}"
9428 [(set_attr "type" "alu")
9429 (set_attr "mode" "HI")])
9430
9431 (define_expand "xorqi3"
9432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9433 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9434 (match_operand:QI 2 "general_operand" "")))
9435 (clobber (reg:CC 17))]
9436 "TARGET_QIMODE_MATH"
9437 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9438
9439 ;; %%% Potential partial reg stall on alternative 2. What to do?
9440 (define_insn "*xorqi_1"
9441 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9442 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9443 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9444 (clobber (reg:CC 17))]
9445 "ix86_binary_operator_ok (XOR, QImode, operands)"
9446 "@
9447 xor{b}\t{%2, %0|%0, %2}
9448 xor{b}\t{%2, %0|%0, %2}
9449 xor{l}\t{%k2, %k0|%k0, %k2}"
9450 [(set_attr "type" "alu")
9451 (set_attr "mode" "QI,QI,SI")])
9452
9453 (define_insn "*xorqi_1_slp"
9454 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9455 (xor:QI (match_dup 0)
9456 (match_operand:QI 1 "general_operand" "qi,qmi")))
9457 (clobber (reg:CC 17))]
9458 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9459 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9460 "xor{b}\t{%1, %0|%0, %1}"
9461 [(set_attr "type" "alu1")
9462 (set_attr "mode" "QI")])
9463
9464 (define_insn "xorqi_ext_0"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466 (const_int 8)
9467 (const_int 8))
9468 (xor:SI
9469 (zero_extract:SI
9470 (match_operand 1 "ext_register_operand" "0")
9471 (const_int 8)
9472 (const_int 8))
9473 (match_operand 2 "const_int_operand" "n")))
9474 (clobber (reg:CC 17))]
9475 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9476 "xor{b}\t{%2, %h0|%h0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "length_immediate" "1")
9479 (set_attr "mode" "QI")])
9480
9481 (define_insn "*xorqi_ext_1"
9482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483 (const_int 8)
9484 (const_int 8))
9485 (xor:SI
9486 (zero_extract:SI
9487 (match_operand 1 "ext_register_operand" "0")
9488 (const_int 8)
9489 (const_int 8))
9490 (zero_extend:SI
9491 (match_operand:QI 2 "general_operand" "Qm"))))
9492 (clobber (reg:CC 17))]
9493 "!TARGET_64BIT
9494 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9495 "xor{b}\t{%2, %h0|%h0, %2}"
9496 [(set_attr "type" "alu")
9497 (set_attr "length_immediate" "0")
9498 (set_attr "mode" "QI")])
9499
9500 (define_insn "*xorqi_ext_1_rex64"
9501 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9502 (const_int 8)
9503 (const_int 8))
9504 (xor:SI
9505 (zero_extract:SI
9506 (match_operand 1 "ext_register_operand" "0")
9507 (const_int 8)
9508 (const_int 8))
9509 (zero_extend:SI
9510 (match_operand 2 "ext_register_operand" "Q"))))
9511 (clobber (reg:CC 17))]
9512 "TARGET_64BIT
9513 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9514 "xor{b}\t{%2, %h0|%h0, %2}"
9515 [(set_attr "type" "alu")
9516 (set_attr "length_immediate" "0")
9517 (set_attr "mode" "QI")])
9518
9519 (define_insn "*xorqi_ext_2"
9520 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9521 (const_int 8)
9522 (const_int 8))
9523 (xor:SI
9524 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9525 (const_int 8)
9526 (const_int 8))
9527 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9528 (const_int 8)
9529 (const_int 8))))
9530 (clobber (reg:CC 17))]
9531 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9532 "xor{b}\t{%h2, %h0|%h0, %h2}"
9533 [(set_attr "type" "alu")
9534 (set_attr "length_immediate" "0")
9535 (set_attr "mode" "QI")])
9536
9537 (define_insn "*xorqi_cc_1"
9538 [(set (reg 17)
9539 (compare
9540 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9541 (match_operand:QI 2 "general_operand" "qim,qi"))
9542 (const_int 0)))
9543 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9544 (xor:QI (match_dup 1) (match_dup 2)))]
9545 "ix86_match_ccmode (insn, CCNOmode)
9546 && ix86_binary_operator_ok (XOR, QImode, operands)"
9547 "xor{b}\t{%2, %0|%0, %2}"
9548 [(set_attr "type" "alu")
9549 (set_attr "mode" "QI")])
9550
9551 (define_insn "*xorqi_2_slp"
9552 [(set (reg 17)
9553 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9554 (match_operand:QI 1 "general_operand" "qim,qi"))
9555 (const_int 0)))
9556 (set (strict_low_part (match_dup 0))
9557 (xor:QI (match_dup 0) (match_dup 1)))]
9558 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9559 && ix86_match_ccmode (insn, CCNOmode)
9560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9561 "xor{b}\t{%1, %0|%0, %1}"
9562 [(set_attr "type" "alu1")
9563 (set_attr "mode" "QI")])
9564
9565 (define_insn "*xorqi_cc_2"
9566 [(set (reg 17)
9567 (compare
9568 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9569 (match_operand:QI 2 "general_operand" "qim"))
9570 (const_int 0)))
9571 (clobber (match_scratch:QI 0 "=q"))]
9572 "ix86_match_ccmode (insn, CCNOmode)
9573 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9574 "xor{b}\t{%2, %0|%0, %2}"
9575 [(set_attr "type" "alu")
9576 (set_attr "mode" "QI")])
9577
9578 (define_insn "*xorqi_cc_ext_1"
9579 [(set (reg 17)
9580 (compare
9581 (xor:SI
9582 (zero_extract:SI
9583 (match_operand 1 "ext_register_operand" "0")
9584 (const_int 8)
9585 (const_int 8))
9586 (match_operand:QI 2 "general_operand" "qmn"))
9587 (const_int 0)))
9588 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9589 (const_int 8)
9590 (const_int 8))
9591 (xor:SI
9592 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9593 (match_dup 2)))]
9594 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9595 "xor{b}\t{%2, %h0|%h0, %2}"
9596 [(set_attr "type" "alu")
9597 (set_attr "mode" "QI")])
9598
9599 (define_insn "*xorqi_cc_ext_1_rex64"
9600 [(set (reg 17)
9601 (compare
9602 (xor:SI
9603 (zero_extract:SI
9604 (match_operand 1 "ext_register_operand" "0")
9605 (const_int 8)
9606 (const_int 8))
9607 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9608 (const_int 0)))
9609 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9610 (const_int 8)
9611 (const_int 8))
9612 (xor:SI
9613 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9614 (match_dup 2)))]
9615 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9616 "xor{b}\t{%2, %h0|%h0, %2}"
9617 [(set_attr "type" "alu")
9618 (set_attr "mode" "QI")])
9619
9620 (define_expand "xorqi_cc_ext_1"
9621 [(parallel [
9622 (set (reg:CCNO 17)
9623 (compare:CCNO
9624 (xor:SI
9625 (zero_extract:SI
9626 (match_operand 1 "ext_register_operand" "")
9627 (const_int 8)
9628 (const_int 8))
9629 (match_operand:QI 2 "general_operand" ""))
9630 (const_int 0)))
9631 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9632 (const_int 8)
9633 (const_int 8))
9634 (xor:SI
9635 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9636 (match_dup 2)))])]
9637 ""
9638 "")
9639
9640 (define_split
9641 [(set (match_operand 0 "register_operand" "")
9642 (xor (match_operand 1 "register_operand" "")
9643 (match_operand 2 "const_int_operand" "")))
9644 (clobber (reg:CC 17))]
9645 "reload_completed
9646 && QI_REG_P (operands[0])
9647 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9648 && !(INTVAL (operands[2]) & ~(255 << 8))
9649 && GET_MODE (operands[0]) != QImode"
9650 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9651 (xor:SI (zero_extract:SI (match_dup 1)
9652 (const_int 8) (const_int 8))
9653 (match_dup 2)))
9654 (clobber (reg:CC 17))])]
9655 "operands[0] = gen_lowpart (SImode, operands[0]);
9656 operands[1] = gen_lowpart (SImode, operands[1]);
9657 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9658
9659 ;; Since XOR can be encoded with sign extended immediate, this is only
9660 ;; profitable when 7th bit is set.
9661 (define_split
9662 [(set (match_operand 0 "register_operand" "")
9663 (xor (match_operand 1 "general_operand" "")
9664 (match_operand 2 "const_int_operand" "")))
9665 (clobber (reg:CC 17))]
9666 "reload_completed
9667 && ANY_QI_REG_P (operands[0])
9668 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9669 && !(INTVAL (operands[2]) & ~255)
9670 && (INTVAL (operands[2]) & 128)
9671 && GET_MODE (operands[0]) != QImode"
9672 [(parallel [(set (strict_low_part (match_dup 0))
9673 (xor:QI (match_dup 1)
9674 (match_dup 2)))
9675 (clobber (reg:CC 17))])]
9676 "operands[0] = gen_lowpart (QImode, operands[0]);
9677 operands[1] = gen_lowpart (QImode, operands[1]);
9678 operands[2] = gen_lowpart (QImode, operands[2]);")
9679 \f
9680 ;; Negation instructions
9681
9682 (define_expand "negdi2"
9683 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9684 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9685 (clobber (reg:CC 17))])]
9686 ""
9687 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9688
9689 (define_insn "*negdi2_1"
9690 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9691 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9692 (clobber (reg:CC 17))]
9693 "!TARGET_64BIT
9694 && ix86_unary_operator_ok (NEG, DImode, operands)"
9695 "#")
9696
9697 (define_split
9698 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9699 (neg:DI (match_operand:DI 1 "general_operand" "")))
9700 (clobber (reg:CC 17))]
9701 "!TARGET_64BIT && reload_completed"
9702 [(parallel
9703 [(set (reg:CCZ 17)
9704 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9705 (set (match_dup 0) (neg:SI (match_dup 2)))])
9706 (parallel
9707 [(set (match_dup 1)
9708 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9709 (match_dup 3))
9710 (const_int 0)))
9711 (clobber (reg:CC 17))])
9712 (parallel
9713 [(set (match_dup 1)
9714 (neg:SI (match_dup 1)))
9715 (clobber (reg:CC 17))])]
9716 "split_di (operands+1, 1, operands+2, operands+3);
9717 split_di (operands+0, 1, operands+0, operands+1);")
9718
9719 (define_insn "*negdi2_1_rex64"
9720 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9721 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9722 (clobber (reg:CC 17))]
9723 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9724 "neg{q}\t%0"
9725 [(set_attr "type" "negnot")
9726 (set_attr "mode" "DI")])
9727
9728 ;; The problem with neg is that it does not perform (compare x 0),
9729 ;; it really performs (compare 0 x), which leaves us with the zero
9730 ;; flag being the only useful item.
9731
9732 (define_insn "*negdi2_cmpz_rex64"
9733 [(set (reg:CCZ 17)
9734 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9735 (const_int 0)))
9736 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9737 (neg:DI (match_dup 1)))]
9738 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9739 "neg{q}\t%0"
9740 [(set_attr "type" "negnot")
9741 (set_attr "mode" "DI")])
9742
9743
9744 (define_expand "negsi2"
9745 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9746 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9747 (clobber (reg:CC 17))])]
9748 ""
9749 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9750
9751 (define_insn "*negsi2_1"
9752 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9753 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9754 (clobber (reg:CC 17))]
9755 "ix86_unary_operator_ok (NEG, SImode, operands)"
9756 "neg{l}\t%0"
9757 [(set_attr "type" "negnot")
9758 (set_attr "mode" "SI")])
9759
9760 ;; Combine is quite creative about this pattern.
9761 (define_insn "*negsi2_1_zext"
9762 [(set (match_operand:DI 0 "register_operand" "=r")
9763 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9764 (const_int 32)))
9765 (const_int 32)))
9766 (clobber (reg:CC 17))]
9767 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9768 "neg{l}\t%k0"
9769 [(set_attr "type" "negnot")
9770 (set_attr "mode" "SI")])
9771
9772 ;; The problem with neg is that it does not perform (compare x 0),
9773 ;; it really performs (compare 0 x), which leaves us with the zero
9774 ;; flag being the only useful item.
9775
9776 (define_insn "*negsi2_cmpz"
9777 [(set (reg:CCZ 17)
9778 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9779 (const_int 0)))
9780 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9781 (neg:SI (match_dup 1)))]
9782 "ix86_unary_operator_ok (NEG, SImode, operands)"
9783 "neg{l}\t%0"
9784 [(set_attr "type" "negnot")
9785 (set_attr "mode" "SI")])
9786
9787 (define_insn "*negsi2_cmpz_zext"
9788 [(set (reg:CCZ 17)
9789 (compare:CCZ (lshiftrt:DI
9790 (neg:DI (ashift:DI
9791 (match_operand:DI 1 "register_operand" "0")
9792 (const_int 32)))
9793 (const_int 32))
9794 (const_int 0)))
9795 (set (match_operand:DI 0 "register_operand" "=r")
9796 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9797 (const_int 32)))
9798 (const_int 32)))]
9799 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9800 "neg{l}\t%k0"
9801 [(set_attr "type" "negnot")
9802 (set_attr "mode" "SI")])
9803
9804 (define_expand "neghi2"
9805 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9806 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9807 (clobber (reg:CC 17))])]
9808 "TARGET_HIMODE_MATH"
9809 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9810
9811 (define_insn "*neghi2_1"
9812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9813 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9814 (clobber (reg:CC 17))]
9815 "ix86_unary_operator_ok (NEG, HImode, operands)"
9816 "neg{w}\t%0"
9817 [(set_attr "type" "negnot")
9818 (set_attr "mode" "HI")])
9819
9820 (define_insn "*neghi2_cmpz"
9821 [(set (reg:CCZ 17)
9822 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9823 (const_int 0)))
9824 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9825 (neg:HI (match_dup 1)))]
9826 "ix86_unary_operator_ok (NEG, HImode, operands)"
9827 "neg{w}\t%0"
9828 [(set_attr "type" "negnot")
9829 (set_attr "mode" "HI")])
9830
9831 (define_expand "negqi2"
9832 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9833 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9834 (clobber (reg:CC 17))])]
9835 "TARGET_QIMODE_MATH"
9836 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9837
9838 (define_insn "*negqi2_1"
9839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9840 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9841 (clobber (reg:CC 17))]
9842 "ix86_unary_operator_ok (NEG, QImode, operands)"
9843 "neg{b}\t%0"
9844 [(set_attr "type" "negnot")
9845 (set_attr "mode" "QI")])
9846
9847 (define_insn "*negqi2_cmpz"
9848 [(set (reg:CCZ 17)
9849 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9850 (const_int 0)))
9851 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9852 (neg:QI (match_dup 1)))]
9853 "ix86_unary_operator_ok (NEG, QImode, operands)"
9854 "neg{b}\t%0"
9855 [(set_attr "type" "negnot")
9856 (set_attr "mode" "QI")])
9857
9858 ;; Changing of sign for FP values is doable using integer unit too.
9859
9860 (define_expand "negsf2"
9861 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9862 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9863 (clobber (reg:CC 17))])]
9864 "TARGET_80387"
9865 "if (TARGET_SSE)
9866 {
9867 /* In case operand is in memory, we will not use SSE. */
9868 if (memory_operand (operands[0], VOIDmode)
9869 && rtx_equal_p (operands[0], operands[1]))
9870 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9871 else
9872 {
9873 /* Using SSE is tricky, since we need bitwise negation of -0
9874 in register. */
9875 rtx reg = gen_reg_rtx (SFmode);
9876 rtx dest = operands[0];
9877 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9878
9879 operands[1] = force_reg (SFmode, operands[1]);
9880 operands[0] = force_reg (SFmode, operands[0]);
9881 reg = force_reg (V4SFmode,
9882 gen_rtx_CONST_VECTOR (V4SFmode,
9883 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9884 CONST0_RTX (SFmode),
9885 CONST0_RTX (SFmode))));
9886 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9887 if (dest != operands[0])
9888 emit_move_insn (dest, operands[0]);
9889 }
9890 DONE;
9891 }
9892 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9893
9894 (define_insn "negsf2_memory"
9895 [(set (match_operand:SF 0 "memory_operand" "=m")
9896 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9897 (clobber (reg:CC 17))]
9898 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9899 "#")
9900
9901 (define_insn "negsf2_ifs"
9902 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9903 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9904 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9905 (clobber (reg:CC 17))]
9906 "TARGET_SSE
9907 && (reload_in_progress || reload_completed
9908 || (register_operand (operands[0], VOIDmode)
9909 && register_operand (operands[1], VOIDmode)))"
9910 "#")
9911
9912 (define_split
9913 [(set (match_operand:SF 0 "memory_operand" "")
9914 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9915 (use (match_operand:SF 2 "" ""))
9916 (clobber (reg:CC 17))]
9917 ""
9918 [(parallel [(set (match_dup 0)
9919 (neg:SF (match_dup 1)))
9920 (clobber (reg:CC 17))])])
9921
9922 (define_split
9923 [(set (match_operand:SF 0 "register_operand" "")
9924 (neg:SF (match_operand:SF 1 "register_operand" "")))
9925 (use (match_operand:V4SF 2 "" ""))
9926 (clobber (reg:CC 17))]
9927 "reload_completed && !SSE_REG_P (operands[0])"
9928 [(parallel [(set (match_dup 0)
9929 (neg:SF (match_dup 1)))
9930 (clobber (reg:CC 17))])])
9931
9932 (define_split
9933 [(set (match_operand:SF 0 "register_operand" "")
9934 (neg:SF (match_operand:SF 1 "register_operand" "")))
9935 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9936 (clobber (reg:CC 17))]
9937 "reload_completed && SSE_REG_P (operands[0])"
9938 [(set (subreg:TI (match_dup 0) 0)
9939 (xor:TI (match_dup 1)
9940 (match_dup 2)))]
9941 {
9942 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9943 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9944 if (operands_match_p (operands[0], operands[2]))
9945 {
9946 rtx tmp;
9947 tmp = operands[1];
9948 operands[1] = operands[2];
9949 operands[2] = tmp;
9950 }
9951 })
9952
9953
9954 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9955 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9956 ;; to itself.
9957 (define_insn "*negsf2_if"
9958 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9959 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9960 (clobber (reg:CC 17))]
9961 "TARGET_80387 && !TARGET_SSE
9962 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9963 "#")
9964
9965 (define_split
9966 [(set (match_operand:SF 0 "fp_register_operand" "")
9967 (neg:SF (match_operand:SF 1 "register_operand" "")))
9968 (clobber (reg:CC 17))]
9969 "TARGET_80387 && reload_completed"
9970 [(set (match_dup 0)
9971 (neg:SF (match_dup 1)))]
9972 "")
9973
9974 (define_split
9975 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9976 (neg:SF (match_operand:SF 1 "register_operand" "")))
9977 (clobber (reg:CC 17))]
9978 "TARGET_80387 && reload_completed"
9979 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9980 (clobber (reg:CC 17))])]
9981 "operands[1] = gen_int_mode (0x80000000, SImode);
9982 operands[0] = gen_lowpart (SImode, operands[0]);")
9983
9984 (define_split
9985 [(set (match_operand 0 "memory_operand" "")
9986 (neg (match_operand 1 "memory_operand" "")))
9987 (clobber (reg:CC 17))]
9988 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9989 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9990 (clobber (reg:CC 17))])]
9991 {
9992 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9993
9994 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9995 if (size >= 12)
9996 size = 10;
9997 operands[0] = adjust_address (operands[0], QImode, size - 1);
9998 operands[1] = gen_int_mode (0x80, QImode);
9999 })
10000
10001 (define_expand "negdf2"
10002 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10003 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10004 (clobber (reg:CC 17))])]
10005 "TARGET_80387"
10006 "if (TARGET_SSE2)
10007 {
10008 /* In case operand is in memory, we will not use SSE. */
10009 if (memory_operand (operands[0], VOIDmode)
10010 && rtx_equal_p (operands[0], operands[1]))
10011 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
10012 else
10013 {
10014 /* Using SSE is tricky, since we need bitwise negation of -0
10015 in register. */
10016 rtx reg;
10017 #if HOST_BITS_PER_WIDE_INT >= 64
10018 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
10019 #else
10020 rtx imm = immed_double_const (0, 0x80000000, DImode);
10021 #endif
10022 rtx dest = operands[0];
10023
10024 operands[1] = force_reg (DFmode, operands[1]);
10025 operands[0] = force_reg (DFmode, operands[0]);
10026 imm = gen_lowpart (DFmode, imm);
10027 reg = force_reg (V2DFmode,
10028 gen_rtx_CONST_VECTOR (V2DFmode,
10029 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10030 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
10031 if (dest != operands[0])
10032 emit_move_insn (dest, operands[0]);
10033 }
10034 DONE;
10035 }
10036 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
10037
10038 (define_insn "negdf2_memory"
10039 [(set (match_operand:DF 0 "memory_operand" "=m")
10040 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10041 (clobber (reg:CC 17))]
10042 "ix86_unary_operator_ok (NEG, DFmode, operands)"
10043 "#")
10044
10045 (define_insn "negdf2_ifs"
10046 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10047 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10048 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10049 (clobber (reg:CC 17))]
10050 "!TARGET_64BIT && TARGET_SSE2
10051 && (reload_in_progress || reload_completed
10052 || (register_operand (operands[0], VOIDmode)
10053 && register_operand (operands[1], VOIDmode)))"
10054 "#")
10055
10056 (define_insn "*negdf2_ifs_rex64"
10057 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10058 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10059 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10060 (clobber (reg:CC 17))]
10061 "TARGET_64BIT && TARGET_SSE2
10062 && (reload_in_progress || reload_completed
10063 || (register_operand (operands[0], VOIDmode)
10064 && register_operand (operands[1], VOIDmode)))"
10065 "#")
10066
10067 (define_split
10068 [(set (match_operand:DF 0 "memory_operand" "")
10069 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10070 (use (match_operand:V2DF 2 "" ""))
10071 (clobber (reg:CC 17))]
10072 ""
10073 [(parallel [(set (match_dup 0)
10074 (neg:DF (match_dup 1)))
10075 (clobber (reg:CC 17))])])
10076
10077 (define_split
10078 [(set (match_operand:DF 0 "register_operand" "")
10079 (neg:DF (match_operand:DF 1 "register_operand" "")))
10080 (use (match_operand:V2DF 2 "" ""))
10081 (clobber (reg:CC 17))]
10082 "reload_completed && !SSE_REG_P (operands[0])
10083 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10084 [(parallel [(set (match_dup 0)
10085 (neg:DF (match_dup 1)))
10086 (clobber (reg:CC 17))])])
10087
10088 (define_split
10089 [(set (match_operand:DF 0 "register_operand" "")
10090 (neg:DF (match_operand:DF 1 "register_operand" "")))
10091 (use (match_operand:V2DF 2 "" ""))
10092 (clobber (reg:CC 17))]
10093 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10094 [(parallel [(set (match_dup 0)
10095 (xor:DI (match_dup 1) (match_dup 2)))
10096 (clobber (reg:CC 17))])]
10097 "operands[0] = gen_lowpart (DImode, operands[0]);
10098 operands[1] = gen_lowpart (DImode, operands[1]);
10099 operands[2] = gen_lowpart (DImode, operands[2]);")
10100
10101 (define_split
10102 [(set (match_operand:DF 0 "register_operand" "")
10103 (neg:DF (match_operand:DF 1 "register_operand" "")))
10104 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10105 (clobber (reg:CC 17))]
10106 "reload_completed && SSE_REG_P (operands[0])"
10107 [(set (subreg:TI (match_dup 0) 0)
10108 (xor:TI (match_dup 1)
10109 (match_dup 2)))]
10110 {
10111 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10112 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10113 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10114 /* Avoid possible reformatting on the operands. */
10115 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10116 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10117 if (operands_match_p (operands[0], operands[2]))
10118 {
10119 rtx tmp;
10120 tmp = operands[1];
10121 operands[1] = operands[2];
10122 operands[2] = tmp;
10123 }
10124 })
10125
10126 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10127 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10128 ;; to itself.
10129 (define_insn "*negdf2_if"
10130 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10131 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10132 (clobber (reg:CC 17))]
10133 "!TARGET_64BIT && TARGET_80387
10134 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10135 "#")
10136
10137 ;; FIXME: We should to allow integer registers here. Problem is that
10138 ;; we need another scratch register to get constant from.
10139 ;; Forcing constant to mem if no register available in peep2 should be
10140 ;; safe even for PIC mode, because of RIP relative addressing.
10141 (define_insn "*negdf2_if_rex64"
10142 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10143 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10144 (clobber (reg:CC 17))]
10145 "TARGET_64BIT && TARGET_80387
10146 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10147 "#")
10148
10149 (define_split
10150 [(set (match_operand:DF 0 "fp_register_operand" "")
10151 (neg:DF (match_operand:DF 1 "register_operand" "")))
10152 (clobber (reg:CC 17))]
10153 "TARGET_80387 && reload_completed"
10154 [(set (match_dup 0)
10155 (neg:DF (match_dup 1)))]
10156 "")
10157
10158 (define_split
10159 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10160 (neg:DF (match_operand:DF 1 "register_operand" "")))
10161 (clobber (reg:CC 17))]
10162 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10163 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10164 (clobber (reg:CC 17))])]
10165 "operands[4] = gen_int_mode (0x80000000, SImode);
10166 split_di (operands+0, 1, operands+2, operands+3);")
10167
10168 (define_expand "negxf2"
10169 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10170 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10171 (clobber (reg:CC 17))])]
10172 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10173 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10174
10175 (define_expand "negtf2"
10176 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10177 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10178 (clobber (reg:CC 17))])]
10179 "TARGET_80387"
10180 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10181
10182 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10183 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10184 ;; to itself.
10185 (define_insn "*negxf2_if"
10186 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10187 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10188 (clobber (reg:CC 17))]
10189 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10190 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10191 "#")
10192
10193 (define_split
10194 [(set (match_operand:XF 0 "fp_register_operand" "")
10195 (neg:XF (match_operand:XF 1 "register_operand" "")))
10196 (clobber (reg:CC 17))]
10197 "TARGET_80387 && reload_completed"
10198 [(set (match_dup 0)
10199 (neg:XF (match_dup 1)))]
10200 "")
10201
10202 (define_split
10203 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10204 (neg:XF (match_operand:XF 1 "register_operand" "")))
10205 (clobber (reg:CC 17))]
10206 "TARGET_80387 && reload_completed"
10207 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10208 (clobber (reg:CC 17))])]
10209 "operands[1] = GEN_INT (0x8000);
10210 operands[0] = gen_rtx_REG (SImode,
10211 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10212
10213 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10214 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10215 ;; to itself.
10216 (define_insn "*negtf2_if"
10217 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10218 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10219 (clobber (reg:CC 17))]
10220 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10221 "#")
10222
10223 (define_split
10224 [(set (match_operand:TF 0 "fp_register_operand" "")
10225 (neg:TF (match_operand:TF 1 "register_operand" "")))
10226 (clobber (reg:CC 17))]
10227 "TARGET_80387 && reload_completed"
10228 [(set (match_dup 0)
10229 (neg:TF (match_dup 1)))]
10230 "")
10231
10232 (define_split
10233 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10234 (neg:TF (match_operand:TF 1 "register_operand" "")))
10235 (clobber (reg:CC 17))]
10236 "TARGET_80387 && reload_completed"
10237 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10238 (clobber (reg:CC 17))])]
10239 "operands[1] = GEN_INT (0x8000);
10240 operands[0] = gen_rtx_REG (SImode,
10241 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10242
10243 ;; Conditionalize these after reload. If they matches before reload, we
10244 ;; lose the clobber and ability to use integer instructions.
10245
10246 (define_insn "*negsf2_1"
10247 [(set (match_operand:SF 0 "register_operand" "=f")
10248 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10249 "TARGET_80387 && reload_completed"
10250 "fchs"
10251 [(set_attr "type" "fsgn")
10252 (set_attr "mode" "SF")
10253 (set_attr "ppro_uops" "few")])
10254
10255 (define_insn "*negdf2_1"
10256 [(set (match_operand:DF 0 "register_operand" "=f")
10257 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10258 "TARGET_80387 && reload_completed"
10259 "fchs"
10260 [(set_attr "type" "fsgn")
10261 (set_attr "mode" "DF")
10262 (set_attr "ppro_uops" "few")])
10263
10264 (define_insn "*negextendsfdf2"
10265 [(set (match_operand:DF 0 "register_operand" "=f")
10266 (neg:DF (float_extend:DF
10267 (match_operand:SF 1 "register_operand" "0"))))]
10268 "TARGET_80387"
10269 "fchs"
10270 [(set_attr "type" "fsgn")
10271 (set_attr "mode" "DF")
10272 (set_attr "ppro_uops" "few")])
10273
10274 (define_insn "*negxf2_1"
10275 [(set (match_operand:XF 0 "register_operand" "=f")
10276 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10277 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10278 "fchs"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "XF")
10281 (set_attr "ppro_uops" "few")])
10282
10283 (define_insn "*negextenddfxf2"
10284 [(set (match_operand:XF 0 "register_operand" "=f")
10285 (neg:XF (float_extend:XF
10286 (match_operand:DF 1 "register_operand" "0"))))]
10287 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10288 "fchs"
10289 [(set_attr "type" "fsgn")
10290 (set_attr "mode" "XF")
10291 (set_attr "ppro_uops" "few")])
10292
10293 (define_insn "*negextendsfxf2"
10294 [(set (match_operand:XF 0 "register_operand" "=f")
10295 (neg:XF (float_extend:XF
10296 (match_operand:SF 1 "register_operand" "0"))))]
10297 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10298 "fchs"
10299 [(set_attr "type" "fsgn")
10300 (set_attr "mode" "XF")
10301 (set_attr "ppro_uops" "few")])
10302
10303 (define_insn "*negtf2_1"
10304 [(set (match_operand:TF 0 "register_operand" "=f")
10305 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10306 "TARGET_80387 && reload_completed"
10307 "fchs"
10308 [(set_attr "type" "fsgn")
10309 (set_attr "mode" "XF")
10310 (set_attr "ppro_uops" "few")])
10311
10312 (define_insn "*negextenddftf2"
10313 [(set (match_operand:TF 0 "register_operand" "=f")
10314 (neg:TF (float_extend:TF
10315 (match_operand:DF 1 "register_operand" "0"))))]
10316 "TARGET_80387"
10317 "fchs"
10318 [(set_attr "type" "fsgn")
10319 (set_attr "mode" "XF")
10320 (set_attr "ppro_uops" "few")])
10321
10322 (define_insn "*negextendsftf2"
10323 [(set (match_operand:TF 0 "register_operand" "=f")
10324 (neg:TF (float_extend:TF
10325 (match_operand:SF 1 "register_operand" "0"))))]
10326 "TARGET_80387"
10327 "fchs"
10328 [(set_attr "type" "fsgn")
10329 (set_attr "mode" "XF")
10330 (set_attr "ppro_uops" "few")])
10331 \f
10332 ;; Absolute value instructions
10333
10334 (define_expand "abssf2"
10335 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10336 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10337 (clobber (reg:CC 17))])]
10338 "TARGET_80387"
10339 "if (TARGET_SSE)
10340 {
10341 /* In case operand is in memory, we will not use SSE. */
10342 if (memory_operand (operands[0], VOIDmode)
10343 && rtx_equal_p (operands[0], operands[1]))
10344 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10345 else
10346 {
10347 /* Using SSE is tricky, since we need bitwise negation of -0
10348 in register. */
10349 rtx reg = gen_reg_rtx (V4SFmode);
10350 rtx dest = operands[0];
10351 rtx imm;
10352
10353 operands[1] = force_reg (SFmode, operands[1]);
10354 operands[0] = force_reg (SFmode, operands[0]);
10355 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10356 reg = force_reg (V4SFmode,
10357 gen_rtx_CONST_VECTOR (V4SFmode,
10358 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10359 CONST0_RTX (SFmode),
10360 CONST0_RTX (SFmode))));
10361 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10362 if (dest != operands[0])
10363 emit_move_insn (dest, operands[0]);
10364 }
10365 DONE;
10366 }
10367 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10368
10369 (define_insn "abssf2_memory"
10370 [(set (match_operand:SF 0 "memory_operand" "=m")
10371 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10372 (clobber (reg:CC 17))]
10373 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10374 "#")
10375
10376 (define_insn "abssf2_ifs"
10377 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10378 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10379 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10380 (clobber (reg:CC 17))]
10381 "TARGET_SSE
10382 && (reload_in_progress || reload_completed
10383 || (register_operand (operands[0], VOIDmode)
10384 && register_operand (operands[1], VOIDmode)))"
10385 "#")
10386
10387 (define_split
10388 [(set (match_operand:SF 0 "memory_operand" "")
10389 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10390 (use (match_operand:V4SF 2 "" ""))
10391 (clobber (reg:CC 17))]
10392 ""
10393 [(parallel [(set (match_dup 0)
10394 (abs:SF (match_dup 1)))
10395 (clobber (reg:CC 17))])])
10396
10397 (define_split
10398 [(set (match_operand:SF 0 "register_operand" "")
10399 (abs:SF (match_operand:SF 1 "register_operand" "")))
10400 (use (match_operand:V4SF 2 "" ""))
10401 (clobber (reg:CC 17))]
10402 "reload_completed && !SSE_REG_P (operands[0])"
10403 [(parallel [(set (match_dup 0)
10404 (abs:SF (match_dup 1)))
10405 (clobber (reg:CC 17))])])
10406
10407 (define_split
10408 [(set (match_operand:SF 0 "register_operand" "")
10409 (abs:SF (match_operand:SF 1 "register_operand" "")))
10410 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10411 (clobber (reg:CC 17))]
10412 "reload_completed && SSE_REG_P (operands[0])"
10413 [(set (subreg:TI (match_dup 0) 0)
10414 (and:TI (match_dup 1)
10415 (match_dup 2)))]
10416 {
10417 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10418 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10419 if (operands_match_p (operands[0], operands[2]))
10420 {
10421 rtx tmp;
10422 tmp = operands[1];
10423 operands[1] = operands[2];
10424 operands[2] = tmp;
10425 }
10426 })
10427
10428 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10429 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10430 ;; to itself.
10431 (define_insn "*abssf2_if"
10432 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10433 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10434 (clobber (reg:CC 17))]
10435 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10436 "#")
10437
10438 (define_split
10439 [(set (match_operand:SF 0 "fp_register_operand" "")
10440 (abs:SF (match_operand:SF 1 "register_operand" "")))
10441 (clobber (reg:CC 17))]
10442 "TARGET_80387 && reload_completed"
10443 [(set (match_dup 0)
10444 (abs:SF (match_dup 1)))]
10445 "")
10446
10447 (define_split
10448 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10449 (abs:SF (match_operand:SF 1 "register_operand" "")))
10450 (clobber (reg:CC 17))]
10451 "TARGET_80387 && reload_completed"
10452 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10453 (clobber (reg:CC 17))])]
10454 "operands[1] = gen_int_mode (~0x80000000, SImode);
10455 operands[0] = gen_lowpart (SImode, operands[0]);")
10456
10457 (define_split
10458 [(set (match_operand 0 "memory_operand" "")
10459 (abs (match_operand 1 "memory_operand" "")))
10460 (clobber (reg:CC 17))]
10461 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10462 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10463 (clobber (reg:CC 17))])]
10464 {
10465 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10466
10467 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10468 if (size >= 12)
10469 size = 10;
10470 operands[0] = adjust_address (operands[0], QImode, size - 1);
10471 operands[1] = gen_int_mode (~0x80, QImode);
10472 })
10473
10474 (define_expand "absdf2"
10475 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10476 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10477 (clobber (reg:CC 17))])]
10478 "TARGET_80387"
10479 "if (TARGET_SSE2)
10480 {
10481 /* In case operand is in memory, we will not use SSE. */
10482 if (memory_operand (operands[0], VOIDmode)
10483 && rtx_equal_p (operands[0], operands[1]))
10484 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10485 else
10486 {
10487 /* Using SSE is tricky, since we need bitwise negation of -0
10488 in register. */
10489 rtx reg = gen_reg_rtx (V2DFmode);
10490 #if HOST_BITS_PER_WIDE_INT >= 64
10491 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10492 #else
10493 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10494 #endif
10495 rtx dest = operands[0];
10496
10497 operands[1] = force_reg (DFmode, operands[1]);
10498 operands[0] = force_reg (DFmode, operands[0]);
10499
10500 /* Produce LONG_DOUBLE with the proper immediate argument. */
10501 imm = gen_lowpart (DFmode, imm);
10502 reg = force_reg (V2DFmode,
10503 gen_rtx_CONST_VECTOR (V2DFmode,
10504 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10505 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10506 if (dest != operands[0])
10507 emit_move_insn (dest, operands[0]);
10508 }
10509 DONE;
10510 }
10511 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10512
10513 (define_insn "absdf2_memory"
10514 [(set (match_operand:DF 0 "memory_operand" "=m")
10515 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10516 (clobber (reg:CC 17))]
10517 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10518 "#")
10519
10520 (define_insn "absdf2_ifs"
10521 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10522 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10523 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10524 (clobber (reg:CC 17))]
10525 "!TARGET_64BIT && TARGET_SSE2
10526 && (reload_in_progress || reload_completed
10527 || (register_operand (operands[0], VOIDmode)
10528 && register_operand (operands[1], VOIDmode)))"
10529 "#")
10530
10531 (define_insn "*absdf2_ifs_rex64"
10532 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10533 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10534 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10535 (clobber (reg:CC 17))]
10536 "TARGET_64BIT && TARGET_SSE2
10537 && (reload_in_progress || reload_completed
10538 || (register_operand (operands[0], VOIDmode)
10539 && register_operand (operands[1], VOIDmode)))"
10540 "#")
10541
10542 (define_split
10543 [(set (match_operand:DF 0 "memory_operand" "")
10544 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10545 (use (match_operand:V2DF 2 "" ""))
10546 (clobber (reg:CC 17))]
10547 ""
10548 [(parallel [(set (match_dup 0)
10549 (abs:DF (match_dup 1)))
10550 (clobber (reg:CC 17))])])
10551
10552 (define_split
10553 [(set (match_operand:DF 0 "register_operand" "")
10554 (abs:DF (match_operand:DF 1 "register_operand" "")))
10555 (use (match_operand:V2DF 2 "" ""))
10556 (clobber (reg:CC 17))]
10557 "reload_completed && !SSE_REG_P (operands[0])"
10558 [(parallel [(set (match_dup 0)
10559 (abs:DF (match_dup 1)))
10560 (clobber (reg:CC 17))])])
10561
10562 (define_split
10563 [(set (match_operand:DF 0 "register_operand" "")
10564 (abs:DF (match_operand:DF 1 "register_operand" "")))
10565 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10566 (clobber (reg:CC 17))]
10567 "reload_completed && SSE_REG_P (operands[0])"
10568 [(set (subreg:TI (match_dup 0) 0)
10569 (and:TI (match_dup 1)
10570 (match_dup 2)))]
10571 {
10572 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10573 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10574 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10575 /* Avoid possible reformatting on the operands. */
10576 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10577 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10578 if (operands_match_p (operands[0], operands[2]))
10579 {
10580 rtx tmp;
10581 tmp = operands[1];
10582 operands[1] = operands[2];
10583 operands[2] = tmp;
10584 }
10585 })
10586
10587
10588 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10589 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10590 ;; to itself.
10591 (define_insn "*absdf2_if"
10592 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10593 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10594 (clobber (reg:CC 17))]
10595 "!TARGET_64BIT && TARGET_80387
10596 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10597 "#")
10598
10599 ;; FIXME: We should to allow integer registers here. Problem is that
10600 ;; we need another scratch register to get constant from.
10601 ;; Forcing constant to mem if no register available in peep2 should be
10602 ;; safe even for PIC mode, because of RIP relative addressing.
10603 (define_insn "*absdf2_if_rex64"
10604 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10605 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10606 (clobber (reg:CC 17))]
10607 "TARGET_64BIT && TARGET_80387
10608 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10609 "#")
10610
10611 (define_split
10612 [(set (match_operand:DF 0 "fp_register_operand" "")
10613 (abs:DF (match_operand:DF 1 "register_operand" "")))
10614 (clobber (reg:CC 17))]
10615 "TARGET_80387 && reload_completed"
10616 [(set (match_dup 0)
10617 (abs:DF (match_dup 1)))]
10618 "")
10619
10620 (define_split
10621 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10622 (abs:DF (match_operand:DF 1 "register_operand" "")))
10623 (clobber (reg:CC 17))]
10624 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10625 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10626 (clobber (reg:CC 17))])]
10627 "operands[4] = gen_int_mode (~0x80000000, SImode);
10628 split_di (operands+0, 1, operands+2, operands+3);")
10629
10630 (define_expand "absxf2"
10631 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10632 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10633 (clobber (reg:CC 17))])]
10634 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10635 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10636
10637 (define_expand "abstf2"
10638 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10639 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10640 (clobber (reg:CC 17))])]
10641 "TARGET_80387"
10642 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10643
10644 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10645 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10646 ;; to itself.
10647 (define_insn "*absxf2_if"
10648 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10649 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10650 (clobber (reg:CC 17))]
10651 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10652 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10653 "#")
10654
10655 (define_split
10656 [(set (match_operand:XF 0 "fp_register_operand" "")
10657 (abs:XF (match_operand:XF 1 "register_operand" "")))
10658 (clobber (reg:CC 17))]
10659 "TARGET_80387 && reload_completed"
10660 [(set (match_dup 0)
10661 (abs:XF (match_dup 1)))]
10662 "")
10663
10664 (define_split
10665 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10666 (abs:XF (match_operand:XF 1 "register_operand" "")))
10667 (clobber (reg:CC 17))]
10668 "TARGET_80387 && reload_completed"
10669 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10670 (clobber (reg:CC 17))])]
10671 "operands[1] = GEN_INT (~0x8000);
10672 operands[0] = gen_rtx_REG (SImode,
10673 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10674
10675 (define_insn "*abstf2_if"
10676 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10677 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10678 (clobber (reg:CC 17))]
10679 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10680 "#")
10681
10682 (define_split
10683 [(set (match_operand:TF 0 "fp_register_operand" "")
10684 (abs:TF (match_operand:TF 1 "register_operand" "")))
10685 (clobber (reg:CC 17))]
10686 "TARGET_80387 && reload_completed"
10687 [(set (match_dup 0)
10688 (abs:TF (match_dup 1)))]
10689 "")
10690
10691 (define_split
10692 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10693 (abs:TF (match_operand:TF 1 "register_operand" "")))
10694 (clobber (reg:CC 17))]
10695 "TARGET_80387 && reload_completed"
10696 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10697 (clobber (reg:CC 17))])]
10698 "operands[1] = GEN_INT (~0x8000);
10699 operands[0] = gen_rtx_REG (SImode,
10700 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10701
10702 (define_insn "*abssf2_1"
10703 [(set (match_operand:SF 0 "register_operand" "=f")
10704 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10705 "TARGET_80387 && reload_completed"
10706 "fabs"
10707 [(set_attr "type" "fsgn")
10708 (set_attr "mode" "SF")])
10709
10710 (define_insn "*absdf2_1"
10711 [(set (match_operand:DF 0 "register_operand" "=f")
10712 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10713 "TARGET_80387 && reload_completed"
10714 "fabs"
10715 [(set_attr "type" "fsgn")
10716 (set_attr "mode" "DF")])
10717
10718 (define_insn "*absextendsfdf2"
10719 [(set (match_operand:DF 0 "register_operand" "=f")
10720 (abs:DF (float_extend:DF
10721 (match_operand:SF 1 "register_operand" "0"))))]
10722 "TARGET_80387"
10723 "fabs"
10724 [(set_attr "type" "fsgn")
10725 (set_attr "mode" "DF")])
10726
10727 (define_insn "*absxf2_1"
10728 [(set (match_operand:XF 0 "register_operand" "=f")
10729 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10730 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10731 "fabs"
10732 [(set_attr "type" "fsgn")
10733 (set_attr "mode" "DF")])
10734
10735 (define_insn "*absextenddfxf2"
10736 [(set (match_operand:XF 0 "register_operand" "=f")
10737 (abs:XF (float_extend:XF
10738 (match_operand:DF 1 "register_operand" "0"))))]
10739 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10740 "fabs"
10741 [(set_attr "type" "fsgn")
10742 (set_attr "mode" "XF")])
10743
10744 (define_insn "*absextendsfxf2"
10745 [(set (match_operand:XF 0 "register_operand" "=f")
10746 (abs:XF (float_extend:XF
10747 (match_operand:SF 1 "register_operand" "0"))))]
10748 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10749 "fabs"
10750 [(set_attr "type" "fsgn")
10751 (set_attr "mode" "XF")])
10752
10753 (define_insn "*abstf2_1"
10754 [(set (match_operand:TF 0 "register_operand" "=f")
10755 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10756 "TARGET_80387 && reload_completed"
10757 "fabs"
10758 [(set_attr "type" "fsgn")
10759 (set_attr "mode" "DF")])
10760
10761 (define_insn "*absextenddftf2"
10762 [(set (match_operand:TF 0 "register_operand" "=f")
10763 (abs:TF (float_extend:TF
10764 (match_operand:DF 1 "register_operand" "0"))))]
10765 "TARGET_80387"
10766 "fabs"
10767 [(set_attr "type" "fsgn")
10768 (set_attr "mode" "XF")])
10769
10770 (define_insn "*absextendsftf2"
10771 [(set (match_operand:TF 0 "register_operand" "=f")
10772 (abs:TF (float_extend:TF
10773 (match_operand:SF 1 "register_operand" "0"))))]
10774 "TARGET_80387"
10775 "fabs"
10776 [(set_attr "type" "fsgn")
10777 (set_attr "mode" "XF")])
10778 \f
10779 ;; One complement instructions
10780
10781 (define_expand "one_cmpldi2"
10782 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10783 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10784 "TARGET_64BIT"
10785 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10786
10787 (define_insn "*one_cmpldi2_1_rex64"
10788 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10789 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10790 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10791 "not{q}\t%0"
10792 [(set_attr "type" "negnot")
10793 (set_attr "mode" "DI")])
10794
10795 (define_insn "*one_cmpldi2_2_rex64"
10796 [(set (reg 17)
10797 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10798 (const_int 0)))
10799 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10800 (not:DI (match_dup 1)))]
10801 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10802 && ix86_unary_operator_ok (NOT, DImode, operands)"
10803 "#"
10804 [(set_attr "type" "alu1")
10805 (set_attr "mode" "DI")])
10806
10807 (define_split
10808 [(set (reg 17)
10809 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10810 (const_int 0)))
10811 (set (match_operand:DI 0 "nonimmediate_operand" "")
10812 (not:DI (match_dup 1)))]
10813 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10814 [(parallel [(set (reg:CCNO 17)
10815 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10816 (const_int 0)))
10817 (set (match_dup 0)
10818 (xor:DI (match_dup 1) (const_int -1)))])]
10819 "")
10820
10821 (define_expand "one_cmplsi2"
10822 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10823 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10824 ""
10825 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10826
10827 (define_insn "*one_cmplsi2_1"
10828 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10829 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10830 "ix86_unary_operator_ok (NOT, SImode, operands)"
10831 "not{l}\t%0"
10832 [(set_attr "type" "negnot")
10833 (set_attr "mode" "SI")])
10834
10835 ;; ??? Currently never generated - xor is used instead.
10836 (define_insn "*one_cmplsi2_1_zext"
10837 [(set (match_operand:DI 0 "register_operand" "=r")
10838 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10839 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10840 "not{l}\t%k0"
10841 [(set_attr "type" "negnot")
10842 (set_attr "mode" "SI")])
10843
10844 (define_insn "*one_cmplsi2_2"
10845 [(set (reg 17)
10846 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10847 (const_int 0)))
10848 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10849 (not:SI (match_dup 1)))]
10850 "ix86_match_ccmode (insn, CCNOmode)
10851 && ix86_unary_operator_ok (NOT, SImode, operands)"
10852 "#"
10853 [(set_attr "type" "alu1")
10854 (set_attr "mode" "SI")])
10855
10856 (define_split
10857 [(set (reg 17)
10858 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10859 (const_int 0)))
10860 (set (match_operand:SI 0 "nonimmediate_operand" "")
10861 (not:SI (match_dup 1)))]
10862 "ix86_match_ccmode (insn, CCNOmode)"
10863 [(parallel [(set (reg:CCNO 17)
10864 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10865 (const_int 0)))
10866 (set (match_dup 0)
10867 (xor:SI (match_dup 1) (const_int -1)))])]
10868 "")
10869
10870 ;; ??? Currently never generated - xor is used instead.
10871 (define_insn "*one_cmplsi2_2_zext"
10872 [(set (reg 17)
10873 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10874 (const_int 0)))
10875 (set (match_operand:DI 0 "register_operand" "=r")
10876 (zero_extend:DI (not:SI (match_dup 1))))]
10877 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10878 && ix86_unary_operator_ok (NOT, SImode, operands)"
10879 "#"
10880 [(set_attr "type" "alu1")
10881 (set_attr "mode" "SI")])
10882
10883 (define_split
10884 [(set (reg 17)
10885 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10886 (const_int 0)))
10887 (set (match_operand:DI 0 "register_operand" "")
10888 (zero_extend:DI (not:SI (match_dup 1))))]
10889 "ix86_match_ccmode (insn, CCNOmode)"
10890 [(parallel [(set (reg:CCNO 17)
10891 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10892 (const_int 0)))
10893 (set (match_dup 0)
10894 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10895 "")
10896
10897 (define_expand "one_cmplhi2"
10898 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10899 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10900 "TARGET_HIMODE_MATH"
10901 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10902
10903 (define_insn "*one_cmplhi2_1"
10904 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10905 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10906 "ix86_unary_operator_ok (NOT, HImode, operands)"
10907 "not{w}\t%0"
10908 [(set_attr "type" "negnot")
10909 (set_attr "mode" "HI")])
10910
10911 (define_insn "*one_cmplhi2_2"
10912 [(set (reg 17)
10913 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10914 (const_int 0)))
10915 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10916 (not:HI (match_dup 1)))]
10917 "ix86_match_ccmode (insn, CCNOmode)
10918 && ix86_unary_operator_ok (NEG, HImode, operands)"
10919 "#"
10920 [(set_attr "type" "alu1")
10921 (set_attr "mode" "HI")])
10922
10923 (define_split
10924 [(set (reg 17)
10925 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10926 (const_int 0)))
10927 (set (match_operand:HI 0 "nonimmediate_operand" "")
10928 (not:HI (match_dup 1)))]
10929 "ix86_match_ccmode (insn, CCNOmode)"
10930 [(parallel [(set (reg:CCNO 17)
10931 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10932 (const_int 0)))
10933 (set (match_dup 0)
10934 (xor:HI (match_dup 1) (const_int -1)))])]
10935 "")
10936
10937 ;; %%% Potential partial reg stall on alternative 1. What to do?
10938 (define_expand "one_cmplqi2"
10939 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10940 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10941 "TARGET_QIMODE_MATH"
10942 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10943
10944 (define_insn "*one_cmplqi2_1"
10945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10946 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10947 "ix86_unary_operator_ok (NOT, QImode, operands)"
10948 "@
10949 not{b}\t%0
10950 not{l}\t%k0"
10951 [(set_attr "type" "negnot")
10952 (set_attr "mode" "QI,SI")])
10953
10954 (define_insn "*one_cmplqi2_2"
10955 [(set (reg 17)
10956 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10957 (const_int 0)))
10958 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10959 (not:QI (match_dup 1)))]
10960 "ix86_match_ccmode (insn, CCNOmode)
10961 && ix86_unary_operator_ok (NOT, QImode, operands)"
10962 "#"
10963 [(set_attr "type" "alu1")
10964 (set_attr "mode" "QI")])
10965
10966 (define_split
10967 [(set (reg 17)
10968 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10969 (const_int 0)))
10970 (set (match_operand:QI 0 "nonimmediate_operand" "")
10971 (not:QI (match_dup 1)))]
10972 "ix86_match_ccmode (insn, CCNOmode)"
10973 [(parallel [(set (reg:CCNO 17)
10974 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10975 (const_int 0)))
10976 (set (match_dup 0)
10977 (xor:QI (match_dup 1) (const_int -1)))])]
10978 "")
10979 \f
10980 ;; Arithmetic shift instructions
10981
10982 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10983 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10984 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10985 ;; from the assembler input.
10986 ;;
10987 ;; This instruction shifts the target reg/mem as usual, but instead of
10988 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10989 ;; is a left shift double, bits are taken from the high order bits of
10990 ;; reg, else if the insn is a shift right double, bits are taken from the
10991 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10992 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10993 ;;
10994 ;; Since sh[lr]d does not change the `reg' operand, that is done
10995 ;; separately, making all shifts emit pairs of shift double and normal
10996 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10997 ;; support a 63 bit shift, each shift where the count is in a reg expands
10998 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10999 ;;
11000 ;; If the shift count is a constant, we need never emit more than one
11001 ;; shift pair, instead using moves and sign extension for counts greater
11002 ;; than 31.
11003
11004 (define_expand "ashldi3"
11005 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11006 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
11007 (match_operand:QI 2 "nonmemory_operand" "")))
11008 (clobber (reg:CC 17))])]
11009 ""
11010 {
11011 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11012 {
11013 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
11014 DONE;
11015 }
11016 ix86_expand_binary_operator (ASHIFT, DImode, operands);
11017 DONE;
11018 })
11019
11020 (define_insn "*ashldi3_1_rex64"
11021 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11022 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
11023 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11024 (clobber (reg:CC 17))]
11025 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11026 {
11027 switch (get_attr_type (insn))
11028 {
11029 case TYPE_ALU:
11030 if (operands[2] != const1_rtx)
11031 abort ();
11032 if (!rtx_equal_p (operands[0], operands[1]))
11033 abort ();
11034 return "add{q}\t{%0, %0|%0, %0}";
11035
11036 case TYPE_LEA:
11037 if (GET_CODE (operands[2]) != CONST_INT
11038 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11039 abort ();
11040 operands[1] = gen_rtx_MULT (DImode, operands[1],
11041 GEN_INT (1 << INTVAL (operands[2])));
11042 return "lea{q}\t{%a1, %0|%0, %a1}";
11043
11044 default:
11045 if (REG_P (operands[2]))
11046 return "sal{q}\t{%b2, %0|%0, %b2}";
11047 else if (GET_CODE (operands[2]) == CONST_INT
11048 && INTVAL (operands[2]) == 1
11049 && (TARGET_SHIFT1 || optimize_size))
11050 return "sal{q}\t%0";
11051 else
11052 return "sal{q}\t{%2, %0|%0, %2}";
11053 }
11054 }
11055 [(set (attr "type")
11056 (cond [(eq_attr "alternative" "1")
11057 (const_string "lea")
11058 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11059 (const_int 0))
11060 (match_operand 0 "register_operand" ""))
11061 (match_operand 2 "const1_operand" ""))
11062 (const_string "alu")
11063 ]
11064 (const_string "ishift")))
11065 (set_attr "mode" "DI")])
11066
11067 ;; Convert lea to the lea pattern to avoid flags dependency.
11068 (define_split
11069 [(set (match_operand:DI 0 "register_operand" "")
11070 (ashift:DI (match_operand:DI 1 "register_operand" "")
11071 (match_operand:QI 2 "immediate_operand" "")))
11072 (clobber (reg:CC 17))]
11073 "TARGET_64BIT && reload_completed
11074 && true_regnum (operands[0]) != true_regnum (operands[1])"
11075 [(set (match_dup 0)
11076 (mult:DI (match_dup 1)
11077 (match_dup 2)))]
11078 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11079
11080 ;; This pattern can't accept a variable shift count, since shifts by
11081 ;; zero don't affect the flags. We assume that shifts by constant
11082 ;; zero are optimized away.
11083 (define_insn "*ashldi3_cmp_rex64"
11084 [(set (reg 17)
11085 (compare
11086 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11087 (match_operand:QI 2 "immediate_operand" "e"))
11088 (const_int 0)))
11089 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11090 (ashift:DI (match_dup 1) (match_dup 2)))]
11091 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11092 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11093 {
11094 switch (get_attr_type (insn))
11095 {
11096 case TYPE_ALU:
11097 if (operands[2] != const1_rtx)
11098 abort ();
11099 return "add{q}\t{%0, %0|%0, %0}";
11100
11101 default:
11102 if (REG_P (operands[2]))
11103 return "sal{q}\t{%b2, %0|%0, %b2}";
11104 else if (GET_CODE (operands[2]) == CONST_INT
11105 && INTVAL (operands[2]) == 1
11106 && (TARGET_SHIFT1 || optimize_size))
11107 return "sal{q}\t%0";
11108 else
11109 return "sal{q}\t{%2, %0|%0, %2}";
11110 }
11111 }
11112 [(set (attr "type")
11113 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11114 (const_int 0))
11115 (match_operand 0 "register_operand" ""))
11116 (match_operand 2 "const1_operand" ""))
11117 (const_string "alu")
11118 ]
11119 (const_string "ishift")))
11120 (set_attr "mode" "DI")])
11121
11122 (define_insn "ashldi3_1"
11123 [(set (match_operand:DI 0 "register_operand" "=r")
11124 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11125 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11126 (clobber (match_scratch:SI 3 "=&r"))
11127 (clobber (reg:CC 17))]
11128 "!TARGET_64BIT && TARGET_CMOVE"
11129 "#"
11130 [(set_attr "type" "multi")])
11131
11132 (define_insn "*ashldi3_2"
11133 [(set (match_operand:DI 0 "register_operand" "=r")
11134 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11135 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11136 (clobber (reg:CC 17))]
11137 "!TARGET_64BIT"
11138 "#"
11139 [(set_attr "type" "multi")])
11140
11141 (define_split
11142 [(set (match_operand:DI 0 "register_operand" "")
11143 (ashift:DI (match_operand:DI 1 "register_operand" "")
11144 (match_operand:QI 2 "nonmemory_operand" "")))
11145 (clobber (match_scratch:SI 3 ""))
11146 (clobber (reg:CC 17))]
11147 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11148 [(const_int 0)]
11149 "ix86_split_ashldi (operands, operands[3]); DONE;")
11150
11151 (define_split
11152 [(set (match_operand:DI 0 "register_operand" "")
11153 (ashift:DI (match_operand:DI 1 "register_operand" "")
11154 (match_operand:QI 2 "nonmemory_operand" "")))
11155 (clobber (reg:CC 17))]
11156 "!TARGET_64BIT && reload_completed"
11157 [(const_int 0)]
11158 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11159
11160 (define_insn "x86_shld_1"
11161 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11162 (ior:SI (ashift:SI (match_dup 0)
11163 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11164 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11165 (minus:QI (const_int 32) (match_dup 2)))))
11166 (clobber (reg:CC 17))]
11167 ""
11168 "@
11169 shld{l}\t{%2, %1, %0|%0, %1, %2}
11170 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11171 [(set_attr "type" "ishift")
11172 (set_attr "prefix_0f" "1")
11173 (set_attr "mode" "SI")
11174 (set_attr "pent_pair" "np")
11175 (set_attr "athlon_decode" "vector")
11176 (set_attr "ppro_uops" "few")])
11177
11178 (define_expand "x86_shift_adj_1"
11179 [(set (reg:CCZ 17)
11180 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11181 (const_int 32))
11182 (const_int 0)))
11183 (set (match_operand:SI 0 "register_operand" "")
11184 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11185 (match_operand:SI 1 "register_operand" "")
11186 (match_dup 0)))
11187 (set (match_dup 1)
11188 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11189 (match_operand:SI 3 "register_operand" "r")
11190 (match_dup 1)))]
11191 "TARGET_CMOVE"
11192 "")
11193
11194 (define_expand "x86_shift_adj_2"
11195 [(use (match_operand:SI 0 "register_operand" ""))
11196 (use (match_operand:SI 1 "register_operand" ""))
11197 (use (match_operand:QI 2 "register_operand" ""))]
11198 ""
11199 {
11200 rtx label = gen_label_rtx ();
11201 rtx tmp;
11202
11203 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11204
11205 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11206 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11207 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11208 gen_rtx_LABEL_REF (VOIDmode, label),
11209 pc_rtx);
11210 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11211 JUMP_LABEL (tmp) = label;
11212
11213 emit_move_insn (operands[0], operands[1]);
11214 emit_move_insn (operands[1], const0_rtx);
11215
11216 emit_label (label);
11217 LABEL_NUSES (label) = 1;
11218
11219 DONE;
11220 })
11221
11222 (define_expand "ashlsi3"
11223 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11224 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11225 (match_operand:QI 2 "nonmemory_operand" "")))
11226 (clobber (reg:CC 17))]
11227 ""
11228 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11229
11230 (define_insn "*ashlsi3_1"
11231 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11232 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11233 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11234 (clobber (reg:CC 17))]
11235 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11236 {
11237 switch (get_attr_type (insn))
11238 {
11239 case TYPE_ALU:
11240 if (operands[2] != const1_rtx)
11241 abort ();
11242 if (!rtx_equal_p (operands[0], operands[1]))
11243 abort ();
11244 return "add{l}\t{%0, %0|%0, %0}";
11245
11246 case TYPE_LEA:
11247 return "#";
11248
11249 default:
11250 if (REG_P (operands[2]))
11251 return "sal{l}\t{%b2, %0|%0, %b2}";
11252 else if (GET_CODE (operands[2]) == CONST_INT
11253 && INTVAL (operands[2]) == 1
11254 && (TARGET_SHIFT1 || optimize_size))
11255 return "sal{l}\t%0";
11256 else
11257 return "sal{l}\t{%2, %0|%0, %2}";
11258 }
11259 }
11260 [(set (attr "type")
11261 (cond [(eq_attr "alternative" "1")
11262 (const_string "lea")
11263 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11264 (const_int 0))
11265 (match_operand 0 "register_operand" ""))
11266 (match_operand 2 "const1_operand" ""))
11267 (const_string "alu")
11268 ]
11269 (const_string "ishift")))
11270 (set_attr "mode" "SI")])
11271
11272 ;; Convert lea to the lea pattern to avoid flags dependency.
11273 (define_split
11274 [(set (match_operand 0 "register_operand" "")
11275 (ashift (match_operand 1 "index_register_operand" "")
11276 (match_operand:QI 2 "const_int_operand" "")))
11277 (clobber (reg:CC 17))]
11278 "reload_completed
11279 && true_regnum (operands[0]) != true_regnum (operands[1])"
11280 [(const_int 0)]
11281 {
11282 rtx pat;
11283 operands[0] = gen_lowpart (SImode, operands[0]);
11284 operands[1] = gen_lowpart (Pmode, operands[1]);
11285 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11286 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11287 if (Pmode != SImode)
11288 pat = gen_rtx_SUBREG (SImode, pat, 0);
11289 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11290 DONE;
11291 })
11292
11293 ;; Rare case of shifting RSP is handled by generating move and shift
11294 (define_split
11295 [(set (match_operand 0 "register_operand" "")
11296 (ashift (match_operand 1 "register_operand" "")
11297 (match_operand:QI 2 "const_int_operand" "")))
11298 (clobber (reg:CC 17))]
11299 "reload_completed
11300 && true_regnum (operands[0]) != true_regnum (operands[1])"
11301 [(const_int 0)]
11302 {
11303 rtx pat, clob;
11304 emit_move_insn (operands[1], operands[0]);
11305 pat = gen_rtx_SET (VOIDmode, operands[0],
11306 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11307 operands[0], operands[2]));
11308 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11309 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11310 DONE;
11311 })
11312
11313 (define_insn "*ashlsi3_1_zext"
11314 [(set (match_operand:DI 0 "register_operand" "=r,r")
11315 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11316 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11317 (clobber (reg:CC 17))]
11318 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11319 {
11320 switch (get_attr_type (insn))
11321 {
11322 case TYPE_ALU:
11323 if (operands[2] != const1_rtx)
11324 abort ();
11325 return "add{l}\t{%k0, %k0|%k0, %k0}";
11326
11327 case TYPE_LEA:
11328 return "#";
11329
11330 default:
11331 if (REG_P (operands[2]))
11332 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11333 else if (GET_CODE (operands[2]) == CONST_INT
11334 && INTVAL (operands[2]) == 1
11335 && (TARGET_SHIFT1 || optimize_size))
11336 return "sal{l}\t%k0";
11337 else
11338 return "sal{l}\t{%2, %k0|%k0, %2}";
11339 }
11340 }
11341 [(set (attr "type")
11342 (cond [(eq_attr "alternative" "1")
11343 (const_string "lea")
11344 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11345 (const_int 0))
11346 (match_operand 2 "const1_operand" ""))
11347 (const_string "alu")
11348 ]
11349 (const_string "ishift")))
11350 (set_attr "mode" "SI")])
11351
11352 ;; Convert lea to the lea pattern to avoid flags dependency.
11353 (define_split
11354 [(set (match_operand:DI 0 "register_operand" "")
11355 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11356 (match_operand:QI 2 "const_int_operand" ""))))
11357 (clobber (reg:CC 17))]
11358 "TARGET_64BIT && reload_completed
11359 && true_regnum (operands[0]) != true_regnum (operands[1])"
11360 [(set (match_dup 0) (zero_extend:DI
11361 (subreg:SI (mult:SI (match_dup 1)
11362 (match_dup 2)) 0)))]
11363 {
11364 operands[1] = gen_lowpart (Pmode, operands[1]);
11365 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11366 })
11367
11368 ;; This pattern can't accept a variable shift count, since shifts by
11369 ;; zero don't affect the flags. We assume that shifts by constant
11370 ;; zero are optimized away.
11371 (define_insn "*ashlsi3_cmp"
11372 [(set (reg 17)
11373 (compare
11374 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11375 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11376 (const_int 0)))
11377 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11378 (ashift:SI (match_dup 1) (match_dup 2)))]
11379 "ix86_match_ccmode (insn, CCGOCmode)
11380 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11381 {
11382 switch (get_attr_type (insn))
11383 {
11384 case TYPE_ALU:
11385 if (operands[2] != const1_rtx)
11386 abort ();
11387 return "add{l}\t{%0, %0|%0, %0}";
11388
11389 default:
11390 if (REG_P (operands[2]))
11391 return "sal{l}\t{%b2, %0|%0, %b2}";
11392 else if (GET_CODE (operands[2]) == CONST_INT
11393 && INTVAL (operands[2]) == 1
11394 && (TARGET_SHIFT1 || optimize_size))
11395 return "sal{l}\t%0";
11396 else
11397 return "sal{l}\t{%2, %0|%0, %2}";
11398 }
11399 }
11400 [(set (attr "type")
11401 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11402 (const_int 0))
11403 (match_operand 0 "register_operand" ""))
11404 (match_operand 2 "const1_operand" ""))
11405 (const_string "alu")
11406 ]
11407 (const_string "ishift")))
11408 (set_attr "mode" "SI")])
11409
11410 (define_insn "*ashlsi3_cmp_zext"
11411 [(set (reg 17)
11412 (compare
11413 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11414 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11415 (const_int 0)))
11416 (set (match_operand:DI 0 "register_operand" "=r")
11417 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11418 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11419 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11420 {
11421 switch (get_attr_type (insn))
11422 {
11423 case TYPE_ALU:
11424 if (operands[2] != const1_rtx)
11425 abort ();
11426 return "add{l}\t{%k0, %k0|%k0, %k0}";
11427
11428 default:
11429 if (REG_P (operands[2]))
11430 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11431 else if (GET_CODE (operands[2]) == CONST_INT
11432 && INTVAL (operands[2]) == 1
11433 && (TARGET_SHIFT1 || optimize_size))
11434 return "sal{l}\t%k0";
11435 else
11436 return "sal{l}\t{%2, %k0|%k0, %2}";
11437 }
11438 }
11439 [(set (attr "type")
11440 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11441 (const_int 0))
11442 (match_operand 2 "const1_operand" ""))
11443 (const_string "alu")
11444 ]
11445 (const_string "ishift")))
11446 (set_attr "mode" "SI")])
11447
11448 (define_expand "ashlhi3"
11449 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11450 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11451 (match_operand:QI 2 "nonmemory_operand" "")))
11452 (clobber (reg:CC 17))]
11453 "TARGET_HIMODE_MATH"
11454 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11455
11456 (define_insn "*ashlhi3_1_lea"
11457 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11458 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11459 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11460 (clobber (reg:CC 17))]
11461 "!TARGET_PARTIAL_REG_STALL
11462 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11463 {
11464 switch (get_attr_type (insn))
11465 {
11466 case TYPE_LEA:
11467 return "#";
11468 case TYPE_ALU:
11469 if (operands[2] != const1_rtx)
11470 abort ();
11471 return "add{w}\t{%0, %0|%0, %0}";
11472
11473 default:
11474 if (REG_P (operands[2]))
11475 return "sal{w}\t{%b2, %0|%0, %b2}";
11476 else if (GET_CODE (operands[2]) == CONST_INT
11477 && INTVAL (operands[2]) == 1
11478 && (TARGET_SHIFT1 || optimize_size))
11479 return "sal{w}\t%0";
11480 else
11481 return "sal{w}\t{%2, %0|%0, %2}";
11482 }
11483 }
11484 [(set (attr "type")
11485 (cond [(eq_attr "alternative" "1")
11486 (const_string "lea")
11487 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11488 (const_int 0))
11489 (match_operand 0 "register_operand" ""))
11490 (match_operand 2 "const1_operand" ""))
11491 (const_string "alu")
11492 ]
11493 (const_string "ishift")))
11494 (set_attr "mode" "HI,SI")])
11495
11496 (define_insn "*ashlhi3_1"
11497 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11498 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11499 (match_operand:QI 2 "nonmemory_operand" "cI")))
11500 (clobber (reg:CC 17))]
11501 "TARGET_PARTIAL_REG_STALL
11502 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11503 {
11504 switch (get_attr_type (insn))
11505 {
11506 case TYPE_ALU:
11507 if (operands[2] != const1_rtx)
11508 abort ();
11509 return "add{w}\t{%0, %0|%0, %0}";
11510
11511 default:
11512 if (REG_P (operands[2]))
11513 return "sal{w}\t{%b2, %0|%0, %b2}";
11514 else if (GET_CODE (operands[2]) == CONST_INT
11515 && INTVAL (operands[2]) == 1
11516 && (TARGET_SHIFT1 || optimize_size))
11517 return "sal{w}\t%0";
11518 else
11519 return "sal{w}\t{%2, %0|%0, %2}";
11520 }
11521 }
11522 [(set (attr "type")
11523 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11524 (const_int 0))
11525 (match_operand 0 "register_operand" ""))
11526 (match_operand 2 "const1_operand" ""))
11527 (const_string "alu")
11528 ]
11529 (const_string "ishift")))
11530 (set_attr "mode" "HI")])
11531
11532 ;; This pattern can't accept a variable shift count, since shifts by
11533 ;; zero don't affect the flags. We assume that shifts by constant
11534 ;; zero are optimized away.
11535 (define_insn "*ashlhi3_cmp"
11536 [(set (reg 17)
11537 (compare
11538 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11539 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11540 (const_int 0)))
11541 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11542 (ashift:HI (match_dup 1) (match_dup 2)))]
11543 "ix86_match_ccmode (insn, CCGOCmode)
11544 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11545 {
11546 switch (get_attr_type (insn))
11547 {
11548 case TYPE_ALU:
11549 if (operands[2] != const1_rtx)
11550 abort ();
11551 return "add{w}\t{%0, %0|%0, %0}";
11552
11553 default:
11554 if (REG_P (operands[2]))
11555 return "sal{w}\t{%b2, %0|%0, %b2}";
11556 else if (GET_CODE (operands[2]) == CONST_INT
11557 && INTVAL (operands[2]) == 1
11558 && (TARGET_SHIFT1 || optimize_size))
11559 return "sal{w}\t%0";
11560 else
11561 return "sal{w}\t{%2, %0|%0, %2}";
11562 }
11563 }
11564 [(set (attr "type")
11565 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11566 (const_int 0))
11567 (match_operand 0 "register_operand" ""))
11568 (match_operand 2 "const1_operand" ""))
11569 (const_string "alu")
11570 ]
11571 (const_string "ishift")))
11572 (set_attr "mode" "HI")])
11573
11574 (define_expand "ashlqi3"
11575 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11576 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11577 (match_operand:QI 2 "nonmemory_operand" "")))
11578 (clobber (reg:CC 17))]
11579 "TARGET_QIMODE_MATH"
11580 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11581
11582 ;; %%% Potential partial reg stall on alternative 2. What to do?
11583
11584 (define_insn "*ashlqi3_1_lea"
11585 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11586 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11587 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11588 (clobber (reg:CC 17))]
11589 "!TARGET_PARTIAL_REG_STALL
11590 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11591 {
11592 switch (get_attr_type (insn))
11593 {
11594 case TYPE_LEA:
11595 return "#";
11596 case TYPE_ALU:
11597 if (operands[2] != const1_rtx)
11598 abort ();
11599 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11600 return "add{l}\t{%k0, %k0|%k0, %k0}";
11601 else
11602 return "add{b}\t{%0, %0|%0, %0}";
11603
11604 default:
11605 if (REG_P (operands[2]))
11606 {
11607 if (get_attr_mode (insn) == MODE_SI)
11608 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11609 else
11610 return "sal{b}\t{%b2, %0|%0, %b2}";
11611 }
11612 else if (GET_CODE (operands[2]) == CONST_INT
11613 && INTVAL (operands[2]) == 1
11614 && (TARGET_SHIFT1 || optimize_size))
11615 {
11616 if (get_attr_mode (insn) == MODE_SI)
11617 return "sal{l}\t%0";
11618 else
11619 return "sal{b}\t%0";
11620 }
11621 else
11622 {
11623 if (get_attr_mode (insn) == MODE_SI)
11624 return "sal{l}\t{%2, %k0|%k0, %2}";
11625 else
11626 return "sal{b}\t{%2, %0|%0, %2}";
11627 }
11628 }
11629 }
11630 [(set (attr "type")
11631 (cond [(eq_attr "alternative" "2")
11632 (const_string "lea")
11633 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11634 (const_int 0))
11635 (match_operand 0 "register_operand" ""))
11636 (match_operand 2 "const1_operand" ""))
11637 (const_string "alu")
11638 ]
11639 (const_string "ishift")))
11640 (set_attr "mode" "QI,SI,SI")])
11641
11642 (define_insn "*ashlqi3_1"
11643 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11644 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11645 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11646 (clobber (reg:CC 17))]
11647 "TARGET_PARTIAL_REG_STALL
11648 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11649 {
11650 switch (get_attr_type (insn))
11651 {
11652 case TYPE_ALU:
11653 if (operands[2] != const1_rtx)
11654 abort ();
11655 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11656 return "add{l}\t{%k0, %k0|%k0, %k0}";
11657 else
11658 return "add{b}\t{%0, %0|%0, %0}";
11659
11660 default:
11661 if (REG_P (operands[2]))
11662 {
11663 if (get_attr_mode (insn) == MODE_SI)
11664 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11665 else
11666 return "sal{b}\t{%b2, %0|%0, %b2}";
11667 }
11668 else if (GET_CODE (operands[2]) == CONST_INT
11669 && INTVAL (operands[2]) == 1
11670 && (TARGET_SHIFT1 || optimize_size))
11671 {
11672 if (get_attr_mode (insn) == MODE_SI)
11673 return "sal{l}\t%0";
11674 else
11675 return "sal{b}\t%0";
11676 }
11677 else
11678 {
11679 if (get_attr_mode (insn) == MODE_SI)
11680 return "sal{l}\t{%2, %k0|%k0, %2}";
11681 else
11682 return "sal{b}\t{%2, %0|%0, %2}";
11683 }
11684 }
11685 }
11686 [(set (attr "type")
11687 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11688 (const_int 0))
11689 (match_operand 0 "register_operand" ""))
11690 (match_operand 2 "const1_operand" ""))
11691 (const_string "alu")
11692 ]
11693 (const_string "ishift")))
11694 (set_attr "mode" "QI,SI")])
11695
11696 ;; This pattern can't accept a variable shift count, since shifts by
11697 ;; zero don't affect the flags. We assume that shifts by constant
11698 ;; zero are optimized away.
11699 (define_insn "*ashlqi3_cmp"
11700 [(set (reg 17)
11701 (compare
11702 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11703 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11704 (const_int 0)))
11705 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11706 (ashift:QI (match_dup 1) (match_dup 2)))]
11707 "ix86_match_ccmode (insn, CCGOCmode)
11708 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11709 {
11710 switch (get_attr_type (insn))
11711 {
11712 case TYPE_ALU:
11713 if (operands[2] != const1_rtx)
11714 abort ();
11715 return "add{b}\t{%0, %0|%0, %0}";
11716
11717 default:
11718 if (REG_P (operands[2]))
11719 return "sal{b}\t{%b2, %0|%0, %b2}";
11720 else if (GET_CODE (operands[2]) == CONST_INT
11721 && INTVAL (operands[2]) == 1
11722 && (TARGET_SHIFT1 || optimize_size))
11723 return "sal{b}\t%0";
11724 else
11725 return "sal{b}\t{%2, %0|%0, %2}";
11726 }
11727 }
11728 [(set (attr "type")
11729 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11730 (const_int 0))
11731 (match_operand 0 "register_operand" ""))
11732 (match_operand 2 "const1_operand" ""))
11733 (const_string "alu")
11734 ]
11735 (const_string "ishift")))
11736 (set_attr "mode" "QI")])
11737
11738 ;; See comment above `ashldi3' about how this works.
11739
11740 (define_expand "ashrdi3"
11741 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11742 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11743 (match_operand:QI 2 "nonmemory_operand" "")))
11744 (clobber (reg:CC 17))])]
11745 ""
11746 {
11747 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11748 {
11749 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11750 DONE;
11751 }
11752 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11753 DONE;
11754 })
11755
11756 (define_insn "ashrdi3_63_rex64"
11757 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11758 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11759 (match_operand:DI 2 "const_int_operand" "i,i")))
11760 (clobber (reg:CC 17))]
11761 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11762 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11763 "@
11764 {cqto|cqo}
11765 sar{q}\t{%2, %0|%0, %2}"
11766 [(set_attr "type" "imovx,ishift")
11767 (set_attr "prefix_0f" "0,*")
11768 (set_attr "length_immediate" "0,*")
11769 (set_attr "modrm" "0,1")
11770 (set_attr "mode" "DI")])
11771
11772 (define_insn "*ashrdi3_1_one_bit_rex64"
11773 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11774 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11775 (match_operand:QI 2 "const_int_1_operand" "")))
11776 (clobber (reg:CC 17))]
11777 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11778 && (TARGET_SHIFT1 || optimize_size)"
11779 "sar{q}\t%0"
11780 [(set_attr "type" "ishift")
11781 (set (attr "length")
11782 (if_then_else (match_operand:DI 0 "register_operand" "")
11783 (const_string "2")
11784 (const_string "*")))])
11785
11786 (define_insn "*ashrdi3_1_rex64"
11787 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11788 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11789 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11790 (clobber (reg:CC 17))]
11791 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11792 "@
11793 sar{q}\t{%2, %0|%0, %2}
11794 sar{q}\t{%b2, %0|%0, %b2}"
11795 [(set_attr "type" "ishift")
11796 (set_attr "mode" "DI")])
11797
11798 ;; This pattern can't accept a variable shift count, since shifts by
11799 ;; zero don't affect the flags. We assume that shifts by constant
11800 ;; zero are optimized away.
11801 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11802 [(set (reg 17)
11803 (compare
11804 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11805 (match_operand:QI 2 "const_int_1_operand" ""))
11806 (const_int 0)))
11807 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11808 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11809 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11810 && (TARGET_SHIFT1 || optimize_size)
11811 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11812 "sar{q}\t%0"
11813 [(set_attr "type" "ishift")
11814 (set (attr "length")
11815 (if_then_else (match_operand:DI 0 "register_operand" "")
11816 (const_string "2")
11817 (const_string "*")))])
11818
11819 ;; This pattern can't accept a variable shift count, since shifts by
11820 ;; zero don't affect the flags. We assume that shifts by constant
11821 ;; zero are optimized away.
11822 (define_insn "*ashrdi3_cmp_rex64"
11823 [(set (reg 17)
11824 (compare
11825 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11826 (match_operand:QI 2 "const_int_operand" "n"))
11827 (const_int 0)))
11828 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11829 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11830 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11831 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11832 "sar{q}\t{%2, %0|%0, %2}"
11833 [(set_attr "type" "ishift")
11834 (set_attr "mode" "DI")])
11835
11836
11837 (define_insn "ashrdi3_1"
11838 [(set (match_operand:DI 0 "register_operand" "=r")
11839 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11840 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11841 (clobber (match_scratch:SI 3 "=&r"))
11842 (clobber (reg:CC 17))]
11843 "!TARGET_64BIT && TARGET_CMOVE"
11844 "#"
11845 [(set_attr "type" "multi")])
11846
11847 (define_insn "*ashrdi3_2"
11848 [(set (match_operand:DI 0 "register_operand" "=r")
11849 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11850 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11851 (clobber (reg:CC 17))]
11852 "!TARGET_64BIT"
11853 "#"
11854 [(set_attr "type" "multi")])
11855
11856 (define_split
11857 [(set (match_operand:DI 0 "register_operand" "")
11858 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11859 (match_operand:QI 2 "nonmemory_operand" "")))
11860 (clobber (match_scratch:SI 3 ""))
11861 (clobber (reg:CC 17))]
11862 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11863 [(const_int 0)]
11864 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11865
11866 (define_split
11867 [(set (match_operand:DI 0 "register_operand" "")
11868 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11869 (match_operand:QI 2 "nonmemory_operand" "")))
11870 (clobber (reg:CC 17))]
11871 "!TARGET_64BIT && reload_completed"
11872 [(const_int 0)]
11873 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11874
11875 (define_insn "x86_shrd_1"
11876 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11877 (ior:SI (ashiftrt:SI (match_dup 0)
11878 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11879 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11880 (minus:QI (const_int 32) (match_dup 2)))))
11881 (clobber (reg:CC 17))]
11882 ""
11883 "@
11884 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11885 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11886 [(set_attr "type" "ishift")
11887 (set_attr "prefix_0f" "1")
11888 (set_attr "pent_pair" "np")
11889 (set_attr "ppro_uops" "few")
11890 (set_attr "mode" "SI")])
11891
11892 (define_expand "x86_shift_adj_3"
11893 [(use (match_operand:SI 0 "register_operand" ""))
11894 (use (match_operand:SI 1 "register_operand" ""))
11895 (use (match_operand:QI 2 "register_operand" ""))]
11896 ""
11897 {
11898 rtx label = gen_label_rtx ();
11899 rtx tmp;
11900
11901 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11902
11903 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11904 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11905 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11906 gen_rtx_LABEL_REF (VOIDmode, label),
11907 pc_rtx);
11908 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11909 JUMP_LABEL (tmp) = label;
11910
11911 emit_move_insn (operands[0], operands[1]);
11912 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11913
11914 emit_label (label);
11915 LABEL_NUSES (label) = 1;
11916
11917 DONE;
11918 })
11919
11920 (define_insn "ashrsi3_31"
11921 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11922 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11923 (match_operand:SI 2 "const_int_operand" "i,i")))
11924 (clobber (reg:CC 17))]
11925 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11926 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11927 "@
11928 {cltd|cdq}
11929 sar{l}\t{%2, %0|%0, %2}"
11930 [(set_attr "type" "imovx,ishift")
11931 (set_attr "prefix_0f" "0,*")
11932 (set_attr "length_immediate" "0,*")
11933 (set_attr "modrm" "0,1")
11934 (set_attr "mode" "SI")])
11935
11936 (define_insn "*ashrsi3_31_zext"
11937 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11938 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11939 (match_operand:SI 2 "const_int_operand" "i,i"))))
11940 (clobber (reg:CC 17))]
11941 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11942 && INTVAL (operands[2]) == 31
11943 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11944 "@
11945 {cltd|cdq}
11946 sar{l}\t{%2, %k0|%k0, %2}"
11947 [(set_attr "type" "imovx,ishift")
11948 (set_attr "prefix_0f" "0,*")
11949 (set_attr "length_immediate" "0,*")
11950 (set_attr "modrm" "0,1")
11951 (set_attr "mode" "SI")])
11952
11953 (define_expand "ashrsi3"
11954 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11955 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11956 (match_operand:QI 2 "nonmemory_operand" "")))
11957 (clobber (reg:CC 17))]
11958 ""
11959 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11960
11961 (define_insn "*ashrsi3_1_one_bit"
11962 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11963 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11964 (match_operand:QI 2 "const_int_1_operand" "")))
11965 (clobber (reg:CC 17))]
11966 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11967 && (TARGET_SHIFT1 || optimize_size)"
11968 "sar{l}\t%0"
11969 [(set_attr "type" "ishift")
11970 (set (attr "length")
11971 (if_then_else (match_operand:SI 0 "register_operand" "")
11972 (const_string "2")
11973 (const_string "*")))])
11974
11975 (define_insn "*ashrsi3_1_one_bit_zext"
11976 [(set (match_operand:DI 0 "register_operand" "=r")
11977 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11978 (match_operand:QI 2 "const_int_1_operand" ""))))
11979 (clobber (reg:CC 17))]
11980 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11981 && (TARGET_SHIFT1 || optimize_size)"
11982 "sar{l}\t%k0"
11983 [(set_attr "type" "ishift")
11984 (set_attr "length" "2")])
11985
11986 (define_insn "*ashrsi3_1"
11987 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11988 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11989 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11990 (clobber (reg:CC 17))]
11991 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11992 "@
11993 sar{l}\t{%2, %0|%0, %2}
11994 sar{l}\t{%b2, %0|%0, %b2}"
11995 [(set_attr "type" "ishift")
11996 (set_attr "mode" "SI")])
11997
11998 (define_insn "*ashrsi3_1_zext"
11999 [(set (match_operand:DI 0 "register_operand" "=r,r")
12000 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12001 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12002 (clobber (reg:CC 17))]
12003 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12004 "@
12005 sar{l}\t{%2, %k0|%k0, %2}
12006 sar{l}\t{%b2, %k0|%k0, %b2}"
12007 [(set_attr "type" "ishift")
12008 (set_attr "mode" "SI")])
12009
12010 ;; This pattern can't accept a variable shift count, since shifts by
12011 ;; zero don't affect the flags. We assume that shifts by constant
12012 ;; zero are optimized away.
12013 (define_insn "*ashrsi3_one_bit_cmp"
12014 [(set (reg 17)
12015 (compare
12016 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12017 (match_operand:QI 2 "const_int_1_operand" ""))
12018 (const_int 0)))
12019 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12020 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12021 "ix86_match_ccmode (insn, CCGOCmode)
12022 && (TARGET_SHIFT1 || optimize_size)
12023 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12024 "sar{l}\t%0"
12025 [(set_attr "type" "ishift")
12026 (set (attr "length")
12027 (if_then_else (match_operand:SI 0 "register_operand" "")
12028 (const_string "2")
12029 (const_string "*")))])
12030
12031 (define_insn "*ashrsi3_one_bit_cmp_zext"
12032 [(set (reg 17)
12033 (compare
12034 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12035 (match_operand:QI 2 "const_int_1_operand" ""))
12036 (const_int 0)))
12037 (set (match_operand:DI 0 "register_operand" "=r")
12038 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12039 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12040 && (TARGET_SHIFT1 || optimize_size)
12041 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12042 "sar{l}\t%k0"
12043 [(set_attr "type" "ishift")
12044 (set_attr "length" "2")])
12045
12046 ;; This pattern can't accept a variable shift count, since shifts by
12047 ;; zero don't affect the flags. We assume that shifts by constant
12048 ;; zero are optimized away.
12049 (define_insn "*ashrsi3_cmp"
12050 [(set (reg 17)
12051 (compare
12052 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12053 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12054 (const_int 0)))
12055 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12056 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12057 "ix86_match_ccmode (insn, CCGOCmode)
12058 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12059 "sar{l}\t{%2, %0|%0, %2}"
12060 [(set_attr "type" "ishift")
12061 (set_attr "mode" "SI")])
12062
12063 (define_insn "*ashrsi3_cmp_zext"
12064 [(set (reg 17)
12065 (compare
12066 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12067 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12068 (const_int 0)))
12069 (set (match_operand:DI 0 "register_operand" "=r")
12070 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12071 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12072 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12073 "sar{l}\t{%2, %k0|%k0, %2}"
12074 [(set_attr "type" "ishift")
12075 (set_attr "mode" "SI")])
12076
12077 (define_expand "ashrhi3"
12078 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12079 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12080 (match_operand:QI 2 "nonmemory_operand" "")))
12081 (clobber (reg:CC 17))]
12082 "TARGET_HIMODE_MATH"
12083 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12084
12085 (define_insn "*ashrhi3_1_one_bit"
12086 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12087 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12088 (match_operand:QI 2 "const_int_1_operand" "")))
12089 (clobber (reg:CC 17))]
12090 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12091 && (TARGET_SHIFT1 || optimize_size)"
12092 "sar{w}\t%0"
12093 [(set_attr "type" "ishift")
12094 (set (attr "length")
12095 (if_then_else (match_operand 0 "register_operand" "")
12096 (const_string "2")
12097 (const_string "*")))])
12098
12099 (define_insn "*ashrhi3_1"
12100 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12101 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12102 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12103 (clobber (reg:CC 17))]
12104 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12105 "@
12106 sar{w}\t{%2, %0|%0, %2}
12107 sar{w}\t{%b2, %0|%0, %b2}"
12108 [(set_attr "type" "ishift")
12109 (set_attr "mode" "HI")])
12110
12111 ;; This pattern can't accept a variable shift count, since shifts by
12112 ;; zero don't affect the flags. We assume that shifts by constant
12113 ;; zero are optimized away.
12114 (define_insn "*ashrhi3_one_bit_cmp"
12115 [(set (reg 17)
12116 (compare
12117 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12118 (match_operand:QI 2 "const_int_1_operand" ""))
12119 (const_int 0)))
12120 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12121 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12122 "ix86_match_ccmode (insn, CCGOCmode)
12123 && (TARGET_SHIFT1 || optimize_size)
12124 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12125 "sar{w}\t%0"
12126 [(set_attr "type" "ishift")
12127 (set (attr "length")
12128 (if_then_else (match_operand 0 "register_operand" "")
12129 (const_string "2")
12130 (const_string "*")))])
12131
12132 ;; This pattern can't accept a variable shift count, since shifts by
12133 ;; zero don't affect the flags. We assume that shifts by constant
12134 ;; zero are optimized away.
12135 (define_insn "*ashrhi3_cmp"
12136 [(set (reg 17)
12137 (compare
12138 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12139 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12140 (const_int 0)))
12141 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12142 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12143 "ix86_match_ccmode (insn, CCGOCmode)
12144 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12145 "sar{w}\t{%2, %0|%0, %2}"
12146 [(set_attr "type" "ishift")
12147 (set_attr "mode" "HI")])
12148
12149 (define_expand "ashrqi3"
12150 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12151 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12152 (match_operand:QI 2 "nonmemory_operand" "")))
12153 (clobber (reg:CC 17))]
12154 "TARGET_QIMODE_MATH"
12155 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12156
12157 (define_insn "*ashrqi3_1_one_bit"
12158 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12159 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12160 (match_operand:QI 2 "const_int_1_operand" "")))
12161 (clobber (reg:CC 17))]
12162 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12163 && (TARGET_SHIFT1 || optimize_size)"
12164 "sar{b}\t%0"
12165 [(set_attr "type" "ishift")
12166 (set (attr "length")
12167 (if_then_else (match_operand 0 "register_operand" "")
12168 (const_string "2")
12169 (const_string "*")))])
12170
12171 (define_insn "*ashrqi3_1_one_bit_slp"
12172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12173 (ashiftrt:QI (match_dup 0)
12174 (match_operand:QI 1 "const_int_1_operand" "")))
12175 (clobber (reg:CC 17))]
12176 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12177 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12178 && (TARGET_SHIFT1 || optimize_size)"
12179 "sar{b}\t%0"
12180 [(set_attr "type" "ishift1")
12181 (set (attr "length")
12182 (if_then_else (match_operand 0 "register_operand" "")
12183 (const_string "2")
12184 (const_string "*")))])
12185
12186 (define_insn "*ashrqi3_1"
12187 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12188 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190 (clobber (reg:CC 17))]
12191 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12192 "@
12193 sar{b}\t{%2, %0|%0, %2}
12194 sar{b}\t{%b2, %0|%0, %b2}"
12195 [(set_attr "type" "ishift")
12196 (set_attr "mode" "QI")])
12197
12198 (define_insn "*ashrqi3_1_slp"
12199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12200 (ashiftrt:QI (match_dup 0)
12201 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12202 (clobber (reg:CC 17))]
12203 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12205 "@
12206 sar{b}\t{%1, %0|%0, %1}
12207 sar{b}\t{%b1, %0|%0, %b1}"
12208 [(set_attr "type" "ishift1")
12209 (set_attr "mode" "QI")])
12210
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags. We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*ashrqi3_one_bit_cmp"
12215 [(set (reg 17)
12216 (compare
12217 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const_int_1_operand" "I"))
12219 (const_int 0)))
12220 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12221 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12222 "ix86_match_ccmode (insn, CCGOCmode)
12223 && (TARGET_SHIFT1 || optimize_size)
12224 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12225 "sar{b}\t%0"
12226 [(set_attr "type" "ishift")
12227 (set (attr "length")
12228 (if_then_else (match_operand 0 "register_operand" "")
12229 (const_string "2")
12230 (const_string "*")))])
12231
12232 ;; This pattern can't accept a variable shift count, since shifts by
12233 ;; zero don't affect the flags. We assume that shifts by constant
12234 ;; zero are optimized away.
12235 (define_insn "*ashrqi3_cmp"
12236 [(set (reg 17)
12237 (compare
12238 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12239 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12240 (const_int 0)))
12241 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12242 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12245 "sar{b}\t{%2, %0|%0, %2}"
12246 [(set_attr "type" "ishift")
12247 (set_attr "mode" "QI")])
12248 \f
12249 ;; Logical shift instructions
12250
12251 ;; See comment above `ashldi3' about how this works.
12252
12253 (define_expand "lshrdi3"
12254 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12255 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12256 (match_operand:QI 2 "nonmemory_operand" "")))
12257 (clobber (reg:CC 17))])]
12258 ""
12259 {
12260 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12261 {
12262 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12263 DONE;
12264 }
12265 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12266 DONE;
12267 })
12268
12269 (define_insn "*lshrdi3_1_one_bit_rex64"
12270 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12271 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12272 (match_operand:QI 2 "const_int_1_operand" "")))
12273 (clobber (reg:CC 17))]
12274 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12275 && (TARGET_SHIFT1 || optimize_size)"
12276 "shr{q}\t%0"
12277 [(set_attr "type" "ishift")
12278 (set (attr "length")
12279 (if_then_else (match_operand:DI 0 "register_operand" "")
12280 (const_string "2")
12281 (const_string "*")))])
12282
12283 (define_insn "*lshrdi3_1_rex64"
12284 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12285 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12286 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12287 (clobber (reg:CC 17))]
12288 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289 "@
12290 shr{q}\t{%2, %0|%0, %2}
12291 shr{q}\t{%b2, %0|%0, %b2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "DI")])
12294
12295 ;; This pattern can't accept a variable shift count, since shifts by
12296 ;; zero don't affect the flags. We assume that shifts by constant
12297 ;; zero are optimized away.
12298 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12299 [(set (reg 17)
12300 (compare
12301 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const_int_1_operand" ""))
12303 (const_int 0)))
12304 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12305 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12306 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12307 && (TARGET_SHIFT1 || optimize_size)
12308 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12309 "shr{q}\t%0"
12310 [(set_attr "type" "ishift")
12311 (set (attr "length")
12312 (if_then_else (match_operand:DI 0 "register_operand" "")
12313 (const_string "2")
12314 (const_string "*")))])
12315
12316 ;; This pattern can't accept a variable shift count, since shifts by
12317 ;; zero don't affect the flags. We assume that shifts by constant
12318 ;; zero are optimized away.
12319 (define_insn "*lshrdi3_cmp_rex64"
12320 [(set (reg 17)
12321 (compare
12322 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12323 (match_operand:QI 2 "const_int_operand" "e"))
12324 (const_int 0)))
12325 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12326 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12327 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12328 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12329 "shr{q}\t{%2, %0|%0, %2}"
12330 [(set_attr "type" "ishift")
12331 (set_attr "mode" "DI")])
12332
12333 (define_insn "lshrdi3_1"
12334 [(set (match_operand:DI 0 "register_operand" "=r")
12335 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12336 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12337 (clobber (match_scratch:SI 3 "=&r"))
12338 (clobber (reg:CC 17))]
12339 "!TARGET_64BIT && TARGET_CMOVE"
12340 "#"
12341 [(set_attr "type" "multi")])
12342
12343 (define_insn "*lshrdi3_2"
12344 [(set (match_operand:DI 0 "register_operand" "=r")
12345 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12346 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12347 (clobber (reg:CC 17))]
12348 "!TARGET_64BIT"
12349 "#"
12350 [(set_attr "type" "multi")])
12351
12352 (define_split
12353 [(set (match_operand:DI 0 "register_operand" "")
12354 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12355 (match_operand:QI 2 "nonmemory_operand" "")))
12356 (clobber (match_scratch:SI 3 ""))
12357 (clobber (reg:CC 17))]
12358 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12359 [(const_int 0)]
12360 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12361
12362 (define_split
12363 [(set (match_operand:DI 0 "register_operand" "")
12364 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12365 (match_operand:QI 2 "nonmemory_operand" "")))
12366 (clobber (reg:CC 17))]
12367 "!TARGET_64BIT && reload_completed"
12368 [(const_int 0)]
12369 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12370
12371 (define_expand "lshrsi3"
12372 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12373 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12374 (match_operand:QI 2 "nonmemory_operand" "")))
12375 (clobber (reg:CC 17))]
12376 ""
12377 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12378
12379 (define_insn "*lshrsi3_1_one_bit"
12380 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12381 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12382 (match_operand:QI 2 "const_int_1_operand" "")))
12383 (clobber (reg:CC 17))]
12384 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12385 && (TARGET_SHIFT1 || optimize_size)"
12386 "shr{l}\t%0"
12387 [(set_attr "type" "ishift")
12388 (set (attr "length")
12389 (if_then_else (match_operand:SI 0 "register_operand" "")
12390 (const_string "2")
12391 (const_string "*")))])
12392
12393 (define_insn "*lshrsi3_1_one_bit_zext"
12394 [(set (match_operand:DI 0 "register_operand" "=r")
12395 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12396 (match_operand:QI 2 "const_int_1_operand" "")))
12397 (clobber (reg:CC 17))]
12398 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12399 && (TARGET_SHIFT1 || optimize_size)"
12400 "shr{l}\t%k0"
12401 [(set_attr "type" "ishift")
12402 (set_attr "length" "2")])
12403
12404 (define_insn "*lshrsi3_1"
12405 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12406 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12407 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12408 (clobber (reg:CC 17))]
12409 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12410 "@
12411 shr{l}\t{%2, %0|%0, %2}
12412 shr{l}\t{%b2, %0|%0, %b2}"
12413 [(set_attr "type" "ishift")
12414 (set_attr "mode" "SI")])
12415
12416 (define_insn "*lshrsi3_1_zext"
12417 [(set (match_operand:DI 0 "register_operand" "=r,r")
12418 (zero_extend:DI
12419 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12420 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12421 (clobber (reg:CC 17))]
12422 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12423 "@
12424 shr{l}\t{%2, %k0|%k0, %2}
12425 shr{l}\t{%b2, %k0|%k0, %b2}"
12426 [(set_attr "type" "ishift")
12427 (set_attr "mode" "SI")])
12428
12429 ;; This pattern can't accept a variable shift count, since shifts by
12430 ;; zero don't affect the flags. We assume that shifts by constant
12431 ;; zero are optimized away.
12432 (define_insn "*lshrsi3_one_bit_cmp"
12433 [(set (reg 17)
12434 (compare
12435 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12436 (match_operand:QI 2 "const_int_1_operand" ""))
12437 (const_int 0)))
12438 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12439 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12440 "ix86_match_ccmode (insn, CCGOCmode)
12441 && (TARGET_SHIFT1 || optimize_size)
12442 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12443 "shr{l}\t%0"
12444 [(set_attr "type" "ishift")
12445 (set (attr "length")
12446 (if_then_else (match_operand:SI 0 "register_operand" "")
12447 (const_string "2")
12448 (const_string "*")))])
12449
12450 (define_insn "*lshrsi3_cmp_one_bit_zext"
12451 [(set (reg 17)
12452 (compare
12453 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12454 (match_operand:QI 2 "const_int_1_operand" ""))
12455 (const_int 0)))
12456 (set (match_operand:DI 0 "register_operand" "=r")
12457 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12458 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12459 && (TARGET_SHIFT1 || optimize_size)
12460 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12461 "shr{l}\t%k0"
12462 [(set_attr "type" "ishift")
12463 (set_attr "length" "2")])
12464
12465 ;; This pattern can't accept a variable shift count, since shifts by
12466 ;; zero don't affect the flags. We assume that shifts by constant
12467 ;; zero are optimized away.
12468 (define_insn "*lshrsi3_cmp"
12469 [(set (reg 17)
12470 (compare
12471 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12472 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12473 (const_int 0)))
12474 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12475 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12476 "ix86_match_ccmode (insn, CCGOCmode)
12477 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12478 "shr{l}\t{%2, %0|%0, %2}"
12479 [(set_attr "type" "ishift")
12480 (set_attr "mode" "SI")])
12481
12482 (define_insn "*lshrsi3_cmp_zext"
12483 [(set (reg 17)
12484 (compare
12485 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12486 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12487 (const_int 0)))
12488 (set (match_operand:DI 0 "register_operand" "=r")
12489 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12490 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12491 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12492 "shr{l}\t{%2, %k0|%k0, %2}"
12493 [(set_attr "type" "ishift")
12494 (set_attr "mode" "SI")])
12495
12496 (define_expand "lshrhi3"
12497 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12498 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12499 (match_operand:QI 2 "nonmemory_operand" "")))
12500 (clobber (reg:CC 17))]
12501 "TARGET_HIMODE_MATH"
12502 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12503
12504 (define_insn "*lshrhi3_1_one_bit"
12505 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12506 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12507 (match_operand:QI 2 "const_int_1_operand" "")))
12508 (clobber (reg:CC 17))]
12509 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12510 && (TARGET_SHIFT1 || optimize_size)"
12511 "shr{w}\t%0"
12512 [(set_attr "type" "ishift")
12513 (set (attr "length")
12514 (if_then_else (match_operand 0 "register_operand" "")
12515 (const_string "2")
12516 (const_string "*")))])
12517
12518 (define_insn "*lshrhi3_1"
12519 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12520 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12521 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12522 (clobber (reg:CC 17))]
12523 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12524 "@
12525 shr{w}\t{%2, %0|%0, %2}
12526 shr{w}\t{%b2, %0|%0, %b2}"
12527 [(set_attr "type" "ishift")
12528 (set_attr "mode" "HI")])
12529
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags. We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrhi3_one_bit_cmp"
12534 [(set (reg 17)
12535 (compare
12536 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12537 (match_operand:QI 2 "const_int_1_operand" ""))
12538 (const_int 0)))
12539 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12540 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12541 "ix86_match_ccmode (insn, CCGOCmode)
12542 && (TARGET_SHIFT1 || optimize_size)
12543 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12544 "shr{w}\t%0"
12545 [(set_attr "type" "ishift")
12546 (set (attr "length")
12547 (if_then_else (match_operand:SI 0 "register_operand" "")
12548 (const_string "2")
12549 (const_string "*")))])
12550
12551 ;; This pattern can't accept a variable shift count, since shifts by
12552 ;; zero don't affect the flags. We assume that shifts by constant
12553 ;; zero are optimized away.
12554 (define_insn "*lshrhi3_cmp"
12555 [(set (reg 17)
12556 (compare
12557 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12558 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12559 (const_int 0)))
12560 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12561 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12562 "ix86_match_ccmode (insn, CCGOCmode)
12563 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12564 "shr{w}\t{%2, %0|%0, %2}"
12565 [(set_attr "type" "ishift")
12566 (set_attr "mode" "HI")])
12567
12568 (define_expand "lshrqi3"
12569 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12570 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12571 (match_operand:QI 2 "nonmemory_operand" "")))
12572 (clobber (reg:CC 17))]
12573 "TARGET_QIMODE_MATH"
12574 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12575
12576 (define_insn "*lshrqi3_1_one_bit"
12577 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12578 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579 (match_operand:QI 2 "const_int_1_operand" "")))
12580 (clobber (reg:CC 17))]
12581 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12582 && (TARGET_SHIFT1 || optimize_size)"
12583 "shr{b}\t%0"
12584 [(set_attr "type" "ishift")
12585 (set (attr "length")
12586 (if_then_else (match_operand 0 "register_operand" "")
12587 (const_string "2")
12588 (const_string "*")))])
12589
12590 (define_insn "*lshrqi3_1_one_bit_slp"
12591 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12592 (lshiftrt:QI (match_dup 0)
12593 (match_operand:QI 1 "const_int_1_operand" "")))
12594 (clobber (reg:CC 17))]
12595 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12596 && (TARGET_SHIFT1 || optimize_size)"
12597 "shr{b}\t%0"
12598 [(set_attr "type" "ishift1")
12599 (set (attr "length")
12600 (if_then_else (match_operand 0 "register_operand" "")
12601 (const_string "2")
12602 (const_string "*")))])
12603
12604 (define_insn "*lshrqi3_1"
12605 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12606 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12607 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12608 (clobber (reg:CC 17))]
12609 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12610 "@
12611 shr{b}\t{%2, %0|%0, %2}
12612 shr{b}\t{%b2, %0|%0, %b2}"
12613 [(set_attr "type" "ishift")
12614 (set_attr "mode" "QI")])
12615
12616 (define_insn "*lshrqi3_1_slp"
12617 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12618 (lshiftrt:QI (match_dup 0)
12619 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12620 (clobber (reg:CC 17))]
12621 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12622 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12623 "@
12624 shr{b}\t{%1, %0|%0, %1}
12625 shr{b}\t{%b1, %0|%0, %b1}"
12626 [(set_attr "type" "ishift1")
12627 (set_attr "mode" "QI")])
12628
12629 ;; This pattern can't accept a variable shift count, since shifts by
12630 ;; zero don't affect the flags. We assume that shifts by constant
12631 ;; zero are optimized away.
12632 (define_insn "*lshrqi2_one_bit_cmp"
12633 [(set (reg 17)
12634 (compare
12635 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12636 (match_operand:QI 2 "const_int_1_operand" ""))
12637 (const_int 0)))
12638 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12639 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12640 "ix86_match_ccmode (insn, CCGOCmode)
12641 && (TARGET_SHIFT1 || optimize_size)
12642 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12643 "shr{b}\t%0"
12644 [(set_attr "type" "ishift")
12645 (set (attr "length")
12646 (if_then_else (match_operand:SI 0 "register_operand" "")
12647 (const_string "2")
12648 (const_string "*")))])
12649
12650 ;; This pattern can't accept a variable shift count, since shifts by
12651 ;; zero don't affect the flags. We assume that shifts by constant
12652 ;; zero are optimized away.
12653 (define_insn "*lshrqi2_cmp"
12654 [(set (reg 17)
12655 (compare
12656 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12657 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12658 (const_int 0)))
12659 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12660 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12661 "ix86_match_ccmode (insn, CCGOCmode)
12662 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12663 "shr{b}\t{%2, %0|%0, %2}"
12664 [(set_attr "type" "ishift")
12665 (set_attr "mode" "QI")])
12666 \f
12667 ;; Rotate instructions
12668
12669 (define_expand "rotldi3"
12670 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12671 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12672 (match_operand:QI 2 "nonmemory_operand" "")))
12673 (clobber (reg:CC 17))]
12674 "TARGET_64BIT"
12675 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12676
12677 (define_insn "*rotlsi3_1_one_bit_rex64"
12678 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12679 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12680 (match_operand:QI 2 "const_int_1_operand" "")))
12681 (clobber (reg:CC 17))]
12682 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12683 && (TARGET_SHIFT1 || optimize_size)"
12684 "rol{q}\t%0"
12685 [(set_attr "type" "rotate")
12686 (set (attr "length")
12687 (if_then_else (match_operand:DI 0 "register_operand" "")
12688 (const_string "2")
12689 (const_string "*")))])
12690
12691 (define_insn "*rotldi3_1_rex64"
12692 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12693 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12694 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12695 (clobber (reg:CC 17))]
12696 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12697 "@
12698 rol{q}\t{%2, %0|%0, %2}
12699 rol{q}\t{%b2, %0|%0, %b2}"
12700 [(set_attr "type" "rotate")
12701 (set_attr "mode" "DI")])
12702
12703 (define_expand "rotlsi3"
12704 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12705 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12706 (match_operand:QI 2 "nonmemory_operand" "")))
12707 (clobber (reg:CC 17))]
12708 ""
12709 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12710
12711 (define_insn "*rotlsi3_1_one_bit"
12712 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12713 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12714 (match_operand:QI 2 "const_int_1_operand" "")))
12715 (clobber (reg:CC 17))]
12716 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12717 && (TARGET_SHIFT1 || optimize_size)"
12718 "rol{l}\t%0"
12719 [(set_attr "type" "rotate")
12720 (set (attr "length")
12721 (if_then_else (match_operand:SI 0 "register_operand" "")
12722 (const_string "2")
12723 (const_string "*")))])
12724
12725 (define_insn "*rotlsi3_1_one_bit_zext"
12726 [(set (match_operand:DI 0 "register_operand" "=r")
12727 (zero_extend:DI
12728 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12729 (match_operand:QI 2 "const_int_1_operand" ""))))
12730 (clobber (reg:CC 17))]
12731 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12732 && (TARGET_SHIFT1 || optimize_size)"
12733 "rol{l}\t%k0"
12734 [(set_attr "type" "rotate")
12735 (set_attr "length" "2")])
12736
12737 (define_insn "*rotlsi3_1"
12738 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12739 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12740 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12741 (clobber (reg:CC 17))]
12742 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12743 "@
12744 rol{l}\t{%2, %0|%0, %2}
12745 rol{l}\t{%b2, %0|%0, %b2}"
12746 [(set_attr "type" "rotate")
12747 (set_attr "mode" "SI")])
12748
12749 (define_insn "*rotlsi3_1_zext"
12750 [(set (match_operand:DI 0 "register_operand" "=r,r")
12751 (zero_extend:DI
12752 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12753 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12754 (clobber (reg:CC 17))]
12755 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12756 "@
12757 rol{l}\t{%2, %k0|%k0, %2}
12758 rol{l}\t{%b2, %k0|%k0, %b2}"
12759 [(set_attr "type" "rotate")
12760 (set_attr "mode" "SI")])
12761
12762 (define_expand "rotlhi3"
12763 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12764 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12765 (match_operand:QI 2 "nonmemory_operand" "")))
12766 (clobber (reg:CC 17))]
12767 "TARGET_HIMODE_MATH"
12768 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12769
12770 (define_insn "*rotlhi3_1_one_bit"
12771 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12772 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12773 (match_operand:QI 2 "const_int_1_operand" "")))
12774 (clobber (reg:CC 17))]
12775 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12776 && (TARGET_SHIFT1 || optimize_size)"
12777 "rol{w}\t%0"
12778 [(set_attr "type" "rotate")
12779 (set (attr "length")
12780 (if_then_else (match_operand 0 "register_operand" "")
12781 (const_string "2")
12782 (const_string "*")))])
12783
12784 (define_insn "*rotlhi3_1"
12785 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12786 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12787 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12788 (clobber (reg:CC 17))]
12789 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12790 "@
12791 rol{w}\t{%2, %0|%0, %2}
12792 rol{w}\t{%b2, %0|%0, %b2}"
12793 [(set_attr "type" "rotate")
12794 (set_attr "mode" "HI")])
12795
12796 (define_expand "rotlqi3"
12797 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12798 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12799 (match_operand:QI 2 "nonmemory_operand" "")))
12800 (clobber (reg:CC 17))]
12801 "TARGET_QIMODE_MATH"
12802 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12803
12804 (define_insn "*rotlqi3_1_one_bit_slp"
12805 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12806 (rotate:QI (match_dup 0)
12807 (match_operand:QI 1 "const_int_1_operand" "")))
12808 (clobber (reg:CC 17))]
12809 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12810 && (TARGET_SHIFT1 || optimize_size)"
12811 "rol{b}\t%0"
12812 [(set_attr "type" "rotate1")
12813 (set (attr "length")
12814 (if_then_else (match_operand 0 "register_operand" "")
12815 (const_string "2")
12816 (const_string "*")))])
12817
12818 (define_insn "*rotlqi3_1_one_bit"
12819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12820 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12821 (match_operand:QI 2 "const_int_1_operand" "")))
12822 (clobber (reg:CC 17))]
12823 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12824 && (TARGET_SHIFT1 || optimize_size)"
12825 "rol{b}\t%0"
12826 [(set_attr "type" "rotate")
12827 (set (attr "length")
12828 (if_then_else (match_operand 0 "register_operand" "")
12829 (const_string "2")
12830 (const_string "*")))])
12831
12832 (define_insn "*rotlqi3_1_slp"
12833 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12834 (rotate:QI (match_dup 0)
12835 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12836 (clobber (reg:CC 17))]
12837 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12838 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12839 "@
12840 rol{b}\t{%1, %0|%0, %1}
12841 rol{b}\t{%b1, %0|%0, %b1}"
12842 [(set_attr "type" "rotate1")
12843 (set_attr "mode" "QI")])
12844
12845 (define_insn "*rotlqi3_1"
12846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12847 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12848 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12849 (clobber (reg:CC 17))]
12850 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12851 "@
12852 rol{b}\t{%2, %0|%0, %2}
12853 rol{b}\t{%b2, %0|%0, %b2}"
12854 [(set_attr "type" "rotate")
12855 (set_attr "mode" "QI")])
12856
12857 (define_expand "rotrdi3"
12858 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12859 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12860 (match_operand:QI 2 "nonmemory_operand" "")))
12861 (clobber (reg:CC 17))]
12862 "TARGET_64BIT"
12863 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12864
12865 (define_insn "*rotrdi3_1_one_bit_rex64"
12866 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12867 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12868 (match_operand:QI 2 "const_int_1_operand" "")))
12869 (clobber (reg:CC 17))]
12870 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12871 && (TARGET_SHIFT1 || optimize_size)"
12872 "ror{q}\t%0"
12873 [(set_attr "type" "rotate")
12874 (set (attr "length")
12875 (if_then_else (match_operand:DI 0 "register_operand" "")
12876 (const_string "2")
12877 (const_string "*")))])
12878
12879 (define_insn "*rotrdi3_1_rex64"
12880 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12881 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12882 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12883 (clobber (reg:CC 17))]
12884 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12885 "@
12886 ror{q}\t{%2, %0|%0, %2}
12887 ror{q}\t{%b2, %0|%0, %b2}"
12888 [(set_attr "type" "rotate")
12889 (set_attr "mode" "DI")])
12890
12891 (define_expand "rotrsi3"
12892 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12893 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12894 (match_operand:QI 2 "nonmemory_operand" "")))
12895 (clobber (reg:CC 17))]
12896 ""
12897 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12898
12899 (define_insn "*rotrsi3_1_one_bit"
12900 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12901 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12902 (match_operand:QI 2 "const_int_1_operand" "")))
12903 (clobber (reg:CC 17))]
12904 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12905 && (TARGET_SHIFT1 || optimize_size)"
12906 "ror{l}\t%0"
12907 [(set_attr "type" "rotate")
12908 (set (attr "length")
12909 (if_then_else (match_operand:SI 0 "register_operand" "")
12910 (const_string "2")
12911 (const_string "*")))])
12912
12913 (define_insn "*rotrsi3_1_one_bit_zext"
12914 [(set (match_operand:DI 0 "register_operand" "=r")
12915 (zero_extend:DI
12916 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12917 (match_operand:QI 2 "const_int_1_operand" ""))))
12918 (clobber (reg:CC 17))]
12919 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12920 && (TARGET_SHIFT1 || optimize_size)"
12921 "ror{l}\t%k0"
12922 [(set_attr "type" "rotate")
12923 (set (attr "length")
12924 (if_then_else (match_operand:SI 0 "register_operand" "")
12925 (const_string "2")
12926 (const_string "*")))])
12927
12928 (define_insn "*rotrsi3_1"
12929 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12930 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12931 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12932 (clobber (reg:CC 17))]
12933 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12934 "@
12935 ror{l}\t{%2, %0|%0, %2}
12936 ror{l}\t{%b2, %0|%0, %b2}"
12937 [(set_attr "type" "rotate")
12938 (set_attr "mode" "SI")])
12939
12940 (define_insn "*rotrsi3_1_zext"
12941 [(set (match_operand:DI 0 "register_operand" "=r,r")
12942 (zero_extend:DI
12943 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12944 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12945 (clobber (reg:CC 17))]
12946 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12947 "@
12948 ror{l}\t{%2, %k0|%k0, %2}
12949 ror{l}\t{%b2, %k0|%k0, %b2}"
12950 [(set_attr "type" "rotate")
12951 (set_attr "mode" "SI")])
12952
12953 (define_expand "rotrhi3"
12954 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12955 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12956 (match_operand:QI 2 "nonmemory_operand" "")))
12957 (clobber (reg:CC 17))]
12958 "TARGET_HIMODE_MATH"
12959 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12960
12961 (define_insn "*rotrhi3_one_bit"
12962 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12963 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12964 (match_operand:QI 2 "const_int_1_operand" "")))
12965 (clobber (reg:CC 17))]
12966 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12967 && (TARGET_SHIFT1 || optimize_size)"
12968 "ror{w}\t%0"
12969 [(set_attr "type" "rotate")
12970 (set (attr "length")
12971 (if_then_else (match_operand 0 "register_operand" "")
12972 (const_string "2")
12973 (const_string "*")))])
12974
12975 (define_insn "*rotrhi3"
12976 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12977 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12978 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12979 (clobber (reg:CC 17))]
12980 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12981 "@
12982 ror{w}\t{%2, %0|%0, %2}
12983 ror{w}\t{%b2, %0|%0, %b2}"
12984 [(set_attr "type" "rotate")
12985 (set_attr "mode" "HI")])
12986
12987 (define_expand "rotrqi3"
12988 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12989 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12990 (match_operand:QI 2 "nonmemory_operand" "")))
12991 (clobber (reg:CC 17))]
12992 "TARGET_QIMODE_MATH"
12993 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12994
12995 (define_insn "*rotrqi3_1_one_bit"
12996 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12997 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12998 (match_operand:QI 2 "const_int_1_operand" "")))
12999 (clobber (reg:CC 17))]
13000 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13001 && (TARGET_SHIFT1 || optimize_size)"
13002 "ror{b}\t%0"
13003 [(set_attr "type" "rotate")
13004 (set (attr "length")
13005 (if_then_else (match_operand 0 "register_operand" "")
13006 (const_string "2")
13007 (const_string "*")))])
13008
13009 (define_insn "*rotrqi3_1_one_bit_slp"
13010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011 (rotatert:QI (match_dup 0)
13012 (match_operand:QI 1 "const_int_1_operand" "")))
13013 (clobber (reg:CC 17))]
13014 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015 && (TARGET_SHIFT1 || optimize_size)"
13016 "ror{b}\t%0"
13017 [(set_attr "type" "rotate1")
13018 (set (attr "length")
13019 (if_then_else (match_operand 0 "register_operand" "")
13020 (const_string "2")
13021 (const_string "*")))])
13022
13023 (define_insn "*rotrqi3_1"
13024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13025 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13026 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13027 (clobber (reg:CC 17))]
13028 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13029 "@
13030 ror{b}\t{%2, %0|%0, %2}
13031 ror{b}\t{%b2, %0|%0, %b2}"
13032 [(set_attr "type" "rotate")
13033 (set_attr "mode" "QI")])
13034
13035 (define_insn "*rotrqi3_1_slp"
13036 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13037 (rotatert:QI (match_dup 0)
13038 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13039 (clobber (reg:CC 17))]
13040 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13041 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13042 "@
13043 ror{b}\t{%1, %0|%0, %1}
13044 ror{b}\t{%b1, %0|%0, %b1}"
13045 [(set_attr "type" "rotate1")
13046 (set_attr "mode" "QI")])
13047 \f
13048 ;; Bit set / bit test instructions
13049
13050 (define_expand "extv"
13051 [(set (match_operand:SI 0 "register_operand" "")
13052 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13053 (match_operand:SI 2 "immediate_operand" "")
13054 (match_operand:SI 3 "immediate_operand" "")))]
13055 ""
13056 {
13057 /* Handle extractions from %ah et al. */
13058 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13059 FAIL;
13060
13061 /* From mips.md: extract_bit_field doesn't verify that our source
13062 matches the predicate, so check it again here. */
13063 if (! register_operand (operands[1], VOIDmode))
13064 FAIL;
13065 })
13066
13067 (define_expand "extzv"
13068 [(set (match_operand:SI 0 "register_operand" "")
13069 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13070 (match_operand:SI 2 "immediate_operand" "")
13071 (match_operand:SI 3 "immediate_operand" "")))]
13072 ""
13073 {
13074 /* Handle extractions from %ah et al. */
13075 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13076 FAIL;
13077
13078 /* From mips.md: extract_bit_field doesn't verify that our source
13079 matches the predicate, so check it again here. */
13080 if (! register_operand (operands[1], VOIDmode))
13081 FAIL;
13082 })
13083
13084 (define_expand "insv"
13085 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13086 (match_operand:SI 1 "immediate_operand" "")
13087 (match_operand:SI 2 "immediate_operand" ""))
13088 (match_operand:SI 3 "register_operand" ""))]
13089 ""
13090 {
13091 /* Handle extractions from %ah et al. */
13092 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13093 FAIL;
13094
13095 /* From mips.md: insert_bit_field doesn't verify that our source
13096 matches the predicate, so check it again here. */
13097 if (! register_operand (operands[0], VOIDmode))
13098 FAIL;
13099 })
13100
13101 ;; %%% bts, btr, btc, bt.
13102 \f
13103 ;; Store-flag instructions.
13104
13105 ;; For all sCOND expanders, also expand the compare or test insn that
13106 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13107
13108 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13109 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13110 ;; way, which can later delete the movzx if only QImode is needed.
13111
13112 (define_expand "seq"
13113 [(set (match_operand:QI 0 "register_operand" "")
13114 (eq:QI (reg:CC 17) (const_int 0)))]
13115 ""
13116 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13117
13118 (define_expand "sne"
13119 [(set (match_operand:QI 0 "register_operand" "")
13120 (ne:QI (reg:CC 17) (const_int 0)))]
13121 ""
13122 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13123
13124 (define_expand "sgt"
13125 [(set (match_operand:QI 0 "register_operand" "")
13126 (gt:QI (reg:CC 17) (const_int 0)))]
13127 ""
13128 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13129
13130 (define_expand "sgtu"
13131 [(set (match_operand:QI 0 "register_operand" "")
13132 (gtu:QI (reg:CC 17) (const_int 0)))]
13133 ""
13134 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13135
13136 (define_expand "slt"
13137 [(set (match_operand:QI 0 "register_operand" "")
13138 (lt:QI (reg:CC 17) (const_int 0)))]
13139 ""
13140 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13141
13142 (define_expand "sltu"
13143 [(set (match_operand:QI 0 "register_operand" "")
13144 (ltu:QI (reg:CC 17) (const_int 0)))]
13145 ""
13146 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13147
13148 (define_expand "sge"
13149 [(set (match_operand:QI 0 "register_operand" "")
13150 (ge:QI (reg:CC 17) (const_int 0)))]
13151 ""
13152 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13153
13154 (define_expand "sgeu"
13155 [(set (match_operand:QI 0 "register_operand" "")
13156 (geu:QI (reg:CC 17) (const_int 0)))]
13157 ""
13158 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13159
13160 (define_expand "sle"
13161 [(set (match_operand:QI 0 "register_operand" "")
13162 (le:QI (reg:CC 17) (const_int 0)))]
13163 ""
13164 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13165
13166 (define_expand "sleu"
13167 [(set (match_operand:QI 0 "register_operand" "")
13168 (leu:QI (reg:CC 17) (const_int 0)))]
13169 ""
13170 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13171
13172 (define_expand "sunordered"
13173 [(set (match_operand:QI 0 "register_operand" "")
13174 (unordered:QI (reg:CC 17) (const_int 0)))]
13175 "TARGET_80387 || TARGET_SSE"
13176 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13177
13178 (define_expand "sordered"
13179 [(set (match_operand:QI 0 "register_operand" "")
13180 (ordered:QI (reg:CC 17) (const_int 0)))]
13181 "TARGET_80387"
13182 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13183
13184 (define_expand "suneq"
13185 [(set (match_operand:QI 0 "register_operand" "")
13186 (uneq:QI (reg:CC 17) (const_int 0)))]
13187 "TARGET_80387 || TARGET_SSE"
13188 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13189
13190 (define_expand "sunge"
13191 [(set (match_operand:QI 0 "register_operand" "")
13192 (unge:QI (reg:CC 17) (const_int 0)))]
13193 "TARGET_80387 || TARGET_SSE"
13194 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13195
13196 (define_expand "sungt"
13197 [(set (match_operand:QI 0 "register_operand" "")
13198 (ungt:QI (reg:CC 17) (const_int 0)))]
13199 "TARGET_80387 || TARGET_SSE"
13200 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13201
13202 (define_expand "sunle"
13203 [(set (match_operand:QI 0 "register_operand" "")
13204 (unle:QI (reg:CC 17) (const_int 0)))]
13205 "TARGET_80387 || TARGET_SSE"
13206 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13207
13208 (define_expand "sunlt"
13209 [(set (match_operand:QI 0 "register_operand" "")
13210 (unlt:QI (reg:CC 17) (const_int 0)))]
13211 "TARGET_80387 || TARGET_SSE"
13212 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13213
13214 (define_expand "sltgt"
13215 [(set (match_operand:QI 0 "register_operand" "")
13216 (ltgt:QI (reg:CC 17) (const_int 0)))]
13217 "TARGET_80387 || TARGET_SSE"
13218 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13219
13220 (define_insn "*setcc_1"
13221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13222 (match_operator:QI 1 "ix86_comparison_operator"
13223 [(reg 17) (const_int 0)]))]
13224 ""
13225 "set%C1\t%0"
13226 [(set_attr "type" "setcc")
13227 (set_attr "mode" "QI")])
13228
13229 (define_insn "setcc_2"
13230 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13231 (match_operator:QI 1 "ix86_comparison_operator"
13232 [(reg 17) (const_int 0)]))]
13233 ""
13234 "set%C1\t%0"
13235 [(set_attr "type" "setcc")
13236 (set_attr "mode" "QI")])
13237
13238 ;; In general it is not safe to assume too much about CCmode registers,
13239 ;; so simplify-rtx stops when it sees a second one. Under certain
13240 ;; conditions this is safe on x86, so help combine not create
13241 ;;
13242 ;; seta %al
13243 ;; testb %al, %al
13244 ;; sete %al
13245
13246 (define_split
13247 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13248 (ne:QI (match_operator 1 "ix86_comparison_operator"
13249 [(reg 17) (const_int 0)])
13250 (const_int 0)))]
13251 ""
13252 [(set (match_dup 0) (match_dup 1))]
13253 {
13254 PUT_MODE (operands[1], QImode);
13255 })
13256
13257 (define_split
13258 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13259 (ne:QI (match_operator 1 "ix86_comparison_operator"
13260 [(reg 17) (const_int 0)])
13261 (const_int 0)))]
13262 ""
13263 [(set (match_dup 0) (match_dup 1))]
13264 {
13265 PUT_MODE (operands[1], QImode);
13266 })
13267
13268 (define_split
13269 [(set (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 (define_split
13289 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13290 (eq:QI (match_operator 1 "ix86_comparison_operator"
13291 [(reg 17) (const_int 0)])
13292 (const_int 0)))]
13293 ""
13294 [(set (match_dup 0) (match_dup 1))]
13295 {
13296 rtx new_op1 = copy_rtx (operands[1]);
13297 operands[1] = new_op1;
13298 PUT_MODE (new_op1, QImode);
13299 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13300 GET_MODE (XEXP (new_op1, 0))));
13301
13302 /* Make sure that (a) the CCmode we have for the flags is strong
13303 enough for the reversed compare or (b) we have a valid FP compare. */
13304 if (! ix86_comparison_operator (new_op1, VOIDmode))
13305 FAIL;
13306 })
13307
13308 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13309 ;; subsequent logical operations are used to imitate conditional moves.
13310 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13311 ;; it directly. Further holding this value in pseudo register might bring
13312 ;; problem in implicit normalization in spill code.
13313 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13314 ;; instructions after reload by splitting the conditional move patterns.
13315
13316 (define_insn "*sse_setccsf"
13317 [(set (match_operand:SF 0 "register_operand" "=x")
13318 (match_operator:SF 1 "sse_comparison_operator"
13319 [(match_operand:SF 2 "register_operand" "0")
13320 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13321 "TARGET_SSE && reload_completed"
13322 "cmp%D1ss\t{%3, %0|%0, %3}"
13323 [(set_attr "type" "ssecmp")
13324 (set_attr "mode" "SF")])
13325
13326 (define_insn "*sse_setccdf"
13327 [(set (match_operand:DF 0 "register_operand" "=Y")
13328 (match_operator:DF 1 "sse_comparison_operator"
13329 [(match_operand:DF 2 "register_operand" "0")
13330 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13331 "TARGET_SSE2 && reload_completed"
13332 "cmp%D1sd\t{%3, %0|%0, %3}"
13333 [(set_attr "type" "ssecmp")
13334 (set_attr "mode" "DF")])
13335 \f
13336 ;; Basic conditional jump instructions.
13337 ;; We ignore the overflow flag for signed branch instructions.
13338
13339 ;; For all bCOND expanders, also expand the compare or test insn that
13340 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13341
13342 (define_expand "beq"
13343 [(set (pc)
13344 (if_then_else (match_dup 1)
13345 (label_ref (match_operand 0 "" ""))
13346 (pc)))]
13347 ""
13348 "ix86_expand_branch (EQ, operands[0]); DONE;")
13349
13350 (define_expand "bne"
13351 [(set (pc)
13352 (if_then_else (match_dup 1)
13353 (label_ref (match_operand 0 "" ""))
13354 (pc)))]
13355 ""
13356 "ix86_expand_branch (NE, operands[0]); DONE;")
13357
13358 (define_expand "bgt"
13359 [(set (pc)
13360 (if_then_else (match_dup 1)
13361 (label_ref (match_operand 0 "" ""))
13362 (pc)))]
13363 ""
13364 "ix86_expand_branch (GT, operands[0]); DONE;")
13365
13366 (define_expand "bgtu"
13367 [(set (pc)
13368 (if_then_else (match_dup 1)
13369 (label_ref (match_operand 0 "" ""))
13370 (pc)))]
13371 ""
13372 "ix86_expand_branch (GTU, operands[0]); DONE;")
13373
13374 (define_expand "blt"
13375 [(set (pc)
13376 (if_then_else (match_dup 1)
13377 (label_ref (match_operand 0 "" ""))
13378 (pc)))]
13379 ""
13380 "ix86_expand_branch (LT, operands[0]); DONE;")
13381
13382 (define_expand "bltu"
13383 [(set (pc)
13384 (if_then_else (match_dup 1)
13385 (label_ref (match_operand 0 "" ""))
13386 (pc)))]
13387 ""
13388 "ix86_expand_branch (LTU, operands[0]); DONE;")
13389
13390 (define_expand "bge"
13391 [(set (pc)
13392 (if_then_else (match_dup 1)
13393 (label_ref (match_operand 0 "" ""))
13394 (pc)))]
13395 ""
13396 "ix86_expand_branch (GE, operands[0]); DONE;")
13397
13398 (define_expand "bgeu"
13399 [(set (pc)
13400 (if_then_else (match_dup 1)
13401 (label_ref (match_operand 0 "" ""))
13402 (pc)))]
13403 ""
13404 "ix86_expand_branch (GEU, operands[0]); DONE;")
13405
13406 (define_expand "ble"
13407 [(set (pc)
13408 (if_then_else (match_dup 1)
13409 (label_ref (match_operand 0 "" ""))
13410 (pc)))]
13411 ""
13412 "ix86_expand_branch (LE, operands[0]); DONE;")
13413
13414 (define_expand "bleu"
13415 [(set (pc)
13416 (if_then_else (match_dup 1)
13417 (label_ref (match_operand 0 "" ""))
13418 (pc)))]
13419 ""
13420 "ix86_expand_branch (LEU, operands[0]); DONE;")
13421
13422 (define_expand "bunordered"
13423 [(set (pc)
13424 (if_then_else (match_dup 1)
13425 (label_ref (match_operand 0 "" ""))
13426 (pc)))]
13427 "TARGET_80387 || TARGET_SSE"
13428 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13429
13430 (define_expand "bordered"
13431 [(set (pc)
13432 (if_then_else (match_dup 1)
13433 (label_ref (match_operand 0 "" ""))
13434 (pc)))]
13435 "TARGET_80387 || TARGET_SSE"
13436 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13437
13438 (define_expand "buneq"
13439 [(set (pc)
13440 (if_then_else (match_dup 1)
13441 (label_ref (match_operand 0 "" ""))
13442 (pc)))]
13443 "TARGET_80387 || TARGET_SSE"
13444 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13445
13446 (define_expand "bunge"
13447 [(set (pc)
13448 (if_then_else (match_dup 1)
13449 (label_ref (match_operand 0 "" ""))
13450 (pc)))]
13451 "TARGET_80387 || TARGET_SSE"
13452 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13453
13454 (define_expand "bungt"
13455 [(set (pc)
13456 (if_then_else (match_dup 1)
13457 (label_ref (match_operand 0 "" ""))
13458 (pc)))]
13459 "TARGET_80387 || TARGET_SSE"
13460 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13461
13462 (define_expand "bunle"
13463 [(set (pc)
13464 (if_then_else (match_dup 1)
13465 (label_ref (match_operand 0 "" ""))
13466 (pc)))]
13467 "TARGET_80387 || TARGET_SSE"
13468 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13469
13470 (define_expand "bunlt"
13471 [(set (pc)
13472 (if_then_else (match_dup 1)
13473 (label_ref (match_operand 0 "" ""))
13474 (pc)))]
13475 "TARGET_80387 || TARGET_SSE"
13476 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13477
13478 (define_expand "bltgt"
13479 [(set (pc)
13480 (if_then_else (match_dup 1)
13481 (label_ref (match_operand 0 "" ""))
13482 (pc)))]
13483 "TARGET_80387 || TARGET_SSE"
13484 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13485
13486 (define_insn "*jcc_1"
13487 [(set (pc)
13488 (if_then_else (match_operator 1 "ix86_comparison_operator"
13489 [(reg 17) (const_int 0)])
13490 (label_ref (match_operand 0 "" ""))
13491 (pc)))]
13492 ""
13493 "%+j%C1\t%l0"
13494 [(set_attr "type" "ibr")
13495 (set_attr "modrm" "0")
13496 (set (attr "length")
13497 (if_then_else (and (ge (minus (match_dup 0) (pc))
13498 (const_int -126))
13499 (lt (minus (match_dup 0) (pc))
13500 (const_int 128)))
13501 (const_int 2)
13502 (const_int 6)))])
13503
13504 (define_insn "*jcc_2"
13505 [(set (pc)
13506 (if_then_else (match_operator 1 "ix86_comparison_operator"
13507 [(reg 17) (const_int 0)])
13508 (pc)
13509 (label_ref (match_operand 0 "" ""))))]
13510 ""
13511 "%+j%c1\t%l0"
13512 [(set_attr "type" "ibr")
13513 (set_attr "modrm" "0")
13514 (set (attr "length")
13515 (if_then_else (and (ge (minus (match_dup 0) (pc))
13516 (const_int -126))
13517 (lt (minus (match_dup 0) (pc))
13518 (const_int 128)))
13519 (const_int 2)
13520 (const_int 6)))])
13521
13522 ;; In general it is not safe to assume too much about CCmode registers,
13523 ;; so simplify-rtx stops when it sees a second one. Under certain
13524 ;; conditions this is safe on x86, so help combine not create
13525 ;;
13526 ;; seta %al
13527 ;; testb %al, %al
13528 ;; je Lfoo
13529
13530 (define_split
13531 [(set (pc)
13532 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13533 [(reg 17) (const_int 0)])
13534 (const_int 0))
13535 (label_ref (match_operand 1 "" ""))
13536 (pc)))]
13537 ""
13538 [(set (pc)
13539 (if_then_else (match_dup 0)
13540 (label_ref (match_dup 1))
13541 (pc)))]
13542 {
13543 PUT_MODE (operands[0], VOIDmode);
13544 })
13545
13546 (define_split
13547 [(set (pc)
13548 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13549 [(reg 17) (const_int 0)])
13550 (const_int 0))
13551 (label_ref (match_operand 1 "" ""))
13552 (pc)))]
13553 ""
13554 [(set (pc)
13555 (if_then_else (match_dup 0)
13556 (label_ref (match_dup 1))
13557 (pc)))]
13558 {
13559 rtx new_op0 = copy_rtx (operands[0]);
13560 operands[0] = new_op0;
13561 PUT_MODE (new_op0, VOIDmode);
13562 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13563 GET_MODE (XEXP (new_op0, 0))));
13564
13565 /* Make sure that (a) the CCmode we have for the flags is strong
13566 enough for the reversed compare or (b) we have a valid FP compare. */
13567 if (! ix86_comparison_operator (new_op0, VOIDmode))
13568 FAIL;
13569 })
13570
13571 ;; Define combination compare-and-branch fp compare instructions to use
13572 ;; during early optimization. Splitting the operation apart early makes
13573 ;; for bad code when we want to reverse the operation.
13574
13575 (define_insn "*fp_jcc_1"
13576 [(set (pc)
13577 (if_then_else (match_operator 0 "comparison_operator"
13578 [(match_operand 1 "register_operand" "f")
13579 (match_operand 2 "register_operand" "f")])
13580 (label_ref (match_operand 3 "" ""))
13581 (pc)))
13582 (clobber (reg:CCFP 18))
13583 (clobber (reg:CCFP 17))]
13584 "TARGET_CMOVE && TARGET_80387
13585 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13586 && FLOAT_MODE_P (GET_MODE (operands[1]))
13587 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13588 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13589 "#")
13590
13591 (define_insn "*fp_jcc_1_sse"
13592 [(set (pc)
13593 (if_then_else (match_operator 0 "comparison_operator"
13594 [(match_operand 1 "register_operand" "f#x,x#f")
13595 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13596 (label_ref (match_operand 3 "" ""))
13597 (pc)))
13598 (clobber (reg:CCFP 18))
13599 (clobber (reg:CCFP 17))]
13600 "TARGET_80387
13601 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13602 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13603 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13604 "#")
13605
13606 (define_insn "*fp_jcc_1_sse_only"
13607 [(set (pc)
13608 (if_then_else (match_operator 0 "comparison_operator"
13609 [(match_operand 1 "register_operand" "x")
13610 (match_operand 2 "nonimmediate_operand" "xm")])
13611 (label_ref (match_operand 3 "" ""))
13612 (pc)))
13613 (clobber (reg:CCFP 18))
13614 (clobber (reg:CCFP 17))]
13615 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13616 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13617 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13618 "#")
13619
13620 (define_insn "*fp_jcc_2"
13621 [(set (pc)
13622 (if_then_else (match_operator 0 "comparison_operator"
13623 [(match_operand 1 "register_operand" "f")
13624 (match_operand 2 "register_operand" "f")])
13625 (pc)
13626 (label_ref (match_operand 3 "" ""))))
13627 (clobber (reg:CCFP 18))
13628 (clobber (reg:CCFP 17))]
13629 "TARGET_CMOVE && TARGET_80387
13630 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13631 && FLOAT_MODE_P (GET_MODE (operands[1]))
13632 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13633 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13634 "#")
13635
13636 (define_insn "*fp_jcc_2_sse"
13637 [(set (pc)
13638 (if_then_else (match_operator 0 "comparison_operator"
13639 [(match_operand 1 "register_operand" "f#x,x#f")
13640 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13641 (pc)
13642 (label_ref (match_operand 3 "" ""))))
13643 (clobber (reg:CCFP 18))
13644 (clobber (reg:CCFP 17))]
13645 "TARGET_80387
13646 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13647 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13648 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13649 "#")
13650
13651 (define_insn "*fp_jcc_2_sse_only"
13652 [(set (pc)
13653 (if_then_else (match_operator 0 "comparison_operator"
13654 [(match_operand 1 "register_operand" "x")
13655 (match_operand 2 "nonimmediate_operand" "xm")])
13656 (pc)
13657 (label_ref (match_operand 3 "" ""))))
13658 (clobber (reg:CCFP 18))
13659 (clobber (reg:CCFP 17))]
13660 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13661 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13662 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13663 "#")
13664
13665 (define_insn "*fp_jcc_3"
13666 [(set (pc)
13667 (if_then_else (match_operator 0 "comparison_operator"
13668 [(match_operand 1 "register_operand" "f")
13669 (match_operand 2 "nonimmediate_operand" "fm")])
13670 (label_ref (match_operand 3 "" ""))
13671 (pc)))
13672 (clobber (reg:CCFP 18))
13673 (clobber (reg:CCFP 17))
13674 (clobber (match_scratch:HI 4 "=a"))]
13675 "TARGET_80387
13676 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13677 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13678 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13679 && SELECT_CC_MODE (GET_CODE (operands[0]),
13680 operands[1], operands[2]) == CCFPmode
13681 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13682 "#")
13683
13684 (define_insn "*fp_jcc_4"
13685 [(set (pc)
13686 (if_then_else (match_operator 0 "comparison_operator"
13687 [(match_operand 1 "register_operand" "f")
13688 (match_operand 2 "nonimmediate_operand" "fm")])
13689 (pc)
13690 (label_ref (match_operand 3 "" ""))))
13691 (clobber (reg:CCFP 18))
13692 (clobber (reg:CCFP 17))
13693 (clobber (match_scratch:HI 4 "=a"))]
13694 "TARGET_80387
13695 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13696 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13697 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13698 && SELECT_CC_MODE (GET_CODE (operands[0]),
13699 operands[1], operands[2]) == CCFPmode
13700 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13701 "#")
13702
13703 (define_insn "*fp_jcc_5"
13704 [(set (pc)
13705 (if_then_else (match_operator 0 "comparison_operator"
13706 [(match_operand 1 "register_operand" "f")
13707 (match_operand 2 "register_operand" "f")])
13708 (label_ref (match_operand 3 "" ""))
13709 (pc)))
13710 (clobber (reg:CCFP 18))
13711 (clobber (reg:CCFP 17))
13712 (clobber (match_scratch:HI 4 "=a"))]
13713 "TARGET_80387
13714 && FLOAT_MODE_P (GET_MODE (operands[1]))
13715 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13716 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13717 "#")
13718
13719 (define_insn "*fp_jcc_6"
13720 [(set (pc)
13721 (if_then_else (match_operator 0 "comparison_operator"
13722 [(match_operand 1 "register_operand" "f")
13723 (match_operand 2 "register_operand" "f")])
13724 (pc)
13725 (label_ref (match_operand 3 "" ""))))
13726 (clobber (reg:CCFP 18))
13727 (clobber (reg:CCFP 17))
13728 (clobber (match_scratch:HI 4 "=a"))]
13729 "TARGET_80387
13730 && FLOAT_MODE_P (GET_MODE (operands[1]))
13731 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13732 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13733 "#")
13734
13735 (define_split
13736 [(set (pc)
13737 (if_then_else (match_operator 0 "comparison_operator"
13738 [(match_operand 1 "register_operand" "")
13739 (match_operand 2 "nonimmediate_operand" "")])
13740 (match_operand 3 "" "")
13741 (match_operand 4 "" "")))
13742 (clobber (reg:CCFP 18))
13743 (clobber (reg:CCFP 17))]
13744 "reload_completed"
13745 [(const_int 0)]
13746 {
13747 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13748 operands[3], operands[4], NULL_RTX);
13749 DONE;
13750 })
13751
13752 (define_split
13753 [(set (pc)
13754 (if_then_else (match_operator 0 "comparison_operator"
13755 [(match_operand 1 "register_operand" "")
13756 (match_operand 2 "nonimmediate_operand" "")])
13757 (match_operand 3 "" "")
13758 (match_operand 4 "" "")))
13759 (clobber (reg:CCFP 18))
13760 (clobber (reg:CCFP 17))
13761 (clobber (match_scratch:HI 5 "=a"))]
13762 "reload_completed"
13763 [(set (pc)
13764 (if_then_else (match_dup 6)
13765 (match_dup 3)
13766 (match_dup 4)))]
13767 {
13768 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13769 operands[3], operands[4], operands[5]);
13770 DONE;
13771 })
13772 \f
13773 ;; Unconditional and other jump instructions
13774
13775 (define_insn "jump"
13776 [(set (pc)
13777 (label_ref (match_operand 0 "" "")))]
13778 ""
13779 "jmp\t%l0"
13780 [(set_attr "type" "ibr")
13781 (set (attr "length")
13782 (if_then_else (and (ge (minus (match_dup 0) (pc))
13783 (const_int -126))
13784 (lt (minus (match_dup 0) (pc))
13785 (const_int 128)))
13786 (const_int 2)
13787 (const_int 5)))
13788 (set_attr "modrm" "0")])
13789
13790 (define_expand "indirect_jump"
13791 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13792 ""
13793 "")
13794
13795 (define_insn "*indirect_jump"
13796 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13797 "!TARGET_64BIT"
13798 "jmp\t%A0"
13799 [(set_attr "type" "ibr")
13800 (set_attr "length_immediate" "0")])
13801
13802 (define_insn "*indirect_jump_rtx64"
13803 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13804 "TARGET_64BIT"
13805 "jmp\t%A0"
13806 [(set_attr "type" "ibr")
13807 (set_attr "length_immediate" "0")])
13808
13809 (define_expand "tablejump"
13810 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13811 (use (label_ref (match_operand 1 "" "")))])]
13812 ""
13813 {
13814 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13815 relative. Convert the relative address to an absolute address. */
13816 if (flag_pic)
13817 {
13818 rtx op0, op1;
13819 enum rtx_code code;
13820
13821 if (TARGET_64BIT)
13822 {
13823 code = PLUS;
13824 op0 = operands[0];
13825 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13826 }
13827 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13828 {
13829 code = PLUS;
13830 op0 = operands[0];
13831 op1 = pic_offset_table_rtx;
13832 }
13833 else
13834 {
13835 code = MINUS;
13836 op0 = pic_offset_table_rtx;
13837 op1 = operands[0];
13838 }
13839
13840 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13841 OPTAB_DIRECT);
13842 }
13843 })
13844
13845 (define_insn "*tablejump_1"
13846 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13847 (use (label_ref (match_operand 1 "" "")))]
13848 "!TARGET_64BIT"
13849 "jmp\t%A0"
13850 [(set_attr "type" "ibr")
13851 (set_attr "length_immediate" "0")])
13852
13853 (define_insn "*tablejump_1_rtx64"
13854 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13855 (use (label_ref (match_operand 1 "" "")))]
13856 "TARGET_64BIT"
13857 "jmp\t%A0"
13858 [(set_attr "type" "ibr")
13859 (set_attr "length_immediate" "0")])
13860 \f
13861 ;; Loop instruction
13862 ;;
13863 ;; This is all complicated by the fact that since this is a jump insn
13864 ;; we must handle our own reloads.
13865
13866 (define_expand "doloop_end"
13867 [(use (match_operand 0 "" "")) ; loop pseudo
13868 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13869 (use (match_operand 2 "" "")) ; max iterations
13870 (use (match_operand 3 "" "")) ; loop level
13871 (use (match_operand 4 "" ""))] ; label
13872 "!TARGET_64BIT && TARGET_USE_LOOP"
13873 "
13874 {
13875 /* Only use cloop on innermost loops. */
13876 if (INTVAL (operands[3]) > 1)
13877 FAIL;
13878 if (GET_MODE (operands[0]) != SImode)
13879 FAIL;
13880 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13881 operands[0]));
13882 DONE;
13883 }")
13884
13885 (define_insn "doloop_end_internal"
13886 [(set (pc)
13887 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13888 (const_int 1))
13889 (label_ref (match_operand 0 "" ""))
13890 (pc)))
13891 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13892 (plus:SI (match_dup 1)
13893 (const_int -1)))
13894 (clobber (match_scratch:SI 3 "=X,X,r"))
13895 (clobber (reg:CC 17))]
13896 "!TARGET_64BIT && TARGET_USE_LOOP"
13897 {
13898 if (which_alternative != 0)
13899 return "#";
13900 if (get_attr_length (insn) == 2)
13901 return "%+loop\t%l0";
13902 else
13903 return "dec{l}\t%1\;%+jne\t%l0";
13904 }
13905 [(set_attr "ppro_uops" "many")
13906 (set (attr "length")
13907 (if_then_else (and (eq_attr "alternative" "0")
13908 (and (ge (minus (match_dup 0) (pc))
13909 (const_int -126))
13910 (lt (minus (match_dup 0) (pc))
13911 (const_int 128))))
13912 (const_int 2)
13913 (const_int 16)))
13914 ;; We don't know the type before shorten branches. Optimistically expect
13915 ;; the loop instruction to match.
13916 (set (attr "type") (const_string "ibr"))])
13917
13918 (define_split
13919 [(set (pc)
13920 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13921 (const_int 1))
13922 (match_operand 0 "" "")
13923 (pc)))
13924 (set (match_dup 1)
13925 (plus:SI (match_dup 1)
13926 (const_int -1)))
13927 (clobber (match_scratch:SI 2 ""))
13928 (clobber (reg:CC 17))]
13929 "!TARGET_64BIT && TARGET_USE_LOOP
13930 && reload_completed
13931 && REGNO (operands[1]) != 2"
13932 [(parallel [(set (reg:CCZ 17)
13933 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13934 (const_int 0)))
13935 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13936 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13937 (match_dup 0)
13938 (pc)))]
13939 "")
13940
13941 (define_split
13942 [(set (pc)
13943 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13944 (const_int 1))
13945 (match_operand 0 "" "")
13946 (pc)))
13947 (set (match_operand:SI 2 "nonimmediate_operand" "")
13948 (plus:SI (match_dup 1)
13949 (const_int -1)))
13950 (clobber (match_scratch:SI 3 ""))
13951 (clobber (reg:CC 17))]
13952 "!TARGET_64BIT && TARGET_USE_LOOP
13953 && reload_completed
13954 && (! REG_P (operands[2])
13955 || ! rtx_equal_p (operands[1], operands[2]))"
13956 [(set (match_dup 3) (match_dup 1))
13957 (parallel [(set (reg:CCZ 17)
13958 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13959 (const_int 0)))
13960 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13961 (set (match_dup 2) (match_dup 3))
13962 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13963 (match_dup 0)
13964 (pc)))]
13965 "")
13966
13967 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13968
13969 (define_peephole2
13970 [(set (reg 17) (match_operand 0 "" ""))
13971 (set (match_operand:QI 1 "register_operand" "")
13972 (match_operator:QI 2 "ix86_comparison_operator"
13973 [(reg 17) (const_int 0)]))
13974 (set (match_operand 3 "q_regs_operand" "")
13975 (zero_extend (match_dup 1)))]
13976 "(peep2_reg_dead_p (3, operands[1])
13977 || operands_match_p (operands[1], operands[3]))
13978 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13979 [(set (match_dup 4) (match_dup 0))
13980 (set (strict_low_part (match_dup 5))
13981 (match_dup 2))]
13982 {
13983 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13984 operands[5] = gen_lowpart (QImode, operands[3]);
13985 ix86_expand_clear (operands[3]);
13986 })
13987
13988 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13989
13990 (define_peephole2
13991 [(set (reg 17) (match_operand 0 "" ""))
13992 (set (match_operand:QI 1 "register_operand" "")
13993 (match_operator:QI 2 "ix86_comparison_operator"
13994 [(reg 17) (const_int 0)]))
13995 (parallel [(set (match_operand 3 "q_regs_operand" "")
13996 (zero_extend (match_dup 1)))
13997 (clobber (reg:CC 17))])]
13998 "(peep2_reg_dead_p (3, operands[1])
13999 || operands_match_p (operands[1], operands[3]))
14000 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14001 [(set (match_dup 4) (match_dup 0))
14002 (set (strict_low_part (match_dup 5))
14003 (match_dup 2))]
14004 {
14005 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
14006 operands[5] = gen_lowpart (QImode, operands[3]);
14007 ix86_expand_clear (operands[3]);
14008 })
14009 \f
14010 ;; Call instructions.
14011
14012 ;; The predicates normally associated with named expanders are not properly
14013 ;; checked for calls. This is a bug in the generic code, but it isn't that
14014 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14015
14016 ;; Call subroutine returning no value.
14017
14018 (define_expand "call_pop"
14019 [(parallel [(call (match_operand:QI 0 "" "")
14020 (match_operand:SI 1 "" ""))
14021 (set (reg:SI 7)
14022 (plus:SI (reg:SI 7)
14023 (match_operand:SI 3 "" "")))])]
14024 "!TARGET_64BIT"
14025 {
14026 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14027 DONE;
14028 })
14029
14030 (define_insn "*call_pop_0"
14031 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14032 (match_operand:SI 1 "" ""))
14033 (set (reg:SI 7) (plus:SI (reg:SI 7)
14034 (match_operand:SI 2 "immediate_operand" "")))]
14035 "!TARGET_64BIT"
14036 {
14037 if (SIBLING_CALL_P (insn))
14038 return "jmp\t%P0";
14039 else
14040 return "call\t%P0";
14041 }
14042 [(set_attr "type" "call")])
14043
14044 (define_insn "*call_pop_1"
14045 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14046 (match_operand:SI 1 "" ""))
14047 (set (reg:SI 7) (plus:SI (reg:SI 7)
14048 (match_operand:SI 2 "immediate_operand" "i")))]
14049 "!TARGET_64BIT"
14050 {
14051 if (constant_call_address_operand (operands[0], Pmode))
14052 {
14053 if (SIBLING_CALL_P (insn))
14054 return "jmp\t%P0";
14055 else
14056 return "call\t%P0";
14057 }
14058 if (SIBLING_CALL_P (insn))
14059 return "jmp\t%A0";
14060 else
14061 return "call\t%A0";
14062 }
14063 [(set_attr "type" "call")])
14064
14065 (define_expand "call"
14066 [(call (match_operand:QI 0 "" "")
14067 (match_operand 1 "" ""))
14068 (use (match_operand 2 "" ""))]
14069 ""
14070 {
14071 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14072 DONE;
14073 })
14074
14075 (define_expand "sibcall"
14076 [(call (match_operand:QI 0 "" "")
14077 (match_operand 1 "" ""))
14078 (use (match_operand 2 "" ""))]
14079 ""
14080 {
14081 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14082 DONE;
14083 })
14084
14085 (define_insn "*call_0"
14086 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14087 (match_operand 1 "" ""))]
14088 ""
14089 {
14090 if (SIBLING_CALL_P (insn))
14091 return "jmp\t%P0";
14092 else
14093 return "call\t%P0";
14094 }
14095 [(set_attr "type" "call")])
14096
14097 (define_insn "*call_1"
14098 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14099 (match_operand 1 "" ""))]
14100 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14101 {
14102 if (constant_call_address_operand (operands[0], QImode))
14103 return "call\t%P0";
14104 return "call\t%A0";
14105 }
14106 [(set_attr "type" "call")])
14107
14108 (define_insn "*sibcall_1"
14109 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14110 (match_operand 1 "" ""))]
14111 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14112 {
14113 if (constant_call_address_operand (operands[0], QImode))
14114 return "jmp\t%P0";
14115 return "jmp\t%A0";
14116 }
14117 [(set_attr "type" "call")])
14118
14119 (define_insn "*call_1_rex64"
14120 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14121 (match_operand 1 "" ""))]
14122 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14123 {
14124 if (constant_call_address_operand (operands[0], QImode))
14125 return "call\t%P0";
14126 return "call\t%A0";
14127 }
14128 [(set_attr "type" "call")])
14129
14130 (define_insn "*sibcall_1_rex64"
14131 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14132 (match_operand 1 "" ""))]
14133 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14134 "jmp\t%P0"
14135 [(set_attr "type" "call")])
14136
14137 (define_insn "*sibcall_1_rex64_v"
14138 [(call (mem:QI (reg:DI 40))
14139 (match_operand 0 "" ""))]
14140 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14141 "jmp\t*%%r11"
14142 [(set_attr "type" "call")])
14143
14144
14145 ;; Call subroutine, returning value in operand 0
14146
14147 (define_expand "call_value_pop"
14148 [(parallel [(set (match_operand 0 "" "")
14149 (call (match_operand:QI 1 "" "")
14150 (match_operand:SI 2 "" "")))
14151 (set (reg:SI 7)
14152 (plus:SI (reg:SI 7)
14153 (match_operand:SI 4 "" "")))])]
14154 "!TARGET_64BIT"
14155 {
14156 ix86_expand_call (operands[0], operands[1], operands[2],
14157 operands[3], operands[4], 0);
14158 DONE;
14159 })
14160
14161 (define_expand "call_value"
14162 [(set (match_operand 0 "" "")
14163 (call (match_operand:QI 1 "" "")
14164 (match_operand:SI 2 "" "")))
14165 (use (match_operand:SI 3 "" ""))]
14166 ;; Operand 2 not used on the i386.
14167 ""
14168 {
14169 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14170 DONE;
14171 })
14172
14173 (define_expand "sibcall_value"
14174 [(set (match_operand 0 "" "")
14175 (call (match_operand:QI 1 "" "")
14176 (match_operand:SI 2 "" "")))
14177 (use (match_operand:SI 3 "" ""))]
14178 ;; Operand 2 not used on the i386.
14179 ""
14180 {
14181 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14182 DONE;
14183 })
14184
14185 ;; Call subroutine returning any type.
14186
14187 (define_expand "untyped_call"
14188 [(parallel [(call (match_operand 0 "" "")
14189 (const_int 0))
14190 (match_operand 1 "" "")
14191 (match_operand 2 "" "")])]
14192 ""
14193 {
14194 int i;
14195
14196 /* In order to give reg-stack an easier job in validating two
14197 coprocessor registers as containing a possible return value,
14198 simply pretend the untyped call returns a complex long double
14199 value. */
14200
14201 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14202 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14203 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14204 NULL, 0);
14205
14206 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14207 {
14208 rtx set = XVECEXP (operands[2], 0, i);
14209 emit_move_insn (SET_DEST (set), SET_SRC (set));
14210 }
14211
14212 /* The optimizer does not know that the call sets the function value
14213 registers we stored in the result block. We avoid problems by
14214 claiming that all hard registers are used and clobbered at this
14215 point. */
14216 emit_insn (gen_blockage (const0_rtx));
14217
14218 DONE;
14219 })
14220 \f
14221 ;; Prologue and epilogue instructions
14222
14223 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14224 ;; all of memory. This blocks insns from being moved across this point.
14225
14226 (define_insn "blockage"
14227 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14228 ""
14229 ""
14230 [(set_attr "length" "0")])
14231
14232 ;; Insn emitted into the body of a function to return from a function.
14233 ;; This is only done if the function's epilogue is known to be simple.
14234 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14235
14236 (define_expand "return"
14237 [(return)]
14238 "ix86_can_use_return_insn_p ()"
14239 {
14240 if (current_function_pops_args)
14241 {
14242 rtx popc = GEN_INT (current_function_pops_args);
14243 emit_jump_insn (gen_return_pop_internal (popc));
14244 DONE;
14245 }
14246 })
14247
14248 (define_insn "return_internal"
14249 [(return)]
14250 "reload_completed"
14251 "ret"
14252 [(set_attr "length" "1")
14253 (set_attr "length_immediate" "0")
14254 (set_attr "modrm" "0")])
14255
14256 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14257 ;; instruction Athlon and K8 have.
14258
14259 (define_insn "return_internal_long"
14260 [(return)
14261 (unspec [(const_int 0)] UNSPEC_REP)]
14262 "reload_completed"
14263 "rep {;} ret"
14264 [(set_attr "length" "1")
14265 (set_attr "length_immediate" "0")
14266 (set_attr "prefix_rep" "1")
14267 (set_attr "modrm" "0")])
14268
14269 (define_insn "return_pop_internal"
14270 [(return)
14271 (use (match_operand:SI 0 "const_int_operand" ""))]
14272 "reload_completed"
14273 "ret\t%0"
14274 [(set_attr "length" "3")
14275 (set_attr "length_immediate" "2")
14276 (set_attr "modrm" "0")])
14277
14278 (define_insn "return_indirect_internal"
14279 [(return)
14280 (use (match_operand:SI 0 "register_operand" "r"))]
14281 "reload_completed"
14282 "jmp\t%A0"
14283 [(set_attr "type" "ibr")
14284 (set_attr "length_immediate" "0")])
14285
14286 (define_insn "nop"
14287 [(const_int 0)]
14288 ""
14289 "nop"
14290 [(set_attr "length" "1")
14291 (set_attr "length_immediate" "0")
14292 (set_attr "modrm" "0")
14293 (set_attr "ppro_uops" "one")])
14294
14295 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14296 ;; branch prediction penalty for the third jump in a 16-byte
14297 ;; block on K8.
14298
14299 (define_insn "align"
14300 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14301 ""
14302 {
14303 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14304 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14305 #else
14306 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14307 The align insn is used to avoid 3 jump instructions in the row to improve
14308 branch prediction and the benefits hardly outweight the cost of extra 8
14309 nops on the average inserted by full alignment pseudo operation. */
14310 #endif
14311 return "";
14312 }
14313 [(set_attr "length" "16")])
14314
14315 (define_expand "prologue"
14316 [(const_int 1)]
14317 ""
14318 "ix86_expand_prologue (); DONE;")
14319
14320 (define_insn "set_got"
14321 [(set (match_operand:SI 0 "register_operand" "=r")
14322 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14323 (clobber (reg:CC 17))]
14324 "!TARGET_64BIT"
14325 { return output_set_got (operands[0]); }
14326 [(set_attr "type" "multi")
14327 (set_attr "length" "12")])
14328
14329 (define_expand "epilogue"
14330 [(const_int 1)]
14331 ""
14332 "ix86_expand_epilogue (1); DONE;")
14333
14334 (define_expand "sibcall_epilogue"
14335 [(const_int 1)]
14336 ""
14337 "ix86_expand_epilogue (0); DONE;")
14338
14339 (define_expand "eh_return"
14340 [(use (match_operand 0 "register_operand" ""))]
14341 ""
14342 {
14343 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14344
14345 /* Tricky bit: we write the address of the handler to which we will
14346 be returning into someone else's stack frame, one word below the
14347 stack address we wish to restore. */
14348 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14349 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14350 tmp = gen_rtx_MEM (Pmode, tmp);
14351 emit_move_insn (tmp, ra);
14352
14353 if (Pmode == SImode)
14354 emit_insn (gen_eh_return_si (sa));
14355 else
14356 emit_insn (gen_eh_return_di (sa));
14357 emit_barrier ();
14358 DONE;
14359 })
14360
14361 (define_insn_and_split "eh_return_si"
14362 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14363 UNSPECV_EH_RETURN)]
14364 "!TARGET_64BIT"
14365 "#"
14366 "reload_completed"
14367 [(const_int 1)]
14368 "ix86_expand_epilogue (2); DONE;")
14369
14370 (define_insn_and_split "eh_return_di"
14371 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14372 UNSPECV_EH_RETURN)]
14373 "TARGET_64BIT"
14374 "#"
14375 "reload_completed"
14376 [(const_int 1)]
14377 "ix86_expand_epilogue (2); DONE;")
14378
14379 (define_insn "leave"
14380 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14381 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14382 (clobber (mem:BLK (scratch)))]
14383 "!TARGET_64BIT"
14384 "leave"
14385 [(set_attr "type" "leave")])
14386
14387 (define_insn "leave_rex64"
14388 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14389 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14390 (clobber (mem:BLK (scratch)))]
14391 "TARGET_64BIT"
14392 "leave"
14393 [(set_attr "type" "leave")])
14394 \f
14395 (define_expand "ffssi2"
14396 [(parallel
14397 [(set (match_operand:SI 0 "register_operand" "")
14398 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14399 (clobber (match_scratch:SI 2 ""))
14400 (clobber (reg:CC 17))])]
14401 ""
14402 "")
14403
14404 (define_insn_and_split "*ffs_cmove"
14405 [(set (match_operand:SI 0 "register_operand" "=r")
14406 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14407 (clobber (match_scratch:SI 2 "=&r"))
14408 (clobber (reg:CC 17))]
14409 "TARGET_CMOVE"
14410 "#"
14411 "&& reload_completed"
14412 [(set (match_dup 2) (const_int -1))
14413 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14414 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14415 (set (match_dup 0) (if_then_else:SI
14416 (eq (reg:CCZ 17) (const_int 0))
14417 (match_dup 2)
14418 (match_dup 0)))
14419 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14420 (clobber (reg:CC 17))])]
14421 "")
14422
14423 (define_insn_and_split "*ffs_no_cmove"
14424 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14425 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14426 (clobber (match_scratch:SI 2 "=&r"))
14427 (clobber (reg:CC 17))]
14428 ""
14429 "#"
14430 "reload_completed"
14431 [(parallel [(set (match_dup 2) (const_int 0))
14432 (clobber (reg:CC 17))])
14433 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14434 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14435 (set (strict_low_part (match_dup 3))
14436 (eq:QI (reg:CCZ 17) (const_int 0)))
14437 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14438 (clobber (reg:CC 17))])
14439 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14440 (clobber (reg:CC 17))])
14441 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14442 (clobber (reg:CC 17))])]
14443 {
14444 operands[3] = gen_lowpart (QImode, operands[2]);
14445 })
14446
14447 (define_insn "*ffssi_1"
14448 [(set (reg:CCZ 17)
14449 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14450 (const_int 0)))
14451 (set (match_operand:SI 0 "register_operand" "=r")
14452 (ctz:SI (match_dup 1)))]
14453 ""
14454 "bsf{l}\t{%1, %0|%0, %1}"
14455 [(set_attr "prefix_0f" "1")
14456 (set_attr "ppro_uops" "few")])
14457
14458 (define_insn "ctzsi2"
14459 [(set (match_operand:SI 0 "register_operand" "=r")
14460 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14461 (clobber (reg:CC 17))]
14462 ""
14463 "bsf{l}\t{%1, %0|%0, %1}"
14464 [(set_attr "prefix_0f" "1")
14465 (set_attr "ppro_uops" "few")])
14466
14467 (define_expand "clzsi2"
14468 [(parallel
14469 [(set (match_operand:SI 0 "register_operand" "")
14470 (minus:SI (const_int 31)
14471 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14472 (clobber (reg:CC 17))])
14473 (parallel
14474 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14475 (clobber (reg:CC 17))])]
14476 ""
14477 "")
14478
14479 (define_insn "*bsr"
14480 [(set (match_operand:SI 0 "register_operand" "=r")
14481 (minus:SI (const_int 31)
14482 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14483 (clobber (reg:CC 17))]
14484 ""
14485 "bsr{l}\t{%1, %0|%0, %1}"
14486 [(set_attr "prefix_0f" "1")
14487 (set_attr "ppro_uops" "few")])
14488 \f
14489 ;; Thread-local storage patterns for ELF.
14490 ;;
14491 ;; Note that these code sequences must appear exactly as shown
14492 ;; in order to allow linker relaxation.
14493
14494 (define_insn "*tls_global_dynamic_32_gnu"
14495 [(set (match_operand:SI 0 "register_operand" "=a")
14496 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14497 (match_operand:SI 2 "tls_symbolic_operand" "")
14498 (match_operand:SI 3 "call_insn_operand" "")]
14499 UNSPEC_TLS_GD))
14500 (clobber (match_scratch:SI 4 "=d"))
14501 (clobber (match_scratch:SI 5 "=c"))
14502 (clobber (reg:CC 17))]
14503 "!TARGET_64BIT && TARGET_GNU_TLS"
14504 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14505 [(set_attr "type" "multi")
14506 (set_attr "length" "12")])
14507
14508 (define_insn "*tls_global_dynamic_32_sun"
14509 [(set (match_operand:SI 0 "register_operand" "=a")
14510 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14511 (match_operand:SI 2 "tls_symbolic_operand" "")
14512 (match_operand:SI 3 "call_insn_operand" "")]
14513 UNSPEC_TLS_GD))
14514 (clobber (match_scratch:SI 4 "=d"))
14515 (clobber (match_scratch:SI 5 "=c"))
14516 (clobber (reg:CC 17))]
14517 "!TARGET_64BIT && TARGET_SUN_TLS"
14518 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14519 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14520 [(set_attr "type" "multi")
14521 (set_attr "length" "14")])
14522
14523 (define_expand "tls_global_dynamic_32"
14524 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14525 (unspec:SI
14526 [(match_dup 2)
14527 (match_operand:SI 1 "tls_symbolic_operand" "")
14528 (match_dup 3)]
14529 UNSPEC_TLS_GD))
14530 (clobber (match_scratch:SI 4 ""))
14531 (clobber (match_scratch:SI 5 ""))
14532 (clobber (reg:CC 17))])]
14533 ""
14534 {
14535 if (flag_pic)
14536 operands[2] = pic_offset_table_rtx;
14537 else
14538 {
14539 operands[2] = gen_reg_rtx (Pmode);
14540 emit_insn (gen_set_got (operands[2]));
14541 }
14542 operands[3] = ix86_tls_get_addr ();
14543 })
14544
14545 (define_insn "*tls_global_dynamic_64"
14546 [(set (match_operand:DI 0 "register_operand" "=a")
14547 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14548 (match_operand:DI 3 "" "")))
14549 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14550 UNSPEC_TLS_GD)]
14551 "TARGET_64BIT"
14552 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14553 [(set_attr "type" "multi")
14554 (set_attr "length" "16")])
14555
14556 (define_expand "tls_global_dynamic_64"
14557 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14558 (call (mem:QI (match_dup 2)) (const_int 0)))
14559 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14560 UNSPEC_TLS_GD)])]
14561 ""
14562 {
14563 operands[2] = ix86_tls_get_addr ();
14564 })
14565
14566 (define_insn "*tls_local_dynamic_base_32_gnu"
14567 [(set (match_operand:SI 0 "register_operand" "=a")
14568 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14569 (match_operand:SI 2 "call_insn_operand" "")]
14570 UNSPEC_TLS_LD_BASE))
14571 (clobber (match_scratch:SI 3 "=d"))
14572 (clobber (match_scratch:SI 4 "=c"))
14573 (clobber (reg:CC 17))]
14574 "!TARGET_64BIT && TARGET_GNU_TLS"
14575 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14576 [(set_attr "type" "multi")
14577 (set_attr "length" "11")])
14578
14579 (define_insn "*tls_local_dynamic_base_32_sun"
14580 [(set (match_operand:SI 0 "register_operand" "=a")
14581 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14582 (match_operand:SI 2 "call_insn_operand" "")]
14583 UNSPEC_TLS_LD_BASE))
14584 (clobber (match_scratch:SI 3 "=d"))
14585 (clobber (match_scratch:SI 4 "=c"))
14586 (clobber (reg:CC 17))]
14587 "!TARGET_64BIT && TARGET_SUN_TLS"
14588 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14589 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14590 [(set_attr "type" "multi")
14591 (set_attr "length" "13")])
14592
14593 (define_expand "tls_local_dynamic_base_32"
14594 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14595 (unspec:SI [(match_dup 1) (match_dup 2)]
14596 UNSPEC_TLS_LD_BASE))
14597 (clobber (match_scratch:SI 3 ""))
14598 (clobber (match_scratch:SI 4 ""))
14599 (clobber (reg:CC 17))])]
14600 ""
14601 {
14602 if (flag_pic)
14603 operands[1] = pic_offset_table_rtx;
14604 else
14605 {
14606 operands[1] = gen_reg_rtx (Pmode);
14607 emit_insn (gen_set_got (operands[1]));
14608 }
14609 operands[2] = ix86_tls_get_addr ();
14610 })
14611
14612 (define_insn "*tls_local_dynamic_base_64"
14613 [(set (match_operand:DI 0 "register_operand" "=a")
14614 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14615 (match_operand:DI 2 "" "")))
14616 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14617 "TARGET_64BIT"
14618 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14619 [(set_attr "type" "multi")
14620 (set_attr "length" "12")])
14621
14622 (define_expand "tls_local_dynamic_base_64"
14623 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14624 (call (mem:QI (match_dup 1)) (const_int 0)))
14625 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14626 ""
14627 {
14628 operands[1] = ix86_tls_get_addr ();
14629 })
14630
14631 ;; Local dynamic of a single variable is a lose. Show combine how
14632 ;; to convert that back to global dynamic.
14633
14634 (define_insn_and_split "*tls_local_dynamic_32_once"
14635 [(set (match_operand:SI 0 "register_operand" "=a")
14636 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14637 (match_operand:SI 2 "call_insn_operand" "")]
14638 UNSPEC_TLS_LD_BASE)
14639 (const:SI (unspec:SI
14640 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14641 UNSPEC_DTPOFF))))
14642 (clobber (match_scratch:SI 4 "=d"))
14643 (clobber (match_scratch:SI 5 "=c"))
14644 (clobber (reg:CC 17))]
14645 ""
14646 "#"
14647 ""
14648 [(parallel [(set (match_dup 0)
14649 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14650 UNSPEC_TLS_GD))
14651 (clobber (match_dup 4))
14652 (clobber (match_dup 5))
14653 (clobber (reg:CC 17))])]
14654 "")
14655
14656 ;; Load and add the thread base pointer from %gs:0.
14657
14658 (define_insn "*load_tp_si"
14659 [(set (match_operand:SI 0 "register_operand" "=r")
14660 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14661 "!TARGET_64BIT"
14662 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14663 [(set_attr "type" "imov")
14664 (set_attr "modrm" "0")
14665 (set_attr "length" "7")
14666 (set_attr "memory" "load")
14667 (set_attr "imm_disp" "false")])
14668
14669 (define_insn "*add_tp_si"
14670 [(set (match_operand:SI 0 "register_operand" "=r")
14671 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14672 (match_operand:SI 1 "register_operand" "0")))
14673 (clobber (reg:CC 17))]
14674 "!TARGET_64BIT"
14675 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14676 [(set_attr "type" "alu")
14677 (set_attr "modrm" "0")
14678 (set_attr "length" "7")
14679 (set_attr "memory" "load")
14680 (set_attr "imm_disp" "false")])
14681
14682 (define_insn "*load_tp_di"
14683 [(set (match_operand:DI 0 "register_operand" "=r")
14684 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14685 "TARGET_64BIT"
14686 "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14687 [(set_attr "type" "imov")
14688 (set_attr "modrm" "0")
14689 (set_attr "length" "7")
14690 (set_attr "memory" "load")
14691 (set_attr "imm_disp" "false")])
14692
14693 (define_insn "*add_tp_di"
14694 [(set (match_operand:DI 0 "register_operand" "=r")
14695 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14696 (match_operand:DI 1 "register_operand" "0")))
14697 (clobber (reg:CC 17))]
14698 "TARGET_64BIT"
14699 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14700 [(set_attr "type" "alu")
14701 (set_attr "modrm" "0")
14702 (set_attr "length" "7")
14703 (set_attr "memory" "load")
14704 (set_attr "imm_disp" "false")])
14705 \f
14706 ;; These patterns match the binary 387 instructions for addM3, subM3,
14707 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14708 ;; SFmode. The first is the normal insn, the second the same insn but
14709 ;; with one operand a conversion, and the third the same insn but with
14710 ;; the other operand a conversion. The conversion may be SFmode or
14711 ;; SImode if the target mode DFmode, but only SImode if the target mode
14712 ;; is SFmode.
14713
14714 ;; Gcc is slightly more smart about handling normal two address instructions
14715 ;; so use special patterns for add and mull.
14716 (define_insn "*fop_sf_comm_nosse"
14717 [(set (match_operand:SF 0 "register_operand" "=f")
14718 (match_operator:SF 3 "binary_fp_operator"
14719 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14720 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14721 "TARGET_80387 && !TARGET_SSE_MATH
14722 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14723 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14724 "* return output_387_binary_op (insn, operands);"
14725 [(set (attr "type")
14726 (if_then_else (match_operand:SF 3 "mult_operator" "")
14727 (const_string "fmul")
14728 (const_string "fop")))
14729 (set_attr "mode" "SF")])
14730
14731 (define_insn "*fop_sf_comm"
14732 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14733 (match_operator:SF 3 "binary_fp_operator"
14734 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14735 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14736 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14737 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14738 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14739 "* return output_387_binary_op (insn, operands);"
14740 [(set (attr "type")
14741 (if_then_else (eq_attr "alternative" "1")
14742 (if_then_else (match_operand:SF 3 "mult_operator" "")
14743 (const_string "ssemul")
14744 (const_string "sseadd"))
14745 (if_then_else (match_operand:SF 3 "mult_operator" "")
14746 (const_string "fmul")
14747 (const_string "fop"))))
14748 (set_attr "mode" "SF")])
14749
14750 (define_insn "*fop_sf_comm_sse"
14751 [(set (match_operand:SF 0 "register_operand" "=x")
14752 (match_operator:SF 3 "binary_fp_operator"
14753 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14754 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14755 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14756 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14757 "* return output_387_binary_op (insn, operands);"
14758 [(set (attr "type")
14759 (if_then_else (match_operand:SF 3 "mult_operator" "")
14760 (const_string "ssemul")
14761 (const_string "sseadd")))
14762 (set_attr "mode" "SF")])
14763
14764 (define_insn "*fop_df_comm_nosse"
14765 [(set (match_operand:DF 0 "register_operand" "=f")
14766 (match_operator:DF 3 "binary_fp_operator"
14767 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14768 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14769 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14770 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14771 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14772 "* return output_387_binary_op (insn, operands);"
14773 [(set (attr "type")
14774 (if_then_else (match_operand:SF 3 "mult_operator" "")
14775 (const_string "fmul")
14776 (const_string "fop")))
14777 (set_attr "mode" "DF")])
14778
14779 (define_insn "*fop_df_comm"
14780 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14781 (match_operator:DF 3 "binary_fp_operator"
14782 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14783 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14784 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14785 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14786 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14787 "* return output_387_binary_op (insn, operands);"
14788 [(set (attr "type")
14789 (if_then_else (eq_attr "alternative" "1")
14790 (if_then_else (match_operand:SF 3 "mult_operator" "")
14791 (const_string "ssemul")
14792 (const_string "sseadd"))
14793 (if_then_else (match_operand:SF 3 "mult_operator" "")
14794 (const_string "fmul")
14795 (const_string "fop"))))
14796 (set_attr "mode" "DF")])
14797
14798 (define_insn "*fop_df_comm_sse"
14799 [(set (match_operand:DF 0 "register_operand" "=Y")
14800 (match_operator:DF 3 "binary_fp_operator"
14801 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14802 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14803 "TARGET_SSE2 && TARGET_SSE_MATH
14804 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14805 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14806 "* return output_387_binary_op (insn, operands);"
14807 [(set (attr "type")
14808 (if_then_else (match_operand:SF 3 "mult_operator" "")
14809 (const_string "ssemul")
14810 (const_string "sseadd")))
14811 (set_attr "mode" "DF")])
14812
14813 (define_insn "*fop_xf_comm"
14814 [(set (match_operand:XF 0 "register_operand" "=f")
14815 (match_operator:XF 3 "binary_fp_operator"
14816 [(match_operand:XF 1 "register_operand" "%0")
14817 (match_operand:XF 2 "register_operand" "f")]))]
14818 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
14819 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14820 "* return output_387_binary_op (insn, operands);"
14821 [(set (attr "type")
14822 (if_then_else (match_operand:XF 3 "mult_operator" "")
14823 (const_string "fmul")
14824 (const_string "fop")))
14825 (set_attr "mode" "XF")])
14826
14827 (define_insn "*fop_tf_comm"
14828 [(set (match_operand:TF 0 "register_operand" "=f")
14829 (match_operator:TF 3 "binary_fp_operator"
14830 [(match_operand:TF 1 "register_operand" "%0")
14831 (match_operand:TF 2 "register_operand" "f")]))]
14832 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14833 "* return output_387_binary_op (insn, operands);"
14834 [(set (attr "type")
14835 (if_then_else (match_operand:TF 3 "mult_operator" "")
14836 (const_string "fmul")
14837 (const_string "fop")))
14838 (set_attr "mode" "XF")])
14839
14840 (define_insn "*fop_sf_1_nosse"
14841 [(set (match_operand:SF 0 "register_operand" "=f,f")
14842 (match_operator:SF 3 "binary_fp_operator"
14843 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14844 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14845 "TARGET_80387 && !TARGET_SSE_MATH
14846 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14847 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14848 "* return output_387_binary_op (insn, operands);"
14849 [(set (attr "type")
14850 (cond [(match_operand:SF 3 "mult_operator" "")
14851 (const_string "fmul")
14852 (match_operand:SF 3 "div_operator" "")
14853 (const_string "fdiv")
14854 ]
14855 (const_string "fop")))
14856 (set_attr "mode" "SF")])
14857
14858 (define_insn "*fop_sf_1"
14859 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14860 (match_operator:SF 3 "binary_fp_operator"
14861 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14862 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14863 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14864 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14865 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14866 "* return output_387_binary_op (insn, operands);"
14867 [(set (attr "type")
14868 (cond [(and (eq_attr "alternative" "2")
14869 (match_operand:SF 3 "mult_operator" ""))
14870 (const_string "ssemul")
14871 (and (eq_attr "alternative" "2")
14872 (match_operand:SF 3 "div_operator" ""))
14873 (const_string "ssediv")
14874 (eq_attr "alternative" "2")
14875 (const_string "sseadd")
14876 (match_operand:SF 3 "mult_operator" "")
14877 (const_string "fmul")
14878 (match_operand:SF 3 "div_operator" "")
14879 (const_string "fdiv")
14880 ]
14881 (const_string "fop")))
14882 (set_attr "mode" "SF")])
14883
14884 (define_insn "*fop_sf_1_sse"
14885 [(set (match_operand:SF 0 "register_operand" "=x")
14886 (match_operator:SF 3 "binary_fp_operator"
14887 [(match_operand:SF 1 "register_operand" "0")
14888 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14889 "TARGET_SSE_MATH
14890 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14891 "* return output_387_binary_op (insn, operands);"
14892 [(set (attr "type")
14893 (cond [(match_operand:SF 3 "mult_operator" "")
14894 (const_string "ssemul")
14895 (match_operand:SF 3 "div_operator" "")
14896 (const_string "ssediv")
14897 ]
14898 (const_string "sseadd")))
14899 (set_attr "mode" "SF")])
14900
14901 ;; ??? Add SSE splitters for these!
14902 (define_insn "*fop_sf_2"
14903 [(set (match_operand:SF 0 "register_operand" "=f,f")
14904 (match_operator:SF 3 "binary_fp_operator"
14905 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14906 (match_operand:SF 2 "register_operand" "0,0")]))]
14907 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14909 [(set (attr "type")
14910 (cond [(match_operand:SF 3 "mult_operator" "")
14911 (const_string "fmul")
14912 (match_operand:SF 3 "div_operator" "")
14913 (const_string "fdiv")
14914 ]
14915 (const_string "fop")))
14916 (set_attr "fp_int_src" "true")
14917 (set_attr "ppro_uops" "many")
14918 (set_attr "mode" "SI")])
14919
14920 (define_insn "*fop_sf_3"
14921 [(set (match_operand:SF 0 "register_operand" "=f,f")
14922 (match_operator:SF 3 "binary_fp_operator"
14923 [(match_operand:SF 1 "register_operand" "0,0")
14924 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14925 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14926 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14927 [(set (attr "type")
14928 (cond [(match_operand:SF 3 "mult_operator" "")
14929 (const_string "fmul")
14930 (match_operand:SF 3 "div_operator" "")
14931 (const_string "fdiv")
14932 ]
14933 (const_string "fop")))
14934 (set_attr "fp_int_src" "true")
14935 (set_attr "ppro_uops" "many")
14936 (set_attr "mode" "SI")])
14937
14938 (define_insn "*fop_df_1_nosse"
14939 [(set (match_operand:DF 0 "register_operand" "=f,f")
14940 (match_operator:DF 3 "binary_fp_operator"
14941 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14942 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14943 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14944 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14945 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14946 "* return output_387_binary_op (insn, operands);"
14947 [(set (attr "type")
14948 (cond [(match_operand:DF 3 "mult_operator" "")
14949 (const_string "fmul")
14950 (match_operand:DF 3 "div_operator" "")
14951 (const_string "fdiv")
14952 ]
14953 (const_string "fop")))
14954 (set_attr "mode" "DF")])
14955
14956
14957 (define_insn "*fop_df_1"
14958 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14959 (match_operator:DF 3 "binary_fp_operator"
14960 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14961 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14962 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14963 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14964 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14965 "* return output_387_binary_op (insn, operands);"
14966 [(set (attr "type")
14967 (cond [(and (eq_attr "alternative" "2")
14968 (match_operand:SF 3 "mult_operator" ""))
14969 (const_string "ssemul")
14970 (and (eq_attr "alternative" "2")
14971 (match_operand:SF 3 "div_operator" ""))
14972 (const_string "ssediv")
14973 (eq_attr "alternative" "2")
14974 (const_string "sseadd")
14975 (match_operand:DF 3 "mult_operator" "")
14976 (const_string "fmul")
14977 (match_operand:DF 3 "div_operator" "")
14978 (const_string "fdiv")
14979 ]
14980 (const_string "fop")))
14981 (set_attr "mode" "DF")])
14982
14983 (define_insn "*fop_df_1_sse"
14984 [(set (match_operand:DF 0 "register_operand" "=Y")
14985 (match_operator:DF 3 "binary_fp_operator"
14986 [(match_operand:DF 1 "register_operand" "0")
14987 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14988 "TARGET_SSE2 && TARGET_SSE_MATH
14989 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14990 "* return output_387_binary_op (insn, operands);"
14991 [(set_attr "mode" "DF")
14992 (set (attr "type")
14993 (cond [(match_operand:SF 3 "mult_operator" "")
14994 (const_string "ssemul")
14995 (match_operand:SF 3 "div_operator" "")
14996 (const_string "ssediv")
14997 ]
14998 (const_string "sseadd")))])
14999
15000 ;; ??? Add SSE splitters for these!
15001 (define_insn "*fop_df_2"
15002 [(set (match_operand:DF 0 "register_operand" "=f,f")
15003 (match_operator:DF 3 "binary_fp_operator"
15004 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15005 (match_operand:DF 2 "register_operand" "0,0")]))]
15006 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15007 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15008 [(set (attr "type")
15009 (cond [(match_operand:DF 3 "mult_operator" "")
15010 (const_string "fmul")
15011 (match_operand:DF 3 "div_operator" "")
15012 (const_string "fdiv")
15013 ]
15014 (const_string "fop")))
15015 (set_attr "fp_int_src" "true")
15016 (set_attr "ppro_uops" "many")
15017 (set_attr "mode" "SI")])
15018
15019 (define_insn "*fop_df_3"
15020 [(set (match_operand:DF 0 "register_operand" "=f,f")
15021 (match_operator:DF 3 "binary_fp_operator"
15022 [(match_operand:DF 1 "register_operand" "0,0")
15023 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15024 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15025 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15026 [(set (attr "type")
15027 (cond [(match_operand:DF 3 "mult_operator" "")
15028 (const_string "fmul")
15029 (match_operand:DF 3 "div_operator" "")
15030 (const_string "fdiv")
15031 ]
15032 (const_string "fop")))
15033 (set_attr "fp_int_src" "true")
15034 (set_attr "ppro_uops" "many")
15035 (set_attr "mode" "SI")])
15036
15037 (define_insn "*fop_df_4"
15038 [(set (match_operand:DF 0 "register_operand" "=f,f")
15039 (match_operator:DF 3 "binary_fp_operator"
15040 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15041 (match_operand:DF 2 "register_operand" "0,f")]))]
15042 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
15043 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15044 "* return output_387_binary_op (insn, operands);"
15045 [(set (attr "type")
15046 (cond [(match_operand:DF 3 "mult_operator" "")
15047 (const_string "fmul")
15048 (match_operand:DF 3 "div_operator" "")
15049 (const_string "fdiv")
15050 ]
15051 (const_string "fop")))
15052 (set_attr "mode" "SF")])
15053
15054 (define_insn "*fop_df_5"
15055 [(set (match_operand:DF 0 "register_operand" "=f,f")
15056 (match_operator:DF 3 "binary_fp_operator"
15057 [(match_operand:DF 1 "register_operand" "0,f")
15058 (float_extend:DF
15059 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15060 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15061 "* return output_387_binary_op (insn, operands);"
15062 [(set (attr "type")
15063 (cond [(match_operand:DF 3 "mult_operator" "")
15064 (const_string "fmul")
15065 (match_operand:DF 3 "div_operator" "")
15066 (const_string "fdiv")
15067 ]
15068 (const_string "fop")))
15069 (set_attr "mode" "SF")])
15070
15071 (define_insn "*fop_df_6"
15072 [(set (match_operand:DF 0 "register_operand" "=f,f")
15073 (match_operator:DF 3 "binary_fp_operator"
15074 [(float_extend:DF
15075 (match_operand:SF 1 "register_operand" "0,f"))
15076 (float_extend:DF
15077 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15078 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15079 "* return output_387_binary_op (insn, operands);"
15080 [(set (attr "type")
15081 (cond [(match_operand:DF 3 "mult_operator" "")
15082 (const_string "fmul")
15083 (match_operand:DF 3 "div_operator" "")
15084 (const_string "fdiv")
15085 ]
15086 (const_string "fop")))
15087 (set_attr "mode" "SF")])
15088
15089 (define_insn "*fop_xf_1"
15090 [(set (match_operand:XF 0 "register_operand" "=f,f")
15091 (match_operator:XF 3 "binary_fp_operator"
15092 [(match_operand:XF 1 "register_operand" "0,f")
15093 (match_operand:XF 2 "register_operand" "f,0")]))]
15094 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
15095 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15096 "* return output_387_binary_op (insn, operands);"
15097 [(set (attr "type")
15098 (cond [(match_operand:XF 3 "mult_operator" "")
15099 (const_string "fmul")
15100 (match_operand:XF 3 "div_operator" "")
15101 (const_string "fdiv")
15102 ]
15103 (const_string "fop")))
15104 (set_attr "mode" "XF")])
15105
15106 (define_insn "*fop_tf_1"
15107 [(set (match_operand:TF 0 "register_operand" "=f,f")
15108 (match_operator:TF 3 "binary_fp_operator"
15109 [(match_operand:TF 1 "register_operand" "0,f")
15110 (match_operand:TF 2 "register_operand" "f,0")]))]
15111 "TARGET_80387
15112 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15113 "* return output_387_binary_op (insn, operands);"
15114 [(set (attr "type")
15115 (cond [(match_operand:TF 3 "mult_operator" "")
15116 (const_string "fmul")
15117 (match_operand:TF 3 "div_operator" "")
15118 (const_string "fdiv")
15119 ]
15120 (const_string "fop")))
15121 (set_attr "mode" "XF")])
15122
15123 (define_insn "*fop_xf_2"
15124 [(set (match_operand:XF 0 "register_operand" "=f,f")
15125 (match_operator:XF 3 "binary_fp_operator"
15126 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15127 (match_operand:XF 2 "register_operand" "0,0")]))]
15128 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15129 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15130 [(set (attr "type")
15131 (cond [(match_operand:XF 3 "mult_operator" "")
15132 (const_string "fmul")
15133 (match_operand:XF 3 "div_operator" "")
15134 (const_string "fdiv")
15135 ]
15136 (const_string "fop")))
15137 (set_attr "fp_int_src" "true")
15138 (set_attr "mode" "SI")
15139 (set_attr "ppro_uops" "many")])
15140
15141 (define_insn "*fop_tf_2"
15142 [(set (match_operand:TF 0 "register_operand" "=f,f")
15143 (match_operator:TF 3 "binary_fp_operator"
15144 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15145 (match_operand:TF 2 "register_operand" "0,0")]))]
15146 "TARGET_80387 && TARGET_USE_FIOP"
15147 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15148 [(set (attr "type")
15149 (cond [(match_operand:TF 3 "mult_operator" "")
15150 (const_string "fmul")
15151 (match_operand:TF 3 "div_operator" "")
15152 (const_string "fdiv")
15153 ]
15154 (const_string "fop")))
15155 (set_attr "fp_int_src" "true")
15156 (set_attr "mode" "SI")
15157 (set_attr "ppro_uops" "many")])
15158
15159 (define_insn "*fop_xf_3"
15160 [(set (match_operand:XF 0 "register_operand" "=f,f")
15161 (match_operator:XF 3 "binary_fp_operator"
15162 [(match_operand:XF 1 "register_operand" "0,0")
15163 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15164 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15165 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15166 [(set (attr "type")
15167 (cond [(match_operand:XF 3 "mult_operator" "")
15168 (const_string "fmul")
15169 (match_operand:XF 3 "div_operator" "")
15170 (const_string "fdiv")
15171 ]
15172 (const_string "fop")))
15173 (set_attr "fp_int_src" "true")
15174 (set_attr "mode" "SI")
15175 (set_attr "ppro_uops" "many")])
15176
15177 (define_insn "*fop_tf_3"
15178 [(set (match_operand:TF 0 "register_operand" "=f,f")
15179 (match_operator:TF 3 "binary_fp_operator"
15180 [(match_operand:TF 1 "register_operand" "0,0")
15181 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15182 "TARGET_80387 && TARGET_USE_FIOP"
15183 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15184 [(set (attr "type")
15185 (cond [(match_operand:TF 3 "mult_operator" "")
15186 (const_string "fmul")
15187 (match_operand:TF 3 "div_operator" "")
15188 (const_string "fdiv")
15189 ]
15190 (const_string "fop")))
15191 (set_attr "fp_int_src" "true")
15192 (set_attr "mode" "SI")
15193 (set_attr "ppro_uops" "many")])
15194
15195 (define_insn "*fop_xf_4"
15196 [(set (match_operand:XF 0 "register_operand" "=f,f")
15197 (match_operator:XF 3 "binary_fp_operator"
15198 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15199 (match_operand:XF 2 "register_operand" "0,f")]))]
15200 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15201 "* return output_387_binary_op (insn, operands);"
15202 [(set (attr "type")
15203 (cond [(match_operand:XF 3 "mult_operator" "")
15204 (const_string "fmul")
15205 (match_operand:XF 3 "div_operator" "")
15206 (const_string "fdiv")
15207 ]
15208 (const_string "fop")))
15209 (set_attr "mode" "SF")])
15210
15211 (define_insn "*fop_tf_4"
15212 [(set (match_operand:TF 0 "register_operand" "=f,f")
15213 (match_operator:TF 3 "binary_fp_operator"
15214 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15215 (match_operand:TF 2 "register_operand" "0,f")]))]
15216 "TARGET_80387"
15217 "* return output_387_binary_op (insn, operands);"
15218 [(set (attr "type")
15219 (cond [(match_operand:TF 3 "mult_operator" "")
15220 (const_string "fmul")
15221 (match_operand:TF 3 "div_operator" "")
15222 (const_string "fdiv")
15223 ]
15224 (const_string "fop")))
15225 (set_attr "mode" "SF")])
15226
15227 (define_insn "*fop_xf_5"
15228 [(set (match_operand:XF 0 "register_operand" "=f,f")
15229 (match_operator:XF 3 "binary_fp_operator"
15230 [(match_operand:XF 1 "register_operand" "0,f")
15231 (float_extend:XF
15232 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15233 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15234 "* return output_387_binary_op (insn, operands);"
15235 [(set (attr "type")
15236 (cond [(match_operand:XF 3 "mult_operator" "")
15237 (const_string "fmul")
15238 (match_operand:XF 3 "div_operator" "")
15239 (const_string "fdiv")
15240 ]
15241 (const_string "fop")))
15242 (set_attr "mode" "SF")])
15243
15244 (define_insn "*fop_tf_5"
15245 [(set (match_operand:TF 0 "register_operand" "=f,f")
15246 (match_operator:TF 3 "binary_fp_operator"
15247 [(match_operand:TF 1 "register_operand" "0,f")
15248 (float_extend:TF
15249 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15250 "TARGET_80387"
15251 "* return output_387_binary_op (insn, operands);"
15252 [(set (attr "type")
15253 (cond [(match_operand:TF 3 "mult_operator" "")
15254 (const_string "fmul")
15255 (match_operand:TF 3 "div_operator" "")
15256 (const_string "fdiv")
15257 ]
15258 (const_string "fop")))
15259 (set_attr "mode" "SF")])
15260
15261 (define_insn "*fop_xf_6"
15262 [(set (match_operand:XF 0 "register_operand" "=f,f")
15263 (match_operator:XF 3 "binary_fp_operator"
15264 [(float_extend:XF
15265 (match_operand 1 "register_operand" "0,f"))
15266 (float_extend:XF
15267 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15268 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15269 "* return output_387_binary_op (insn, operands);"
15270 [(set (attr "type")
15271 (cond [(match_operand:XF 3 "mult_operator" "")
15272 (const_string "fmul")
15273 (match_operand:XF 3 "div_operator" "")
15274 (const_string "fdiv")
15275 ]
15276 (const_string "fop")))
15277 (set_attr "mode" "SF")])
15278
15279 (define_insn "*fop_tf_6"
15280 [(set (match_operand:TF 0 "register_operand" "=f,f")
15281 (match_operator:TF 3 "binary_fp_operator"
15282 [(float_extend:TF
15283 (match_operand 1 "register_operand" "0,f"))
15284 (float_extend:TF
15285 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15286 "TARGET_80387"
15287 "* return output_387_binary_op (insn, operands);"
15288 [(set (attr "type")
15289 (cond [(match_operand:TF 3 "mult_operator" "")
15290 (const_string "fmul")
15291 (match_operand:TF 3 "div_operator" "")
15292 (const_string "fdiv")
15293 ]
15294 (const_string "fop")))
15295 (set_attr "mode" "SF")])
15296
15297 (define_split
15298 [(set (match_operand 0 "register_operand" "")
15299 (match_operator 3 "binary_fp_operator"
15300 [(float (match_operand:SI 1 "register_operand" ""))
15301 (match_operand 2 "register_operand" "")]))]
15302 "TARGET_80387 && reload_completed
15303 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15304 [(const_int 0)]
15305 {
15306 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15307 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15308 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15309 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15310 GET_MODE (operands[3]),
15311 operands[4],
15312 operands[2])));
15313 ix86_free_from_memory (GET_MODE (operands[1]));
15314 DONE;
15315 })
15316
15317 (define_split
15318 [(set (match_operand 0 "register_operand" "")
15319 (match_operator 3 "binary_fp_operator"
15320 [(match_operand 1 "register_operand" "")
15321 (float (match_operand:SI 2 "register_operand" ""))]))]
15322 "TARGET_80387 && reload_completed
15323 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15324 [(const_int 0)]
15325 {
15326 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15327 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15328 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15329 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15330 GET_MODE (operands[3]),
15331 operands[1],
15332 operands[4])));
15333 ix86_free_from_memory (GET_MODE (operands[2]));
15334 DONE;
15335 })
15336 \f
15337 ;; FPU special functions.
15338
15339 (define_expand "sqrtsf2"
15340 [(set (match_operand:SF 0 "register_operand" "")
15341 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15342 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15343 {
15344 if (!TARGET_SSE_MATH)
15345 operands[1] = force_reg (SFmode, operands[1]);
15346 })
15347
15348 (define_insn "sqrtsf2_1"
15349 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15350 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15351 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15352 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15353 "@
15354 fsqrt
15355 sqrtss\t{%1, %0|%0, %1}"
15356 [(set_attr "type" "fpspc,sse")
15357 (set_attr "mode" "SF,SF")
15358 (set_attr "athlon_decode" "direct,*")])
15359
15360 (define_insn "sqrtsf2_1_sse_only"
15361 [(set (match_operand:SF 0 "register_operand" "=x")
15362 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15363 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15364 "sqrtss\t{%1, %0|%0, %1}"
15365 [(set_attr "type" "sse")
15366 (set_attr "mode" "SF")
15367 (set_attr "athlon_decode" "*")])
15368
15369 (define_insn "sqrtsf2_i387"
15370 [(set (match_operand:SF 0 "register_operand" "=f")
15371 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15372 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15373 && !TARGET_SSE_MATH"
15374 "fsqrt"
15375 [(set_attr "type" "fpspc")
15376 (set_attr "mode" "SF")
15377 (set_attr "athlon_decode" "direct")])
15378
15379 (define_expand "sqrtdf2"
15380 [(set (match_operand:DF 0 "register_operand" "")
15381 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15382 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15383 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15384 {
15385 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15386 operands[1] = force_reg (DFmode, operands[1]);
15387 })
15388
15389 (define_insn "sqrtdf2_1"
15390 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15391 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15392 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15393 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15394 "@
15395 fsqrt
15396 sqrtsd\t{%1, %0|%0, %1}"
15397 [(set_attr "type" "fpspc,sse")
15398 (set_attr "mode" "DF,DF")
15399 (set_attr "athlon_decode" "direct,*")])
15400
15401 (define_insn "sqrtdf2_1_sse_only"
15402 [(set (match_operand:DF 0 "register_operand" "=Y")
15403 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15404 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15405 "sqrtsd\t{%1, %0|%0, %1}"
15406 [(set_attr "type" "sse")
15407 (set_attr "mode" "DF")
15408 (set_attr "athlon_decode" "*")])
15409
15410 (define_insn "sqrtdf2_i387"
15411 [(set (match_operand:DF 0 "register_operand" "=f")
15412 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15413 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15414 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15415 "fsqrt"
15416 [(set_attr "type" "fpspc")
15417 (set_attr "mode" "DF")
15418 (set_attr "athlon_decode" "direct")])
15419
15420 (define_insn "*sqrtextendsfdf2"
15421 [(set (match_operand:DF 0 "register_operand" "=f")
15422 (sqrt:DF (float_extend:DF
15423 (match_operand:SF 1 "register_operand" "0"))))]
15424 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15425 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15426 "fsqrt"
15427 [(set_attr "type" "fpspc")
15428 (set_attr "mode" "DF")
15429 (set_attr "athlon_decode" "direct")])
15430
15431 (define_insn "sqrtxf2"
15432 [(set (match_operand:XF 0 "register_operand" "=f")
15433 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15434 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15435 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15436 "fsqrt"
15437 [(set_attr "type" "fpspc")
15438 (set_attr "mode" "XF")
15439 (set_attr "athlon_decode" "direct")])
15440
15441 (define_insn "sqrttf2"
15442 [(set (match_operand:TF 0 "register_operand" "=f")
15443 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15444 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15445 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15446 "fsqrt"
15447 [(set_attr "type" "fpspc")
15448 (set_attr "mode" "XF")
15449 (set_attr "athlon_decode" "direct")])
15450
15451 (define_insn "*sqrtextenddfxf2"
15452 [(set (match_operand:XF 0 "register_operand" "=f")
15453 (sqrt:XF (float_extend:XF
15454 (match_operand:DF 1 "register_operand" "0"))))]
15455 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15456 "fsqrt"
15457 [(set_attr "type" "fpspc")
15458 (set_attr "mode" "XF")
15459 (set_attr "athlon_decode" "direct")])
15460
15461 (define_insn "*sqrtextenddftf2"
15462 [(set (match_operand:TF 0 "register_operand" "=f")
15463 (sqrt:TF (float_extend:TF
15464 (match_operand:DF 1 "register_operand" "0"))))]
15465 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15466 "fsqrt"
15467 [(set_attr "type" "fpspc")
15468 (set_attr "mode" "XF")
15469 (set_attr "athlon_decode" "direct")])
15470
15471 (define_insn "*sqrtextendsfxf2"
15472 [(set (match_operand:XF 0 "register_operand" "=f")
15473 (sqrt:XF (float_extend:XF
15474 (match_operand:SF 1 "register_operand" "0"))))]
15475 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15476 "fsqrt"
15477 [(set_attr "type" "fpspc")
15478 (set_attr "mode" "XF")
15479 (set_attr "athlon_decode" "direct")])
15480
15481 (define_insn "*sqrtextendsftf2"
15482 [(set (match_operand:TF 0 "register_operand" "=f")
15483 (sqrt:TF (float_extend:TF
15484 (match_operand:SF 1 "register_operand" "0"))))]
15485 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15486 "fsqrt"
15487 [(set_attr "type" "fpspc")
15488 (set_attr "mode" "XF")
15489 (set_attr "athlon_decode" "direct")])
15490
15491 (define_insn "sindf2"
15492 [(set (match_operand:DF 0 "register_operand" "=f")
15493 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15494 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15495 && flag_unsafe_math_optimizations"
15496 "fsin"
15497 [(set_attr "type" "fpspc")
15498 (set_attr "mode" "DF")])
15499
15500 (define_insn "sinsf2"
15501 [(set (match_operand:SF 0 "register_operand" "=f")
15502 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15503 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15504 && flag_unsafe_math_optimizations"
15505 "fsin"
15506 [(set_attr "type" "fpspc")
15507 (set_attr "mode" "SF")])
15508
15509 (define_insn "*sinextendsfdf2"
15510 [(set (match_operand:DF 0 "register_operand" "=f")
15511 (unspec:DF [(float_extend:DF
15512 (match_operand:SF 1 "register_operand" "0"))]
15513 UNSPEC_SIN))]
15514 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15515 && flag_unsafe_math_optimizations"
15516 "fsin"
15517 [(set_attr "type" "fpspc")
15518 (set_attr "mode" "DF")])
15519
15520 (define_insn "sinxf2"
15521 [(set (match_operand:XF 0 "register_operand" "=f")
15522 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15523 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15524 && flag_unsafe_math_optimizations"
15525 "fsin"
15526 [(set_attr "type" "fpspc")
15527 (set_attr "mode" "XF")])
15528
15529 (define_insn "sintf2"
15530 [(set (match_operand:TF 0 "register_operand" "=f")
15531 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15532 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15533 && flag_unsafe_math_optimizations"
15534 "fsin"
15535 [(set_attr "type" "fpspc")
15536 (set_attr "mode" "XF")])
15537
15538 (define_insn "cosdf2"
15539 [(set (match_operand:DF 0 "register_operand" "=f")
15540 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15541 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15542 && flag_unsafe_math_optimizations"
15543 "fcos"
15544 [(set_attr "type" "fpspc")
15545 (set_attr "mode" "DF")])
15546
15547 (define_insn "cossf2"
15548 [(set (match_operand:SF 0 "register_operand" "=f")
15549 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15550 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15551 && flag_unsafe_math_optimizations"
15552 "fcos"
15553 [(set_attr "type" "fpspc")
15554 (set_attr "mode" "SF")])
15555
15556 (define_insn "*cosextendsfdf2"
15557 [(set (match_operand:DF 0 "register_operand" "=f")
15558 (unspec:DF [(float_extend:DF
15559 (match_operand:SF 1 "register_operand" "0"))]
15560 UNSPEC_COS))]
15561 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15562 && flag_unsafe_math_optimizations"
15563 "fcos"
15564 [(set_attr "type" "fpspc")
15565 (set_attr "mode" "DF")])
15566
15567 (define_insn "cosxf2"
15568 [(set (match_operand:XF 0 "register_operand" "=f")
15569 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15570 "!TARGET_128BIT_LONG_DOUBLE && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15571 && flag_unsafe_math_optimizations"
15572 "fcos"
15573 [(set_attr "type" "fpspc")
15574 (set_attr "mode" "XF")])
15575
15576 (define_insn "costf2"
15577 [(set (match_operand:TF 0 "register_operand" "=f")
15578 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15579 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15580 && flag_unsafe_math_optimizations"
15581 "fcos"
15582 [(set_attr "type" "fpspc")
15583 (set_attr "mode" "XF")])
15584
15585 (define_insn "atan2df3"
15586 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15587 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15588 (match_operand:DF 1 "register_operand" "u")]
15589 UNSPEC_FPATAN))
15590 (clobber (match_dup 1))])]
15591 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15592 && flag_unsafe_math_optimizations"
15593 "fpatan"
15594 [(set_attr "type" "fpspc")
15595 (set_attr "mode" "DF")])
15596
15597 (define_insn "atan2sf3"
15598 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15599 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15600 (match_operand:SF 1 "register_operand" "u")]
15601 UNSPEC_FPATAN))
15602 (clobber (match_dup 1))])]
15603 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15604 && flag_unsafe_math_optimizations"
15605 "fpatan"
15606 [(set_attr "type" "fpspc")
15607 (set_attr "mode" "SF")])
15608
15609 (define_insn "atan2xf3"
15610 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15611 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15612 (match_operand:XF 1 "register_operand" "u")]
15613 UNSPEC_FPATAN))
15614 (clobber (match_dup 1))])]
15615 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15616 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15617 "fpatan"
15618 [(set_attr "type" "fpspc")
15619 (set_attr "mode" "XF")])
15620
15621 (define_insn "atan2tf3"
15622 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15623 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15624 (match_operand:TF 1 "register_operand" "u")]
15625 UNSPEC_FPATAN))
15626 (clobber (match_dup 1))])]
15627 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15628 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15629 "fpatan"
15630 [(set_attr "type" "fpspc")
15631 (set_attr "mode" "XF")])
15632
15633 (define_insn "*fyl2x_sfxf3"
15634 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15635 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15636 (match_operand 1 "register_operand" "u")]
15637 UNSPEC_FYL2X))
15638 (clobber (match_dup 1))])]
15639 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15640 && flag_unsafe_math_optimizations
15641 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15642 "fyl2x"
15643 [(set_attr "type" "fpspc")
15644 (set_attr "mode" "SF")])
15645
15646 (define_insn "*fyl2x_dfxf3"
15647 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15648 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15649 (match_operand 1 "register_operand" "u")]
15650 UNSPEC_FYL2X))
15651 (clobber (match_dup 1))])]
15652 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15653 && flag_unsafe_math_optimizations
15654 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15655 "fyl2x"
15656 [(set_attr "type" "fpspc")
15657 (set_attr "mode" "DF")])
15658
15659 (define_insn "*fyl2x_xf3"
15660 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15661 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15662 (match_operand:XF 1 "register_operand" "u")]
15663 UNSPEC_FYL2X))
15664 (clobber (match_dup 1))])]
15665 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15666 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15667 "fyl2x"
15668 [(set_attr "type" "fpspc")
15669 (set_attr "mode" "XF")])
15670
15671 (define_insn "*fyl2x_tfxf3"
15672 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15673 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15674 (match_operand:TF 1 "register_operand" "u")]
15675 UNSPEC_FYL2X))
15676 (clobber (match_dup 1))])]
15677 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15678 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15679 "fyl2x"
15680 [(set_attr "type" "fpspc")
15681 (set_attr "mode" "XF")])
15682
15683 (define_expand "logsf2"
15684 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15685 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15686 (match_dup 2)] UNSPEC_FYL2X))
15687 (clobber (match_dup 2))])]
15688 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15689 && flag_unsafe_math_optimizations"
15690 {
15691 rtx temp;
15692
15693 operands[2] = gen_reg_rtx (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode);
15694 temp = standard_80387_constant_rtx (4); /* fldln2 */
15695 emit_move_insn (operands[2], temp);
15696 })
15697
15698 (define_expand "logdf2"
15699 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15700 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15701 (match_dup 2)] UNSPEC_FYL2X))
15702 (clobber (match_dup 2))])]
15703 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15704 && flag_unsafe_math_optimizations"
15705 {
15706 rtx temp;
15707
15708 operands[2] = gen_reg_rtx (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode);
15709 temp = standard_80387_constant_rtx (4); /* fldln2 */
15710 emit_move_insn (operands[2], temp);
15711 })
15712
15713 (define_expand "logxf2"
15714 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15715 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15716 (match_dup 2)] UNSPEC_FYL2X))
15717 (clobber (match_dup 2))])]
15718 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15719 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15720 {
15721 rtx temp;
15722
15723 operands[2] = gen_reg_rtx (XFmode);
15724 temp = standard_80387_constant_rtx (4); /* fldln2 */
15725 emit_move_insn (operands[2], temp);
15726 })
15727
15728 (define_expand "logtf2"
15729 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15730 (unspec:TF [(match_operand:TF 1 "register_operand" "")
15731 (match_dup 2)] UNSPEC_FYL2X))
15732 (clobber (match_dup 2))])]
15733 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15734 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15735 {
15736 rtx temp;
15737
15738 operands[2] = gen_reg_rtx (TFmode);
15739 temp = standard_80387_constant_rtx (4); /* fldln2 */
15740 emit_move_insn (operands[2], temp);
15741 })
15742
15743 (define_insn "*fscale_sfxf3"
15744 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15745 (unspec:SF [(match_operand 2 "register_operand" "0")
15746 (match_operand 1 "register_operand" "u")]
15747 UNSPEC_FSCALE))
15748 (clobber (match_dup 1))])]
15749 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15750 && flag_unsafe_math_optimizations
15751 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)
15752 && GET_MODE (operands[2]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15753 "fscale\;fstp\t%y1"
15754 [(set_attr "type" "fpspc")
15755 (set_attr "mode" "SF")])
15756
15757 (define_insn "*fscale_dfxf3"
15758 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15759 (unspec:DF [(match_operand 2 "register_operand" "0")
15760 (match_operand 1 "register_operand" "u")]
15761 UNSPEC_FSCALE))
15762 (clobber (match_dup 1))])]
15763 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15764 && flag_unsafe_math_optimizations
15765 && GET_MODE (operands[1]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)
15766 && GET_MODE (operands[2]) == (TARGET_128BIT_LONG_DOUBLE ? TFmode : XFmode)"
15767 "fscale\;fstp\t%y1"
15768 [(set_attr "type" "fpspc")
15769 (set_attr "mode" "DF")])
15770
15771 (define_insn "*fscale_xf3"
15772 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15773 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15774 (match_operand:XF 1 "register_operand" "u")]
15775 UNSPEC_FSCALE))
15776 (clobber (match_dup 1))])]
15777 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15778 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15779 "fscale\;fstp\t%y1"
15780 [(set_attr "type" "fpspc")
15781 (set_attr "mode" "XF")])
15782
15783 (define_insn "*fscale_tf3"
15784 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15785 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15786 (match_operand:TF 1 "register_operand" "u")]
15787 UNSPEC_FSCALE))
15788 (clobber (match_dup 1))])]
15789 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15790 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15791 "fscale\;fstp\t%y1"
15792 [(set_attr "type" "fpspc")
15793 (set_attr "mode" "XF")])
15794
15795 (define_insn "*frndintxf2"
15796 [(set (match_operand:XF 0 "register_operand" "=f")
15797 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15798 UNSPEC_FRNDINT))]
15799 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15800 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15801 "frndint"
15802 [(set_attr "type" "fpspc")
15803 (set_attr "mode" "XF")])
15804
15805 (define_insn "*frndinttf2"
15806 [(set (match_operand:TF 0 "register_operand" "=f")
15807 (unspec:TF [(match_operand:TF 1 "register_operand" "0")]
15808 UNSPEC_FRNDINT))]
15809 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15810 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15811 "frndint"
15812 [(set_attr "type" "fpspc")
15813 (set_attr "mode" "XF")])
15814
15815 (define_insn "*f2xm1xf2"
15816 [(set (match_operand:XF 0 "register_operand" "=f")
15817 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15818 UNSPEC_F2XM1))]
15819 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15820 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15821 "f2xm1"
15822 [(set_attr "type" "fpspc")
15823 (set_attr "mode" "XF")])
15824
15825 (define_insn "*f2xm1tf2"
15826 [(set (match_operand:TF 0 "register_operand" "=f")
15827 (unspec:TF [(match_operand:TF 1 "register_operand" "0")]
15828 UNSPEC_F2XM1))]
15829 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15830 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15831 "f2xm1"
15832 [(set_attr "type" "fpspc")
15833 (set_attr "mode" "XF")])
15834
15835 (define_expand "expsf2"
15836 [(set (match_dup 2)
15837 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15838 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15839 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15840 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15841 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15842 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15843 (parallel [(set (match_operand:SF 0 "register_operand" "")
15844 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15845 (clobber (match_dup 5))])]
15846 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15847 && flag_unsafe_math_optimizations"
15848 {
15849 rtx temp;
15850 int i;
15851
15852 if (TARGET_128BIT_LONG_DOUBLE)
15853 {
15854 emit_insn (gen_expsf2_tf (operands[0], operands[1]));
15855 DONE;
15856 }
15857
15858 for (i=2; i<10; i++)
15859 operands[i] = gen_reg_rtx (XFmode);
15860 temp = standard_80387_constant_rtx (5); /* fldl2e */
15861 emit_move_insn (operands[3], temp);
15862 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15863 })
15864
15865 (define_expand "expsf2_tf"
15866 [(set (match_dup 2)
15867 (float_extend:TF (match_operand:SF 1 "register_operand" "")))
15868 (set (match_dup 4) (mult:TF (match_dup 2) (match_dup 3)))
15869 (set (match_dup 5) (unspec:TF [(match_dup 4)] UNSPEC_FRNDINT))
15870 (set (match_dup 6) (minus:TF (match_dup 4) (match_dup 5)))
15871 (set (match_dup 7) (unspec:TF [(match_dup 6)] UNSPEC_F2XM1))
15872 (set (match_dup 9) (plus:TF (match_dup 7) (match_dup 8)))
15873 (parallel [(set (match_operand:SF 0 "register_operand" "")
15874 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15875 (clobber (match_dup 5))])]
15876 ""
15877 {
15878 rtx temp;
15879 int i;
15880
15881 for (i=2; i<10; i++)
15882 operands[i] = gen_reg_rtx (TFmode);
15883 temp = standard_80387_constant_rtx (5); /* fldl2e */
15884 emit_move_insn (operands[3], temp);
15885 emit_move_insn (operands[8], CONST1_RTX (TFmode)); /* fld1 */
15886 })
15887
15888 (define_expand "expdf2"
15889 [(set (match_dup 2)
15890 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15891 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15892 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15893 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15894 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15895 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15896 (parallel [(set (match_operand:DF 0 "register_operand" "")
15897 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15898 (clobber (match_dup 5))])]
15899 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15900 && flag_unsafe_math_optimizations"
15901 {
15902 rtx temp;
15903 int i;
15904
15905 if (TARGET_128BIT_LONG_DOUBLE)
15906 {
15907 emit_insn (gen_expdf2_tf (operands[0], operands[1]));
15908 DONE;
15909 }
15910
15911 for (i=2; i<10; i++)
15912 operands[i] = gen_reg_rtx (XFmode);
15913 temp = standard_80387_constant_rtx (5); /* fldl2e */
15914 emit_move_insn (operands[3], temp);
15915 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15916 })
15917
15918
15919 (define_expand "expdf2_tf"
15920 [(set (match_dup 2)
15921 (float_extend:TF (match_operand:DF 1 "register_operand" "")))
15922 (set (match_dup 4) (mult:TF (match_dup 2) (match_dup 3)))
15923 (set (match_dup 5) (unspec:TF [(match_dup 4)] UNSPEC_FRNDINT))
15924 (set (match_dup 6) (minus:TF (match_dup 4) (match_dup 5)))
15925 (set (match_dup 7) (unspec:TF [(match_dup 6)] UNSPEC_F2XM1))
15926 (set (match_dup 9) (plus:TF (match_dup 7) (match_dup 8)))
15927 (parallel [(set (match_operand:DF 0 "register_operand" "")
15928 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15929 (clobber (match_dup 5))])]
15930 ""
15931 {
15932 rtx temp;
15933 int i;
15934
15935 for (i=2; i<10; i++)
15936 operands[i] = gen_reg_rtx (TFmode);
15937 temp = standard_80387_constant_rtx (5); /* fldl2e */
15938 emit_move_insn (operands[3], temp);
15939 emit_move_insn (operands[8], CONST1_RTX (TFmode)); /* fld1 */
15940 })
15941
15942 (define_expand "expxf2"
15943 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15944 (match_dup 2)))
15945 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15946 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15947 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15948 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15949 (parallel [(set (match_operand:XF 0 "register_operand" "")
15950 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15951 (clobber (match_dup 4))])]
15952 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15953 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
15954 {
15955 rtx temp;
15956 int i;
15957
15958 for (i=2; i<9; i++)
15959 operands[i] = gen_reg_rtx (XFmode);
15960 temp = standard_80387_constant_rtx (5); /* fldl2e */
15961 emit_move_insn (operands[2], temp);
15962 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15963 })
15964
15965 (define_expand "atansf2"
15966 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15967 (unspec:SF [(match_dup 2)
15968 (match_operand:SF 1 "register_operand" "")]
15969 UNSPEC_FPATAN))
15970 (clobber (match_dup 1))])]
15971 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15972 && flag_unsafe_math_optimizations"
15973 {
15974 operands[2] = gen_reg_rtx (SFmode);
15975 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15976 })
15977
15978 (define_expand "exptf2"
15979 [(set (match_dup 3) (mult:TF (match_operand:TF 1 "register_operand" "")
15980 (match_dup 2)))
15981 (set (match_dup 4) (unspec:TF [(match_dup 3)] UNSPEC_FRNDINT))
15982 (set (match_dup 5) (minus:TF (match_dup 3) (match_dup 4)))
15983 (set (match_dup 6) (unspec:TF [(match_dup 5)] UNSPEC_F2XM1))
15984 (set (match_dup 8) (plus:TF (match_dup 6) (match_dup 7)))
15985 (parallel [(set (match_operand:TF 0 "register_operand" "")
15986 (unspec:TF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15987 (clobber (match_dup 4))])]
15988 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15989 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
15990 {
15991 rtx temp;
15992 int i;
15993
15994 for (i=2; i<9; i++)
15995 operands[i] = gen_reg_rtx (TFmode);
15996 temp = standard_80387_constant_rtx (5); /* fldl2e */
15997 emit_move_insn (operands[2], temp);
15998 emit_move_insn (operands[7], CONST1_RTX (TFmode)); /* fld1 */
15999 })
16000
16001 (define_expand "atandf2"
16002 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16003 (unspec:DF [(match_dup 2)
16004 (match_operand:DF 1 "register_operand" "")]
16005 UNSPEC_FPATAN))
16006 (clobber (match_dup 1))])]
16007 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16008 && flag_unsafe_math_optimizations"
16009 {
16010 operands[2] = gen_reg_rtx (DFmode);
16011 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16012 })
16013
16014 (define_expand "atanxf2"
16015 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16016 (unspec:XF [(match_dup 2)
16017 (match_operand:XF 1 "register_operand" "")]
16018 UNSPEC_FPATAN))
16019 (clobber (match_dup 1))])]
16020 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16021 && flag_unsafe_math_optimizations && !TARGET_128BIT_LONG_DOUBLE"
16022 {
16023 operands[2] = gen_reg_rtx (XFmode);
16024 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16025 })
16026
16027 (define_expand "atantf2"
16028 [(parallel [(set (match_operand:TF 0 "register_operand" "")
16029 (unspec:TF [(match_dup 2)
16030 (match_operand:TF 1 "register_operand" "")]
16031 UNSPEC_FPATAN))
16032 (clobber (match_dup 1))])]
16033 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16034 && flag_unsafe_math_optimizations && TARGET_128BIT_LONG_DOUBLE"
16035 {
16036 operands[2] = gen_reg_rtx (TFmode);
16037 emit_move_insn (operands[2], CONST1_RTX (TFmode)); /* fld1 */
16038 })
16039 \f
16040 ;; Block operation instructions
16041
16042 (define_insn "cld"
16043 [(set (reg:SI 19) (const_int 0))]
16044 ""
16045 "cld"
16046 [(set_attr "type" "cld")])
16047
16048 (define_expand "movstrsi"
16049 [(use (match_operand:BLK 0 "memory_operand" ""))
16050 (use (match_operand:BLK 1 "memory_operand" ""))
16051 (use (match_operand:SI 2 "nonmemory_operand" ""))
16052 (use (match_operand:SI 3 "const_int_operand" ""))]
16053 ""
16054 {
16055 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16056 DONE;
16057 else
16058 FAIL;
16059 })
16060
16061 (define_expand "movstrdi"
16062 [(use (match_operand:BLK 0 "memory_operand" ""))
16063 (use (match_operand:BLK 1 "memory_operand" ""))
16064 (use (match_operand:DI 2 "nonmemory_operand" ""))
16065 (use (match_operand:DI 3 "const_int_operand" ""))]
16066 "TARGET_64BIT"
16067 {
16068 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16069 DONE;
16070 else
16071 FAIL;
16072 })
16073
16074 ;; Most CPUs don't like single string operations
16075 ;; Handle this case here to simplify previous expander.
16076
16077 (define_expand "strmovdi_rex64"
16078 [(set (match_dup 2)
16079 (mem:DI (match_operand:DI 1 "register_operand" "")))
16080 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
16081 (match_dup 2))
16082 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16083 (clobber (reg:CC 17))])
16084 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
16085 (clobber (reg:CC 17))])]
16086 "TARGET_64BIT"
16087 {
16088 if (TARGET_SINGLE_STRINGOP || optimize_size)
16089 {
16090 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
16091 operands[1]));
16092 DONE;
16093 }
16094 else
16095 operands[2] = gen_reg_rtx (DImode);
16096 })
16097
16098
16099 (define_expand "strmovsi"
16100 [(set (match_dup 2)
16101 (mem:SI (match_operand:SI 1 "register_operand" "")))
16102 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
16103 (match_dup 2))
16104 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16105 (clobber (reg:CC 17))])
16106 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
16107 (clobber (reg:CC 17))])]
16108 ""
16109 {
16110 if (TARGET_64BIT)
16111 {
16112 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
16113 DONE;
16114 }
16115 if (TARGET_SINGLE_STRINGOP || optimize_size)
16116 {
16117 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
16118 operands[1]));
16119 DONE;
16120 }
16121 else
16122 operands[2] = gen_reg_rtx (SImode);
16123 })
16124
16125 (define_expand "strmovsi_rex64"
16126 [(set (match_dup 2)
16127 (mem:SI (match_operand:DI 1 "register_operand" "")))
16128 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
16129 (match_dup 2))
16130 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16131 (clobber (reg:CC 17))])
16132 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
16133 (clobber (reg:CC 17))])]
16134 "TARGET_64BIT"
16135 {
16136 if (TARGET_SINGLE_STRINGOP || optimize_size)
16137 {
16138 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
16139 operands[1]));
16140 DONE;
16141 }
16142 else
16143 operands[2] = gen_reg_rtx (SImode);
16144 })
16145
16146 (define_expand "strmovhi"
16147 [(set (match_dup 2)
16148 (mem:HI (match_operand:SI 1 "register_operand" "")))
16149 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
16150 (match_dup 2))
16151 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16152 (clobber (reg:CC 17))])
16153 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
16154 (clobber (reg:CC 17))])]
16155 ""
16156 {
16157 if (TARGET_64BIT)
16158 {
16159 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
16160 DONE;
16161 }
16162 if (TARGET_SINGLE_STRINGOP || optimize_size)
16163 {
16164 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
16165 operands[1]));
16166 DONE;
16167 }
16168 else
16169 operands[2] = gen_reg_rtx (HImode);
16170 })
16171
16172 (define_expand "strmovhi_rex64"
16173 [(set (match_dup 2)
16174 (mem:HI (match_operand:DI 1 "register_operand" "")))
16175 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
16176 (match_dup 2))
16177 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16178 (clobber (reg:CC 17))])
16179 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
16180 (clobber (reg:CC 17))])]
16181 "TARGET_64BIT"
16182 {
16183 if (TARGET_SINGLE_STRINGOP || optimize_size)
16184 {
16185 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
16186 operands[1]));
16187 DONE;
16188 }
16189 else
16190 operands[2] = gen_reg_rtx (HImode);
16191 })
16192
16193 (define_expand "strmovqi"
16194 [(set (match_dup 2)
16195 (mem:QI (match_operand:SI 1 "register_operand" "")))
16196 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
16197 (match_dup 2))
16198 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16199 (clobber (reg:CC 17))])
16200 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
16201 (clobber (reg:CC 17))])]
16202 ""
16203 {
16204 if (TARGET_64BIT)
16205 {
16206 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
16207 DONE;
16208 }
16209 if (TARGET_SINGLE_STRINGOP || optimize_size)
16210 {
16211 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
16212 operands[1]));
16213 DONE;
16214 }
16215 else
16216 operands[2] = gen_reg_rtx (QImode);
16217 })
16218
16219 (define_expand "strmovqi_rex64"
16220 [(set (match_dup 2)
16221 (mem:QI (match_operand:DI 1 "register_operand" "")))
16222 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
16223 (match_dup 2))
16224 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16225 (clobber (reg:CC 17))])
16226 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
16227 (clobber (reg:CC 17))])]
16228 "TARGET_64BIT"
16229 {
16230 if (TARGET_SINGLE_STRINGOP || optimize_size)
16231 {
16232 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
16233 operands[1]));
16234 DONE;
16235 }
16236 else
16237 operands[2] = gen_reg_rtx (QImode);
16238 })
16239
16240 (define_insn "strmovdi_rex_1"
16241 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16242 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16243 (set (match_operand:DI 0 "register_operand" "=D")
16244 (plus:DI (match_dup 2)
16245 (const_int 8)))
16246 (set (match_operand:DI 1 "register_operand" "=S")
16247 (plus:DI (match_dup 3)
16248 (const_int 8)))
16249 (use (reg:SI 19))]
16250 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16251 "movsq"
16252 [(set_attr "type" "str")
16253 (set_attr "mode" "DI")
16254 (set_attr "memory" "both")])
16255
16256 (define_insn "strmovsi_1"
16257 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16258 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16259 (set (match_operand:SI 0 "register_operand" "=D")
16260 (plus:SI (match_dup 2)
16261 (const_int 4)))
16262 (set (match_operand:SI 1 "register_operand" "=S")
16263 (plus:SI (match_dup 3)
16264 (const_int 4)))
16265 (use (reg:SI 19))]
16266 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16267 "{movsl|movsd}"
16268 [(set_attr "type" "str")
16269 (set_attr "mode" "SI")
16270 (set_attr "memory" "both")])
16271
16272 (define_insn "strmovsi_rex_1"
16273 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16274 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16275 (set (match_operand:DI 0 "register_operand" "=D")
16276 (plus:DI (match_dup 2)
16277 (const_int 4)))
16278 (set (match_operand:DI 1 "register_operand" "=S")
16279 (plus:DI (match_dup 3)
16280 (const_int 4)))
16281 (use (reg:SI 19))]
16282 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16283 "{movsl|movsd}"
16284 [(set_attr "type" "str")
16285 (set_attr "mode" "SI")
16286 (set_attr "memory" "both")])
16287
16288 (define_insn "strmovhi_1"
16289 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16290 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16291 (set (match_operand:SI 0 "register_operand" "=D")
16292 (plus:SI (match_dup 2)
16293 (const_int 2)))
16294 (set (match_operand:SI 1 "register_operand" "=S")
16295 (plus:SI (match_dup 3)
16296 (const_int 2)))
16297 (use (reg:SI 19))]
16298 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16299 "movsw"
16300 [(set_attr "type" "str")
16301 (set_attr "memory" "both")
16302 (set_attr "mode" "HI")])
16303
16304 (define_insn "strmovhi_rex_1"
16305 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16306 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16307 (set (match_operand:DI 0 "register_operand" "=D")
16308 (plus:DI (match_dup 2)
16309 (const_int 2)))
16310 (set (match_operand:DI 1 "register_operand" "=S")
16311 (plus:DI (match_dup 3)
16312 (const_int 2)))
16313 (use (reg:SI 19))]
16314 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16315 "movsw"
16316 [(set_attr "type" "str")
16317 (set_attr "memory" "both")
16318 (set_attr "mode" "HI")])
16319
16320 (define_insn "strmovqi_1"
16321 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16322 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16323 (set (match_operand:SI 0 "register_operand" "=D")
16324 (plus:SI (match_dup 2)
16325 (const_int 1)))
16326 (set (match_operand:SI 1 "register_operand" "=S")
16327 (plus:SI (match_dup 3)
16328 (const_int 1)))
16329 (use (reg:SI 19))]
16330 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16331 "movsb"
16332 [(set_attr "type" "str")
16333 (set_attr "memory" "both")
16334 (set_attr "mode" "QI")])
16335
16336 (define_insn "strmovqi_rex_1"
16337 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16338 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16339 (set (match_operand:DI 0 "register_operand" "=D")
16340 (plus:DI (match_dup 2)
16341 (const_int 1)))
16342 (set (match_operand:DI 1 "register_operand" "=S")
16343 (plus:DI (match_dup 3)
16344 (const_int 1)))
16345 (use (reg:SI 19))]
16346 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16347 "movsb"
16348 [(set_attr "type" "str")
16349 (set_attr "memory" "both")
16350 (set_attr "mode" "QI")])
16351
16352 (define_insn "rep_movdi_rex64"
16353 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16354 (set (match_operand:DI 0 "register_operand" "=D")
16355 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16356 (const_int 3))
16357 (match_operand:DI 3 "register_operand" "0")))
16358 (set (match_operand:DI 1 "register_operand" "=S")
16359 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16360 (match_operand:DI 4 "register_operand" "1")))
16361 (set (mem:BLK (match_dup 3))
16362 (mem:BLK (match_dup 4)))
16363 (use (match_dup 5))
16364 (use (reg:SI 19))]
16365 "TARGET_64BIT"
16366 "{rep\;movsq|rep movsq}"
16367 [(set_attr "type" "str")
16368 (set_attr "prefix_rep" "1")
16369 (set_attr "memory" "both")
16370 (set_attr "mode" "DI")])
16371
16372 (define_insn "rep_movsi"
16373 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16374 (set (match_operand:SI 0 "register_operand" "=D")
16375 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16376 (const_int 2))
16377 (match_operand:SI 3 "register_operand" "0")))
16378 (set (match_operand:SI 1 "register_operand" "=S")
16379 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16380 (match_operand:SI 4 "register_operand" "1")))
16381 (set (mem:BLK (match_dup 3))
16382 (mem:BLK (match_dup 4)))
16383 (use (match_dup 5))
16384 (use (reg:SI 19))]
16385 "!TARGET_64BIT"
16386 "{rep\;movsl|rep movsd}"
16387 [(set_attr "type" "str")
16388 (set_attr "prefix_rep" "1")
16389 (set_attr "memory" "both")
16390 (set_attr "mode" "SI")])
16391
16392 (define_insn "rep_movsi_rex64"
16393 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16394 (set (match_operand:DI 0 "register_operand" "=D")
16395 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16396 (const_int 2))
16397 (match_operand:DI 3 "register_operand" "0")))
16398 (set (match_operand:DI 1 "register_operand" "=S")
16399 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16400 (match_operand:DI 4 "register_operand" "1")))
16401 (set (mem:BLK (match_dup 3))
16402 (mem:BLK (match_dup 4)))
16403 (use (match_dup 5))
16404 (use (reg:SI 19))]
16405 "TARGET_64BIT"
16406 "{rep\;movsl|rep movsd}"
16407 [(set_attr "type" "str")
16408 (set_attr "prefix_rep" "1")
16409 (set_attr "memory" "both")
16410 (set_attr "mode" "SI")])
16411
16412 (define_insn "rep_movqi"
16413 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16414 (set (match_operand:SI 0 "register_operand" "=D")
16415 (plus:SI (match_operand:SI 3 "register_operand" "0")
16416 (match_operand:SI 5 "register_operand" "2")))
16417 (set (match_operand:SI 1 "register_operand" "=S")
16418 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16419 (set (mem:BLK (match_dup 3))
16420 (mem:BLK (match_dup 4)))
16421 (use (match_dup 5))
16422 (use (reg:SI 19))]
16423 "!TARGET_64BIT"
16424 "{rep\;movsb|rep movsb}"
16425 [(set_attr "type" "str")
16426 (set_attr "prefix_rep" "1")
16427 (set_attr "memory" "both")
16428 (set_attr "mode" "SI")])
16429
16430 (define_insn "rep_movqi_rex64"
16431 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16432 (set (match_operand:DI 0 "register_operand" "=D")
16433 (plus:DI (match_operand:DI 3 "register_operand" "0")
16434 (match_operand:DI 5 "register_operand" "2")))
16435 (set (match_operand:DI 1 "register_operand" "=S")
16436 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16437 (set (mem:BLK (match_dup 3))
16438 (mem:BLK (match_dup 4)))
16439 (use (match_dup 5))
16440 (use (reg:SI 19))]
16441 "TARGET_64BIT"
16442 "{rep\;movsb|rep movsb}"
16443 [(set_attr "type" "str")
16444 (set_attr "prefix_rep" "1")
16445 (set_attr "memory" "both")
16446 (set_attr "mode" "SI")])
16447
16448 (define_expand "clrstrsi"
16449 [(use (match_operand:BLK 0 "memory_operand" ""))
16450 (use (match_operand:SI 1 "nonmemory_operand" ""))
16451 (use (match_operand 2 "const_int_operand" ""))]
16452 ""
16453 {
16454 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16455 DONE;
16456 else
16457 FAIL;
16458 })
16459
16460 (define_expand "clrstrdi"
16461 [(use (match_operand:BLK 0 "memory_operand" ""))
16462 (use (match_operand:DI 1 "nonmemory_operand" ""))
16463 (use (match_operand 2 "const_int_operand" ""))]
16464 "TARGET_64BIT"
16465 {
16466 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16467 DONE;
16468 else
16469 FAIL;
16470 })
16471
16472 ;; Most CPUs don't like single string operations
16473 ;; Handle this case here to simplify previous expander.
16474
16475 (define_expand "strsetdi_rex64"
16476 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
16477 (match_operand:DI 1 "register_operand" ""))
16478 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16479 (clobber (reg:CC 17))])]
16480 "TARGET_64BIT"
16481 {
16482 if (TARGET_SINGLE_STRINGOP || optimize_size)
16483 {
16484 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
16485 DONE;
16486 }
16487 })
16488
16489 (define_expand "strsetsi"
16490 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
16491 (match_operand:SI 1 "register_operand" ""))
16492 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16493 (clobber (reg:CC 17))])]
16494 ""
16495 {
16496 if (TARGET_64BIT)
16497 {
16498 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
16499 DONE;
16500 }
16501 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16502 {
16503 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
16504 DONE;
16505 }
16506 })
16507
16508 (define_expand "strsetsi_rex64"
16509 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
16510 (match_operand:SI 1 "register_operand" ""))
16511 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16512 (clobber (reg:CC 17))])]
16513 "TARGET_64BIT"
16514 {
16515 if (TARGET_SINGLE_STRINGOP || optimize_size)
16516 {
16517 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16518 DONE;
16519 }
16520 })
16521
16522 (define_expand "strsethi"
16523 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16524 (match_operand:HI 1 "register_operand" ""))
16525 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16526 (clobber (reg:CC 17))])]
16527 ""
16528 {
16529 if (TARGET_64BIT)
16530 {
16531 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16532 DONE;
16533 }
16534 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16535 {
16536 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16537 DONE;
16538 }
16539 })
16540
16541 (define_expand "strsethi_rex64"
16542 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16543 (match_operand:HI 1 "register_operand" ""))
16544 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16545 (clobber (reg:CC 17))])]
16546 "TARGET_64BIT"
16547 {
16548 if (TARGET_SINGLE_STRINGOP || optimize_size)
16549 {
16550 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16551 DONE;
16552 }
16553 })
16554
16555 (define_expand "strsetqi"
16556 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16557 (match_operand:QI 1 "register_operand" ""))
16558 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16559 (clobber (reg:CC 17))])]
16560 ""
16561 {
16562 if (TARGET_64BIT)
16563 {
16564 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16565 DONE;
16566 }
16567 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16568 {
16569 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16570 DONE;
16571 }
16572 })
16573
16574 (define_expand "strsetqi_rex64"
16575 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16576 (match_operand:QI 1 "register_operand" ""))
16577 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16578 (clobber (reg:CC 17))])]
16579 "TARGET_64BIT"
16580 {
16581 if (TARGET_SINGLE_STRINGOP || optimize_size)
16582 {
16583 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16584 DONE;
16585 }
16586 })
16587
16588 (define_insn "strsetdi_rex_1"
16589 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16590 (match_operand:SI 2 "register_operand" "a"))
16591 (set (match_operand:DI 0 "register_operand" "=D")
16592 (plus:DI (match_dup 1)
16593 (const_int 8)))
16594 (use (reg:SI 19))]
16595 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16596 "stosq"
16597 [(set_attr "type" "str")
16598 (set_attr "memory" "store")
16599 (set_attr "mode" "DI")])
16600
16601 (define_insn "strsetsi_1"
16602 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16603 (match_operand:SI 2 "register_operand" "a"))
16604 (set (match_operand:SI 0 "register_operand" "=D")
16605 (plus:SI (match_dup 1)
16606 (const_int 4)))
16607 (use (reg:SI 19))]
16608 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16609 "{stosl|stosd}"
16610 [(set_attr "type" "str")
16611 (set_attr "memory" "store")
16612 (set_attr "mode" "SI")])
16613
16614 (define_insn "strsetsi_rex_1"
16615 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16616 (match_operand:SI 2 "register_operand" "a"))
16617 (set (match_operand:DI 0 "register_operand" "=D")
16618 (plus:DI (match_dup 1)
16619 (const_int 4)))
16620 (use (reg:SI 19))]
16621 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16622 "{stosl|stosd}"
16623 [(set_attr "type" "str")
16624 (set_attr "memory" "store")
16625 (set_attr "mode" "SI")])
16626
16627 (define_insn "strsethi_1"
16628 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16629 (match_operand:HI 2 "register_operand" "a"))
16630 (set (match_operand:SI 0 "register_operand" "=D")
16631 (plus:SI (match_dup 1)
16632 (const_int 2)))
16633 (use (reg:SI 19))]
16634 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16635 "stosw"
16636 [(set_attr "type" "str")
16637 (set_attr "memory" "store")
16638 (set_attr "mode" "HI")])
16639
16640 (define_insn "strsethi_rex_1"
16641 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16642 (match_operand:HI 2 "register_operand" "a"))
16643 (set (match_operand:DI 0 "register_operand" "=D")
16644 (plus:DI (match_dup 1)
16645 (const_int 2)))
16646 (use (reg:SI 19))]
16647 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16648 "stosw"
16649 [(set_attr "type" "str")
16650 (set_attr "memory" "store")
16651 (set_attr "mode" "HI")])
16652
16653 (define_insn "strsetqi_1"
16654 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16655 (match_operand:QI 2 "register_operand" "a"))
16656 (set (match_operand:SI 0 "register_operand" "=D")
16657 (plus:SI (match_dup 1)
16658 (const_int 1)))
16659 (use (reg:SI 19))]
16660 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16661 "stosb"
16662 [(set_attr "type" "str")
16663 (set_attr "memory" "store")
16664 (set_attr "mode" "QI")])
16665
16666 (define_insn "strsetqi_rex_1"
16667 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16668 (match_operand:QI 2 "register_operand" "a"))
16669 (set (match_operand:DI 0 "register_operand" "=D")
16670 (plus:DI (match_dup 1)
16671 (const_int 1)))
16672 (use (reg:SI 19))]
16673 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16674 "stosb"
16675 [(set_attr "type" "str")
16676 (set_attr "memory" "store")
16677 (set_attr "mode" "QI")])
16678
16679 (define_insn "rep_stosdi_rex64"
16680 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16681 (set (match_operand:DI 0 "register_operand" "=D")
16682 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16683 (const_int 3))
16684 (match_operand:DI 3 "register_operand" "0")))
16685 (set (mem:BLK (match_dup 3))
16686 (const_int 0))
16687 (use (match_operand:DI 2 "register_operand" "a"))
16688 (use (match_dup 4))
16689 (use (reg:SI 19))]
16690 "TARGET_64BIT"
16691 "{rep\;stosq|rep stosq}"
16692 [(set_attr "type" "str")
16693 (set_attr "prefix_rep" "1")
16694 (set_attr "memory" "store")
16695 (set_attr "mode" "DI")])
16696
16697 (define_insn "rep_stossi"
16698 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16699 (set (match_operand:SI 0 "register_operand" "=D")
16700 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16701 (const_int 2))
16702 (match_operand:SI 3 "register_operand" "0")))
16703 (set (mem:BLK (match_dup 3))
16704 (const_int 0))
16705 (use (match_operand:SI 2 "register_operand" "a"))
16706 (use (match_dup 4))
16707 (use (reg:SI 19))]
16708 "!TARGET_64BIT"
16709 "{rep\;stosl|rep stosd}"
16710 [(set_attr "type" "str")
16711 (set_attr "prefix_rep" "1")
16712 (set_attr "memory" "store")
16713 (set_attr "mode" "SI")])
16714
16715 (define_insn "rep_stossi_rex64"
16716 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16717 (set (match_operand:DI 0 "register_operand" "=D")
16718 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16719 (const_int 2))
16720 (match_operand:DI 3 "register_operand" "0")))
16721 (set (mem:BLK (match_dup 3))
16722 (const_int 0))
16723 (use (match_operand:SI 2 "register_operand" "a"))
16724 (use (match_dup 4))
16725 (use (reg:SI 19))]
16726 "TARGET_64BIT"
16727 "{rep\;stosl|rep stosd}"
16728 [(set_attr "type" "str")
16729 (set_attr "prefix_rep" "1")
16730 (set_attr "memory" "store")
16731 (set_attr "mode" "SI")])
16732
16733 (define_insn "rep_stosqi"
16734 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16735 (set (match_operand:SI 0 "register_operand" "=D")
16736 (plus:SI (match_operand:SI 3 "register_operand" "0")
16737 (match_operand:SI 4 "register_operand" "1")))
16738 (set (mem:BLK (match_dup 3))
16739 (const_int 0))
16740 (use (match_operand:QI 2 "register_operand" "a"))
16741 (use (match_dup 4))
16742 (use (reg:SI 19))]
16743 "!TARGET_64BIT"
16744 "{rep\;stosb|rep stosb}"
16745 [(set_attr "type" "str")
16746 (set_attr "prefix_rep" "1")
16747 (set_attr "memory" "store")
16748 (set_attr "mode" "QI")])
16749
16750 (define_insn "rep_stosqi_rex64"
16751 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16752 (set (match_operand:DI 0 "register_operand" "=D")
16753 (plus:DI (match_operand:DI 3 "register_operand" "0")
16754 (match_operand:DI 4 "register_operand" "1")))
16755 (set (mem:BLK (match_dup 3))
16756 (const_int 0))
16757 (use (match_operand:QI 2 "register_operand" "a"))
16758 (use (match_dup 4))
16759 (use (reg:DI 19))]
16760 "TARGET_64BIT"
16761 "{rep\;stosb|rep stosb}"
16762 [(set_attr "type" "str")
16763 (set_attr "prefix_rep" "1")
16764 (set_attr "memory" "store")
16765 (set_attr "mode" "QI")])
16766
16767 (define_expand "cmpstrsi"
16768 [(set (match_operand:SI 0 "register_operand" "")
16769 (compare:SI (match_operand:BLK 1 "general_operand" "")
16770 (match_operand:BLK 2 "general_operand" "")))
16771 (use (match_operand 3 "general_operand" ""))
16772 (use (match_operand 4 "immediate_operand" ""))]
16773 ""
16774 {
16775 rtx addr1, addr2, out, outlow, count, countreg, align;
16776
16777 /* Can't use this if the user has appropriated esi or edi. */
16778 if (global_regs[4] || global_regs[5])
16779 FAIL;
16780
16781 out = operands[0];
16782 if (GET_CODE (out) != REG)
16783 out = gen_reg_rtx (SImode);
16784
16785 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16786 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16787
16788 count = operands[3];
16789 countreg = ix86_zero_extend_to_Pmode (count);
16790
16791 /* %%% Iff we are testing strict equality, we can use known alignment
16792 to good advantage. This may be possible with combine, particularly
16793 once cc0 is dead. */
16794 align = operands[4];
16795
16796 emit_insn (gen_cld ());
16797 if (GET_CODE (count) == CONST_INT)
16798 {
16799 if (INTVAL (count) == 0)
16800 {
16801 emit_move_insn (operands[0], const0_rtx);
16802 DONE;
16803 }
16804 if (TARGET_64BIT)
16805 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16806 addr1, addr2, countreg));
16807 else
16808 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16809 addr1, addr2, countreg));
16810 }
16811 else
16812 {
16813 if (TARGET_64BIT)
16814 {
16815 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16816 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16817 addr1, addr2, countreg));
16818 }
16819 else
16820 {
16821 emit_insn (gen_cmpsi_1 (countreg, countreg));
16822 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16823 addr1, addr2, countreg));
16824 }
16825 }
16826
16827 outlow = gen_lowpart (QImode, out);
16828 emit_insn (gen_cmpintqi (outlow));
16829 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16830
16831 if (operands[0] != out)
16832 emit_move_insn (operands[0], out);
16833
16834 DONE;
16835 })
16836
16837 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16838
16839 (define_expand "cmpintqi"
16840 [(set (match_dup 1)
16841 (gtu:QI (reg:CC 17) (const_int 0)))
16842 (set (match_dup 2)
16843 (ltu:QI (reg:CC 17) (const_int 0)))
16844 (parallel [(set (match_operand:QI 0 "register_operand" "")
16845 (minus:QI (match_dup 1)
16846 (match_dup 2)))
16847 (clobber (reg:CC 17))])]
16848 ""
16849 "operands[1] = gen_reg_rtx (QImode);
16850 operands[2] = gen_reg_rtx (QImode);")
16851
16852 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16853 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16854
16855 (define_insn "cmpstrqi_nz_1"
16856 [(set (reg:CC 17)
16857 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16858 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16859 (use (match_operand:SI 6 "register_operand" "2"))
16860 (use (match_operand:SI 3 "immediate_operand" "i"))
16861 (use (reg:SI 19))
16862 (clobber (match_operand:SI 0 "register_operand" "=S"))
16863 (clobber (match_operand:SI 1 "register_operand" "=D"))
16864 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16865 "!TARGET_64BIT"
16866 "repz{\;| }cmpsb"
16867 [(set_attr "type" "str")
16868 (set_attr "mode" "QI")
16869 (set_attr "prefix_rep" "1")])
16870
16871 (define_insn "cmpstrqi_nz_rex_1"
16872 [(set (reg:CC 17)
16873 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16874 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16875 (use (match_operand:DI 6 "register_operand" "2"))
16876 (use (match_operand:SI 3 "immediate_operand" "i"))
16877 (use (reg:SI 19))
16878 (clobber (match_operand:DI 0 "register_operand" "=S"))
16879 (clobber (match_operand:DI 1 "register_operand" "=D"))
16880 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16881 "TARGET_64BIT"
16882 "repz{\;| }cmpsb"
16883 [(set_attr "type" "str")
16884 (set_attr "mode" "QI")
16885 (set_attr "prefix_rep" "1")])
16886
16887 ;; The same, but the count is not known to not be zero.
16888
16889 (define_insn "cmpstrqi_1"
16890 [(set (reg:CC 17)
16891 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16892 (const_int 0))
16893 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16894 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16895 (const_int 0)))
16896 (use (match_operand:SI 3 "immediate_operand" "i"))
16897 (use (reg:CC 17))
16898 (use (reg:SI 19))
16899 (clobber (match_operand:SI 0 "register_operand" "=S"))
16900 (clobber (match_operand:SI 1 "register_operand" "=D"))
16901 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16902 "!TARGET_64BIT"
16903 "repz{\;| }cmpsb"
16904 [(set_attr "type" "str")
16905 (set_attr "mode" "QI")
16906 (set_attr "prefix_rep" "1")])
16907
16908 (define_insn "cmpstrqi_rex_1"
16909 [(set (reg:CC 17)
16910 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16911 (const_int 0))
16912 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16913 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16914 (const_int 0)))
16915 (use (match_operand:SI 3 "immediate_operand" "i"))
16916 (use (reg:CC 17))
16917 (use (reg:SI 19))
16918 (clobber (match_operand:DI 0 "register_operand" "=S"))
16919 (clobber (match_operand:DI 1 "register_operand" "=D"))
16920 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16921 "TARGET_64BIT"
16922 "repz{\;| }cmpsb"
16923 [(set_attr "type" "str")
16924 (set_attr "mode" "QI")
16925 (set_attr "prefix_rep" "1")])
16926
16927 (define_expand "strlensi"
16928 [(set (match_operand:SI 0 "register_operand" "")
16929 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16930 (match_operand:QI 2 "immediate_operand" "")
16931 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16932 ""
16933 {
16934 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16935 DONE;
16936 else
16937 FAIL;
16938 })
16939
16940 (define_expand "strlendi"
16941 [(set (match_operand:DI 0 "register_operand" "")
16942 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16943 (match_operand:QI 2 "immediate_operand" "")
16944 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16945 ""
16946 {
16947 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16948 DONE;
16949 else
16950 FAIL;
16951 })
16952
16953 (define_insn "strlenqi_1"
16954 [(set (match_operand:SI 0 "register_operand" "=&c")
16955 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16956 (match_operand:QI 2 "register_operand" "a")
16957 (match_operand:SI 3 "immediate_operand" "i")
16958 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16959 (use (reg:SI 19))
16960 (clobber (match_operand:SI 1 "register_operand" "=D"))
16961 (clobber (reg:CC 17))]
16962 "!TARGET_64BIT"
16963 "repnz{\;| }scasb"
16964 [(set_attr "type" "str")
16965 (set_attr "mode" "QI")
16966 (set_attr "prefix_rep" "1")])
16967
16968 (define_insn "strlenqi_rex_1"
16969 [(set (match_operand:DI 0 "register_operand" "=&c")
16970 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16971 (match_operand:QI 2 "register_operand" "a")
16972 (match_operand:DI 3 "immediate_operand" "i")
16973 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16974 (use (reg:SI 19))
16975 (clobber (match_operand:DI 1 "register_operand" "=D"))
16976 (clobber (reg:CC 17))]
16977 "TARGET_64BIT"
16978 "repnz{\;| }scasb"
16979 [(set_attr "type" "str")
16980 (set_attr "mode" "QI")
16981 (set_attr "prefix_rep" "1")])
16982
16983 ;; Peephole optimizations to clean up after cmpstr*. This should be
16984 ;; handled in combine, but it is not currently up to the task.
16985 ;; When used for their truth value, the cmpstr* expanders generate
16986 ;; code like this:
16987 ;;
16988 ;; repz cmpsb
16989 ;; seta %al
16990 ;; setb %dl
16991 ;; cmpb %al, %dl
16992 ;; jcc label
16993 ;;
16994 ;; The intermediate three instructions are unnecessary.
16995
16996 ;; This one handles cmpstr*_nz_1...
16997 (define_peephole2
16998 [(parallel[
16999 (set (reg:CC 17)
17000 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17001 (mem:BLK (match_operand 5 "register_operand" ""))))
17002 (use (match_operand 6 "register_operand" ""))
17003 (use (match_operand:SI 3 "immediate_operand" ""))
17004 (use (reg:SI 19))
17005 (clobber (match_operand 0 "register_operand" ""))
17006 (clobber (match_operand 1 "register_operand" ""))
17007 (clobber (match_operand 2 "register_operand" ""))])
17008 (set (match_operand:QI 7 "register_operand" "")
17009 (gtu:QI (reg:CC 17) (const_int 0)))
17010 (set (match_operand:QI 8 "register_operand" "")
17011 (ltu:QI (reg:CC 17) (const_int 0)))
17012 (set (reg 17)
17013 (compare (match_dup 7) (match_dup 8)))
17014 ]
17015 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17016 [(parallel[
17017 (set (reg:CC 17)
17018 (compare:CC (mem:BLK (match_dup 4))
17019 (mem:BLK (match_dup 5))))
17020 (use (match_dup 6))
17021 (use (match_dup 3))
17022 (use (reg:SI 19))
17023 (clobber (match_dup 0))
17024 (clobber (match_dup 1))
17025 (clobber (match_dup 2))])]
17026 "")
17027
17028 ;; ...and this one handles cmpstr*_1.
17029 (define_peephole2
17030 [(parallel[
17031 (set (reg:CC 17)
17032 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17033 (const_int 0))
17034 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17035 (mem:BLK (match_operand 5 "register_operand" "")))
17036 (const_int 0)))
17037 (use (match_operand:SI 3 "immediate_operand" ""))
17038 (use (reg:CC 17))
17039 (use (reg:SI 19))
17040 (clobber (match_operand 0 "register_operand" ""))
17041 (clobber (match_operand 1 "register_operand" ""))
17042 (clobber (match_operand 2 "register_operand" ""))])
17043 (set (match_operand:QI 7 "register_operand" "")
17044 (gtu:QI (reg:CC 17) (const_int 0)))
17045 (set (match_operand:QI 8 "register_operand" "")
17046 (ltu:QI (reg:CC 17) (const_int 0)))
17047 (set (reg 17)
17048 (compare (match_dup 7) (match_dup 8)))
17049 ]
17050 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17051 [(parallel[
17052 (set (reg:CC 17)
17053 (if_then_else:CC (ne (match_dup 6)
17054 (const_int 0))
17055 (compare:CC (mem:BLK (match_dup 4))
17056 (mem:BLK (match_dup 5)))
17057 (const_int 0)))
17058 (use (match_dup 3))
17059 (use (reg:CC 17))
17060 (use (reg:SI 19))
17061 (clobber (match_dup 0))
17062 (clobber (match_dup 1))
17063 (clobber (match_dup 2))])]
17064 "")
17065
17066
17067 \f
17068 ;; Conditional move instructions.
17069
17070 (define_expand "movdicc"
17071 [(set (match_operand:DI 0 "register_operand" "")
17072 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17073 (match_operand:DI 2 "general_operand" "")
17074 (match_operand:DI 3 "general_operand" "")))]
17075 "TARGET_64BIT"
17076 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17077
17078 (define_insn "x86_movdicc_0_m1_rex64"
17079 [(set (match_operand:DI 0 "register_operand" "=r")
17080 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17081 (const_int -1)
17082 (const_int 0)))
17083 (clobber (reg:CC 17))]
17084 "TARGET_64BIT"
17085 "sbb{q}\t%0, %0"
17086 ; Since we don't have the proper number of operands for an alu insn,
17087 ; fill in all the blanks.
17088 [(set_attr "type" "alu")
17089 (set_attr "pent_pair" "pu")
17090 (set_attr "memory" "none")
17091 (set_attr "imm_disp" "false")
17092 (set_attr "mode" "DI")
17093 (set_attr "length_immediate" "0")])
17094
17095 (define_insn "movdicc_c_rex64"
17096 [(set (match_operand:DI 0 "register_operand" "=r,r")
17097 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17098 [(reg 17) (const_int 0)])
17099 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17100 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17101 "TARGET_64BIT && TARGET_CMOVE
17102 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17103 "@
17104 cmov%O2%C1\t{%2, %0|%0, %2}
17105 cmov%O2%c1\t{%3, %0|%0, %3}"
17106 [(set_attr "type" "icmov")
17107 (set_attr "mode" "DI")])
17108
17109 (define_expand "movsicc"
17110 [(set (match_operand:SI 0 "register_operand" "")
17111 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17112 (match_operand:SI 2 "general_operand" "")
17113 (match_operand:SI 3 "general_operand" "")))]
17114 ""
17115 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17116
17117 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17118 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17119 ;; So just document what we're doing explicitly.
17120
17121 (define_insn "x86_movsicc_0_m1"
17122 [(set (match_operand:SI 0 "register_operand" "=r")
17123 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17124 (const_int -1)
17125 (const_int 0)))
17126 (clobber (reg:CC 17))]
17127 ""
17128 "sbb{l}\t%0, %0"
17129 ; Since we don't have the proper number of operands for an alu insn,
17130 ; fill in all the blanks.
17131 [(set_attr "type" "alu")
17132 (set_attr "pent_pair" "pu")
17133 (set_attr "memory" "none")
17134 (set_attr "imm_disp" "false")
17135 (set_attr "mode" "SI")
17136 (set_attr "length_immediate" "0")])
17137
17138 (define_insn "*movsicc_noc"
17139 [(set (match_operand:SI 0 "register_operand" "=r,r")
17140 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17141 [(reg 17) (const_int 0)])
17142 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17143 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17144 "TARGET_CMOVE
17145 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17146 "@
17147 cmov%O2%C1\t{%2, %0|%0, %2}
17148 cmov%O2%c1\t{%3, %0|%0, %3}"
17149 [(set_attr "type" "icmov")
17150 (set_attr "mode" "SI")])
17151
17152 (define_expand "movhicc"
17153 [(set (match_operand:HI 0 "register_operand" "")
17154 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17155 (match_operand:HI 2 "general_operand" "")
17156 (match_operand:HI 3 "general_operand" "")))]
17157 "TARGET_HIMODE_MATH"
17158 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17159
17160 (define_insn "*movhicc_noc"
17161 [(set (match_operand:HI 0 "register_operand" "=r,r")
17162 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17163 [(reg 17) (const_int 0)])
17164 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17165 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17166 "TARGET_CMOVE
17167 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17168 "@
17169 cmov%O2%C1\t{%2, %0|%0, %2}
17170 cmov%O2%c1\t{%3, %0|%0, %3}"
17171 [(set_attr "type" "icmov")
17172 (set_attr "mode" "HI")])
17173
17174 (define_expand "movqicc"
17175 [(set (match_operand:QI 0 "register_operand" "")
17176 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17177 (match_operand:QI 2 "general_operand" "")
17178 (match_operand:QI 3 "general_operand" "")))]
17179 "TARGET_QIMODE_MATH"
17180 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17181
17182 (define_insn_and_split "*movqicc_noc"
17183 [(set (match_operand:QI 0 "register_operand" "=r,r")
17184 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17185 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17186 (match_operand:QI 2 "register_operand" "r,0")
17187 (match_operand:QI 3 "register_operand" "0,r")))]
17188 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17189 "#"
17190 "&& reload_completed"
17191 [(set (match_dup 0)
17192 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17193 (match_dup 2)
17194 (match_dup 3)))]
17195 "operands[0] = gen_lowpart (SImode, operands[0]);
17196 operands[2] = gen_lowpart (SImode, operands[2]);
17197 operands[3] = gen_lowpart (SImode, operands[3]);"
17198 [(set_attr "type" "icmov")
17199 (set_attr "mode" "SI")])
17200
17201 (define_expand "movsfcc"
17202 [(set (match_operand:SF 0 "register_operand" "")
17203 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17204 (match_operand:SF 2 "register_operand" "")
17205 (match_operand:SF 3 "register_operand" "")))]
17206 "TARGET_CMOVE"
17207 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17208
17209 (define_insn "*movsfcc_1"
17210 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17211 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17212 [(reg 17) (const_int 0)])
17213 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17214 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17215 "TARGET_CMOVE
17216 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17217 "@
17218 fcmov%F1\t{%2, %0|%0, %2}
17219 fcmov%f1\t{%3, %0|%0, %3}
17220 cmov%O2%C1\t{%2, %0|%0, %2}
17221 cmov%O2%c1\t{%3, %0|%0, %3}"
17222 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17223 (set_attr "mode" "SF,SF,SI,SI")])
17224
17225 (define_expand "movdfcc"
17226 [(set (match_operand:DF 0 "register_operand" "")
17227 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17228 (match_operand:DF 2 "register_operand" "")
17229 (match_operand:DF 3 "register_operand" "")))]
17230 "TARGET_CMOVE"
17231 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17232
17233 (define_insn "*movdfcc_1"
17234 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17235 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17236 [(reg 17) (const_int 0)])
17237 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17238 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17239 "!TARGET_64BIT && TARGET_CMOVE
17240 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17241 "@
17242 fcmov%F1\t{%2, %0|%0, %2}
17243 fcmov%f1\t{%3, %0|%0, %3}
17244 #
17245 #"
17246 [(set_attr "type" "fcmov,fcmov,multi,multi")
17247 (set_attr "mode" "DF")])
17248
17249 (define_insn "*movdfcc_1_rex64"
17250 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17251 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17252 [(reg 17) (const_int 0)])
17253 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17254 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17255 "TARGET_64BIT && TARGET_CMOVE
17256 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17257 "@
17258 fcmov%F1\t{%2, %0|%0, %2}
17259 fcmov%f1\t{%3, %0|%0, %3}
17260 cmov%O2%C1\t{%2, %0|%0, %2}
17261 cmov%O2%c1\t{%3, %0|%0, %3}"
17262 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17263 (set_attr "mode" "DF")])
17264
17265 (define_split
17266 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17267 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17268 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17269 (match_operand:DF 2 "nonimmediate_operand" "")
17270 (match_operand:DF 3 "nonimmediate_operand" "")))]
17271 "!TARGET_64BIT && reload_completed"
17272 [(set (match_dup 2)
17273 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17274 (match_dup 5)
17275 (match_dup 7)))
17276 (set (match_dup 3)
17277 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17278 (match_dup 6)
17279 (match_dup 8)))]
17280 "split_di (operands+2, 1, operands+5, operands+6);
17281 split_di (operands+3, 1, operands+7, operands+8);
17282 split_di (operands, 1, operands+2, operands+3);")
17283
17284 (define_expand "movxfcc"
17285 [(set (match_operand:XF 0 "register_operand" "")
17286 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17287 (match_operand:XF 2 "register_operand" "")
17288 (match_operand:XF 3 "register_operand" "")))]
17289 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17290 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17291
17292 (define_expand "movtfcc"
17293 [(set (match_operand:TF 0 "register_operand" "")
17294 (if_then_else:TF (match_operand 1 "comparison_operator" "")
17295 (match_operand:TF 2 "register_operand" "")
17296 (match_operand:TF 3 "register_operand" "")))]
17297 "TARGET_CMOVE"
17298 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17299
17300 (define_insn "*movxfcc_1"
17301 [(set (match_operand:XF 0 "register_operand" "=f,f")
17302 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17303 [(reg 17) (const_int 0)])
17304 (match_operand:XF 2 "register_operand" "f,0")
17305 (match_operand:XF 3 "register_operand" "0,f")))]
17306 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17307 "@
17308 fcmov%F1\t{%2, %0|%0, %2}
17309 fcmov%f1\t{%3, %0|%0, %3}"
17310 [(set_attr "type" "fcmov")
17311 (set_attr "mode" "XF")])
17312
17313 (define_insn "*movtfcc_1"
17314 [(set (match_operand:TF 0 "register_operand" "=f,f")
17315 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
17316 [(reg 17) (const_int 0)])
17317 (match_operand:TF 2 "register_operand" "f,0")
17318 (match_operand:TF 3 "register_operand" "0,f")))]
17319 "TARGET_CMOVE"
17320 "@
17321 fcmov%F1\t{%2, %0|%0, %2}
17322 fcmov%f1\t{%3, %0|%0, %3}"
17323 [(set_attr "type" "fcmov")
17324 (set_attr "mode" "XF")])
17325
17326 (define_expand "minsf3"
17327 [(parallel [
17328 (set (match_operand:SF 0 "register_operand" "")
17329 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17330 (match_operand:SF 2 "nonimmediate_operand" ""))
17331 (match_dup 1)
17332 (match_dup 2)))
17333 (clobber (reg:CC 17))])]
17334 "TARGET_SSE"
17335 "")
17336
17337 (define_insn "*minsf"
17338 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17339 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17340 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17341 (match_dup 1)
17342 (match_dup 2)))
17343 (clobber (reg:CC 17))]
17344 "TARGET_SSE && TARGET_IEEE_FP"
17345 "#")
17346
17347 (define_insn "*minsf_nonieee"
17348 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17349 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17350 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17351 (match_dup 1)
17352 (match_dup 2)))
17353 (clobber (reg:CC 17))]
17354 "TARGET_SSE && !TARGET_IEEE_FP
17355 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17356 "#")
17357
17358 (define_split
17359 [(set (match_operand:SF 0 "register_operand" "")
17360 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17361 (match_operand:SF 2 "nonimmediate_operand" ""))
17362 (match_operand:SF 3 "register_operand" "")
17363 (match_operand:SF 4 "nonimmediate_operand" "")))
17364 (clobber (reg:CC 17))]
17365 "SSE_REG_P (operands[0]) && reload_completed
17366 && ((operands_match_p (operands[1], operands[3])
17367 && operands_match_p (operands[2], operands[4]))
17368 || (operands_match_p (operands[1], operands[4])
17369 && operands_match_p (operands[2], operands[3])))"
17370 [(set (match_dup 0)
17371 (if_then_else:SF (lt (match_dup 1)
17372 (match_dup 2))
17373 (match_dup 1)
17374 (match_dup 2)))])
17375
17376 ;; Conditional addition patterns
17377 (define_expand "addqicc"
17378 [(match_operand:QI 0 "register_operand" "")
17379 (match_operand 1 "comparison_operator" "")
17380 (match_operand:QI 2 "register_operand" "")
17381 (match_operand:QI 3 "const_int_operand" "")]
17382 ""
17383 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17384
17385 (define_expand "addhicc"
17386 [(match_operand:HI 0 "register_operand" "")
17387 (match_operand 1 "comparison_operator" "")
17388 (match_operand:HI 2 "register_operand" "")
17389 (match_operand:HI 3 "const_int_operand" "")]
17390 ""
17391 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17392
17393 (define_expand "addsicc"
17394 [(match_operand:SI 0 "register_operand" "")
17395 (match_operand 1 "comparison_operator" "")
17396 (match_operand:SI 2 "register_operand" "")
17397 (match_operand:SI 3 "const_int_operand" "")]
17398 ""
17399 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17400
17401 (define_expand "adddicc"
17402 [(match_operand:DI 0 "register_operand" "")
17403 (match_operand 1 "comparison_operator" "")
17404 (match_operand:DI 2 "register_operand" "")
17405 (match_operand:DI 3 "const_int_operand" "")]
17406 "TARGET_64BIT"
17407 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17408
17409 ;; We can't represent the LT test directly. Do this by swapping the operands.
17410
17411 (define_split
17412 [(set (match_operand:SF 0 "fp_register_operand" "")
17413 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17414 (match_operand:SF 2 "register_operand" ""))
17415 (match_operand:SF 3 "register_operand" "")
17416 (match_operand:SF 4 "register_operand" "")))
17417 (clobber (reg:CC 17))]
17418 "reload_completed
17419 && ((operands_match_p (operands[1], operands[3])
17420 && operands_match_p (operands[2], operands[4]))
17421 || (operands_match_p (operands[1], operands[4])
17422 && operands_match_p (operands[2], operands[3])))"
17423 [(set (reg:CCFP 17)
17424 (compare:CCFP (match_dup 2)
17425 (match_dup 1)))
17426 (set (match_dup 0)
17427 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17428 (match_dup 1)
17429 (match_dup 2)))])
17430
17431 (define_insn "*minsf_sse"
17432 [(set (match_operand:SF 0 "register_operand" "=x")
17433 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17434 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17435 (match_dup 1)
17436 (match_dup 2)))]
17437 "TARGET_SSE && reload_completed"
17438 "minss\t{%2, %0|%0, %2}"
17439 [(set_attr "type" "sse")
17440 (set_attr "mode" "SF")])
17441
17442 (define_expand "mindf3"
17443 [(parallel [
17444 (set (match_operand:DF 0 "register_operand" "")
17445 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17446 (match_operand:DF 2 "nonimmediate_operand" ""))
17447 (match_dup 1)
17448 (match_dup 2)))
17449 (clobber (reg:CC 17))])]
17450 "TARGET_SSE2 && TARGET_SSE_MATH"
17451 "#")
17452
17453 (define_insn "*mindf"
17454 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17455 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17456 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17457 (match_dup 1)
17458 (match_dup 2)))
17459 (clobber (reg:CC 17))]
17460 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17461 "#")
17462
17463 (define_insn "*mindf_nonieee"
17464 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17465 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17466 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17467 (match_dup 1)
17468 (match_dup 2)))
17469 (clobber (reg:CC 17))]
17470 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17471 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17472 "#")
17473
17474 (define_split
17475 [(set (match_operand:DF 0 "register_operand" "")
17476 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17477 (match_operand:DF 2 "nonimmediate_operand" ""))
17478 (match_operand:DF 3 "register_operand" "")
17479 (match_operand:DF 4 "nonimmediate_operand" "")))
17480 (clobber (reg:CC 17))]
17481 "SSE_REG_P (operands[0]) && reload_completed
17482 && ((operands_match_p (operands[1], operands[3])
17483 && operands_match_p (operands[2], operands[4]))
17484 || (operands_match_p (operands[1], operands[4])
17485 && operands_match_p (operands[2], operands[3])))"
17486 [(set (match_dup 0)
17487 (if_then_else:DF (lt (match_dup 1)
17488 (match_dup 2))
17489 (match_dup 1)
17490 (match_dup 2)))])
17491
17492 ;; We can't represent the LT test directly. Do this by swapping the operands.
17493 (define_split
17494 [(set (match_operand:DF 0 "fp_register_operand" "")
17495 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17496 (match_operand:DF 2 "register_operand" ""))
17497 (match_operand:DF 3 "register_operand" "")
17498 (match_operand:DF 4 "register_operand" "")))
17499 (clobber (reg:CC 17))]
17500 "reload_completed
17501 && ((operands_match_p (operands[1], operands[3])
17502 && operands_match_p (operands[2], operands[4]))
17503 || (operands_match_p (operands[1], operands[4])
17504 && operands_match_p (operands[2], operands[3])))"
17505 [(set (reg:CCFP 17)
17506 (compare:CCFP (match_dup 2)
17507 (match_dup 2)))
17508 (set (match_dup 0)
17509 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17510 (match_dup 1)
17511 (match_dup 2)))])
17512
17513 (define_insn "*mindf_sse"
17514 [(set (match_operand:DF 0 "register_operand" "=Y")
17515 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17516 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17517 (match_dup 1)
17518 (match_dup 2)))]
17519 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17520 "minsd\t{%2, %0|%0, %2}"
17521 [(set_attr "type" "sse")
17522 (set_attr "mode" "DF")])
17523
17524 (define_expand "maxsf3"
17525 [(parallel [
17526 (set (match_operand:SF 0 "register_operand" "")
17527 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17528 (match_operand:SF 2 "nonimmediate_operand" ""))
17529 (match_dup 1)
17530 (match_dup 2)))
17531 (clobber (reg:CC 17))])]
17532 "TARGET_SSE"
17533 "#")
17534
17535 (define_insn "*maxsf"
17536 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17537 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17538 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17539 (match_dup 1)
17540 (match_dup 2)))
17541 (clobber (reg:CC 17))]
17542 "TARGET_SSE && TARGET_IEEE_FP"
17543 "#")
17544
17545 (define_insn "*maxsf_nonieee"
17546 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17547 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17548 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17549 (match_dup 1)
17550 (match_dup 2)))
17551 (clobber (reg:CC 17))]
17552 "TARGET_SSE && !TARGET_IEEE_FP
17553 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17554 "#")
17555
17556 (define_split
17557 [(set (match_operand:SF 0 "register_operand" "")
17558 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17559 (match_operand:SF 2 "nonimmediate_operand" ""))
17560 (match_operand:SF 3 "register_operand" "")
17561 (match_operand:SF 4 "nonimmediate_operand" "")))
17562 (clobber (reg:CC 17))]
17563 "SSE_REG_P (operands[0]) && reload_completed
17564 && ((operands_match_p (operands[1], operands[3])
17565 && operands_match_p (operands[2], operands[4]))
17566 || (operands_match_p (operands[1], operands[4])
17567 && operands_match_p (operands[2], operands[3])))"
17568 [(set (match_dup 0)
17569 (if_then_else:SF (gt (match_dup 1)
17570 (match_dup 2))
17571 (match_dup 1)
17572 (match_dup 2)))])
17573
17574 (define_split
17575 [(set (match_operand:SF 0 "fp_register_operand" "")
17576 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17577 (match_operand:SF 2 "register_operand" ""))
17578 (match_operand:SF 3 "register_operand" "")
17579 (match_operand:SF 4 "register_operand" "")))
17580 (clobber (reg:CC 17))]
17581 "reload_completed
17582 && ((operands_match_p (operands[1], operands[3])
17583 && operands_match_p (operands[2], operands[4]))
17584 || (operands_match_p (operands[1], operands[4])
17585 && operands_match_p (operands[2], operands[3])))"
17586 [(set (reg:CCFP 17)
17587 (compare:CCFP (match_dup 1)
17588 (match_dup 2)))
17589 (set (match_dup 0)
17590 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17591 (match_dup 1)
17592 (match_dup 2)))])
17593
17594 (define_insn "*maxsf_sse"
17595 [(set (match_operand:SF 0 "register_operand" "=x")
17596 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17597 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17598 (match_dup 1)
17599 (match_dup 2)))]
17600 "TARGET_SSE && reload_completed"
17601 "maxss\t{%2, %0|%0, %2}"
17602 [(set_attr "type" "sse")
17603 (set_attr "mode" "SF")])
17604
17605 (define_expand "maxdf3"
17606 [(parallel [
17607 (set (match_operand:DF 0 "register_operand" "")
17608 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17609 (match_operand:DF 2 "nonimmediate_operand" ""))
17610 (match_dup 1)
17611 (match_dup 2)))
17612 (clobber (reg:CC 17))])]
17613 "TARGET_SSE2 && TARGET_SSE_MATH"
17614 "#")
17615
17616 (define_insn "*maxdf"
17617 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17618 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17619 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17620 (match_dup 1)
17621 (match_dup 2)))
17622 (clobber (reg:CC 17))]
17623 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17624 "#")
17625
17626 (define_insn "*maxdf_nonieee"
17627 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17628 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17629 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17630 (match_dup 1)
17631 (match_dup 2)))
17632 (clobber (reg:CC 17))]
17633 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17634 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17635 "#")
17636
17637 (define_split
17638 [(set (match_operand:DF 0 "register_operand" "")
17639 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17640 (match_operand:DF 2 "nonimmediate_operand" ""))
17641 (match_operand:DF 3 "register_operand" "")
17642 (match_operand:DF 4 "nonimmediate_operand" "")))
17643 (clobber (reg:CC 17))]
17644 "SSE_REG_P (operands[0]) && reload_completed
17645 && ((operands_match_p (operands[1], operands[3])
17646 && operands_match_p (operands[2], operands[4]))
17647 || (operands_match_p (operands[1], operands[4])
17648 && operands_match_p (operands[2], operands[3])))"
17649 [(set (match_dup 0)
17650 (if_then_else:DF (gt (match_dup 1)
17651 (match_dup 2))
17652 (match_dup 1)
17653 (match_dup 2)))])
17654
17655 (define_split
17656 [(set (match_operand:DF 0 "fp_register_operand" "")
17657 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17658 (match_operand:DF 2 "register_operand" ""))
17659 (match_operand:DF 3 "register_operand" "")
17660 (match_operand:DF 4 "register_operand" "")))
17661 (clobber (reg:CC 17))]
17662 "reload_completed
17663 && ((operands_match_p (operands[1], operands[3])
17664 && operands_match_p (operands[2], operands[4]))
17665 || (operands_match_p (operands[1], operands[4])
17666 && operands_match_p (operands[2], operands[3])))"
17667 [(set (reg:CCFP 17)
17668 (compare:CCFP (match_dup 1)
17669 (match_dup 2)))
17670 (set (match_dup 0)
17671 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17672 (match_dup 1)
17673 (match_dup 2)))])
17674
17675 (define_insn "*maxdf_sse"
17676 [(set (match_operand:DF 0 "register_operand" "=Y")
17677 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17678 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17679 (match_dup 1)
17680 (match_dup 2)))]
17681 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17682 "maxsd\t{%2, %0|%0, %2}"
17683 [(set_attr "type" "sse")
17684 (set_attr "mode" "DF")])
17685 \f
17686 ;; Misc patterns (?)
17687
17688 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17689 ;; Otherwise there will be nothing to keep
17690 ;;
17691 ;; [(set (reg ebp) (reg esp))]
17692 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17693 ;; (clobber (eflags)]
17694 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17695 ;;
17696 ;; in proper program order.
17697 (define_expand "pro_epilogue_adjust_stack"
17698 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17699 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17700 (match_operand:SI 2 "immediate_operand" "i,i")))
17701 (clobber (reg:CC 17))
17702 (clobber (mem:BLK (scratch)))])]
17703 ""
17704 {
17705 if (TARGET_64BIT)
17706 {
17707 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17708 (operands[0], operands[1], operands[2]));
17709 DONE;
17710 }
17711 })
17712
17713 (define_insn "*pro_epilogue_adjust_stack_1"
17714 [(set (match_operand:SI 0 "register_operand" "=r,r")
17715 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17716 (match_operand:SI 2 "immediate_operand" "i,i")))
17717 (clobber (reg:CC 17))
17718 (clobber (mem:BLK (scratch)))]
17719 "!TARGET_64BIT"
17720 {
17721 switch (get_attr_type (insn))
17722 {
17723 case TYPE_IMOV:
17724 return "mov{l}\t{%1, %0|%0, %1}";
17725
17726 case TYPE_ALU:
17727 if (GET_CODE (operands[2]) == CONST_INT
17728 && (INTVAL (operands[2]) == 128
17729 || (INTVAL (operands[2]) < 0
17730 && INTVAL (operands[2]) != -128)))
17731 {
17732 operands[2] = GEN_INT (-INTVAL (operands[2]));
17733 return "sub{l}\t{%2, %0|%0, %2}";
17734 }
17735 return "add{l}\t{%2, %0|%0, %2}";
17736
17737 case TYPE_LEA:
17738 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17739 return "lea{l}\t{%a2, %0|%0, %a2}";
17740
17741 default:
17742 abort ();
17743 }
17744 }
17745 [(set (attr "type")
17746 (cond [(eq_attr "alternative" "0")
17747 (const_string "alu")
17748 (match_operand:SI 2 "const0_operand" "")
17749 (const_string "imov")
17750 ]
17751 (const_string "lea")))
17752 (set_attr "mode" "SI")])
17753
17754 (define_insn "pro_epilogue_adjust_stack_rex64"
17755 [(set (match_operand:DI 0 "register_operand" "=r,r")
17756 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17757 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17758 (clobber (reg:CC 17))
17759 (clobber (mem:BLK (scratch)))]
17760 "TARGET_64BIT"
17761 {
17762 switch (get_attr_type (insn))
17763 {
17764 case TYPE_IMOV:
17765 return "mov{q}\t{%1, %0|%0, %1}";
17766
17767 case TYPE_ALU:
17768 if (GET_CODE (operands[2]) == CONST_INT
17769 && (INTVAL (operands[2]) == 128
17770 || (INTVAL (operands[2]) < 0
17771 && INTVAL (operands[2]) != -128)))
17772 {
17773 operands[2] = GEN_INT (-INTVAL (operands[2]));
17774 return "sub{q}\t{%2, %0|%0, %2}";
17775 }
17776 return "add{q}\t{%2, %0|%0, %2}";
17777
17778 case TYPE_LEA:
17779 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17780 return "lea{q}\t{%a2, %0|%0, %a2}";
17781
17782 default:
17783 abort ();
17784 }
17785 }
17786 [(set (attr "type")
17787 (cond [(eq_attr "alternative" "0")
17788 (const_string "alu")
17789 (match_operand:DI 2 "const0_operand" "")
17790 (const_string "imov")
17791 ]
17792 (const_string "lea")))
17793 (set_attr "mode" "DI")])
17794
17795
17796 ;; Placeholder for the conditional moves. This one is split either to SSE
17797 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17798 ;; fact is that compares supported by the cmp??ss instructions are exactly
17799 ;; swapped of those supported by cmove sequence.
17800 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17801 ;; supported by i387 comparisons and we do need to emit two conditional moves
17802 ;; in tandem.
17803
17804 (define_insn "sse_movsfcc"
17805 [(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")
17806 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17807 [(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")
17808 (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")])
17809 (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")
17810 (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")))
17811 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17812 (clobber (reg:CC 17))]
17813 "TARGET_SSE
17814 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17815 /* Avoid combine from being smart and converting min/max
17816 instruction patterns into conditional moves. */
17817 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17818 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17819 || !rtx_equal_p (operands[4], operands[2])
17820 || !rtx_equal_p (operands[5], operands[3]))
17821 && (!TARGET_IEEE_FP
17822 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17823 "#")
17824
17825 (define_insn "sse_movsfcc_eq"
17826 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17827 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17828 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17829 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17830 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17831 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17832 (clobber (reg:CC 17))]
17833 "TARGET_SSE
17834 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17835 "#")
17836
17837 (define_insn "sse_movdfcc"
17838 [(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")
17839 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17840 [(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")
17841 (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")])
17842 (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")
17843 (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")))
17844 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17845 (clobber (reg:CC 17))]
17846 "TARGET_SSE2
17847 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17848 /* Avoid combine from being smart and converting min/max
17849 instruction patterns into conditional moves. */
17850 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17851 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17852 || !rtx_equal_p (operands[4], operands[2])
17853 || !rtx_equal_p (operands[5], operands[3]))
17854 && (!TARGET_IEEE_FP
17855 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17856 "#")
17857
17858 (define_insn "sse_movdfcc_eq"
17859 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17860 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17861 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17862 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17863 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17864 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17865 (clobber (reg:CC 17))]
17866 "TARGET_SSE
17867 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17868 "#")
17869
17870 ;; For non-sse moves just expand the usual cmove sequence.
17871 (define_split
17872 [(set (match_operand 0 "register_operand" "")
17873 (if_then_else (match_operator 1 "comparison_operator"
17874 [(match_operand 4 "nonimmediate_operand" "")
17875 (match_operand 5 "register_operand" "")])
17876 (match_operand 2 "nonimmediate_operand" "")
17877 (match_operand 3 "nonimmediate_operand" "")))
17878 (clobber (match_operand 6 "" ""))
17879 (clobber (reg:CC 17))]
17880 "!SSE_REG_P (operands[0]) && reload_completed
17881 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17882 [(const_int 0)]
17883 {
17884 ix86_compare_op0 = operands[5];
17885 ix86_compare_op1 = operands[4];
17886 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17887 VOIDmode, operands[5], operands[4]);
17888 ix86_expand_fp_movcc (operands);
17889 DONE;
17890 })
17891
17892 ;; Split SSE based conditional move into sequence:
17893 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17894 ;; and op2, op0 - zero op2 if comparison was false
17895 ;; nand op0, op3 - load op3 to op0 if comparison was false
17896 ;; or op2, op0 - get the nonzero one into the result.
17897 (define_split
17898 [(set (match_operand 0 "register_operand" "")
17899 (if_then_else (match_operator 1 "sse_comparison_operator"
17900 [(match_operand 4 "register_operand" "")
17901 (match_operand 5 "nonimmediate_operand" "")])
17902 (match_operand 2 "register_operand" "")
17903 (match_operand 3 "register_operand" "")))
17904 (clobber (match_operand 6 "" ""))
17905 (clobber (reg:CC 17))]
17906 "SSE_REG_P (operands[0]) && reload_completed"
17907 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17908 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17909 (subreg:TI (match_dup 4) 0)))
17910 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17911 (subreg:TI (match_dup 3) 0)))
17912 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17913 (subreg:TI (match_dup 7) 0)))]
17914 {
17915 if (GET_MODE (operands[2]) == DFmode
17916 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17917 {
17918 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17919 emit_insn (gen_sse2_unpcklpd (op, op, op));
17920 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17921 emit_insn (gen_sse2_unpcklpd (op, op, op));
17922 }
17923
17924 /* If op2 == op3, op3 would be clobbered before it is used. */
17925 if (operands_match_p (operands[2], operands[3]))
17926 {
17927 emit_move_insn (operands[0], operands[2]);
17928 DONE;
17929 }
17930
17931 PUT_MODE (operands[1], GET_MODE (operands[0]));
17932 if (operands_match_p (operands[0], operands[4]))
17933 operands[6] = operands[4], operands[7] = operands[2];
17934 else
17935 operands[6] = operands[2], operands[7] = operands[4];
17936 })
17937
17938 ;; Special case of conditional move we can handle effectively.
17939 ;; Do not brother with the integer/floating point case, since these are
17940 ;; bot considerably slower, unlike in the generic case.
17941 (define_insn "*sse_movsfcc_const0_1"
17942 [(set (match_operand:SF 0 "register_operand" "=&x")
17943 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17944 [(match_operand:SF 4 "register_operand" "0")
17945 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17946 (match_operand:SF 2 "register_operand" "x")
17947 (match_operand:SF 3 "const0_operand" "X")))]
17948 "TARGET_SSE"
17949 "#")
17950
17951 (define_insn "*sse_movsfcc_const0_2"
17952 [(set (match_operand:SF 0 "register_operand" "=&x")
17953 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17954 [(match_operand:SF 4 "register_operand" "0")
17955 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17956 (match_operand:SF 2 "const0_operand" "X")
17957 (match_operand:SF 3 "register_operand" "x")))]
17958 "TARGET_SSE"
17959 "#")
17960
17961 (define_insn "*sse_movsfcc_const0_3"
17962 [(set (match_operand:SF 0 "register_operand" "=&x")
17963 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17964 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17965 (match_operand:SF 5 "register_operand" "0")])
17966 (match_operand:SF 2 "register_operand" "x")
17967 (match_operand:SF 3 "const0_operand" "X")))]
17968 "TARGET_SSE"
17969 "#")
17970
17971 (define_insn "*sse_movsfcc_const0_4"
17972 [(set (match_operand:SF 0 "register_operand" "=&x")
17973 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17974 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17975 (match_operand:SF 5 "register_operand" "0")])
17976 (match_operand:SF 2 "const0_operand" "X")
17977 (match_operand:SF 3 "register_operand" "x")))]
17978 "TARGET_SSE"
17979 "#")
17980
17981 (define_insn "*sse_movdfcc_const0_1"
17982 [(set (match_operand:DF 0 "register_operand" "=&Y")
17983 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17984 [(match_operand:DF 4 "register_operand" "0")
17985 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17986 (match_operand:DF 2 "register_operand" "Y")
17987 (match_operand:DF 3 "const0_operand" "X")))]
17988 "TARGET_SSE2"
17989 "#")
17990
17991 (define_insn "*sse_movdfcc_const0_2"
17992 [(set (match_operand:DF 0 "register_operand" "=&Y")
17993 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17994 [(match_operand:DF 4 "register_operand" "0")
17995 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17996 (match_operand:DF 2 "const0_operand" "X")
17997 (match_operand:DF 3 "register_operand" "Y")))]
17998 "TARGET_SSE2"
17999 "#")
18000
18001 (define_insn "*sse_movdfcc_const0_3"
18002 [(set (match_operand:DF 0 "register_operand" "=&Y")
18003 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18004 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18005 (match_operand:DF 5 "register_operand" "0")])
18006 (match_operand:DF 2 "register_operand" "Y")
18007 (match_operand:DF 3 "const0_operand" "X")))]
18008 "TARGET_SSE2"
18009 "#")
18010
18011 (define_insn "*sse_movdfcc_const0_4"
18012 [(set (match_operand:DF 0 "register_operand" "=&Y")
18013 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18014 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18015 (match_operand:DF 5 "register_operand" "0")])
18016 (match_operand:DF 2 "const0_operand" "X")
18017 (match_operand:DF 3 "register_operand" "Y")))]
18018 "TARGET_SSE2"
18019 "#")
18020
18021 (define_split
18022 [(set (match_operand 0 "register_operand" "")
18023 (if_then_else (match_operator 1 "comparison_operator"
18024 [(match_operand 4 "nonimmediate_operand" "")
18025 (match_operand 5 "nonimmediate_operand" "")])
18026 (match_operand 2 "nonmemory_operand" "")
18027 (match_operand 3 "nonmemory_operand" "")))]
18028 "SSE_REG_P (operands[0]) && reload_completed
18029 && (const0_operand (operands[2], GET_MODE (operands[0]))
18030 || const0_operand (operands[3], GET_MODE (operands[0])))"
18031 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18032 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
18033 (match_dup 7)))]
18034 {
18035 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18036 && GET_MODE (operands[2]) == DFmode)
18037 {
18038 if (REG_P (operands[2]))
18039 {
18040 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18041 emit_insn (gen_sse2_unpcklpd (op, op, op));
18042 }
18043 if (REG_P (operands[3]))
18044 {
18045 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18046 emit_insn (gen_sse2_unpcklpd (op, op, op));
18047 }
18048 }
18049 PUT_MODE (operands[1], GET_MODE (operands[0]));
18050 if (!sse_comparison_operator (operands[1], VOIDmode)
18051 || !rtx_equal_p (operands[0], operands[4]))
18052 {
18053 rtx tmp = operands[5];
18054 operands[5] = operands[4];
18055 operands[4] = tmp;
18056 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18057 }
18058 if (!rtx_equal_p (operands[0], operands[4]))
18059 abort ();
18060 if (const0_operand (operands[2], GET_MODE (operands[0])))
18061 {
18062 operands[7] = operands[3];
18063 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
18064 0));
18065 }
18066 else
18067 {
18068 operands[7] = operands[2];
18069 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
18070 }
18071 operands[7] = simplify_gen_subreg (TImode, operands[7],
18072 GET_MODE (operands[7]), 0);
18073 })
18074
18075 (define_expand "allocate_stack_worker"
18076 [(match_operand:SI 0 "register_operand" "")]
18077 "TARGET_STACK_PROBE"
18078 {
18079 if (TARGET_64BIT)
18080 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18081 else
18082 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18083 DONE;
18084 })
18085
18086 (define_insn "allocate_stack_worker_1"
18087 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18088 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
18089 (clobber (match_dup 0))
18090 (clobber (reg:CC 17))]
18091 "!TARGET_64BIT && TARGET_STACK_PROBE"
18092 "call\t__alloca"
18093 [(set_attr "type" "multi")
18094 (set_attr "length" "5")])
18095
18096 (define_insn "allocate_stack_worker_rex64"
18097 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18098 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
18099 (clobber (match_dup 0))
18100 (clobber (reg:CC 17))]
18101 "TARGET_64BIT && TARGET_STACK_PROBE"
18102 "call\t__alloca"
18103 [(set_attr "type" "multi")
18104 (set_attr "length" "5")])
18105
18106 (define_expand "allocate_stack"
18107 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18108 (minus:SI (reg:SI 7)
18109 (match_operand:SI 1 "general_operand" "")))
18110 (clobber (reg:CC 17))])
18111 (parallel [(set (reg:SI 7)
18112 (minus:SI (reg:SI 7) (match_dup 1)))
18113 (clobber (reg:CC 17))])]
18114 "TARGET_STACK_PROBE"
18115 {
18116 #ifdef CHECK_STACK_LIMIT
18117 if (GET_CODE (operands[1]) == CONST_INT
18118 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18119 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18120 operands[1]));
18121 else
18122 #endif
18123 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18124 operands[1])));
18125
18126 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18127 DONE;
18128 })
18129
18130 (define_expand "builtin_setjmp_receiver"
18131 [(label_ref (match_operand 0 "" ""))]
18132 "!TARGET_64BIT && flag_pic"
18133 {
18134 emit_insn (gen_set_got (pic_offset_table_rtx));
18135 DONE;
18136 })
18137 \f
18138 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18139
18140 (define_split
18141 [(set (match_operand 0 "register_operand" "")
18142 (match_operator 3 "promotable_binary_operator"
18143 [(match_operand 1 "register_operand" "")
18144 (match_operand 2 "aligned_operand" "")]))
18145 (clobber (reg:CC 17))]
18146 "! TARGET_PARTIAL_REG_STALL && reload_completed
18147 && ((GET_MODE (operands[0]) == HImode
18148 && ((!optimize_size && !TARGET_FAST_PREFIX)
18149 || GET_CODE (operands[2]) != CONST_INT
18150 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18151 || (GET_MODE (operands[0]) == QImode
18152 && (TARGET_PROMOTE_QImode || optimize_size)))"
18153 [(parallel [(set (match_dup 0)
18154 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18155 (clobber (reg:CC 17))])]
18156 "operands[0] = gen_lowpart (SImode, operands[0]);
18157 operands[1] = gen_lowpart (SImode, operands[1]);
18158 if (GET_CODE (operands[3]) != ASHIFT)
18159 operands[2] = gen_lowpart (SImode, operands[2]);
18160 PUT_MODE (operands[3], SImode);")
18161
18162 ; Promote the QImode tests, as i386 has encoding of the AND
18163 ; instruction with 32-bit sign-extended immediate and thus the
18164 ; instruction size is unchanged, except in the %eax case for
18165 ; which it is increased by one byte, hence the ! optimize_size.
18166 (define_split
18167 [(set (reg 17)
18168 (compare (and (match_operand 1 "aligned_operand" "")
18169 (match_operand 2 "const_int_operand" ""))
18170 (const_int 0)))
18171 (set (match_operand 0 "register_operand" "")
18172 (and (match_dup 1) (match_dup 2)))]
18173 "! TARGET_PARTIAL_REG_STALL && reload_completed
18174 /* Ensure that the operand will remain sign-extended immediate. */
18175 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18176 && ! optimize_size
18177 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18178 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18179 [(parallel [(set (reg:CCNO 17)
18180 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18181 (const_int 0)))
18182 (set (match_dup 0)
18183 (and:SI (match_dup 1) (match_dup 2)))])]
18184 "operands[2]
18185 = gen_int_mode (INTVAL (operands[2])
18186 & GET_MODE_MASK (GET_MODE (operands[0])),
18187 SImode);
18188 operands[0] = gen_lowpart (SImode, operands[0]);
18189 operands[1] = gen_lowpart (SImode, operands[1]);")
18190
18191 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18192 ; the TEST instruction with 32-bit sign-extended immediate and thus
18193 ; the instruction size would at least double, which is not what we
18194 ; want even with ! optimize_size.
18195 (define_split
18196 [(set (reg 17)
18197 (compare (and (match_operand:HI 0 "aligned_operand" "")
18198 (match_operand:HI 1 "const_int_operand" ""))
18199 (const_int 0)))]
18200 "! TARGET_PARTIAL_REG_STALL && reload_completed
18201 /* Ensure that the operand will remain sign-extended immediate. */
18202 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18203 && ! TARGET_FAST_PREFIX
18204 && ! optimize_size"
18205 [(set (reg:CCNO 17)
18206 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18207 (const_int 0)))]
18208 "operands[1]
18209 = gen_int_mode (INTVAL (operands[1])
18210 & GET_MODE_MASK (GET_MODE (operands[0])),
18211 SImode);
18212 operands[0] = gen_lowpart (SImode, operands[0]);")
18213
18214 (define_split
18215 [(set (match_operand 0 "register_operand" "")
18216 (neg (match_operand 1 "register_operand" "")))
18217 (clobber (reg:CC 17))]
18218 "! TARGET_PARTIAL_REG_STALL && reload_completed
18219 && (GET_MODE (operands[0]) == HImode
18220 || (GET_MODE (operands[0]) == QImode
18221 && (TARGET_PROMOTE_QImode || optimize_size)))"
18222 [(parallel [(set (match_dup 0)
18223 (neg:SI (match_dup 1)))
18224 (clobber (reg:CC 17))])]
18225 "operands[0] = gen_lowpart (SImode, operands[0]);
18226 operands[1] = gen_lowpart (SImode, operands[1]);")
18227
18228 (define_split
18229 [(set (match_operand 0 "register_operand" "")
18230 (not (match_operand 1 "register_operand" "")))]
18231 "! TARGET_PARTIAL_REG_STALL && reload_completed
18232 && (GET_MODE (operands[0]) == HImode
18233 || (GET_MODE (operands[0]) == QImode
18234 && (TARGET_PROMOTE_QImode || optimize_size)))"
18235 [(set (match_dup 0)
18236 (not:SI (match_dup 1)))]
18237 "operands[0] = gen_lowpart (SImode, operands[0]);
18238 operands[1] = gen_lowpart (SImode, operands[1]);")
18239
18240 (define_split
18241 [(set (match_operand 0 "register_operand" "")
18242 (if_then_else (match_operator 1 "comparison_operator"
18243 [(reg 17) (const_int 0)])
18244 (match_operand 2 "register_operand" "")
18245 (match_operand 3 "register_operand" "")))]
18246 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18247 && (GET_MODE (operands[0]) == HImode
18248 || (GET_MODE (operands[0]) == QImode
18249 && (TARGET_PROMOTE_QImode || optimize_size)))"
18250 [(set (match_dup 0)
18251 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18252 "operands[0] = gen_lowpart (SImode, operands[0]);
18253 operands[2] = gen_lowpart (SImode, operands[2]);
18254 operands[3] = gen_lowpart (SImode, operands[3]);")
18255
18256 \f
18257 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18258 ;; transform a complex memory operation into two memory to register operations.
18259
18260 ;; Don't push memory operands
18261 (define_peephole2
18262 [(set (match_operand:SI 0 "push_operand" "")
18263 (match_operand:SI 1 "memory_operand" ""))
18264 (match_scratch:SI 2 "r")]
18265 "! optimize_size && ! TARGET_PUSH_MEMORY"
18266 [(set (match_dup 2) (match_dup 1))
18267 (set (match_dup 0) (match_dup 2))]
18268 "")
18269
18270 (define_peephole2
18271 [(set (match_operand:DI 0 "push_operand" "")
18272 (match_operand:DI 1 "memory_operand" ""))
18273 (match_scratch:DI 2 "r")]
18274 "! optimize_size && ! TARGET_PUSH_MEMORY"
18275 [(set (match_dup 2) (match_dup 1))
18276 (set (match_dup 0) (match_dup 2))]
18277 "")
18278
18279 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18280 ;; SImode pushes.
18281 (define_peephole2
18282 [(set (match_operand:SF 0 "push_operand" "")
18283 (match_operand:SF 1 "memory_operand" ""))
18284 (match_scratch:SF 2 "r")]
18285 "! optimize_size && ! TARGET_PUSH_MEMORY"
18286 [(set (match_dup 2) (match_dup 1))
18287 (set (match_dup 0) (match_dup 2))]
18288 "")
18289
18290 (define_peephole2
18291 [(set (match_operand:HI 0 "push_operand" "")
18292 (match_operand:HI 1 "memory_operand" ""))
18293 (match_scratch:HI 2 "r")]
18294 "! optimize_size && ! TARGET_PUSH_MEMORY"
18295 [(set (match_dup 2) (match_dup 1))
18296 (set (match_dup 0) (match_dup 2))]
18297 "")
18298
18299 (define_peephole2
18300 [(set (match_operand:QI 0 "push_operand" "")
18301 (match_operand:QI 1 "memory_operand" ""))
18302 (match_scratch:QI 2 "q")]
18303 "! optimize_size && ! TARGET_PUSH_MEMORY"
18304 [(set (match_dup 2) (match_dup 1))
18305 (set (match_dup 0) (match_dup 2))]
18306 "")
18307
18308 ;; Don't move an immediate directly to memory when the instruction
18309 ;; gets too big.
18310 (define_peephole2
18311 [(match_scratch:SI 1 "r")
18312 (set (match_operand:SI 0 "memory_operand" "")
18313 (const_int 0))]
18314 "! optimize_size
18315 && ! TARGET_USE_MOV0
18316 && TARGET_SPLIT_LONG_MOVES
18317 && get_attr_length (insn) >= ix86_cost->large_insn
18318 && peep2_regno_dead_p (0, FLAGS_REG)"
18319 [(parallel [(set (match_dup 1) (const_int 0))
18320 (clobber (reg:CC 17))])
18321 (set (match_dup 0) (match_dup 1))]
18322 "")
18323
18324 (define_peephole2
18325 [(match_scratch:HI 1 "r")
18326 (set (match_operand:HI 0 "memory_operand" "")
18327 (const_int 0))]
18328 "! optimize_size
18329 && ! TARGET_USE_MOV0
18330 && TARGET_SPLIT_LONG_MOVES
18331 && get_attr_length (insn) >= ix86_cost->large_insn
18332 && peep2_regno_dead_p (0, FLAGS_REG)"
18333 [(parallel [(set (match_dup 2) (const_int 0))
18334 (clobber (reg:CC 17))])
18335 (set (match_dup 0) (match_dup 1))]
18336 "operands[2] = gen_lowpart (SImode, operands[1]);")
18337
18338 (define_peephole2
18339 [(match_scratch:QI 1 "q")
18340 (set (match_operand:QI 0 "memory_operand" "")
18341 (const_int 0))]
18342 "! optimize_size
18343 && ! TARGET_USE_MOV0
18344 && TARGET_SPLIT_LONG_MOVES
18345 && get_attr_length (insn) >= ix86_cost->large_insn
18346 && peep2_regno_dead_p (0, FLAGS_REG)"
18347 [(parallel [(set (match_dup 2) (const_int 0))
18348 (clobber (reg:CC 17))])
18349 (set (match_dup 0) (match_dup 1))]
18350 "operands[2] = gen_lowpart (SImode, operands[1]);")
18351
18352 (define_peephole2
18353 [(match_scratch:SI 2 "r")
18354 (set (match_operand:SI 0 "memory_operand" "")
18355 (match_operand:SI 1 "immediate_operand" ""))]
18356 "! optimize_size
18357 && get_attr_length (insn) >= ix86_cost->large_insn
18358 && TARGET_SPLIT_LONG_MOVES"
18359 [(set (match_dup 2) (match_dup 1))
18360 (set (match_dup 0) (match_dup 2))]
18361 "")
18362
18363 (define_peephole2
18364 [(match_scratch:HI 2 "r")
18365 (set (match_operand:HI 0 "memory_operand" "")
18366 (match_operand:HI 1 "immediate_operand" ""))]
18367 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18368 && TARGET_SPLIT_LONG_MOVES"
18369 [(set (match_dup 2) (match_dup 1))
18370 (set (match_dup 0) (match_dup 2))]
18371 "")
18372
18373 (define_peephole2
18374 [(match_scratch:QI 2 "q")
18375 (set (match_operand:QI 0 "memory_operand" "")
18376 (match_operand:QI 1 "immediate_operand" ""))]
18377 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18378 && TARGET_SPLIT_LONG_MOVES"
18379 [(set (match_dup 2) (match_dup 1))
18380 (set (match_dup 0) (match_dup 2))]
18381 "")
18382
18383 ;; Don't compare memory with zero, load and use a test instead.
18384 (define_peephole2
18385 [(set (reg 17)
18386 (compare (match_operand:SI 0 "memory_operand" "")
18387 (const_int 0)))
18388 (match_scratch:SI 3 "r")]
18389 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18390 [(set (match_dup 3) (match_dup 0))
18391 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18392 "")
18393
18394 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18395 ;; Don't split NOTs with a displacement operand, because resulting XOR
18396 ;; will not be pairable anyway.
18397 ;;
18398 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18399 ;; represented using a modRM byte. The XOR replacement is long decoded,
18400 ;; so this split helps here as well.
18401 ;;
18402 ;; Note: Can't do this as a regular split because we can't get proper
18403 ;; lifetime information then.
18404
18405 (define_peephole2
18406 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18407 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18408 "!optimize_size
18409 && peep2_regno_dead_p (0, FLAGS_REG)
18410 && ((TARGET_PENTIUM
18411 && (GET_CODE (operands[0]) != MEM
18412 || !memory_displacement_operand (operands[0], SImode)))
18413 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18414 [(parallel [(set (match_dup 0)
18415 (xor:SI (match_dup 1) (const_int -1)))
18416 (clobber (reg:CC 17))])]
18417 "")
18418
18419 (define_peephole2
18420 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18421 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18422 "!optimize_size
18423 && peep2_regno_dead_p (0, FLAGS_REG)
18424 && ((TARGET_PENTIUM
18425 && (GET_CODE (operands[0]) != MEM
18426 || !memory_displacement_operand (operands[0], HImode)))
18427 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18428 [(parallel [(set (match_dup 0)
18429 (xor:HI (match_dup 1) (const_int -1)))
18430 (clobber (reg:CC 17))])]
18431 "")
18432
18433 (define_peephole2
18434 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18435 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18436 "!optimize_size
18437 && peep2_regno_dead_p (0, FLAGS_REG)
18438 && ((TARGET_PENTIUM
18439 && (GET_CODE (operands[0]) != MEM
18440 || !memory_displacement_operand (operands[0], QImode)))
18441 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18442 [(parallel [(set (match_dup 0)
18443 (xor:QI (match_dup 1) (const_int -1)))
18444 (clobber (reg:CC 17))])]
18445 "")
18446
18447 ;; Non pairable "test imm, reg" instructions can be translated to
18448 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18449 ;; byte opcode instead of two, have a short form for byte operands),
18450 ;; so do it for other CPUs as well. Given that the value was dead,
18451 ;; this should not create any new dependencies. Pass on the sub-word
18452 ;; versions if we're concerned about partial register stalls.
18453
18454 (define_peephole2
18455 [(set (reg 17)
18456 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18457 (match_operand:SI 1 "immediate_operand" ""))
18458 (const_int 0)))]
18459 "ix86_match_ccmode (insn, CCNOmode)
18460 && (true_regnum (operands[0]) != 0
18461 || (GET_CODE (operands[1]) == CONST_INT
18462 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18463 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18464 [(parallel
18465 [(set (reg:CCNO 17)
18466 (compare:CCNO (and:SI (match_dup 0)
18467 (match_dup 1))
18468 (const_int 0)))
18469 (set (match_dup 0)
18470 (and:SI (match_dup 0) (match_dup 1)))])]
18471 "")
18472
18473 ;; We don't need to handle HImode case, because it will be promoted to SImode
18474 ;; on ! TARGET_PARTIAL_REG_STALL
18475
18476 (define_peephole2
18477 [(set (reg 17)
18478 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18479 (match_operand:QI 1 "immediate_operand" ""))
18480 (const_int 0)))]
18481 "! TARGET_PARTIAL_REG_STALL
18482 && ix86_match_ccmode (insn, CCNOmode)
18483 && true_regnum (operands[0]) != 0
18484 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18485 [(parallel
18486 [(set (reg:CCNO 17)
18487 (compare:CCNO (and:QI (match_dup 0)
18488 (match_dup 1))
18489 (const_int 0)))
18490 (set (match_dup 0)
18491 (and:QI (match_dup 0) (match_dup 1)))])]
18492 "")
18493
18494 (define_peephole2
18495 [(set (reg 17)
18496 (compare
18497 (and:SI
18498 (zero_extract:SI
18499 (match_operand 0 "ext_register_operand" "")
18500 (const_int 8)
18501 (const_int 8))
18502 (match_operand 1 "const_int_operand" ""))
18503 (const_int 0)))]
18504 "! TARGET_PARTIAL_REG_STALL
18505 && ix86_match_ccmode (insn, CCNOmode)
18506 && true_regnum (operands[0]) != 0
18507 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18508 [(parallel [(set (reg:CCNO 17)
18509 (compare:CCNO
18510 (and:SI
18511 (zero_extract:SI
18512 (match_dup 0)
18513 (const_int 8)
18514 (const_int 8))
18515 (match_dup 1))
18516 (const_int 0)))
18517 (set (zero_extract:SI (match_dup 0)
18518 (const_int 8)
18519 (const_int 8))
18520 (and:SI
18521 (zero_extract:SI
18522 (match_dup 0)
18523 (const_int 8)
18524 (const_int 8))
18525 (match_dup 1)))])]
18526 "")
18527
18528 ;; Don't do logical operations with memory inputs.
18529 (define_peephole2
18530 [(match_scratch:SI 2 "r")
18531 (parallel [(set (match_operand:SI 0 "register_operand" "")
18532 (match_operator:SI 3 "arith_or_logical_operator"
18533 [(match_dup 0)
18534 (match_operand:SI 1 "memory_operand" "")]))
18535 (clobber (reg:CC 17))])]
18536 "! optimize_size && ! TARGET_READ_MODIFY"
18537 [(set (match_dup 2) (match_dup 1))
18538 (parallel [(set (match_dup 0)
18539 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18540 (clobber (reg:CC 17))])]
18541 "")
18542
18543 (define_peephole2
18544 [(match_scratch:SI 2 "r")
18545 (parallel [(set (match_operand:SI 0 "register_operand" "")
18546 (match_operator:SI 3 "arith_or_logical_operator"
18547 [(match_operand:SI 1 "memory_operand" "")
18548 (match_dup 0)]))
18549 (clobber (reg:CC 17))])]
18550 "! optimize_size && ! TARGET_READ_MODIFY"
18551 [(set (match_dup 2) (match_dup 1))
18552 (parallel [(set (match_dup 0)
18553 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18554 (clobber (reg:CC 17))])]
18555 "")
18556
18557 ; Don't do logical operations with memory outputs
18558 ;
18559 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18560 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18561 ; the same decoder scheduling characteristics as the original.
18562
18563 (define_peephole2
18564 [(match_scratch:SI 2 "r")
18565 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18566 (match_operator:SI 3 "arith_or_logical_operator"
18567 [(match_dup 0)
18568 (match_operand:SI 1 "nonmemory_operand" "")]))
18569 (clobber (reg:CC 17))])]
18570 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18571 [(set (match_dup 2) (match_dup 0))
18572 (parallel [(set (match_dup 2)
18573 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18574 (clobber (reg:CC 17))])
18575 (set (match_dup 0) (match_dup 2))]
18576 "")
18577
18578 (define_peephole2
18579 [(match_scratch:SI 2 "r")
18580 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18581 (match_operator:SI 3 "arith_or_logical_operator"
18582 [(match_operand:SI 1 "nonmemory_operand" "")
18583 (match_dup 0)]))
18584 (clobber (reg:CC 17))])]
18585 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18586 [(set (match_dup 2) (match_dup 0))
18587 (parallel [(set (match_dup 2)
18588 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18589 (clobber (reg:CC 17))])
18590 (set (match_dup 0) (match_dup 2))]
18591 "")
18592
18593 ;; Attempt to always use XOR for zeroing registers.
18594 (define_peephole2
18595 [(set (match_operand 0 "register_operand" "")
18596 (const_int 0))]
18597 "(GET_MODE (operands[0]) == QImode
18598 || GET_MODE (operands[0]) == HImode
18599 || GET_MODE (operands[0]) == SImode
18600 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18601 && (! TARGET_USE_MOV0 || optimize_size)
18602 && peep2_regno_dead_p (0, FLAGS_REG)"
18603 [(parallel [(set (match_dup 0) (const_int 0))
18604 (clobber (reg:CC 17))])]
18605 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18606 operands[0]);")
18607
18608 (define_peephole2
18609 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18610 (const_int 0))]
18611 "(GET_MODE (operands[0]) == QImode
18612 || GET_MODE (operands[0]) == HImode)
18613 && (! TARGET_USE_MOV0 || optimize_size)
18614 && peep2_regno_dead_p (0, FLAGS_REG)"
18615 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18616 (clobber (reg:CC 17))])])
18617
18618 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18619 (define_peephole2
18620 [(set (match_operand 0 "register_operand" "")
18621 (const_int -1))]
18622 "(GET_MODE (operands[0]) == HImode
18623 || GET_MODE (operands[0]) == SImode
18624 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18625 && (optimize_size || TARGET_PENTIUM)
18626 && peep2_regno_dead_p (0, FLAGS_REG)"
18627 [(parallel [(set (match_dup 0) (const_int -1))
18628 (clobber (reg:CC 17))])]
18629 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18630 operands[0]);")
18631
18632 ;; Attempt to convert simple leas to adds. These can be created by
18633 ;; move expanders.
18634 (define_peephole2
18635 [(set (match_operand:SI 0 "register_operand" "")
18636 (plus:SI (match_dup 0)
18637 (match_operand:SI 1 "nonmemory_operand" "")))]
18638 "peep2_regno_dead_p (0, FLAGS_REG)"
18639 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18640 (clobber (reg:CC 17))])]
18641 "")
18642
18643 (define_peephole2
18644 [(set (match_operand:SI 0 "register_operand" "")
18645 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18646 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18647 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18648 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18649 (clobber (reg:CC 17))])]
18650 "operands[2] = gen_lowpart (SImode, operands[2]);")
18651
18652 (define_peephole2
18653 [(set (match_operand:DI 0 "register_operand" "")
18654 (plus:DI (match_dup 0)
18655 (match_operand:DI 1 "x86_64_general_operand" "")))]
18656 "peep2_regno_dead_p (0, FLAGS_REG)"
18657 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18658 (clobber (reg:CC 17))])]
18659 "")
18660
18661 (define_peephole2
18662 [(set (match_operand:SI 0 "register_operand" "")
18663 (mult:SI (match_dup 0)
18664 (match_operand:SI 1 "const_int_operand" "")))]
18665 "exact_log2 (INTVAL (operands[1])) >= 0
18666 && peep2_regno_dead_p (0, FLAGS_REG)"
18667 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18668 (clobber (reg:CC 17))])]
18669 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18670
18671 (define_peephole2
18672 [(set (match_operand:DI 0 "register_operand" "")
18673 (mult:DI (match_dup 0)
18674 (match_operand:DI 1 "const_int_operand" "")))]
18675 "exact_log2 (INTVAL (operands[1])) >= 0
18676 && peep2_regno_dead_p (0, FLAGS_REG)"
18677 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18678 (clobber (reg:CC 17))])]
18679 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18680
18681 (define_peephole2
18682 [(set (match_operand:SI 0 "register_operand" "")
18683 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18684 (match_operand:DI 2 "const_int_operand" "")) 0))]
18685 "exact_log2 (INTVAL (operands[2])) >= 0
18686 && REGNO (operands[0]) == REGNO (operands[1])
18687 && peep2_regno_dead_p (0, FLAGS_REG)"
18688 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18689 (clobber (reg:CC 17))])]
18690 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18691
18692 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18693 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18694 ;; many CPUs it is also faster, since special hardware to avoid esp
18695 ;; dependencies is present.
18696
18697 ;; While some of these conversions may be done using splitters, we use peepholes
18698 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18699
18700 ;; Convert prologue esp subtractions to push.
18701 ;; We need register to push. In order to keep verify_flow_info happy we have
18702 ;; two choices
18703 ;; - use scratch and clobber it in order to avoid dependencies
18704 ;; - use already live register
18705 ;; We can't use the second way right now, since there is no reliable way how to
18706 ;; verify that given register is live. First choice will also most likely in
18707 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18708 ;; call clobbered registers are dead. We may want to use base pointer as an
18709 ;; alternative when no register is available later.
18710
18711 (define_peephole2
18712 [(match_scratch:SI 0 "r")
18713 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18714 (clobber (reg:CC 17))
18715 (clobber (mem:BLK (scratch)))])]
18716 "optimize_size || !TARGET_SUB_ESP_4"
18717 [(clobber (match_dup 0))
18718 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18719 (clobber (mem:BLK (scratch)))])])
18720
18721 (define_peephole2
18722 [(match_scratch:SI 0 "r")
18723 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18724 (clobber (reg:CC 17))
18725 (clobber (mem:BLK (scratch)))])]
18726 "optimize_size || !TARGET_SUB_ESP_8"
18727 [(clobber (match_dup 0))
18728 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18729 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18730 (clobber (mem:BLK (scratch)))])])
18731
18732 ;; Convert esp subtractions to push.
18733 (define_peephole2
18734 [(match_scratch:SI 0 "r")
18735 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18736 (clobber (reg:CC 17))])]
18737 "optimize_size || !TARGET_SUB_ESP_4"
18738 [(clobber (match_dup 0))
18739 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18740
18741 (define_peephole2
18742 [(match_scratch:SI 0 "r")
18743 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18744 (clobber (reg:CC 17))])]
18745 "optimize_size || !TARGET_SUB_ESP_8"
18746 [(clobber (match_dup 0))
18747 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18748 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18749
18750 ;; Convert epilogue deallocator to pop.
18751 (define_peephole2
18752 [(match_scratch:SI 0 "r")
18753 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18754 (clobber (reg:CC 17))
18755 (clobber (mem:BLK (scratch)))])]
18756 "optimize_size || !TARGET_ADD_ESP_4"
18757 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18758 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18759 (clobber (mem:BLK (scratch)))])]
18760 "")
18761
18762 ;; Two pops case is tricky, since pop causes dependency on destination register.
18763 ;; We use two registers if available.
18764 (define_peephole2
18765 [(match_scratch:SI 0 "r")
18766 (match_scratch:SI 1 "r")
18767 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18768 (clobber (reg:CC 17))
18769 (clobber (mem:BLK (scratch)))])]
18770 "optimize_size || !TARGET_ADD_ESP_8"
18771 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18772 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18773 (clobber (mem:BLK (scratch)))])
18774 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18775 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18776 "")
18777
18778 (define_peephole2
18779 [(match_scratch:SI 0 "r")
18780 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18781 (clobber (reg:CC 17))
18782 (clobber (mem:BLK (scratch)))])]
18783 "optimize_size"
18784 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18785 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18786 (clobber (mem:BLK (scratch)))])
18787 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18788 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18789 "")
18790
18791 ;; Convert esp additions to pop.
18792 (define_peephole2
18793 [(match_scratch:SI 0 "r")
18794 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18795 (clobber (reg:CC 17))])]
18796 ""
18797 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18798 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18799 "")
18800
18801 ;; Two pops case is tricky, since pop causes dependency on destination register.
18802 ;; We use two registers if available.
18803 (define_peephole2
18804 [(match_scratch:SI 0 "r")
18805 (match_scratch:SI 1 "r")
18806 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18807 (clobber (reg:CC 17))])]
18808 ""
18809 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18810 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18811 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18812 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18813 "")
18814
18815 (define_peephole2
18816 [(match_scratch:SI 0 "r")
18817 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18818 (clobber (reg:CC 17))])]
18819 "optimize_size"
18820 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18821 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18822 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18823 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18824 "")
18825 \f
18826 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18827 ;; required and register dies.
18828 (define_peephole2
18829 [(set (reg 17)
18830 (compare (match_operand:SI 0 "register_operand" "")
18831 (match_operand:SI 1 "incdec_operand" "")))]
18832 "ix86_match_ccmode (insn, CCGCmode)
18833 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18834 [(parallel [(set (reg:CCGC 17)
18835 (compare:CCGC (match_dup 0)
18836 (match_dup 1)))
18837 (clobber (match_dup 0))])]
18838 "")
18839
18840 (define_peephole2
18841 [(set (reg 17)
18842 (compare (match_operand:HI 0 "register_operand" "")
18843 (match_operand:HI 1 "incdec_operand" "")))]
18844 "ix86_match_ccmode (insn, CCGCmode)
18845 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18846 [(parallel [(set (reg:CCGC 17)
18847 (compare:CCGC (match_dup 0)
18848 (match_dup 1)))
18849 (clobber (match_dup 0))])]
18850 "")
18851
18852 (define_peephole2
18853 [(set (reg 17)
18854 (compare (match_operand:QI 0 "register_operand" "")
18855 (match_operand:QI 1 "incdec_operand" "")))]
18856 "ix86_match_ccmode (insn, CCGCmode)
18857 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18858 [(parallel [(set (reg:CCGC 17)
18859 (compare:CCGC (match_dup 0)
18860 (match_dup 1)))
18861 (clobber (match_dup 0))])]
18862 "")
18863
18864 ;; Convert compares with 128 to shorter add -128
18865 (define_peephole2
18866 [(set (reg 17)
18867 (compare (match_operand:SI 0 "register_operand" "")
18868 (const_int 128)))]
18869 "ix86_match_ccmode (insn, CCGCmode)
18870 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18871 [(parallel [(set (reg:CCGC 17)
18872 (compare:CCGC (match_dup 0)
18873 (const_int 128)))
18874 (clobber (match_dup 0))])]
18875 "")
18876
18877 (define_peephole2
18878 [(set (reg 17)
18879 (compare (match_operand:HI 0 "register_operand" "")
18880 (const_int 128)))]
18881 "ix86_match_ccmode (insn, CCGCmode)
18882 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18883 [(parallel [(set (reg:CCGC 17)
18884 (compare:CCGC (match_dup 0)
18885 (const_int 128)))
18886 (clobber (match_dup 0))])]
18887 "")
18888 \f
18889 (define_peephole2
18890 [(match_scratch:DI 0 "r")
18891 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18892 (clobber (reg:CC 17))
18893 (clobber (mem:BLK (scratch)))])]
18894 "optimize_size || !TARGET_SUB_ESP_4"
18895 [(clobber (match_dup 0))
18896 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18897 (clobber (mem:BLK (scratch)))])])
18898
18899 (define_peephole2
18900 [(match_scratch:DI 0 "r")
18901 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18902 (clobber (reg:CC 17))
18903 (clobber (mem:BLK (scratch)))])]
18904 "optimize_size || !TARGET_SUB_ESP_8"
18905 [(clobber (match_dup 0))
18906 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18907 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18908 (clobber (mem:BLK (scratch)))])])
18909
18910 ;; Convert esp subtractions to push.
18911 (define_peephole2
18912 [(match_scratch:DI 0 "r")
18913 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18914 (clobber (reg:CC 17))])]
18915 "optimize_size || !TARGET_SUB_ESP_4"
18916 [(clobber (match_dup 0))
18917 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18918
18919 (define_peephole2
18920 [(match_scratch:DI 0 "r")
18921 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18922 (clobber (reg:CC 17))])]
18923 "optimize_size || !TARGET_SUB_ESP_8"
18924 [(clobber (match_dup 0))
18925 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18926 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18927
18928 ;; Convert epilogue deallocator to pop.
18929 (define_peephole2
18930 [(match_scratch:DI 0 "r")
18931 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18932 (clobber (reg:CC 17))
18933 (clobber (mem:BLK (scratch)))])]
18934 "optimize_size || !TARGET_ADD_ESP_4"
18935 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18936 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18937 (clobber (mem:BLK (scratch)))])]
18938 "")
18939
18940 ;; Two pops case is tricky, since pop causes dependency on destination register.
18941 ;; We use two registers if available.
18942 (define_peephole2
18943 [(match_scratch:DI 0 "r")
18944 (match_scratch:DI 1 "r")
18945 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18946 (clobber (reg:CC 17))
18947 (clobber (mem:BLK (scratch)))])]
18948 "optimize_size || !TARGET_ADD_ESP_8"
18949 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18950 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18951 (clobber (mem:BLK (scratch)))])
18952 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18953 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18954 "")
18955
18956 (define_peephole2
18957 [(match_scratch:DI 0 "r")
18958 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18959 (clobber (reg:CC 17))
18960 (clobber (mem:BLK (scratch)))])]
18961 "optimize_size"
18962 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18963 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18964 (clobber (mem:BLK (scratch)))])
18965 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18966 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18967 "")
18968
18969 ;; Convert esp additions to pop.
18970 (define_peephole2
18971 [(match_scratch:DI 0 "r")
18972 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18973 (clobber (reg:CC 17))])]
18974 ""
18975 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18976 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18977 "")
18978
18979 ;; Two pops case is tricky, since pop causes dependency on destination register.
18980 ;; We use two registers if available.
18981 (define_peephole2
18982 [(match_scratch:DI 0 "r")
18983 (match_scratch:DI 1 "r")
18984 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18985 (clobber (reg:CC 17))])]
18986 ""
18987 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18988 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18989 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18990 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18991 "")
18992
18993 (define_peephole2
18994 [(match_scratch:DI 0 "r")
18995 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18996 (clobber (reg:CC 17))])]
18997 "optimize_size"
18998 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18999 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
19000 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19001 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19002 "")
19003 \f
19004 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19005 ;; imul $32bit_imm, reg, reg is direct decoded.
19006 (define_peephole2
19007 [(match_scratch:DI 3 "r")
19008 (parallel [(set (match_operand:DI 0 "register_operand" "")
19009 (mult:DI (match_operand:DI 1 "memory_operand" "")
19010 (match_operand:DI 2 "immediate_operand" "")))
19011 (clobber (reg:CC 17))])]
19012 "TARGET_K8 && !optimize_size
19013 && (GET_CODE (operands[2]) != CONST_INT
19014 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19015 [(set (match_dup 3) (match_dup 1))
19016 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19017 (clobber (reg:CC 17))])]
19018 "")
19019
19020 (define_peephole2
19021 [(match_scratch:SI 3 "r")
19022 (parallel [(set (match_operand:SI 0 "register_operand" "")
19023 (mult:SI (match_operand:SI 1 "memory_operand" "")
19024 (match_operand:SI 2 "immediate_operand" "")))
19025 (clobber (reg:CC 17))])]
19026 "TARGET_K8 && !optimize_size
19027 && (GET_CODE (operands[2]) != CONST_INT
19028 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19029 [(set (match_dup 3) (match_dup 1))
19030 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19031 (clobber (reg:CC 17))])]
19032 "")
19033
19034 (define_peephole2
19035 [(match_scratch:SI 3 "r")
19036 (parallel [(set (match_operand:DI 0 "register_operand" "")
19037 (zero_extend:DI
19038 (mult:SI (match_operand:SI 1 "memory_operand" "")
19039 (match_operand:SI 2 "immediate_operand" ""))))
19040 (clobber (reg:CC 17))])]
19041 "TARGET_K8 && !optimize_size
19042 && (GET_CODE (operands[2]) != CONST_INT
19043 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19044 [(set (match_dup 3) (match_dup 1))
19045 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19046 (clobber (reg:CC 17))])]
19047 "")
19048
19049 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19050 ;; Convert it into imul reg, reg
19051 ;; It would be better to force assembler to encode instruction using long
19052 ;; immediate, but there is apparently no way to do so.
19053 (define_peephole2
19054 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19055 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19056 (match_operand:DI 2 "const_int_operand" "")))
19057 (clobber (reg:CC 17))])
19058 (match_scratch:DI 3 "r")]
19059 "TARGET_K8 && !optimize_size
19060 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19061 [(set (match_dup 3) (match_dup 2))
19062 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19063 (clobber (reg:CC 17))])]
19064 {
19065 if (!rtx_equal_p (operands[0], operands[1]))
19066 emit_move_insn (operands[0], operands[1]);
19067 })
19068
19069 (define_peephole2
19070 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19071 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19072 (match_operand:SI 2 "const_int_operand" "")))
19073 (clobber (reg:CC 17))])
19074 (match_scratch:SI 3 "r")]
19075 "TARGET_K8 && !optimize_size
19076 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19077 [(set (match_dup 3) (match_dup 2))
19078 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19079 (clobber (reg:CC 17))])]
19080 {
19081 if (!rtx_equal_p (operands[0], operands[1]))
19082 emit_move_insn (operands[0], operands[1]);
19083 })
19084
19085 (define_peephole2
19086 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19087 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19088 (match_operand:HI 2 "immediate_operand" "")))
19089 (clobber (reg:CC 17))])
19090 (match_scratch:HI 3 "r")]
19091 "TARGET_K8 && !optimize_size"
19092 [(set (match_dup 3) (match_dup 2))
19093 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19094 (clobber (reg:CC 17))])]
19095 {
19096 if (!rtx_equal_p (operands[0], operands[1]))
19097 emit_move_insn (operands[0], operands[1]);
19098 })
19099 \f
19100 ;; Call-value patterns last so that the wildcard operand does not
19101 ;; disrupt insn-recog's switch tables.
19102
19103 (define_insn "*call_value_pop_0"
19104 [(set (match_operand 0 "" "")
19105 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19106 (match_operand:SI 2 "" "")))
19107 (set (reg:SI 7) (plus:SI (reg:SI 7)
19108 (match_operand:SI 3 "immediate_operand" "")))]
19109 "!TARGET_64BIT"
19110 {
19111 if (SIBLING_CALL_P (insn))
19112 return "jmp\t%P1";
19113 else
19114 return "call\t%P1";
19115 }
19116 [(set_attr "type" "callv")])
19117
19118 (define_insn "*call_value_pop_1"
19119 [(set (match_operand 0 "" "")
19120 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19121 (match_operand:SI 2 "" "")))
19122 (set (reg:SI 7) (plus:SI (reg:SI 7)
19123 (match_operand:SI 3 "immediate_operand" "i")))]
19124 "!TARGET_64BIT"
19125 {
19126 if (constant_call_address_operand (operands[1], QImode))
19127 {
19128 if (SIBLING_CALL_P (insn))
19129 return "jmp\t%P1";
19130 else
19131 return "call\t%P1";
19132 }
19133 if (SIBLING_CALL_P (insn))
19134 return "jmp\t%A1";
19135 else
19136 return "call\t%A1";
19137 }
19138 [(set_attr "type" "callv")])
19139
19140 (define_insn "*call_value_0"
19141 [(set (match_operand 0 "" "")
19142 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19143 (match_operand:SI 2 "" "")))]
19144 "!TARGET_64BIT"
19145 {
19146 if (SIBLING_CALL_P (insn))
19147 return "jmp\t%P1";
19148 else
19149 return "call\t%P1";
19150 }
19151 [(set_attr "type" "callv")])
19152
19153 (define_insn "*call_value_0_rex64"
19154 [(set (match_operand 0 "" "")
19155 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19156 (match_operand:DI 2 "const_int_operand" "")))]
19157 "TARGET_64BIT"
19158 {
19159 if (SIBLING_CALL_P (insn))
19160 return "jmp\t%P1";
19161 else
19162 return "call\t%P1";
19163 }
19164 [(set_attr "type" "callv")])
19165
19166 (define_insn "*call_value_1"
19167 [(set (match_operand 0 "" "")
19168 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19169 (match_operand:SI 2 "" "")))]
19170 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19171 {
19172 if (constant_call_address_operand (operands[1], QImode))
19173 return "call\t%P1";
19174 return "call\t%*%1";
19175 }
19176 [(set_attr "type" "callv")])
19177
19178 (define_insn "*sibcall_value_1"
19179 [(set (match_operand 0 "" "")
19180 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19181 (match_operand:SI 2 "" "")))]
19182 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19183 {
19184 if (constant_call_address_operand (operands[1], QImode))
19185 return "jmp\t%P1";
19186 return "jmp\t%*%1";
19187 }
19188 [(set_attr "type" "callv")])
19189
19190 (define_insn "*call_value_1_rex64"
19191 [(set (match_operand 0 "" "")
19192 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19193 (match_operand:DI 2 "" "")))]
19194 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19195 {
19196 if (constant_call_address_operand (operands[1], QImode))
19197 return "call\t%P1";
19198 return "call\t%A1";
19199 }
19200 [(set_attr "type" "callv")])
19201
19202 (define_insn "*sibcall_value_1_rex64"
19203 [(set (match_operand 0 "" "")
19204 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19205 (match_operand:DI 2 "" "")))]
19206 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19207 "jmp\t%P1"
19208 [(set_attr "type" "callv")])
19209
19210 (define_insn "*sibcall_value_1_rex64_v"
19211 [(set (match_operand 0 "" "")
19212 (call (mem:QI (reg:DI 40))
19213 (match_operand:DI 1 "" "")))]
19214 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19215 "jmp\t*%%r11"
19216 [(set_attr "type" "callv")])
19217 \f
19218 (define_insn "trap"
19219 [(trap_if (const_int 1) (const_int 5))]
19220 ""
19221 "int\t$5")
19222
19223 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19224 ;;; for the sake of bounds checking. By emitting bounds checks as
19225 ;;; conditional traps rather than as conditional jumps around
19226 ;;; unconditional traps we avoid introducing spurious basic-block
19227 ;;; boundaries and facilitate elimination of redundant checks. In
19228 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19229 ;;; interrupt 5.
19230 ;;;
19231 ;;; FIXME: Static branch prediction rules for ix86 are such that
19232 ;;; forward conditional branches predict as untaken. As implemented
19233 ;;; below, pseudo conditional traps violate that rule. We should use
19234 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19235 ;;; section loaded at the end of the text segment and branch forward
19236 ;;; there on bounds-failure, and then jump back immediately (in case
19237 ;;; the system chooses to ignore bounds violations, or to report
19238 ;;; violations and continue execution).
19239
19240 (define_expand "conditional_trap"
19241 [(trap_if (match_operator 0 "comparison_operator"
19242 [(match_dup 2) (const_int 0)])
19243 (match_operand 1 "const_int_operand" ""))]
19244 ""
19245 {
19246 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19247 ix86_expand_compare (GET_CODE (operands[0]),
19248 NULL, NULL),
19249 operands[1]));
19250 DONE;
19251 })
19252
19253 (define_insn "*conditional_trap_1"
19254 [(trap_if (match_operator 0 "comparison_operator"
19255 [(reg 17) (const_int 0)])
19256 (match_operand 1 "const_int_operand" ""))]
19257 ""
19258 {
19259 operands[2] = gen_label_rtx ();
19260 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19261 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19262 CODE_LABEL_NUMBER (operands[2]));
19263 RET;
19264 })
19265
19266 ;; Pentium III SIMD instructions.
19267
19268 ;; Moves for SSE/MMX regs.
19269
19270 (define_insn "movv4sf_internal"
19271 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19272 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19273 "TARGET_SSE"
19274 "@
19275 xorps\t%0, %0
19276 movaps\t{%1, %0|%0, %1}
19277 movaps\t{%1, %0|%0, %1}"
19278 [(set_attr "type" "ssemov")
19279 (set_attr "mode" "V4SF")])
19280
19281 (define_split
19282 [(set (match_operand:V4SF 0 "register_operand" "")
19283 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19284 "TARGET_SSE"
19285 [(set (match_dup 0)
19286 (vec_merge:V4SF
19287 (vec_duplicate:V4SF (match_dup 1))
19288 (match_dup 2)
19289 (const_int 1)))]
19290 {
19291 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19292 operands[2] = CONST0_RTX (V4SFmode);
19293 })
19294
19295 (define_insn "movv4si_internal"
19296 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19297 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19298 "TARGET_SSE"
19299 {
19300 switch (which_alternative)
19301 {
19302 case 0:
19303 if (get_attr_mode (insn) == MODE_V4SF)
19304 return "xorps\t%0, %0";
19305 else
19306 return "pxor\t%0, %0";
19307 case 1:
19308 case 2:
19309 if (get_attr_mode (insn) == MODE_V4SF)
19310 return "movaps\t{%1, %0|%0, %1}";
19311 else
19312 return "movdqa\t{%1, %0|%0, %1}";
19313 default:
19314 abort ();
19315 }
19316 }
19317 [(set_attr "type" "ssemov")
19318 (set (attr "mode")
19319 (cond [(eq_attr "alternative" "0,1")
19320 (if_then_else
19321 (ne (symbol_ref "optimize_size")
19322 (const_int 0))
19323 (const_string "V4SF")
19324 (const_string "TI"))
19325 (eq_attr "alternative" "2")
19326 (if_then_else
19327 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19328 (const_int 0))
19329 (ne (symbol_ref "optimize_size")
19330 (const_int 0)))
19331 (const_string "V4SF")
19332 (const_string "TI"))]
19333 (const_string "TI")))])
19334
19335 (define_insn "movv2di_internal"
19336 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19337 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19338 "TARGET_SSE2"
19339 {
19340 switch (which_alternative)
19341 {
19342 case 0:
19343 if (get_attr_mode (insn) == MODE_V4SF)
19344 return "xorps\t%0, %0";
19345 else
19346 return "pxor\t%0, %0";
19347 case 1:
19348 case 2:
19349 if (get_attr_mode (insn) == MODE_V4SF)
19350 return "movaps\t{%1, %0|%0, %1}";
19351 else
19352 return "movdqa\t{%1, %0|%0, %1}";
19353 default:
19354 abort ();
19355 }
19356 }
19357 [(set_attr "type" "ssemov")
19358 (set (attr "mode")
19359 (cond [(eq_attr "alternative" "0,1")
19360 (if_then_else
19361 (ne (symbol_ref "optimize_size")
19362 (const_int 0))
19363 (const_string "V4SF")
19364 (const_string "TI"))
19365 (eq_attr "alternative" "2")
19366 (if_then_else
19367 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19368 (const_int 0))
19369 (ne (symbol_ref "optimize_size")
19370 (const_int 0)))
19371 (const_string "V4SF")
19372 (const_string "TI"))]
19373 (const_string "TI")))])
19374
19375 (define_split
19376 [(set (match_operand:V2DF 0 "register_operand" "")
19377 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19378 "TARGET_SSE2"
19379 [(set (match_dup 0)
19380 (vec_merge:V2DF
19381 (vec_duplicate:V2DF (match_dup 1))
19382 (match_dup 2)
19383 (const_int 1)))]
19384 {
19385 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19386 operands[2] = CONST0_RTX (V2DFmode);
19387 })
19388
19389 (define_insn "movv8qi_internal"
19390 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19391 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19392 "TARGET_MMX
19393 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19394 "@
19395 pxor\t%0, %0
19396 movq\t{%1, %0|%0, %1}
19397 movq\t{%1, %0|%0, %1}"
19398 [(set_attr "type" "mmxmov")
19399 (set_attr "mode" "DI")])
19400
19401 (define_insn "movv4hi_internal"
19402 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19403 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19404 "TARGET_MMX
19405 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19406 "@
19407 pxor\t%0, %0
19408 movq\t{%1, %0|%0, %1}
19409 movq\t{%1, %0|%0, %1}"
19410 [(set_attr "type" "mmxmov")
19411 (set_attr "mode" "DI")])
19412
19413 (define_insn "movv2si_internal"
19414 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19415 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19416 "TARGET_MMX
19417 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19418 "@
19419 pxor\t%0, %0
19420 movq\t{%1, %0|%0, %1}
19421 movq\t{%1, %0|%0, %1}"
19422 [(set_attr "type" "mmxcvt")
19423 (set_attr "mode" "DI")])
19424
19425 (define_insn "movv2sf_internal"
19426 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19427 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19428 "TARGET_3DNOW
19429 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19430 "@
19431 pxor\t%0, %0
19432 movq\t{%1, %0|%0, %1}
19433 movq\t{%1, %0|%0, %1}"
19434 [(set_attr "type" "mmxcvt")
19435 (set_attr "mode" "DI")])
19436
19437 (define_expand "movti"
19438 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19439 (match_operand:TI 1 "nonimmediate_operand" ""))]
19440 "TARGET_SSE || TARGET_64BIT"
19441 {
19442 if (TARGET_64BIT)
19443 ix86_expand_move (TImode, operands);
19444 else
19445 ix86_expand_vector_move (TImode, operands);
19446 DONE;
19447 })
19448
19449 (define_insn "movv2df_internal"
19450 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19451 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19452 "TARGET_SSE2
19453 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19454 {
19455 switch (which_alternative)
19456 {
19457 case 0:
19458 if (get_attr_mode (insn) == MODE_V4SF)
19459 return "xorps\t%0, %0";
19460 else
19461 return "xorpd\t%0, %0";
19462 case 1:
19463 case 2:
19464 if (get_attr_mode (insn) == MODE_V4SF)
19465 return "movaps\t{%1, %0|%0, %1}";
19466 else
19467 return "movapd\t{%1, %0|%0, %1}";
19468 default:
19469 abort ();
19470 }
19471 }
19472 [(set_attr "type" "ssemov")
19473 (set (attr "mode")
19474 (cond [(eq_attr "alternative" "0,1")
19475 (if_then_else
19476 (ne (symbol_ref "optimize_size")
19477 (const_int 0))
19478 (const_string "V4SF")
19479 (const_string "V2DF"))
19480 (eq_attr "alternative" "2")
19481 (if_then_else
19482 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19483 (const_int 0))
19484 (ne (symbol_ref "optimize_size")
19485 (const_int 0)))
19486 (const_string "V4SF")
19487 (const_string "V2DF"))]
19488 (const_string "V2DF")))])
19489
19490 (define_insn "movv8hi_internal"
19491 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19492 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19493 "TARGET_SSE2
19494 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19495 {
19496 switch (which_alternative)
19497 {
19498 case 0:
19499 if (get_attr_mode (insn) == MODE_V4SF)
19500 return "xorps\t%0, %0";
19501 else
19502 return "pxor\t%0, %0";
19503 case 1:
19504 case 2:
19505 if (get_attr_mode (insn) == MODE_V4SF)
19506 return "movaps\t{%1, %0|%0, %1}";
19507 else
19508 return "movdqa\t{%1, %0|%0, %1}";
19509 default:
19510 abort ();
19511 }
19512 }
19513 [(set_attr "type" "ssemov")
19514 (set (attr "mode")
19515 (cond [(eq_attr "alternative" "0,1")
19516 (if_then_else
19517 (ne (symbol_ref "optimize_size")
19518 (const_int 0))
19519 (const_string "V4SF")
19520 (const_string "TI"))
19521 (eq_attr "alternative" "2")
19522 (if_then_else
19523 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19524 (const_int 0))
19525 (ne (symbol_ref "optimize_size")
19526 (const_int 0)))
19527 (const_string "V4SF")
19528 (const_string "TI"))]
19529 (const_string "TI")))])
19530
19531 (define_insn "movv16qi_internal"
19532 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19533 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19534 "TARGET_SSE2
19535 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19536 {
19537 switch (which_alternative)
19538 {
19539 case 0:
19540 if (get_attr_mode (insn) == MODE_V4SF)
19541 return "xorps\t%0, %0";
19542 else
19543 return "pxor\t%0, %0";
19544 case 1:
19545 case 2:
19546 if (get_attr_mode (insn) == MODE_V4SF)
19547 return "movaps\t{%1, %0|%0, %1}";
19548 else
19549 return "movdqa\t{%1, %0|%0, %1}";
19550 default:
19551 abort ();
19552 }
19553 }
19554 [(set_attr "type" "ssemov")
19555 (set (attr "mode")
19556 (cond [(eq_attr "alternative" "0,1")
19557 (if_then_else
19558 (ne (symbol_ref "optimize_size")
19559 (const_int 0))
19560 (const_string "V4SF")
19561 (const_string "TI"))
19562 (eq_attr "alternative" "2")
19563 (if_then_else
19564 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19565 (const_int 0))
19566 (ne (symbol_ref "optimize_size")
19567 (const_int 0)))
19568 (const_string "V4SF")
19569 (const_string "TI"))]
19570 (const_string "TI")))])
19571
19572 (define_expand "movv2df"
19573 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19574 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19575 "TARGET_SSE2"
19576 {
19577 ix86_expand_vector_move (V2DFmode, operands);
19578 DONE;
19579 })
19580
19581 (define_expand "movv8hi"
19582 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19583 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19584 "TARGET_SSE2"
19585 {
19586 ix86_expand_vector_move (V8HImode, operands);
19587 DONE;
19588 })
19589
19590 (define_expand "movv16qi"
19591 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19592 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19593 "TARGET_SSE2"
19594 {
19595 ix86_expand_vector_move (V16QImode, operands);
19596 DONE;
19597 })
19598
19599 (define_expand "movv4sf"
19600 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19601 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19602 "TARGET_SSE"
19603 {
19604 ix86_expand_vector_move (V4SFmode, operands);
19605 DONE;
19606 })
19607
19608 (define_expand "movv4si"
19609 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19610 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19611 "TARGET_SSE"
19612 {
19613 ix86_expand_vector_move (V4SImode, operands);
19614 DONE;
19615 })
19616
19617 (define_expand "movv2di"
19618 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19619 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19620 "TARGET_SSE"
19621 {
19622 ix86_expand_vector_move (V2DImode, operands);
19623 DONE;
19624 })
19625
19626 (define_expand "movv2si"
19627 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19628 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19629 "TARGET_MMX"
19630 {
19631 ix86_expand_vector_move (V2SImode, operands);
19632 DONE;
19633 })
19634
19635 (define_expand "movv4hi"
19636 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19637 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19638 "TARGET_MMX"
19639 {
19640 ix86_expand_vector_move (V4HImode, operands);
19641 DONE;
19642 })
19643
19644 (define_expand "movv8qi"
19645 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19646 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19647 "TARGET_MMX"
19648 {
19649 ix86_expand_vector_move (V8QImode, operands);
19650 DONE;
19651 })
19652
19653 (define_expand "movv2sf"
19654 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19655 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19656 "TARGET_3DNOW"
19657 {
19658 ix86_expand_vector_move (V2SFmode, operands);
19659 DONE;
19660 })
19661
19662 (define_insn "*pushti"
19663 [(set (match_operand:TI 0 "push_operand" "=<")
19664 (match_operand:TI 1 "register_operand" "x"))]
19665 "TARGET_SSE"
19666 "#")
19667
19668 (define_insn "*pushv2df"
19669 [(set (match_operand:V2DF 0 "push_operand" "=<")
19670 (match_operand:V2DF 1 "register_operand" "x"))]
19671 "TARGET_SSE"
19672 "#")
19673
19674 (define_insn "*pushv2di"
19675 [(set (match_operand:V2DI 0 "push_operand" "=<")
19676 (match_operand:V2DI 1 "register_operand" "x"))]
19677 "TARGET_SSE2"
19678 "#")
19679
19680 (define_insn "*pushv8hi"
19681 [(set (match_operand:V8HI 0 "push_operand" "=<")
19682 (match_operand:V8HI 1 "register_operand" "x"))]
19683 "TARGET_SSE2"
19684 "#")
19685
19686 (define_insn "*pushv16qi"
19687 [(set (match_operand:V16QI 0 "push_operand" "=<")
19688 (match_operand:V16QI 1 "register_operand" "x"))]
19689 "TARGET_SSE2"
19690 "#")
19691
19692 (define_insn "*pushv4sf"
19693 [(set (match_operand:V4SF 0 "push_operand" "=<")
19694 (match_operand:V4SF 1 "register_operand" "x"))]
19695 "TARGET_SSE"
19696 "#")
19697
19698 (define_insn "*pushv4si"
19699 [(set (match_operand:V4SI 0 "push_operand" "=<")
19700 (match_operand:V4SI 1 "register_operand" "x"))]
19701 "TARGET_SSE2"
19702 "#")
19703
19704 (define_insn "*pushv2si"
19705 [(set (match_operand:V2SI 0 "push_operand" "=<")
19706 (match_operand:V2SI 1 "register_operand" "y"))]
19707 "TARGET_MMX"
19708 "#")
19709
19710 (define_insn "*pushv4hi"
19711 [(set (match_operand:V4HI 0 "push_operand" "=<")
19712 (match_operand:V4HI 1 "register_operand" "y"))]
19713 "TARGET_MMX"
19714 "#")
19715
19716 (define_insn "*pushv8qi"
19717 [(set (match_operand:V8QI 0 "push_operand" "=<")
19718 (match_operand:V8QI 1 "register_operand" "y"))]
19719 "TARGET_MMX"
19720 "#")
19721
19722 (define_insn "*pushv2sf"
19723 [(set (match_operand:V2SF 0 "push_operand" "=<")
19724 (match_operand:V2SF 1 "register_operand" "y"))]
19725 "TARGET_3DNOW"
19726 "#")
19727
19728 (define_split
19729 [(set (match_operand 0 "push_operand" "")
19730 (match_operand 1 "register_operand" ""))]
19731 "!TARGET_64BIT && reload_completed
19732 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19733 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19734 (set (match_dup 2) (match_dup 1))]
19735 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19736 stack_pointer_rtx);
19737 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19738
19739 (define_split
19740 [(set (match_operand 0 "push_operand" "")
19741 (match_operand 1 "register_operand" ""))]
19742 "TARGET_64BIT && reload_completed
19743 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19744 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19745 (set (match_dup 2) (match_dup 1))]
19746 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19747 stack_pointer_rtx);
19748 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19749
19750
19751 (define_insn "movti_internal"
19752 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19753 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19754 "TARGET_SSE && !TARGET_64BIT
19755 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19756 {
19757 switch (which_alternative)
19758 {
19759 case 0:
19760 if (get_attr_mode (insn) == MODE_V4SF)
19761 return "xorps\t%0, %0";
19762 else
19763 return "pxor\t%0, %0";
19764 case 1:
19765 case 2:
19766 if (get_attr_mode (insn) == MODE_V4SF)
19767 return "movaps\t{%1, %0|%0, %1}";
19768 else
19769 return "movdqa\t{%1, %0|%0, %1}";
19770 default:
19771 abort ();
19772 }
19773 }
19774 [(set_attr "type" "ssemov,ssemov,ssemov")
19775 (set (attr "mode")
19776 (cond [(eq_attr "alternative" "0,1")
19777 (if_then_else
19778 (ne (symbol_ref "optimize_size")
19779 (const_int 0))
19780 (const_string "V4SF")
19781 (const_string "TI"))
19782 (eq_attr "alternative" "2")
19783 (if_then_else
19784 (ne (symbol_ref "optimize_size")
19785 (const_int 0))
19786 (const_string "V4SF")
19787 (const_string "TI"))]
19788 (const_string "TI")))])
19789
19790 (define_insn "*movti_rex64"
19791 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19792 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19793 "TARGET_64BIT
19794 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19795 {
19796 switch (which_alternative)
19797 {
19798 case 0:
19799 case 1:
19800 return "#";
19801 case 2:
19802 if (get_attr_mode (insn) == MODE_V4SF)
19803 return "xorps\t%0, %0";
19804 else
19805 return "pxor\t%0, %0";
19806 case 3:
19807 case 4:
19808 if (get_attr_mode (insn) == MODE_V4SF)
19809 return "movaps\t{%1, %0|%0, %1}";
19810 else
19811 return "movdqa\t{%1, %0|%0, %1}";
19812 default:
19813 abort ();
19814 }
19815 }
19816 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19817 (set (attr "mode")
19818 (cond [(eq_attr "alternative" "2,3")
19819 (if_then_else
19820 (ne (symbol_ref "optimize_size")
19821 (const_int 0))
19822 (const_string "V4SF")
19823 (const_string "TI"))
19824 (eq_attr "alternative" "4")
19825 (if_then_else
19826 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19827 (const_int 0))
19828 (ne (symbol_ref "optimize_size")
19829 (const_int 0)))
19830 (const_string "V4SF")
19831 (const_string "TI"))]
19832 (const_string "DI")))])
19833
19834 (define_split
19835 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19836 (match_operand:TI 1 "general_operand" ""))]
19837 "reload_completed && !SSE_REG_P (operands[0])
19838 && !SSE_REG_P (operands[1])"
19839 [(const_int 0)]
19840 "ix86_split_long_move (operands); DONE;")
19841
19842 ;; These two patterns are useful for specifying exactly whether to use
19843 ;; movaps or movups
19844 (define_expand "sse_movaps"
19845 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19846 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19847 UNSPEC_MOVA))]
19848 "TARGET_SSE"
19849 {
19850 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19851 {
19852 rtx tmp = gen_reg_rtx (V4SFmode);
19853 emit_insn (gen_sse_movaps (tmp, operands[1]));
19854 emit_move_insn (operands[0], tmp);
19855 DONE;
19856 }
19857 })
19858
19859 (define_insn "*sse_movaps_1"
19860 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19861 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19862 UNSPEC_MOVA))]
19863 "TARGET_SSE
19864 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19865 "movaps\t{%1, %0|%0, %1}"
19866 [(set_attr "type" "ssemov,ssemov")
19867 (set_attr "mode" "V4SF")])
19868
19869 (define_expand "sse_movups"
19870 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19871 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19872 UNSPEC_MOVU))]
19873 "TARGET_SSE"
19874 {
19875 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19876 {
19877 rtx tmp = gen_reg_rtx (V4SFmode);
19878 emit_insn (gen_sse_movups (tmp, operands[1]));
19879 emit_move_insn (operands[0], tmp);
19880 DONE;
19881 }
19882 })
19883
19884 (define_insn "*sse_movups_1"
19885 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19886 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19887 UNSPEC_MOVU))]
19888 "TARGET_SSE
19889 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19890 "movups\t{%1, %0|%0, %1}"
19891 [(set_attr "type" "ssecvt,ssecvt")
19892 (set_attr "mode" "V4SF")])
19893
19894 ;; SSE Strange Moves.
19895
19896 (define_insn "sse_movmskps"
19897 [(set (match_operand:SI 0 "register_operand" "=r")
19898 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19899 UNSPEC_MOVMSK))]
19900 "TARGET_SSE"
19901 "movmskps\t{%1, %0|%0, %1}"
19902 [(set_attr "type" "ssecvt")
19903 (set_attr "mode" "V4SF")])
19904
19905 (define_insn "mmx_pmovmskb"
19906 [(set (match_operand:SI 0 "register_operand" "=r")
19907 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19908 UNSPEC_MOVMSK))]
19909 "TARGET_SSE || TARGET_3DNOW_A"
19910 "pmovmskb\t{%1, %0|%0, %1}"
19911 [(set_attr "type" "ssecvt")
19912 (set_attr "mode" "V4SF")])
19913
19914
19915 (define_insn "mmx_maskmovq"
19916 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19917 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19918 (match_operand:V8QI 2 "register_operand" "y")]
19919 UNSPEC_MASKMOV))]
19920 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19921 ;; @@@ check ordering of operands in intel/nonintel syntax
19922 "maskmovq\t{%2, %1|%1, %2}"
19923 [(set_attr "type" "mmxcvt")
19924 (set_attr "mode" "DI")])
19925
19926 (define_insn "mmx_maskmovq_rex"
19927 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19928 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19929 (match_operand:V8QI 2 "register_operand" "y")]
19930 UNSPEC_MASKMOV))]
19931 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19932 ;; @@@ check ordering of operands in intel/nonintel syntax
19933 "maskmovq\t{%2, %1|%1, %2}"
19934 [(set_attr "type" "mmxcvt")
19935 (set_attr "mode" "DI")])
19936
19937 (define_insn "sse_movntv4sf"
19938 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19939 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19940 UNSPEC_MOVNT))]
19941 "TARGET_SSE"
19942 "movntps\t{%1, %0|%0, %1}"
19943 [(set_attr "type" "ssemov")
19944 (set_attr "mode" "V4SF")])
19945
19946 (define_insn "sse_movntdi"
19947 [(set (match_operand:DI 0 "memory_operand" "=m")
19948 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19949 UNSPEC_MOVNT))]
19950 "TARGET_SSE || TARGET_3DNOW_A"
19951 "movntq\t{%1, %0|%0, %1}"
19952 [(set_attr "type" "mmxmov")
19953 (set_attr "mode" "DI")])
19954
19955 (define_insn "sse_movhlps"
19956 [(set (match_operand:V4SF 0 "register_operand" "=x")
19957 (vec_merge:V4SF
19958 (match_operand:V4SF 1 "register_operand" "0")
19959 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19960 (parallel [(const_int 2)
19961 (const_int 3)
19962 (const_int 0)
19963 (const_int 1)]))
19964 (const_int 3)))]
19965 "TARGET_SSE"
19966 "movhlps\t{%2, %0|%0, %2}"
19967 [(set_attr "type" "ssecvt")
19968 (set_attr "mode" "V4SF")])
19969
19970 (define_insn "sse_movlhps"
19971 [(set (match_operand:V4SF 0 "register_operand" "=x")
19972 (vec_merge:V4SF
19973 (match_operand:V4SF 1 "register_operand" "0")
19974 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19975 (parallel [(const_int 2)
19976 (const_int 3)
19977 (const_int 0)
19978 (const_int 1)]))
19979 (const_int 12)))]
19980 "TARGET_SSE"
19981 "movlhps\t{%2, %0|%0, %2}"
19982 [(set_attr "type" "ssecvt")
19983 (set_attr "mode" "V4SF")])
19984
19985 (define_insn "sse_movhps"
19986 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19987 (vec_merge:V4SF
19988 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19989 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19990 (const_int 12)))]
19991 "TARGET_SSE
19992 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19993 "movhps\t{%2, %0|%0, %2}"
19994 [(set_attr "type" "ssecvt")
19995 (set_attr "mode" "V4SF")])
19996
19997 (define_insn "sse_movlps"
19998 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19999 (vec_merge:V4SF
20000 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20001 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20002 (const_int 3)))]
20003 "TARGET_SSE
20004 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20005 "movlps\t{%2, %0|%0, %2}"
20006 [(set_attr "type" "ssecvt")
20007 (set_attr "mode" "V4SF")])
20008
20009 (define_expand "sse_loadss"
20010 [(match_operand:V4SF 0 "register_operand" "")
20011 (match_operand:SF 1 "memory_operand" "")]
20012 "TARGET_SSE"
20013 {
20014 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20015 CONST0_RTX (V4SFmode)));
20016 DONE;
20017 })
20018
20019 (define_insn "sse_loadss_1"
20020 [(set (match_operand:V4SF 0 "register_operand" "=x")
20021 (vec_merge:V4SF
20022 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20023 (match_operand:V4SF 2 "const0_operand" "X")
20024 (const_int 1)))]
20025 "TARGET_SSE"
20026 "movss\t{%1, %0|%0, %1}"
20027 [(set_attr "type" "ssemov")
20028 (set_attr "mode" "SF")])
20029
20030 (define_insn "sse_movss"
20031 [(set (match_operand:V4SF 0 "register_operand" "=x")
20032 (vec_merge:V4SF
20033 (match_operand:V4SF 1 "register_operand" "0")
20034 (match_operand:V4SF 2 "register_operand" "x")
20035 (const_int 1)))]
20036 "TARGET_SSE"
20037 "movss\t{%2, %0|%0, %2}"
20038 [(set_attr "type" "ssemov")
20039 (set_attr "mode" "SF")])
20040
20041 (define_insn "sse_storess"
20042 [(set (match_operand:SF 0 "memory_operand" "=m")
20043 (vec_select:SF
20044 (match_operand:V4SF 1 "register_operand" "x")
20045 (parallel [(const_int 0)])))]
20046 "TARGET_SSE"
20047 "movss\t{%1, %0|%0, %1}"
20048 [(set_attr "type" "ssemov")
20049 (set_attr "mode" "SF")])
20050
20051 (define_insn "sse_shufps"
20052 [(set (match_operand:V4SF 0 "register_operand" "=x")
20053 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20054 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20055 (match_operand:SI 3 "immediate_operand" "i")]
20056 UNSPEC_SHUFFLE))]
20057 "TARGET_SSE"
20058 ;; @@@ check operand order for intel/nonintel syntax
20059 "shufps\t{%3, %2, %0|%0, %2, %3}"
20060 [(set_attr "type" "ssecvt")
20061 (set_attr "mode" "V4SF")])
20062
20063
20064 ;; SSE arithmetic
20065
20066 (define_insn "addv4sf3"
20067 [(set (match_operand:V4SF 0 "register_operand" "=x")
20068 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20069 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20070 "TARGET_SSE"
20071 "addps\t{%2, %0|%0, %2}"
20072 [(set_attr "type" "sseadd")
20073 (set_attr "mode" "V4SF")])
20074
20075 (define_insn "vmaddv4sf3"
20076 [(set (match_operand:V4SF 0 "register_operand" "=x")
20077 (vec_merge:V4SF
20078 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20079 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20080 (match_dup 1)
20081 (const_int 1)))]
20082 "TARGET_SSE"
20083 "addss\t{%2, %0|%0, %2}"
20084 [(set_attr "type" "sseadd")
20085 (set_attr "mode" "SF")])
20086
20087 (define_insn "subv4sf3"
20088 [(set (match_operand:V4SF 0 "register_operand" "=x")
20089 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20090 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20091 "TARGET_SSE"
20092 "subps\t{%2, %0|%0, %2}"
20093 [(set_attr "type" "sseadd")
20094 (set_attr "mode" "V4SF")])
20095
20096 (define_insn "vmsubv4sf3"
20097 [(set (match_operand:V4SF 0 "register_operand" "=x")
20098 (vec_merge:V4SF
20099 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20100 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20101 (match_dup 1)
20102 (const_int 1)))]
20103 "TARGET_SSE"
20104 "subss\t{%2, %0|%0, %2}"
20105 [(set_attr "type" "sseadd")
20106 (set_attr "mode" "SF")])
20107
20108 (define_insn "mulv4sf3"
20109 [(set (match_operand:V4SF 0 "register_operand" "=x")
20110 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20111 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20112 "TARGET_SSE"
20113 "mulps\t{%2, %0|%0, %2}"
20114 [(set_attr "type" "ssemul")
20115 (set_attr "mode" "V4SF")])
20116
20117 (define_insn "vmmulv4sf3"
20118 [(set (match_operand:V4SF 0 "register_operand" "=x")
20119 (vec_merge:V4SF
20120 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20121 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20122 (match_dup 1)
20123 (const_int 1)))]
20124 "TARGET_SSE"
20125 "mulss\t{%2, %0|%0, %2}"
20126 [(set_attr "type" "ssemul")
20127 (set_attr "mode" "SF")])
20128
20129 (define_insn "divv4sf3"
20130 [(set (match_operand:V4SF 0 "register_operand" "=x")
20131 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20132 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20133 "TARGET_SSE"
20134 "divps\t{%2, %0|%0, %2}"
20135 [(set_attr "type" "ssediv")
20136 (set_attr "mode" "V4SF")])
20137
20138 (define_insn "vmdivv4sf3"
20139 [(set (match_operand:V4SF 0 "register_operand" "=x")
20140 (vec_merge:V4SF
20141 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20142 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20143 (match_dup 1)
20144 (const_int 1)))]
20145 "TARGET_SSE"
20146 "divss\t{%2, %0|%0, %2}"
20147 [(set_attr "type" "ssediv")
20148 (set_attr "mode" "SF")])
20149
20150
20151 ;; SSE square root/reciprocal
20152
20153 (define_insn "rcpv4sf2"
20154 [(set (match_operand:V4SF 0 "register_operand" "=x")
20155 (unspec:V4SF
20156 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20157 "TARGET_SSE"
20158 "rcpps\t{%1, %0|%0, %1}"
20159 [(set_attr "type" "sse")
20160 (set_attr "mode" "V4SF")])
20161
20162 (define_insn "vmrcpv4sf2"
20163 [(set (match_operand:V4SF 0 "register_operand" "=x")
20164 (vec_merge:V4SF
20165 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20166 UNSPEC_RCP)
20167 (match_operand:V4SF 2 "register_operand" "0")
20168 (const_int 1)))]
20169 "TARGET_SSE"
20170 "rcpss\t{%1, %0|%0, %1}"
20171 [(set_attr "type" "sse")
20172 (set_attr "mode" "SF")])
20173
20174 (define_insn "rsqrtv4sf2"
20175 [(set (match_operand:V4SF 0 "register_operand" "=x")
20176 (unspec:V4SF
20177 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20178 "TARGET_SSE"
20179 "rsqrtps\t{%1, %0|%0, %1}"
20180 [(set_attr "type" "sse")
20181 (set_attr "mode" "V4SF")])
20182
20183 (define_insn "vmrsqrtv4sf2"
20184 [(set (match_operand:V4SF 0 "register_operand" "=x")
20185 (vec_merge:V4SF
20186 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20187 UNSPEC_RSQRT)
20188 (match_operand:V4SF 2 "register_operand" "0")
20189 (const_int 1)))]
20190 "TARGET_SSE"
20191 "rsqrtss\t{%1, %0|%0, %1}"
20192 [(set_attr "type" "sse")
20193 (set_attr "mode" "SF")])
20194
20195 (define_insn "sqrtv4sf2"
20196 [(set (match_operand:V4SF 0 "register_operand" "=x")
20197 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20198 "TARGET_SSE"
20199 "sqrtps\t{%1, %0|%0, %1}"
20200 [(set_attr "type" "sse")
20201 (set_attr "mode" "V4SF")])
20202
20203 (define_insn "vmsqrtv4sf2"
20204 [(set (match_operand:V4SF 0 "register_operand" "=x")
20205 (vec_merge:V4SF
20206 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20207 (match_operand:V4SF 2 "register_operand" "0")
20208 (const_int 1)))]
20209 "TARGET_SSE"
20210 "sqrtss\t{%1, %0|%0, %1}"
20211 [(set_attr "type" "sse")
20212 (set_attr "mode" "SF")])
20213
20214 ;; SSE logical operations.
20215
20216 ;; SSE defines logical operations on floating point values. This brings
20217 ;; interesting challenge to RTL representation where logicals are only valid
20218 ;; on integral types. We deal with this by representing the floating point
20219 ;; logical as logical on arguments casted to TImode as this is what hardware
20220 ;; really does. Unfortunately hardware requires the type information to be
20221 ;; present and thus we must avoid subregs from being simplified and eliminated
20222 ;; in later compilation phases.
20223 ;;
20224 ;; We have following variants from each instruction:
20225 ;; sse_andsf3 - the operation taking V4SF vector operands
20226 ;; and doing TImode cast on them
20227 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20228 ;; TImode, since backend insist on eliminating casts
20229 ;; on memory operands
20230 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20231 ;; We can not accept memory operand here as instruction reads
20232 ;; whole scalar. This is generated only post reload by GCC
20233 ;; scalar float operations that expands to logicals (fabs)
20234 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20235 ;; memory operand. Eventually combine can be able
20236 ;; to synthesize these using splitter.
20237 ;; sse2_anddf3, *sse2_anddf3_memory
20238 ;;
20239 ;;
20240 ;; These are not called andti3 etc. because we really really don't want
20241 ;; the compiler to widen DImode ands to TImode ands and then try to move
20242 ;; into DImode subregs of SSE registers, and them together, and move out
20243 ;; of DImode subregs again!
20244 ;; SSE1 single precision floating point logical operation
20245 (define_expand "sse_andv4sf3"
20246 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20247 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20248 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20249 "TARGET_SSE"
20250 "")
20251
20252 (define_insn "*sse_andv4sf3"
20253 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20254 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20255 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20256 "TARGET_SSE
20257 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20258 "andps\t{%2, %0|%0, %2}"
20259 [(set_attr "type" "sselog")
20260 (set_attr "mode" "V4SF")])
20261
20262 (define_insn "*sse_andsf3"
20263 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20264 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20265 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20266 "TARGET_SSE
20267 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20268 "andps\t{%2, %0|%0, %2}"
20269 [(set_attr "type" "sselog")
20270 (set_attr "mode" "V4SF")])
20271
20272 (define_expand "sse_nandv4sf3"
20273 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20274 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
20275 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20276 "TARGET_SSE"
20277 "")
20278
20279 (define_insn "*sse_nandv4sf3"
20280 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20281 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20282 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20283 "TARGET_SSE"
20284 "andnps\t{%2, %0|%0, %2}"
20285 [(set_attr "type" "sselog")
20286 (set_attr "mode" "V4SF")])
20287
20288 (define_insn "*sse_nandsf3"
20289 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20290 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20291 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20292 "TARGET_SSE"
20293 "andnps\t{%2, %0|%0, %2}"
20294 [(set_attr "type" "sselog")
20295 (set_attr "mode" "V4SF")])
20296
20297 (define_expand "sse_iorv4sf3"
20298 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20299 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20300 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20301 "TARGET_SSE"
20302 "")
20303
20304 (define_insn "*sse_iorv4sf3"
20305 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20306 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20307 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20308 "TARGET_SSE
20309 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20310 "orps\t{%2, %0|%0, %2}"
20311 [(set_attr "type" "sselog")
20312 (set_attr "mode" "V4SF")])
20313
20314 (define_insn "*sse_iorsf3"
20315 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20316 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20317 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20318 "TARGET_SSE
20319 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20320 "orps\t{%2, %0|%0, %2}"
20321 [(set_attr "type" "sselog")
20322 (set_attr "mode" "V4SF")])
20323
20324 (define_expand "sse_xorv4sf3"
20325 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20326 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20327 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20328 "TARGET_SSE
20329 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20330 "")
20331
20332 (define_insn "*sse_xorv4sf3"
20333 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20334 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20335 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20336 "TARGET_SSE
20337 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20338 "xorps\t{%2, %0|%0, %2}"
20339 [(set_attr "type" "sselog")
20340 (set_attr "mode" "V4SF")])
20341
20342 (define_insn "*sse_xorsf3"
20343 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20344 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20345 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20346 "TARGET_SSE
20347 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20348 "xorps\t{%2, %0|%0, %2}"
20349 [(set_attr "type" "sselog")
20350 (set_attr "mode" "V4SF")])
20351
20352 ;; SSE2 double precision floating point logical operation
20353
20354 (define_expand "sse2_andv2df3"
20355 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20356 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20357 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20358 "TARGET_SSE2"
20359 "")
20360
20361 (define_insn "*sse2_andv2df3"
20362 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20363 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20364 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20365 "TARGET_SSE2
20366 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20367 "andpd\t{%2, %0|%0, %2}"
20368 [(set_attr "type" "sselog")
20369 (set_attr "mode" "V2DF")])
20370
20371 (define_insn "*sse2_andv2df3"
20372 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20373 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20374 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20375 "TARGET_SSE2
20376 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20377 "andpd\t{%2, %0|%0, %2}"
20378 [(set_attr "type" "sselog")
20379 (set_attr "mode" "V2DF")])
20380
20381 (define_expand "sse2_nandv2df3"
20382 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20383 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
20384 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20385 "TARGET_SSE2"
20386 "")
20387
20388 (define_insn "*sse2_nandv2df3"
20389 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20390 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20391 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20392 "TARGET_SSE2"
20393 "andnpd\t{%2, %0|%0, %2}"
20394 [(set_attr "type" "sselog")
20395 (set_attr "mode" "V2DF")])
20396
20397 (define_insn "*sse_nandti3_df"
20398 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
20399 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20400 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
20401 "TARGET_SSE2"
20402 "andnpd\t{%2, %0|%0, %2}"
20403 [(set_attr "type" "sselog")
20404 (set_attr "mode" "V2DF")])
20405
20406 (define_expand "sse2_iorv2df3"
20407 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20408 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20409 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20410 "TARGET_SSE2"
20411 "")
20412
20413 (define_insn "*sse2_iorv2df3"
20414 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20415 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20416 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20417 "TARGET_SSE2
20418 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20419 "orpd\t{%2, %0|%0, %2}"
20420 [(set_attr "type" "sselog")
20421 (set_attr "mode" "V2DF")])
20422
20423 (define_insn "*sse2_iordf3"
20424 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20425 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20426 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20427 "TARGET_SSE2
20428 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20429 "orpd\t{%2, %0|%0, %2}"
20430 [(set_attr "type" "sselog")
20431 (set_attr "mode" "V2DF")])
20432
20433 (define_expand "sse2_xorv2df3"
20434 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20435 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
20436 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20437 "TARGET_SSE2"
20438 "")
20439
20440 (define_insn "*sse2_xorv2df3"
20441 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20442 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20443 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20444 "TARGET_SSE2
20445 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20446 "xorpd\t{%2, %0|%0, %2}"
20447 [(set_attr "type" "sselog")
20448 (set_attr "mode" "V2DF")])
20449
20450 (define_insn "*sse2_xordf3"
20451 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20452 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20453 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20454 "TARGET_SSE2
20455 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20456 "xorpd\t{%2, %0|%0, %2}"
20457 [(set_attr "type" "sselog")
20458 (set_attr "mode" "V2DF")])
20459
20460 ;; SSE2 integral logicals. These patterns must always come after floating
20461 ;; point ones since we don't want compiler to use integer opcodes on floating
20462 ;; point SSE values to avoid matching of subregs in the match_operand.
20463 (define_insn "*sse2_andti3"
20464 [(set (match_operand:TI 0 "register_operand" "=x")
20465 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20466 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20467 "TARGET_SSE2
20468 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20469 "pand\t{%2, %0|%0, %2}"
20470 [(set_attr "type" "sselog")
20471 (set_attr "mode" "TI")])
20472
20473 (define_insn "sse2_andv2di3"
20474 [(set (match_operand:V2DI 0 "register_operand" "=x")
20475 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20476 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20477 "TARGET_SSE2
20478 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20479 "pand\t{%2, %0|%0, %2}"
20480 [(set_attr "type" "sselog")
20481 (set_attr "mode" "TI")])
20482
20483 (define_insn "*sse2_nandti3"
20484 [(set (match_operand:TI 0 "register_operand" "=x")
20485 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20486 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20487 "TARGET_SSE2"
20488 "pandn\t{%2, %0|%0, %2}"
20489 [(set_attr "type" "sselog")
20490 (set_attr "mode" "TI")])
20491
20492 (define_insn "sse2_nandv2di3"
20493 [(set (match_operand:V2DI 0 "register_operand" "=x")
20494 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20495 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20496 "TARGET_SSE2
20497 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20498 "pandn\t{%2, %0|%0, %2}"
20499 [(set_attr "type" "sselog")
20500 (set_attr "mode" "TI")])
20501
20502 (define_insn "*sse2_iorti3"
20503 [(set (match_operand:TI 0 "register_operand" "=x")
20504 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20505 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20506 "TARGET_SSE2
20507 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20508 "por\t{%2, %0|%0, %2}"
20509 [(set_attr "type" "sselog")
20510 (set_attr "mode" "TI")])
20511
20512 (define_insn "sse2_iorv2di3"
20513 [(set (match_operand:V2DI 0 "register_operand" "=x")
20514 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20515 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20516 "TARGET_SSE2
20517 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20518 "por\t{%2, %0|%0, %2}"
20519 [(set_attr "type" "sselog")
20520 (set_attr "mode" "TI")])
20521
20522 (define_insn "*sse2_xorti3"
20523 [(set (match_operand:TI 0 "register_operand" "=x")
20524 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20525 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20526 "TARGET_SSE2
20527 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20528 "pxor\t{%2, %0|%0, %2}"
20529 [(set_attr "type" "sselog")
20530 (set_attr "mode" "TI")])
20531
20532 (define_insn "sse2_xorv2di3"
20533 [(set (match_operand:V2DI 0 "register_operand" "=x")
20534 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20535 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20536 "TARGET_SSE2
20537 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20538 "pxor\t{%2, %0|%0, %2}"
20539 [(set_attr "type" "sselog")
20540 (set_attr "mode" "TI")])
20541
20542 ;; Use xor, but don't show input operands so they aren't live before
20543 ;; this insn.
20544 (define_insn "sse_clrv4sf"
20545 [(set (match_operand:V4SF 0 "register_operand" "=x")
20546 (match_operand:V4SF 1 "const0_operand" "X"))]
20547 "TARGET_SSE"
20548 {
20549 if (get_attr_mode (insn) == MODE_TI)
20550 return "pxor\t{%0, %0|%0, %0}";
20551 else
20552 return "xorps\t{%0, %0|%0, %0}";
20553 }
20554 [(set_attr "type" "sselog")
20555 (set_attr "memory" "none")
20556 (set (attr "mode")
20557 (if_then_else
20558 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20559 (const_int 0))
20560 (ne (symbol_ref "TARGET_SSE2")
20561 (const_int 0)))
20562 (eq (symbol_ref "optimize_size")
20563 (const_int 0)))
20564 (const_string "TI")
20565 (const_string "V4SF")))])
20566
20567 ;; Use xor, but don't show input operands so they aren't live before
20568 ;; this insn.
20569 (define_insn "sse_clrv2df"
20570 [(set (match_operand:V2DF 0 "register_operand" "=x")
20571 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20572 "TARGET_SSE2"
20573 "xorpd\t{%0, %0|%0, %0}"
20574 [(set_attr "type" "sselog")
20575 (set_attr "memory" "none")
20576 (set_attr "mode" "V4SF")])
20577
20578 ;; SSE mask-generating compares
20579
20580 (define_insn "maskcmpv4sf3"
20581 [(set (match_operand:V4SI 0 "register_operand" "=x")
20582 (match_operator:V4SI 3 "sse_comparison_operator"
20583 [(match_operand:V4SF 1 "register_operand" "0")
20584 (match_operand:V4SF 2 "register_operand" "x")]))]
20585 "TARGET_SSE"
20586 "cmp%D3ps\t{%2, %0|%0, %2}"
20587 [(set_attr "type" "ssecmp")
20588 (set_attr "mode" "V4SF")])
20589
20590 (define_insn "maskncmpv4sf3"
20591 [(set (match_operand:V4SI 0 "register_operand" "=x")
20592 (not:V4SI
20593 (match_operator:V4SI 3 "sse_comparison_operator"
20594 [(match_operand:V4SF 1 "register_operand" "0")
20595 (match_operand:V4SF 2 "register_operand" "x")])))]
20596 "TARGET_SSE"
20597 {
20598 if (GET_CODE (operands[3]) == UNORDERED)
20599 return "cmpordps\t{%2, %0|%0, %2}";
20600 else
20601 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20602 }
20603 [(set_attr "type" "ssecmp")
20604 (set_attr "mode" "V4SF")])
20605
20606 (define_insn "vmmaskcmpv4sf3"
20607 [(set (match_operand:V4SI 0 "register_operand" "=x")
20608 (vec_merge:V4SI
20609 (match_operator:V4SI 3 "sse_comparison_operator"
20610 [(match_operand:V4SF 1 "register_operand" "0")
20611 (match_operand:V4SF 2 "register_operand" "x")])
20612 (subreg:V4SI (match_dup 1) 0)
20613 (const_int 1)))]
20614 "TARGET_SSE"
20615 "cmp%D3ss\t{%2, %0|%0, %2}"
20616 [(set_attr "type" "ssecmp")
20617 (set_attr "mode" "SF")])
20618
20619 (define_insn "vmmaskncmpv4sf3"
20620 [(set (match_operand:V4SI 0 "register_operand" "=x")
20621 (vec_merge:V4SI
20622 (not:V4SI
20623 (match_operator:V4SI 3 "sse_comparison_operator"
20624 [(match_operand:V4SF 1 "register_operand" "0")
20625 (match_operand:V4SF 2 "register_operand" "x")]))
20626 (subreg:V4SI (match_dup 1) 0)
20627 (const_int 1)))]
20628 "TARGET_SSE"
20629 {
20630 if (GET_CODE (operands[3]) == UNORDERED)
20631 return "cmpordss\t{%2, %0|%0, %2}";
20632 else
20633 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20634 }
20635 [(set_attr "type" "ssecmp")
20636 (set_attr "mode" "SF")])
20637
20638 (define_insn "sse_comi"
20639 [(set (reg:CCFP 17)
20640 (compare:CCFP (vec_select:SF
20641 (match_operand:V4SF 0 "register_operand" "x")
20642 (parallel [(const_int 0)]))
20643 (vec_select:SF
20644 (match_operand:V4SF 1 "register_operand" "x")
20645 (parallel [(const_int 0)]))))]
20646 "TARGET_SSE"
20647 "comiss\t{%1, %0|%0, %1}"
20648 [(set_attr "type" "ssecomi")
20649 (set_attr "mode" "SF")])
20650
20651 (define_insn "sse_ucomi"
20652 [(set (reg:CCFPU 17)
20653 (compare:CCFPU (vec_select:SF
20654 (match_operand:V4SF 0 "register_operand" "x")
20655 (parallel [(const_int 0)]))
20656 (vec_select:SF
20657 (match_operand:V4SF 1 "register_operand" "x")
20658 (parallel [(const_int 0)]))))]
20659 "TARGET_SSE"
20660 "ucomiss\t{%1, %0|%0, %1}"
20661 [(set_attr "type" "ssecomi")
20662 (set_attr "mode" "SF")])
20663
20664
20665 ;; SSE unpack
20666
20667 (define_insn "sse_unpckhps"
20668 [(set (match_operand:V4SF 0 "register_operand" "=x")
20669 (vec_merge:V4SF
20670 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20671 (parallel [(const_int 2)
20672 (const_int 0)
20673 (const_int 3)
20674 (const_int 1)]))
20675 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20676 (parallel [(const_int 0)
20677 (const_int 2)
20678 (const_int 1)
20679 (const_int 3)]))
20680 (const_int 5)))]
20681 "TARGET_SSE"
20682 "unpckhps\t{%2, %0|%0, %2}"
20683 [(set_attr "type" "ssecvt")
20684 (set_attr "mode" "V4SF")])
20685
20686 (define_insn "sse_unpcklps"
20687 [(set (match_operand:V4SF 0 "register_operand" "=x")
20688 (vec_merge:V4SF
20689 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20690 (parallel [(const_int 0)
20691 (const_int 2)
20692 (const_int 1)
20693 (const_int 3)]))
20694 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20695 (parallel [(const_int 2)
20696 (const_int 0)
20697 (const_int 3)
20698 (const_int 1)]))
20699 (const_int 5)))]
20700 "TARGET_SSE"
20701 "unpcklps\t{%2, %0|%0, %2}"
20702 [(set_attr "type" "ssecvt")
20703 (set_attr "mode" "V4SF")])
20704
20705
20706 ;; SSE min/max
20707
20708 (define_insn "smaxv4sf3"
20709 [(set (match_operand:V4SF 0 "register_operand" "=x")
20710 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20711 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20712 "TARGET_SSE"
20713 "maxps\t{%2, %0|%0, %2}"
20714 [(set_attr "type" "sse")
20715 (set_attr "mode" "V4SF")])
20716
20717 (define_insn "vmsmaxv4sf3"
20718 [(set (match_operand:V4SF 0 "register_operand" "=x")
20719 (vec_merge:V4SF
20720 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20721 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20722 (match_dup 1)
20723 (const_int 1)))]
20724 "TARGET_SSE"
20725 "maxss\t{%2, %0|%0, %2}"
20726 [(set_attr "type" "sse")
20727 (set_attr "mode" "SF")])
20728
20729 (define_insn "sminv4sf3"
20730 [(set (match_operand:V4SF 0 "register_operand" "=x")
20731 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20732 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20733 "TARGET_SSE"
20734 "minps\t{%2, %0|%0, %2}"
20735 [(set_attr "type" "sse")
20736 (set_attr "mode" "V4SF")])
20737
20738 (define_insn "vmsminv4sf3"
20739 [(set (match_operand:V4SF 0 "register_operand" "=x")
20740 (vec_merge:V4SF
20741 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20742 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20743 (match_dup 1)
20744 (const_int 1)))]
20745 "TARGET_SSE"
20746 "minss\t{%2, %0|%0, %2}"
20747 [(set_attr "type" "sse")
20748 (set_attr "mode" "SF")])
20749
20750 ;; SSE <-> integer/MMX conversions
20751
20752 (define_insn "cvtpi2ps"
20753 [(set (match_operand:V4SF 0 "register_operand" "=x")
20754 (vec_merge:V4SF
20755 (match_operand:V4SF 1 "register_operand" "0")
20756 (vec_duplicate:V4SF
20757 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20758 (const_int 12)))]
20759 "TARGET_SSE"
20760 "cvtpi2ps\t{%2, %0|%0, %2}"
20761 [(set_attr "type" "ssecvt")
20762 (set_attr "mode" "V4SF")])
20763
20764 (define_insn "cvtps2pi"
20765 [(set (match_operand:V2SI 0 "register_operand" "=y")
20766 (vec_select:V2SI
20767 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20768 (parallel [(const_int 0) (const_int 1)])))]
20769 "TARGET_SSE"
20770 "cvtps2pi\t{%1, %0|%0, %1}"
20771 [(set_attr "type" "ssecvt")
20772 (set_attr "mode" "V4SF")])
20773
20774 (define_insn "cvttps2pi"
20775 [(set (match_operand:V2SI 0 "register_operand" "=y")
20776 (vec_select:V2SI
20777 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20778 UNSPEC_FIX)
20779 (parallel [(const_int 0) (const_int 1)])))]
20780 "TARGET_SSE"
20781 "cvttps2pi\t{%1, %0|%0, %1}"
20782 [(set_attr "type" "ssecvt")
20783 (set_attr "mode" "SF")])
20784
20785 (define_insn "cvtsi2ss"
20786 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20787 (vec_merge:V4SF
20788 (match_operand:V4SF 1 "register_operand" "0,0")
20789 (vec_duplicate:V4SF
20790 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20791 (const_int 14)))]
20792 "TARGET_SSE"
20793 "cvtsi2ss\t{%2, %0|%0, %2}"
20794 [(set_attr "type" "sseicvt")
20795 (set_attr "athlon_decode" "vector,double")
20796 (set_attr "mode" "SF")])
20797
20798 (define_insn "cvtsi2ssq"
20799 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20800 (vec_merge:V4SF
20801 (match_operand:V4SF 1 "register_operand" "0,0")
20802 (vec_duplicate:V4SF
20803 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20804 (const_int 14)))]
20805 "TARGET_SSE && TARGET_64BIT"
20806 "cvtsi2ssq\t{%2, %0|%0, %2}"
20807 [(set_attr "type" "sseicvt")
20808 (set_attr "athlon_decode" "vector,double")
20809 (set_attr "mode" "SF")])
20810
20811 (define_insn "cvtss2si"
20812 [(set (match_operand:SI 0 "register_operand" "=r,r")
20813 (vec_select:SI
20814 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20815 (parallel [(const_int 0)])))]
20816 "TARGET_SSE"
20817 "cvtss2si\t{%1, %0|%0, %1}"
20818 [(set_attr "type" "sseicvt")
20819 (set_attr "athlon_decode" "double,vector")
20820 (set_attr "mode" "SI")])
20821
20822 (define_insn "cvtss2siq"
20823 [(set (match_operand:DI 0 "register_operand" "=r,r")
20824 (vec_select:DI
20825 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20826 (parallel [(const_int 0)])))]
20827 "TARGET_SSE"
20828 "cvtss2siq\t{%1, %0|%0, %1}"
20829 [(set_attr "type" "sseicvt")
20830 (set_attr "athlon_decode" "double,vector")
20831 (set_attr "mode" "DI")])
20832
20833 (define_insn "cvttss2si"
20834 [(set (match_operand:SI 0 "register_operand" "=r,r")
20835 (vec_select:SI
20836 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20837 UNSPEC_FIX)
20838 (parallel [(const_int 0)])))]
20839 "TARGET_SSE"
20840 "cvttss2si\t{%1, %0|%0, %1}"
20841 [(set_attr "type" "sseicvt")
20842 (set_attr "mode" "SF")
20843 (set_attr "athlon_decode" "double,vector")])
20844
20845 (define_insn "cvttss2siq"
20846 [(set (match_operand:DI 0 "register_operand" "=r,r")
20847 (vec_select:DI
20848 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20849 UNSPEC_FIX)
20850 (parallel [(const_int 0)])))]
20851 "TARGET_SSE && TARGET_64BIT"
20852 "cvttss2siq\t{%1, %0|%0, %1}"
20853 [(set_attr "type" "sseicvt")
20854 (set_attr "mode" "SF")
20855 (set_attr "athlon_decode" "double,vector")])
20856
20857
20858 ;; MMX insns
20859
20860 ;; MMX arithmetic
20861
20862 (define_insn "addv8qi3"
20863 [(set (match_operand:V8QI 0 "register_operand" "=y")
20864 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20865 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20866 "TARGET_MMX"
20867 "paddb\t{%2, %0|%0, %2}"
20868 [(set_attr "type" "mmxadd")
20869 (set_attr "mode" "DI")])
20870
20871 (define_insn "addv4hi3"
20872 [(set (match_operand:V4HI 0 "register_operand" "=y")
20873 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20874 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20875 "TARGET_MMX"
20876 "paddw\t{%2, %0|%0, %2}"
20877 [(set_attr "type" "mmxadd")
20878 (set_attr "mode" "DI")])
20879
20880 (define_insn "addv2si3"
20881 [(set (match_operand:V2SI 0 "register_operand" "=y")
20882 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20883 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20884 "TARGET_MMX"
20885 "paddd\t{%2, %0|%0, %2}"
20886 [(set_attr "type" "mmxadd")
20887 (set_attr "mode" "DI")])
20888
20889 (define_insn "mmx_adddi3"
20890 [(set (match_operand:DI 0 "register_operand" "=y")
20891 (unspec:DI
20892 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20893 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20894 UNSPEC_NOP))]
20895 "TARGET_MMX"
20896 "paddq\t{%2, %0|%0, %2}"
20897 [(set_attr "type" "mmxadd")
20898 (set_attr "mode" "DI")])
20899
20900 (define_insn "ssaddv8qi3"
20901 [(set (match_operand:V8QI 0 "register_operand" "=y")
20902 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20903 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20904 "TARGET_MMX"
20905 "paddsb\t{%2, %0|%0, %2}"
20906 [(set_attr "type" "mmxadd")
20907 (set_attr "mode" "DI")])
20908
20909 (define_insn "ssaddv4hi3"
20910 [(set (match_operand:V4HI 0 "register_operand" "=y")
20911 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20912 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20913 "TARGET_MMX"
20914 "paddsw\t{%2, %0|%0, %2}"
20915 [(set_attr "type" "mmxadd")
20916 (set_attr "mode" "DI")])
20917
20918 (define_insn "usaddv8qi3"
20919 [(set (match_operand:V8QI 0 "register_operand" "=y")
20920 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20921 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20922 "TARGET_MMX"
20923 "paddusb\t{%2, %0|%0, %2}"
20924 [(set_attr "type" "mmxadd")
20925 (set_attr "mode" "DI")])
20926
20927 (define_insn "usaddv4hi3"
20928 [(set (match_operand:V4HI 0 "register_operand" "=y")
20929 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20930 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20931 "TARGET_MMX"
20932 "paddusw\t{%2, %0|%0, %2}"
20933 [(set_attr "type" "mmxadd")
20934 (set_attr "mode" "DI")])
20935
20936 (define_insn "subv8qi3"
20937 [(set (match_operand:V8QI 0 "register_operand" "=y")
20938 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20939 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20940 "TARGET_MMX"
20941 "psubb\t{%2, %0|%0, %2}"
20942 [(set_attr "type" "mmxadd")
20943 (set_attr "mode" "DI")])
20944
20945 (define_insn "subv4hi3"
20946 [(set (match_operand:V4HI 0 "register_operand" "=y")
20947 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20948 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20949 "TARGET_MMX"
20950 "psubw\t{%2, %0|%0, %2}"
20951 [(set_attr "type" "mmxadd")
20952 (set_attr "mode" "DI")])
20953
20954 (define_insn "subv2si3"
20955 [(set (match_operand:V2SI 0 "register_operand" "=y")
20956 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20957 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20958 "TARGET_MMX"
20959 "psubd\t{%2, %0|%0, %2}"
20960 [(set_attr "type" "mmxadd")
20961 (set_attr "mode" "DI")])
20962
20963 (define_insn "mmx_subdi3"
20964 [(set (match_operand:DI 0 "register_operand" "=y")
20965 (unspec:DI
20966 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20967 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20968 UNSPEC_NOP))]
20969 "TARGET_MMX"
20970 "psubq\t{%2, %0|%0, %2}"
20971 [(set_attr "type" "mmxadd")
20972 (set_attr "mode" "DI")])
20973
20974 (define_insn "sssubv8qi3"
20975 [(set (match_operand:V8QI 0 "register_operand" "=y")
20976 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20977 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20978 "TARGET_MMX"
20979 "psubsb\t{%2, %0|%0, %2}"
20980 [(set_attr "type" "mmxadd")
20981 (set_attr "mode" "DI")])
20982
20983 (define_insn "sssubv4hi3"
20984 [(set (match_operand:V4HI 0 "register_operand" "=y")
20985 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20986 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20987 "TARGET_MMX"
20988 "psubsw\t{%2, %0|%0, %2}"
20989 [(set_attr "type" "mmxadd")
20990 (set_attr "mode" "DI")])
20991
20992 (define_insn "ussubv8qi3"
20993 [(set (match_operand:V8QI 0 "register_operand" "=y")
20994 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20995 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20996 "TARGET_MMX"
20997 "psubusb\t{%2, %0|%0, %2}"
20998 [(set_attr "type" "mmxadd")
20999 (set_attr "mode" "DI")])
21000
21001 (define_insn "ussubv4hi3"
21002 [(set (match_operand:V4HI 0 "register_operand" "=y")
21003 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21004 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21005 "TARGET_MMX"
21006 "psubusw\t{%2, %0|%0, %2}"
21007 [(set_attr "type" "mmxadd")
21008 (set_attr "mode" "DI")])
21009
21010 (define_insn "mulv4hi3"
21011 [(set (match_operand:V4HI 0 "register_operand" "=y")
21012 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21013 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21014 "TARGET_MMX"
21015 "pmullw\t{%2, %0|%0, %2}"
21016 [(set_attr "type" "mmxmul")
21017 (set_attr "mode" "DI")])
21018
21019 (define_insn "smulv4hi3_highpart"
21020 [(set (match_operand:V4HI 0 "register_operand" "=y")
21021 (truncate:V4HI
21022 (lshiftrt:V4SI
21023 (mult:V4SI (sign_extend:V4SI
21024 (match_operand:V4HI 1 "register_operand" "0"))
21025 (sign_extend:V4SI
21026 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21027 (const_int 16))))]
21028 "TARGET_MMX"
21029 "pmulhw\t{%2, %0|%0, %2}"
21030 [(set_attr "type" "mmxmul")
21031 (set_attr "mode" "DI")])
21032
21033 (define_insn "umulv4hi3_highpart"
21034 [(set (match_operand:V4HI 0 "register_operand" "=y")
21035 (truncate:V4HI
21036 (lshiftrt:V4SI
21037 (mult:V4SI (zero_extend:V4SI
21038 (match_operand:V4HI 1 "register_operand" "0"))
21039 (zero_extend:V4SI
21040 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21041 (const_int 16))))]
21042 "TARGET_SSE || TARGET_3DNOW_A"
21043 "pmulhuw\t{%2, %0|%0, %2}"
21044 [(set_attr "type" "mmxmul")
21045 (set_attr "mode" "DI")])
21046
21047 (define_insn "mmx_pmaddwd"
21048 [(set (match_operand:V2SI 0 "register_operand" "=y")
21049 (plus:V2SI
21050 (mult:V2SI
21051 (sign_extend:V2SI
21052 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21053 (parallel [(const_int 0) (const_int 2)])))
21054 (sign_extend:V2SI
21055 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21056 (parallel [(const_int 0) (const_int 2)]))))
21057 (mult:V2SI
21058 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21059 (parallel [(const_int 1)
21060 (const_int 3)])))
21061 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21062 (parallel [(const_int 1)
21063 (const_int 3)]))))))]
21064 "TARGET_MMX"
21065 "pmaddwd\t{%2, %0|%0, %2}"
21066 [(set_attr "type" "mmxmul")
21067 (set_attr "mode" "DI")])
21068
21069
21070 ;; MMX logical operations
21071 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21072 ;; normal code that also wants to use the FPU from getting broken.
21073 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21074 (define_insn "mmx_iordi3"
21075 [(set (match_operand:DI 0 "register_operand" "=y")
21076 (unspec:DI
21077 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21078 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21079 UNSPEC_NOP))]
21080 "TARGET_MMX"
21081 "por\t{%2, %0|%0, %2}"
21082 [(set_attr "type" "mmxadd")
21083 (set_attr "mode" "DI")])
21084
21085 (define_insn "mmx_xordi3"
21086 [(set (match_operand:DI 0 "register_operand" "=y")
21087 (unspec:DI
21088 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21089 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21090 UNSPEC_NOP))]
21091 "TARGET_MMX"
21092 "pxor\t{%2, %0|%0, %2}"
21093 [(set_attr "type" "mmxadd")
21094 (set_attr "mode" "DI")
21095 (set_attr "memory" "none")])
21096
21097 ;; Same as pxor, but don't show input operands so that we don't think
21098 ;; they are live.
21099 (define_insn "mmx_clrdi"
21100 [(set (match_operand:DI 0 "register_operand" "=y")
21101 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21102 "TARGET_MMX"
21103 "pxor\t{%0, %0|%0, %0}"
21104 [(set_attr "type" "mmxadd")
21105 (set_attr "mode" "DI")
21106 (set_attr "memory" "none")])
21107
21108 (define_insn "mmx_anddi3"
21109 [(set (match_operand:DI 0 "register_operand" "=y")
21110 (unspec:DI
21111 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21112 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21113 UNSPEC_NOP))]
21114 "TARGET_MMX"
21115 "pand\t{%2, %0|%0, %2}"
21116 [(set_attr "type" "mmxadd")
21117 (set_attr "mode" "DI")])
21118
21119 (define_insn "mmx_nanddi3"
21120 [(set (match_operand:DI 0 "register_operand" "=y")
21121 (unspec:DI
21122 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21123 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21124 UNSPEC_NOP))]
21125 "TARGET_MMX"
21126 "pandn\t{%2, %0|%0, %2}"
21127 [(set_attr "type" "mmxadd")
21128 (set_attr "mode" "DI")])
21129
21130
21131 ;; MMX unsigned averages/sum of absolute differences
21132
21133 (define_insn "mmx_uavgv8qi3"
21134 [(set (match_operand:V8QI 0 "register_operand" "=y")
21135 (ashiftrt:V8QI
21136 (plus:V8QI (plus:V8QI
21137 (match_operand:V8QI 1 "register_operand" "0")
21138 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21139 (const_vector:V8QI [(const_int 1)
21140 (const_int 1)
21141 (const_int 1)
21142 (const_int 1)
21143 (const_int 1)
21144 (const_int 1)
21145 (const_int 1)
21146 (const_int 1)]))
21147 (const_int 1)))]
21148 "TARGET_SSE || TARGET_3DNOW_A"
21149 "pavgb\t{%2, %0|%0, %2}"
21150 [(set_attr "type" "mmxshft")
21151 (set_attr "mode" "DI")])
21152
21153 (define_insn "mmx_uavgv4hi3"
21154 [(set (match_operand:V4HI 0 "register_operand" "=y")
21155 (ashiftrt:V4HI
21156 (plus:V4HI (plus:V4HI
21157 (match_operand:V4HI 1 "register_operand" "0")
21158 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21159 (const_vector:V4HI [(const_int 1)
21160 (const_int 1)
21161 (const_int 1)
21162 (const_int 1)]))
21163 (const_int 1)))]
21164 "TARGET_SSE || TARGET_3DNOW_A"
21165 "pavgw\t{%2, %0|%0, %2}"
21166 [(set_attr "type" "mmxshft")
21167 (set_attr "mode" "DI")])
21168
21169 (define_insn "mmx_psadbw"
21170 [(set (match_operand:DI 0 "register_operand" "=y")
21171 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21172 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21173 UNSPEC_PSADBW))]
21174 "TARGET_SSE || TARGET_3DNOW_A"
21175 "psadbw\t{%2, %0|%0, %2}"
21176 [(set_attr "type" "mmxshft")
21177 (set_attr "mode" "DI")])
21178
21179
21180 ;; MMX insert/extract/shuffle
21181
21182 (define_insn "mmx_pinsrw"
21183 [(set (match_operand:V4HI 0 "register_operand" "=y")
21184 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21185 (vec_duplicate:V4HI
21186 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21187 (match_operand:SI 3 "immediate_operand" "i")))]
21188 "TARGET_SSE || TARGET_3DNOW_A"
21189 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21190 [(set_attr "type" "mmxcvt")
21191 (set_attr "mode" "DI")])
21192
21193 (define_insn "mmx_pextrw"
21194 [(set (match_operand:SI 0 "register_operand" "=r")
21195 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21196 (parallel
21197 [(match_operand:SI 2 "immediate_operand" "i")]))))]
21198 "TARGET_SSE || TARGET_3DNOW_A"
21199 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21200 [(set_attr "type" "mmxcvt")
21201 (set_attr "mode" "DI")])
21202
21203 (define_insn "mmx_pshufw"
21204 [(set (match_operand:V4HI 0 "register_operand" "=y")
21205 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
21206 (match_operand:SI 2 "immediate_operand" "i")]
21207 UNSPEC_SHUFFLE))]
21208 "TARGET_SSE || TARGET_3DNOW_A"
21209 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21210 [(set_attr "type" "mmxcvt")
21211 (set_attr "mode" "DI")])
21212
21213
21214 ;; MMX mask-generating comparisons
21215
21216 (define_insn "eqv8qi3"
21217 [(set (match_operand:V8QI 0 "register_operand" "=y")
21218 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21219 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21220 "TARGET_MMX"
21221 "pcmpeqb\t{%2, %0|%0, %2}"
21222 [(set_attr "type" "mmxcmp")
21223 (set_attr "mode" "DI")])
21224
21225 (define_insn "eqv4hi3"
21226 [(set (match_operand:V4HI 0 "register_operand" "=y")
21227 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21228 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21229 "TARGET_MMX"
21230 "pcmpeqw\t{%2, %0|%0, %2}"
21231 [(set_attr "type" "mmxcmp")
21232 (set_attr "mode" "DI")])
21233
21234 (define_insn "eqv2si3"
21235 [(set (match_operand:V2SI 0 "register_operand" "=y")
21236 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21237 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21238 "TARGET_MMX"
21239 "pcmpeqd\t{%2, %0|%0, %2}"
21240 [(set_attr "type" "mmxcmp")
21241 (set_attr "mode" "DI")])
21242
21243 (define_insn "gtv8qi3"
21244 [(set (match_operand:V8QI 0 "register_operand" "=y")
21245 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21246 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21247 "TARGET_MMX"
21248 "pcmpgtb\t{%2, %0|%0, %2}"
21249 [(set_attr "type" "mmxcmp")
21250 (set_attr "mode" "DI")])
21251
21252 (define_insn "gtv4hi3"
21253 [(set (match_operand:V4HI 0 "register_operand" "=y")
21254 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21255 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21256 "TARGET_MMX"
21257 "pcmpgtw\t{%2, %0|%0, %2}"
21258 [(set_attr "type" "mmxcmp")
21259 (set_attr "mode" "DI")])
21260
21261 (define_insn "gtv2si3"
21262 [(set (match_operand:V2SI 0 "register_operand" "=y")
21263 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21264 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21265 "TARGET_MMX"
21266 "pcmpgtd\t{%2, %0|%0, %2}"
21267 [(set_attr "type" "mmxcmp")
21268 (set_attr "mode" "DI")])
21269
21270
21271 ;; MMX max/min insns
21272
21273 (define_insn "umaxv8qi3"
21274 [(set (match_operand:V8QI 0 "register_operand" "=y")
21275 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21276 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21277 "TARGET_SSE || TARGET_3DNOW_A"
21278 "pmaxub\t{%2, %0|%0, %2}"
21279 [(set_attr "type" "mmxadd")
21280 (set_attr "mode" "DI")])
21281
21282 (define_insn "smaxv4hi3"
21283 [(set (match_operand:V4HI 0 "register_operand" "=y")
21284 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21285 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21286 "TARGET_SSE || TARGET_3DNOW_A"
21287 "pmaxsw\t{%2, %0|%0, %2}"
21288 [(set_attr "type" "mmxadd")
21289 (set_attr "mode" "DI")])
21290
21291 (define_insn "uminv8qi3"
21292 [(set (match_operand:V8QI 0 "register_operand" "=y")
21293 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21294 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21295 "TARGET_SSE || TARGET_3DNOW_A"
21296 "pminub\t{%2, %0|%0, %2}"
21297 [(set_attr "type" "mmxadd")
21298 (set_attr "mode" "DI")])
21299
21300 (define_insn "sminv4hi3"
21301 [(set (match_operand:V4HI 0 "register_operand" "=y")
21302 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21303 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21304 "TARGET_SSE || TARGET_3DNOW_A"
21305 "pminsw\t{%2, %0|%0, %2}"
21306 [(set_attr "type" "mmxadd")
21307 (set_attr "mode" "DI")])
21308
21309
21310 ;; MMX shifts
21311
21312 (define_insn "ashrv4hi3"
21313 [(set (match_operand:V4HI 0 "register_operand" "=y")
21314 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21315 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21316 "TARGET_MMX"
21317 "psraw\t{%2, %0|%0, %2}"
21318 [(set_attr "type" "mmxshft")
21319 (set_attr "mode" "DI")])
21320
21321 (define_insn "ashrv2si3"
21322 [(set (match_operand:V2SI 0 "register_operand" "=y")
21323 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21324 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21325 "TARGET_MMX"
21326 "psrad\t{%2, %0|%0, %2}"
21327 [(set_attr "type" "mmxshft")
21328 (set_attr "mode" "DI")])
21329
21330 (define_insn "lshrv4hi3"
21331 [(set (match_operand:V4HI 0 "register_operand" "=y")
21332 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21333 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21334 "TARGET_MMX"
21335 "psrlw\t{%2, %0|%0, %2}"
21336 [(set_attr "type" "mmxshft")
21337 (set_attr "mode" "DI")])
21338
21339 (define_insn "lshrv2si3"
21340 [(set (match_operand:V2SI 0 "register_operand" "=y")
21341 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21342 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21343 "TARGET_MMX"
21344 "psrld\t{%2, %0|%0, %2}"
21345 [(set_attr "type" "mmxshft")
21346 (set_attr "mode" "DI")])
21347
21348 ;; See logical MMX insns.
21349 (define_insn "mmx_lshrdi3"
21350 [(set (match_operand:DI 0 "register_operand" "=y")
21351 (unspec:DI
21352 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21353 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21354 UNSPEC_NOP))]
21355 "TARGET_MMX"
21356 "psrlq\t{%2, %0|%0, %2}"
21357 [(set_attr "type" "mmxshft")
21358 (set_attr "mode" "DI")])
21359
21360 (define_insn "ashlv4hi3"
21361 [(set (match_operand:V4HI 0 "register_operand" "=y")
21362 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21363 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21364 "TARGET_MMX"
21365 "psllw\t{%2, %0|%0, %2}"
21366 [(set_attr "type" "mmxshft")
21367 (set_attr "mode" "DI")])
21368
21369 (define_insn "ashlv2si3"
21370 [(set (match_operand:V2SI 0 "register_operand" "=y")
21371 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21372 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21373 "TARGET_MMX"
21374 "pslld\t{%2, %0|%0, %2}"
21375 [(set_attr "type" "mmxshft")
21376 (set_attr "mode" "DI")])
21377
21378 ;; See logical MMX insns.
21379 (define_insn "mmx_ashldi3"
21380 [(set (match_operand:DI 0 "register_operand" "=y")
21381 (unspec:DI
21382 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21383 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21384 UNSPEC_NOP))]
21385 "TARGET_MMX"
21386 "psllq\t{%2, %0|%0, %2}"
21387 [(set_attr "type" "mmxshft")
21388 (set_attr "mode" "DI")])
21389
21390
21391 ;; MMX pack/unpack insns.
21392
21393 (define_insn "mmx_packsswb"
21394 [(set (match_operand:V8QI 0 "register_operand" "=y")
21395 (vec_concat:V8QI
21396 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21397 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21398 "TARGET_MMX"
21399 "packsswb\t{%2, %0|%0, %2}"
21400 [(set_attr "type" "mmxshft")
21401 (set_attr "mode" "DI")])
21402
21403 (define_insn "mmx_packssdw"
21404 [(set (match_operand:V4HI 0 "register_operand" "=y")
21405 (vec_concat:V4HI
21406 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21407 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21408 "TARGET_MMX"
21409 "packssdw\t{%2, %0|%0, %2}"
21410 [(set_attr "type" "mmxshft")
21411 (set_attr "mode" "DI")])
21412
21413 (define_insn "mmx_packuswb"
21414 [(set (match_operand:V8QI 0 "register_operand" "=y")
21415 (vec_concat:V8QI
21416 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21417 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21418 "TARGET_MMX"
21419 "packuswb\t{%2, %0|%0, %2}"
21420 [(set_attr "type" "mmxshft")
21421 (set_attr "mode" "DI")])
21422
21423 (define_insn "mmx_punpckhbw"
21424 [(set (match_operand:V8QI 0 "register_operand" "=y")
21425 (vec_merge:V8QI
21426 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21427 (parallel [(const_int 4)
21428 (const_int 0)
21429 (const_int 5)
21430 (const_int 1)
21431 (const_int 6)
21432 (const_int 2)
21433 (const_int 7)
21434 (const_int 3)]))
21435 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21436 (parallel [(const_int 0)
21437 (const_int 4)
21438 (const_int 1)
21439 (const_int 5)
21440 (const_int 2)
21441 (const_int 6)
21442 (const_int 3)
21443 (const_int 7)]))
21444 (const_int 85)))]
21445 "TARGET_MMX"
21446 "punpckhbw\t{%2, %0|%0, %2}"
21447 [(set_attr "type" "mmxcvt")
21448 (set_attr "mode" "DI")])
21449
21450 (define_insn "mmx_punpckhwd"
21451 [(set (match_operand:V4HI 0 "register_operand" "=y")
21452 (vec_merge:V4HI
21453 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21454 (parallel [(const_int 0)
21455 (const_int 2)
21456 (const_int 1)
21457 (const_int 3)]))
21458 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21459 (parallel [(const_int 2)
21460 (const_int 0)
21461 (const_int 3)
21462 (const_int 1)]))
21463 (const_int 5)))]
21464 "TARGET_MMX"
21465 "punpckhwd\t{%2, %0|%0, %2}"
21466 [(set_attr "type" "mmxcvt")
21467 (set_attr "mode" "DI")])
21468
21469 (define_insn "mmx_punpckhdq"
21470 [(set (match_operand:V2SI 0 "register_operand" "=y")
21471 (vec_merge:V2SI
21472 (match_operand:V2SI 1 "register_operand" "0")
21473 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21474 (parallel [(const_int 1)
21475 (const_int 0)]))
21476 (const_int 1)))]
21477 "TARGET_MMX"
21478 "punpckhdq\t{%2, %0|%0, %2}"
21479 [(set_attr "type" "mmxcvt")
21480 (set_attr "mode" "DI")])
21481
21482 (define_insn "mmx_punpcklbw"
21483 [(set (match_operand:V8QI 0 "register_operand" "=y")
21484 (vec_merge:V8QI
21485 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21486 (parallel [(const_int 0)
21487 (const_int 4)
21488 (const_int 1)
21489 (const_int 5)
21490 (const_int 2)
21491 (const_int 6)
21492 (const_int 3)
21493 (const_int 7)]))
21494 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21495 (parallel [(const_int 4)
21496 (const_int 0)
21497 (const_int 5)
21498 (const_int 1)
21499 (const_int 6)
21500 (const_int 2)
21501 (const_int 7)
21502 (const_int 3)]))
21503 (const_int 85)))]
21504 "TARGET_MMX"
21505 "punpcklbw\t{%2, %0|%0, %2}"
21506 [(set_attr "type" "mmxcvt")
21507 (set_attr "mode" "DI")])
21508
21509 (define_insn "mmx_punpcklwd"
21510 [(set (match_operand:V4HI 0 "register_operand" "=y")
21511 (vec_merge:V4HI
21512 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21513 (parallel [(const_int 2)
21514 (const_int 0)
21515 (const_int 3)
21516 (const_int 1)]))
21517 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21518 (parallel [(const_int 0)
21519 (const_int 2)
21520 (const_int 1)
21521 (const_int 3)]))
21522 (const_int 5)))]
21523 "TARGET_MMX"
21524 "punpcklwd\t{%2, %0|%0, %2}"
21525 [(set_attr "type" "mmxcvt")
21526 (set_attr "mode" "DI")])
21527
21528 (define_insn "mmx_punpckldq"
21529 [(set (match_operand:V2SI 0 "register_operand" "=y")
21530 (vec_merge:V2SI
21531 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21532 (parallel [(const_int 1)
21533 (const_int 0)]))
21534 (match_operand:V2SI 2 "register_operand" "y")
21535 (const_int 1)))]
21536 "TARGET_MMX"
21537 "punpckldq\t{%2, %0|%0, %2}"
21538 [(set_attr "type" "mmxcvt")
21539 (set_attr "mode" "DI")])
21540
21541
21542 ;; Miscellaneous stuff
21543
21544 (define_insn "emms"
21545 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21546 (clobber (reg:XF 8))
21547 (clobber (reg:XF 9))
21548 (clobber (reg:XF 10))
21549 (clobber (reg:XF 11))
21550 (clobber (reg:XF 12))
21551 (clobber (reg:XF 13))
21552 (clobber (reg:XF 14))
21553 (clobber (reg:XF 15))
21554 (clobber (reg:DI 29))
21555 (clobber (reg:DI 30))
21556 (clobber (reg:DI 31))
21557 (clobber (reg:DI 32))
21558 (clobber (reg:DI 33))
21559 (clobber (reg:DI 34))
21560 (clobber (reg:DI 35))
21561 (clobber (reg:DI 36))]
21562 "TARGET_MMX"
21563 "emms"
21564 [(set_attr "type" "mmx")
21565 (set_attr "memory" "unknown")])
21566
21567 (define_insn "ldmxcsr"
21568 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21569 UNSPECV_LDMXCSR)]
21570 "TARGET_SSE"
21571 "ldmxcsr\t%0"
21572 [(set_attr "type" "sse")
21573 (set_attr "memory" "load")])
21574
21575 (define_insn "stmxcsr"
21576 [(set (match_operand:SI 0 "memory_operand" "=m")
21577 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21578 "TARGET_SSE"
21579 "stmxcsr\t%0"
21580 [(set_attr "type" "sse")
21581 (set_attr "memory" "store")])
21582
21583 (define_expand "sfence"
21584 [(set (match_dup 0)
21585 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21586 "TARGET_SSE || TARGET_3DNOW_A"
21587 {
21588 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21589 MEM_VOLATILE_P (operands[0]) = 1;
21590 })
21591
21592 (define_insn "*sfence_insn"
21593 [(set (match_operand:BLK 0 "" "")
21594 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21595 "TARGET_SSE || TARGET_3DNOW_A"
21596 "sfence"
21597 [(set_attr "type" "sse")
21598 (set_attr "memory" "unknown")])
21599
21600 (define_expand "sse_prologue_save"
21601 [(parallel [(set (match_operand:BLK 0 "" "")
21602 (unspec:BLK [(reg:DI 21)
21603 (reg:DI 22)
21604 (reg:DI 23)
21605 (reg:DI 24)
21606 (reg:DI 25)
21607 (reg:DI 26)
21608 (reg:DI 27)
21609 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21610 (use (match_operand:DI 1 "register_operand" ""))
21611 (use (match_operand:DI 2 "immediate_operand" ""))
21612 (use (label_ref:DI (match_operand 3 "" "")))])]
21613 "TARGET_64BIT"
21614 "")
21615
21616 (define_insn "*sse_prologue_save_insn"
21617 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21618 (match_operand:DI 4 "const_int_operand" "n")))
21619 (unspec:BLK [(reg:DI 21)
21620 (reg:DI 22)
21621 (reg:DI 23)
21622 (reg:DI 24)
21623 (reg:DI 25)
21624 (reg:DI 26)
21625 (reg:DI 27)
21626 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21627 (use (match_operand:DI 1 "register_operand" "r"))
21628 (use (match_operand:DI 2 "const_int_operand" "i"))
21629 (use (label_ref:DI (match_operand 3 "" "X")))]
21630 "TARGET_64BIT
21631 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21632 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21633 "*
21634 {
21635 int i;
21636 operands[0] = gen_rtx_MEM (Pmode,
21637 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21638 output_asm_insn (\"jmp\\t%A1\", operands);
21639 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21640 {
21641 operands[4] = adjust_address (operands[0], DImode, i*16);
21642 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21643 PUT_MODE (operands[4], TImode);
21644 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21645 output_asm_insn (\"rex\", operands);
21646 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21647 }
21648 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21649 CODE_LABEL_NUMBER (operands[3]));
21650 RET;
21651 }
21652 "
21653 [(set_attr "type" "other")
21654 (set_attr "length_immediate" "0")
21655 (set_attr "length_address" "0")
21656 (set_attr "length" "135")
21657 (set_attr "memory" "store")
21658 (set_attr "modrm" "0")
21659 (set_attr "mode" "DI")])
21660
21661 ;; 3Dnow! instructions
21662
21663 (define_insn "addv2sf3"
21664 [(set (match_operand:V2SF 0 "register_operand" "=y")
21665 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21666 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21667 "TARGET_3DNOW"
21668 "pfadd\\t{%2, %0|%0, %2}"
21669 [(set_attr "type" "mmxadd")
21670 (set_attr "mode" "V2SF")])
21671
21672 (define_insn "subv2sf3"
21673 [(set (match_operand:V2SF 0 "register_operand" "=y")
21674 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21675 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21676 "TARGET_3DNOW"
21677 "pfsub\\t{%2, %0|%0, %2}"
21678 [(set_attr "type" "mmxadd")
21679 (set_attr "mode" "V2SF")])
21680
21681 (define_insn "subrv2sf3"
21682 [(set (match_operand:V2SF 0 "register_operand" "=y")
21683 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21684 (match_operand:V2SF 1 "register_operand" "0")))]
21685 "TARGET_3DNOW"
21686 "pfsubr\\t{%2, %0|%0, %2}"
21687 [(set_attr "type" "mmxadd")
21688 (set_attr "mode" "V2SF")])
21689
21690 (define_insn "gtv2sf3"
21691 [(set (match_operand:V2SI 0 "register_operand" "=y")
21692 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21693 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21694 "TARGET_3DNOW"
21695 "pfcmpgt\\t{%2, %0|%0, %2}"
21696 [(set_attr "type" "mmxcmp")
21697 (set_attr "mode" "V2SF")])
21698
21699 (define_insn "gev2sf3"
21700 [(set (match_operand:V2SI 0 "register_operand" "=y")
21701 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21702 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21703 "TARGET_3DNOW"
21704 "pfcmpge\\t{%2, %0|%0, %2}"
21705 [(set_attr "type" "mmxcmp")
21706 (set_attr "mode" "V2SF")])
21707
21708 (define_insn "eqv2sf3"
21709 [(set (match_operand:V2SI 0 "register_operand" "=y")
21710 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21711 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21712 "TARGET_3DNOW"
21713 "pfcmpeq\\t{%2, %0|%0, %2}"
21714 [(set_attr "type" "mmxcmp")
21715 (set_attr "mode" "V2SF")])
21716
21717 (define_insn "pfmaxv2sf3"
21718 [(set (match_operand:V2SF 0 "register_operand" "=y")
21719 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21720 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21721 "TARGET_3DNOW"
21722 "pfmax\\t{%2, %0|%0, %2}"
21723 [(set_attr "type" "mmxadd")
21724 (set_attr "mode" "V2SF")])
21725
21726 (define_insn "pfminv2sf3"
21727 [(set (match_operand:V2SF 0 "register_operand" "=y")
21728 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21729 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21730 "TARGET_3DNOW"
21731 "pfmin\\t{%2, %0|%0, %2}"
21732 [(set_attr "type" "mmxadd")
21733 (set_attr "mode" "V2SF")])
21734
21735 (define_insn "mulv2sf3"
21736 [(set (match_operand:V2SF 0 "register_operand" "=y")
21737 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21738 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21739 "TARGET_3DNOW"
21740 "pfmul\\t{%2, %0|%0, %2}"
21741 [(set_attr "type" "mmxmul")
21742 (set_attr "mode" "V2SF")])
21743
21744 (define_insn "femms"
21745 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21746 (clobber (reg:XF 8))
21747 (clobber (reg:XF 9))
21748 (clobber (reg:XF 10))
21749 (clobber (reg:XF 11))
21750 (clobber (reg:XF 12))
21751 (clobber (reg:XF 13))
21752 (clobber (reg:XF 14))
21753 (clobber (reg:XF 15))
21754 (clobber (reg:DI 29))
21755 (clobber (reg:DI 30))
21756 (clobber (reg:DI 31))
21757 (clobber (reg:DI 32))
21758 (clobber (reg:DI 33))
21759 (clobber (reg:DI 34))
21760 (clobber (reg:DI 35))
21761 (clobber (reg:DI 36))]
21762 "TARGET_3DNOW"
21763 "femms"
21764 [(set_attr "type" "mmx")
21765 (set_attr "memory" "none")])
21766
21767 (define_insn "pf2id"
21768 [(set (match_operand:V2SI 0 "register_operand" "=y")
21769 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21770 "TARGET_3DNOW"
21771 "pf2id\\t{%1, %0|%0, %1}"
21772 [(set_attr "type" "mmxcvt")
21773 (set_attr "mode" "V2SF")])
21774
21775 (define_insn "pf2iw"
21776 [(set (match_operand:V2SI 0 "register_operand" "=y")
21777 (sign_extend:V2SI
21778 (ss_truncate:V2HI
21779 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21780 "TARGET_3DNOW_A"
21781 "pf2iw\\t{%1, %0|%0, %1}"
21782 [(set_attr "type" "mmxcvt")
21783 (set_attr "mode" "V2SF")])
21784
21785 (define_insn "pfacc"
21786 [(set (match_operand:V2SF 0 "register_operand" "=y")
21787 (vec_concat:V2SF
21788 (plus:SF
21789 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21790 (parallel [(const_int 0)]))
21791 (vec_select:SF (match_dup 1)
21792 (parallel [(const_int 1)])))
21793 (plus:SF
21794 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21795 (parallel [(const_int 0)]))
21796 (vec_select:SF (match_dup 2)
21797 (parallel [(const_int 1)])))))]
21798 "TARGET_3DNOW"
21799 "pfacc\\t{%2, %0|%0, %2}"
21800 [(set_attr "type" "mmxadd")
21801 (set_attr "mode" "V2SF")])
21802
21803 (define_insn "pfnacc"
21804 [(set (match_operand:V2SF 0 "register_operand" "=y")
21805 (vec_concat:V2SF
21806 (minus:SF
21807 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21808 (parallel [(const_int 0)]))
21809 (vec_select:SF (match_dup 1)
21810 (parallel [(const_int 1)])))
21811 (minus:SF
21812 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21813 (parallel [(const_int 0)]))
21814 (vec_select:SF (match_dup 2)
21815 (parallel [(const_int 1)])))))]
21816 "TARGET_3DNOW_A"
21817 "pfnacc\\t{%2, %0|%0, %2}"
21818 [(set_attr "type" "mmxadd")
21819 (set_attr "mode" "V2SF")])
21820
21821 (define_insn "pfpnacc"
21822 [(set (match_operand:V2SF 0 "register_operand" "=y")
21823 (vec_concat:V2SF
21824 (minus:SF
21825 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21826 (parallel [(const_int 0)]))
21827 (vec_select:SF (match_dup 1)
21828 (parallel [(const_int 1)])))
21829 (plus:SF
21830 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21831 (parallel [(const_int 0)]))
21832 (vec_select:SF (match_dup 2)
21833 (parallel [(const_int 1)])))))]
21834 "TARGET_3DNOW_A"
21835 "pfpnacc\\t{%2, %0|%0, %2}"
21836 [(set_attr "type" "mmxadd")
21837 (set_attr "mode" "V2SF")])
21838
21839 (define_insn "pi2fw"
21840 [(set (match_operand:V2SF 0 "register_operand" "=y")
21841 (float:V2SF
21842 (vec_concat:V2SI
21843 (sign_extend:SI
21844 (truncate:HI
21845 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21846 (parallel [(const_int 0)]))))
21847 (sign_extend:SI
21848 (truncate:HI
21849 (vec_select:SI (match_dup 1)
21850 (parallel [(const_int 1)])))))))]
21851 "TARGET_3DNOW_A"
21852 "pi2fw\\t{%1, %0|%0, %1}"
21853 [(set_attr "type" "mmxcvt")
21854 (set_attr "mode" "V2SF")])
21855
21856 (define_insn "floatv2si2"
21857 [(set (match_operand:V2SF 0 "register_operand" "=y")
21858 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21859 "TARGET_3DNOW"
21860 "pi2fd\\t{%1, %0|%0, %1}"
21861 [(set_attr "type" "mmxcvt")
21862 (set_attr "mode" "V2SF")])
21863
21864 ;; This insn is identical to pavgb in operation, but the opcode is
21865 ;; different. To avoid accidentally matching pavgb, use an unspec.
21866
21867 (define_insn "pavgusb"
21868 [(set (match_operand:V8QI 0 "register_operand" "=y")
21869 (unspec:V8QI
21870 [(match_operand:V8QI 1 "register_operand" "0")
21871 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21872 UNSPEC_PAVGUSB))]
21873 "TARGET_3DNOW"
21874 "pavgusb\\t{%2, %0|%0, %2}"
21875 [(set_attr "type" "mmxshft")
21876 (set_attr "mode" "TI")])
21877
21878 ;; 3DNow reciprocal and sqrt
21879
21880 (define_insn "pfrcpv2sf2"
21881 [(set (match_operand:V2SF 0 "register_operand" "=y")
21882 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21883 UNSPEC_PFRCP))]
21884 "TARGET_3DNOW"
21885 "pfrcp\\t{%1, %0|%0, %1}"
21886 [(set_attr "type" "mmx")
21887 (set_attr "mode" "TI")])
21888
21889 (define_insn "pfrcpit1v2sf3"
21890 [(set (match_operand:V2SF 0 "register_operand" "=y")
21891 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21892 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21893 UNSPEC_PFRCPIT1))]
21894 "TARGET_3DNOW"
21895 "pfrcpit1\\t{%2, %0|%0, %2}"
21896 [(set_attr "type" "mmx")
21897 (set_attr "mode" "TI")])
21898
21899 (define_insn "pfrcpit2v2sf3"
21900 [(set (match_operand:V2SF 0 "register_operand" "=y")
21901 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21902 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21903 UNSPEC_PFRCPIT2))]
21904 "TARGET_3DNOW"
21905 "pfrcpit2\\t{%2, %0|%0, %2}"
21906 [(set_attr "type" "mmx")
21907 (set_attr "mode" "TI")])
21908
21909 (define_insn "pfrsqrtv2sf2"
21910 [(set (match_operand:V2SF 0 "register_operand" "=y")
21911 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21912 UNSPEC_PFRSQRT))]
21913 "TARGET_3DNOW"
21914 "pfrsqrt\\t{%1, %0|%0, %1}"
21915 [(set_attr "type" "mmx")
21916 (set_attr "mode" "TI")])
21917
21918 (define_insn "pfrsqit1v2sf3"
21919 [(set (match_operand:V2SF 0 "register_operand" "=y")
21920 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21921 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21922 UNSPEC_PFRSQIT1))]
21923 "TARGET_3DNOW"
21924 "pfrsqit1\\t{%2, %0|%0, %2}"
21925 [(set_attr "type" "mmx")
21926 (set_attr "mode" "TI")])
21927
21928 (define_insn "pmulhrwv4hi3"
21929 [(set (match_operand:V4HI 0 "register_operand" "=y")
21930 (truncate:V4HI
21931 (lshiftrt:V4SI
21932 (plus:V4SI
21933 (mult:V4SI
21934 (sign_extend:V4SI
21935 (match_operand:V4HI 1 "register_operand" "0"))
21936 (sign_extend:V4SI
21937 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21938 (const_vector:V4SI [(const_int 32768)
21939 (const_int 32768)
21940 (const_int 32768)
21941 (const_int 32768)]))
21942 (const_int 16))))]
21943 "TARGET_3DNOW"
21944 "pmulhrw\\t{%2, %0|%0, %2}"
21945 [(set_attr "type" "mmxmul")
21946 (set_attr "mode" "TI")])
21947
21948 (define_insn "pswapdv2si2"
21949 [(set (match_operand:V2SI 0 "register_operand" "=y")
21950 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21951 (parallel [(const_int 1) (const_int 0)])))]
21952 "TARGET_3DNOW_A"
21953 "pswapd\\t{%1, %0|%0, %1}"
21954 [(set_attr "type" "mmxcvt")
21955 (set_attr "mode" "TI")])
21956
21957 (define_insn "pswapdv2sf2"
21958 [(set (match_operand:V2SF 0 "register_operand" "=y")
21959 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21960 (parallel [(const_int 1) (const_int 0)])))]
21961 "TARGET_3DNOW_A"
21962 "pswapd\\t{%1, %0|%0, %1}"
21963 [(set_attr "type" "mmxcvt")
21964 (set_attr "mode" "TI")])
21965
21966 (define_expand "prefetch"
21967 [(prefetch (match_operand 0 "address_operand" "")
21968 (match_operand:SI 1 "const_int_operand" "")
21969 (match_operand:SI 2 "const_int_operand" ""))]
21970 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21971 {
21972 int rw = INTVAL (operands[1]);
21973 int locality = INTVAL (operands[2]);
21974
21975 if (rw != 0 && rw != 1)
21976 abort ();
21977 if (locality < 0 || locality > 3)
21978 abort ();
21979 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21980 abort ();
21981
21982 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21983 suported by SSE counterpart or the SSE prefetch is not available
21984 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21985 of locality. */
21986 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21987 operands[2] = GEN_INT (3);
21988 else
21989 operands[1] = const0_rtx;
21990 })
21991
21992 (define_insn "*prefetch_sse"
21993 [(prefetch (match_operand:SI 0 "address_operand" "p")
21994 (const_int 0)
21995 (match_operand:SI 1 "const_int_operand" ""))]
21996 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21997 {
21998 static const char * const patterns[4] = {
21999 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22000 };
22001
22002 int locality = INTVAL (operands[1]);
22003 if (locality < 0 || locality > 3)
22004 abort ();
22005
22006 return patterns[locality];
22007 }
22008 [(set_attr "type" "sse")
22009 (set_attr "memory" "none")])
22010
22011 (define_insn "*prefetch_sse_rex"
22012 [(prefetch (match_operand:DI 0 "address_operand" "p")
22013 (const_int 0)
22014 (match_operand:SI 1 "const_int_operand" ""))]
22015 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22016 {
22017 static const char * const patterns[4] = {
22018 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22019 };
22020
22021 int locality = INTVAL (operands[1]);
22022 if (locality < 0 || locality > 3)
22023 abort ();
22024
22025 return patterns[locality];
22026 }
22027 [(set_attr "type" "sse")
22028 (set_attr "memory" "none")])
22029
22030 (define_insn "*prefetch_3dnow"
22031 [(prefetch (match_operand:SI 0 "address_operand" "p")
22032 (match_operand:SI 1 "const_int_operand" "n")
22033 (const_int 3))]
22034 "TARGET_3DNOW && !TARGET_64BIT"
22035 {
22036 if (INTVAL (operands[1]) == 0)
22037 return "prefetch\t%a0";
22038 else
22039 return "prefetchw\t%a0";
22040 }
22041 [(set_attr "type" "mmx")
22042 (set_attr "memory" "none")])
22043
22044 (define_insn "*prefetch_3dnow_rex"
22045 [(prefetch (match_operand:DI 0 "address_operand" "p")
22046 (match_operand:SI 1 "const_int_operand" "n")
22047 (const_int 3))]
22048 "TARGET_3DNOW && TARGET_64BIT"
22049 {
22050 if (INTVAL (operands[1]) == 0)
22051 return "prefetch\t%a0";
22052 else
22053 return "prefetchw\t%a0";
22054 }
22055 [(set_attr "type" "mmx")
22056 (set_attr "memory" "none")])
22057
22058 ;; SSE2 support
22059
22060 (define_insn "addv2df3"
22061 [(set (match_operand:V2DF 0 "register_operand" "=x")
22062 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22063 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22064 "TARGET_SSE2"
22065 "addpd\t{%2, %0|%0, %2}"
22066 [(set_attr "type" "sseadd")
22067 (set_attr "mode" "V2DF")])
22068
22069 (define_insn "vmaddv2df3"
22070 [(set (match_operand:V2DF 0 "register_operand" "=x")
22071 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22072 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22073 (match_dup 1)
22074 (const_int 1)))]
22075 "TARGET_SSE2"
22076 "addsd\t{%2, %0|%0, %2}"
22077 [(set_attr "type" "sseadd")
22078 (set_attr "mode" "DF")])
22079
22080 (define_insn "subv2df3"
22081 [(set (match_operand:V2DF 0 "register_operand" "=x")
22082 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22083 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22084 "TARGET_SSE2"
22085 "subpd\t{%2, %0|%0, %2}"
22086 [(set_attr "type" "sseadd")
22087 (set_attr "mode" "V2DF")])
22088
22089 (define_insn "vmsubv2df3"
22090 [(set (match_operand:V2DF 0 "register_operand" "=x")
22091 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22092 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22093 (match_dup 1)
22094 (const_int 1)))]
22095 "TARGET_SSE2"
22096 "subsd\t{%2, %0|%0, %2}"
22097 [(set_attr "type" "sseadd")
22098 (set_attr "mode" "DF")])
22099
22100 (define_insn "mulv2df3"
22101 [(set (match_operand:V2DF 0 "register_operand" "=x")
22102 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22103 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22104 "TARGET_SSE2"
22105 "mulpd\t{%2, %0|%0, %2}"
22106 [(set_attr "type" "ssemul")
22107 (set_attr "mode" "V2DF")])
22108
22109 (define_insn "vmmulv2df3"
22110 [(set (match_operand:V2DF 0 "register_operand" "=x")
22111 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22112 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22113 (match_dup 1)
22114 (const_int 1)))]
22115 "TARGET_SSE2"
22116 "mulsd\t{%2, %0|%0, %2}"
22117 [(set_attr "type" "ssemul")
22118 (set_attr "mode" "DF")])
22119
22120 (define_insn "divv2df3"
22121 [(set (match_operand:V2DF 0 "register_operand" "=x")
22122 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22123 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22124 "TARGET_SSE2"
22125 "divpd\t{%2, %0|%0, %2}"
22126 [(set_attr "type" "ssediv")
22127 (set_attr "mode" "V2DF")])
22128
22129 (define_insn "vmdivv2df3"
22130 [(set (match_operand:V2DF 0 "register_operand" "=x")
22131 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22132 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22133 (match_dup 1)
22134 (const_int 1)))]
22135 "TARGET_SSE2"
22136 "divsd\t{%2, %0|%0, %2}"
22137 [(set_attr "type" "ssediv")
22138 (set_attr "mode" "DF")])
22139
22140 ;; SSE min/max
22141
22142 (define_insn "smaxv2df3"
22143 [(set (match_operand:V2DF 0 "register_operand" "=x")
22144 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22145 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22146 "TARGET_SSE2"
22147 "maxpd\t{%2, %0|%0, %2}"
22148 [(set_attr "type" "sseadd")
22149 (set_attr "mode" "V2DF")])
22150
22151 (define_insn "vmsmaxv2df3"
22152 [(set (match_operand:V2DF 0 "register_operand" "=x")
22153 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22154 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22155 (match_dup 1)
22156 (const_int 1)))]
22157 "TARGET_SSE2"
22158 "maxsd\t{%2, %0|%0, %2}"
22159 [(set_attr "type" "sseadd")
22160 (set_attr "mode" "DF")])
22161
22162 (define_insn "sminv2df3"
22163 [(set (match_operand:V2DF 0 "register_operand" "=x")
22164 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22165 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22166 "TARGET_SSE2"
22167 "minpd\t{%2, %0|%0, %2}"
22168 [(set_attr "type" "sseadd")
22169 (set_attr "mode" "V2DF")])
22170
22171 (define_insn "vmsminv2df3"
22172 [(set (match_operand:V2DF 0 "register_operand" "=x")
22173 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22174 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22175 (match_dup 1)
22176 (const_int 1)))]
22177 "TARGET_SSE2"
22178 "minsd\t{%2, %0|%0, %2}"
22179 [(set_attr "type" "sseadd")
22180 (set_attr "mode" "DF")])
22181 ;; SSE2 square root. There doesn't appear to be an extension for the
22182 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22183
22184 (define_insn "sqrtv2df2"
22185 [(set (match_operand:V2DF 0 "register_operand" "=x")
22186 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22187 "TARGET_SSE2"
22188 "sqrtpd\t{%1, %0|%0, %1}"
22189 [(set_attr "type" "sse")
22190 (set_attr "mode" "V2DF")])
22191
22192 (define_insn "vmsqrtv2df2"
22193 [(set (match_operand:V2DF 0 "register_operand" "=x")
22194 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22195 (match_operand:V2DF 2 "register_operand" "0")
22196 (const_int 1)))]
22197 "TARGET_SSE2"
22198 "sqrtsd\t{%1, %0|%0, %1}"
22199 [(set_attr "type" "sse")
22200 (set_attr "mode" "SF")])
22201
22202 ;; SSE mask-generating compares
22203
22204 (define_insn "maskcmpv2df3"
22205 [(set (match_operand:V2DI 0 "register_operand" "=x")
22206 (match_operator:V2DI 3 "sse_comparison_operator"
22207 [(match_operand:V2DF 1 "register_operand" "0")
22208 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22209 "TARGET_SSE2"
22210 "cmp%D3pd\t{%2, %0|%0, %2}"
22211 [(set_attr "type" "ssecmp")
22212 (set_attr "mode" "V2DF")])
22213
22214 (define_insn "maskncmpv2df3"
22215 [(set (match_operand:V2DI 0 "register_operand" "=x")
22216 (not:V2DI
22217 (match_operator:V2DI 3 "sse_comparison_operator"
22218 [(match_operand:V2DF 1 "register_operand" "0")
22219 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22220 "TARGET_SSE2"
22221 {
22222 if (GET_CODE (operands[3]) == UNORDERED)
22223 return "cmpordps\t{%2, %0|%0, %2}";
22224 else
22225 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22226 }
22227 [(set_attr "type" "ssecmp")
22228 (set_attr "mode" "V2DF")])
22229
22230 (define_insn "vmmaskcmpv2df3"
22231 [(set (match_operand:V2DI 0 "register_operand" "=x")
22232 (vec_merge:V2DI
22233 (match_operator:V2DI 3 "sse_comparison_operator"
22234 [(match_operand:V2DF 1 "register_operand" "0")
22235 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22236 (subreg:V2DI (match_dup 1) 0)
22237 (const_int 1)))]
22238 "TARGET_SSE2"
22239 "cmp%D3sd\t{%2, %0|%0, %2}"
22240 [(set_attr "type" "ssecmp")
22241 (set_attr "mode" "DF")])
22242
22243 (define_insn "vmmaskncmpv2df3"
22244 [(set (match_operand:V2DI 0 "register_operand" "=x")
22245 (vec_merge:V2DI
22246 (not:V2DI
22247 (match_operator:V2DI 3 "sse_comparison_operator"
22248 [(match_operand:V2DF 1 "register_operand" "0")
22249 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22250 (subreg:V2DI (match_dup 1) 0)
22251 (const_int 1)))]
22252 "TARGET_SSE2"
22253 {
22254 if (GET_CODE (operands[3]) == UNORDERED)
22255 return "cmpordsd\t{%2, %0|%0, %2}";
22256 else
22257 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22258 }
22259 [(set_attr "type" "ssecmp")
22260 (set_attr "mode" "DF")])
22261
22262 (define_insn "sse2_comi"
22263 [(set (reg:CCFP 17)
22264 (compare:CCFP (vec_select:DF
22265 (match_operand:V2DF 0 "register_operand" "x")
22266 (parallel [(const_int 0)]))
22267 (vec_select:DF
22268 (match_operand:V2DF 1 "register_operand" "x")
22269 (parallel [(const_int 0)]))))]
22270 "TARGET_SSE2"
22271 "comisd\t{%1, %0|%0, %1}"
22272 [(set_attr "type" "ssecomi")
22273 (set_attr "mode" "DF")])
22274
22275 (define_insn "sse2_ucomi"
22276 [(set (reg:CCFPU 17)
22277 (compare:CCFPU (vec_select:DF
22278 (match_operand:V2DF 0 "register_operand" "x")
22279 (parallel [(const_int 0)]))
22280 (vec_select:DF
22281 (match_operand:V2DF 1 "register_operand" "x")
22282 (parallel [(const_int 0)]))))]
22283 "TARGET_SSE2"
22284 "ucomisd\t{%1, %0|%0, %1}"
22285 [(set_attr "type" "ssecomi")
22286 (set_attr "mode" "DF")])
22287
22288 ;; SSE Strange Moves.
22289
22290 (define_insn "sse2_movmskpd"
22291 [(set (match_operand:SI 0 "register_operand" "=r")
22292 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22293 UNSPEC_MOVMSK))]
22294 "TARGET_SSE2"
22295 "movmskpd\t{%1, %0|%0, %1}"
22296 [(set_attr "type" "ssecvt")
22297 (set_attr "mode" "V2DF")])
22298
22299 (define_insn "sse2_pmovmskb"
22300 [(set (match_operand:SI 0 "register_operand" "=r")
22301 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22302 UNSPEC_MOVMSK))]
22303 "TARGET_SSE2"
22304 "pmovmskb\t{%1, %0|%0, %1}"
22305 [(set_attr "type" "ssecvt")
22306 (set_attr "mode" "V2DF")])
22307
22308 (define_insn "sse2_maskmovdqu"
22309 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22310 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22311 (match_operand:V16QI 2 "register_operand" "x")]
22312 UNSPEC_MASKMOV))]
22313 "TARGET_SSE2"
22314 ;; @@@ check ordering of operands in intel/nonintel syntax
22315 "maskmovdqu\t{%2, %1|%1, %2}"
22316 [(set_attr "type" "ssecvt")
22317 (set_attr "mode" "TI")])
22318
22319 (define_insn "sse2_maskmovdqu_rex64"
22320 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22321 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22322 (match_operand:V16QI 2 "register_operand" "x")]
22323 UNSPEC_MASKMOV))]
22324 "TARGET_SSE2"
22325 ;; @@@ check ordering of operands in intel/nonintel syntax
22326 "maskmovdqu\t{%2, %1|%1, %2}"
22327 [(set_attr "type" "ssecvt")
22328 (set_attr "mode" "TI")])
22329
22330 (define_insn "sse2_movntv2df"
22331 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22332 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22333 UNSPEC_MOVNT))]
22334 "TARGET_SSE2"
22335 "movntpd\t{%1, %0|%0, %1}"
22336 [(set_attr "type" "ssecvt")
22337 (set_attr "mode" "V2DF")])
22338
22339 (define_insn "sse2_movntv2di"
22340 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22341 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22342 UNSPEC_MOVNT))]
22343 "TARGET_SSE2"
22344 "movntdq\t{%1, %0|%0, %1}"
22345 [(set_attr "type" "ssecvt")
22346 (set_attr "mode" "TI")])
22347
22348 (define_insn "sse2_movntsi"
22349 [(set (match_operand:SI 0 "memory_operand" "=m")
22350 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22351 UNSPEC_MOVNT))]
22352 "TARGET_SSE2"
22353 "movnti\t{%1, %0|%0, %1}"
22354 [(set_attr "type" "ssecvt")
22355 (set_attr "mode" "V2DF")])
22356
22357 ;; SSE <-> integer/MMX conversions
22358
22359 ;; Conversions between SI and SF
22360
22361 (define_insn "cvtdq2ps"
22362 [(set (match_operand:V4SF 0 "register_operand" "=x")
22363 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22364 "TARGET_SSE2"
22365 "cvtdq2ps\t{%1, %0|%0, %1}"
22366 [(set_attr "type" "ssecvt")
22367 (set_attr "mode" "V2DF")])
22368
22369 (define_insn "cvtps2dq"
22370 [(set (match_operand:V4SI 0 "register_operand" "=x")
22371 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22372 "TARGET_SSE2"
22373 "cvtps2dq\t{%1, %0|%0, %1}"
22374 [(set_attr "type" "ssecvt")
22375 (set_attr "mode" "TI")])
22376
22377 (define_insn "cvttps2dq"
22378 [(set (match_operand:V4SI 0 "register_operand" "=x")
22379 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22380 UNSPEC_FIX))]
22381 "TARGET_SSE2"
22382 "cvttps2dq\t{%1, %0|%0, %1}"
22383 [(set_attr "type" "ssecvt")
22384 (set_attr "mode" "TI")])
22385
22386 ;; Conversions between SI and DF
22387
22388 (define_insn "cvtdq2pd"
22389 [(set (match_operand:V2DF 0 "register_operand" "=x")
22390 (float:V2DF (vec_select:V2SI
22391 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22392 (parallel
22393 [(const_int 0)
22394 (const_int 1)]))))]
22395 "TARGET_SSE2"
22396 "cvtdq2pd\t{%1, %0|%0, %1}"
22397 [(set_attr "type" "ssecvt")
22398 (set_attr "mode" "V2DF")])
22399
22400 (define_insn "cvtpd2dq"
22401 [(set (match_operand:V4SI 0 "register_operand" "=x")
22402 (vec_concat:V4SI
22403 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22404 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22405 "TARGET_SSE2"
22406 "cvtpd2dq\t{%1, %0|%0, %1}"
22407 [(set_attr "type" "ssecvt")
22408 (set_attr "mode" "TI")])
22409
22410 (define_insn "cvttpd2dq"
22411 [(set (match_operand:V4SI 0 "register_operand" "=x")
22412 (vec_concat:V4SI
22413 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22414 UNSPEC_FIX)
22415 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22416 "TARGET_SSE2"
22417 "cvttpd2dq\t{%1, %0|%0, %1}"
22418 [(set_attr "type" "ssecvt")
22419 (set_attr "mode" "TI")])
22420
22421 (define_insn "cvtpd2pi"
22422 [(set (match_operand:V2SI 0 "register_operand" "=y")
22423 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22424 "TARGET_SSE2"
22425 "cvtpd2pi\t{%1, %0|%0, %1}"
22426 [(set_attr "type" "ssecvt")
22427 (set_attr "mode" "TI")])
22428
22429 (define_insn "cvttpd2pi"
22430 [(set (match_operand:V2SI 0 "register_operand" "=y")
22431 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22432 UNSPEC_FIX))]
22433 "TARGET_SSE2"
22434 "cvttpd2pi\t{%1, %0|%0, %1}"
22435 [(set_attr "type" "ssecvt")
22436 (set_attr "mode" "TI")])
22437
22438 (define_insn "cvtpi2pd"
22439 [(set (match_operand:V2DF 0 "register_operand" "=x")
22440 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22441 "TARGET_SSE2"
22442 "cvtpi2pd\t{%1, %0|%0, %1}"
22443 [(set_attr "type" "ssecvt")
22444 (set_attr "mode" "TI")])
22445
22446 ;; Conversions between SI and DF
22447
22448 (define_insn "cvtsd2si"
22449 [(set (match_operand:SI 0 "register_operand" "=r,r")
22450 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22451 (parallel [(const_int 0)]))))]
22452 "TARGET_SSE2"
22453 "cvtsd2si\t{%1, %0|%0, %1}"
22454 [(set_attr "type" "sseicvt")
22455 (set_attr "athlon_decode" "double,vector")
22456 (set_attr "mode" "SI")])
22457
22458 (define_insn "cvtsd2siq"
22459 [(set (match_operand:DI 0 "register_operand" "=r,r")
22460 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22461 (parallel [(const_int 0)]))))]
22462 "TARGET_SSE2 && TARGET_64BIT"
22463 "cvtsd2siq\t{%1, %0|%0, %1}"
22464 [(set_attr "type" "sseicvt")
22465 (set_attr "athlon_decode" "double,vector")
22466 (set_attr "mode" "DI")])
22467
22468 (define_insn "cvttsd2si"
22469 [(set (match_operand:SI 0 "register_operand" "=r,r")
22470 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22471 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22472 "TARGET_SSE2"
22473 "cvttsd2si\t{%1, %0|%0, %1}"
22474 [(set_attr "type" "sseicvt")
22475 (set_attr "mode" "SI")
22476 (set_attr "athlon_decode" "double,vector")])
22477
22478 (define_insn "cvttsd2siq"
22479 [(set (match_operand:DI 0 "register_operand" "=r,r")
22480 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22481 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22482 "TARGET_SSE2 && TARGET_64BIT"
22483 "cvttsd2siq\t{%1, %0|%0, %1}"
22484 [(set_attr "type" "sseicvt")
22485 (set_attr "mode" "DI")
22486 (set_attr "athlon_decode" "double,vector")])
22487
22488 (define_insn "cvtsi2sd"
22489 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22490 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22491 (vec_duplicate:V2DF
22492 (float:DF
22493 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22494 (const_int 2)))]
22495 "TARGET_SSE2"
22496 "cvtsi2sd\t{%2, %0|%0, %2}"
22497 [(set_attr "type" "sseicvt")
22498 (set_attr "mode" "DF")
22499 (set_attr "athlon_decode" "double,direct")])
22500
22501 (define_insn "cvtsi2sdq"
22502 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22503 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22504 (vec_duplicate:V2DF
22505 (float:DF
22506 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22507 (const_int 2)))]
22508 "TARGET_SSE2 && TARGET_64BIT"
22509 "cvtsi2sdq\t{%2, %0|%0, %2}"
22510 [(set_attr "type" "sseicvt")
22511 (set_attr "mode" "DF")
22512 (set_attr "athlon_decode" "double,direct")])
22513
22514 ;; Conversions between SF and DF
22515
22516 (define_insn "cvtsd2ss"
22517 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22518 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22519 (vec_duplicate:V4SF
22520 (float_truncate:V2SF
22521 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22522 (const_int 14)))]
22523 "TARGET_SSE2"
22524 "cvtsd2ss\t{%2, %0|%0, %2}"
22525 [(set_attr "type" "ssecvt")
22526 (set_attr "athlon_decode" "vector,double")
22527 (set_attr "mode" "SF")])
22528
22529 (define_insn "cvtss2sd"
22530 [(set (match_operand:V2DF 0 "register_operand" "=x")
22531 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22532 (float_extend:V2DF
22533 (vec_select:V2SF
22534 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22535 (parallel [(const_int 0)
22536 (const_int 1)])))
22537 (const_int 2)))]
22538 "TARGET_SSE2"
22539 "cvtss2sd\t{%2, %0|%0, %2}"
22540 [(set_attr "type" "ssecvt")
22541 (set_attr "mode" "DF")])
22542
22543 (define_insn "cvtpd2ps"
22544 [(set (match_operand:V4SF 0 "register_operand" "=x")
22545 (subreg:V4SF
22546 (vec_concat:V4SI
22547 (subreg:V2SI (float_truncate:V2SF
22548 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22549 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22550 "TARGET_SSE2"
22551 "cvtpd2ps\t{%1, %0|%0, %1}"
22552 [(set_attr "type" "ssecvt")
22553 (set_attr "mode" "V4SF")])
22554
22555 (define_insn "cvtps2pd"
22556 [(set (match_operand:V2DF 0 "register_operand" "=x")
22557 (float_extend:V2DF
22558 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22559 (parallel [(const_int 0)
22560 (const_int 1)]))))]
22561 "TARGET_SSE2"
22562 "cvtps2pd\t{%1, %0|%0, %1}"
22563 [(set_attr "type" "ssecvt")
22564 (set_attr "mode" "V2DF")])
22565
22566 ;; SSE2 variants of MMX insns
22567
22568 ;; MMX arithmetic
22569
22570 (define_insn "addv16qi3"
22571 [(set (match_operand:V16QI 0 "register_operand" "=x")
22572 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22573 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22574 "TARGET_SSE2"
22575 "paddb\t{%2, %0|%0, %2}"
22576 [(set_attr "type" "sseiadd")
22577 (set_attr "mode" "TI")])
22578
22579 (define_insn "addv8hi3"
22580 [(set (match_operand:V8HI 0 "register_operand" "=x")
22581 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22582 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22583 "TARGET_SSE2"
22584 "paddw\t{%2, %0|%0, %2}"
22585 [(set_attr "type" "sseiadd")
22586 (set_attr "mode" "TI")])
22587
22588 (define_insn "addv4si3"
22589 [(set (match_operand:V4SI 0 "register_operand" "=x")
22590 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22591 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22592 "TARGET_SSE2"
22593 "paddd\t{%2, %0|%0, %2}"
22594 [(set_attr "type" "sseiadd")
22595 (set_attr "mode" "TI")])
22596
22597 (define_insn "addv2di3"
22598 [(set (match_operand:V2DI 0 "register_operand" "=x")
22599 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22600 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22601 "TARGET_SSE2"
22602 "paddq\t{%2, %0|%0, %2}"
22603 [(set_attr "type" "sseiadd")
22604 (set_attr "mode" "TI")])
22605
22606 (define_insn "ssaddv16qi3"
22607 [(set (match_operand:V16QI 0 "register_operand" "=x")
22608 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22609 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22610 "TARGET_SSE2"
22611 "paddsb\t{%2, %0|%0, %2}"
22612 [(set_attr "type" "sseiadd")
22613 (set_attr "mode" "TI")])
22614
22615 (define_insn "ssaddv8hi3"
22616 [(set (match_operand:V8HI 0 "register_operand" "=x")
22617 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22618 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22619 "TARGET_SSE2"
22620 "paddsw\t{%2, %0|%0, %2}"
22621 [(set_attr "type" "sseiadd")
22622 (set_attr "mode" "TI")])
22623
22624 (define_insn "usaddv16qi3"
22625 [(set (match_operand:V16QI 0 "register_operand" "=x")
22626 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22627 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22628 "TARGET_SSE2"
22629 "paddusb\t{%2, %0|%0, %2}"
22630 [(set_attr "type" "sseiadd")
22631 (set_attr "mode" "TI")])
22632
22633 (define_insn "usaddv8hi3"
22634 [(set (match_operand:V8HI 0 "register_operand" "=x")
22635 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22636 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22637 "TARGET_SSE2"
22638 "paddusw\t{%2, %0|%0, %2}"
22639 [(set_attr "type" "sseiadd")
22640 (set_attr "mode" "TI")])
22641
22642 (define_insn "subv16qi3"
22643 [(set (match_operand:V16QI 0 "register_operand" "=x")
22644 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22645 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22646 "TARGET_SSE2"
22647 "psubb\t{%2, %0|%0, %2}"
22648 [(set_attr "type" "sseiadd")
22649 (set_attr "mode" "TI")])
22650
22651 (define_insn "subv8hi3"
22652 [(set (match_operand:V8HI 0 "register_operand" "=x")
22653 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22654 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22655 "TARGET_SSE2"
22656 "psubw\t{%2, %0|%0, %2}"
22657 [(set_attr "type" "sseiadd")
22658 (set_attr "mode" "TI")])
22659
22660 (define_insn "subv4si3"
22661 [(set (match_operand:V4SI 0 "register_operand" "=x")
22662 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22663 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22664 "TARGET_SSE2"
22665 "psubd\t{%2, %0|%0, %2}"
22666 [(set_attr "type" "sseiadd")
22667 (set_attr "mode" "TI")])
22668
22669 (define_insn "subv2di3"
22670 [(set (match_operand:V2DI 0 "register_operand" "=x")
22671 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22672 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22673 "TARGET_SSE2"
22674 "psubq\t{%2, %0|%0, %2}"
22675 [(set_attr "type" "sseiadd")
22676 (set_attr "mode" "TI")])
22677
22678 (define_insn "sssubv16qi3"
22679 [(set (match_operand:V16QI 0 "register_operand" "=x")
22680 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22681 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22682 "TARGET_SSE2"
22683 "psubsb\t{%2, %0|%0, %2}"
22684 [(set_attr "type" "sseiadd")
22685 (set_attr "mode" "TI")])
22686
22687 (define_insn "sssubv8hi3"
22688 [(set (match_operand:V8HI 0 "register_operand" "=x")
22689 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22690 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22691 "TARGET_SSE2"
22692 "psubsw\t{%2, %0|%0, %2}"
22693 [(set_attr "type" "sseiadd")
22694 (set_attr "mode" "TI")])
22695
22696 (define_insn "ussubv16qi3"
22697 [(set (match_operand:V16QI 0 "register_operand" "=x")
22698 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22699 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22700 "TARGET_SSE2"
22701 "psubusb\t{%2, %0|%0, %2}"
22702 [(set_attr "type" "sseiadd")
22703 (set_attr "mode" "TI")])
22704
22705 (define_insn "ussubv8hi3"
22706 [(set (match_operand:V8HI 0 "register_operand" "=x")
22707 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22708 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22709 "TARGET_SSE2"
22710 "psubusw\t{%2, %0|%0, %2}"
22711 [(set_attr "type" "sseiadd")
22712 (set_attr "mode" "TI")])
22713
22714 (define_insn "mulv8hi3"
22715 [(set (match_operand:V8HI 0 "register_operand" "=x")
22716 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22717 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22718 "TARGET_SSE2"
22719 "pmullw\t{%2, %0|%0, %2}"
22720 [(set_attr "type" "sseimul")
22721 (set_attr "mode" "TI")])
22722
22723 (define_insn "smulv8hi3_highpart"
22724 [(set (match_operand:V8HI 0 "register_operand" "=x")
22725 (truncate:V8HI
22726 (lshiftrt:V8SI
22727 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22728 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22729 (const_int 16))))]
22730 "TARGET_SSE2"
22731 "pmulhw\t{%2, %0|%0, %2}"
22732 [(set_attr "type" "sseimul")
22733 (set_attr "mode" "TI")])
22734
22735 (define_insn "umulv8hi3_highpart"
22736 [(set (match_operand:V8HI 0 "register_operand" "=x")
22737 (truncate:V8HI
22738 (lshiftrt:V8SI
22739 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22740 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22741 (const_int 16))))]
22742 "TARGET_SSE2"
22743 "pmulhuw\t{%2, %0|%0, %2}"
22744 [(set_attr "type" "sseimul")
22745 (set_attr "mode" "TI")])
22746
22747 (define_insn "sse2_umulsidi3"
22748 [(set (match_operand:DI 0 "register_operand" "=y")
22749 (mult:DI (zero_extend:DI (vec_select:SI
22750 (match_operand:V2SI 1 "register_operand" "0")
22751 (parallel [(const_int 0)])))
22752 (zero_extend:DI (vec_select:SI
22753 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22754 (parallel [(const_int 0)])))))]
22755 "TARGET_SSE2"
22756 "pmuludq\t{%2, %0|%0, %2}"
22757 [(set_attr "type" "sseimul")
22758 (set_attr "mode" "TI")])
22759
22760 (define_insn "sse2_umulv2siv2di3"
22761 [(set (match_operand:V2DI 0 "register_operand" "=x")
22762 (mult:V2DI (zero_extend:V2DI
22763 (vec_select:V2SI
22764 (match_operand:V4SI 1 "register_operand" "0")
22765 (parallel [(const_int 0) (const_int 2)])))
22766 (zero_extend:V2DI
22767 (vec_select:V2SI
22768 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22769 (parallel [(const_int 0) (const_int 2)])))))]
22770 "TARGET_SSE2"
22771 "pmuludq\t{%2, %0|%0, %2}"
22772 [(set_attr "type" "sseimul")
22773 (set_attr "mode" "TI")])
22774
22775 (define_insn "sse2_pmaddwd"
22776 [(set (match_operand:V4SI 0 "register_operand" "=x")
22777 (plus:V4SI
22778 (mult:V4SI
22779 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22780 (parallel [(const_int 0)
22781 (const_int 2)
22782 (const_int 4)
22783 (const_int 6)])))
22784 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22785 (parallel [(const_int 0)
22786 (const_int 2)
22787 (const_int 4)
22788 (const_int 6)]))))
22789 (mult:V4SI
22790 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22791 (parallel [(const_int 1)
22792 (const_int 3)
22793 (const_int 5)
22794 (const_int 7)])))
22795 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22796 (parallel [(const_int 1)
22797 (const_int 3)
22798 (const_int 5)
22799 (const_int 7)]))))))]
22800 "TARGET_SSE2"
22801 "pmaddwd\t{%2, %0|%0, %2}"
22802 [(set_attr "type" "sseiadd")
22803 (set_attr "mode" "TI")])
22804
22805 ;; Same as pxor, but don't show input operands so that we don't think
22806 ;; they are live.
22807 (define_insn "sse2_clrti"
22808 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22809 "TARGET_SSE2"
22810 {
22811 if (get_attr_mode (insn) == MODE_TI)
22812 return "pxor\t%0, %0";
22813 else
22814 return "xorps\t%0, %0";
22815 }
22816 [(set_attr "type" "ssemov")
22817 (set_attr "memory" "none")
22818 (set (attr "mode")
22819 (if_then_else
22820 (ne (symbol_ref "optimize_size")
22821 (const_int 0))
22822 (const_string "V4SF")
22823 (const_string "TI")))])
22824
22825 ;; MMX unsigned averages/sum of absolute differences
22826
22827 (define_insn "sse2_uavgv16qi3"
22828 [(set (match_operand:V16QI 0 "register_operand" "=x")
22829 (ashiftrt:V16QI
22830 (plus:V16QI (plus:V16QI
22831 (match_operand:V16QI 1 "register_operand" "0")
22832 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22833 (const_vector:V16QI [(const_int 1) (const_int 1)
22834 (const_int 1) (const_int 1)
22835 (const_int 1) (const_int 1)
22836 (const_int 1) (const_int 1)
22837 (const_int 1) (const_int 1)
22838 (const_int 1) (const_int 1)
22839 (const_int 1) (const_int 1)
22840 (const_int 1) (const_int 1)]))
22841 (const_int 1)))]
22842 "TARGET_SSE2"
22843 "pavgb\t{%2, %0|%0, %2}"
22844 [(set_attr "type" "sseiadd")
22845 (set_attr "mode" "TI")])
22846
22847 (define_insn "sse2_uavgv8hi3"
22848 [(set (match_operand:V8HI 0 "register_operand" "=x")
22849 (ashiftrt:V8HI
22850 (plus:V8HI (plus:V8HI
22851 (match_operand:V8HI 1 "register_operand" "0")
22852 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22853 (const_vector:V8HI [(const_int 1) (const_int 1)
22854 (const_int 1) (const_int 1)
22855 (const_int 1) (const_int 1)
22856 (const_int 1) (const_int 1)]))
22857 (const_int 1)))]
22858 "TARGET_SSE2"
22859 "pavgw\t{%2, %0|%0, %2}"
22860 [(set_attr "type" "sseiadd")
22861 (set_attr "mode" "TI")])
22862
22863 ;; @@@ this isn't the right representation.
22864 (define_insn "sse2_psadbw"
22865 [(set (match_operand:V2DI 0 "register_operand" "=x")
22866 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22867 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22868 UNSPEC_PSADBW))]
22869 "TARGET_SSE2"
22870 "psadbw\t{%2, %0|%0, %2}"
22871 [(set_attr "type" "sseiadd")
22872 (set_attr "mode" "TI")])
22873
22874
22875 ;; MMX insert/extract/shuffle
22876
22877 (define_insn "sse2_pinsrw"
22878 [(set (match_operand:V8HI 0 "register_operand" "=x")
22879 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22880 (vec_duplicate:V8HI
22881 (truncate:HI
22882 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22883 (match_operand:SI 3 "immediate_operand" "i")))]
22884 "TARGET_SSE2"
22885 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22886 [(set_attr "type" "ssecvt")
22887 (set_attr "mode" "TI")])
22888
22889 (define_insn "sse2_pextrw"
22890 [(set (match_operand:SI 0 "register_operand" "=r")
22891 (zero_extend:SI
22892 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22893 (parallel
22894 [(match_operand:SI 2 "immediate_operand" "i")]))))]
22895 "TARGET_SSE2"
22896 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22897 [(set_attr "type" "ssecvt")
22898 (set_attr "mode" "TI")])
22899
22900 (define_insn "sse2_pshufd"
22901 [(set (match_operand:V4SI 0 "register_operand" "=x")
22902 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22903 (match_operand:SI 2 "immediate_operand" "i")]
22904 UNSPEC_SHUFFLE))]
22905 "TARGET_SSE2"
22906 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22907 [(set_attr "type" "ssecvt")
22908 (set_attr "mode" "TI")])
22909
22910 (define_insn "sse2_pshuflw"
22911 [(set (match_operand:V8HI 0 "register_operand" "=x")
22912 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22913 (match_operand:SI 2 "immediate_operand" "i")]
22914 UNSPEC_PSHUFLW))]
22915 "TARGET_SSE2"
22916 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22917 [(set_attr "type" "ssecvt")
22918 (set_attr "mode" "TI")])
22919
22920 (define_insn "sse2_pshufhw"
22921 [(set (match_operand:V8HI 0 "register_operand" "=x")
22922 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22923 (match_operand:SI 2 "immediate_operand" "i")]
22924 UNSPEC_PSHUFHW))]
22925 "TARGET_SSE2"
22926 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22927 [(set_attr "type" "ssecvt")
22928 (set_attr "mode" "TI")])
22929
22930 ;; MMX mask-generating comparisons
22931
22932 (define_insn "eqv16qi3"
22933 [(set (match_operand:V16QI 0 "register_operand" "=x")
22934 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22935 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22936 "TARGET_SSE2"
22937 "pcmpeqb\t{%2, %0|%0, %2}"
22938 [(set_attr "type" "ssecmp")
22939 (set_attr "mode" "TI")])
22940
22941 (define_insn "eqv8hi3"
22942 [(set (match_operand:V8HI 0 "register_operand" "=x")
22943 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22944 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22945 "TARGET_SSE2"
22946 "pcmpeqw\t{%2, %0|%0, %2}"
22947 [(set_attr "type" "ssecmp")
22948 (set_attr "mode" "TI")])
22949
22950 (define_insn "eqv4si3"
22951 [(set (match_operand:V4SI 0 "register_operand" "=x")
22952 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22953 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22954 "TARGET_SSE2"
22955 "pcmpeqd\t{%2, %0|%0, %2}"
22956 [(set_attr "type" "ssecmp")
22957 (set_attr "mode" "TI")])
22958
22959 (define_insn "gtv16qi3"
22960 [(set (match_operand:V16QI 0 "register_operand" "=x")
22961 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22962 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22963 "TARGET_SSE2"
22964 "pcmpgtb\t{%2, %0|%0, %2}"
22965 [(set_attr "type" "ssecmp")
22966 (set_attr "mode" "TI")])
22967
22968 (define_insn "gtv8hi3"
22969 [(set (match_operand:V8HI 0 "register_operand" "=x")
22970 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22971 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22972 "TARGET_SSE2"
22973 "pcmpgtw\t{%2, %0|%0, %2}"
22974 [(set_attr "type" "ssecmp")
22975 (set_attr "mode" "TI")])
22976
22977 (define_insn "gtv4si3"
22978 [(set (match_operand:V4SI 0 "register_operand" "=x")
22979 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22980 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22981 "TARGET_SSE2"
22982 "pcmpgtd\t{%2, %0|%0, %2}"
22983 [(set_attr "type" "ssecmp")
22984 (set_attr "mode" "TI")])
22985
22986
22987 ;; MMX max/min insns
22988
22989 (define_insn "umaxv16qi3"
22990 [(set (match_operand:V16QI 0 "register_operand" "=x")
22991 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22992 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22993 "TARGET_SSE2"
22994 "pmaxub\t{%2, %0|%0, %2}"
22995 [(set_attr "type" "sseiadd")
22996 (set_attr "mode" "TI")])
22997
22998 (define_insn "smaxv8hi3"
22999 [(set (match_operand:V8HI 0 "register_operand" "=x")
23000 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23001 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23002 "TARGET_SSE2"
23003 "pmaxsw\t{%2, %0|%0, %2}"
23004 [(set_attr "type" "sseiadd")
23005 (set_attr "mode" "TI")])
23006
23007 (define_insn "uminv16qi3"
23008 [(set (match_operand:V16QI 0 "register_operand" "=x")
23009 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23010 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23011 "TARGET_SSE2"
23012 "pminub\t{%2, %0|%0, %2}"
23013 [(set_attr "type" "sseiadd")
23014 (set_attr "mode" "TI")])
23015
23016 (define_insn "sminv8hi3"
23017 [(set (match_operand:V8HI 0 "register_operand" "=x")
23018 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23019 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23020 "TARGET_SSE2"
23021 "pminsw\t{%2, %0|%0, %2}"
23022 [(set_attr "type" "sseiadd")
23023 (set_attr "mode" "TI")])
23024
23025
23026 ;; MMX shifts
23027
23028 (define_insn "ashrv8hi3"
23029 [(set (match_operand:V8HI 0 "register_operand" "=x")
23030 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23031 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23032 "TARGET_SSE2"
23033 "psraw\t{%2, %0|%0, %2}"
23034 [(set_attr "type" "sseishft")
23035 (set_attr "mode" "TI")])
23036
23037 (define_insn "ashrv4si3"
23038 [(set (match_operand:V4SI 0 "register_operand" "=x")
23039 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23040 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23041 "TARGET_SSE2"
23042 "psrad\t{%2, %0|%0, %2}"
23043 [(set_attr "type" "sseishft")
23044 (set_attr "mode" "TI")])
23045
23046 (define_insn "lshrv8hi3"
23047 [(set (match_operand:V8HI 0 "register_operand" "=x")
23048 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23049 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23050 "TARGET_SSE2"
23051 "psrlw\t{%2, %0|%0, %2}"
23052 [(set_attr "type" "sseishft")
23053 (set_attr "mode" "TI")])
23054
23055 (define_insn "lshrv4si3"
23056 [(set (match_operand:V4SI 0 "register_operand" "=x")
23057 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23058 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23059 "TARGET_SSE2"
23060 "psrld\t{%2, %0|%0, %2}"
23061 [(set_attr "type" "sseishft")
23062 (set_attr "mode" "TI")])
23063
23064 (define_insn "lshrv2di3"
23065 [(set (match_operand:V2DI 0 "register_operand" "=x")
23066 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23067 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23068 "TARGET_SSE2"
23069 "psrlq\t{%2, %0|%0, %2}"
23070 [(set_attr "type" "sseishft")
23071 (set_attr "mode" "TI")])
23072
23073 (define_insn "ashlv8hi3"
23074 [(set (match_operand:V8HI 0 "register_operand" "=x")
23075 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23076 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23077 "TARGET_SSE2"
23078 "psllw\t{%2, %0|%0, %2}"
23079 [(set_attr "type" "sseishft")
23080 (set_attr "mode" "TI")])
23081
23082 (define_insn "ashlv4si3"
23083 [(set (match_operand:V4SI 0 "register_operand" "=x")
23084 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23085 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23086 "TARGET_SSE2"
23087 "pslld\t{%2, %0|%0, %2}"
23088 [(set_attr "type" "sseishft")
23089 (set_attr "mode" "TI")])
23090
23091 (define_insn "ashlv2di3"
23092 [(set (match_operand:V2DI 0 "register_operand" "=x")
23093 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23094 (match_operand:TI 2 "nonmemory_operand" "xi")))]
23095 "TARGET_SSE2"
23096 "psllq\t{%2, %0|%0, %2}"
23097 [(set_attr "type" "sseishft")
23098 (set_attr "mode" "TI")])
23099
23100 (define_insn "ashrv8hi3_ti"
23101 [(set (match_operand:V8HI 0 "register_operand" "=x")
23102 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23103 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23104 "TARGET_SSE2"
23105 "psraw\t{%2, %0|%0, %2}"
23106 [(set_attr "type" "sseishft")
23107 (set_attr "mode" "TI")])
23108
23109 (define_insn "ashrv4si3_ti"
23110 [(set (match_operand:V4SI 0 "register_operand" "=x")
23111 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23112 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23113 "TARGET_SSE2"
23114 "psrad\t{%2, %0|%0, %2}"
23115 [(set_attr "type" "sseishft")
23116 (set_attr "mode" "TI")])
23117
23118 (define_insn "lshrv8hi3_ti"
23119 [(set (match_operand:V8HI 0 "register_operand" "=x")
23120 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23121 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23122 "TARGET_SSE2"
23123 "psrlw\t{%2, %0|%0, %2}"
23124 [(set_attr "type" "sseishft")
23125 (set_attr "mode" "TI")])
23126
23127 (define_insn "lshrv4si3_ti"
23128 [(set (match_operand:V4SI 0 "register_operand" "=x")
23129 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23130 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23131 "TARGET_SSE2"
23132 "psrld\t{%2, %0|%0, %2}"
23133 [(set_attr "type" "sseishft")
23134 (set_attr "mode" "TI")])
23135
23136 (define_insn "lshrv2di3_ti"
23137 [(set (match_operand:V2DI 0 "register_operand" "=x")
23138 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23139 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23140 "TARGET_SSE2"
23141 "psrlq\t{%2, %0|%0, %2}"
23142 [(set_attr "type" "sseishft")
23143 (set_attr "mode" "TI")])
23144
23145 (define_insn "ashlv8hi3_ti"
23146 [(set (match_operand:V8HI 0 "register_operand" "=x")
23147 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23148 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23149 "TARGET_SSE2"
23150 "psllw\t{%2, %0|%0, %2}"
23151 [(set_attr "type" "sseishft")
23152 (set_attr "mode" "TI")])
23153
23154 (define_insn "ashlv4si3_ti"
23155 [(set (match_operand:V4SI 0 "register_operand" "=x")
23156 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23157 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23158 "TARGET_SSE2"
23159 "pslld\t{%2, %0|%0, %2}"
23160 [(set_attr "type" "sseishft")
23161 (set_attr "mode" "TI")])
23162
23163 (define_insn "ashlv2di3_ti"
23164 [(set (match_operand:V2DI 0 "register_operand" "=x")
23165 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23166 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23167 "TARGET_SSE2"
23168 "psllq\t{%2, %0|%0, %2}"
23169 [(set_attr "type" "sseishft")
23170 (set_attr "mode" "TI")])
23171
23172 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23173 ;; we wouldn't need here it since we never generate TImode arithmetic.
23174
23175 ;; There has to be some kind of prize for the weirdest new instruction...
23176 (define_insn "sse2_ashlti3"
23177 [(set (match_operand:TI 0 "register_operand" "=x")
23178 (unspec:TI
23179 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23180 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23181 (const_int 8)))] UNSPEC_NOP))]
23182 "TARGET_SSE2"
23183 "pslldq\t{%2, %0|%0, %2}"
23184 [(set_attr "type" "sseishft")
23185 (set_attr "mode" "TI")])
23186
23187 (define_insn "sse2_lshrti3"
23188 [(set (match_operand:TI 0 "register_operand" "=x")
23189 (unspec:TI
23190 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23191 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23192 (const_int 8)))] UNSPEC_NOP))]
23193 "TARGET_SSE2"
23194 "psrldq\t{%2, %0|%0, %2}"
23195 [(set_attr "type" "sseishft")
23196 (set_attr "mode" "TI")])
23197
23198 ;; SSE unpack
23199
23200 (define_insn "sse2_unpckhpd"
23201 [(set (match_operand:V2DF 0 "register_operand" "=x")
23202 (vec_concat:V2DF
23203 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23204 (parallel [(const_int 1)]))
23205 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23206 (parallel [(const_int 0)]))))]
23207 "TARGET_SSE2"
23208 "unpckhpd\t{%2, %0|%0, %2}"
23209 [(set_attr "type" "ssecvt")
23210 (set_attr "mode" "TI")])
23211
23212 (define_insn "sse2_unpcklpd"
23213 [(set (match_operand:V2DF 0 "register_operand" "=x")
23214 (vec_concat:V2DF
23215 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23216 (parallel [(const_int 0)]))
23217 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23218 (parallel [(const_int 1)]))))]
23219 "TARGET_SSE2"
23220 "unpcklpd\t{%2, %0|%0, %2}"
23221 [(set_attr "type" "ssecvt")
23222 (set_attr "mode" "TI")])
23223
23224 ;; MMX pack/unpack insns.
23225
23226 (define_insn "sse2_packsswb"
23227 [(set (match_operand:V16QI 0 "register_operand" "=x")
23228 (vec_concat:V16QI
23229 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23230 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23231 "TARGET_SSE2"
23232 "packsswb\t{%2, %0|%0, %2}"
23233 [(set_attr "type" "ssecvt")
23234 (set_attr "mode" "TI")])
23235
23236 (define_insn "sse2_packssdw"
23237 [(set (match_operand:V8HI 0 "register_operand" "=x")
23238 (vec_concat:V8HI
23239 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23240 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23241 "TARGET_SSE2"
23242 "packssdw\t{%2, %0|%0, %2}"
23243 [(set_attr "type" "ssecvt")
23244 (set_attr "mode" "TI")])
23245
23246 (define_insn "sse2_packuswb"
23247 [(set (match_operand:V16QI 0 "register_operand" "=x")
23248 (vec_concat:V16QI
23249 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23250 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23251 "TARGET_SSE2"
23252 "packuswb\t{%2, %0|%0, %2}"
23253 [(set_attr "type" "ssecvt")
23254 (set_attr "mode" "TI")])
23255
23256 (define_insn "sse2_punpckhbw"
23257 [(set (match_operand:V16QI 0 "register_operand" "=x")
23258 (vec_merge:V16QI
23259 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23260 (parallel [(const_int 8) (const_int 0)
23261 (const_int 9) (const_int 1)
23262 (const_int 10) (const_int 2)
23263 (const_int 11) (const_int 3)
23264 (const_int 12) (const_int 4)
23265 (const_int 13) (const_int 5)
23266 (const_int 14) (const_int 6)
23267 (const_int 15) (const_int 7)]))
23268 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23269 (parallel [(const_int 0) (const_int 8)
23270 (const_int 1) (const_int 9)
23271 (const_int 2) (const_int 10)
23272 (const_int 3) (const_int 11)
23273 (const_int 4) (const_int 12)
23274 (const_int 5) (const_int 13)
23275 (const_int 6) (const_int 14)
23276 (const_int 7) (const_int 15)]))
23277 (const_int 21845)))]
23278 "TARGET_SSE2"
23279 "punpckhbw\t{%2, %0|%0, %2}"
23280 [(set_attr "type" "ssecvt")
23281 (set_attr "mode" "TI")])
23282
23283 (define_insn "sse2_punpckhwd"
23284 [(set (match_operand:V8HI 0 "register_operand" "=x")
23285 (vec_merge:V8HI
23286 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23287 (parallel [(const_int 4) (const_int 0)
23288 (const_int 5) (const_int 1)
23289 (const_int 6) (const_int 2)
23290 (const_int 7) (const_int 3)]))
23291 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23292 (parallel [(const_int 0) (const_int 4)
23293 (const_int 1) (const_int 5)
23294 (const_int 2) (const_int 6)
23295 (const_int 3) (const_int 7)]))
23296 (const_int 85)))]
23297 "TARGET_SSE2"
23298 "punpckhwd\t{%2, %0|%0, %2}"
23299 [(set_attr "type" "ssecvt")
23300 (set_attr "mode" "TI")])
23301
23302 (define_insn "sse2_punpckhdq"
23303 [(set (match_operand:V4SI 0 "register_operand" "=x")
23304 (vec_merge:V4SI
23305 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23306 (parallel [(const_int 2) (const_int 0)
23307 (const_int 3) (const_int 1)]))
23308 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23309 (parallel [(const_int 0) (const_int 2)
23310 (const_int 1) (const_int 3)]))
23311 (const_int 5)))]
23312 "TARGET_SSE2"
23313 "punpckhdq\t{%2, %0|%0, %2}"
23314 [(set_attr "type" "ssecvt")
23315 (set_attr "mode" "TI")])
23316
23317 (define_insn "sse2_punpcklbw"
23318 [(set (match_operand:V16QI 0 "register_operand" "=x")
23319 (vec_merge:V16QI
23320 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23321 (parallel [(const_int 0) (const_int 8)
23322 (const_int 1) (const_int 9)
23323 (const_int 2) (const_int 10)
23324 (const_int 3) (const_int 11)
23325 (const_int 4) (const_int 12)
23326 (const_int 5) (const_int 13)
23327 (const_int 6) (const_int 14)
23328 (const_int 7) (const_int 15)]))
23329 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23330 (parallel [(const_int 8) (const_int 0)
23331 (const_int 9) (const_int 1)
23332 (const_int 10) (const_int 2)
23333 (const_int 11) (const_int 3)
23334 (const_int 12) (const_int 4)
23335 (const_int 13) (const_int 5)
23336 (const_int 14) (const_int 6)
23337 (const_int 15) (const_int 7)]))
23338 (const_int 21845)))]
23339 "TARGET_SSE2"
23340 "punpcklbw\t{%2, %0|%0, %2}"
23341 [(set_attr "type" "ssecvt")
23342 (set_attr "mode" "TI")])
23343
23344 (define_insn "sse2_punpcklwd"
23345 [(set (match_operand:V8HI 0 "register_operand" "=x")
23346 (vec_merge:V8HI
23347 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23348 (parallel [(const_int 0) (const_int 4)
23349 (const_int 1) (const_int 5)
23350 (const_int 2) (const_int 6)
23351 (const_int 3) (const_int 7)]))
23352 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23353 (parallel [(const_int 4) (const_int 0)
23354 (const_int 5) (const_int 1)
23355 (const_int 6) (const_int 2)
23356 (const_int 7) (const_int 3)]))
23357 (const_int 85)))]
23358 "TARGET_SSE2"
23359 "punpcklwd\t{%2, %0|%0, %2}"
23360 [(set_attr "type" "ssecvt")
23361 (set_attr "mode" "TI")])
23362
23363 (define_insn "sse2_punpckldq"
23364 [(set (match_operand:V4SI 0 "register_operand" "=x")
23365 (vec_merge:V4SI
23366 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23367 (parallel [(const_int 0) (const_int 2)
23368 (const_int 1) (const_int 3)]))
23369 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23370 (parallel [(const_int 2) (const_int 0)
23371 (const_int 3) (const_int 1)]))
23372 (const_int 5)))]
23373 "TARGET_SSE2"
23374 "punpckldq\t{%2, %0|%0, %2}"
23375 [(set_attr "type" "ssecvt")
23376 (set_attr "mode" "TI")])
23377
23378 (define_insn "sse2_punpcklqdq"
23379 [(set (match_operand:V2DI 0 "register_operand" "=x")
23380 (vec_merge:V2DI
23381 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23382 (parallel [(const_int 1)
23383 (const_int 0)]))
23384 (match_operand:V2DI 1 "register_operand" "0")
23385 (const_int 1)))]
23386 "TARGET_SSE2"
23387 "punpcklqdq\t{%2, %0|%0, %2}"
23388 [(set_attr "type" "ssecvt")
23389 (set_attr "mode" "TI")])
23390
23391 (define_insn "sse2_punpckhqdq"
23392 [(set (match_operand:V2DI 0 "register_operand" "=x")
23393 (vec_merge:V2DI
23394 (match_operand:V2DI 1 "register_operand" "0")
23395 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23396 (parallel [(const_int 1)
23397 (const_int 0)]))
23398 (const_int 1)))]
23399 "TARGET_SSE2"
23400 "punpckhqdq\t{%2, %0|%0, %2}"
23401 [(set_attr "type" "ssecvt")
23402 (set_attr "mode" "TI")])
23403
23404 ;; SSE2 moves
23405
23406 (define_insn "sse2_movapd"
23407 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23408 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23409 UNSPEC_MOVA))]
23410 "TARGET_SSE2
23411 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23412 "movapd\t{%1, %0|%0, %1}"
23413 [(set_attr "type" "ssemov")
23414 (set_attr "mode" "V2DF")])
23415
23416 (define_insn "sse2_movupd"
23417 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23418 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23419 UNSPEC_MOVU))]
23420 "TARGET_SSE2
23421 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23422 "movupd\t{%1, %0|%0, %1}"
23423 [(set_attr "type" "ssecvt")
23424 (set_attr "mode" "V2DF")])
23425
23426 (define_insn "sse2_movdqa"
23427 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23428 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23429 UNSPEC_MOVA))]
23430 "TARGET_SSE2
23431 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23432 "movdqa\t{%1, %0|%0, %1}"
23433 [(set_attr "type" "ssemov")
23434 (set_attr "mode" "TI")])
23435
23436 (define_insn "sse2_movdqu"
23437 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23438 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23439 UNSPEC_MOVU))]
23440 "TARGET_SSE2
23441 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23442 "movdqu\t{%1, %0|%0, %1}"
23443 [(set_attr "type" "ssecvt")
23444 (set_attr "mode" "TI")])
23445
23446 (define_insn "sse2_movdq2q"
23447 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23448 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23449 (parallel [(const_int 0)])))]
23450 "TARGET_SSE2 && !TARGET_64BIT"
23451 "@
23452 movq\t{%1, %0|%0, %1}
23453 movdq2q\t{%1, %0|%0, %1}"
23454 [(set_attr "type" "ssecvt")
23455 (set_attr "mode" "TI")])
23456
23457 (define_insn "sse2_movdq2q_rex64"
23458 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23459 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23460 (parallel [(const_int 0)])))]
23461 "TARGET_SSE2 && TARGET_64BIT"
23462 "@
23463 movq\t{%1, %0|%0, %1}
23464 movdq2q\t{%1, %0|%0, %1}
23465 movd\t{%1, %0|%0, %1}"
23466 [(set_attr "type" "ssecvt")
23467 (set_attr "mode" "TI")])
23468
23469 (define_insn "sse2_movq2dq"
23470 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23471 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23472 (const_int 0)))]
23473 "TARGET_SSE2 && !TARGET_64BIT"
23474 "@
23475 movq\t{%1, %0|%0, %1}
23476 movq2dq\t{%1, %0|%0, %1}"
23477 [(set_attr "type" "ssecvt,ssemov")
23478 (set_attr "mode" "TI")])
23479
23480 (define_insn "sse2_movq2dq_rex64"
23481 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23482 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23483 (const_int 0)))]
23484 "TARGET_SSE2 && TARGET_64BIT"
23485 "@
23486 movq\t{%1, %0|%0, %1}
23487 movq2dq\t{%1, %0|%0, %1}
23488 movd\t{%1, %0|%0, %1}"
23489 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23490 (set_attr "mode" "TI")])
23491
23492 (define_insn "sse2_movq"
23493 [(set (match_operand:V2DI 0 "register_operand" "=x")
23494 (vec_concat:V2DI (vec_select:DI
23495 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23496 (parallel [(const_int 0)]))
23497 (const_int 0)))]
23498 "TARGET_SSE2"
23499 "movq\t{%1, %0|%0, %1}"
23500 [(set_attr "type" "ssemov")
23501 (set_attr "mode" "TI")])
23502
23503 (define_insn "sse2_loadd"
23504 [(set (match_operand:V4SI 0 "register_operand" "=x")
23505 (vec_merge:V4SI
23506 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23507 (const_vector:V4SI [(const_int 0)
23508 (const_int 0)
23509 (const_int 0)
23510 (const_int 0)])
23511 (const_int 1)))]
23512 "TARGET_SSE2"
23513 "movd\t{%1, %0|%0, %1}"
23514 [(set_attr "type" "ssemov")
23515 (set_attr "mode" "TI")])
23516
23517 (define_insn "sse2_stored"
23518 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23519 (vec_select:SI
23520 (match_operand:V4SI 1 "register_operand" "x")
23521 (parallel [(const_int 0)])))]
23522 "TARGET_SSE2"
23523 "movd\t{%1, %0|%0, %1}"
23524 [(set_attr "type" "ssemov")
23525 (set_attr "mode" "TI")])
23526
23527 (define_insn "sse2_movhpd"
23528 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23529 (vec_merge:V2DF
23530 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23531 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23532 (const_int 2)))]
23533 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23534 "movhpd\t{%2, %0|%0, %2}"
23535 [(set_attr "type" "ssecvt")
23536 (set_attr "mode" "V2DF")])
23537
23538 (define_insn "sse2_movlpd"
23539 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23540 (vec_merge:V2DF
23541 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23542 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23543 (const_int 1)))]
23544 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23545 "movlpd\t{%2, %0|%0, %2}"
23546 [(set_attr "type" "ssecvt")
23547 (set_attr "mode" "V2DF")])
23548
23549 (define_expand "sse2_loadsd"
23550 [(match_operand:V2DF 0 "register_operand" "")
23551 (match_operand:DF 1 "memory_operand" "")]
23552 "TARGET_SSE2"
23553 {
23554 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23555 CONST0_RTX (V2DFmode)));
23556 DONE;
23557 })
23558
23559 (define_insn "sse2_loadsd_1"
23560 [(set (match_operand:V2DF 0 "register_operand" "=x")
23561 (vec_merge:V2DF
23562 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23563 (match_operand:V2DF 2 "const0_operand" "X")
23564 (const_int 1)))]
23565 "TARGET_SSE2"
23566 "movsd\t{%1, %0|%0, %1}"
23567 [(set_attr "type" "ssecvt")
23568 (set_attr "mode" "DF")])
23569
23570 (define_insn "sse2_movsd"
23571 [(set (match_operand:V2DF 0 "register_operand" "=x")
23572 (vec_merge:V2DF
23573 (match_operand:V2DF 1 "register_operand" "0")
23574 (match_operand:V2DF 2 "register_operand" "x")
23575 (const_int 1)))]
23576 "TARGET_SSE2"
23577 "movsd\t{%2, %0|%0, %2}"
23578 [(set_attr "type" "ssecvt")
23579 (set_attr "mode" "DF")])
23580
23581 (define_insn "sse2_storesd"
23582 [(set (match_operand:DF 0 "memory_operand" "=m")
23583 (vec_select:DF
23584 (match_operand:V2DF 1 "register_operand" "x")
23585 (parallel [(const_int 0)])))]
23586 "TARGET_SSE2"
23587 "movsd\t{%1, %0|%0, %1}"
23588 [(set_attr "type" "ssecvt")
23589 (set_attr "mode" "DF")])
23590
23591 (define_insn "sse2_shufpd"
23592 [(set (match_operand:V2DF 0 "register_operand" "=x")
23593 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23594 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23595 (match_operand:SI 3 "immediate_operand" "i")]
23596 UNSPEC_SHUFFLE))]
23597 "TARGET_SSE2"
23598 ;; @@@ check operand order for intel/nonintel syntax
23599 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23600 [(set_attr "type" "ssecvt")
23601 (set_attr "mode" "V2DF")])
23602
23603 (define_insn "sse2_clflush"
23604 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23605 UNSPECV_CLFLUSH)]
23606 "TARGET_SSE2"
23607 "clflush %0"
23608 [(set_attr "type" "sse")
23609 (set_attr "memory" "unknown")])
23610
23611 (define_expand "sse2_mfence"
23612 [(set (match_dup 0)
23613 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23614 "TARGET_SSE2"
23615 {
23616 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23617 MEM_VOLATILE_P (operands[0]) = 1;
23618 })
23619
23620 (define_insn "*mfence_insn"
23621 [(set (match_operand:BLK 0 "" "")
23622 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23623 "TARGET_SSE2"
23624 "mfence"
23625 [(set_attr "type" "sse")
23626 (set_attr "memory" "unknown")])
23627
23628 (define_expand "sse2_lfence"
23629 [(set (match_dup 0)
23630 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23631 "TARGET_SSE2"
23632 {
23633 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23634 MEM_VOLATILE_P (operands[0]) = 1;
23635 })
23636
23637 (define_insn "*lfence_insn"
23638 [(set (match_operand:BLK 0 "" "")
23639 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23640 "TARGET_SSE2"
23641 "lfence"
23642 [(set_attr "type" "sse")
23643 (set_attr "memory" "unknown")])
23644
23645 ;; PNI
23646
23647 (define_insn "mwait"
23648 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23649 (match_operand:SI 1 "register_operand" "c")]
23650 UNSPECV_MWAIT)]
23651 "TARGET_PNI"
23652 "mwait\t%0, %1"
23653 [(set_attr "length" "3")])
23654
23655 (define_insn "monitor"
23656 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23657 (match_operand:SI 1 "register_operand" "c")
23658 (match_operand:SI 2 "register_operand" "d")]
23659 UNSPECV_MONITOR)]
23660 "TARGET_PNI"
23661 "monitor\t%0, %1, %2"
23662 [(set_attr "length" "3")])
23663
23664 ;; PNI arithmetic
23665
23666 (define_insn "addsubv4sf3"
23667 [(set (match_operand:V4SF 0 "register_operand" "=x")
23668 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23669 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23670 UNSPEC_ADDSUB))]
23671 "TARGET_PNI"
23672 "addsubps\t{%2, %0|%0, %2}"
23673 [(set_attr "type" "sseadd")
23674 (set_attr "mode" "V4SF")])
23675
23676 (define_insn "addsubv2df3"
23677 [(set (match_operand:V2DF 0 "register_operand" "=x")
23678 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23679 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23680 UNSPEC_ADDSUB))]
23681 "TARGET_PNI"
23682 "addsubpd\t{%2, %0|%0, %2}"
23683 [(set_attr "type" "sseadd")
23684 (set_attr "mode" "V2DF")])
23685
23686 (define_insn "haddv4sf3"
23687 [(set (match_operand:V4SF 0 "register_operand" "=x")
23688 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23689 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23690 UNSPEC_HADD))]
23691 "TARGET_PNI"
23692 "haddps\t{%2, %0|%0, %2}"
23693 [(set_attr "type" "sseadd")
23694 (set_attr "mode" "V4SF")])
23695
23696 (define_insn "haddv2df3"
23697 [(set (match_operand:V2DF 0 "register_operand" "=x")
23698 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23699 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23700 UNSPEC_HADD))]
23701 "TARGET_PNI"
23702 "haddpd\t{%2, %0|%0, %2}"
23703 [(set_attr "type" "sseadd")
23704 (set_attr "mode" "V2DF")])
23705
23706 (define_insn "hsubv4sf3"
23707 [(set (match_operand:V4SF 0 "register_operand" "=x")
23708 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23709 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23710 UNSPEC_HSUB))]
23711 "TARGET_PNI"
23712 "hsubps\t{%2, %0|%0, %2}"
23713 [(set_attr "type" "sseadd")
23714 (set_attr "mode" "V4SF")])
23715
23716 (define_insn "hsubv2df3"
23717 [(set (match_operand:V2DF 0 "register_operand" "=x")
23718 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23719 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23720 UNSPEC_HSUB))]
23721 "TARGET_PNI"
23722 "hsubpd\t{%2, %0|%0, %2}"
23723 [(set_attr "type" "sseadd")
23724 (set_attr "mode" "V2DF")])
23725
23726 (define_insn "movshdup"
23727 [(set (match_operand:V4SF 0 "register_operand" "=x")
23728 (unspec:V4SF
23729 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23730 "TARGET_PNI"
23731 "movshdup\t{%1, %0|%0, %1}"
23732 [(set_attr "type" "sse")
23733 (set_attr "mode" "V4SF")])
23734
23735 (define_insn "movsldup"
23736 [(set (match_operand:V4SF 0 "register_operand" "=x")
23737 (unspec:V4SF
23738 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23739 "TARGET_PNI"
23740 "movsldup\t{%1, %0|%0, %1}"
23741 [(set_attr "type" "sse")
23742 (set_attr "mode" "V4SF")])
23743
23744 (define_insn "lddqu"
23745 [(set (match_operand:V16QI 0 "register_operand" "=x")
23746 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23747 UNSPEC_LDQQU))]
23748 "TARGET_PNI"
23749 "lddqu\t{%1, %0|%0, %1}"
23750 [(set_attr "type" "ssecvt")
23751 (set_attr "mode" "TI")])
23752
23753 (define_insn "loadddup"
23754 [(set (match_operand:V2DF 0 "register_operand" "=x")
23755 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23756 "TARGET_PNI"
23757 "movddup\t{%1, %0|%0, %1}"
23758 [(set_attr "type" "ssecvt")
23759 (set_attr "mode" "DF")])
23760
23761 (define_insn "movddup"
23762 [(set (match_operand:V2DF 0 "register_operand" "=x")
23763 (vec_duplicate:V2DF
23764 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23765 (parallel [(const_int 0)]))))]
23766 "TARGET_PNI"
23767 "movddup\t{%1, %0|%0, %1}"
23768 [(set_attr "type" "ssecvt")
23769 (set_attr "mode" "DF")])