optabs.h (enum optab_index): Add new OTI_expm1.
[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, 2004
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 GCC.
9 ;;
10 ;; GCC 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 ;; GCC 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 GCC; 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 REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_PROBE 10)
67 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SET_GOT 12)
69 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70
71 ; TLS support
72 (UNSPEC_TP 15)
73 (UNSPEC_TLS_GD 16)
74 (UNSPEC_TLS_LD_BASE 17)
75
76 ; Other random patterns
77 (UNSPEC_SCAS 20)
78 (UNSPEC_SIN 21)
79 (UNSPEC_COS 22)
80 (UNSPEC_FNSTSW 24)
81 (UNSPEC_SAHF 25)
82 (UNSPEC_FSTCW 26)
83 (UNSPEC_ADD_CARRY 27)
84 (UNSPEC_FLDCW 28)
85
86 ; For SSE/MMX support:
87 (UNSPEC_FIX 30)
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
119 (UNSPEC_FYL2X 66)
120 (UNSPEC_FRNDINT 68)
121 (UNSPEC_F2XM1 69)
122
123 ; x87 Double output FP
124 (UNSPEC_SINCOS_COS 80)
125 (UNSPEC_SINCOS_SIN 81)
126 (UNSPEC_TAN_ONE 82)
127 (UNSPEC_TAN_TAN 83)
128 (UNSPEC_XTRACT_FRACT 84)
129 (UNSPEC_XTRACT_EXP 85)
130 (UNSPEC_FSCALE_FRACT 86)
131 (UNSPEC_FSCALE_EXP 87)
132
133 ; REP instruction
134 (UNSPEC_REP 75)
135 ])
136
137 (define_constants
138 [(UNSPECV_BLOCKAGE 0)
139 (UNSPECV_EH_RETURN 13)
140 (UNSPECV_EMMS 31)
141 (UNSPECV_LDMXCSR 37)
142 (UNSPECV_STMXCSR 40)
143 (UNSPECV_FEMMS 46)
144 (UNSPECV_CLFLUSH 57)
145 (UNSPECV_ALIGN 68)
146 (UNSPECV_MONITOR 69)
147 (UNSPECV_MWAIT 70)
148 ])
149
150 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
151 ;; from i386.c.
152
153 ;; In C guard expressions, put expressions which may be compile-time
154 ;; constants first. This allows for better optimization. For
155 ;; example, write "TARGET_64BIT && reload_completed", not
156 ;; "reload_completed && TARGET_64BIT".
157
158 \f
159 ;; Processor type. This attribute must exactly match the processor_type
160 ;; enumeration in i386.h.
161 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
162 (const (symbol_ref "ix86_tune")))
163
164 ;; A basic instruction type. Refinements due to arguments to be
165 ;; provided in other attributes.
166 (define_attr "type"
167 "other,multi,
168 alu,alu1,negnot,imov,imovx,lea,
169 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
170 icmp,test,ibr,setcc,icmov,
171 push,pop,call,callv,leave,
172 str,cld,
173 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
174 sselog,sseiadd,sseishft,sseimul,
175 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
176 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
177 (const_string "other"))
178
179 ;; Main data type used by the insn
180 (define_attr "mode"
181 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
182 (const_string "unknown"))
183
184 ;; The CPU unit operations uses.
185 (define_attr "unit" "integer,i387,sse,mmx,unknown"
186 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
187 (const_string "i387")
188 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
189 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
190 (const_string "sse")
191 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
192 (const_string "mmx")
193 (eq_attr "type" "other")
194 (const_string "unknown")]
195 (const_string "integer")))
196
197 ;; The (bounding maximum) length of an instruction immediate.
198 (define_attr "length_immediate" ""
199 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
200 (const_int 0)
201 (eq_attr "unit" "i387,sse,mmx")
202 (const_int 0)
203 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
204 imul,icmp,push,pop")
205 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
206 (eq_attr "type" "imov,test")
207 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
208 (eq_attr "type" "call")
209 (if_then_else (match_operand 0 "constant_call_address_operand" "")
210 (const_int 4)
211 (const_int 0))
212 (eq_attr "type" "callv")
213 (if_then_else (match_operand 1 "constant_call_address_operand" "")
214 (const_int 4)
215 (const_int 0))
216 ;; We don't know the size before shorten_branches. Expect
217 ;; the instruction to fit for better scheduling.
218 (eq_attr "type" "ibr")
219 (const_int 1)
220 ]
221 (symbol_ref "/* Update immediate_length and other attributes! */
222 abort(),1")))
223
224 ;; The (bounding maximum) length of an instruction address.
225 (define_attr "length_address" ""
226 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
227 (const_int 0)
228 (and (eq_attr "type" "call")
229 (match_operand 0 "constant_call_address_operand" ""))
230 (const_int 0)
231 (and (eq_attr "type" "callv")
232 (match_operand 1 "constant_call_address_operand" ""))
233 (const_int 0)
234 ]
235 (symbol_ref "ix86_attr_length_address_default (insn)")))
236
237 ;; Set when length prefix is used.
238 (define_attr "prefix_data16" ""
239 (if_then_else (ior (eq_attr "mode" "HI")
240 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
241 (const_int 1)
242 (const_int 0)))
243
244 ;; Set when string REP prefix is used.
245 (define_attr "prefix_rep" ""
246 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
247 (const_int 1)
248 (const_int 0)))
249
250 ;; Set when 0f opcode prefix is used.
251 (define_attr "prefix_0f" ""
252 (if_then_else
253 (ior (eq_attr "type" "imovx,setcc,icmov")
254 (eq_attr "unit" "sse,mmx"))
255 (const_int 1)
256 (const_int 0)))
257
258 ;; Set when REX opcode prefix is used.
259 (define_attr "prefix_rex" ""
260 (cond [(and (eq_attr "mode" "DI")
261 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
262 (const_int 1)
263 (and (eq_attr "mode" "QI")
264 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
265 (const_int 0)))
266 (const_int 1)
267 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
268 (const_int 0))
269 (const_int 1)
270 ]
271 (const_int 0)))
272
273 ;; Set when modrm byte is used.
274 (define_attr "modrm" ""
275 (cond [(eq_attr "type" "str,cld,leave")
276 (const_int 0)
277 (eq_attr "unit" "i387")
278 (const_int 0)
279 (and (eq_attr "type" "incdec")
280 (ior (match_operand:SI 1 "register_operand" "")
281 (match_operand:HI 1 "register_operand" "")))
282 (const_int 0)
283 (and (eq_attr "type" "push")
284 (not (match_operand 1 "memory_operand" "")))
285 (const_int 0)
286 (and (eq_attr "type" "pop")
287 (not (match_operand 0 "memory_operand" "")))
288 (const_int 0)
289 (and (eq_attr "type" "imov")
290 (and (match_operand 0 "register_operand" "")
291 (match_operand 1 "immediate_operand" "")))
292 (const_int 0)
293 (and (eq_attr "type" "call")
294 (match_operand 0 "constant_call_address_operand" ""))
295 (const_int 0)
296 (and (eq_attr "type" "callv")
297 (match_operand 1 "constant_call_address_operand" ""))
298 (const_int 0)
299 ]
300 (const_int 1)))
301
302 ;; The (bounding maximum) length of an instruction in bytes.
303 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
304 ;; to split it and compute proper length as for other insns.
305 (define_attr "length" ""
306 (cond [(eq_attr "type" "other,multi,fistp")
307 (const_int 16)
308 (eq_attr "type" "fcmp")
309 (const_int 4)
310 (eq_attr "unit" "i387")
311 (plus (const_int 2)
312 (plus (attr "prefix_data16")
313 (attr "length_address")))]
314 (plus (plus (attr "modrm")
315 (plus (attr "prefix_0f")
316 (plus (attr "prefix_rex")
317 (const_int 1))))
318 (plus (attr "prefix_rep")
319 (plus (attr "prefix_data16")
320 (plus (attr "length_immediate")
321 (attr "length_address")))))))
322
323 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
324 ;; `store' if there is a simple memory reference therein, or `unknown'
325 ;; if the instruction is complex.
326
327 (define_attr "memory" "none,load,store,both,unknown"
328 (cond [(eq_attr "type" "other,multi,str")
329 (const_string "unknown")
330 (eq_attr "type" "lea,fcmov,fpspc,cld")
331 (const_string "none")
332 (eq_attr "type" "fistp,leave")
333 (const_string "both")
334 (eq_attr "type" "push")
335 (if_then_else (match_operand 1 "memory_operand" "")
336 (const_string "both")
337 (const_string "store"))
338 (eq_attr "type" "pop")
339 (if_then_else (match_operand 0 "memory_operand" "")
340 (const_string "both")
341 (const_string "load"))
342 (eq_attr "type" "setcc")
343 (if_then_else (match_operand 0 "memory_operand" "")
344 (const_string "store")
345 (const_string "none"))
346 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
347 (if_then_else (ior (match_operand 0 "memory_operand" "")
348 (match_operand 1 "memory_operand" ""))
349 (const_string "load")
350 (const_string "none"))
351 (eq_attr "type" "ibr")
352 (if_then_else (match_operand 0 "memory_operand" "")
353 (const_string "load")
354 (const_string "none"))
355 (eq_attr "type" "call")
356 (if_then_else (match_operand 0 "constant_call_address_operand" "")
357 (const_string "none")
358 (const_string "load"))
359 (eq_attr "type" "callv")
360 (if_then_else (match_operand 1 "constant_call_address_operand" "")
361 (const_string "none")
362 (const_string "load"))
363 (and (eq_attr "type" "alu1,negnot,ishift1")
364 (match_operand 1 "memory_operand" ""))
365 (const_string "both")
366 (and (match_operand 0 "memory_operand" "")
367 (match_operand 1 "memory_operand" ""))
368 (const_string "both")
369 (match_operand 0 "memory_operand" "")
370 (const_string "store")
371 (match_operand 1 "memory_operand" "")
372 (const_string "load")
373 (and (eq_attr "type"
374 "!alu1,negnot,ishift1,
375 imov,imovx,icmp,test,
376 fmov,fcmp,fsgn,
377 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
378 mmx,mmxmov,mmxcmp,mmxcvt")
379 (match_operand 2 "memory_operand" ""))
380 (const_string "load")
381 (and (eq_attr "type" "icmov")
382 (match_operand 3 "memory_operand" ""))
383 (const_string "load")
384 ]
385 (const_string "none")))
386
387 ;; Indicates if an instruction has both an immediate and a displacement.
388
389 (define_attr "imm_disp" "false,true,unknown"
390 (cond [(eq_attr "type" "other,multi")
391 (const_string "unknown")
392 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
393 (and (match_operand 0 "memory_displacement_operand" "")
394 (match_operand 1 "immediate_operand" "")))
395 (const_string "true")
396 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
397 (and (match_operand 0 "memory_displacement_operand" "")
398 (match_operand 2 "immediate_operand" "")))
399 (const_string "true")
400 ]
401 (const_string "false")))
402
403 ;; Indicates if an FP operation has an integer source.
404
405 (define_attr "fp_int_src" "false,true"
406 (const_string "false"))
407
408 ;; Describe a user's asm statement.
409 (define_asm_attributes
410 [(set_attr "length" "128")
411 (set_attr "type" "multi")])
412 \f
413 (include "pentium.md")
414 (include "ppro.md")
415 (include "k6.md")
416 (include "athlon.md")
417 \f
418 ;; Compare instructions.
419
420 ;; All compare insns have expanders that save the operands away without
421 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
422 ;; after the cmp) will actually emit the cmpM.
423
424 (define_expand "cmpdi"
425 [(set (reg:CC 17)
426 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
427 (match_operand:DI 1 "x86_64_general_operand" "")))]
428 ""
429 {
430 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
431 operands[0] = force_reg (DImode, operands[0]);
432 ix86_compare_op0 = operands[0];
433 ix86_compare_op1 = operands[1];
434 DONE;
435 })
436
437 (define_expand "cmpsi"
438 [(set (reg:CC 17)
439 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
440 (match_operand:SI 1 "general_operand" "")))]
441 ""
442 {
443 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
444 operands[0] = force_reg (SImode, operands[0]);
445 ix86_compare_op0 = operands[0];
446 ix86_compare_op1 = operands[1];
447 DONE;
448 })
449
450 (define_expand "cmphi"
451 [(set (reg:CC 17)
452 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
453 (match_operand:HI 1 "general_operand" "")))]
454 ""
455 {
456 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
457 operands[0] = force_reg (HImode, operands[0]);
458 ix86_compare_op0 = operands[0];
459 ix86_compare_op1 = operands[1];
460 DONE;
461 })
462
463 (define_expand "cmpqi"
464 [(set (reg:CC 17)
465 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
466 (match_operand:QI 1 "general_operand" "")))]
467 "TARGET_QIMODE_MATH"
468 {
469 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
470 operands[0] = force_reg (QImode, operands[0]);
471 ix86_compare_op0 = operands[0];
472 ix86_compare_op1 = operands[1];
473 DONE;
474 })
475
476 (define_insn "cmpdi_ccno_1_rex64"
477 [(set (reg 17)
478 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
479 (match_operand:DI 1 "const0_operand" "n,n")))]
480 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
481 "@
482 test{q}\t{%0, %0|%0, %0}
483 cmp{q}\t{%1, %0|%0, %1}"
484 [(set_attr "type" "test,icmp")
485 (set_attr "length_immediate" "0,1")
486 (set_attr "mode" "DI")])
487
488 (define_insn "*cmpdi_minus_1_rex64"
489 [(set (reg 17)
490 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
491 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
492 (const_int 0)))]
493 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
494 "cmp{q}\t{%1, %0|%0, %1}"
495 [(set_attr "type" "icmp")
496 (set_attr "mode" "DI")])
497
498 (define_expand "cmpdi_1_rex64"
499 [(set (reg:CC 17)
500 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
501 (match_operand:DI 1 "general_operand" "")))]
502 "TARGET_64BIT"
503 "")
504
505 (define_insn "cmpdi_1_insn_rex64"
506 [(set (reg 17)
507 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
508 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
509 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
510 "cmp{q}\t{%1, %0|%0, %1}"
511 [(set_attr "type" "icmp")
512 (set_attr "mode" "DI")])
513
514
515 (define_insn "*cmpsi_ccno_1"
516 [(set (reg 17)
517 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
518 (match_operand:SI 1 "const0_operand" "n,n")))]
519 "ix86_match_ccmode (insn, CCNOmode)"
520 "@
521 test{l}\t{%0, %0|%0, %0}
522 cmp{l}\t{%1, %0|%0, %1}"
523 [(set_attr "type" "test,icmp")
524 (set_attr "length_immediate" "0,1")
525 (set_attr "mode" "SI")])
526
527 (define_insn "*cmpsi_minus_1"
528 [(set (reg 17)
529 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
530 (match_operand:SI 1 "general_operand" "ri,mr"))
531 (const_int 0)))]
532 "ix86_match_ccmode (insn, CCGOCmode)"
533 "cmp{l}\t{%1, %0|%0, %1}"
534 [(set_attr "type" "icmp")
535 (set_attr "mode" "SI")])
536
537 (define_expand "cmpsi_1"
538 [(set (reg:CC 17)
539 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
540 (match_operand:SI 1 "general_operand" "ri,mr")))]
541 ""
542 "")
543
544 (define_insn "*cmpsi_1_insn"
545 [(set (reg 17)
546 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
547 (match_operand:SI 1 "general_operand" "ri,mr")))]
548 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
549 && ix86_match_ccmode (insn, CCmode)"
550 "cmp{l}\t{%1, %0|%0, %1}"
551 [(set_attr "type" "icmp")
552 (set_attr "mode" "SI")])
553
554 (define_insn "*cmphi_ccno_1"
555 [(set (reg 17)
556 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
557 (match_operand:HI 1 "const0_operand" "n,n")))]
558 "ix86_match_ccmode (insn, CCNOmode)"
559 "@
560 test{w}\t{%0, %0|%0, %0}
561 cmp{w}\t{%1, %0|%0, %1}"
562 [(set_attr "type" "test,icmp")
563 (set_attr "length_immediate" "0,1")
564 (set_attr "mode" "HI")])
565
566 (define_insn "*cmphi_minus_1"
567 [(set (reg 17)
568 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
569 (match_operand:HI 1 "general_operand" "ri,mr"))
570 (const_int 0)))]
571 "ix86_match_ccmode (insn, CCGOCmode)"
572 "cmp{w}\t{%1, %0|%0, %1}"
573 [(set_attr "type" "icmp")
574 (set_attr "mode" "HI")])
575
576 (define_insn "*cmphi_1"
577 [(set (reg 17)
578 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
579 (match_operand:HI 1 "general_operand" "ri,mr")))]
580 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
581 && ix86_match_ccmode (insn, CCmode)"
582 "cmp{w}\t{%1, %0|%0, %1}"
583 [(set_attr "type" "icmp")
584 (set_attr "mode" "HI")])
585
586 (define_insn "*cmpqi_ccno_1"
587 [(set (reg 17)
588 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
589 (match_operand:QI 1 "const0_operand" "n,n")))]
590 "ix86_match_ccmode (insn, CCNOmode)"
591 "@
592 test{b}\t{%0, %0|%0, %0}
593 cmp{b}\t{$0, %0|%0, 0}"
594 [(set_attr "type" "test,icmp")
595 (set_attr "length_immediate" "0,1")
596 (set_attr "mode" "QI")])
597
598 (define_insn "*cmpqi_1"
599 [(set (reg 17)
600 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
601 (match_operand:QI 1 "general_operand" "qi,mq")))]
602 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
603 && ix86_match_ccmode (insn, CCmode)"
604 "cmp{b}\t{%1, %0|%0, %1}"
605 [(set_attr "type" "icmp")
606 (set_attr "mode" "QI")])
607
608 (define_insn "*cmpqi_minus_1"
609 [(set (reg 17)
610 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
611 (match_operand:QI 1 "general_operand" "qi,mq"))
612 (const_int 0)))]
613 "ix86_match_ccmode (insn, CCGOCmode)"
614 "cmp{b}\t{%1, %0|%0, %1}"
615 [(set_attr "type" "icmp")
616 (set_attr "mode" "QI")])
617
618 (define_insn "*cmpqi_ext_1"
619 [(set (reg 17)
620 (compare
621 (match_operand:QI 0 "general_operand" "Qm")
622 (subreg:QI
623 (zero_extract:SI
624 (match_operand 1 "ext_register_operand" "Q")
625 (const_int 8)
626 (const_int 8)) 0)))]
627 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
628 "cmp{b}\t{%h1, %0|%0, %h1}"
629 [(set_attr "type" "icmp")
630 (set_attr "mode" "QI")])
631
632 (define_insn "*cmpqi_ext_1_rex64"
633 [(set (reg 17)
634 (compare
635 (match_operand:QI 0 "register_operand" "Q")
636 (subreg:QI
637 (zero_extract:SI
638 (match_operand 1 "ext_register_operand" "Q")
639 (const_int 8)
640 (const_int 8)) 0)))]
641 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
642 "cmp{b}\t{%h1, %0|%0, %h1}"
643 [(set_attr "type" "icmp")
644 (set_attr "mode" "QI")])
645
646 (define_insn "*cmpqi_ext_2"
647 [(set (reg 17)
648 (compare
649 (subreg:QI
650 (zero_extract:SI
651 (match_operand 0 "ext_register_operand" "Q")
652 (const_int 8)
653 (const_int 8)) 0)
654 (match_operand:QI 1 "const0_operand" "n")))]
655 "ix86_match_ccmode (insn, CCNOmode)"
656 "test{b}\t%h0, %h0"
657 [(set_attr "type" "test")
658 (set_attr "length_immediate" "0")
659 (set_attr "mode" "QI")])
660
661 (define_expand "cmpqi_ext_3"
662 [(set (reg:CC 17)
663 (compare:CC
664 (subreg:QI
665 (zero_extract:SI
666 (match_operand 0 "ext_register_operand" "")
667 (const_int 8)
668 (const_int 8)) 0)
669 (match_operand:QI 1 "general_operand" "")))]
670 ""
671 "")
672
673 (define_insn "cmpqi_ext_3_insn"
674 [(set (reg 17)
675 (compare
676 (subreg:QI
677 (zero_extract:SI
678 (match_operand 0 "ext_register_operand" "Q")
679 (const_int 8)
680 (const_int 8)) 0)
681 (match_operand:QI 1 "general_operand" "Qmn")))]
682 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
683 "cmp{b}\t{%1, %h0|%h0, %1}"
684 [(set_attr "type" "icmp")
685 (set_attr "mode" "QI")])
686
687 (define_insn "cmpqi_ext_3_insn_rex64"
688 [(set (reg 17)
689 (compare
690 (subreg:QI
691 (zero_extract:SI
692 (match_operand 0 "ext_register_operand" "Q")
693 (const_int 8)
694 (const_int 8)) 0)
695 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
696 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
697 "cmp{b}\t{%1, %h0|%h0, %1}"
698 [(set_attr "type" "icmp")
699 (set_attr "mode" "QI")])
700
701 (define_insn "*cmpqi_ext_4"
702 [(set (reg 17)
703 (compare
704 (subreg:QI
705 (zero_extract:SI
706 (match_operand 0 "ext_register_operand" "Q")
707 (const_int 8)
708 (const_int 8)) 0)
709 (subreg:QI
710 (zero_extract:SI
711 (match_operand 1 "ext_register_operand" "Q")
712 (const_int 8)
713 (const_int 8)) 0)))]
714 "ix86_match_ccmode (insn, CCmode)"
715 "cmp{b}\t{%h1, %h0|%h0, %h1}"
716 [(set_attr "type" "icmp")
717 (set_attr "mode" "QI")])
718
719 ;; These implement float point compares.
720 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
721 ;; which would allow mix and match FP modes on the compares. Which is what
722 ;; the old patterns did, but with many more of them.
723
724 (define_expand "cmpxf"
725 [(set (reg:CC 17)
726 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
727 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
728 "TARGET_80387"
729 {
730 ix86_compare_op0 = operands[0];
731 ix86_compare_op1 = operands[1];
732 DONE;
733 })
734
735 (define_expand "cmpdf"
736 [(set (reg:CC 17)
737 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
738 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
739 "TARGET_80387 || TARGET_SSE2"
740 {
741 ix86_compare_op0 = operands[0];
742 ix86_compare_op1 = operands[1];
743 DONE;
744 })
745
746 (define_expand "cmpsf"
747 [(set (reg:CC 17)
748 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
749 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
750 "TARGET_80387 || TARGET_SSE"
751 {
752 ix86_compare_op0 = operands[0];
753 ix86_compare_op1 = operands[1];
754 DONE;
755 })
756
757 ;; FP compares, step 1:
758 ;; Set the FP condition codes.
759 ;;
760 ;; CCFPmode compare with exceptions
761 ;; CCFPUmode compare with no exceptions
762
763 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
764 ;; and that fp moves clobber the condition codes, and that there is
765 ;; currently no way to describe this fact to reg-stack. So there are
766 ;; no splitters yet for this.
767
768 ;; %%% YIKES! This scheme does not retain a strong connection between
769 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
770 ;; work! Only allow tos/mem with tos in op 0.
771 ;;
772 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
773 ;; things aren't as bad as they sound...
774
775 (define_insn "*cmpfp_0"
776 [(set (match_operand:HI 0 "register_operand" "=a")
777 (unspec:HI
778 [(compare:CCFP (match_operand 1 "register_operand" "f")
779 (match_operand 2 "const0_operand" "X"))]
780 UNSPEC_FNSTSW))]
781 "TARGET_80387
782 && FLOAT_MODE_P (GET_MODE (operands[1]))
783 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
784 {
785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
786 return "ftst\;fnstsw\t%0\;fstp\t%y0";
787 else
788 return "ftst\;fnstsw\t%0";
789 }
790 [(set_attr "type" "multi")
791 (set (attr "mode")
792 (cond [(match_operand:SF 1 "" "")
793 (const_string "SF")
794 (match_operand:DF 1 "" "")
795 (const_string "DF")
796 ]
797 (const_string "XF")))])
798
799 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
800 ;; used to manage the reg stack popping would not be preserved.
801
802 (define_insn "*cmpfp_2_sf"
803 [(set (reg:CCFP 18)
804 (compare:CCFP
805 (match_operand:SF 0 "register_operand" "f")
806 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
807 "TARGET_80387"
808 "* return output_fp_compare (insn, operands, 0, 0);"
809 [(set_attr "type" "fcmp")
810 (set_attr "mode" "SF")])
811
812 (define_insn "*cmpfp_2_sf_1"
813 [(set (match_operand:HI 0 "register_operand" "=a")
814 (unspec:HI
815 [(compare:CCFP
816 (match_operand:SF 1 "register_operand" "f")
817 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
818 UNSPEC_FNSTSW))]
819 "TARGET_80387"
820 "* return output_fp_compare (insn, operands, 2, 0);"
821 [(set_attr "type" "fcmp")
822 (set_attr "mode" "SF")])
823
824 (define_insn "*cmpfp_2_df"
825 [(set (reg:CCFP 18)
826 (compare:CCFP
827 (match_operand:DF 0 "register_operand" "f")
828 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
829 "TARGET_80387"
830 "* return output_fp_compare (insn, operands, 0, 0);"
831 [(set_attr "type" "fcmp")
832 (set_attr "mode" "DF")])
833
834 (define_insn "*cmpfp_2_df_1"
835 [(set (match_operand:HI 0 "register_operand" "=a")
836 (unspec:HI
837 [(compare:CCFP
838 (match_operand:DF 1 "register_operand" "f")
839 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
840 UNSPEC_FNSTSW))]
841 "TARGET_80387"
842 "* return output_fp_compare (insn, operands, 2, 0);"
843 [(set_attr "type" "multi")
844 (set_attr "mode" "DF")])
845
846 (define_insn "*cmpfp_2_xf"
847 [(set (reg:CCFP 18)
848 (compare:CCFP
849 (match_operand:XF 0 "register_operand" "f")
850 (match_operand:XF 1 "register_operand" "f")))]
851 "TARGET_80387"
852 "* return output_fp_compare (insn, operands, 0, 0);"
853 [(set_attr "type" "fcmp")
854 (set_attr "mode" "XF")])
855
856 (define_insn "*cmpfp_2_xf_1"
857 [(set (match_operand:HI 0 "register_operand" "=a")
858 (unspec:HI
859 [(compare:CCFP
860 (match_operand:XF 1 "register_operand" "f")
861 (match_operand:XF 2 "register_operand" "f"))]
862 UNSPEC_FNSTSW))]
863 "TARGET_80387"
864 "* return output_fp_compare (insn, operands, 2, 0);"
865 [(set_attr "type" "multi")
866 (set_attr "mode" "XF")])
867
868 (define_insn "*cmpfp_2u"
869 [(set (reg:CCFPU 18)
870 (compare:CCFPU
871 (match_operand 0 "register_operand" "f")
872 (match_operand 1 "register_operand" "f")))]
873 "TARGET_80387
874 && FLOAT_MODE_P (GET_MODE (operands[0]))
875 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
876 "* return output_fp_compare (insn, operands, 0, 1);"
877 [(set_attr "type" "fcmp")
878 (set (attr "mode")
879 (cond [(match_operand:SF 1 "" "")
880 (const_string "SF")
881 (match_operand:DF 1 "" "")
882 (const_string "DF")
883 ]
884 (const_string "XF")))])
885
886 (define_insn "*cmpfp_2u_1"
887 [(set (match_operand:HI 0 "register_operand" "=a")
888 (unspec:HI
889 [(compare:CCFPU
890 (match_operand 1 "register_operand" "f")
891 (match_operand 2 "register_operand" "f"))]
892 UNSPEC_FNSTSW))]
893 "TARGET_80387
894 && FLOAT_MODE_P (GET_MODE (operands[1]))
895 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
896 "* return output_fp_compare (insn, operands, 2, 1);"
897 [(set_attr "type" "multi")
898 (set (attr "mode")
899 (cond [(match_operand:SF 1 "" "")
900 (const_string "SF")
901 (match_operand:DF 1 "" "")
902 (const_string "DF")
903 ]
904 (const_string "XF")))])
905
906 ;; Patterns to match the SImode-in-memory ficom instructions.
907 ;;
908 ;; %%% Play games with accepting gp registers, as otherwise we have to
909 ;; force them to memory during rtl generation, which is no good. We
910 ;; can get rid of this once we teach reload to do memory input reloads
911 ;; via pushes.
912
913 (define_insn "*ficom_1"
914 [(set (reg:CCFP 18)
915 (compare:CCFP
916 (match_operand 0 "register_operand" "f,f")
917 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
918 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
919 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
920 "#")
921
922 ;; Split the not-really-implemented gp register case into a
923 ;; push-op-pop sequence.
924 ;;
925 ;; %%% This is most efficient, but am I gonna get in trouble
926 ;; for separating cc0_setter and cc0_user?
927
928 (define_split
929 [(set (reg:CCFP 18)
930 (compare:CCFP
931 (match_operand:SF 0 "register_operand" "")
932 (float (match_operand:SI 1 "register_operand" ""))))]
933 "0 && TARGET_80387 && reload_completed"
934 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
935 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
936 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
937 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
938 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
939 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
940
941 ;; FP compares, step 2
942 ;; Move the fpsw to ax.
943
944 (define_insn "*x86_fnstsw_1"
945 [(set (match_operand:HI 0 "register_operand" "=a")
946 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
947 "TARGET_80387"
948 "fnstsw\t%0"
949 [(set_attr "length" "2")
950 (set_attr "mode" "SI")
951 (set_attr "unit" "i387")])
952
953 ;; FP compares, step 3
954 ;; Get ax into flags, general case.
955
956 (define_insn "x86_sahf_1"
957 [(set (reg:CC 17)
958 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
959 "!TARGET_64BIT"
960 "sahf"
961 [(set_attr "length" "1")
962 (set_attr "athlon_decode" "vector")
963 (set_attr "mode" "SI")])
964
965 ;; Pentium Pro can do steps 1 through 3 in one go.
966
967 (define_insn "*cmpfp_i"
968 [(set (reg:CCFP 17)
969 (compare:CCFP (match_operand 0 "register_operand" "f")
970 (match_operand 1 "register_operand" "f")))]
971 "TARGET_80387 && TARGET_CMOVE
972 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
973 && FLOAT_MODE_P (GET_MODE (operands[0]))
974 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
975 "* return output_fp_compare (insn, operands, 1, 0);"
976 [(set_attr "type" "fcmp")
977 (set (attr "mode")
978 (cond [(match_operand:SF 1 "" "")
979 (const_string "SF")
980 (match_operand:DF 1 "" "")
981 (const_string "DF")
982 ]
983 (const_string "XF")))
984 (set_attr "athlon_decode" "vector")])
985
986 (define_insn "*cmpfp_i_sse"
987 [(set (reg:CCFP 17)
988 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
989 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
990 "TARGET_80387
991 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
992 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
993 "* return output_fp_compare (insn, operands, 1, 0);"
994 [(set_attr "type" "fcmp,ssecomi")
995 (set (attr "mode")
996 (if_then_else (match_operand:SF 1 "" "")
997 (const_string "SF")
998 (const_string "DF")))
999 (set_attr "athlon_decode" "vector")])
1000
1001 (define_insn "*cmpfp_i_sse_only"
1002 [(set (reg:CCFP 17)
1003 (compare:CCFP (match_operand 0 "register_operand" "x")
1004 (match_operand 1 "nonimmediate_operand" "xm")))]
1005 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "ssecomi")
1009 (set (attr "mode")
1010 (if_then_else (match_operand:SF 1 "" "")
1011 (const_string "SF")
1012 (const_string "DF")))
1013 (set_attr "athlon_decode" "vector")])
1014
1015 (define_insn "*cmpfp_iu"
1016 [(set (reg:CCFPU 17)
1017 (compare:CCFPU (match_operand 0 "register_operand" "f")
1018 (match_operand 1 "register_operand" "f")))]
1019 "TARGET_80387 && TARGET_CMOVE
1020 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && FLOAT_MODE_P (GET_MODE (operands[0]))
1022 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1023 "* return output_fp_compare (insn, operands, 1, 1);"
1024 [(set_attr "type" "fcmp")
1025 (set (attr "mode")
1026 (cond [(match_operand:SF 1 "" "")
1027 (const_string "SF")
1028 (match_operand:DF 1 "" "")
1029 (const_string "DF")
1030 ]
1031 (const_string "XF")))
1032 (set_attr "athlon_decode" "vector")])
1033
1034 (define_insn "*cmpfp_iu_sse"
1035 [(set (reg:CCFPU 17)
1036 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1037 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1038 "TARGET_80387
1039 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1040 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1041 "* return output_fp_compare (insn, operands, 1, 1);"
1042 [(set_attr "type" "fcmp,ssecomi")
1043 (set (attr "mode")
1044 (if_then_else (match_operand:SF 1 "" "")
1045 (const_string "SF")
1046 (const_string "DF")))
1047 (set_attr "athlon_decode" "vector")])
1048
1049 (define_insn "*cmpfp_iu_sse_only"
1050 [(set (reg:CCFPU 17)
1051 (compare:CCFPU (match_operand 0 "register_operand" "x")
1052 (match_operand 1 "nonimmediate_operand" "xm")))]
1053 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055 "* return output_fp_compare (insn, operands, 1, 1);"
1056 [(set_attr "type" "ssecomi")
1057 (set (attr "mode")
1058 (if_then_else (match_operand:SF 1 "" "")
1059 (const_string "SF")
1060 (const_string "DF")))
1061 (set_attr "athlon_decode" "vector")])
1062 \f
1063 ;; Move instructions.
1064
1065 ;; General case of fullword move.
1066
1067 (define_expand "movsi"
1068 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1069 (match_operand:SI 1 "general_operand" ""))]
1070 ""
1071 "ix86_expand_move (SImode, operands); DONE;")
1072
1073 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1074 ;; general_operand.
1075 ;;
1076 ;; %%% We don't use a post-inc memory reference because x86 is not a
1077 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1078 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1079 ;; targets without our curiosities, and it is just as easy to represent
1080 ;; this differently.
1081
1082 (define_insn "*pushsi2"
1083 [(set (match_operand:SI 0 "push_operand" "=<")
1084 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1085 "!TARGET_64BIT"
1086 "push{l}\t%1"
1087 [(set_attr "type" "push")
1088 (set_attr "mode" "SI")])
1089
1090 ;; For 64BIT abi we always round up to 8 bytes.
1091 (define_insn "*pushsi2_rex64"
1092 [(set (match_operand:SI 0 "push_operand" "=X")
1093 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1094 "TARGET_64BIT"
1095 "push{q}\t%q1"
1096 [(set_attr "type" "push")
1097 (set_attr "mode" "SI")])
1098
1099 (define_insn "*pushsi2_prologue"
1100 [(set (match_operand:SI 0 "push_operand" "=<")
1101 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1102 (clobber (mem:BLK (scratch)))]
1103 "!TARGET_64BIT"
1104 "push{l}\t%1"
1105 [(set_attr "type" "push")
1106 (set_attr "mode" "SI")])
1107
1108 (define_insn "*popsi1_epilogue"
1109 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1110 (mem:SI (reg:SI 7)))
1111 (set (reg:SI 7)
1112 (plus:SI (reg:SI 7) (const_int 4)))
1113 (clobber (mem:BLK (scratch)))]
1114 "!TARGET_64BIT"
1115 "pop{l}\t%0"
1116 [(set_attr "type" "pop")
1117 (set_attr "mode" "SI")])
1118
1119 (define_insn "popsi1"
1120 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1121 (mem:SI (reg:SI 7)))
1122 (set (reg:SI 7)
1123 (plus:SI (reg:SI 7) (const_int 4)))]
1124 "!TARGET_64BIT"
1125 "pop{l}\t%0"
1126 [(set_attr "type" "pop")
1127 (set_attr "mode" "SI")])
1128
1129 (define_insn "*movsi_xor"
1130 [(set (match_operand:SI 0 "register_operand" "=r")
1131 (match_operand:SI 1 "const0_operand" "i"))
1132 (clobber (reg:CC 17))]
1133 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1134 "xor{l}\t{%0, %0|%0, %0}"
1135 [(set_attr "type" "alu1")
1136 (set_attr "mode" "SI")
1137 (set_attr "length_immediate" "0")])
1138
1139 (define_insn "*movsi_or"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (match_operand:SI 1 "immediate_operand" "i"))
1142 (clobber (reg:CC 17))]
1143 "reload_completed
1144 && operands[1] == constm1_rtx
1145 && (TARGET_PENTIUM || optimize_size)"
1146 {
1147 operands[1] = constm1_rtx;
1148 return "or{l}\t{%1, %0|%0, %1}";
1149 }
1150 [(set_attr "type" "alu1")
1151 (set_attr "mode" "SI")
1152 (set_attr "length_immediate" "1")])
1153
1154 (define_insn "*movsi_1"
1155 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1156 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1157 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1158 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1159 {
1160 switch (get_attr_type (insn))
1161 {
1162 case TYPE_SSEMOV:
1163 if (get_attr_mode (insn) == MODE_TI)
1164 return "movdqa\t{%1, %0|%0, %1}";
1165 return "movd\t{%1, %0|%0, %1}";
1166
1167 case TYPE_MMXMOV:
1168 if (get_attr_mode (insn) == MODE_DI)
1169 return "movq\t{%1, %0|%0, %1}";
1170 return "movd\t{%1, %0|%0, %1}";
1171
1172 case TYPE_LEA:
1173 return "lea{l}\t{%1, %0|%0, %1}";
1174
1175 default:
1176 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1177 abort();
1178 return "mov{l}\t{%1, %0|%0, %1}";
1179 }
1180 }
1181 [(set (attr "type")
1182 (cond [(eq_attr "alternative" "2,3,4")
1183 (const_string "mmxmov")
1184 (eq_attr "alternative" "5,6,7")
1185 (const_string "ssemov")
1186 (and (ne (symbol_ref "flag_pic") (const_int 0))
1187 (match_operand:SI 1 "symbolic_operand" ""))
1188 (const_string "lea")
1189 ]
1190 (const_string "imov")))
1191 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1192
1193 (define_insn "*movsi_1_nointernunit"
1194 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1195 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1196 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1197 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1198 {
1199 switch (get_attr_type (insn))
1200 {
1201 case TYPE_SSEMOV:
1202 if (get_attr_mode (insn) == MODE_TI)
1203 return "movdqa\t{%1, %0|%0, %1}";
1204 return "movd\t{%1, %0|%0, %1}";
1205
1206 case TYPE_MMXMOV:
1207 if (get_attr_mode (insn) == MODE_DI)
1208 return "movq\t{%1, %0|%0, %1}";
1209 return "movd\t{%1, %0|%0, %1}";
1210
1211 case TYPE_LEA:
1212 return "lea{l}\t{%1, %0|%0, %1}";
1213
1214 default:
1215 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1216 abort();
1217 return "mov{l}\t{%1, %0|%0, %1}";
1218 }
1219 }
1220 [(set (attr "type")
1221 (cond [(eq_attr "alternative" "2,3,4")
1222 (const_string "mmxmov")
1223 (eq_attr "alternative" "5,6,7")
1224 (const_string "ssemov")
1225 (and (ne (symbol_ref "flag_pic") (const_int 0))
1226 (match_operand:SI 1 "symbolic_operand" ""))
1227 (const_string "lea")
1228 ]
1229 (const_string "imov")))
1230 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1231
1232 ;; Stores and loads of ax to arbitrary constant address.
1233 ;; We fake an second form of instruction to force reload to load address
1234 ;; into register when rax is not available
1235 (define_insn "*movabssi_1_rex64"
1236 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1237 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1238 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1239 "@
1240 movabs{l}\t{%1, %P0|%P0, %1}
1241 mov{l}\t{%1, %a0|%a0, %1}"
1242 [(set_attr "type" "imov")
1243 (set_attr "modrm" "0,*")
1244 (set_attr "length_address" "8,0")
1245 (set_attr "length_immediate" "0,*")
1246 (set_attr "memory" "store")
1247 (set_attr "mode" "SI")])
1248
1249 (define_insn "*movabssi_2_rex64"
1250 [(set (match_operand:SI 0 "register_operand" "=a,r")
1251 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1252 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1253 "@
1254 movabs{l}\t{%P1, %0|%0, %P1}
1255 mov{l}\t{%a1, %0|%0, %a1}"
1256 [(set_attr "type" "imov")
1257 (set_attr "modrm" "0,*")
1258 (set_attr "length_address" "8,0")
1259 (set_attr "length_immediate" "0")
1260 (set_attr "memory" "load")
1261 (set_attr "mode" "SI")])
1262
1263 (define_insn "*swapsi"
1264 [(set (match_operand:SI 0 "register_operand" "+r")
1265 (match_operand:SI 1 "register_operand" "+r"))
1266 (set (match_dup 1)
1267 (match_dup 0))]
1268 ""
1269 "xchg{l}\t%1, %0"
1270 [(set_attr "type" "imov")
1271 (set_attr "pent_pair" "np")
1272 (set_attr "athlon_decode" "vector")
1273 (set_attr "mode" "SI")
1274 (set_attr "modrm" "0")])
1275
1276 (define_expand "movhi"
1277 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1278 (match_operand:HI 1 "general_operand" ""))]
1279 ""
1280 "ix86_expand_move (HImode, operands); DONE;")
1281
1282 (define_insn "*pushhi2"
1283 [(set (match_operand:HI 0 "push_operand" "=<,<")
1284 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1285 "!TARGET_64BIT"
1286 "@
1287 push{w}\t{|WORD PTR }%1
1288 push{w}\t%1"
1289 [(set_attr "type" "push")
1290 (set_attr "mode" "HI")])
1291
1292 ;; For 64BIT abi we always round up to 8 bytes.
1293 (define_insn "*pushhi2_rex64"
1294 [(set (match_operand:HI 0 "push_operand" "=X")
1295 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1296 "TARGET_64BIT"
1297 "push{q}\t%q1"
1298 [(set_attr "type" "push")
1299 (set_attr "mode" "QI")])
1300
1301 (define_insn "*movhi_1"
1302 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1303 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1304 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1305 {
1306 switch (get_attr_type (insn))
1307 {
1308 case TYPE_IMOVX:
1309 /* movzwl is faster than movw on p2 due to partial word stalls,
1310 though not as fast as an aligned movl. */
1311 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1312 default:
1313 if (get_attr_mode (insn) == MODE_SI)
1314 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1315 else
1316 return "mov{w}\t{%1, %0|%0, %1}";
1317 }
1318 }
1319 [(set (attr "type")
1320 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "0")
1323 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1324 (const_int 0))
1325 (eq (symbol_ref "TARGET_HIMODE_MATH")
1326 (const_int 0))))
1327 (const_string "imov")
1328 (and (eq_attr "alternative" "1,2")
1329 (match_operand:HI 1 "aligned_operand" ""))
1330 (const_string "imov")
1331 (and (ne (symbol_ref "TARGET_MOVX")
1332 (const_int 0))
1333 (eq_attr "alternative" "0,2"))
1334 (const_string "imovx")
1335 ]
1336 (const_string "imov")))
1337 (set (attr "mode")
1338 (cond [(eq_attr "type" "imovx")
1339 (const_string "SI")
1340 (and (eq_attr "alternative" "1,2")
1341 (match_operand:HI 1 "aligned_operand" ""))
1342 (const_string "SI")
1343 (and (eq_attr "alternative" "0")
1344 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1345 (const_int 0))
1346 (eq (symbol_ref "TARGET_HIMODE_MATH")
1347 (const_int 0))))
1348 (const_string "SI")
1349 ]
1350 (const_string "HI")))])
1351
1352 ;; Stores and loads of ax to arbitrary constant address.
1353 ;; We fake an second form of instruction to force reload to load address
1354 ;; into register when rax is not available
1355 (define_insn "*movabshi_1_rex64"
1356 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1357 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1358 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1359 "@
1360 movabs{w}\t{%1, %P0|%P0, %1}
1361 mov{w}\t{%1, %a0|%a0, %1}"
1362 [(set_attr "type" "imov")
1363 (set_attr "modrm" "0,*")
1364 (set_attr "length_address" "8,0")
1365 (set_attr "length_immediate" "0,*")
1366 (set_attr "memory" "store")
1367 (set_attr "mode" "HI")])
1368
1369 (define_insn "*movabshi_2_rex64"
1370 [(set (match_operand:HI 0 "register_operand" "=a,r")
1371 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1372 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1373 "@
1374 movabs{w}\t{%P1, %0|%0, %P1}
1375 mov{w}\t{%a1, %0|%0, %a1}"
1376 [(set_attr "type" "imov")
1377 (set_attr "modrm" "0,*")
1378 (set_attr "length_address" "8,0")
1379 (set_attr "length_immediate" "0")
1380 (set_attr "memory" "load")
1381 (set_attr "mode" "HI")])
1382
1383 (define_insn "*swaphi_1"
1384 [(set (match_operand:HI 0 "register_operand" "+r")
1385 (match_operand:HI 1 "register_operand" "+r"))
1386 (set (match_dup 1)
1387 (match_dup 0))]
1388 "TARGET_PARTIAL_REG_STALL"
1389 "xchg{w}\t%1, %0"
1390 [(set_attr "type" "imov")
1391 (set_attr "pent_pair" "np")
1392 (set_attr "mode" "HI")
1393 (set_attr "modrm" "0")])
1394
1395 (define_insn "*swaphi_2"
1396 [(set (match_operand:HI 0 "register_operand" "+r")
1397 (match_operand:HI 1 "register_operand" "+r"))
1398 (set (match_dup 1)
1399 (match_dup 0))]
1400 "! TARGET_PARTIAL_REG_STALL"
1401 "xchg{l}\t%k1, %k0"
1402 [(set_attr "type" "imov")
1403 (set_attr "pent_pair" "np")
1404 (set_attr "mode" "SI")
1405 (set_attr "modrm" "0")])
1406
1407 (define_expand "movstricthi"
1408 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1409 (match_operand:HI 1 "general_operand" ""))]
1410 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1411 {
1412 /* Don't generate memory->memory moves, go through a register */
1413 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1414 operands[1] = force_reg (HImode, operands[1]);
1415 })
1416
1417 (define_insn "*movstricthi_1"
1418 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1419 (match_operand:HI 1 "general_operand" "rn,m"))]
1420 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1421 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1422 "mov{w}\t{%1, %0|%0, %1}"
1423 [(set_attr "type" "imov")
1424 (set_attr "mode" "HI")])
1425
1426 (define_insn "*movstricthi_xor"
1427 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1428 (match_operand:HI 1 "const0_operand" "i"))
1429 (clobber (reg:CC 17))]
1430 "reload_completed
1431 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1432 "xor{w}\t{%0, %0|%0, %0}"
1433 [(set_attr "type" "alu1")
1434 (set_attr "mode" "HI")
1435 (set_attr "length_immediate" "0")])
1436
1437 (define_expand "movqi"
1438 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1439 (match_operand:QI 1 "general_operand" ""))]
1440 ""
1441 "ix86_expand_move (QImode, operands); DONE;")
1442
1443 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1444 ;; "push a byte". But actually we use pushw, which has the effect
1445 ;; of rounding the amount pushed up to a halfword.
1446
1447 (define_insn "*pushqi2"
1448 [(set (match_operand:QI 0 "push_operand" "=X,X")
1449 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1450 "!TARGET_64BIT"
1451 "@
1452 push{w}\t{|word ptr }%1
1453 push{w}\t%w1"
1454 [(set_attr "type" "push")
1455 (set_attr "mode" "HI")])
1456
1457 ;; For 64BIT abi we always round up to 8 bytes.
1458 (define_insn "*pushqi2_rex64"
1459 [(set (match_operand:QI 0 "push_operand" "=X")
1460 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1461 "TARGET_64BIT"
1462 "push{q}\t%q1"
1463 [(set_attr "type" "push")
1464 (set_attr "mode" "QI")])
1465
1466 ;; Situation is quite tricky about when to choose full sized (SImode) move
1467 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1468 ;; partial register dependency machines (such as AMD Athlon), where QImode
1469 ;; moves issue extra dependency and for partial register stalls machines
1470 ;; that don't use QImode patterns (and QImode move cause stall on the next
1471 ;; instruction).
1472 ;;
1473 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1474 ;; register stall machines with, where we use QImode instructions, since
1475 ;; partial register stall can be caused there. Then we use movzx.
1476 (define_insn "*movqi_1"
1477 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1478 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1479 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1480 {
1481 switch (get_attr_type (insn))
1482 {
1483 case TYPE_IMOVX:
1484 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1485 abort ();
1486 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1487 default:
1488 if (get_attr_mode (insn) == MODE_SI)
1489 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1490 else
1491 return "mov{b}\t{%1, %0|%0, %1}";
1492 }
1493 }
1494 [(set (attr "type")
1495 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1496 (const_string "imov")
1497 (and (eq_attr "alternative" "3")
1498 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1499 (const_int 0))
1500 (eq (symbol_ref "TARGET_QIMODE_MATH")
1501 (const_int 0))))
1502 (const_string "imov")
1503 (eq_attr "alternative" "3,5")
1504 (const_string "imovx")
1505 (and (ne (symbol_ref "TARGET_MOVX")
1506 (const_int 0))
1507 (eq_attr "alternative" "2"))
1508 (const_string "imovx")
1509 ]
1510 (const_string "imov")))
1511 (set (attr "mode")
1512 (cond [(eq_attr "alternative" "3,4,5")
1513 (const_string "SI")
1514 (eq_attr "alternative" "6")
1515 (const_string "QI")
1516 (eq_attr "type" "imovx")
1517 (const_string "SI")
1518 (and (eq_attr "type" "imov")
1519 (and (eq_attr "alternative" "0,1,2")
1520 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1521 (const_int 0))))
1522 (const_string "SI")
1523 ;; Avoid partial register stalls when not using QImode arithmetic
1524 (and (eq_attr "type" "imov")
1525 (and (eq_attr "alternative" "0,1,2")
1526 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527 (const_int 0))
1528 (eq (symbol_ref "TARGET_QIMODE_MATH")
1529 (const_int 0)))))
1530 (const_string "SI")
1531 ]
1532 (const_string "QI")))])
1533
1534 (define_expand "reload_outqi"
1535 [(parallel [(match_operand:QI 0 "" "=m")
1536 (match_operand:QI 1 "register_operand" "r")
1537 (match_operand:QI 2 "register_operand" "=&q")])]
1538 ""
1539 {
1540 rtx op0, op1, op2;
1541 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1542
1543 if (reg_overlap_mentioned_p (op2, op0))
1544 abort ();
1545 if (! q_regs_operand (op1, QImode))
1546 {
1547 emit_insn (gen_movqi (op2, op1));
1548 op1 = op2;
1549 }
1550 emit_insn (gen_movqi (op0, op1));
1551 DONE;
1552 })
1553
1554 (define_insn "*swapqi"
1555 [(set (match_operand:QI 0 "register_operand" "+r")
1556 (match_operand:QI 1 "register_operand" "+r"))
1557 (set (match_dup 1)
1558 (match_dup 0))]
1559 ""
1560 "xchg{b}\t%1, %0"
1561 [(set_attr "type" "imov")
1562 (set_attr "pent_pair" "np")
1563 (set_attr "mode" "QI")
1564 (set_attr "modrm" "0")])
1565
1566 (define_expand "movstrictqi"
1567 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1568 (match_operand:QI 1 "general_operand" ""))]
1569 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1570 {
1571 /* Don't generate memory->memory moves, go through a register. */
1572 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1573 operands[1] = force_reg (QImode, operands[1]);
1574 })
1575
1576 (define_insn "*movstrictqi_1"
1577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1578 (match_operand:QI 1 "general_operand" "*qn,m"))]
1579 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1580 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1581 "mov{b}\t{%1, %0|%0, %1}"
1582 [(set_attr "type" "imov")
1583 (set_attr "mode" "QI")])
1584
1585 (define_insn "*movstrictqi_xor"
1586 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1587 (match_operand:QI 1 "const0_operand" "i"))
1588 (clobber (reg:CC 17))]
1589 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1590 "xor{b}\t{%0, %0|%0, %0}"
1591 [(set_attr "type" "alu1")
1592 (set_attr "mode" "QI")
1593 (set_attr "length_immediate" "0")])
1594
1595 (define_insn "*movsi_extv_1"
1596 [(set (match_operand:SI 0 "register_operand" "=R")
1597 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1598 (const_int 8)
1599 (const_int 8)))]
1600 ""
1601 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1602 [(set_attr "type" "imovx")
1603 (set_attr "mode" "SI")])
1604
1605 (define_insn "*movhi_extv_1"
1606 [(set (match_operand:HI 0 "register_operand" "=R")
1607 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1608 (const_int 8)
1609 (const_int 8)))]
1610 ""
1611 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1612 [(set_attr "type" "imovx")
1613 (set_attr "mode" "SI")])
1614
1615 (define_insn "*movqi_extv_1"
1616 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1617 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1618 (const_int 8)
1619 (const_int 8)))]
1620 "!TARGET_64BIT"
1621 {
1622 switch (get_attr_type (insn))
1623 {
1624 case TYPE_IMOVX:
1625 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1626 default:
1627 return "mov{b}\t{%h1, %0|%0, %h1}";
1628 }
1629 }
1630 [(set (attr "type")
1631 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1632 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1633 (ne (symbol_ref "TARGET_MOVX")
1634 (const_int 0))))
1635 (const_string "imovx")
1636 (const_string "imov")))
1637 (set (attr "mode")
1638 (if_then_else (eq_attr "type" "imovx")
1639 (const_string "SI")
1640 (const_string "QI")))])
1641
1642 (define_insn "*movqi_extv_1_rex64"
1643 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1644 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1645 (const_int 8)
1646 (const_int 8)))]
1647 "TARGET_64BIT"
1648 {
1649 switch (get_attr_type (insn))
1650 {
1651 case TYPE_IMOVX:
1652 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1653 default:
1654 return "mov{b}\t{%h1, %0|%0, %h1}";
1655 }
1656 }
1657 [(set (attr "type")
1658 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1659 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1660 (ne (symbol_ref "TARGET_MOVX")
1661 (const_int 0))))
1662 (const_string "imovx")
1663 (const_string "imov")))
1664 (set (attr "mode")
1665 (if_then_else (eq_attr "type" "imovx")
1666 (const_string "SI")
1667 (const_string "QI")))])
1668
1669 ;; Stores and loads of ax to arbitrary constant address.
1670 ;; We fake an second form of instruction to force reload to load address
1671 ;; into register when rax is not available
1672 (define_insn "*movabsqi_1_rex64"
1673 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1674 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1675 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1676 "@
1677 movabs{b}\t{%1, %P0|%P0, %1}
1678 mov{b}\t{%1, %a0|%a0, %1}"
1679 [(set_attr "type" "imov")
1680 (set_attr "modrm" "0,*")
1681 (set_attr "length_address" "8,0")
1682 (set_attr "length_immediate" "0,*")
1683 (set_attr "memory" "store")
1684 (set_attr "mode" "QI")])
1685
1686 (define_insn "*movabsqi_2_rex64"
1687 [(set (match_operand:QI 0 "register_operand" "=a,r")
1688 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1689 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1690 "@
1691 movabs{b}\t{%P1, %0|%0, %P1}
1692 mov{b}\t{%a1, %0|%0, %a1}"
1693 [(set_attr "type" "imov")
1694 (set_attr "modrm" "0,*")
1695 (set_attr "length_address" "8,0")
1696 (set_attr "length_immediate" "0")
1697 (set_attr "memory" "load")
1698 (set_attr "mode" "QI")])
1699
1700 (define_insn "*movsi_extzv_1"
1701 [(set (match_operand:SI 0 "register_operand" "=R")
1702 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1703 (const_int 8)
1704 (const_int 8)))]
1705 ""
1706 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1707 [(set_attr "type" "imovx")
1708 (set_attr "mode" "SI")])
1709
1710 (define_insn "*movqi_extzv_2"
1711 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1712 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1713 (const_int 8)
1714 (const_int 8)) 0))]
1715 "!TARGET_64BIT"
1716 {
1717 switch (get_attr_type (insn))
1718 {
1719 case TYPE_IMOVX:
1720 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1721 default:
1722 return "mov{b}\t{%h1, %0|%0, %h1}";
1723 }
1724 }
1725 [(set (attr "type")
1726 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1727 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1728 (ne (symbol_ref "TARGET_MOVX")
1729 (const_int 0))))
1730 (const_string "imovx")
1731 (const_string "imov")))
1732 (set (attr "mode")
1733 (if_then_else (eq_attr "type" "imovx")
1734 (const_string "SI")
1735 (const_string "QI")))])
1736
1737 (define_insn "*movqi_extzv_2_rex64"
1738 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1739 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1740 (const_int 8)
1741 (const_int 8)) 0))]
1742 "TARGET_64BIT"
1743 {
1744 switch (get_attr_type (insn))
1745 {
1746 case TYPE_IMOVX:
1747 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1748 default:
1749 return "mov{b}\t{%h1, %0|%0, %h1}";
1750 }
1751 }
1752 [(set (attr "type")
1753 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1754 (ne (symbol_ref "TARGET_MOVX")
1755 (const_int 0)))
1756 (const_string "imovx")
1757 (const_string "imov")))
1758 (set (attr "mode")
1759 (if_then_else (eq_attr "type" "imovx")
1760 (const_string "SI")
1761 (const_string "QI")))])
1762
1763 (define_insn "movsi_insv_1"
1764 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1765 (const_int 8)
1766 (const_int 8))
1767 (match_operand:SI 1 "general_operand" "Qmn"))]
1768 "!TARGET_64BIT"
1769 "mov{b}\t{%b1, %h0|%h0, %b1}"
1770 [(set_attr "type" "imov")
1771 (set_attr "mode" "QI")])
1772
1773 (define_insn "*movsi_insv_1_rex64"
1774 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1775 (const_int 8)
1776 (const_int 8))
1777 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1778 "TARGET_64BIT"
1779 "mov{b}\t{%b1, %h0|%h0, %b1}"
1780 [(set_attr "type" "imov")
1781 (set_attr "mode" "QI")])
1782
1783 (define_insn "*movqi_insv_2"
1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785 (const_int 8)
1786 (const_int 8))
1787 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1788 (const_int 8)))]
1789 ""
1790 "mov{b}\t{%h1, %h0|%h0, %h1}"
1791 [(set_attr "type" "imov")
1792 (set_attr "mode" "QI")])
1793
1794 (define_expand "movdi"
1795 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1796 (match_operand:DI 1 "general_operand" ""))]
1797 ""
1798 "ix86_expand_move (DImode, operands); DONE;")
1799
1800 (define_insn "*pushdi"
1801 [(set (match_operand:DI 0 "push_operand" "=<")
1802 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1803 "!TARGET_64BIT"
1804 "#")
1805
1806 (define_insn "pushdi2_rex64"
1807 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1808 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1809 "TARGET_64BIT"
1810 "@
1811 push{q}\t%1
1812 #"
1813 [(set_attr "type" "push,multi")
1814 (set_attr "mode" "DI")])
1815
1816 ;; Convert impossible pushes of immediate to existing instructions.
1817 ;; First try to get scratch register and go through it. In case this
1818 ;; fails, push sign extended lower part first and then overwrite
1819 ;; upper part by 32bit move.
1820 (define_peephole2
1821 [(match_scratch:DI 2 "r")
1822 (set (match_operand:DI 0 "push_operand" "")
1823 (match_operand:DI 1 "immediate_operand" ""))]
1824 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1825 && !x86_64_immediate_operand (operands[1], DImode)"
1826 [(set (match_dup 2) (match_dup 1))
1827 (set (match_dup 0) (match_dup 2))]
1828 "")
1829
1830 ;; We need to define this as both peepholer and splitter for case
1831 ;; peephole2 pass is not run.
1832 (define_peephole2
1833 [(set (match_operand:DI 0 "push_operand" "")
1834 (match_operand:DI 1 "immediate_operand" ""))]
1835 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1836 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1837 [(set (match_dup 0) (match_dup 1))
1838 (set (match_dup 2) (match_dup 3))]
1839 "split_di (operands + 1, 1, operands + 2, operands + 3);
1840 operands[1] = gen_lowpart (DImode, operands[2]);
1841 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1842 GEN_INT (4)));
1843 ")
1844
1845 (define_split
1846 [(set (match_operand:DI 0 "push_operand" "")
1847 (match_operand:DI 1 "immediate_operand" ""))]
1848 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1849 && !symbolic_operand (operands[1], DImode)
1850 && !x86_64_immediate_operand (operands[1], DImode)"
1851 [(set (match_dup 0) (match_dup 1))
1852 (set (match_dup 2) (match_dup 3))]
1853 "split_di (operands + 1, 1, operands + 2, operands + 3);
1854 operands[1] = gen_lowpart (DImode, operands[2]);
1855 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1856 GEN_INT (4)));
1857 ")
1858
1859 (define_insn "*pushdi2_prologue_rex64"
1860 [(set (match_operand:DI 0 "push_operand" "=<")
1861 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1862 (clobber (mem:BLK (scratch)))]
1863 "TARGET_64BIT"
1864 "push{q}\t%1"
1865 [(set_attr "type" "push")
1866 (set_attr "mode" "DI")])
1867
1868 (define_insn "*popdi1_epilogue_rex64"
1869 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1870 (mem:DI (reg:DI 7)))
1871 (set (reg:DI 7)
1872 (plus:DI (reg:DI 7) (const_int 8)))
1873 (clobber (mem:BLK (scratch)))]
1874 "TARGET_64BIT"
1875 "pop{q}\t%0"
1876 [(set_attr "type" "pop")
1877 (set_attr "mode" "DI")])
1878
1879 (define_insn "popdi1"
1880 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1881 (mem:DI (reg:DI 7)))
1882 (set (reg:DI 7)
1883 (plus:DI (reg:DI 7) (const_int 8)))]
1884 "TARGET_64BIT"
1885 "pop{q}\t%0"
1886 [(set_attr "type" "pop")
1887 (set_attr "mode" "DI")])
1888
1889 (define_insn "*movdi_xor_rex64"
1890 [(set (match_operand:DI 0 "register_operand" "=r")
1891 (match_operand:DI 1 "const0_operand" "i"))
1892 (clobber (reg:CC 17))]
1893 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1894 && reload_completed"
1895 "xor{l}\t{%k0, %k0|%k0, %k0}"
1896 [(set_attr "type" "alu1")
1897 (set_attr "mode" "SI")
1898 (set_attr "length_immediate" "0")])
1899
1900 (define_insn "*movdi_or_rex64"
1901 [(set (match_operand:DI 0 "register_operand" "=r")
1902 (match_operand:DI 1 "const_int_operand" "i"))
1903 (clobber (reg:CC 17))]
1904 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1905 && reload_completed
1906 && operands[1] == constm1_rtx"
1907 {
1908 operands[1] = constm1_rtx;
1909 return "or{q}\t{%1, %0|%0, %1}";
1910 }
1911 [(set_attr "type" "alu1")
1912 (set_attr "mode" "DI")
1913 (set_attr "length_immediate" "1")])
1914
1915 (define_insn "*movdi_2"
1916 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1917 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1918 "!TARGET_64BIT
1919 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1920 "@
1921 #
1922 #
1923 movq\t{%1, %0|%0, %1}
1924 movq\t{%1, %0|%0, %1}
1925 movq\t{%1, %0|%0, %1}
1926 movdqa\t{%1, %0|%0, %1}
1927 movq\t{%1, %0|%0, %1}"
1928 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1929 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1930
1931 (define_split
1932 [(set (match_operand:DI 0 "push_operand" "")
1933 (match_operand:DI 1 "general_operand" ""))]
1934 "!TARGET_64BIT && reload_completed
1935 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1936 [(const_int 0)]
1937 "ix86_split_long_move (operands); DONE;")
1938
1939 ;; %%% This multiword shite has got to go.
1940 (define_split
1941 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1942 (match_operand:DI 1 "general_operand" ""))]
1943 "!TARGET_64BIT && reload_completed
1944 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1945 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1946 [(const_int 0)]
1947 "ix86_split_long_move (operands); DONE;")
1948
1949 (define_insn "*movdi_1_rex64"
1950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1951 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1952 "TARGET_64BIT
1953 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1954 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1955 {
1956 switch (get_attr_type (insn))
1957 {
1958 case TYPE_SSEMOV:
1959 if (get_attr_mode (insn) == MODE_TI)
1960 return "movdqa\t{%1, %0|%0, %1}";
1961 /* FALLTHRU */
1962 case TYPE_MMXMOV:
1963 /* Moves from and into integer register is done using movd opcode with
1964 REX prefix. */
1965 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1966 return "movd\t{%1, %0|%0, %1}";
1967 return "movq\t{%1, %0|%0, %1}";
1968 case TYPE_MULTI:
1969 return "#";
1970 case TYPE_LEA:
1971 return "lea{q}\t{%a1, %0|%0, %a1}";
1972 default:
1973 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1974 abort ();
1975 if (get_attr_mode (insn) == MODE_SI)
1976 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1977 else if (which_alternative == 2)
1978 return "movabs{q}\t{%1, %0|%0, %1}";
1979 else
1980 return "mov{q}\t{%1, %0|%0, %1}";
1981 }
1982 }
1983 [(set (attr "type")
1984 (cond [(eq_attr "alternative" "5,6,7")
1985 (const_string "mmxmov")
1986 (eq_attr "alternative" "8,9,10")
1987 (const_string "ssemov")
1988 (eq_attr "alternative" "4")
1989 (const_string "multi")
1990 (and (ne (symbol_ref "flag_pic") (const_int 0))
1991 (match_operand:DI 1 "symbolic_operand" ""))
1992 (const_string "lea")
1993 ]
1994 (const_string "imov")))
1995 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1996 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1997 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1998
1999 (define_insn "*movdi_1_rex64_nointerunit"
2000 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2001 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2002 "TARGET_64BIT
2003 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2004 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2005 {
2006 switch (get_attr_type (insn))
2007 {
2008 case TYPE_SSEMOV:
2009 if (get_attr_mode (insn) == MODE_TI)
2010 return "movdqa\t{%1, %0|%0, %1}";
2011 /* FALLTHRU */
2012 case TYPE_MMXMOV:
2013 return "movq\t{%1, %0|%0, %1}";
2014 case TYPE_MULTI:
2015 return "#";
2016 case TYPE_LEA:
2017 return "lea{q}\t{%a1, %0|%0, %a1}";
2018 default:
2019 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2020 abort ();
2021 if (get_attr_mode (insn) == MODE_SI)
2022 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2023 else if (which_alternative == 2)
2024 return "movabs{q}\t{%1, %0|%0, %1}";
2025 else
2026 return "mov{q}\t{%1, %0|%0, %1}";
2027 }
2028 }
2029 [(set (attr "type")
2030 (cond [(eq_attr "alternative" "5,6,7")
2031 (const_string "mmxmov")
2032 (eq_attr "alternative" "8,9,10")
2033 (const_string "ssemov")
2034 (eq_attr "alternative" "4")
2035 (const_string "multi")
2036 (and (ne (symbol_ref "flag_pic") (const_int 0))
2037 (match_operand:DI 1 "symbolic_operand" ""))
2038 (const_string "lea")
2039 ]
2040 (const_string "imov")))
2041 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2042 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2043 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2044
2045 ;; Stores and loads of ax to arbitrary constant address.
2046 ;; We fake an second form of instruction to force reload to load address
2047 ;; into register when rax is not available
2048 (define_insn "*movabsdi_1_rex64"
2049 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2050 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2051 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2052 "@
2053 movabs{q}\t{%1, %P0|%P0, %1}
2054 mov{q}\t{%1, %a0|%a0, %1}"
2055 [(set_attr "type" "imov")
2056 (set_attr "modrm" "0,*")
2057 (set_attr "length_address" "8,0")
2058 (set_attr "length_immediate" "0,*")
2059 (set_attr "memory" "store")
2060 (set_attr "mode" "DI")])
2061
2062 (define_insn "*movabsdi_2_rex64"
2063 [(set (match_operand:DI 0 "register_operand" "=a,r")
2064 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2065 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2066 "@
2067 movabs{q}\t{%P1, %0|%0, %P1}
2068 mov{q}\t{%a1, %0|%0, %a1}"
2069 [(set_attr "type" "imov")
2070 (set_attr "modrm" "0,*")
2071 (set_attr "length_address" "8,0")
2072 (set_attr "length_immediate" "0")
2073 (set_attr "memory" "load")
2074 (set_attr "mode" "DI")])
2075
2076 ;; Convert impossible stores of immediate to existing instructions.
2077 ;; First try to get scratch register and go through it. In case this
2078 ;; fails, move by 32bit parts.
2079 (define_peephole2
2080 [(match_scratch:DI 2 "r")
2081 (set (match_operand:DI 0 "memory_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode)"
2085 [(set (match_dup 2) (match_dup 1))
2086 (set (match_dup 0) (match_dup 2))]
2087 "")
2088
2089 ;; We need to define this as both peepholer and splitter for case
2090 ;; peephole2 pass is not run.
2091 (define_peephole2
2092 [(set (match_operand:DI 0 "memory_operand" "")
2093 (match_operand:DI 1 "immediate_operand" ""))]
2094 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2095 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2096 [(set (match_dup 2) (match_dup 3))
2097 (set (match_dup 4) (match_dup 5))]
2098 "split_di (operands, 2, operands + 2, operands + 4);")
2099
2100 (define_split
2101 [(set (match_operand:DI 0 "memory_operand" "")
2102 (match_operand:DI 1 "immediate_operand" ""))]
2103 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2104 && !symbolic_operand (operands[1], DImode)
2105 && !x86_64_immediate_operand (operands[1], DImode)"
2106 [(set (match_dup 2) (match_dup 3))
2107 (set (match_dup 4) (match_dup 5))]
2108 "split_di (operands, 2, operands + 2, operands + 4);")
2109
2110 (define_insn "*swapdi_rex64"
2111 [(set (match_operand:DI 0 "register_operand" "+r")
2112 (match_operand:DI 1 "register_operand" "+r"))
2113 (set (match_dup 1)
2114 (match_dup 0))]
2115 "TARGET_64BIT"
2116 "xchg{q}\t%1, %0"
2117 [(set_attr "type" "imov")
2118 (set_attr "pent_pair" "np")
2119 (set_attr "athlon_decode" "vector")
2120 (set_attr "mode" "DI")
2121 (set_attr "modrm" "0")])
2122
2123
2124 (define_expand "movsf"
2125 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2126 (match_operand:SF 1 "general_operand" ""))]
2127 ""
2128 "ix86_expand_move (SFmode, operands); DONE;")
2129
2130 (define_insn "*pushsf"
2131 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2132 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2133 "!TARGET_64BIT"
2134 {
2135 switch (which_alternative)
2136 {
2137 case 1:
2138 return "push{l}\t%1";
2139
2140 default:
2141 /* This insn should be already split before reg-stack. */
2142 abort ();
2143 }
2144 }
2145 [(set_attr "type" "multi,push,multi")
2146 (set_attr "mode" "SF,SI,SF")])
2147
2148 (define_insn "*pushsf_rex64"
2149 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2150 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2151 "TARGET_64BIT"
2152 {
2153 switch (which_alternative)
2154 {
2155 case 1:
2156 return "push{q}\t%q1";
2157
2158 default:
2159 /* This insn should be already split before reg-stack. */
2160 abort ();
2161 }
2162 }
2163 [(set_attr "type" "multi,push,multi")
2164 (set_attr "mode" "SF,DI,SF")])
2165
2166 (define_split
2167 [(set (match_operand:SF 0 "push_operand" "")
2168 (match_operand:SF 1 "memory_operand" ""))]
2169 "reload_completed
2170 && GET_CODE (operands[1]) == MEM
2171 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2172 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2173 [(set (match_dup 0)
2174 (match_dup 1))]
2175 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2176
2177
2178 ;; %%% Kill this when call knows how to work this out.
2179 (define_split
2180 [(set (match_operand:SF 0 "push_operand" "")
2181 (match_operand:SF 1 "any_fp_register_operand" ""))]
2182 "!TARGET_64BIT"
2183 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2184 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2185
2186 (define_split
2187 [(set (match_operand:SF 0 "push_operand" "")
2188 (match_operand:SF 1 "any_fp_register_operand" ""))]
2189 "TARGET_64BIT"
2190 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2191 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2192
2193 (define_insn "*movsf_1"
2194 [(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")
2195 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2196 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2197 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2198 && (reload_in_progress || reload_completed
2199 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2200 || GET_CODE (operands[1]) != CONST_DOUBLE
2201 || memory_operand (operands[0], SFmode))"
2202 {
2203 switch (which_alternative)
2204 {
2205 case 0:
2206 return output_387_reg_move (insn, operands);
2207
2208 case 1:
2209 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2210 return "fstp%z0\t%y0";
2211 else
2212 return "fst%z0\t%y0";
2213
2214 case 2:
2215 return standard_80387_constant_opcode (operands[1]);
2216
2217 case 3:
2218 case 4:
2219 return "mov{l}\t{%1, %0|%0, %1}";
2220 case 5:
2221 if (get_attr_mode (insn) == MODE_TI)
2222 return "pxor\t%0, %0";
2223 else
2224 return "xorps\t%0, %0";
2225 case 6:
2226 if (get_attr_mode (insn) == MODE_V4SF)
2227 return "movaps\t{%1, %0|%0, %1}";
2228 else
2229 return "movss\t{%1, %0|%0, %1}";
2230 case 7:
2231 case 8:
2232 return "movss\t{%1, %0|%0, %1}";
2233
2234 case 9:
2235 case 10:
2236 return "movd\t{%1, %0|%0, %1}";
2237
2238 case 11:
2239 return "movq\t{%1, %0|%0, %1}";
2240
2241 default:
2242 abort();
2243 }
2244 }
2245 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2246 (set (attr "mode")
2247 (cond [(eq_attr "alternative" "3,4,9,10")
2248 (const_string "SI")
2249 (eq_attr "alternative" "5")
2250 (if_then_else
2251 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2252 (const_int 0))
2253 (ne (symbol_ref "TARGET_SSE2")
2254 (const_int 0)))
2255 (eq (symbol_ref "optimize_size")
2256 (const_int 0)))
2257 (const_string "TI")
2258 (const_string "V4SF"))
2259 /* For architectures resolving dependencies on
2260 whole SSE registers use APS move to break dependency
2261 chains, otherwise use short move to avoid extra work.
2262
2263 Do the same for architectures resolving dependencies on
2264 the parts. While in DF mode it is better to always handle
2265 just register parts, the SF mode is different due to lack
2266 of instructions to load just part of the register. It is
2267 better to maintain the whole registers in single format
2268 to avoid problems on using packed logical operations. */
2269 (eq_attr "alternative" "6")
2270 (if_then_else
2271 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2272 (const_int 0))
2273 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2274 (const_int 0)))
2275 (const_string "V4SF")
2276 (const_string "SF"))
2277 (eq_attr "alternative" "11")
2278 (const_string "DI")]
2279 (const_string "SF")))])
2280
2281 (define_insn "*movsf_1_nointerunit"
2282 [(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")
2283 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2284 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2285 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2286 && (reload_in_progress || reload_completed
2287 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2288 || GET_CODE (operands[1]) != CONST_DOUBLE
2289 || memory_operand (operands[0], SFmode))"
2290 {
2291 switch (which_alternative)
2292 {
2293 case 0:
2294 return output_387_reg_move (insn, operands);
2295
2296 case 1:
2297 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2298 return "fstp%z0\t%y0";
2299 else
2300 return "fst%z0\t%y0";
2301
2302 case 2:
2303 return standard_80387_constant_opcode (operands[1]);
2304
2305 case 3:
2306 case 4:
2307 return "mov{l}\t{%1, %0|%0, %1}";
2308 case 5:
2309 if (get_attr_mode (insn) == MODE_TI)
2310 return "pxor\t%0, %0";
2311 else
2312 return "xorps\t%0, %0";
2313 case 6:
2314 if (get_attr_mode (insn) == MODE_V4SF)
2315 return "movaps\t{%1, %0|%0, %1}";
2316 else
2317 return "movss\t{%1, %0|%0, %1}";
2318 case 7:
2319 case 8:
2320 return "movss\t{%1, %0|%0, %1}";
2321
2322 case 9:
2323 case 10:
2324 return "movd\t{%1, %0|%0, %1}";
2325
2326 case 11:
2327 return "movq\t{%1, %0|%0, %1}";
2328
2329 default:
2330 abort();
2331 }
2332 }
2333 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334 (set (attr "mode")
2335 (cond [(eq_attr "alternative" "3,4,9,10")
2336 (const_string "SI")
2337 (eq_attr "alternative" "5")
2338 (if_then_else
2339 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340 (const_int 0))
2341 (ne (symbol_ref "TARGET_SSE2")
2342 (const_int 0)))
2343 (eq (symbol_ref "optimize_size")
2344 (const_int 0)))
2345 (const_string "TI")
2346 (const_string "V4SF"))
2347 /* For architectures resolving dependencies on
2348 whole SSE registers use APS move to break dependency
2349 chains, otherwise use short move to avoid extra work.
2350
2351 Do the same for architectures resolving dependencies on
2352 the parts. While in DF mode it is better to always handle
2353 just register parts, the SF mode is different due to lack
2354 of instructions to load just part of the register. It is
2355 better to maintain the whole registers in single format
2356 to avoid problems on using packed logical operations. */
2357 (eq_attr "alternative" "6")
2358 (if_then_else
2359 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360 (const_int 0))
2361 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2362 (const_int 0)))
2363 (const_string "V4SF")
2364 (const_string "SF"))
2365 (eq_attr "alternative" "11")
2366 (const_string "DI")]
2367 (const_string "SF")))])
2368
2369 (define_insn "*swapsf"
2370 [(set (match_operand:SF 0 "register_operand" "+f")
2371 (match_operand:SF 1 "register_operand" "+f"))
2372 (set (match_dup 1)
2373 (match_dup 0))]
2374 "reload_completed || !TARGET_SSE"
2375 {
2376 if (STACK_TOP_P (operands[0]))
2377 return "fxch\t%1";
2378 else
2379 return "fxch\t%0";
2380 }
2381 [(set_attr "type" "fxch")
2382 (set_attr "mode" "SF")])
2383
2384 (define_expand "movdf"
2385 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2386 (match_operand:DF 1 "general_operand" ""))]
2387 ""
2388 "ix86_expand_move (DFmode, operands); DONE;")
2389
2390 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2391 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2392 ;; On the average, pushdf using integers can be still shorter. Allow this
2393 ;; pattern for optimize_size too.
2394
2395 (define_insn "*pushdf_nointeger"
2396 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2397 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2398 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 {
2400 /* This insn should be already split before reg-stack. */
2401 abort ();
2402 }
2403 [(set_attr "type" "multi")
2404 (set_attr "mode" "DF,SI,SI,DF")])
2405
2406 (define_insn "*pushdf_integer"
2407 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2410 {
2411 /* This insn should be already split before reg-stack. */
2412 abort ();
2413 }
2414 [(set_attr "type" "multi")
2415 (set_attr "mode" "DF,SI,DF")])
2416
2417 ;; %%% Kill this when call knows how to work this out.
2418 (define_split
2419 [(set (match_operand:DF 0 "push_operand" "")
2420 (match_operand:DF 1 "any_fp_register_operand" ""))]
2421 "!TARGET_64BIT && reload_completed"
2422 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2423 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2424 "")
2425
2426 (define_split
2427 [(set (match_operand:DF 0 "push_operand" "")
2428 (match_operand:DF 1 "any_fp_register_operand" ""))]
2429 "TARGET_64BIT && reload_completed"
2430 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2431 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2432 "")
2433
2434 (define_split
2435 [(set (match_operand:DF 0 "push_operand" "")
2436 (match_operand:DF 1 "general_operand" ""))]
2437 "reload_completed"
2438 [(const_int 0)]
2439 "ix86_split_long_move (operands); DONE;")
2440
2441 ;; Moving is usually shorter when only FP registers are used. This separate
2442 ;; movdf pattern avoids the use of integer registers for FP operations
2443 ;; when optimizing for size.
2444
2445 (define_insn "*movdf_nointeger"
2446 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2447 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2448 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2449 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2450 && (reload_in_progress || reload_completed
2451 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2452 || GET_CODE (operands[1]) != CONST_DOUBLE
2453 || memory_operand (operands[0], DFmode))"
2454 {
2455 switch (which_alternative)
2456 {
2457 case 0:
2458 return output_387_reg_move (insn, operands);
2459
2460 case 1:
2461 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2462 return "fstp%z0\t%y0";
2463 else
2464 return "fst%z0\t%y0";
2465
2466 case 2:
2467 return standard_80387_constant_opcode (operands[1]);
2468
2469 case 3:
2470 case 4:
2471 return "#";
2472 case 5:
2473 switch (get_attr_mode (insn))
2474 {
2475 case MODE_V4SF:
2476 return "xorps\t%0, %0";
2477 case MODE_V2DF:
2478 return "xorpd\t%0, %0";
2479 case MODE_TI:
2480 return "pxor\t%0, %0";
2481 default:
2482 abort ();
2483 }
2484 case 6:
2485 switch (get_attr_mode (insn))
2486 {
2487 case MODE_V4SF:
2488 return "movaps\t{%1, %0|%0, %1}";
2489 case MODE_V2DF:
2490 return "movapd\t{%1, %0|%0, %1}";
2491 case MODE_DF:
2492 return "movsd\t{%1, %0|%0, %1}";
2493 default:
2494 abort ();
2495 }
2496 case 7:
2497 if (get_attr_mode (insn) == MODE_V2DF)
2498 return "movlpd\t{%1, %0|%0, %1}";
2499 else
2500 return "movsd\t{%1, %0|%0, %1}";
2501 case 8:
2502 return "movsd\t{%1, %0|%0, %1}";
2503
2504 default:
2505 abort();
2506 }
2507 }
2508 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2509 (set (attr "mode")
2510 (cond [(eq_attr "alternative" "3,4")
2511 (const_string "SI")
2512 /* xorps is one byte shorter. */
2513 (eq_attr "alternative" "5")
2514 (cond [(ne (symbol_ref "optimize_size")
2515 (const_int 0))
2516 (const_string "V4SF")
2517 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2518 (const_int 0))
2519 (const_string "TI")]
2520 (const_string "V2DF"))
2521 /* For architectures resolving dependencies on
2522 whole SSE registers use APD move to break dependency
2523 chains, otherwise use short move to avoid extra work.
2524
2525 movaps encodes one byte shorter. */
2526 (eq_attr "alternative" "6")
2527 (cond
2528 [(ne (symbol_ref "optimize_size")
2529 (const_int 0))
2530 (const_string "V4SF")
2531 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2532 (const_int 0))
2533 (const_string "V2DF")]
2534 (const_string "DF"))
2535 /* For architectures resolving dependencies on register
2536 parts we may avoid extra work to zero out upper part
2537 of register. */
2538 (eq_attr "alternative" "7")
2539 (if_then_else
2540 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2541 (const_int 0))
2542 (const_string "V2DF")
2543 (const_string "DF"))]
2544 (const_string "DF")))])
2545
2546 (define_insn "*movdf_integer"
2547 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2548 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2549 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2550 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2551 && (reload_in_progress || reload_completed
2552 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2553 || GET_CODE (operands[1]) != CONST_DOUBLE
2554 || memory_operand (operands[0], DFmode))"
2555 {
2556 switch (which_alternative)
2557 {
2558 case 0:
2559 return output_387_reg_move (insn, operands);
2560
2561 case 1:
2562 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2563 return "fstp%z0\t%y0";
2564 else
2565 return "fst%z0\t%y0";
2566
2567 case 2:
2568 return standard_80387_constant_opcode (operands[1]);
2569
2570 case 3:
2571 case 4:
2572 return "#";
2573
2574 case 5:
2575 switch (get_attr_mode (insn))
2576 {
2577 case MODE_V4SF:
2578 return "xorps\t%0, %0";
2579 case MODE_V2DF:
2580 return "xorpd\t%0, %0";
2581 case MODE_TI:
2582 return "pxor\t%0, %0";
2583 default:
2584 abort ();
2585 }
2586 case 6:
2587 switch (get_attr_mode (insn))
2588 {
2589 case MODE_V4SF:
2590 return "movaps\t{%1, %0|%0, %1}";
2591 case MODE_V2DF:
2592 return "movapd\t{%1, %0|%0, %1}";
2593 case MODE_DF:
2594 return "movsd\t{%1, %0|%0, %1}";
2595 default:
2596 abort ();
2597 }
2598 case 7:
2599 if (get_attr_mode (insn) == MODE_V2DF)
2600 return "movlpd\t{%1, %0|%0, %1}";
2601 else
2602 return "movsd\t{%1, %0|%0, %1}";
2603 case 8:
2604 return "movsd\t{%1, %0|%0, %1}";
2605
2606 default:
2607 abort();
2608 }
2609 }
2610 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2611 (set (attr "mode")
2612 (cond [(eq_attr "alternative" "3,4")
2613 (const_string "SI")
2614 /* xorps is one byte shorter. */
2615 (eq_attr "alternative" "5")
2616 (cond [(ne (symbol_ref "optimize_size")
2617 (const_int 0))
2618 (const_string "V4SF")
2619 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2620 (const_int 0))
2621 (const_string "TI")]
2622 (const_string "V2DF"))
2623 /* For architectures resolving dependencies on
2624 whole SSE registers use APD move to break dependency
2625 chains, otherwise use short move to avoid extra work.
2626
2627 movaps encodes one byte shorter. */
2628 (eq_attr "alternative" "6")
2629 (cond
2630 [(ne (symbol_ref "optimize_size")
2631 (const_int 0))
2632 (const_string "V4SF")
2633 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2634 (const_int 0))
2635 (const_string "V2DF")]
2636 (const_string "DF"))
2637 /* For architectures resolving dependencies on register
2638 parts we may avoid extra work to zero out upper part
2639 of register. */
2640 (eq_attr "alternative" "7")
2641 (if_then_else
2642 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2643 (const_int 0))
2644 (const_string "V2DF")
2645 (const_string "DF"))]
2646 (const_string "DF")))])
2647
2648 (define_split
2649 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2650 (match_operand:DF 1 "general_operand" ""))]
2651 "reload_completed
2652 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2653 && ! (ANY_FP_REG_P (operands[0]) ||
2654 (GET_CODE (operands[0]) == SUBREG
2655 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2656 && ! (ANY_FP_REG_P (operands[1]) ||
2657 (GET_CODE (operands[1]) == SUBREG
2658 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2659 [(const_int 0)]
2660 "ix86_split_long_move (operands); DONE;")
2661
2662 (define_insn "*swapdf"
2663 [(set (match_operand:DF 0 "register_operand" "+f")
2664 (match_operand:DF 1 "register_operand" "+f"))
2665 (set (match_dup 1)
2666 (match_dup 0))]
2667 "reload_completed || !TARGET_SSE2"
2668 {
2669 if (STACK_TOP_P (operands[0]))
2670 return "fxch\t%1";
2671 else
2672 return "fxch\t%0";
2673 }
2674 [(set_attr "type" "fxch")
2675 (set_attr "mode" "DF")])
2676
2677 (define_expand "movxf"
2678 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2679 (match_operand:XF 1 "general_operand" ""))]
2680 ""
2681 "ix86_expand_move (XFmode, operands); DONE;")
2682
2683 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2684 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2685 ;; Pushing using integer instructions is longer except for constants
2686 ;; and direct memory references.
2687 ;; (assuming that any given constant is pushed only once, but this ought to be
2688 ;; handled elsewhere).
2689
2690 (define_insn "*pushxf_nointeger"
2691 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2692 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2693 "optimize_size"
2694 {
2695 /* This insn should be already split before reg-stack. */
2696 abort ();
2697 }
2698 [(set_attr "type" "multi")
2699 (set_attr "mode" "XF,SI,SI")])
2700
2701 (define_insn "*pushxf_integer"
2702 [(set (match_operand:XF 0 "push_operand" "=<,<")
2703 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2704 "!optimize_size"
2705 {
2706 /* This insn should be already split before reg-stack. */
2707 abort ();
2708 }
2709 [(set_attr "type" "multi")
2710 (set_attr "mode" "XF,SI")])
2711
2712 (define_split
2713 [(set (match_operand 0 "push_operand" "")
2714 (match_operand 1 "general_operand" ""))]
2715 "reload_completed
2716 && (GET_MODE (operands[0]) == XFmode
2717 || GET_MODE (operands[0]) == DFmode)
2718 && !ANY_FP_REG_P (operands[1])"
2719 [(const_int 0)]
2720 "ix86_split_long_move (operands); DONE;")
2721
2722 (define_split
2723 [(set (match_operand:XF 0 "push_operand" "")
2724 (match_operand:XF 1 "any_fp_register_operand" ""))]
2725 "!TARGET_64BIT"
2726 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2727 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2728 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2729
2730 (define_split
2731 [(set (match_operand:XF 0 "push_operand" "")
2732 (match_operand:XF 1 "any_fp_register_operand" ""))]
2733 "TARGET_64BIT"
2734 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2735 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2736 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2737
2738 ;; Do not use integer registers when optimizing for size
2739 (define_insn "*movxf_nointeger"
2740 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2741 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2742 "optimize_size
2743 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2744 && (reload_in_progress || reload_completed
2745 || GET_CODE (operands[1]) != CONST_DOUBLE
2746 || memory_operand (operands[0], XFmode))"
2747 {
2748 switch (which_alternative)
2749 {
2750 case 0:
2751 return output_387_reg_move (insn, operands);
2752
2753 case 1:
2754 /* There is no non-popping store to memory for XFmode. So if
2755 we need one, follow the store with a load. */
2756 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2757 return "fstp%z0\t%y0\;fld%z0\t%y0";
2758 else
2759 return "fstp%z0\t%y0";
2760
2761 case 2:
2762 return standard_80387_constant_opcode (operands[1]);
2763
2764 case 3: case 4:
2765 return "#";
2766 }
2767 abort();
2768 }
2769 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2770 (set_attr "mode" "XF,XF,XF,SI,SI")])
2771
2772 (define_insn "*movxf_integer"
2773 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2774 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2775 "!optimize_size
2776 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2777 && (reload_in_progress || reload_completed
2778 || GET_CODE (operands[1]) != CONST_DOUBLE
2779 || memory_operand (operands[0], XFmode))"
2780 {
2781 switch (which_alternative)
2782 {
2783 case 0:
2784 return output_387_reg_move (insn, operands);
2785
2786 case 1:
2787 /* There is no non-popping store to memory for XFmode. So if
2788 we need one, follow the store with a load. */
2789 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2790 return "fstp%z0\t%y0\;fld%z0\t%y0";
2791 else
2792 return "fstp%z0\t%y0";
2793
2794 case 2:
2795 return standard_80387_constant_opcode (operands[1]);
2796
2797 case 3: case 4:
2798 return "#";
2799 }
2800 abort();
2801 }
2802 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2803 (set_attr "mode" "XF,XF,XF,SI,SI")])
2804
2805 (define_split
2806 [(set (match_operand 0 "nonimmediate_operand" "")
2807 (match_operand 1 "general_operand" ""))]
2808 "reload_completed
2809 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2810 && GET_MODE (operands[0]) == XFmode
2811 && ! (ANY_FP_REG_P (operands[0]) ||
2812 (GET_CODE (operands[0]) == SUBREG
2813 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2814 && ! (ANY_FP_REG_P (operands[1]) ||
2815 (GET_CODE (operands[1]) == SUBREG
2816 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2817 [(const_int 0)]
2818 "ix86_split_long_move (operands); DONE;")
2819
2820 (define_split
2821 [(set (match_operand 0 "register_operand" "")
2822 (match_operand 1 "memory_operand" ""))]
2823 "reload_completed
2824 && GET_CODE (operands[1]) == MEM
2825 && (GET_MODE (operands[0]) == XFmode
2826 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2827 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2828 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2829 [(set (match_dup 0) (match_dup 1))]
2830 {
2831 rtx c = get_pool_constant (XEXP (operands[1], 0));
2832 rtx r = operands[0];
2833
2834 if (GET_CODE (r) == SUBREG)
2835 r = SUBREG_REG (r);
2836
2837 if (SSE_REG_P (r))
2838 {
2839 if (!standard_sse_constant_p (c))
2840 FAIL;
2841 }
2842 else if (FP_REG_P (r))
2843 {
2844 if (!standard_80387_constant_p (c))
2845 FAIL;
2846 }
2847 else if (MMX_REG_P (r))
2848 FAIL;
2849
2850 operands[1] = c;
2851 })
2852
2853 (define_insn "swapxf"
2854 [(set (match_operand:XF 0 "register_operand" "+f")
2855 (match_operand:XF 1 "register_operand" "+f"))
2856 (set (match_dup 1)
2857 (match_dup 0))]
2858 ""
2859 {
2860 if (STACK_TOP_P (operands[0]))
2861 return "fxch\t%1";
2862 else
2863 return "fxch\t%0";
2864 }
2865 [(set_attr "type" "fxch")
2866 (set_attr "mode" "XF")])
2867 \f
2868 ;; Zero extension instructions
2869
2870 (define_expand "zero_extendhisi2"
2871 [(set (match_operand:SI 0 "register_operand" "")
2872 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2873 ""
2874 {
2875 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2876 {
2877 operands[1] = force_reg (HImode, operands[1]);
2878 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2879 DONE;
2880 }
2881 })
2882
2883 (define_insn "zero_extendhisi2_and"
2884 [(set (match_operand:SI 0 "register_operand" "=r")
2885 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2886 (clobber (reg:CC 17))]
2887 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2888 "#"
2889 [(set_attr "type" "alu1")
2890 (set_attr "mode" "SI")])
2891
2892 (define_split
2893 [(set (match_operand:SI 0 "register_operand" "")
2894 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2895 (clobber (reg:CC 17))]
2896 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2897 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2898 (clobber (reg:CC 17))])]
2899 "")
2900
2901 (define_insn "*zero_extendhisi2_movzwl"
2902 [(set (match_operand:SI 0 "register_operand" "=r")
2903 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2904 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2905 "movz{wl|x}\t{%1, %0|%0, %1}"
2906 [(set_attr "type" "imovx")
2907 (set_attr "mode" "SI")])
2908
2909 (define_expand "zero_extendqihi2"
2910 [(parallel
2911 [(set (match_operand:HI 0 "register_operand" "")
2912 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2913 (clobber (reg:CC 17))])]
2914 ""
2915 "")
2916
2917 (define_insn "*zero_extendqihi2_and"
2918 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2919 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2920 (clobber (reg:CC 17))]
2921 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2922 "#"
2923 [(set_attr "type" "alu1")
2924 (set_attr "mode" "HI")])
2925
2926 (define_insn "*zero_extendqihi2_movzbw_and"
2927 [(set (match_operand:HI 0 "register_operand" "=r,r")
2928 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2929 (clobber (reg:CC 17))]
2930 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2931 "#"
2932 [(set_attr "type" "imovx,alu1")
2933 (set_attr "mode" "HI")])
2934
2935 (define_insn "*zero_extendqihi2_movzbw"
2936 [(set (match_operand:HI 0 "register_operand" "=r")
2937 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2938 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2939 "movz{bw|x}\t{%1, %0|%0, %1}"
2940 [(set_attr "type" "imovx")
2941 (set_attr "mode" "HI")])
2942
2943 ;; For the movzbw case strip only the clobber
2944 (define_split
2945 [(set (match_operand:HI 0 "register_operand" "")
2946 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2947 (clobber (reg:CC 17))]
2948 "reload_completed
2949 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2950 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2951 [(set (match_operand:HI 0 "register_operand" "")
2952 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2953
2954 ;; When source and destination does not overlap, clear destination
2955 ;; first and then do the movb
2956 (define_split
2957 [(set (match_operand:HI 0 "register_operand" "")
2958 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2959 (clobber (reg:CC 17))]
2960 "reload_completed
2961 && ANY_QI_REG_P (operands[0])
2962 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2963 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2964 [(set (match_dup 0) (const_int 0))
2965 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2966 "operands[2] = gen_lowpart (QImode, operands[0]);")
2967
2968 ;; Rest is handled by single and.
2969 (define_split
2970 [(set (match_operand:HI 0 "register_operand" "")
2971 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2972 (clobber (reg:CC 17))]
2973 "reload_completed
2974 && true_regnum (operands[0]) == true_regnum (operands[1])"
2975 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2976 (clobber (reg:CC 17))])]
2977 "")
2978
2979 (define_expand "zero_extendqisi2"
2980 [(parallel
2981 [(set (match_operand:SI 0 "register_operand" "")
2982 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2983 (clobber (reg:CC 17))])]
2984 ""
2985 "")
2986
2987 (define_insn "*zero_extendqisi2_and"
2988 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2989 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2990 (clobber (reg:CC 17))]
2991 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2992 "#"
2993 [(set_attr "type" "alu1")
2994 (set_attr "mode" "SI")])
2995
2996 (define_insn "*zero_extendqisi2_movzbw_and"
2997 [(set (match_operand:SI 0 "register_operand" "=r,r")
2998 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2999 (clobber (reg:CC 17))]
3000 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3001 "#"
3002 [(set_attr "type" "imovx,alu1")
3003 (set_attr "mode" "SI")])
3004
3005 (define_insn "*zero_extendqisi2_movzbw"
3006 [(set (match_operand:SI 0 "register_operand" "=r")
3007 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3008 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3009 "movz{bl|x}\t{%1, %0|%0, %1}"
3010 [(set_attr "type" "imovx")
3011 (set_attr "mode" "SI")])
3012
3013 ;; For the movzbl case strip only the clobber
3014 (define_split
3015 [(set (match_operand:SI 0 "register_operand" "")
3016 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3017 (clobber (reg:CC 17))]
3018 "reload_completed
3019 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3020 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3021 [(set (match_dup 0)
3022 (zero_extend:SI (match_dup 1)))])
3023
3024 ;; When source and destination does not overlap, clear destination
3025 ;; first and then do the movb
3026 (define_split
3027 [(set (match_operand:SI 0 "register_operand" "")
3028 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3029 (clobber (reg:CC 17))]
3030 "reload_completed
3031 && ANY_QI_REG_P (operands[0])
3032 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3033 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3034 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3035 [(set (match_dup 0) (const_int 0))
3036 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3037 "operands[2] = gen_lowpart (QImode, operands[0]);")
3038
3039 ;; Rest is handled by single and.
3040 (define_split
3041 [(set (match_operand:SI 0 "register_operand" "")
3042 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3043 (clobber (reg:CC 17))]
3044 "reload_completed
3045 && true_regnum (operands[0]) == true_regnum (operands[1])"
3046 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3047 (clobber (reg:CC 17))])]
3048 "")
3049
3050 ;; %%% Kill me once multi-word ops are sane.
3051 (define_expand "zero_extendsidi2"
3052 [(set (match_operand:DI 0 "register_operand" "=r")
3053 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3054 ""
3055 "if (!TARGET_64BIT)
3056 {
3057 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3058 DONE;
3059 }
3060 ")
3061
3062 (define_insn "zero_extendsidi2_32"
3063 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3064 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3065 (clobber (reg:CC 17))]
3066 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3067 "@
3068 #
3069 #
3070 #
3071 movd\t{%1, %0|%0, %1}
3072 movd\t{%1, %0|%0, %1}"
3073 [(set_attr "mode" "SI,SI,SI,DI,TI")
3074 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3075
3076 (define_insn "*zero_extendsidi2_32_1"
3077 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3078 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3079 (clobber (reg:CC 17))]
3080 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3081 "@
3082 #
3083 #
3084 #
3085 movd\t{%1, %0|%0, %1}
3086 movd\t{%1, %0|%0, %1}"
3087 [(set_attr "mode" "SI,SI,SI,DI,TI")
3088 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3089
3090 (define_insn "zero_extendsidi2_rex64"
3091 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3092 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3093 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3094 "@
3095 mov\t{%k1, %k0|%k0, %k1}
3096 #
3097 movd\t{%1, %0|%0, %1}
3098 movd\t{%1, %0|%0, %1}"
3099 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3100 (set_attr "mode" "SI,DI,DI,TI")])
3101
3102 (define_insn "*zero_extendsidi2_rex64_1"
3103 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3104 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3105 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3106 "@
3107 mov\t{%k1, %k0|%k0, %k1}
3108 #
3109 movd\t{%1, %0|%0, %1}
3110 movd\t{%1, %0|%0, %1}"
3111 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3112 (set_attr "mode" "SI,DI,SI,SI")])
3113
3114 (define_split
3115 [(set (match_operand:DI 0 "memory_operand" "")
3116 (zero_extend:DI (match_dup 0)))]
3117 "TARGET_64BIT"
3118 [(set (match_dup 4) (const_int 0))]
3119 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3120
3121 (define_split
3122 [(set (match_operand:DI 0 "register_operand" "")
3123 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3124 (clobber (reg:CC 17))]
3125 "!TARGET_64BIT && reload_completed
3126 && true_regnum (operands[0]) == true_regnum (operands[1])"
3127 [(set (match_dup 4) (const_int 0))]
3128 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3129
3130 (define_split
3131 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3132 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3133 (clobber (reg:CC 17))]
3134 "!TARGET_64BIT && reload_completed
3135 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3136 [(set (match_dup 3) (match_dup 1))
3137 (set (match_dup 4) (const_int 0))]
3138 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3139
3140 (define_insn "zero_extendhidi2"
3141 [(set (match_operand:DI 0 "register_operand" "=r,r")
3142 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3143 "TARGET_64BIT"
3144 "@
3145 movz{wl|x}\t{%1, %k0|%k0, %1}
3146 movz{wq|x}\t{%1, %0|%0, %1}"
3147 [(set_attr "type" "imovx")
3148 (set_attr "mode" "SI,DI")])
3149
3150 (define_insn "zero_extendqidi2"
3151 [(set (match_operand:DI 0 "register_operand" "=r,r")
3152 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3153 "TARGET_64BIT"
3154 "@
3155 movz{bl|x}\t{%1, %k0|%k0, %1}
3156 movz{bq|x}\t{%1, %0|%0, %1}"
3157 [(set_attr "type" "imovx")
3158 (set_attr "mode" "SI,DI")])
3159 \f
3160 ;; Sign extension instructions
3161
3162 (define_expand "extendsidi2"
3163 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3164 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3165 (clobber (reg:CC 17))
3166 (clobber (match_scratch:SI 2 ""))])]
3167 ""
3168 {
3169 if (TARGET_64BIT)
3170 {
3171 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3172 DONE;
3173 }
3174 })
3175
3176 (define_insn "*extendsidi2_1"
3177 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3178 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3179 (clobber (reg:CC 17))
3180 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3181 "!TARGET_64BIT"
3182 "#")
3183
3184 (define_insn "extendsidi2_rex64"
3185 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3186 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3187 "TARGET_64BIT"
3188 "@
3189 {cltq|cdqe}
3190 movs{lq|x}\t{%1,%0|%0, %1}"
3191 [(set_attr "type" "imovx")
3192 (set_attr "mode" "DI")
3193 (set_attr "prefix_0f" "0")
3194 (set_attr "modrm" "0,1")])
3195
3196 (define_insn "extendhidi2"
3197 [(set (match_operand:DI 0 "register_operand" "=r")
3198 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3199 "TARGET_64BIT"
3200 "movs{wq|x}\t{%1,%0|%0, %1}"
3201 [(set_attr "type" "imovx")
3202 (set_attr "mode" "DI")])
3203
3204 (define_insn "extendqidi2"
3205 [(set (match_operand:DI 0 "register_operand" "=r")
3206 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3207 "TARGET_64BIT"
3208 "movs{bq|x}\t{%1,%0|%0, %1}"
3209 [(set_attr "type" "imovx")
3210 (set_attr "mode" "DI")])
3211
3212 ;; Extend to memory case when source register does die.
3213 (define_split
3214 [(set (match_operand:DI 0 "memory_operand" "")
3215 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3216 (clobber (reg:CC 17))
3217 (clobber (match_operand:SI 2 "register_operand" ""))]
3218 "(reload_completed
3219 && dead_or_set_p (insn, operands[1])
3220 && !reg_mentioned_p (operands[1], operands[0]))"
3221 [(set (match_dup 3) (match_dup 1))
3222 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3223 (clobber (reg:CC 17))])
3224 (set (match_dup 4) (match_dup 1))]
3225 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3226
3227 ;; Extend to memory case when source register does not die.
3228 (define_split
3229 [(set (match_operand:DI 0 "memory_operand" "")
3230 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3231 (clobber (reg:CC 17))
3232 (clobber (match_operand:SI 2 "register_operand" ""))]
3233 "reload_completed"
3234 [(const_int 0)]
3235 {
3236 split_di (&operands[0], 1, &operands[3], &operands[4]);
3237
3238 emit_move_insn (operands[3], operands[1]);
3239
3240 /* Generate a cltd if possible and doing so it profitable. */
3241 if (true_regnum (operands[1]) == 0
3242 && true_regnum (operands[2]) == 1
3243 && (optimize_size || TARGET_USE_CLTD))
3244 {
3245 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3246 }
3247 else
3248 {
3249 emit_move_insn (operands[2], operands[1]);
3250 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3251 }
3252 emit_move_insn (operands[4], operands[2]);
3253 DONE;
3254 })
3255
3256 ;; Extend to register case. Optimize case where source and destination
3257 ;; registers match and cases where we can use cltd.
3258 (define_split
3259 [(set (match_operand:DI 0 "register_operand" "")
3260 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3261 (clobber (reg:CC 17))
3262 (clobber (match_scratch:SI 2 ""))]
3263 "reload_completed"
3264 [(const_int 0)]
3265 {
3266 split_di (&operands[0], 1, &operands[3], &operands[4]);
3267
3268 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3269 emit_move_insn (operands[3], operands[1]);
3270
3271 /* Generate a cltd if possible and doing so it profitable. */
3272 if (true_regnum (operands[3]) == 0
3273 && (optimize_size || TARGET_USE_CLTD))
3274 {
3275 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3276 DONE;
3277 }
3278
3279 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3280 emit_move_insn (operands[4], operands[1]);
3281
3282 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3283 DONE;
3284 })
3285
3286 (define_insn "extendhisi2"
3287 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3288 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3289 ""
3290 {
3291 switch (get_attr_prefix_0f (insn))
3292 {
3293 case 0:
3294 return "{cwtl|cwde}";
3295 default:
3296 return "movs{wl|x}\t{%1,%0|%0, %1}";
3297 }
3298 }
3299 [(set_attr "type" "imovx")
3300 (set_attr "mode" "SI")
3301 (set (attr "prefix_0f")
3302 ;; movsx is short decodable while cwtl is vector decoded.
3303 (if_then_else (and (eq_attr "cpu" "!k6")
3304 (eq_attr "alternative" "0"))
3305 (const_string "0")
3306 (const_string "1")))
3307 (set (attr "modrm")
3308 (if_then_else (eq_attr "prefix_0f" "0")
3309 (const_string "0")
3310 (const_string "1")))])
3311
3312 (define_insn "*extendhisi2_zext"
3313 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3314 (zero_extend:DI
3315 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3316 "TARGET_64BIT"
3317 {
3318 switch (get_attr_prefix_0f (insn))
3319 {
3320 case 0:
3321 return "{cwtl|cwde}";
3322 default:
3323 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3324 }
3325 }
3326 [(set_attr "type" "imovx")
3327 (set_attr "mode" "SI")
3328 (set (attr "prefix_0f")
3329 ;; movsx is short decodable while cwtl is vector decoded.
3330 (if_then_else (and (eq_attr "cpu" "!k6")
3331 (eq_attr "alternative" "0"))
3332 (const_string "0")
3333 (const_string "1")))
3334 (set (attr "modrm")
3335 (if_then_else (eq_attr "prefix_0f" "0")
3336 (const_string "0")
3337 (const_string "1")))])
3338
3339 (define_insn "extendqihi2"
3340 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3341 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3342 ""
3343 {
3344 switch (get_attr_prefix_0f (insn))
3345 {
3346 case 0:
3347 return "{cbtw|cbw}";
3348 default:
3349 return "movs{bw|x}\t{%1,%0|%0, %1}";
3350 }
3351 }
3352 [(set_attr "type" "imovx")
3353 (set_attr "mode" "HI")
3354 (set (attr "prefix_0f")
3355 ;; movsx is short decodable while cwtl is vector decoded.
3356 (if_then_else (and (eq_attr "cpu" "!k6")
3357 (eq_attr "alternative" "0"))
3358 (const_string "0")
3359 (const_string "1")))
3360 (set (attr "modrm")
3361 (if_then_else (eq_attr "prefix_0f" "0")
3362 (const_string "0")
3363 (const_string "1")))])
3364
3365 (define_insn "extendqisi2"
3366 [(set (match_operand:SI 0 "register_operand" "=r")
3367 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3368 ""
3369 "movs{bl|x}\t{%1,%0|%0, %1}"
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI")])
3372
3373 (define_insn "*extendqisi2_zext"
3374 [(set (match_operand:DI 0 "register_operand" "=r")
3375 (zero_extend:DI
3376 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3377 "TARGET_64BIT"
3378 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3379 [(set_attr "type" "imovx")
3380 (set_attr "mode" "SI")])
3381 \f
3382 ;; Conversions between float and double.
3383
3384 ;; These are all no-ops in the model used for the 80387. So just
3385 ;; emit moves.
3386
3387 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3388 (define_insn "*dummy_extendsfdf2"
3389 [(set (match_operand:DF 0 "push_operand" "=<")
3390 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3391 "0"
3392 "#")
3393
3394 (define_split
3395 [(set (match_operand:DF 0 "push_operand" "")
3396 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3397 "!TARGET_64BIT"
3398 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3399 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3400
3401 (define_split
3402 [(set (match_operand:DF 0 "push_operand" "")
3403 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3404 "TARGET_64BIT"
3405 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3406 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3407
3408 (define_insn "*dummy_extendsfxf2"
3409 [(set (match_operand:XF 0 "push_operand" "=<")
3410 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3411 "0"
3412 "#")
3413
3414 (define_split
3415 [(set (match_operand:XF 0 "push_operand" "")
3416 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3417 ""
3418 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3419 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3420 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3421
3422 (define_split
3423 [(set (match_operand:XF 0 "push_operand" "")
3424 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3425 "TARGET_64BIT"
3426 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3427 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3428 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3429
3430 (define_split
3431 [(set (match_operand:XF 0 "push_operand" "")
3432 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3433 ""
3434 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3435 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3436 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3437
3438 (define_split
3439 [(set (match_operand:XF 0 "push_operand" "")
3440 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3441 "TARGET_64BIT"
3442 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3443 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3444 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3445
3446 (define_expand "extendsfdf2"
3447 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3448 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3449 "TARGET_80387 || TARGET_SSE2"
3450 {
3451 /* ??? Needed for compress_float_constant since all fp constants
3452 are LEGITIMATE_CONSTANT_P. */
3453 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3454 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3455 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3456 operands[1] = force_reg (SFmode, operands[1]);
3457 })
3458
3459 (define_insn "*extendsfdf2_1"
3460 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3461 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3462 "(TARGET_80387 || TARGET_SSE2)
3463 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3464 {
3465 switch (which_alternative)
3466 {
3467 case 0:
3468 return output_387_reg_move (insn, operands);
3469
3470 case 1:
3471 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3472 return "fstp%z0\t%y0";
3473 else
3474 return "fst%z0\t%y0";
3475
3476 case 2:
3477 return "cvtss2sd\t{%1, %0|%0, %1}";
3478
3479 default:
3480 abort ();
3481 }
3482 }
3483 [(set_attr "type" "fmov,fmov,ssecvt")
3484 (set_attr "mode" "SF,XF,DF")])
3485
3486 (define_insn "*extendsfdf2_1_sse_only"
3487 [(set (match_operand:DF 0 "register_operand" "=Y")
3488 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3489 "!TARGET_80387 && TARGET_SSE2
3490 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3491 "cvtss2sd\t{%1, %0|%0, %1}"
3492 [(set_attr "type" "ssecvt")
3493 (set_attr "mode" "DF")])
3494
3495 (define_expand "extendsfxf2"
3496 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3497 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3498 "TARGET_80387"
3499 {
3500 /* ??? Needed for compress_float_constant since all fp constants
3501 are LEGITIMATE_CONSTANT_P. */
3502 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3503 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3504 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3505 operands[1] = force_reg (SFmode, operands[1]);
3506 })
3507
3508 (define_insn "*extendsfxf2_1"
3509 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3510 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3511 "TARGET_80387
3512 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3513 {
3514 switch (which_alternative)
3515 {
3516 case 0:
3517 return output_387_reg_move (insn, operands);
3518
3519 case 1:
3520 /* There is no non-popping store to memory for XFmode. So if
3521 we need one, follow the store with a load. */
3522 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3523 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3524 else
3525 return "fstp%z0\t%y0";
3526
3527 default:
3528 abort ();
3529 }
3530 }
3531 [(set_attr "type" "fmov")
3532 (set_attr "mode" "SF,XF")])
3533
3534 (define_expand "extenddfxf2"
3535 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3536 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3537 "TARGET_80387"
3538 {
3539 /* ??? Needed for compress_float_constant since all fp constants
3540 are LEGITIMATE_CONSTANT_P. */
3541 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3542 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3543 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3544 operands[1] = force_reg (DFmode, operands[1]);
3545 })
3546
3547 (define_insn "*extenddfxf2_1"
3548 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3549 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3550 "TARGET_80387
3551 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3552 {
3553 switch (which_alternative)
3554 {
3555 case 0:
3556 return output_387_reg_move (insn, operands);
3557
3558 case 1:
3559 /* There is no non-popping store to memory for XFmode. So if
3560 we need one, follow the store with a load. */
3561 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3562 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3563 else
3564 return "fstp%z0\t%y0";
3565
3566 default:
3567 abort ();
3568 }
3569 }
3570 [(set_attr "type" "fmov")
3571 (set_attr "mode" "DF,XF")])
3572
3573 ;; %%% This seems bad bad news.
3574 ;; This cannot output into an f-reg because there is no way to be sure
3575 ;; of truncating in that case. Otherwise this is just like a simple move
3576 ;; insn. So we pretend we can output to a reg in order to get better
3577 ;; register preferencing, but we really use a stack slot.
3578
3579 (define_expand "truncdfsf2"
3580 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3581 (float_truncate:SF
3582 (match_operand:DF 1 "register_operand" "")))
3583 (clobber (match_dup 2))])]
3584 "TARGET_80387 || TARGET_SSE2"
3585 "
3586 if (!TARGET_80387)
3587 {
3588 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3589 DONE;
3590 }
3591 else if (flag_unsafe_math_optimizations)
3592 {
3593 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3594 emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3595 if (reg != operands[0])
3596 emit_move_insn (operands[0], reg);
3597 DONE;
3598 }
3599 else
3600 operands[2] = assign_386_stack_local (SFmode, 0);
3601 ")
3602
3603 (define_insn "truncdfsf2_noop"
3604 [(set (match_operand:SF 0 "register_operand" "=f")
3605 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3606 "TARGET_80387 && flag_unsafe_math_optimizations"
3607 {
3608 return output_387_reg_move (insn, operands);
3609 }
3610 [(set_attr "type" "fmov")
3611 (set_attr "mode" "SF")])
3612
3613 (define_insn "*truncdfsf2_1"
3614 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3615 (float_truncate:SF
3616 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3617 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3618 "TARGET_80387 && !TARGET_SSE2"
3619 {
3620 switch (which_alternative)
3621 {
3622 case 0:
3623 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624 return "fstp%z0\t%y0";
3625 else
3626 return "fst%z0\t%y0";
3627 default:
3628 abort ();
3629 }
3630 }
3631 [(set_attr "type" "fmov,multi,multi,multi")
3632 (set_attr "mode" "SF,SF,SF,SF")])
3633
3634 (define_insn "*truncdfsf2_1_sse"
3635 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3636 (float_truncate:SF
3637 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3638 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3639 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3640 {
3641 switch (which_alternative)
3642 {
3643 case 0:
3644 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3645 return "fstp%z0\t%y0";
3646 else
3647 return "fst%z0\t%y0";
3648 case 4:
3649 return "#";
3650 default:
3651 abort ();
3652 }
3653 }
3654 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3655 (set_attr "mode" "SF,SF,SF,SF,DF")])
3656
3657 (define_insn "*truncdfsf2_1_sse_nooverlap"
3658 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3659 (float_truncate:SF
3660 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3661 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3662 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3663 {
3664 switch (which_alternative)
3665 {
3666 case 0:
3667 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668 return "fstp%z0\t%y0";
3669 else
3670 return "fst%z0\t%y0";
3671 case 4:
3672 return "#";
3673 default:
3674 abort ();
3675 }
3676 }
3677 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3678 (set_attr "mode" "SF,SF,SF,SF,DF")])
3679
3680 (define_insn "*truncdfsf2_2"
3681 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3682 (float_truncate:SF
3683 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3684 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3685 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3686 {
3687 switch (which_alternative)
3688 {
3689 case 0:
3690 case 1:
3691 return "cvtsd2ss\t{%1, %0|%0, %1}";
3692 case 2:
3693 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3694 return "fstp%z0\t%y0";
3695 else
3696 return "fst%z0\t%y0";
3697 default:
3698 abort ();
3699 }
3700 }
3701 [(set_attr "type" "ssecvt,ssecvt,fmov")
3702 (set_attr "athlon_decode" "vector,double,*")
3703 (set_attr "mode" "SF,SF,SF")])
3704
3705 (define_insn "*truncdfsf2_2_nooverlap"
3706 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3707 (float_truncate:SF
3708 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3709 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3710 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3711 {
3712 switch (which_alternative)
3713 {
3714 case 0:
3715 return "#";
3716 case 1:
3717 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3718 return "fstp%z0\t%y0";
3719 else
3720 return "fst%z0\t%y0";
3721 default:
3722 abort ();
3723 }
3724 }
3725 [(set_attr "type" "ssecvt,fmov")
3726 (set_attr "mode" "DF,SF")])
3727
3728 (define_insn "*truncdfsf2_3"
3729 [(set (match_operand:SF 0 "memory_operand" "=m")
3730 (float_truncate:SF
3731 (match_operand:DF 1 "register_operand" "f")))]
3732 "TARGET_80387"
3733 {
3734 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3735 return "fstp%z0\t%y0";
3736 else
3737 return "fst%z0\t%y0";
3738 }
3739 [(set_attr "type" "fmov")
3740 (set_attr "mode" "SF")])
3741
3742 (define_insn "truncdfsf2_sse_only"
3743 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3744 (float_truncate:SF
3745 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3746 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3747 "cvtsd2ss\t{%1, %0|%0, %1}"
3748 [(set_attr "type" "ssecvt")
3749 (set_attr "athlon_decode" "vector,double")
3750 (set_attr "mode" "SF")])
3751
3752 (define_insn "*truncdfsf2_sse_only_nooverlap"
3753 [(set (match_operand:SF 0 "register_operand" "=&Y")
3754 (float_truncate:SF
3755 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3756 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3757 "#"
3758 [(set_attr "type" "ssecvt")
3759 (set_attr "mode" "DF")])
3760
3761 (define_split
3762 [(set (match_operand:SF 0 "memory_operand" "")
3763 (float_truncate:SF
3764 (match_operand:DF 1 "register_operand" "")))
3765 (clobber (match_operand:SF 2 "memory_operand" ""))]
3766 "TARGET_80387"
3767 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3768 "")
3769
3770 ; Avoid possible reformatting penalty on the destination by first
3771 ; zeroing it out
3772 (define_split
3773 [(set (match_operand:SF 0 "register_operand" "")
3774 (float_truncate:SF
3775 (match_operand:DF 1 "nonimmediate_operand" "")))
3776 (clobber (match_operand 2 "" ""))]
3777 "TARGET_80387 && reload_completed
3778 && SSE_REG_P (operands[0])
3779 && !STACK_REG_P (operands[1])"
3780 [(const_int 0)]
3781 {
3782 rtx src, dest;
3783 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3784 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3785 else
3786 {
3787 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3788 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3789 /* simplify_gen_subreg refuses to widen memory references. */
3790 if (GET_CODE (src) == SUBREG)
3791 alter_subreg (&src);
3792 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3793 abort ();
3794 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3795 emit_insn (gen_cvtsd2ss (dest, dest, src));
3796 }
3797 DONE;
3798 })
3799
3800 (define_split
3801 [(set (match_operand:SF 0 "register_operand" "")
3802 (float_truncate:SF
3803 (match_operand:DF 1 "nonimmediate_operand" "")))]
3804 "TARGET_80387 && reload_completed
3805 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3806 [(const_int 0)]
3807 {
3808 rtx src, dest;
3809 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3810 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3811 /* simplify_gen_subreg refuses to widen memory references. */
3812 if (GET_CODE (src) == SUBREG)
3813 alter_subreg (&src);
3814 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3815 abort ();
3816 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3817 emit_insn (gen_cvtsd2ss (dest, dest, src));
3818 DONE;
3819 })
3820
3821 (define_split
3822 [(set (match_operand:SF 0 "register_operand" "")
3823 (float_truncate:SF
3824 (match_operand:DF 1 "fp_register_operand" "")))
3825 (clobber (match_operand:SF 2 "memory_operand" ""))]
3826 "TARGET_80387 && reload_completed"
3827 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3828 (set (match_dup 0) (match_dup 2))]
3829 "")
3830
3831 (define_expand "truncxfsf2"
3832 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3833 (float_truncate:SF
3834 (match_operand:XF 1 "register_operand" "")))
3835 (clobber (match_dup 2))])]
3836 "TARGET_80387"
3837 "
3838 if (flag_unsafe_math_optimizations)
3839 {
3840 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3841 emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3842 if (reg != operands[0])
3843 emit_move_insn (operands[0], reg);
3844 DONE;
3845 }
3846 else
3847 operands[2] = assign_386_stack_local (SFmode, 0);
3848 ")
3849
3850 (define_insn "truncxfsf2_noop"
3851 [(set (match_operand:SF 0 "register_operand" "=f")
3852 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3853 "TARGET_80387 && flag_unsafe_math_optimizations"
3854 {
3855 return output_387_reg_move (insn, operands);
3856 }
3857 [(set_attr "type" "fmov")
3858 (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncxfsf2_1"
3861 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3862 (float_truncate:SF
3863 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3864 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3865 "TARGET_80387"
3866 {
3867 switch (which_alternative)
3868 {
3869 case 0:
3870 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3871 return "fstp%z0\t%y0";
3872 else
3873 return "fst%z0\t%y0";
3874 default:
3875 abort();
3876 }
3877 }
3878 [(set_attr "type" "fmov,multi,multi,multi")
3879 (set_attr "mode" "SF")])
3880
3881 (define_insn "*truncxfsf2_2"
3882 [(set (match_operand:SF 0 "memory_operand" "=m")
3883 (float_truncate:SF
3884 (match_operand:XF 1 "register_operand" "f")))]
3885 "TARGET_80387"
3886 {
3887 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3888 return "fstp%z0\t%y0";
3889 else
3890 return "fst%z0\t%y0";
3891 }
3892 [(set_attr "type" "fmov")
3893 (set_attr "mode" "SF")])
3894
3895 (define_split
3896 [(set (match_operand:SF 0 "memory_operand" "")
3897 (float_truncate:SF
3898 (match_operand:XF 1 "register_operand" "")))
3899 (clobber (match_operand:SF 2 "memory_operand" ""))]
3900 "TARGET_80387"
3901 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3902 "")
3903
3904 (define_split
3905 [(set (match_operand:SF 0 "register_operand" "")
3906 (float_truncate:SF
3907 (match_operand:XF 1 "register_operand" "")))
3908 (clobber (match_operand:SF 2 "memory_operand" ""))]
3909 "TARGET_80387 && reload_completed"
3910 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3911 (set (match_dup 0) (match_dup 2))]
3912 "")
3913
3914 (define_expand "truncxfdf2"
3915 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3916 (float_truncate:DF
3917 (match_operand:XF 1 "register_operand" "")))
3918 (clobber (match_dup 2))])]
3919 "TARGET_80387"
3920 "
3921 if (flag_unsafe_math_optimizations)
3922 {
3923 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3924 emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3925 if (reg != operands[0])
3926 emit_move_insn (operands[0], reg);
3927 DONE;
3928 }
3929 else
3930 operands[2] = assign_386_stack_local (DFmode, 0);
3931 ")
3932
3933 (define_insn "truncxfdf2_noop"
3934 [(set (match_operand:DF 0 "register_operand" "=f")
3935 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3936 "TARGET_80387 && flag_unsafe_math_optimizations"
3937 {
3938 return output_387_reg_move (insn, operands);
3939 }
3940 [(set_attr "type" "fmov")
3941 (set_attr "mode" "DF")])
3942
3943 (define_insn "*truncxfdf2_1"
3944 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3945 (float_truncate:DF
3946 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3947 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3948 "TARGET_80387"
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 default:
3958 abort();
3959 }
3960 abort ();
3961 }
3962 [(set_attr "type" "fmov,multi,multi,multi")
3963 (set_attr "mode" "DF")])
3964
3965 (define_insn "*truncxfdf2_2"
3966 [(set (match_operand:DF 0 "memory_operand" "=m")
3967 (float_truncate:DF
3968 (match_operand:XF 1 "register_operand" "f")))]
3969 "TARGET_80387"
3970 {
3971 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3972 return "fstp%z0\t%y0";
3973 else
3974 return "fst%z0\t%y0";
3975 }
3976 [(set_attr "type" "fmov")
3977 (set_attr "mode" "DF")])
3978
3979 (define_split
3980 [(set (match_operand:DF 0 "memory_operand" "")
3981 (float_truncate:DF
3982 (match_operand:XF 1 "register_operand" "")))
3983 (clobber (match_operand:DF 2 "memory_operand" ""))]
3984 "TARGET_80387"
3985 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3986 "")
3987
3988 (define_split
3989 [(set (match_operand:DF 0 "register_operand" "")
3990 (float_truncate:DF
3991 (match_operand:XF 1 "register_operand" "")))
3992 (clobber (match_operand:DF 2 "memory_operand" ""))]
3993 "TARGET_80387 && reload_completed"
3994 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3995 (set (match_dup 0) (match_dup 2))]
3996 "")
3997
3998 \f
3999 ;; %%% Break up all these bad boys.
4000
4001 ;; Signed conversion to DImode.
4002
4003 (define_expand "fix_truncxfdi2"
4004 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4005 (fix:DI (match_operand:XF 1 "register_operand" "")))
4006 (clobber (reg:CC 17))])]
4007 "TARGET_80387"
4008 "")
4009
4010 (define_expand "fix_truncdfdi2"
4011 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4012 (fix:DI (match_operand:DF 1 "register_operand" "")))
4013 (clobber (reg:CC 17))])]
4014 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4015 {
4016 if (TARGET_64BIT && TARGET_SSE2)
4017 {
4018 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4019 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4020 if (out != operands[0])
4021 emit_move_insn (operands[0], out);
4022 DONE;
4023 }
4024 })
4025
4026 (define_expand "fix_truncsfdi2"
4027 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028 (fix:DI (match_operand:SF 1 "register_operand" "")))
4029 (clobber (reg:CC 17))])]
4030 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4031 {
4032 if (TARGET_SSE && TARGET_64BIT)
4033 {
4034 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4035 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4036 if (out != operands[0])
4037 emit_move_insn (operands[0], out);
4038 DONE;
4039 }
4040 })
4041
4042 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4043 ;; of the machinery.
4044 (define_insn_and_split "*fix_truncdi_1"
4045 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4046 (fix:DI (match_operand 1 "register_operand" "f,f")))
4047 (clobber (reg:CC 17))]
4048 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4049 && !reload_completed && !reload_in_progress
4050 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4051 "#"
4052 "&& 1"
4053 [(const_int 0)]
4054 {
4055 ix86_optimize_mode_switching = 1;
4056 operands[2] = assign_386_stack_local (HImode, 1);
4057 operands[3] = assign_386_stack_local (HImode, 2);
4058 if (memory_operand (operands[0], VOIDmode))
4059 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4060 operands[2], operands[3]));
4061 else
4062 {
4063 operands[4] = assign_386_stack_local (DImode, 0);
4064 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4065 operands[2], operands[3],
4066 operands[4]));
4067 }
4068 DONE;
4069 }
4070 [(set_attr "type" "fistp")
4071 (set_attr "mode" "DI")])
4072
4073 (define_insn "fix_truncdi_nomemory"
4074 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4075 (fix:DI (match_operand 1 "register_operand" "f,f")))
4076 (use (match_operand:HI 2 "memory_operand" "m,m"))
4077 (use (match_operand:HI 3 "memory_operand" "m,m"))
4078 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4079 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4080 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4081 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4082 "#"
4083 [(set_attr "type" "fistp")
4084 (set_attr "mode" "DI")])
4085
4086 (define_insn "fix_truncdi_memory"
4087 [(set (match_operand:DI 0 "memory_operand" "=m")
4088 (fix:DI (match_operand 1 "register_operand" "f")))
4089 (use (match_operand:HI 2 "memory_operand" "m"))
4090 (use (match_operand:HI 3 "memory_operand" "m"))
4091 (clobber (match_scratch:DF 4 "=&1f"))]
4092 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4093 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4094 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4095 [(set_attr "type" "fistp")
4096 (set_attr "mode" "DI")])
4097
4098 (define_split
4099 [(set (match_operand:DI 0 "register_operand" "")
4100 (fix:DI (match_operand 1 "register_operand" "")))
4101 (use (match_operand:HI 2 "memory_operand" ""))
4102 (use (match_operand:HI 3 "memory_operand" ""))
4103 (clobber (match_operand:DI 4 "memory_operand" ""))
4104 (clobber (match_scratch 5 ""))]
4105 "reload_completed"
4106 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4107 (use (match_dup 2))
4108 (use (match_dup 3))
4109 (clobber (match_dup 5))])
4110 (set (match_dup 0) (match_dup 4))]
4111 "")
4112
4113 (define_split
4114 [(set (match_operand:DI 0 "memory_operand" "")
4115 (fix:DI (match_operand 1 "register_operand" "")))
4116 (use (match_operand:HI 2 "memory_operand" ""))
4117 (use (match_operand:HI 3 "memory_operand" ""))
4118 (clobber (match_operand:DI 4 "memory_operand" ""))
4119 (clobber (match_scratch 5 ""))]
4120 "reload_completed"
4121 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4122 (use (match_dup 2))
4123 (use (match_dup 3))
4124 (clobber (match_dup 5))])]
4125 "")
4126
4127 ;; When SSE available, it is always faster to use it!
4128 (define_insn "fix_truncsfdi_sse"
4129 [(set (match_operand:DI 0 "register_operand" "=r,r")
4130 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4131 "TARGET_64BIT && TARGET_SSE"
4132 "cvttss2si{q}\t{%1, %0|%0, %1}"
4133 [(set_attr "type" "sseicvt")
4134 (set_attr "mode" "SF")
4135 (set_attr "athlon_decode" "double,vector")])
4136
4137 ;; Avoid vector decoded form of the instruction.
4138 (define_peephole2
4139 [(match_scratch:SF 2 "x")
4140 (set (match_operand:DI 0 "register_operand" "")
4141 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4142 "TARGET_K8 && !optimize_size"
4143 [(set (match_dup 2) (match_dup 1))
4144 (set (match_dup 0) (fix:DI (match_dup 2)))]
4145 "")
4146
4147 (define_insn "fix_truncdfdi_sse"
4148 [(set (match_operand:DI 0 "register_operand" "=r,r")
4149 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4150 "TARGET_64BIT && TARGET_SSE2"
4151 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4152 [(set_attr "type" "sseicvt,sseicvt")
4153 (set_attr "mode" "DF")
4154 (set_attr "athlon_decode" "double,vector")])
4155
4156 ;; Avoid vector decoded form of the instruction.
4157 (define_peephole2
4158 [(match_scratch:DF 2 "Y")
4159 (set (match_operand:DI 0 "register_operand" "")
4160 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4161 "TARGET_K8 && !optimize_size"
4162 [(set (match_dup 2) (match_dup 1))
4163 (set (match_dup 0) (fix:DI (match_dup 2)))]
4164 "")
4165
4166 ;; Signed conversion to SImode.
4167
4168 (define_expand "fix_truncxfsi2"
4169 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4170 (fix:SI (match_operand:XF 1 "register_operand" "")))
4171 (clobber (reg:CC 17))])]
4172 "TARGET_80387"
4173 "")
4174
4175 (define_expand "fix_truncdfsi2"
4176 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4177 (fix:SI (match_operand:DF 1 "register_operand" "")))
4178 (clobber (reg:CC 17))])]
4179 "TARGET_80387 || TARGET_SSE2"
4180 {
4181 if (TARGET_SSE2)
4182 {
4183 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4184 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4185 if (out != operands[0])
4186 emit_move_insn (operands[0], out);
4187 DONE;
4188 }
4189 })
4190
4191 (define_expand "fix_truncsfsi2"
4192 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4193 (fix:SI (match_operand:SF 1 "register_operand" "")))
4194 (clobber (reg:CC 17))])]
4195 "TARGET_80387 || TARGET_SSE"
4196 {
4197 if (TARGET_SSE)
4198 {
4199 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4200 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4201 if (out != operands[0])
4202 emit_move_insn (operands[0], out);
4203 DONE;
4204 }
4205 })
4206
4207 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4208 ;; of the machinery.
4209 (define_insn_and_split "*fix_truncsi_1"
4210 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4211 (fix:SI (match_operand 1 "register_operand" "f,f")))
4212 (clobber (reg:CC 17))]
4213 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && !reload_completed && !reload_in_progress
4215 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4216 "#"
4217 "&& 1"
4218 [(const_int 0)]
4219 {
4220 ix86_optimize_mode_switching = 1;
4221 operands[2] = assign_386_stack_local (HImode, 1);
4222 operands[3] = assign_386_stack_local (HImode, 2);
4223 if (memory_operand (operands[0], VOIDmode))
4224 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4225 operands[2], operands[3]));
4226 else
4227 {
4228 operands[4] = assign_386_stack_local (SImode, 0);
4229 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4230 operands[2], operands[3],
4231 operands[4]));
4232 }
4233 DONE;
4234 }
4235 [(set_attr "type" "fistp")
4236 (set_attr "mode" "SI")])
4237
4238 (define_insn "fix_truncsi_nomemory"
4239 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4240 (fix:SI (match_operand 1 "register_operand" "f,f")))
4241 (use (match_operand:HI 2 "memory_operand" "m,m"))
4242 (use (match_operand:HI 3 "memory_operand" "m,m"))
4243 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4244 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4245 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4246 "#"
4247 [(set_attr "type" "fistp")
4248 (set_attr "mode" "SI")])
4249
4250 (define_insn "fix_truncsi_memory"
4251 [(set (match_operand:SI 0 "memory_operand" "=m")
4252 (fix:SI (match_operand 1 "register_operand" "f")))
4253 (use (match_operand:HI 2 "memory_operand" "m"))
4254 (use (match_operand:HI 3 "memory_operand" "m"))]
4255 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4256 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4257 "* return output_fix_trunc (insn, operands);"
4258 [(set_attr "type" "fistp")
4259 (set_attr "mode" "SI")])
4260
4261 ;; When SSE available, it is always faster to use it!
4262 (define_insn "fix_truncsfsi_sse"
4263 [(set (match_operand:SI 0 "register_operand" "=r,r")
4264 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4265 "TARGET_SSE"
4266 "cvttss2si\t{%1, %0|%0, %1}"
4267 [(set_attr "type" "sseicvt")
4268 (set_attr "mode" "DF")
4269 (set_attr "athlon_decode" "double,vector")])
4270
4271 ;; Avoid vector decoded form of the instruction.
4272 (define_peephole2
4273 [(match_scratch:SF 2 "x")
4274 (set (match_operand:SI 0 "register_operand" "")
4275 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4276 "TARGET_K8 && !optimize_size"
4277 [(set (match_dup 2) (match_dup 1))
4278 (set (match_dup 0) (fix:SI (match_dup 2)))]
4279 "")
4280
4281 (define_insn "fix_truncdfsi_sse"
4282 [(set (match_operand:SI 0 "register_operand" "=r,r")
4283 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4284 "TARGET_SSE2"
4285 "cvttsd2si\t{%1, %0|%0, %1}"
4286 [(set_attr "type" "sseicvt")
4287 (set_attr "mode" "DF")
4288 (set_attr "athlon_decode" "double,vector")])
4289
4290 ;; Avoid vector decoded form of the instruction.
4291 (define_peephole2
4292 [(match_scratch:DF 2 "Y")
4293 (set (match_operand:SI 0 "register_operand" "")
4294 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4295 "TARGET_K8 && !optimize_size"
4296 [(set (match_dup 2) (match_dup 1))
4297 (set (match_dup 0) (fix:SI (match_dup 2)))]
4298 "")
4299
4300 (define_split
4301 [(set (match_operand:SI 0 "register_operand" "")
4302 (fix:SI (match_operand 1 "register_operand" "")))
4303 (use (match_operand:HI 2 "memory_operand" ""))
4304 (use (match_operand:HI 3 "memory_operand" ""))
4305 (clobber (match_operand:SI 4 "memory_operand" ""))]
4306 "reload_completed"
4307 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4308 (use (match_dup 2))
4309 (use (match_dup 3))])
4310 (set (match_dup 0) (match_dup 4))]
4311 "")
4312
4313 (define_split
4314 [(set (match_operand:SI 0 "memory_operand" "")
4315 (fix:SI (match_operand 1 "register_operand" "")))
4316 (use (match_operand:HI 2 "memory_operand" ""))
4317 (use (match_operand:HI 3 "memory_operand" ""))
4318 (clobber (match_operand:SI 4 "memory_operand" ""))]
4319 "reload_completed"
4320 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4321 (use (match_dup 2))
4322 (use (match_dup 3))])]
4323 "")
4324
4325 ;; Signed conversion to HImode.
4326
4327 (define_expand "fix_truncxfhi2"
4328 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4329 (fix:HI (match_operand:XF 1 "register_operand" "")))
4330 (clobber (reg:CC 17))])]
4331 "TARGET_80387"
4332 "")
4333
4334 (define_expand "fix_truncdfhi2"
4335 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4336 (fix:HI (match_operand:DF 1 "register_operand" "")))
4337 (clobber (reg:CC 17))])]
4338 "TARGET_80387 && !TARGET_SSE2"
4339 "")
4340
4341 (define_expand "fix_truncsfhi2"
4342 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4343 (fix:HI (match_operand:SF 1 "register_operand" "")))
4344 (clobber (reg:CC 17))])]
4345 "TARGET_80387 && !TARGET_SSE"
4346 "")
4347
4348 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4349 ;; of the machinery.
4350 (define_insn_and_split "*fix_trunchi_1"
4351 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4352 (fix:HI (match_operand 1 "register_operand" "f,f")))
4353 (clobber (reg:CC 17))]
4354 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4355 && !reload_completed && !reload_in_progress
4356 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4357 "#"
4358 ""
4359 [(const_int 0)]
4360 {
4361 ix86_optimize_mode_switching = 1;
4362 operands[2] = assign_386_stack_local (HImode, 1);
4363 operands[3] = assign_386_stack_local (HImode, 2);
4364 if (memory_operand (operands[0], VOIDmode))
4365 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4366 operands[2], operands[3]));
4367 else
4368 {
4369 operands[4] = assign_386_stack_local (HImode, 0);
4370 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4371 operands[2], operands[3],
4372 operands[4]));
4373 }
4374 DONE;
4375 }
4376 [(set_attr "type" "fistp")
4377 (set_attr "mode" "HI")])
4378
4379 (define_insn "fix_trunchi_nomemory"
4380 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4381 (fix:HI (match_operand 1 "register_operand" "f,f")))
4382 (use (match_operand:HI 2 "memory_operand" "m,m"))
4383 (use (match_operand:HI 3 "memory_operand" "m,m"))
4384 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4385 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4386 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4387 "#"
4388 [(set_attr "type" "fistp")
4389 (set_attr "mode" "HI")])
4390
4391 (define_insn "fix_trunchi_memory"
4392 [(set (match_operand:HI 0 "memory_operand" "=m")
4393 (fix:HI (match_operand 1 "register_operand" "f")))
4394 (use (match_operand:HI 2 "memory_operand" "m"))
4395 (use (match_operand:HI 3 "memory_operand" "m"))]
4396 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4397 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4398 "* return output_fix_trunc (insn, operands);"
4399 [(set_attr "type" "fistp")
4400 (set_attr "mode" "HI")])
4401
4402 (define_split
4403 [(set (match_operand:HI 0 "memory_operand" "")
4404 (fix:HI (match_operand 1 "register_operand" "")))
4405 (use (match_operand:HI 2 "memory_operand" ""))
4406 (use (match_operand:HI 3 "memory_operand" ""))
4407 (clobber (match_operand:HI 4 "memory_operand" ""))]
4408 "reload_completed"
4409 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4410 (use (match_dup 2))
4411 (use (match_dup 3))])]
4412 "")
4413
4414 (define_split
4415 [(set (match_operand:HI 0 "register_operand" "")
4416 (fix:HI (match_operand 1 "register_operand" "")))
4417 (use (match_operand:HI 2 "memory_operand" ""))
4418 (use (match_operand:HI 3 "memory_operand" ""))
4419 (clobber (match_operand:HI 4 "memory_operand" ""))]
4420 "reload_completed"
4421 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4422 (use (match_dup 2))
4423 (use (match_dup 3))
4424 (clobber (match_dup 4))])
4425 (set (match_dup 0) (match_dup 4))]
4426 "")
4427
4428 ;; %% Not used yet.
4429 (define_insn "x86_fnstcw_1"
4430 [(set (match_operand:HI 0 "memory_operand" "=m")
4431 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4432 "TARGET_80387"
4433 "fnstcw\t%0"
4434 [(set_attr "length" "2")
4435 (set_attr "mode" "HI")
4436 (set_attr "unit" "i387")])
4437
4438 (define_insn "x86_fldcw_1"
4439 [(set (reg:HI 18)
4440 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4441 "TARGET_80387"
4442 "fldcw\t%0"
4443 [(set_attr "length" "2")
4444 (set_attr "mode" "HI")
4445 (set_attr "unit" "i387")
4446 (set_attr "athlon_decode" "vector")])
4447 \f
4448 ;; Conversion between fixed point and floating point.
4449
4450 ;; Even though we only accept memory inputs, the backend _really_
4451 ;; wants to be able to do this between registers.
4452
4453 (define_expand "floathisf2"
4454 [(set (match_operand:SF 0 "register_operand" "")
4455 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4456 "TARGET_SSE || TARGET_80387"
4457 {
4458 if (TARGET_SSE && TARGET_SSE_MATH)
4459 {
4460 emit_insn (gen_floatsisf2 (operands[0],
4461 convert_to_mode (SImode, operands[1], 0)));
4462 DONE;
4463 }
4464 })
4465
4466 (define_insn "*floathisf2_1"
4467 [(set (match_operand:SF 0 "register_operand" "=f,f")
4468 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4469 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4470 "@
4471 fild%z1\t%1
4472 #"
4473 [(set_attr "type" "fmov,multi")
4474 (set_attr "mode" "SF")
4475 (set_attr "fp_int_src" "true")])
4476
4477 (define_expand "floatsisf2"
4478 [(set (match_operand:SF 0 "register_operand" "")
4479 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4480 "TARGET_SSE || TARGET_80387"
4481 "")
4482
4483 (define_insn "*floatsisf2_i387"
4484 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4485 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4486 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4487 "@
4488 fild%z1\t%1
4489 #
4490 cvtsi2ss\t{%1, %0|%0, %1}
4491 cvtsi2ss\t{%1, %0|%0, %1}"
4492 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4493 (set_attr "mode" "SF")
4494 (set_attr "athlon_decode" "*,*,vector,double")
4495 (set_attr "fp_int_src" "true")])
4496
4497 (define_insn "*floatsisf2_sse"
4498 [(set (match_operand:SF 0 "register_operand" "=x,x")
4499 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4500 "TARGET_SSE"
4501 "cvtsi2ss\t{%1, %0|%0, %1}"
4502 [(set_attr "type" "sseicvt")
4503 (set_attr "mode" "SF")
4504 (set_attr "athlon_decode" "vector,double")
4505 (set_attr "fp_int_src" "true")])
4506
4507 ; Avoid possible reformatting penalty on the destination by first
4508 ; zeroing it out
4509 (define_split
4510 [(set (match_operand:SF 0 "register_operand" "")
4511 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4512 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4513 && SSE_REG_P (operands[0])"
4514 [(const_int 0)]
4515 {
4516 rtx dest;
4517 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4518 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4519 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4520 DONE;
4521 })
4522
4523 (define_expand "floatdisf2"
4524 [(set (match_operand:SF 0 "register_operand" "")
4525 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4526 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4527 "")
4528
4529 (define_insn "*floatdisf2_i387_only"
4530 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4531 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4532 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4533 "@
4534 fild%z1\t%1
4535 #"
4536 [(set_attr "type" "fmov,multi")
4537 (set_attr "mode" "SF")
4538 (set_attr "fp_int_src" "true")])
4539
4540 (define_insn "*floatdisf2_i387"
4541 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4542 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4543 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4544 "@
4545 fild%z1\t%1
4546 #
4547 cvtsi2ss{q}\t{%1, %0|%0, %1}
4548 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4549 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4550 (set_attr "mode" "SF")
4551 (set_attr "athlon_decode" "*,*,vector,double")
4552 (set_attr "fp_int_src" "true")])
4553
4554 (define_insn "*floatdisf2_sse"
4555 [(set (match_operand:SF 0 "register_operand" "=x,x")
4556 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4557 "TARGET_64BIT && TARGET_SSE"
4558 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4559 [(set_attr "type" "sseicvt")
4560 (set_attr "mode" "SF")
4561 (set_attr "athlon_decode" "vector,double")
4562 (set_attr "fp_int_src" "true")])
4563
4564 ; Avoid possible reformatting penalty on the destination by first
4565 ; zeroing it out
4566 (define_split
4567 [(set (match_operand:SF 0 "register_operand" "")
4568 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4569 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4570 && SSE_REG_P (operands[0])"
4571 [(const_int 0)]
4572 {
4573 rtx dest;
4574 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4575 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4576 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4577 DONE;
4578 })
4579
4580 (define_expand "floathidf2"
4581 [(set (match_operand:DF 0 "register_operand" "")
4582 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4583 "TARGET_SSE2 || TARGET_80387"
4584 {
4585 if (TARGET_SSE && TARGET_SSE_MATH)
4586 {
4587 emit_insn (gen_floatsidf2 (operands[0],
4588 convert_to_mode (SImode, operands[1], 0)));
4589 DONE;
4590 }
4591 })
4592
4593 (define_insn "*floathidf2_1"
4594 [(set (match_operand:DF 0 "register_operand" "=f,f")
4595 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4596 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4597 "@
4598 fild%z1\t%1
4599 #"
4600 [(set_attr "type" "fmov,multi")
4601 (set_attr "mode" "DF")
4602 (set_attr "fp_int_src" "true")])
4603
4604 (define_expand "floatsidf2"
4605 [(set (match_operand:DF 0 "register_operand" "")
4606 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4607 "TARGET_80387 || TARGET_SSE2"
4608 "")
4609
4610 (define_insn "*floatsidf2_i387"
4611 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4612 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4613 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4614 "@
4615 fild%z1\t%1
4616 #
4617 cvtsi2sd\t{%1, %0|%0, %1}
4618 cvtsi2sd\t{%1, %0|%0, %1}"
4619 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4620 (set_attr "mode" "DF")
4621 (set_attr "athlon_decode" "*,*,double,direct")
4622 (set_attr "fp_int_src" "true")])
4623
4624 (define_insn "*floatsidf2_sse"
4625 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4626 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4627 "TARGET_SSE2"
4628 "cvtsi2sd\t{%1, %0|%0, %1}"
4629 [(set_attr "type" "sseicvt")
4630 (set_attr "mode" "DF")
4631 (set_attr "athlon_decode" "double,direct")
4632 (set_attr "fp_int_src" "true")])
4633
4634 (define_expand "floatdidf2"
4635 [(set (match_operand:DF 0 "register_operand" "")
4636 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4637 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4638 "")
4639
4640 (define_insn "*floatdidf2_i387_only"
4641 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4642 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4643 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4644 "@
4645 fild%z1\t%1
4646 #"
4647 [(set_attr "type" "fmov,multi")
4648 (set_attr "mode" "DF")
4649 (set_attr "fp_int_src" "true")])
4650
4651 (define_insn "*floatdidf2_i387"
4652 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4653 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4654 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4655 "@
4656 fild%z1\t%1
4657 #
4658 cvtsi2sd{q}\t{%1, %0|%0, %1}
4659 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4660 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4661 (set_attr "mode" "DF")
4662 (set_attr "athlon_decode" "*,*,double,direct")
4663 (set_attr "fp_int_src" "true")])
4664
4665 (define_insn "*floatdidf2_sse"
4666 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4667 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4668 "TARGET_SSE2"
4669 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4670 [(set_attr "type" "sseicvt")
4671 (set_attr "mode" "DF")
4672 (set_attr "athlon_decode" "double,direct")
4673 (set_attr "fp_int_src" "true")])
4674
4675 (define_insn "floathixf2"
4676 [(set (match_operand:XF 0 "register_operand" "=f,f")
4677 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4678 "TARGET_80387"
4679 "@
4680 fild%z1\t%1
4681 #"
4682 [(set_attr "type" "fmov,multi")
4683 (set_attr "mode" "XF")
4684 (set_attr "fp_int_src" "true")])
4685
4686 (define_insn "floatsixf2"
4687 [(set (match_operand:XF 0 "register_operand" "=f,f")
4688 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4689 "TARGET_80387"
4690 "@
4691 fild%z1\t%1
4692 #"
4693 [(set_attr "type" "fmov,multi")
4694 (set_attr "mode" "XF")
4695 (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "floatdixf2"
4698 [(set (match_operand:XF 0 "register_operand" "=f,f")
4699 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4700 "TARGET_80387"
4701 "@
4702 fild%z1\t%1
4703 #"
4704 [(set_attr "type" "fmov,multi")
4705 (set_attr "mode" "XF")
4706 (set_attr "fp_int_src" "true")])
4707
4708 ;; %%% Kill these when reload knows how to do it.
4709 (define_split
4710 [(set (match_operand 0 "fp_register_operand" "")
4711 (float (match_operand 1 "register_operand" "")))]
4712 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4713 [(const_int 0)]
4714 {
4715 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4716 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4717 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4718 ix86_free_from_memory (GET_MODE (operands[1]));
4719 DONE;
4720 })
4721
4722 (define_expand "floatunssisf2"
4723 [(use (match_operand:SF 0 "register_operand" ""))
4724 (use (match_operand:SI 1 "register_operand" ""))]
4725 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4726 "x86_emit_floatuns (operands); DONE;")
4727
4728 (define_expand "floatunsdisf2"
4729 [(use (match_operand:SF 0 "register_operand" ""))
4730 (use (match_operand:DI 1 "register_operand" ""))]
4731 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4732 "x86_emit_floatuns (operands); DONE;")
4733
4734 (define_expand "floatunsdidf2"
4735 [(use (match_operand:DF 0 "register_operand" ""))
4736 (use (match_operand:DI 1 "register_operand" ""))]
4737 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4738 "x86_emit_floatuns (operands); DONE;")
4739 \f
4740 ;; SSE extract/set expanders
4741
4742 (define_expand "vec_setv2df"
4743 [(match_operand:V2DF 0 "register_operand" "")
4744 (match_operand:DF 1 "register_operand" "")
4745 (match_operand 2 "const_int_operand" "")]
4746 "TARGET_SSE2"
4747 {
4748 switch (INTVAL (operands[2]))
4749 {
4750 case 0:
4751 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4752 simplify_gen_subreg (V2DFmode, operands[1],
4753 DFmode, 0)));
4754 break;
4755 case 1:
4756 {
4757 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4758
4759 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4760 }
4761 break;
4762 default:
4763 abort ();
4764 }
4765 DONE;
4766 })
4767
4768 (define_expand "vec_extractv2df"
4769 [(match_operand:DF 0 "register_operand" "")
4770 (match_operand:V2DF 1 "register_operand" "")
4771 (match_operand 2 "const_int_operand" "")]
4772 "TARGET_SSE2"
4773 {
4774 switch (INTVAL (operands[2]))
4775 {
4776 case 0:
4777 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4778 break;
4779 case 1:
4780 {
4781 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4782
4783 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4784 }
4785 break;
4786 default:
4787 abort ();
4788 }
4789 DONE;
4790 })
4791
4792 (define_expand "vec_initv2df"
4793 [(match_operand:V2DF 0 "register_operand" "")
4794 (match_operand 1 "" "")]
4795 "TARGET_SSE2"
4796 {
4797 ix86_expand_vector_init (operands[0], operands[1]);
4798 DONE;
4799 })
4800
4801 (define_expand "vec_setv4sf"
4802 [(match_operand:V4SF 0 "register_operand" "")
4803 (match_operand:SF 1 "register_operand" "")
4804 (match_operand 2 "const_int_operand" "")]
4805 "TARGET_SSE"
4806 {
4807 switch (INTVAL (operands[2]))
4808 {
4809 case 0:
4810 emit_insn (gen_sse_movss (operands[0], operands[0],
4811 simplify_gen_subreg (V4SFmode, operands[1],
4812 SFmode, 0)));
4813 break;
4814 case 1:
4815 {
4816 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4817 rtx tmp = gen_reg_rtx (V4SFmode);
4818
4819 emit_move_insn (tmp, operands[0]);
4820 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4821 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4822 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4823 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4824 }
4825 case 2:
4826 {
4827 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4828 rtx tmp = gen_reg_rtx (V4SFmode);
4829
4830 emit_move_insn (tmp, operands[0]);
4831 emit_insn (gen_sse_movss (tmp, tmp, op1));
4832 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4833 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4834 }
4835 break;
4836 case 3:
4837 {
4838 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4839 rtx tmp = gen_reg_rtx (V4SFmode);
4840
4841 emit_move_insn (tmp, operands[0]);
4842 emit_insn (gen_sse_movss (tmp, tmp, op1));
4843 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4844 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4845 }
4846 break;
4847 default:
4848 abort ();
4849 }
4850 DONE;
4851 })
4852
4853 (define_expand "vec_extractv4sf"
4854 [(match_operand:SF 0 "register_operand" "")
4855 (match_operand:V4SF 1 "register_operand" "")
4856 (match_operand 2 "const_int_operand" "")]
4857 "TARGET_SSE"
4858 {
4859 switch (INTVAL (operands[2]))
4860 {
4861 case 0:
4862 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4863 break;
4864 case 1:
4865 {
4866 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4867 rtx tmp = gen_reg_rtx (V4SFmode);
4868
4869 emit_move_insn (tmp, operands[1]);
4870 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4871 const1_rtx));
4872 }
4873 case 2:
4874 {
4875 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4876 rtx tmp = gen_reg_rtx (V4SFmode);
4877
4878 emit_move_insn (tmp, operands[1]);
4879 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4880 }
4881 case 3:
4882 {
4883 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4884 rtx tmp = gen_reg_rtx (V4SFmode);
4885
4886 emit_move_insn (tmp, operands[1]);
4887 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4888 GEN_INT (3)));
4889 }
4890 default:
4891 abort ();
4892 }
4893 DONE;
4894 })
4895
4896 (define_expand "vec_initv4sf"
4897 [(match_operand:V4SF 0 "register_operand" "")
4898 (match_operand 1 "" "")]
4899 "TARGET_SSE"
4900 {
4901 ix86_expand_vector_init (operands[0], operands[1]);
4902 DONE;
4903 })
4904 \f
4905 ;; Add instructions
4906
4907 ;; %%% splits for addsidi3
4908 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4909 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4910 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4911
4912 (define_expand "adddi3"
4913 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4914 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4915 (match_operand:DI 2 "x86_64_general_operand" "")))
4916 (clobber (reg:CC 17))]
4917 ""
4918 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4919
4920 (define_insn "*adddi3_1"
4921 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4922 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4923 (match_operand:DI 2 "general_operand" "roiF,riF")))
4924 (clobber (reg:CC 17))]
4925 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4926 "#")
4927
4928 (define_split
4929 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4930 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4931 (match_operand:DI 2 "general_operand" "")))
4932 (clobber (reg:CC 17))]
4933 "!TARGET_64BIT && reload_completed"
4934 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4935 UNSPEC_ADD_CARRY))
4936 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4937 (parallel [(set (match_dup 3)
4938 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4939 (match_dup 4))
4940 (match_dup 5)))
4941 (clobber (reg:CC 17))])]
4942 "split_di (operands+0, 1, operands+0, operands+3);
4943 split_di (operands+1, 1, operands+1, operands+4);
4944 split_di (operands+2, 1, operands+2, operands+5);")
4945
4946 (define_insn "adddi3_carry_rex64"
4947 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4948 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4949 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4950 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4951 (clobber (reg:CC 17))]
4952 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4953 "adc{q}\t{%2, %0|%0, %2}"
4954 [(set_attr "type" "alu")
4955 (set_attr "pent_pair" "pu")
4956 (set_attr "mode" "DI")])
4957
4958 (define_insn "*adddi3_cc_rex64"
4959 [(set (reg:CC 17)
4960 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4961 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4962 UNSPEC_ADD_CARRY))
4963 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4964 (plus:DI (match_dup 1) (match_dup 2)))]
4965 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4966 "add{q}\t{%2, %0|%0, %2}"
4967 [(set_attr "type" "alu")
4968 (set_attr "mode" "DI")])
4969
4970 (define_insn "addqi3_carry"
4971 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4972 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4973 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4974 (match_operand:QI 2 "general_operand" "qi,qm")))
4975 (clobber (reg:CC 17))]
4976 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4977 "adc{b}\t{%2, %0|%0, %2}"
4978 [(set_attr "type" "alu")
4979 (set_attr "pent_pair" "pu")
4980 (set_attr "mode" "QI")])
4981
4982 (define_insn "addhi3_carry"
4983 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4984 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4985 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4986 (match_operand:HI 2 "general_operand" "ri,rm")))
4987 (clobber (reg:CC 17))]
4988 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4989 "adc{w}\t{%2, %0|%0, %2}"
4990 [(set_attr "type" "alu")
4991 (set_attr "pent_pair" "pu")
4992 (set_attr "mode" "HI")])
4993
4994 (define_insn "addsi3_carry"
4995 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4996 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4997 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4998 (match_operand:SI 2 "general_operand" "ri,rm")))
4999 (clobber (reg:CC 17))]
5000 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5001 "adc{l}\t{%2, %0|%0, %2}"
5002 [(set_attr "type" "alu")
5003 (set_attr "pent_pair" "pu")
5004 (set_attr "mode" "SI")])
5005
5006 (define_insn "*addsi3_carry_zext"
5007 [(set (match_operand:DI 0 "register_operand" "=r")
5008 (zero_extend:DI
5009 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5010 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5011 (match_operand:SI 2 "general_operand" "rim"))))
5012 (clobber (reg:CC 17))]
5013 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5014 "adc{l}\t{%2, %k0|%k0, %2}"
5015 [(set_attr "type" "alu")
5016 (set_attr "pent_pair" "pu")
5017 (set_attr "mode" "SI")])
5018
5019 (define_insn "*addsi3_cc"
5020 [(set (reg:CC 17)
5021 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5022 (match_operand:SI 2 "general_operand" "ri,rm")]
5023 UNSPEC_ADD_CARRY))
5024 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5025 (plus:SI (match_dup 1) (match_dup 2)))]
5026 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5027 "add{l}\t{%2, %0|%0, %2}"
5028 [(set_attr "type" "alu")
5029 (set_attr "mode" "SI")])
5030
5031 (define_insn "addqi3_cc"
5032 [(set (reg:CC 17)
5033 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5034 (match_operand:QI 2 "general_operand" "qi,qm")]
5035 UNSPEC_ADD_CARRY))
5036 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5037 (plus:QI (match_dup 1) (match_dup 2)))]
5038 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5039 "add{b}\t{%2, %0|%0, %2}"
5040 [(set_attr "type" "alu")
5041 (set_attr "mode" "QI")])
5042
5043 (define_expand "addsi3"
5044 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5045 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5046 (match_operand:SI 2 "general_operand" "")))
5047 (clobber (reg:CC 17))])]
5048 ""
5049 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5050
5051 (define_insn "*lea_1"
5052 [(set (match_operand:SI 0 "register_operand" "=r")
5053 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5054 "!TARGET_64BIT"
5055 "lea{l}\t{%a1, %0|%0, %a1}"
5056 [(set_attr "type" "lea")
5057 (set_attr "mode" "SI")])
5058
5059 (define_insn "*lea_1_rex64"
5060 [(set (match_operand:SI 0 "register_operand" "=r")
5061 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5062 "TARGET_64BIT"
5063 "lea{l}\t{%a1, %0|%0, %a1}"
5064 [(set_attr "type" "lea")
5065 (set_attr "mode" "SI")])
5066
5067 (define_insn "*lea_1_zext"
5068 [(set (match_operand:DI 0 "register_operand" "=r")
5069 (zero_extend:DI
5070 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5071 "TARGET_64BIT"
5072 "lea{l}\t{%a1, %k0|%k0, %a1}"
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
5075
5076 (define_insn "*lea_2_rex64"
5077 [(set (match_operand:DI 0 "register_operand" "=r")
5078 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5079 "TARGET_64BIT"
5080 "lea{q}\t{%a1, %0|%0, %a1}"
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "DI")])
5083
5084 ;; The lea patterns for non-Pmodes needs to be matched by several
5085 ;; insns converted to real lea by splitters.
5086
5087 (define_insn_and_split "*lea_general_1"
5088 [(set (match_operand 0 "register_operand" "=r")
5089 (plus (plus (match_operand 1 "index_register_operand" "r")
5090 (match_operand 2 "register_operand" "r"))
5091 (match_operand 3 "immediate_operand" "i")))]
5092 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5093 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5094 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5095 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5096 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5097 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5098 || GET_MODE (operands[3]) == VOIDmode)"
5099 "#"
5100 "&& reload_completed"
5101 [(const_int 0)]
5102 {
5103 rtx pat;
5104 operands[0] = gen_lowpart (SImode, operands[0]);
5105 operands[1] = gen_lowpart (Pmode, operands[1]);
5106 operands[2] = gen_lowpart (Pmode, operands[2]);
5107 operands[3] = gen_lowpart (Pmode, operands[3]);
5108 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5109 operands[3]);
5110 if (Pmode != SImode)
5111 pat = gen_rtx_SUBREG (SImode, pat, 0);
5112 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5113 DONE;
5114 }
5115 [(set_attr "type" "lea")
5116 (set_attr "mode" "SI")])
5117
5118 (define_insn_and_split "*lea_general_1_zext"
5119 [(set (match_operand:DI 0 "register_operand" "=r")
5120 (zero_extend:DI
5121 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5122 (match_operand:SI 2 "register_operand" "r"))
5123 (match_operand:SI 3 "immediate_operand" "i"))))]
5124 "TARGET_64BIT"
5125 "#"
5126 "&& reload_completed"
5127 [(set (match_dup 0)
5128 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5129 (match_dup 2))
5130 (match_dup 3)) 0)))]
5131 {
5132 operands[1] = gen_lowpart (Pmode, operands[1]);
5133 operands[2] = gen_lowpart (Pmode, operands[2]);
5134 operands[3] = gen_lowpart (Pmode, operands[3]);
5135 }
5136 [(set_attr "type" "lea")
5137 (set_attr "mode" "SI")])
5138
5139 (define_insn_and_split "*lea_general_2"
5140 [(set (match_operand 0 "register_operand" "=r")
5141 (plus (mult (match_operand 1 "index_register_operand" "r")
5142 (match_operand 2 "const248_operand" "i"))
5143 (match_operand 3 "nonmemory_operand" "ri")))]
5144 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5145 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5146 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5147 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5148 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5149 || GET_MODE (operands[3]) == VOIDmode)"
5150 "#"
5151 "&& reload_completed"
5152 [(const_int 0)]
5153 {
5154 rtx pat;
5155 operands[0] = gen_lowpart (SImode, operands[0]);
5156 operands[1] = gen_lowpart (Pmode, operands[1]);
5157 operands[3] = gen_lowpart (Pmode, operands[3]);
5158 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5159 operands[3]);
5160 if (Pmode != SImode)
5161 pat = gen_rtx_SUBREG (SImode, pat, 0);
5162 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5163 DONE;
5164 }
5165 [(set_attr "type" "lea")
5166 (set_attr "mode" "SI")])
5167
5168 (define_insn_and_split "*lea_general_2_zext"
5169 [(set (match_operand:DI 0 "register_operand" "=r")
5170 (zero_extend:DI
5171 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5172 (match_operand:SI 2 "const248_operand" "n"))
5173 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5174 "TARGET_64BIT"
5175 "#"
5176 "&& reload_completed"
5177 [(set (match_dup 0)
5178 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5179 (match_dup 2))
5180 (match_dup 3)) 0)))]
5181 {
5182 operands[1] = gen_lowpart (Pmode, operands[1]);
5183 operands[3] = gen_lowpart (Pmode, operands[3]);
5184 }
5185 [(set_attr "type" "lea")
5186 (set_attr "mode" "SI")])
5187
5188 (define_insn_and_split "*lea_general_3"
5189 [(set (match_operand 0 "register_operand" "=r")
5190 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5191 (match_operand 2 "const248_operand" "i"))
5192 (match_operand 3 "register_operand" "r"))
5193 (match_operand 4 "immediate_operand" "i")))]
5194 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5195 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5196 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5197 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5198 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5199 "#"
5200 "&& reload_completed"
5201 [(const_int 0)]
5202 {
5203 rtx pat;
5204 operands[0] = gen_lowpart (SImode, operands[0]);
5205 operands[1] = gen_lowpart (Pmode, operands[1]);
5206 operands[3] = gen_lowpart (Pmode, operands[3]);
5207 operands[4] = gen_lowpart (Pmode, operands[4]);
5208 pat = gen_rtx_PLUS (Pmode,
5209 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5210 operands[2]),
5211 operands[3]),
5212 operands[4]);
5213 if (Pmode != SImode)
5214 pat = gen_rtx_SUBREG (SImode, pat, 0);
5215 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5216 DONE;
5217 }
5218 [(set_attr "type" "lea")
5219 (set_attr "mode" "SI")])
5220
5221 (define_insn_and_split "*lea_general_3_zext"
5222 [(set (match_operand:DI 0 "register_operand" "=r")
5223 (zero_extend:DI
5224 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5225 (match_operand:SI 2 "const248_operand" "n"))
5226 (match_operand:SI 3 "register_operand" "r"))
5227 (match_operand:SI 4 "immediate_operand" "i"))))]
5228 "TARGET_64BIT"
5229 "#"
5230 "&& reload_completed"
5231 [(set (match_dup 0)
5232 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5233 (match_dup 2))
5234 (match_dup 3))
5235 (match_dup 4)) 0)))]
5236 {
5237 operands[1] = gen_lowpart (Pmode, operands[1]);
5238 operands[3] = gen_lowpart (Pmode, operands[3]);
5239 operands[4] = gen_lowpart (Pmode, operands[4]);
5240 }
5241 [(set_attr "type" "lea")
5242 (set_attr "mode" "SI")])
5243
5244 (define_insn "*adddi_1_rex64"
5245 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5246 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5247 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5248 (clobber (reg:CC 17))]
5249 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5250 {
5251 switch (get_attr_type (insn))
5252 {
5253 case TYPE_LEA:
5254 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5255 return "lea{q}\t{%a2, %0|%0, %a2}";
5256
5257 case TYPE_INCDEC:
5258 if (! rtx_equal_p (operands[0], operands[1]))
5259 abort ();
5260 if (operands[2] == const1_rtx)
5261 return "inc{q}\t%0";
5262 else if (operands[2] == constm1_rtx)
5263 return "dec{q}\t%0";
5264 else
5265 abort ();
5266
5267 default:
5268 if (! rtx_equal_p (operands[0], operands[1]))
5269 abort ();
5270
5271 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5272 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5273 if (GET_CODE (operands[2]) == CONST_INT
5274 /* Avoid overflows. */
5275 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5276 && (INTVAL (operands[2]) == 128
5277 || (INTVAL (operands[2]) < 0
5278 && INTVAL (operands[2]) != -128)))
5279 {
5280 operands[2] = GEN_INT (-INTVAL (operands[2]));
5281 return "sub{q}\t{%2, %0|%0, %2}";
5282 }
5283 return "add{q}\t{%2, %0|%0, %2}";
5284 }
5285 }
5286 [(set (attr "type")
5287 (cond [(eq_attr "alternative" "2")
5288 (const_string "lea")
5289 ; Current assemblers are broken and do not allow @GOTOFF in
5290 ; ought but a memory context.
5291 (match_operand:DI 2 "pic_symbolic_operand" "")
5292 (const_string "lea")
5293 (match_operand:DI 2 "incdec_operand" "")
5294 (const_string "incdec")
5295 ]
5296 (const_string "alu")))
5297 (set_attr "mode" "DI")])
5298
5299 ;; Convert lea to the lea pattern to avoid flags dependency.
5300 (define_split
5301 [(set (match_operand:DI 0 "register_operand" "")
5302 (plus:DI (match_operand:DI 1 "register_operand" "")
5303 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5304 (clobber (reg:CC 17))]
5305 "TARGET_64BIT && reload_completed
5306 && true_regnum (operands[0]) != true_regnum (operands[1])"
5307 [(set (match_dup 0)
5308 (plus:DI (match_dup 1)
5309 (match_dup 2)))]
5310 "")
5311
5312 (define_insn "*adddi_2_rex64"
5313 [(set (reg 17)
5314 (compare
5315 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5316 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5317 (const_int 0)))
5318 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5319 (plus:DI (match_dup 1) (match_dup 2)))]
5320 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5321 && ix86_binary_operator_ok (PLUS, DImode, operands)
5322 /* Current assemblers are broken and do not allow @GOTOFF in
5323 ought but a memory context. */
5324 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5325 {
5326 switch (get_attr_type (insn))
5327 {
5328 case TYPE_INCDEC:
5329 if (! rtx_equal_p (operands[0], operands[1]))
5330 abort ();
5331 if (operands[2] == const1_rtx)
5332 return "inc{q}\t%0";
5333 else if (operands[2] == constm1_rtx)
5334 return "dec{q}\t%0";
5335 else
5336 abort ();
5337
5338 default:
5339 if (! rtx_equal_p (operands[0], operands[1]))
5340 abort ();
5341 /* ???? We ought to handle there the 32bit case too
5342 - do we need new constraint? */
5343 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5344 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5345 if (GET_CODE (operands[2]) == CONST_INT
5346 /* Avoid overflows. */
5347 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5348 && (INTVAL (operands[2]) == 128
5349 || (INTVAL (operands[2]) < 0
5350 && INTVAL (operands[2]) != -128)))
5351 {
5352 operands[2] = GEN_INT (-INTVAL (operands[2]));
5353 return "sub{q}\t{%2, %0|%0, %2}";
5354 }
5355 return "add{q}\t{%2, %0|%0, %2}";
5356 }
5357 }
5358 [(set (attr "type")
5359 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5360 (const_string "incdec")
5361 (const_string "alu")))
5362 (set_attr "mode" "DI")])
5363
5364 (define_insn "*adddi_3_rex64"
5365 [(set (reg 17)
5366 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5367 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5368 (clobber (match_scratch:DI 0 "=r"))]
5369 "TARGET_64BIT
5370 && ix86_match_ccmode (insn, CCZmode)
5371 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5372 /* Current assemblers are broken and do not allow @GOTOFF in
5373 ought but a memory context. */
5374 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5375 {
5376 switch (get_attr_type (insn))
5377 {
5378 case TYPE_INCDEC:
5379 if (! rtx_equal_p (operands[0], operands[1]))
5380 abort ();
5381 if (operands[2] == const1_rtx)
5382 return "inc{q}\t%0";
5383 else if (operands[2] == constm1_rtx)
5384 return "dec{q}\t%0";
5385 else
5386 abort ();
5387
5388 default:
5389 if (! rtx_equal_p (operands[0], operands[1]))
5390 abort ();
5391 /* ???? We ought to handle there the 32bit case too
5392 - do we need new constraint? */
5393 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5394 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5395 if (GET_CODE (operands[2]) == CONST_INT
5396 /* Avoid overflows. */
5397 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5398 && (INTVAL (operands[2]) == 128
5399 || (INTVAL (operands[2]) < 0
5400 && INTVAL (operands[2]) != -128)))
5401 {
5402 operands[2] = GEN_INT (-INTVAL (operands[2]));
5403 return "sub{q}\t{%2, %0|%0, %2}";
5404 }
5405 return "add{q}\t{%2, %0|%0, %2}";
5406 }
5407 }
5408 [(set (attr "type")
5409 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5410 (const_string "incdec")
5411 (const_string "alu")))
5412 (set_attr "mode" "DI")])
5413
5414 ; For comparisons against 1, -1 and 128, we may generate better code
5415 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5416 ; is matched then. We can't accept general immediate, because for
5417 ; case of overflows, the result is messed up.
5418 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5419 ; when negated.
5420 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5421 ; only for comparisons not depending on it.
5422 (define_insn "*adddi_4_rex64"
5423 [(set (reg 17)
5424 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5425 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5426 (clobber (match_scratch:DI 0 "=rm"))]
5427 "TARGET_64BIT
5428 && ix86_match_ccmode (insn, CCGCmode)"
5429 {
5430 switch (get_attr_type (insn))
5431 {
5432 case TYPE_INCDEC:
5433 if (operands[2] == constm1_rtx)
5434 return "inc{q}\t%0";
5435 else if (operands[2] == const1_rtx)
5436 return "dec{q}\t%0";
5437 else
5438 abort();
5439
5440 default:
5441 if (! rtx_equal_p (operands[0], operands[1]))
5442 abort ();
5443 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5445 if ((INTVAL (operands[2]) == -128
5446 || (INTVAL (operands[2]) > 0
5447 && INTVAL (operands[2]) != 128))
5448 /* Avoid overflows. */
5449 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5450 return "sub{q}\t{%2, %0|%0, %2}";
5451 operands[2] = GEN_INT (-INTVAL (operands[2]));
5452 return "add{q}\t{%2, %0|%0, %2}";
5453 }
5454 }
5455 [(set (attr "type")
5456 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5457 (const_string "incdec")
5458 (const_string "alu")))
5459 (set_attr "mode" "DI")])
5460
5461 (define_insn "*adddi_5_rex64"
5462 [(set (reg 17)
5463 (compare
5464 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5465 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5466 (const_int 0)))
5467 (clobber (match_scratch:DI 0 "=r"))]
5468 "TARGET_64BIT
5469 && ix86_match_ccmode (insn, CCGOCmode)
5470 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5471 /* Current assemblers are broken and do not allow @GOTOFF in
5472 ought but a memory context. */
5473 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5474 {
5475 switch (get_attr_type (insn))
5476 {
5477 case TYPE_INCDEC:
5478 if (! rtx_equal_p (operands[0], operands[1]))
5479 abort ();
5480 if (operands[2] == const1_rtx)
5481 return "inc{q}\t%0";
5482 else if (operands[2] == constm1_rtx)
5483 return "dec{q}\t%0";
5484 else
5485 abort();
5486
5487 default:
5488 if (! rtx_equal_p (operands[0], operands[1]))
5489 abort ();
5490 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5491 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5492 if (GET_CODE (operands[2]) == CONST_INT
5493 /* Avoid overflows. */
5494 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5495 && (INTVAL (operands[2]) == 128
5496 || (INTVAL (operands[2]) < 0
5497 && INTVAL (operands[2]) != -128)))
5498 {
5499 operands[2] = GEN_INT (-INTVAL (operands[2]));
5500 return "sub{q}\t{%2, %0|%0, %2}";
5501 }
5502 return "add{q}\t{%2, %0|%0, %2}";
5503 }
5504 }
5505 [(set (attr "type")
5506 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5507 (const_string "incdec")
5508 (const_string "alu")))
5509 (set_attr "mode" "DI")])
5510
5511
5512 (define_insn "*addsi_1"
5513 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5514 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5515 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5516 (clobber (reg:CC 17))]
5517 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5518 {
5519 switch (get_attr_type (insn))
5520 {
5521 case TYPE_LEA:
5522 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5523 return "lea{l}\t{%a2, %0|%0, %a2}";
5524
5525 case TYPE_INCDEC:
5526 if (! rtx_equal_p (operands[0], operands[1]))
5527 abort ();
5528 if (operands[2] == const1_rtx)
5529 return "inc{l}\t%0";
5530 else if (operands[2] == constm1_rtx)
5531 return "dec{l}\t%0";
5532 else
5533 abort();
5534
5535 default:
5536 if (! rtx_equal_p (operands[0], operands[1]))
5537 abort ();
5538
5539 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5541 if (GET_CODE (operands[2]) == CONST_INT
5542 && (INTVAL (operands[2]) == 128
5543 || (INTVAL (operands[2]) < 0
5544 && INTVAL (operands[2]) != -128)))
5545 {
5546 operands[2] = GEN_INT (-INTVAL (operands[2]));
5547 return "sub{l}\t{%2, %0|%0, %2}";
5548 }
5549 return "add{l}\t{%2, %0|%0, %2}";
5550 }
5551 }
5552 [(set (attr "type")
5553 (cond [(eq_attr "alternative" "2")
5554 (const_string "lea")
5555 ; Current assemblers are broken and do not allow @GOTOFF in
5556 ; ought but a memory context.
5557 (match_operand:SI 2 "pic_symbolic_operand" "")
5558 (const_string "lea")
5559 (match_operand:SI 2 "incdec_operand" "")
5560 (const_string "incdec")
5561 ]
5562 (const_string "alu")))
5563 (set_attr "mode" "SI")])
5564
5565 ;; Convert lea to the lea pattern to avoid flags dependency.
5566 (define_split
5567 [(set (match_operand 0 "register_operand" "")
5568 (plus (match_operand 1 "register_operand" "")
5569 (match_operand 2 "nonmemory_operand" "")))
5570 (clobber (reg:CC 17))]
5571 "reload_completed
5572 && true_regnum (operands[0]) != true_regnum (operands[1])"
5573 [(const_int 0)]
5574 {
5575 rtx pat;
5576 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5577 may confuse gen_lowpart. */
5578 if (GET_MODE (operands[0]) != Pmode)
5579 {
5580 operands[1] = gen_lowpart (Pmode, operands[1]);
5581 operands[2] = gen_lowpart (Pmode, operands[2]);
5582 }
5583 operands[0] = gen_lowpart (SImode, operands[0]);
5584 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5585 if (Pmode != SImode)
5586 pat = gen_rtx_SUBREG (SImode, pat, 0);
5587 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5588 DONE;
5589 })
5590
5591 ;; It may seem that nonimmediate operand is proper one for operand 1.
5592 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5593 ;; we take care in ix86_binary_operator_ok to not allow two memory
5594 ;; operands so proper swapping will be done in reload. This allow
5595 ;; patterns constructed from addsi_1 to match.
5596 (define_insn "addsi_1_zext"
5597 [(set (match_operand:DI 0 "register_operand" "=r,r")
5598 (zero_extend:DI
5599 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5600 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5601 (clobber (reg:CC 17))]
5602 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5603 {
5604 switch (get_attr_type (insn))
5605 {
5606 case TYPE_LEA:
5607 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5608 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5609
5610 case TYPE_INCDEC:
5611 if (operands[2] == const1_rtx)
5612 return "inc{l}\t%k0";
5613 else if (operands[2] == constm1_rtx)
5614 return "dec{l}\t%k0";
5615 else
5616 abort();
5617
5618 default:
5619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5621 if (GET_CODE (operands[2]) == CONST_INT
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{l}\t{%2, %k0|%k0, %2}";
5628 }
5629 return "add{l}\t{%2, %k0|%k0, %2}";
5630 }
5631 }
5632 [(set (attr "type")
5633 (cond [(eq_attr "alternative" "1")
5634 (const_string "lea")
5635 ; Current assemblers are broken and do not allow @GOTOFF in
5636 ; ought but a memory context.
5637 (match_operand:SI 2 "pic_symbolic_operand" "")
5638 (const_string "lea")
5639 (match_operand:SI 2 "incdec_operand" "")
5640 (const_string "incdec")
5641 ]
5642 (const_string "alu")))
5643 (set_attr "mode" "SI")])
5644
5645 ;; Convert lea to the lea pattern to avoid flags dependency.
5646 (define_split
5647 [(set (match_operand:DI 0 "register_operand" "")
5648 (zero_extend:DI
5649 (plus:SI (match_operand:SI 1 "register_operand" "")
5650 (match_operand:SI 2 "nonmemory_operand" ""))))
5651 (clobber (reg:CC 17))]
5652 "TARGET_64BIT && reload_completed
5653 && true_regnum (operands[0]) != true_regnum (operands[1])"
5654 [(set (match_dup 0)
5655 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5656 {
5657 operands[1] = gen_lowpart (Pmode, operands[1]);
5658 operands[2] = gen_lowpart (Pmode, operands[2]);
5659 })
5660
5661 (define_insn "*addsi_2"
5662 [(set (reg 17)
5663 (compare
5664 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5665 (match_operand:SI 2 "general_operand" "rmni,rni"))
5666 (const_int 0)))
5667 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5668 (plus:SI (match_dup 1) (match_dup 2)))]
5669 "ix86_match_ccmode (insn, CCGOCmode)
5670 && ix86_binary_operator_ok (PLUS, SImode, operands)
5671 /* Current assemblers are broken and do not allow @GOTOFF in
5672 ought but a memory context. */
5673 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5674 {
5675 switch (get_attr_type (insn))
5676 {
5677 case TYPE_INCDEC:
5678 if (! rtx_equal_p (operands[0], operands[1]))
5679 abort ();
5680 if (operands[2] == const1_rtx)
5681 return "inc{l}\t%0";
5682 else if (operands[2] == constm1_rtx)
5683 return "dec{l}\t%0";
5684 else
5685 abort();
5686
5687 default:
5688 if (! rtx_equal_p (operands[0], operands[1]))
5689 abort ();
5690 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5691 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5692 if (GET_CODE (operands[2]) == CONST_INT
5693 && (INTVAL (operands[2]) == 128
5694 || (INTVAL (operands[2]) < 0
5695 && INTVAL (operands[2]) != -128)))
5696 {
5697 operands[2] = GEN_INT (-INTVAL (operands[2]));
5698 return "sub{l}\t{%2, %0|%0, %2}";
5699 }
5700 return "add{l}\t{%2, %0|%0, %2}";
5701 }
5702 }
5703 [(set (attr "type")
5704 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5705 (const_string "incdec")
5706 (const_string "alu")))
5707 (set_attr "mode" "SI")])
5708
5709 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5710 (define_insn "*addsi_2_zext"
5711 [(set (reg 17)
5712 (compare
5713 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5714 (match_operand:SI 2 "general_operand" "rmni"))
5715 (const_int 0)))
5716 (set (match_operand:DI 0 "register_operand" "=r")
5717 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5718 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5719 && ix86_binary_operator_ok (PLUS, SImode, operands)
5720 /* Current assemblers are broken and do not allow @GOTOFF in
5721 ought but a memory context. */
5722 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5723 {
5724 switch (get_attr_type (insn))
5725 {
5726 case TYPE_INCDEC:
5727 if (operands[2] == const1_rtx)
5728 return "inc{l}\t%k0";
5729 else if (operands[2] == constm1_rtx)
5730 return "dec{l}\t%k0";
5731 else
5732 abort();
5733
5734 default:
5735 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5736 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5737 if (GET_CODE (operands[2]) == CONST_INT
5738 && (INTVAL (operands[2]) == 128
5739 || (INTVAL (operands[2]) < 0
5740 && INTVAL (operands[2]) != -128)))
5741 {
5742 operands[2] = GEN_INT (-INTVAL (operands[2]));
5743 return "sub{l}\t{%2, %k0|%k0, %2}";
5744 }
5745 return "add{l}\t{%2, %k0|%k0, %2}";
5746 }
5747 }
5748 [(set (attr "type")
5749 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5750 (const_string "incdec")
5751 (const_string "alu")))
5752 (set_attr "mode" "SI")])
5753
5754 (define_insn "*addsi_3"
5755 [(set (reg 17)
5756 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5757 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5758 (clobber (match_scratch:SI 0 "=r"))]
5759 "ix86_match_ccmode (insn, CCZmode)
5760 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761 /* Current assemblers are broken and do not allow @GOTOFF in
5762 ought but a memory context. */
5763 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5764 {
5765 switch (get_attr_type (insn))
5766 {
5767 case TYPE_INCDEC:
5768 if (! rtx_equal_p (operands[0], operands[1]))
5769 abort ();
5770 if (operands[2] == const1_rtx)
5771 return "inc{l}\t%0";
5772 else if (operands[2] == constm1_rtx)
5773 return "dec{l}\t%0";
5774 else
5775 abort();
5776
5777 default:
5778 if (! rtx_equal_p (operands[0], operands[1]))
5779 abort ();
5780 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5782 if (GET_CODE (operands[2]) == CONST_INT
5783 && (INTVAL (operands[2]) == 128
5784 || (INTVAL (operands[2]) < 0
5785 && INTVAL (operands[2]) != -128)))
5786 {
5787 operands[2] = GEN_INT (-INTVAL (operands[2]));
5788 return "sub{l}\t{%2, %0|%0, %2}";
5789 }
5790 return "add{l}\t{%2, %0|%0, %2}";
5791 }
5792 }
5793 [(set (attr "type")
5794 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5795 (const_string "incdec")
5796 (const_string "alu")))
5797 (set_attr "mode" "SI")])
5798
5799 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5800 (define_insn "*addsi_3_zext"
5801 [(set (reg 17)
5802 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5803 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5804 (set (match_operand:DI 0 "register_operand" "=r")
5805 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5806 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5807 && ix86_binary_operator_ok (PLUS, SImode, operands)
5808 /* Current assemblers are broken and do not allow @GOTOFF in
5809 ought but a memory context. */
5810 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5811 {
5812 switch (get_attr_type (insn))
5813 {
5814 case TYPE_INCDEC:
5815 if (operands[2] == const1_rtx)
5816 return "inc{l}\t%k0";
5817 else if (operands[2] == constm1_rtx)
5818 return "dec{l}\t%k0";
5819 else
5820 abort();
5821
5822 default:
5823 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5824 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5825 if (GET_CODE (operands[2]) == CONST_INT
5826 && (INTVAL (operands[2]) == 128
5827 || (INTVAL (operands[2]) < 0
5828 && INTVAL (operands[2]) != -128)))
5829 {
5830 operands[2] = GEN_INT (-INTVAL (operands[2]));
5831 return "sub{l}\t{%2, %k0|%k0, %2}";
5832 }
5833 return "add{l}\t{%2, %k0|%k0, %2}";
5834 }
5835 }
5836 [(set (attr "type")
5837 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5838 (const_string "incdec")
5839 (const_string "alu")))
5840 (set_attr "mode" "SI")])
5841
5842 ; For comparisons against 1, -1 and 128, we may generate better code
5843 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5844 ; is matched then. We can't accept general immediate, because for
5845 ; case of overflows, the result is messed up.
5846 ; This pattern also don't hold of 0x80000000, since the value overflows
5847 ; when negated.
5848 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5849 ; only for comparisons not depending on it.
5850 (define_insn "*addsi_4"
5851 [(set (reg 17)
5852 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5853 (match_operand:SI 2 "const_int_operand" "n")))
5854 (clobber (match_scratch:SI 0 "=rm"))]
5855 "ix86_match_ccmode (insn, CCGCmode)
5856 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5857 {
5858 switch (get_attr_type (insn))
5859 {
5860 case TYPE_INCDEC:
5861 if (operands[2] == constm1_rtx)
5862 return "inc{l}\t%0";
5863 else if (operands[2] == const1_rtx)
5864 return "dec{l}\t%0";
5865 else
5866 abort();
5867
5868 default:
5869 if (! rtx_equal_p (operands[0], operands[1]))
5870 abort ();
5871 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5872 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5873 if ((INTVAL (operands[2]) == -128
5874 || (INTVAL (operands[2]) > 0
5875 && INTVAL (operands[2]) != 128)))
5876 return "sub{l}\t{%2, %0|%0, %2}";
5877 operands[2] = GEN_INT (-INTVAL (operands[2]));
5878 return "add{l}\t{%2, %0|%0, %2}";
5879 }
5880 }
5881 [(set (attr "type")
5882 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5883 (const_string "incdec")
5884 (const_string "alu")))
5885 (set_attr "mode" "SI")])
5886
5887 (define_insn "*addsi_5"
5888 [(set (reg 17)
5889 (compare
5890 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5891 (match_operand:SI 2 "general_operand" "rmni"))
5892 (const_int 0)))
5893 (clobber (match_scratch:SI 0 "=r"))]
5894 "ix86_match_ccmode (insn, CCGOCmode)
5895 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5896 /* Current assemblers are broken and do not allow @GOTOFF in
5897 ought but a memory context. */
5898 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5899 {
5900 switch (get_attr_type (insn))
5901 {
5902 case TYPE_INCDEC:
5903 if (! rtx_equal_p (operands[0], operands[1]))
5904 abort ();
5905 if (operands[2] == const1_rtx)
5906 return "inc{l}\t%0";
5907 else if (operands[2] == constm1_rtx)
5908 return "dec{l}\t%0";
5909 else
5910 abort();
5911
5912 default:
5913 if (! rtx_equal_p (operands[0], operands[1]))
5914 abort ();
5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5917 if (GET_CODE (operands[2]) == CONST_INT
5918 && (INTVAL (operands[2]) == 128
5919 || (INTVAL (operands[2]) < 0
5920 && INTVAL (operands[2]) != -128)))
5921 {
5922 operands[2] = GEN_INT (-INTVAL (operands[2]));
5923 return "sub{l}\t{%2, %0|%0, %2}";
5924 }
5925 return "add{l}\t{%2, %0|%0, %2}";
5926 }
5927 }
5928 [(set (attr "type")
5929 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5930 (const_string "incdec")
5931 (const_string "alu")))
5932 (set_attr "mode" "SI")])
5933
5934 (define_expand "addhi3"
5935 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5936 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5937 (match_operand:HI 2 "general_operand" "")))
5938 (clobber (reg:CC 17))])]
5939 "TARGET_HIMODE_MATH"
5940 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5941
5942 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5943 ;; type optimizations enabled by define-splits. This is not important
5944 ;; for PII, and in fact harmful because of partial register stalls.
5945
5946 (define_insn "*addhi_1_lea"
5947 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5948 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5949 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5950 (clobber (reg:CC 17))]
5951 "!TARGET_PARTIAL_REG_STALL
5952 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5953 {
5954 switch (get_attr_type (insn))
5955 {
5956 case TYPE_LEA:
5957 return "#";
5958 case TYPE_INCDEC:
5959 if (operands[2] == const1_rtx)
5960 return "inc{w}\t%0";
5961 else if (operands[2] == constm1_rtx)
5962 return "dec{w}\t%0";
5963 abort();
5964
5965 default:
5966 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5968 if (GET_CODE (operands[2]) == CONST_INT
5969 && (INTVAL (operands[2]) == 128
5970 || (INTVAL (operands[2]) < 0
5971 && INTVAL (operands[2]) != -128)))
5972 {
5973 operands[2] = GEN_INT (-INTVAL (operands[2]));
5974 return "sub{w}\t{%2, %0|%0, %2}";
5975 }
5976 return "add{w}\t{%2, %0|%0, %2}";
5977 }
5978 }
5979 [(set (attr "type")
5980 (if_then_else (eq_attr "alternative" "2")
5981 (const_string "lea")
5982 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5983 (const_string "incdec")
5984 (const_string "alu"))))
5985 (set_attr "mode" "HI,HI,SI")])
5986
5987 (define_insn "*addhi_1"
5988 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5989 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5990 (match_operand:HI 2 "general_operand" "ri,rm")))
5991 (clobber (reg:CC 17))]
5992 "TARGET_PARTIAL_REG_STALL
5993 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5994 {
5995 switch (get_attr_type (insn))
5996 {
5997 case TYPE_INCDEC:
5998 if (operands[2] == const1_rtx)
5999 return "inc{w}\t%0";
6000 else if (operands[2] == constm1_rtx)
6001 return "dec{w}\t%0";
6002 abort();
6003
6004 default:
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (GET_CODE (operands[2]) == CONST_INT
6008 && (INTVAL (operands[2]) == 128
6009 || (INTVAL (operands[2]) < 0
6010 && INTVAL (operands[2]) != -128)))
6011 {
6012 operands[2] = GEN_INT (-INTVAL (operands[2]));
6013 return "sub{w}\t{%2, %0|%0, %2}";
6014 }
6015 return "add{w}\t{%2, %0|%0, %2}";
6016 }
6017 }
6018 [(set (attr "type")
6019 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020 (const_string "incdec")
6021 (const_string "alu")))
6022 (set_attr "mode" "HI")])
6023
6024 (define_insn "*addhi_2"
6025 [(set (reg 17)
6026 (compare
6027 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6028 (match_operand:HI 2 "general_operand" "rmni,rni"))
6029 (const_int 0)))
6030 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6031 (plus:HI (match_dup 1) (match_dup 2)))]
6032 "ix86_match_ccmode (insn, CCGOCmode)
6033 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6034 {
6035 switch (get_attr_type (insn))
6036 {
6037 case TYPE_INCDEC:
6038 if (operands[2] == const1_rtx)
6039 return "inc{w}\t%0";
6040 else if (operands[2] == constm1_rtx)
6041 return "dec{w}\t%0";
6042 abort();
6043
6044 default:
6045 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6046 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6047 if (GET_CODE (operands[2]) == CONST_INT
6048 && (INTVAL (operands[2]) == 128
6049 || (INTVAL (operands[2]) < 0
6050 && INTVAL (operands[2]) != -128)))
6051 {
6052 operands[2] = GEN_INT (-INTVAL (operands[2]));
6053 return "sub{w}\t{%2, %0|%0, %2}";
6054 }
6055 return "add{w}\t{%2, %0|%0, %2}";
6056 }
6057 }
6058 [(set (attr "type")
6059 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6060 (const_string "incdec")
6061 (const_string "alu")))
6062 (set_attr "mode" "HI")])
6063
6064 (define_insn "*addhi_3"
6065 [(set (reg 17)
6066 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6067 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6068 (clobber (match_scratch:HI 0 "=r"))]
6069 "ix86_match_ccmode (insn, CCZmode)
6070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6071 {
6072 switch (get_attr_type (insn))
6073 {
6074 case TYPE_INCDEC:
6075 if (operands[2] == const1_rtx)
6076 return "inc{w}\t%0";
6077 else if (operands[2] == constm1_rtx)
6078 return "dec{w}\t%0";
6079 abort();
6080
6081 default:
6082 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6083 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6084 if (GET_CODE (operands[2]) == CONST_INT
6085 && (INTVAL (operands[2]) == 128
6086 || (INTVAL (operands[2]) < 0
6087 && INTVAL (operands[2]) != -128)))
6088 {
6089 operands[2] = GEN_INT (-INTVAL (operands[2]));
6090 return "sub{w}\t{%2, %0|%0, %2}";
6091 }
6092 return "add{w}\t{%2, %0|%0, %2}";
6093 }
6094 }
6095 [(set (attr "type")
6096 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6097 (const_string "incdec")
6098 (const_string "alu")))
6099 (set_attr "mode" "HI")])
6100
6101 ; See comments above addsi_3_imm for details.
6102 (define_insn "*addhi_4"
6103 [(set (reg 17)
6104 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6105 (match_operand:HI 2 "const_int_operand" "n")))
6106 (clobber (match_scratch:HI 0 "=rm"))]
6107 "ix86_match_ccmode (insn, CCGCmode)
6108 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6109 {
6110 switch (get_attr_type (insn))
6111 {
6112 case TYPE_INCDEC:
6113 if (operands[2] == constm1_rtx)
6114 return "inc{w}\t%0";
6115 else if (operands[2] == const1_rtx)
6116 return "dec{w}\t%0";
6117 else
6118 abort();
6119
6120 default:
6121 if (! rtx_equal_p (operands[0], operands[1]))
6122 abort ();
6123 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6124 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6125 if ((INTVAL (operands[2]) == -128
6126 || (INTVAL (operands[2]) > 0
6127 && INTVAL (operands[2]) != 128)))
6128 return "sub{w}\t{%2, %0|%0, %2}";
6129 operands[2] = GEN_INT (-INTVAL (operands[2]));
6130 return "add{w}\t{%2, %0|%0, %2}";
6131 }
6132 }
6133 [(set (attr "type")
6134 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu")))
6137 (set_attr "mode" "SI")])
6138
6139
6140 (define_insn "*addhi_5"
6141 [(set (reg 17)
6142 (compare
6143 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6144 (match_operand:HI 2 "general_operand" "rmni"))
6145 (const_int 0)))
6146 (clobber (match_scratch:HI 0 "=r"))]
6147 "ix86_match_ccmode (insn, CCGOCmode)
6148 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6149 {
6150 switch (get_attr_type (insn))
6151 {
6152 case TYPE_INCDEC:
6153 if (operands[2] == const1_rtx)
6154 return "inc{w}\t%0";
6155 else if (operands[2] == constm1_rtx)
6156 return "dec{w}\t%0";
6157 abort();
6158
6159 default:
6160 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6161 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6162 if (GET_CODE (operands[2]) == CONST_INT
6163 && (INTVAL (operands[2]) == 128
6164 || (INTVAL (operands[2]) < 0
6165 && INTVAL (operands[2]) != -128)))
6166 {
6167 operands[2] = GEN_INT (-INTVAL (operands[2]));
6168 return "sub{w}\t{%2, %0|%0, %2}";
6169 }
6170 return "add{w}\t{%2, %0|%0, %2}";
6171 }
6172 }
6173 [(set (attr "type")
6174 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set_attr "mode" "HI")])
6178
6179 (define_expand "addqi3"
6180 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6181 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6182 (match_operand:QI 2 "general_operand" "")))
6183 (clobber (reg:CC 17))])]
6184 "TARGET_QIMODE_MATH"
6185 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6186
6187 ;; %%% Potential partial reg stall on alternative 2. What to do?
6188 (define_insn "*addqi_1_lea"
6189 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6190 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6191 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6192 (clobber (reg:CC 17))]
6193 "!TARGET_PARTIAL_REG_STALL
6194 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6195 {
6196 int widen = (which_alternative == 2);
6197 switch (get_attr_type (insn))
6198 {
6199 case TYPE_LEA:
6200 return "#";
6201 case TYPE_INCDEC:
6202 if (operands[2] == const1_rtx)
6203 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6204 else if (operands[2] == constm1_rtx)
6205 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6206 abort();
6207
6208 default:
6209 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6210 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6211 if (GET_CODE (operands[2]) == CONST_INT
6212 && (INTVAL (operands[2]) == 128
6213 || (INTVAL (operands[2]) < 0
6214 && INTVAL (operands[2]) != -128)))
6215 {
6216 operands[2] = GEN_INT (-INTVAL (operands[2]));
6217 if (widen)
6218 return "sub{l}\t{%2, %k0|%k0, %2}";
6219 else
6220 return "sub{b}\t{%2, %0|%0, %2}";
6221 }
6222 if (widen)
6223 return "add{l}\t{%k2, %k0|%k0, %k2}";
6224 else
6225 return "add{b}\t{%2, %0|%0, %2}";
6226 }
6227 }
6228 [(set (attr "type")
6229 (if_then_else (eq_attr "alternative" "3")
6230 (const_string "lea")
6231 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6232 (const_string "incdec")
6233 (const_string "alu"))))
6234 (set_attr "mode" "QI,QI,SI,SI")])
6235
6236 (define_insn "*addqi_1"
6237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6238 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6239 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6240 (clobber (reg:CC 17))]
6241 "TARGET_PARTIAL_REG_STALL
6242 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6243 {
6244 int widen = (which_alternative == 2);
6245 switch (get_attr_type (insn))
6246 {
6247 case TYPE_INCDEC:
6248 if (operands[2] == const1_rtx)
6249 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6250 else if (operands[2] == constm1_rtx)
6251 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6252 abort();
6253
6254 default:
6255 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6256 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6257 if (GET_CODE (operands[2]) == CONST_INT
6258 && (INTVAL (operands[2]) == 128
6259 || (INTVAL (operands[2]) < 0
6260 && INTVAL (operands[2]) != -128)))
6261 {
6262 operands[2] = GEN_INT (-INTVAL (operands[2]));
6263 if (widen)
6264 return "sub{l}\t{%2, %k0|%k0, %2}";
6265 else
6266 return "sub{b}\t{%2, %0|%0, %2}";
6267 }
6268 if (widen)
6269 return "add{l}\t{%k2, %k0|%k0, %k2}";
6270 else
6271 return "add{b}\t{%2, %0|%0, %2}";
6272 }
6273 }
6274 [(set (attr "type")
6275 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6276 (const_string "incdec")
6277 (const_string "alu")))
6278 (set_attr "mode" "QI,QI,SI")])
6279
6280 (define_insn "*addqi_1_slp"
6281 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6282 (plus:QI (match_dup 0)
6283 (match_operand:QI 1 "general_operand" "qn,qnm")))
6284 (clobber (reg:CC 17))]
6285 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6286 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6287 {
6288 switch (get_attr_type (insn))
6289 {
6290 case TYPE_INCDEC:
6291 if (operands[1] == const1_rtx)
6292 return "inc{b}\t%0";
6293 else if (operands[1] == constm1_rtx)
6294 return "dec{b}\t%0";
6295 abort();
6296
6297 default:
6298 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6299 if (GET_CODE (operands[1]) == CONST_INT
6300 && INTVAL (operands[1]) < 0)
6301 {
6302 operands[1] = GEN_INT (-INTVAL (operands[1]));
6303 return "sub{b}\t{%1, %0|%0, %1}";
6304 }
6305 return "add{b}\t{%1, %0|%0, %1}";
6306 }
6307 }
6308 [(set (attr "type")
6309 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu1")))
6312 (set_attr "mode" "QI")])
6313
6314 (define_insn "*addqi_2"
6315 [(set (reg 17)
6316 (compare
6317 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6318 (match_operand:QI 2 "general_operand" "qmni,qni"))
6319 (const_int 0)))
6320 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6321 (plus:QI (match_dup 1) (match_dup 2)))]
6322 "ix86_match_ccmode (insn, CCGOCmode)
6323 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6324 {
6325 switch (get_attr_type (insn))
6326 {
6327 case TYPE_INCDEC:
6328 if (operands[2] == const1_rtx)
6329 return "inc{b}\t%0";
6330 else if (operands[2] == constm1_rtx
6331 || (GET_CODE (operands[2]) == CONST_INT
6332 && INTVAL (operands[2]) == 255))
6333 return "dec{b}\t%0";
6334 abort();
6335
6336 default:
6337 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6338 if (GET_CODE (operands[2]) == CONST_INT
6339 && INTVAL (operands[2]) < 0)
6340 {
6341 operands[2] = GEN_INT (-INTVAL (operands[2]));
6342 return "sub{b}\t{%2, %0|%0, %2}";
6343 }
6344 return "add{b}\t{%2, %0|%0, %2}";
6345 }
6346 }
6347 [(set (attr "type")
6348 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6349 (const_string "incdec")
6350 (const_string "alu")))
6351 (set_attr "mode" "QI")])
6352
6353 (define_insn "*addqi_3"
6354 [(set (reg 17)
6355 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6356 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6357 (clobber (match_scratch:QI 0 "=q"))]
6358 "ix86_match_ccmode (insn, CCZmode)
6359 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6360 {
6361 switch (get_attr_type (insn))
6362 {
6363 case TYPE_INCDEC:
6364 if (operands[2] == const1_rtx)
6365 return "inc{b}\t%0";
6366 else if (operands[2] == constm1_rtx
6367 || (GET_CODE (operands[2]) == CONST_INT
6368 && INTVAL (operands[2]) == 255))
6369 return "dec{b}\t%0";
6370 abort();
6371
6372 default:
6373 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6374 if (GET_CODE (operands[2]) == CONST_INT
6375 && INTVAL (operands[2]) < 0)
6376 {
6377 operands[2] = GEN_INT (-INTVAL (operands[2]));
6378 return "sub{b}\t{%2, %0|%0, %2}";
6379 }
6380 return "add{b}\t{%2, %0|%0, %2}";
6381 }
6382 }
6383 [(set (attr "type")
6384 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6385 (const_string "incdec")
6386 (const_string "alu")))
6387 (set_attr "mode" "QI")])
6388
6389 ; See comments above addsi_3_imm for details.
6390 (define_insn "*addqi_4"
6391 [(set (reg 17)
6392 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6393 (match_operand:QI 2 "const_int_operand" "n")))
6394 (clobber (match_scratch:QI 0 "=qm"))]
6395 "ix86_match_ccmode (insn, CCGCmode)
6396 && (INTVAL (operands[2]) & 0xff) != 0x80"
6397 {
6398 switch (get_attr_type (insn))
6399 {
6400 case TYPE_INCDEC:
6401 if (operands[2] == constm1_rtx
6402 || (GET_CODE (operands[2]) == CONST_INT
6403 && INTVAL (operands[2]) == 255))
6404 return "inc{b}\t%0";
6405 else if (operands[2] == const1_rtx)
6406 return "dec{b}\t%0";
6407 else
6408 abort();
6409
6410 default:
6411 if (! rtx_equal_p (operands[0], operands[1]))
6412 abort ();
6413 if (INTVAL (operands[2]) < 0)
6414 {
6415 operands[2] = GEN_INT (-INTVAL (operands[2]));
6416 return "add{b}\t{%2, %0|%0, %2}";
6417 }
6418 return "sub{b}\t{%2, %0|%0, %2}";
6419 }
6420 }
6421 [(set (attr "type")
6422 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6423 (const_string "incdec")
6424 (const_string "alu")))
6425 (set_attr "mode" "QI")])
6426
6427
6428 (define_insn "*addqi_5"
6429 [(set (reg 17)
6430 (compare
6431 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6432 (match_operand:QI 2 "general_operand" "qmni"))
6433 (const_int 0)))
6434 (clobber (match_scratch:QI 0 "=q"))]
6435 "ix86_match_ccmode (insn, CCGOCmode)
6436 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6437 {
6438 switch (get_attr_type (insn))
6439 {
6440 case TYPE_INCDEC:
6441 if (operands[2] == const1_rtx)
6442 return "inc{b}\t%0";
6443 else if (operands[2] == constm1_rtx
6444 || (GET_CODE (operands[2]) == CONST_INT
6445 && INTVAL (operands[2]) == 255))
6446 return "dec{b}\t%0";
6447 abort();
6448
6449 default:
6450 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6451 if (GET_CODE (operands[2]) == CONST_INT
6452 && INTVAL (operands[2]) < 0)
6453 {
6454 operands[2] = GEN_INT (-INTVAL (operands[2]));
6455 return "sub{b}\t{%2, %0|%0, %2}";
6456 }
6457 return "add{b}\t{%2, %0|%0, %2}";
6458 }
6459 }
6460 [(set (attr "type")
6461 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6462 (const_string "incdec")
6463 (const_string "alu")))
6464 (set_attr "mode" "QI")])
6465
6466
6467 (define_insn "addqi_ext_1"
6468 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6469 (const_int 8)
6470 (const_int 8))
6471 (plus:SI
6472 (zero_extract:SI
6473 (match_operand 1 "ext_register_operand" "0")
6474 (const_int 8)
6475 (const_int 8))
6476 (match_operand:QI 2 "general_operand" "Qmn")))
6477 (clobber (reg:CC 17))]
6478 "!TARGET_64BIT"
6479 {
6480 switch (get_attr_type (insn))
6481 {
6482 case TYPE_INCDEC:
6483 if (operands[2] == const1_rtx)
6484 return "inc{b}\t%h0";
6485 else if (operands[2] == constm1_rtx
6486 || (GET_CODE (operands[2]) == CONST_INT
6487 && INTVAL (operands[2]) == 255))
6488 return "dec{b}\t%h0";
6489 abort();
6490
6491 default:
6492 return "add{b}\t{%2, %h0|%h0, %2}";
6493 }
6494 }
6495 [(set (attr "type")
6496 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6497 (const_string "incdec")
6498 (const_string "alu")))
6499 (set_attr "mode" "QI")])
6500
6501 (define_insn "*addqi_ext_1_rex64"
6502 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6503 (const_int 8)
6504 (const_int 8))
6505 (plus:SI
6506 (zero_extract:SI
6507 (match_operand 1 "ext_register_operand" "0")
6508 (const_int 8)
6509 (const_int 8))
6510 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6511 (clobber (reg:CC 17))]
6512 "TARGET_64BIT"
6513 {
6514 switch (get_attr_type (insn))
6515 {
6516 case TYPE_INCDEC:
6517 if (operands[2] == const1_rtx)
6518 return "inc{b}\t%h0";
6519 else if (operands[2] == constm1_rtx
6520 || (GET_CODE (operands[2]) == CONST_INT
6521 && INTVAL (operands[2]) == 255))
6522 return "dec{b}\t%h0";
6523 abort();
6524
6525 default:
6526 return "add{b}\t{%2, %h0|%h0, %2}";
6527 }
6528 }
6529 [(set (attr "type")
6530 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6531 (const_string "incdec")
6532 (const_string "alu")))
6533 (set_attr "mode" "QI")])
6534
6535 (define_insn "*addqi_ext_2"
6536 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6537 (const_int 8)
6538 (const_int 8))
6539 (plus:SI
6540 (zero_extract:SI
6541 (match_operand 1 "ext_register_operand" "%0")
6542 (const_int 8)
6543 (const_int 8))
6544 (zero_extract:SI
6545 (match_operand 2 "ext_register_operand" "Q")
6546 (const_int 8)
6547 (const_int 8))))
6548 (clobber (reg:CC 17))]
6549 ""
6550 "add{b}\t{%h2, %h0|%h0, %h2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "mode" "QI")])
6553
6554 ;; The patterns that match these are at the end of this file.
6555
6556 (define_expand "addxf3"
6557 [(set (match_operand:XF 0 "register_operand" "")
6558 (plus:XF (match_operand:XF 1 "register_operand" "")
6559 (match_operand:XF 2 "register_operand" "")))]
6560 "TARGET_80387"
6561 "")
6562
6563 (define_expand "adddf3"
6564 [(set (match_operand:DF 0 "register_operand" "")
6565 (plus:DF (match_operand:DF 1 "register_operand" "")
6566 (match_operand:DF 2 "nonimmediate_operand" "")))]
6567 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6568 "")
6569
6570 (define_expand "addsf3"
6571 [(set (match_operand:SF 0 "register_operand" "")
6572 (plus:SF (match_operand:SF 1 "register_operand" "")
6573 (match_operand:SF 2 "nonimmediate_operand" "")))]
6574 "TARGET_80387 || TARGET_SSE_MATH"
6575 "")
6576 \f
6577 ;; Subtract instructions
6578
6579 ;; %%% splits for subsidi3
6580
6581 (define_expand "subdi3"
6582 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6583 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6584 (match_operand:DI 2 "x86_64_general_operand" "")))
6585 (clobber (reg:CC 17))])]
6586 ""
6587 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6588
6589 (define_insn "*subdi3_1"
6590 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6591 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6592 (match_operand:DI 2 "general_operand" "roiF,riF")))
6593 (clobber (reg:CC 17))]
6594 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6595 "#")
6596
6597 (define_split
6598 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6599 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6600 (match_operand:DI 2 "general_operand" "")))
6601 (clobber (reg:CC 17))]
6602 "!TARGET_64BIT && reload_completed"
6603 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6604 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6605 (parallel [(set (match_dup 3)
6606 (minus:SI (match_dup 4)
6607 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6608 (match_dup 5))))
6609 (clobber (reg:CC 17))])]
6610 "split_di (operands+0, 1, operands+0, operands+3);
6611 split_di (operands+1, 1, operands+1, operands+4);
6612 split_di (operands+2, 1, operands+2, operands+5);")
6613
6614 (define_insn "subdi3_carry_rex64"
6615 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6616 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6617 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6618 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6619 (clobber (reg:CC 17))]
6620 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6621 "sbb{q}\t{%2, %0|%0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "pent_pair" "pu")
6624 (set_attr "mode" "DI")])
6625
6626 (define_insn "*subdi_1_rex64"
6627 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6628 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6629 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6630 (clobber (reg:CC 17))]
6631 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6632 "sub{q}\t{%2, %0|%0, %2}"
6633 [(set_attr "type" "alu")
6634 (set_attr "mode" "DI")])
6635
6636 (define_insn "*subdi_2_rex64"
6637 [(set (reg 17)
6638 (compare
6639 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6640 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6641 (const_int 0)))
6642 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6643 (minus:DI (match_dup 1) (match_dup 2)))]
6644 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6645 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6646 "sub{q}\t{%2, %0|%0, %2}"
6647 [(set_attr "type" "alu")
6648 (set_attr "mode" "DI")])
6649
6650 (define_insn "*subdi_3_rex63"
6651 [(set (reg 17)
6652 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6653 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6654 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6655 (minus:DI (match_dup 1) (match_dup 2)))]
6656 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6657 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6658 "sub{q}\t{%2, %0|%0, %2}"
6659 [(set_attr "type" "alu")
6660 (set_attr "mode" "DI")])
6661
6662 (define_insn "subqi3_carry"
6663 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6664 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6665 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6666 (match_operand:QI 2 "general_operand" "qi,qm"))))
6667 (clobber (reg:CC 17))]
6668 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6669 "sbb{b}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "pent_pair" "pu")
6672 (set_attr "mode" "QI")])
6673
6674 (define_insn "subhi3_carry"
6675 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6676 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6677 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6678 (match_operand:HI 2 "general_operand" "ri,rm"))))
6679 (clobber (reg:CC 17))]
6680 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6681 "sbb{w}\t{%2, %0|%0, %2}"
6682 [(set_attr "type" "alu")
6683 (set_attr "pent_pair" "pu")
6684 (set_attr "mode" "HI")])
6685
6686 (define_insn "subsi3_carry"
6687 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6688 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6689 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6690 (match_operand:SI 2 "general_operand" "ri,rm"))))
6691 (clobber (reg:CC 17))]
6692 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6693 "sbb{l}\t{%2, %0|%0, %2}"
6694 [(set_attr "type" "alu")
6695 (set_attr "pent_pair" "pu")
6696 (set_attr "mode" "SI")])
6697
6698 (define_insn "subsi3_carry_zext"
6699 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6700 (zero_extend:DI
6701 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6702 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6703 (match_operand:SI 2 "general_operand" "ri,rm")))))
6704 (clobber (reg:CC 17))]
6705 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6706 "sbb{l}\t{%2, %k0|%k0, %2}"
6707 [(set_attr "type" "alu")
6708 (set_attr "pent_pair" "pu")
6709 (set_attr "mode" "SI")])
6710
6711 (define_expand "subsi3"
6712 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6713 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6714 (match_operand:SI 2 "general_operand" "")))
6715 (clobber (reg:CC 17))])]
6716 ""
6717 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6718
6719 (define_insn "*subsi_1"
6720 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6721 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6722 (match_operand:SI 2 "general_operand" "ri,rm")))
6723 (clobber (reg:CC 17))]
6724 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6725 "sub{l}\t{%2, %0|%0, %2}"
6726 [(set_attr "type" "alu")
6727 (set_attr "mode" "SI")])
6728
6729 (define_insn "*subsi_1_zext"
6730 [(set (match_operand:DI 0 "register_operand" "=r")
6731 (zero_extend:DI
6732 (minus:SI (match_operand:SI 1 "register_operand" "0")
6733 (match_operand:SI 2 "general_operand" "rim"))))
6734 (clobber (reg:CC 17))]
6735 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6736 "sub{l}\t{%2, %k0|%k0, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "mode" "SI")])
6739
6740 (define_insn "*subsi_2"
6741 [(set (reg 17)
6742 (compare
6743 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6744 (match_operand:SI 2 "general_operand" "ri,rm"))
6745 (const_int 0)))
6746 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6747 (minus:SI (match_dup 1) (match_dup 2)))]
6748 "ix86_match_ccmode (insn, CCGOCmode)
6749 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750 "sub{l}\t{%2, %0|%0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "mode" "SI")])
6753
6754 (define_insn "*subsi_2_zext"
6755 [(set (reg 17)
6756 (compare
6757 (minus:SI (match_operand:SI 1 "register_operand" "0")
6758 (match_operand:SI 2 "general_operand" "rim"))
6759 (const_int 0)))
6760 (set (match_operand:DI 0 "register_operand" "=r")
6761 (zero_extend:DI
6762 (minus:SI (match_dup 1)
6763 (match_dup 2))))]
6764 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6765 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6766 "sub{l}\t{%2, %k0|%k0, %2}"
6767 [(set_attr "type" "alu")
6768 (set_attr "mode" "SI")])
6769
6770 (define_insn "*subsi_3"
6771 [(set (reg 17)
6772 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:SI 2 "general_operand" "ri,rm")))
6774 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6775 (minus:SI (match_dup 1) (match_dup 2)))]
6776 "ix86_match_ccmode (insn, CCmode)
6777 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6778 "sub{l}\t{%2, %0|%0, %2}"
6779 [(set_attr "type" "alu")
6780 (set_attr "mode" "SI")])
6781
6782 (define_insn "*subsi_3_zext"
6783 [(set (reg 17)
6784 (compare (match_operand:SI 1 "register_operand" "0")
6785 (match_operand:SI 2 "general_operand" "rim")))
6786 (set (match_operand:DI 0 "register_operand" "=r")
6787 (zero_extend:DI
6788 (minus:SI (match_dup 1)
6789 (match_dup 2))))]
6790 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6791 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6792 "sub{q}\t{%2, %0|%0, %2}"
6793 [(set_attr "type" "alu")
6794 (set_attr "mode" "DI")])
6795
6796 (define_expand "subhi3"
6797 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6798 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6799 (match_operand:HI 2 "general_operand" "")))
6800 (clobber (reg:CC 17))])]
6801 "TARGET_HIMODE_MATH"
6802 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6803
6804 (define_insn "*subhi_1"
6805 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6806 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6807 (match_operand:HI 2 "general_operand" "ri,rm")))
6808 (clobber (reg:CC 17))]
6809 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6810 "sub{w}\t{%2, %0|%0, %2}"
6811 [(set_attr "type" "alu")
6812 (set_attr "mode" "HI")])
6813
6814 (define_insn "*subhi_2"
6815 [(set (reg 17)
6816 (compare
6817 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6818 (match_operand:HI 2 "general_operand" "ri,rm"))
6819 (const_int 0)))
6820 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6821 (minus:HI (match_dup 1) (match_dup 2)))]
6822 "ix86_match_ccmode (insn, CCGOCmode)
6823 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6824 "sub{w}\t{%2, %0|%0, %2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "HI")])
6827
6828 (define_insn "*subhi_3"
6829 [(set (reg 17)
6830 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6831 (match_operand:HI 2 "general_operand" "ri,rm")))
6832 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6833 (minus:HI (match_dup 1) (match_dup 2)))]
6834 "ix86_match_ccmode (insn, CCmode)
6835 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6836 "sub{w}\t{%2, %0|%0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "mode" "HI")])
6839
6840 (define_expand "subqi3"
6841 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6842 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6843 (match_operand:QI 2 "general_operand" "")))
6844 (clobber (reg:CC 17))])]
6845 "TARGET_QIMODE_MATH"
6846 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6847
6848 (define_insn "*subqi_1"
6849 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6850 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6851 (match_operand:QI 2 "general_operand" "qn,qmn")))
6852 (clobber (reg:CC 17))]
6853 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6854 "sub{b}\t{%2, %0|%0, %2}"
6855 [(set_attr "type" "alu")
6856 (set_attr "mode" "QI")])
6857
6858 (define_insn "*subqi_1_slp"
6859 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6860 (minus:QI (match_dup 0)
6861 (match_operand:QI 1 "general_operand" "qn,qmn")))
6862 (clobber (reg:CC 17))]
6863 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6864 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6865 "sub{b}\t{%1, %0|%0, %1}"
6866 [(set_attr "type" "alu1")
6867 (set_attr "mode" "QI")])
6868
6869 (define_insn "*subqi_2"
6870 [(set (reg 17)
6871 (compare
6872 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6873 (match_operand:QI 2 "general_operand" "qi,qm"))
6874 (const_int 0)))
6875 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6876 (minus:HI (match_dup 1) (match_dup 2)))]
6877 "ix86_match_ccmode (insn, CCGOCmode)
6878 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6879 "sub{b}\t{%2, %0|%0, %2}"
6880 [(set_attr "type" "alu")
6881 (set_attr "mode" "QI")])
6882
6883 (define_insn "*subqi_3"
6884 [(set (reg 17)
6885 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6886 (match_operand:QI 2 "general_operand" "qi,qm")))
6887 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6888 (minus:HI (match_dup 1) (match_dup 2)))]
6889 "ix86_match_ccmode (insn, CCmode)
6890 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6891 "sub{b}\t{%2, %0|%0, %2}"
6892 [(set_attr "type" "alu")
6893 (set_attr "mode" "QI")])
6894
6895 ;; The patterns that match these are at the end of this file.
6896
6897 (define_expand "subxf3"
6898 [(set (match_operand:XF 0 "register_operand" "")
6899 (minus:XF (match_operand:XF 1 "register_operand" "")
6900 (match_operand:XF 2 "register_operand" "")))]
6901 "TARGET_80387"
6902 "")
6903
6904 (define_expand "subdf3"
6905 [(set (match_operand:DF 0 "register_operand" "")
6906 (minus:DF (match_operand:DF 1 "register_operand" "")
6907 (match_operand:DF 2 "nonimmediate_operand" "")))]
6908 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6909 "")
6910
6911 (define_expand "subsf3"
6912 [(set (match_operand:SF 0 "register_operand" "")
6913 (minus:SF (match_operand:SF 1 "register_operand" "")
6914 (match_operand:SF 2 "nonimmediate_operand" "")))]
6915 "TARGET_80387 || TARGET_SSE_MATH"
6916 "")
6917 \f
6918 ;; Multiply instructions
6919
6920 (define_expand "muldi3"
6921 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6922 (mult:DI (match_operand:DI 1 "register_operand" "")
6923 (match_operand:DI 2 "x86_64_general_operand" "")))
6924 (clobber (reg:CC 17))])]
6925 "TARGET_64BIT"
6926 "")
6927
6928 (define_insn "*muldi3_1_rex64"
6929 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6930 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6931 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6932 (clobber (reg:CC 17))]
6933 "TARGET_64BIT
6934 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6935 "@
6936 imul{q}\t{%2, %1, %0|%0, %1, %2}
6937 imul{q}\t{%2, %1, %0|%0, %1, %2}
6938 imul{q}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "1")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "2")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set_attr "mode" "DI")])
6951
6952 (define_expand "mulsi3"
6953 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6954 (mult:SI (match_operand:SI 1 "register_operand" "")
6955 (match_operand:SI 2 "general_operand" "")))
6956 (clobber (reg:CC 17))])]
6957 ""
6958 "")
6959
6960 (define_insn "*mulsi3_1"
6961 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6962 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6963 (match_operand:SI 2 "general_operand" "K,i,mr")))
6964 (clobber (reg:CC 17))]
6965 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6966 "@
6967 imul{l}\t{%2, %1, %0|%0, %1, %2}
6968 imul{l}\t{%2, %1, %0|%0, %1, %2}
6969 imul{l}\t{%2, %0|%0, %2}"
6970 [(set_attr "type" "imul")
6971 (set_attr "prefix_0f" "0,0,1")
6972 (set (attr "athlon_decode")
6973 (cond [(eq_attr "cpu" "athlon")
6974 (const_string "vector")
6975 (eq_attr "alternative" "1")
6976 (const_string "vector")
6977 (and (eq_attr "alternative" "2")
6978 (match_operand 1 "memory_operand" ""))
6979 (const_string "vector")]
6980 (const_string "direct")))
6981 (set_attr "mode" "SI")])
6982
6983 (define_insn "*mulsi3_1_zext"
6984 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6985 (zero_extend:DI
6986 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6987 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6988 (clobber (reg:CC 17))]
6989 "TARGET_64BIT
6990 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6991 "@
6992 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6993 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6994 imul{l}\t{%2, %k0|%k0, %2}"
6995 [(set_attr "type" "imul")
6996 (set_attr "prefix_0f" "0,0,1")
6997 (set (attr "athlon_decode")
6998 (cond [(eq_attr "cpu" "athlon")
6999 (const_string "vector")
7000 (eq_attr "alternative" "1")
7001 (const_string "vector")
7002 (and (eq_attr "alternative" "2")
7003 (match_operand 1 "memory_operand" ""))
7004 (const_string "vector")]
7005 (const_string "direct")))
7006 (set_attr "mode" "SI")])
7007
7008 (define_expand "mulhi3"
7009 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7010 (mult:HI (match_operand:HI 1 "register_operand" "")
7011 (match_operand:HI 2 "general_operand" "")))
7012 (clobber (reg:CC 17))])]
7013 "TARGET_HIMODE_MATH"
7014 "")
7015
7016 (define_insn "*mulhi3_1"
7017 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7018 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7019 (match_operand:HI 2 "general_operand" "K,i,mr")))
7020 (clobber (reg:CC 17))]
7021 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7022 "@
7023 imul{w}\t{%2, %1, %0|%0, %1, %2}
7024 imul{w}\t{%2, %1, %0|%0, %1, %2}
7025 imul{w}\t{%2, %0|%0, %2}"
7026 [(set_attr "type" "imul")
7027 (set_attr "prefix_0f" "0,0,1")
7028 (set (attr "athlon_decode")
7029 (cond [(eq_attr "cpu" "athlon")
7030 (const_string "vector")
7031 (eq_attr "alternative" "1,2")
7032 (const_string "vector")]
7033 (const_string "direct")))
7034 (set_attr "mode" "HI")])
7035
7036 (define_expand "mulqi3"
7037 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7038 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7039 (match_operand:QI 2 "register_operand" "")))
7040 (clobber (reg:CC 17))])]
7041 "TARGET_QIMODE_MATH"
7042 "")
7043
7044 (define_insn "*mulqi3_1"
7045 [(set (match_operand:QI 0 "register_operand" "=a")
7046 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7047 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7048 (clobber (reg:CC 17))]
7049 "TARGET_QIMODE_MATH
7050 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7051 "mul{b}\t%2"
7052 [(set_attr "type" "imul")
7053 (set_attr "length_immediate" "0")
7054 (set (attr "athlon_decode")
7055 (if_then_else (eq_attr "cpu" "athlon")
7056 (const_string "vector")
7057 (const_string "direct")))
7058 (set_attr "mode" "QI")])
7059
7060 (define_expand "umulqihi3"
7061 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7062 (mult:HI (zero_extend:HI
7063 (match_operand:QI 1 "nonimmediate_operand" ""))
7064 (zero_extend:HI
7065 (match_operand:QI 2 "register_operand" ""))))
7066 (clobber (reg:CC 17))])]
7067 "TARGET_QIMODE_MATH"
7068 "")
7069
7070 (define_insn "*umulqihi3_1"
7071 [(set (match_operand:HI 0 "register_operand" "=a")
7072 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7073 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7074 (clobber (reg:CC 17))]
7075 "TARGET_QIMODE_MATH
7076 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7077 "mul{b}\t%2"
7078 [(set_attr "type" "imul")
7079 (set_attr "length_immediate" "0")
7080 (set (attr "athlon_decode")
7081 (if_then_else (eq_attr "cpu" "athlon")
7082 (const_string "vector")
7083 (const_string "direct")))
7084 (set_attr "mode" "QI")])
7085
7086 (define_expand "mulqihi3"
7087 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7088 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7089 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7090 (clobber (reg:CC 17))])]
7091 "TARGET_QIMODE_MATH"
7092 "")
7093
7094 (define_insn "*mulqihi3_insn"
7095 [(set (match_operand:HI 0 "register_operand" "=a")
7096 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7097 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7098 (clobber (reg:CC 17))]
7099 "TARGET_QIMODE_MATH
7100 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7101 "imul{b}\t%2"
7102 [(set_attr "type" "imul")
7103 (set_attr "length_immediate" "0")
7104 (set (attr "athlon_decode")
7105 (if_then_else (eq_attr "cpu" "athlon")
7106 (const_string "vector")
7107 (const_string "direct")))
7108 (set_attr "mode" "QI")])
7109
7110 (define_expand "umulditi3"
7111 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7112 (mult:TI (zero_extend:TI
7113 (match_operand:DI 1 "nonimmediate_operand" ""))
7114 (zero_extend:TI
7115 (match_operand:DI 2 "register_operand" ""))))
7116 (clobber (reg:CC 17))])]
7117 "TARGET_64BIT"
7118 "")
7119
7120 (define_insn "*umulditi3_insn"
7121 [(set (match_operand:TI 0 "register_operand" "=A")
7122 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7123 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7124 (clobber (reg:CC 17))]
7125 "TARGET_64BIT
7126 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7127 "mul{q}\t%2"
7128 [(set_attr "type" "imul")
7129 (set_attr "length_immediate" "0")
7130 (set (attr "athlon_decode")
7131 (if_then_else (eq_attr "cpu" "athlon")
7132 (const_string "vector")
7133 (const_string "double")))
7134 (set_attr "mode" "DI")])
7135
7136 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7137 (define_expand "umulsidi3"
7138 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7139 (mult:DI (zero_extend:DI
7140 (match_operand:SI 1 "nonimmediate_operand" ""))
7141 (zero_extend:DI
7142 (match_operand:SI 2 "register_operand" ""))))
7143 (clobber (reg:CC 17))])]
7144 "!TARGET_64BIT"
7145 "")
7146
7147 (define_insn "*umulsidi3_insn"
7148 [(set (match_operand:DI 0 "register_operand" "=A")
7149 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7150 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7151 (clobber (reg:CC 17))]
7152 "!TARGET_64BIT
7153 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7154 "mul{l}\t%2"
7155 [(set_attr "type" "imul")
7156 (set_attr "length_immediate" "0")
7157 (set (attr "athlon_decode")
7158 (if_then_else (eq_attr "cpu" "athlon")
7159 (const_string "vector")
7160 (const_string "double")))
7161 (set_attr "mode" "SI")])
7162
7163 (define_expand "mulditi3"
7164 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7165 (mult:TI (sign_extend:TI
7166 (match_operand:DI 1 "nonimmediate_operand" ""))
7167 (sign_extend:TI
7168 (match_operand:DI 2 "register_operand" ""))))
7169 (clobber (reg:CC 17))])]
7170 "TARGET_64BIT"
7171 "")
7172
7173 (define_insn "*mulditi3_insn"
7174 [(set (match_operand:TI 0 "register_operand" "=A")
7175 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7176 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7177 (clobber (reg:CC 17))]
7178 "TARGET_64BIT
7179 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7180 "imul{q}\t%2"
7181 [(set_attr "type" "imul")
7182 (set_attr "length_immediate" "0")
7183 (set (attr "athlon_decode")
7184 (if_then_else (eq_attr "cpu" "athlon")
7185 (const_string "vector")
7186 (const_string "double")))
7187 (set_attr "mode" "DI")])
7188
7189 (define_expand "mulsidi3"
7190 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7191 (mult:DI (sign_extend:DI
7192 (match_operand:SI 1 "nonimmediate_operand" ""))
7193 (sign_extend:DI
7194 (match_operand:SI 2 "register_operand" ""))))
7195 (clobber (reg:CC 17))])]
7196 "!TARGET_64BIT"
7197 "")
7198
7199 (define_insn "*mulsidi3_insn"
7200 [(set (match_operand:DI 0 "register_operand" "=A")
7201 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7202 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7203 (clobber (reg:CC 17))]
7204 "!TARGET_64BIT
7205 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7206 "imul{l}\t%2"
7207 [(set_attr "type" "imul")
7208 (set_attr "length_immediate" "0")
7209 (set (attr "athlon_decode")
7210 (if_then_else (eq_attr "cpu" "athlon")
7211 (const_string "vector")
7212 (const_string "double")))
7213 (set_attr "mode" "SI")])
7214
7215 (define_expand "umuldi3_highpart"
7216 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7217 (truncate:DI
7218 (lshiftrt:TI
7219 (mult:TI (zero_extend:TI
7220 (match_operand:DI 1 "nonimmediate_operand" ""))
7221 (zero_extend:TI
7222 (match_operand:DI 2 "register_operand" "")))
7223 (const_int 64))))
7224 (clobber (match_scratch:DI 3 ""))
7225 (clobber (reg:CC 17))])]
7226 "TARGET_64BIT"
7227 "")
7228
7229 (define_insn "*umuldi3_highpart_rex64"
7230 [(set (match_operand:DI 0 "register_operand" "=d")
7231 (truncate:DI
7232 (lshiftrt:TI
7233 (mult:TI (zero_extend:TI
7234 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7235 (zero_extend:TI
7236 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7237 (const_int 64))))
7238 (clobber (match_scratch:DI 3 "=1"))
7239 (clobber (reg:CC 17))]
7240 "TARGET_64BIT
7241 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7242 "mul{q}\t%2"
7243 [(set_attr "type" "imul")
7244 (set_attr "length_immediate" "0")
7245 (set (attr "athlon_decode")
7246 (if_then_else (eq_attr "cpu" "athlon")
7247 (const_string "vector")
7248 (const_string "double")))
7249 (set_attr "mode" "DI")])
7250
7251 (define_expand "umulsi3_highpart"
7252 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7253 (truncate:SI
7254 (lshiftrt:DI
7255 (mult:DI (zero_extend:DI
7256 (match_operand:SI 1 "nonimmediate_operand" ""))
7257 (zero_extend:DI
7258 (match_operand:SI 2 "register_operand" "")))
7259 (const_int 32))))
7260 (clobber (match_scratch:SI 3 ""))
7261 (clobber (reg:CC 17))])]
7262 ""
7263 "")
7264
7265 (define_insn "*umulsi3_highpart_insn"
7266 [(set (match_operand:SI 0 "register_operand" "=d")
7267 (truncate:SI
7268 (lshiftrt:DI
7269 (mult:DI (zero_extend:DI
7270 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7271 (zero_extend:DI
7272 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7273 (const_int 32))))
7274 (clobber (match_scratch:SI 3 "=1"))
7275 (clobber (reg:CC 17))]
7276 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7277 "mul{l}\t%2"
7278 [(set_attr "type" "imul")
7279 (set_attr "length_immediate" "0")
7280 (set (attr "athlon_decode")
7281 (if_then_else (eq_attr "cpu" "athlon")
7282 (const_string "vector")
7283 (const_string "double")))
7284 (set_attr "mode" "SI")])
7285
7286 (define_insn "*umulsi3_highpart_zext"
7287 [(set (match_operand:DI 0 "register_operand" "=d")
7288 (zero_extend:DI (truncate:SI
7289 (lshiftrt:DI
7290 (mult:DI (zero_extend:DI
7291 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7292 (zero_extend:DI
7293 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7294 (const_int 32)))))
7295 (clobber (match_scratch:SI 3 "=1"))
7296 (clobber (reg:CC 17))]
7297 "TARGET_64BIT
7298 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7299 "mul{l}\t%2"
7300 [(set_attr "type" "imul")
7301 (set_attr "length_immediate" "0")
7302 (set (attr "athlon_decode")
7303 (if_then_else (eq_attr "cpu" "athlon")
7304 (const_string "vector")
7305 (const_string "double")))
7306 (set_attr "mode" "SI")])
7307
7308 (define_expand "smuldi3_highpart"
7309 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7310 (truncate:DI
7311 (lshiftrt:TI
7312 (mult:TI (sign_extend:TI
7313 (match_operand:DI 1 "nonimmediate_operand" ""))
7314 (sign_extend:TI
7315 (match_operand:DI 2 "register_operand" "")))
7316 (const_int 64))))
7317 (clobber (match_scratch:DI 3 ""))
7318 (clobber (reg:CC 17))])]
7319 "TARGET_64BIT"
7320 "")
7321
7322 (define_insn "*smuldi3_highpart_rex64"
7323 [(set (match_operand:DI 0 "register_operand" "=d")
7324 (truncate:DI
7325 (lshiftrt:TI
7326 (mult:TI (sign_extend:TI
7327 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7328 (sign_extend:TI
7329 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7330 (const_int 64))))
7331 (clobber (match_scratch:DI 3 "=1"))
7332 (clobber (reg:CC 17))]
7333 "TARGET_64BIT
7334 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7335 "imul{q}\t%2"
7336 [(set_attr "type" "imul")
7337 (set (attr "athlon_decode")
7338 (if_then_else (eq_attr "cpu" "athlon")
7339 (const_string "vector")
7340 (const_string "double")))
7341 (set_attr "mode" "DI")])
7342
7343 (define_expand "smulsi3_highpart"
7344 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7345 (truncate:SI
7346 (lshiftrt:DI
7347 (mult:DI (sign_extend:DI
7348 (match_operand:SI 1 "nonimmediate_operand" ""))
7349 (sign_extend:DI
7350 (match_operand:SI 2 "register_operand" "")))
7351 (const_int 32))))
7352 (clobber (match_scratch:SI 3 ""))
7353 (clobber (reg:CC 17))])]
7354 ""
7355 "")
7356
7357 (define_insn "*smulsi3_highpart_insn"
7358 [(set (match_operand:SI 0 "register_operand" "=d")
7359 (truncate:SI
7360 (lshiftrt:DI
7361 (mult:DI (sign_extend:DI
7362 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7363 (sign_extend:DI
7364 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7365 (const_int 32))))
7366 (clobber (match_scratch:SI 3 "=1"))
7367 (clobber (reg:CC 17))]
7368 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7369 "imul{l}\t%2"
7370 [(set_attr "type" "imul")
7371 (set (attr "athlon_decode")
7372 (if_then_else (eq_attr "cpu" "athlon")
7373 (const_string "vector")
7374 (const_string "double")))
7375 (set_attr "mode" "SI")])
7376
7377 (define_insn "*smulsi3_highpart_zext"
7378 [(set (match_operand:DI 0 "register_operand" "=d")
7379 (zero_extend:DI (truncate:SI
7380 (lshiftrt:DI
7381 (mult:DI (sign_extend:DI
7382 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7383 (sign_extend:DI
7384 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7385 (const_int 32)))))
7386 (clobber (match_scratch:SI 3 "=1"))
7387 (clobber (reg:CC 17))]
7388 "TARGET_64BIT
7389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7390 "imul{l}\t%2"
7391 [(set_attr "type" "imul")
7392 (set (attr "athlon_decode")
7393 (if_then_else (eq_attr "cpu" "athlon")
7394 (const_string "vector")
7395 (const_string "double")))
7396 (set_attr "mode" "SI")])
7397
7398 ;; The patterns that match these are at the end of this file.
7399
7400 (define_expand "mulxf3"
7401 [(set (match_operand:XF 0 "register_operand" "")
7402 (mult:XF (match_operand:XF 1 "register_operand" "")
7403 (match_operand:XF 2 "register_operand" "")))]
7404 "TARGET_80387"
7405 "")
7406
7407 (define_expand "muldf3"
7408 [(set (match_operand:DF 0 "register_operand" "")
7409 (mult:DF (match_operand:DF 1 "register_operand" "")
7410 (match_operand:DF 2 "nonimmediate_operand" "")))]
7411 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7412 "")
7413
7414 (define_expand "mulsf3"
7415 [(set (match_operand:SF 0 "register_operand" "")
7416 (mult:SF (match_operand:SF 1 "register_operand" "")
7417 (match_operand:SF 2 "nonimmediate_operand" "")))]
7418 "TARGET_80387 || TARGET_SSE_MATH"
7419 "")
7420 \f
7421 ;; Divide instructions
7422
7423 (define_insn "divqi3"
7424 [(set (match_operand:QI 0 "register_operand" "=a")
7425 (div:QI (match_operand:HI 1 "register_operand" "0")
7426 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7427 (clobber (reg:CC 17))]
7428 "TARGET_QIMODE_MATH"
7429 "idiv{b}\t%2"
7430 [(set_attr "type" "idiv")
7431 (set_attr "mode" "QI")])
7432
7433 (define_insn "udivqi3"
7434 [(set (match_operand:QI 0 "register_operand" "=a")
7435 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7436 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7437 (clobber (reg:CC 17))]
7438 "TARGET_QIMODE_MATH"
7439 "div{b}\t%2"
7440 [(set_attr "type" "idiv")
7441 (set_attr "mode" "QI")])
7442
7443 ;; The patterns that match these are at the end of this file.
7444
7445 (define_expand "divxf3"
7446 [(set (match_operand:XF 0 "register_operand" "")
7447 (div:XF (match_operand:XF 1 "register_operand" "")
7448 (match_operand:XF 2 "register_operand" "")))]
7449 "TARGET_80387"
7450 "")
7451
7452 (define_expand "divdf3"
7453 [(set (match_operand:DF 0 "register_operand" "")
7454 (div:DF (match_operand:DF 1 "register_operand" "")
7455 (match_operand:DF 2 "nonimmediate_operand" "")))]
7456 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7457 "")
7458
7459 (define_expand "divsf3"
7460 [(set (match_operand:SF 0 "register_operand" "")
7461 (div:SF (match_operand:SF 1 "register_operand" "")
7462 (match_operand:SF 2 "nonimmediate_operand" "")))]
7463 "TARGET_80387 || TARGET_SSE_MATH"
7464 "")
7465 \f
7466 ;; Remainder instructions.
7467
7468 (define_expand "divmoddi4"
7469 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7470 (div:DI (match_operand:DI 1 "register_operand" "")
7471 (match_operand:DI 2 "nonimmediate_operand" "")))
7472 (set (match_operand:DI 3 "register_operand" "")
7473 (mod:DI (match_dup 1) (match_dup 2)))
7474 (clobber (reg:CC 17))])]
7475 "TARGET_64BIT"
7476 "")
7477
7478 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7479 ;; Penalize eax case slightly because it results in worse scheduling
7480 ;; of code.
7481 (define_insn "*divmoddi4_nocltd_rex64"
7482 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7483 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7484 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7485 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7486 (mod:DI (match_dup 2) (match_dup 3)))
7487 (clobber (reg:CC 17))]
7488 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7489 "#"
7490 [(set_attr "type" "multi")])
7491
7492 (define_insn "*divmoddi4_cltd_rex64"
7493 [(set (match_operand:DI 0 "register_operand" "=a")
7494 (div:DI (match_operand:DI 2 "register_operand" "a")
7495 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7496 (set (match_operand:DI 1 "register_operand" "=&d")
7497 (mod:DI (match_dup 2) (match_dup 3)))
7498 (clobber (reg:CC 17))]
7499 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7500 "#"
7501 [(set_attr "type" "multi")])
7502
7503 (define_insn "*divmoddi_noext_rex64"
7504 [(set (match_operand:DI 0 "register_operand" "=a")
7505 (div:DI (match_operand:DI 1 "register_operand" "0")
7506 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7507 (set (match_operand:DI 3 "register_operand" "=d")
7508 (mod:DI (match_dup 1) (match_dup 2)))
7509 (use (match_operand:DI 4 "register_operand" "3"))
7510 (clobber (reg:CC 17))]
7511 "TARGET_64BIT"
7512 "idiv{q}\t%2"
7513 [(set_attr "type" "idiv")
7514 (set_attr "mode" "DI")])
7515
7516 (define_split
7517 [(set (match_operand:DI 0 "register_operand" "")
7518 (div:DI (match_operand:DI 1 "register_operand" "")
7519 (match_operand:DI 2 "nonimmediate_operand" "")))
7520 (set (match_operand:DI 3 "register_operand" "")
7521 (mod:DI (match_dup 1) (match_dup 2)))
7522 (clobber (reg:CC 17))]
7523 "TARGET_64BIT && reload_completed"
7524 [(parallel [(set (match_dup 3)
7525 (ashiftrt:DI (match_dup 4) (const_int 63)))
7526 (clobber (reg:CC 17))])
7527 (parallel [(set (match_dup 0)
7528 (div:DI (reg:DI 0) (match_dup 2)))
7529 (set (match_dup 3)
7530 (mod:DI (reg:DI 0) (match_dup 2)))
7531 (use (match_dup 3))
7532 (clobber (reg:CC 17))])]
7533 {
7534 /* Avoid use of cltd in favor of a mov+shift. */
7535 if (!TARGET_USE_CLTD && !optimize_size)
7536 {
7537 if (true_regnum (operands[1]))
7538 emit_move_insn (operands[0], operands[1]);
7539 else
7540 emit_move_insn (operands[3], operands[1]);
7541 operands[4] = operands[3];
7542 }
7543 else
7544 {
7545 if (true_regnum (operands[1]))
7546 abort();
7547 operands[4] = operands[1];
7548 }
7549 })
7550
7551
7552 (define_expand "divmodsi4"
7553 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7554 (div:SI (match_operand:SI 1 "register_operand" "")
7555 (match_operand:SI 2 "nonimmediate_operand" "")))
7556 (set (match_operand:SI 3 "register_operand" "")
7557 (mod:SI (match_dup 1) (match_dup 2)))
7558 (clobber (reg:CC 17))])]
7559 ""
7560 "")
7561
7562 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7563 ;; Penalize eax case slightly because it results in worse scheduling
7564 ;; of code.
7565 (define_insn "*divmodsi4_nocltd"
7566 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7567 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7568 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7569 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7570 (mod:SI (match_dup 2) (match_dup 3)))
7571 (clobber (reg:CC 17))]
7572 "!optimize_size && !TARGET_USE_CLTD"
7573 "#"
7574 [(set_attr "type" "multi")])
7575
7576 (define_insn "*divmodsi4_cltd"
7577 [(set (match_operand:SI 0 "register_operand" "=a")
7578 (div:SI (match_operand:SI 2 "register_operand" "a")
7579 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7580 (set (match_operand:SI 1 "register_operand" "=&d")
7581 (mod:SI (match_dup 2) (match_dup 3)))
7582 (clobber (reg:CC 17))]
7583 "optimize_size || TARGET_USE_CLTD"
7584 "#"
7585 [(set_attr "type" "multi")])
7586
7587 (define_insn "*divmodsi_noext"
7588 [(set (match_operand:SI 0 "register_operand" "=a")
7589 (div:SI (match_operand:SI 1 "register_operand" "0")
7590 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591 (set (match_operand:SI 3 "register_operand" "=d")
7592 (mod:SI (match_dup 1) (match_dup 2)))
7593 (use (match_operand:SI 4 "register_operand" "3"))
7594 (clobber (reg:CC 17))]
7595 ""
7596 "idiv{l}\t%2"
7597 [(set_attr "type" "idiv")
7598 (set_attr "mode" "SI")])
7599
7600 (define_split
7601 [(set (match_operand:SI 0 "register_operand" "")
7602 (div:SI (match_operand:SI 1 "register_operand" "")
7603 (match_operand:SI 2 "nonimmediate_operand" "")))
7604 (set (match_operand:SI 3 "register_operand" "")
7605 (mod:SI (match_dup 1) (match_dup 2)))
7606 (clobber (reg:CC 17))]
7607 "reload_completed"
7608 [(parallel [(set (match_dup 3)
7609 (ashiftrt:SI (match_dup 4) (const_int 31)))
7610 (clobber (reg:CC 17))])
7611 (parallel [(set (match_dup 0)
7612 (div:SI (reg:SI 0) (match_dup 2)))
7613 (set (match_dup 3)
7614 (mod:SI (reg:SI 0) (match_dup 2)))
7615 (use (match_dup 3))
7616 (clobber (reg:CC 17))])]
7617 {
7618 /* Avoid use of cltd in favor of a mov+shift. */
7619 if (!TARGET_USE_CLTD && !optimize_size)
7620 {
7621 if (true_regnum (operands[1]))
7622 emit_move_insn (operands[0], operands[1]);
7623 else
7624 emit_move_insn (operands[3], operands[1]);
7625 operands[4] = operands[3];
7626 }
7627 else
7628 {
7629 if (true_regnum (operands[1]))
7630 abort();
7631 operands[4] = operands[1];
7632 }
7633 })
7634 ;; %%% Split me.
7635 (define_insn "divmodhi4"
7636 [(set (match_operand:HI 0 "register_operand" "=a")
7637 (div:HI (match_operand:HI 1 "register_operand" "0")
7638 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7639 (set (match_operand:HI 3 "register_operand" "=&d")
7640 (mod:HI (match_dup 1) (match_dup 2)))
7641 (clobber (reg:CC 17))]
7642 "TARGET_HIMODE_MATH"
7643 "cwtd\;idiv{w}\t%2"
7644 [(set_attr "type" "multi")
7645 (set_attr "length_immediate" "0")
7646 (set_attr "mode" "SI")])
7647
7648 (define_insn "udivmoddi4"
7649 [(set (match_operand:DI 0 "register_operand" "=a")
7650 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7651 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7652 (set (match_operand:DI 3 "register_operand" "=&d")
7653 (umod:DI (match_dup 1) (match_dup 2)))
7654 (clobber (reg:CC 17))]
7655 "TARGET_64BIT"
7656 "xor{q}\t%3, %3\;div{q}\t%2"
7657 [(set_attr "type" "multi")
7658 (set_attr "length_immediate" "0")
7659 (set_attr "mode" "DI")])
7660
7661 (define_insn "*udivmoddi4_noext"
7662 [(set (match_operand:DI 0 "register_operand" "=a")
7663 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7664 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7665 (set (match_operand:DI 3 "register_operand" "=d")
7666 (umod:DI (match_dup 1) (match_dup 2)))
7667 (use (match_dup 3))
7668 (clobber (reg:CC 17))]
7669 "TARGET_64BIT"
7670 "div{q}\t%2"
7671 [(set_attr "type" "idiv")
7672 (set_attr "mode" "DI")])
7673
7674 (define_split
7675 [(set (match_operand:DI 0 "register_operand" "")
7676 (udiv:DI (match_operand:DI 1 "register_operand" "")
7677 (match_operand:DI 2 "nonimmediate_operand" "")))
7678 (set (match_operand:DI 3 "register_operand" "")
7679 (umod:DI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC 17))]
7681 "TARGET_64BIT && reload_completed"
7682 [(set (match_dup 3) (const_int 0))
7683 (parallel [(set (match_dup 0)
7684 (udiv:DI (match_dup 1) (match_dup 2)))
7685 (set (match_dup 3)
7686 (umod:DI (match_dup 1) (match_dup 2)))
7687 (use (match_dup 3))
7688 (clobber (reg:CC 17))])]
7689 "")
7690
7691 (define_insn "udivmodsi4"
7692 [(set (match_operand:SI 0 "register_operand" "=a")
7693 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7694 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7695 (set (match_operand:SI 3 "register_operand" "=&d")
7696 (umod:SI (match_dup 1) (match_dup 2)))
7697 (clobber (reg:CC 17))]
7698 ""
7699 "xor{l}\t%3, %3\;div{l}\t%2"
7700 [(set_attr "type" "multi")
7701 (set_attr "length_immediate" "0")
7702 (set_attr "mode" "SI")])
7703
7704 (define_insn "*udivmodsi4_noext"
7705 [(set (match_operand:SI 0 "register_operand" "=a")
7706 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7707 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7708 (set (match_operand:SI 3 "register_operand" "=d")
7709 (umod:SI (match_dup 1) (match_dup 2)))
7710 (use (match_dup 3))
7711 (clobber (reg:CC 17))]
7712 ""
7713 "div{l}\t%2"
7714 [(set_attr "type" "idiv")
7715 (set_attr "mode" "SI")])
7716
7717 (define_split
7718 [(set (match_operand:SI 0 "register_operand" "")
7719 (udiv:SI (match_operand:SI 1 "register_operand" "")
7720 (match_operand:SI 2 "nonimmediate_operand" "")))
7721 (set (match_operand:SI 3 "register_operand" "")
7722 (umod:SI (match_dup 1) (match_dup 2)))
7723 (clobber (reg:CC 17))]
7724 "reload_completed"
7725 [(set (match_dup 3) (const_int 0))
7726 (parallel [(set (match_dup 0)
7727 (udiv:SI (match_dup 1) (match_dup 2)))
7728 (set (match_dup 3)
7729 (umod:SI (match_dup 1) (match_dup 2)))
7730 (use (match_dup 3))
7731 (clobber (reg:CC 17))])]
7732 "")
7733
7734 (define_expand "udivmodhi4"
7735 [(set (match_dup 4) (const_int 0))
7736 (parallel [(set (match_operand:HI 0 "register_operand" "")
7737 (udiv:HI (match_operand:HI 1 "register_operand" "")
7738 (match_operand:HI 2 "nonimmediate_operand" "")))
7739 (set (match_operand:HI 3 "register_operand" "")
7740 (umod:HI (match_dup 1) (match_dup 2)))
7741 (use (match_dup 4))
7742 (clobber (reg:CC 17))])]
7743 "TARGET_HIMODE_MATH"
7744 "operands[4] = gen_reg_rtx (HImode);")
7745
7746 (define_insn "*udivmodhi_noext"
7747 [(set (match_operand:HI 0 "register_operand" "=a")
7748 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7749 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7750 (set (match_operand:HI 3 "register_operand" "=d")
7751 (umod:HI (match_dup 1) (match_dup 2)))
7752 (use (match_operand:HI 4 "register_operand" "3"))
7753 (clobber (reg:CC 17))]
7754 ""
7755 "div{w}\t%2"
7756 [(set_attr "type" "idiv")
7757 (set_attr "mode" "HI")])
7758
7759 ;; We can not use div/idiv for double division, because it causes
7760 ;; "division by zero" on the overflow and that's not what we expect
7761 ;; from truncate. Because true (non truncating) double division is
7762 ;; never generated, we can't create this insn anyway.
7763 ;
7764 ;(define_insn ""
7765 ; [(set (match_operand:SI 0 "register_operand" "=a")
7766 ; (truncate:SI
7767 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7768 ; (zero_extend:DI
7769 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7770 ; (set (match_operand:SI 3 "register_operand" "=d")
7771 ; (truncate:SI
7772 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7773 ; (clobber (reg:CC 17))]
7774 ; ""
7775 ; "div{l}\t{%2, %0|%0, %2}"
7776 ; [(set_attr "type" "idiv")])
7777 \f
7778 ;;- Logical AND instructions
7779
7780 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7781 ;; Note that this excludes ah.
7782
7783 (define_insn "*testdi_1_rex64"
7784 [(set (reg 17)
7785 (compare
7786 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7787 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7788 (const_int 0)))]
7789 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7790 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7791 "@
7792 test{l}\t{%k1, %k0|%k0, %k1}
7793 test{l}\t{%k1, %k0|%k0, %k1}
7794 test{q}\t{%1, %0|%0, %1}
7795 test{q}\t{%1, %0|%0, %1}
7796 test{q}\t{%1, %0|%0, %1}"
7797 [(set_attr "type" "test")
7798 (set_attr "modrm" "0,1,0,1,1")
7799 (set_attr "mode" "SI,SI,DI,DI,DI")
7800 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7801
7802 (define_insn "testsi_1"
7803 [(set (reg 17)
7804 (compare
7805 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7806 (match_operand:SI 1 "general_operand" "in,in,rin"))
7807 (const_int 0)))]
7808 "ix86_match_ccmode (insn, CCNOmode)
7809 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7810 "test{l}\t{%1, %0|%0, %1}"
7811 [(set_attr "type" "test")
7812 (set_attr "modrm" "0,1,1")
7813 (set_attr "mode" "SI")
7814 (set_attr "pent_pair" "uv,np,uv")])
7815
7816 (define_expand "testsi_ccno_1"
7817 [(set (reg:CCNO 17)
7818 (compare:CCNO
7819 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7820 (match_operand:SI 1 "nonmemory_operand" ""))
7821 (const_int 0)))]
7822 ""
7823 "")
7824
7825 (define_insn "*testhi_1"
7826 [(set (reg 17)
7827 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7828 (match_operand:HI 1 "general_operand" "n,n,rn"))
7829 (const_int 0)))]
7830 "ix86_match_ccmode (insn, CCNOmode)
7831 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7832 "test{w}\t{%1, %0|%0, %1}"
7833 [(set_attr "type" "test")
7834 (set_attr "modrm" "0,1,1")
7835 (set_attr "mode" "HI")
7836 (set_attr "pent_pair" "uv,np,uv")])
7837
7838 (define_expand "testqi_ccz_1"
7839 [(set (reg:CCZ 17)
7840 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7841 (match_operand:QI 1 "nonmemory_operand" ""))
7842 (const_int 0)))]
7843 ""
7844 "")
7845
7846 (define_insn "*testqi_1"
7847 [(set (reg 17)
7848 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7849 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7850 (const_int 0)))]
7851 "ix86_match_ccmode (insn, CCNOmode)
7852 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7853 {
7854 if (which_alternative == 3)
7855 {
7856 if (GET_CODE (operands[1]) == CONST_INT
7857 && (INTVAL (operands[1]) & 0xffffff00))
7858 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7859 return "test{l}\t{%1, %k0|%k0, %1}";
7860 }
7861 return "test{b}\t{%1, %0|%0, %1}";
7862 }
7863 [(set_attr "type" "test")
7864 (set_attr "modrm" "0,1,1,1")
7865 (set_attr "mode" "QI,QI,QI,SI")
7866 (set_attr "pent_pair" "uv,np,uv,np")])
7867
7868 (define_expand "testqi_ext_ccno_0"
7869 [(set (reg:CCNO 17)
7870 (compare:CCNO
7871 (and:SI
7872 (zero_extract:SI
7873 (match_operand 0 "ext_register_operand" "")
7874 (const_int 8)
7875 (const_int 8))
7876 (match_operand 1 "const_int_operand" ""))
7877 (const_int 0)))]
7878 ""
7879 "")
7880
7881 (define_insn "*testqi_ext_0"
7882 [(set (reg 17)
7883 (compare
7884 (and:SI
7885 (zero_extract:SI
7886 (match_operand 0 "ext_register_operand" "Q")
7887 (const_int 8)
7888 (const_int 8))
7889 (match_operand 1 "const_int_operand" "n"))
7890 (const_int 0)))]
7891 "ix86_match_ccmode (insn, CCNOmode)"
7892 "test{b}\t{%1, %h0|%h0, %1}"
7893 [(set_attr "type" "test")
7894 (set_attr "mode" "QI")
7895 (set_attr "length_immediate" "1")
7896 (set_attr "pent_pair" "np")])
7897
7898 (define_insn "*testqi_ext_1"
7899 [(set (reg 17)
7900 (compare
7901 (and:SI
7902 (zero_extract:SI
7903 (match_operand 0 "ext_register_operand" "Q")
7904 (const_int 8)
7905 (const_int 8))
7906 (zero_extend:SI
7907 (match_operand:QI 1 "general_operand" "Qm")))
7908 (const_int 0)))]
7909 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7911 "test{b}\t{%1, %h0|%h0, %1}"
7912 [(set_attr "type" "test")
7913 (set_attr "mode" "QI")])
7914
7915 (define_insn "*testqi_ext_1_rex64"
7916 [(set (reg 17)
7917 (compare
7918 (and:SI
7919 (zero_extract:SI
7920 (match_operand 0 "ext_register_operand" "Q")
7921 (const_int 8)
7922 (const_int 8))
7923 (zero_extend:SI
7924 (match_operand:QI 1 "register_operand" "Q")))
7925 (const_int 0)))]
7926 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7927 "test{b}\t{%1, %h0|%h0, %1}"
7928 [(set_attr "type" "test")
7929 (set_attr "mode" "QI")])
7930
7931 (define_insn "*testqi_ext_2"
7932 [(set (reg 17)
7933 (compare
7934 (and:SI
7935 (zero_extract:SI
7936 (match_operand 0 "ext_register_operand" "Q")
7937 (const_int 8)
7938 (const_int 8))
7939 (zero_extract:SI
7940 (match_operand 1 "ext_register_operand" "Q")
7941 (const_int 8)
7942 (const_int 8)))
7943 (const_int 0)))]
7944 "ix86_match_ccmode (insn, CCNOmode)"
7945 "test{b}\t{%h1, %h0|%h0, %h1}"
7946 [(set_attr "type" "test")
7947 (set_attr "mode" "QI")])
7948
7949 ;; Combine likes to form bit extractions for some tests. Humor it.
7950 (define_insn "*testqi_ext_3"
7951 [(set (reg 17)
7952 (compare (zero_extract:SI
7953 (match_operand 0 "nonimmediate_operand" "rm")
7954 (match_operand:SI 1 "const_int_operand" "")
7955 (match_operand:SI 2 "const_int_operand" ""))
7956 (const_int 0)))]
7957 "ix86_match_ccmode (insn, CCNOmode)
7958 && (GET_MODE (operands[0]) == SImode
7959 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7960 || GET_MODE (operands[0]) == HImode
7961 || GET_MODE (operands[0]) == QImode)"
7962 "#")
7963
7964 (define_insn "*testqi_ext_3_rex64"
7965 [(set (reg 17)
7966 (compare (zero_extract:DI
7967 (match_operand 0 "nonimmediate_operand" "rm")
7968 (match_operand:DI 1 "const_int_operand" "")
7969 (match_operand:DI 2 "const_int_operand" ""))
7970 (const_int 0)))]
7971 "TARGET_64BIT
7972 && ix86_match_ccmode (insn, CCNOmode)
7973 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7974 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7975 /* Ensure that resulting mask is zero or sign extended operand. */
7976 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7977 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7978 && INTVAL (operands[1]) > 32))
7979 && (GET_MODE (operands[0]) == SImode
7980 || GET_MODE (operands[0]) == DImode
7981 || GET_MODE (operands[0]) == HImode
7982 || GET_MODE (operands[0]) == QImode)"
7983 "#")
7984
7985 (define_split
7986 [(set (reg 17)
7987 (compare (zero_extract
7988 (match_operand 0 "nonimmediate_operand" "")
7989 (match_operand 1 "const_int_operand" "")
7990 (match_operand 2 "const_int_operand" ""))
7991 (const_int 0)))]
7992 "ix86_match_ccmode (insn, CCNOmode)"
7993 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7994 {
7995 HOST_WIDE_INT len = INTVAL (operands[1]);
7996 HOST_WIDE_INT pos = INTVAL (operands[2]);
7997 HOST_WIDE_INT mask;
7998 enum machine_mode mode, submode;
7999
8000 mode = GET_MODE (operands[0]);
8001 if (GET_CODE (operands[0]) == MEM)
8002 {
8003 /* ??? Combine likes to put non-volatile mem extractions in QImode
8004 no matter the size of the test. So find a mode that works. */
8005 if (! MEM_VOLATILE_P (operands[0]))
8006 {
8007 mode = smallest_mode_for_size (pos + len, MODE_INT);
8008 operands[0] = adjust_address (operands[0], mode, 0);
8009 }
8010 }
8011 else if (GET_CODE (operands[0]) == SUBREG
8012 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8013 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8014 && pos + len <= GET_MODE_BITSIZE (submode))
8015 {
8016 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8017 mode = submode;
8018 operands[0] = SUBREG_REG (operands[0]);
8019 }
8020 else if (mode == HImode && pos + len <= 8)
8021 {
8022 /* Small HImode tests can be converted to QImode. */
8023 mode = QImode;
8024 operands[0] = gen_lowpart (QImode, operands[0]);
8025 }
8026
8027 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8028 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8029
8030 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8031 })
8032
8033 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8034 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8035 ;; this is relatively important trick.
8036 ;; Do the conversion only post-reload to avoid limiting of the register class
8037 ;; to QI regs.
8038 (define_split
8039 [(set (reg 17)
8040 (compare
8041 (and (match_operand 0 "register_operand" "")
8042 (match_operand 1 "const_int_operand" ""))
8043 (const_int 0)))]
8044 "reload_completed
8045 && QI_REG_P (operands[0])
8046 && ((ix86_match_ccmode (insn, CCZmode)
8047 && !(INTVAL (operands[1]) & ~(255 << 8)))
8048 || (ix86_match_ccmode (insn, CCNOmode)
8049 && !(INTVAL (operands[1]) & ~(127 << 8))))
8050 && GET_MODE (operands[0]) != QImode"
8051 [(set (reg:CCNO 17)
8052 (compare:CCNO
8053 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8054 (match_dup 1))
8055 (const_int 0)))]
8056 "operands[0] = gen_lowpart (SImode, operands[0]);
8057 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8058
8059 (define_split
8060 [(set (reg 17)
8061 (compare
8062 (and (match_operand 0 "nonimmediate_operand" "")
8063 (match_operand 1 "const_int_operand" ""))
8064 (const_int 0)))]
8065 "reload_completed
8066 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8067 && ((ix86_match_ccmode (insn, CCZmode)
8068 && !(INTVAL (operands[1]) & ~255))
8069 || (ix86_match_ccmode (insn, CCNOmode)
8070 && !(INTVAL (operands[1]) & ~127)))
8071 && GET_MODE (operands[0]) != QImode"
8072 [(set (reg:CCNO 17)
8073 (compare:CCNO
8074 (and:QI (match_dup 0)
8075 (match_dup 1))
8076 (const_int 0)))]
8077 "operands[0] = gen_lowpart (QImode, operands[0]);
8078 operands[1] = gen_lowpart (QImode, operands[1]);")
8079
8080
8081 ;; %%% This used to optimize known byte-wide and operations to memory,
8082 ;; and sometimes to QImode registers. If this is considered useful,
8083 ;; it should be done with splitters.
8084
8085 (define_expand "anddi3"
8086 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8087 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8088 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8089 (clobber (reg:CC 17))]
8090 "TARGET_64BIT"
8091 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8092
8093 (define_insn "*anddi_1_rex64"
8094 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8095 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8096 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8097 (clobber (reg:CC 17))]
8098 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8099 {
8100 switch (get_attr_type (insn))
8101 {
8102 case TYPE_IMOVX:
8103 {
8104 enum machine_mode mode;
8105
8106 if (GET_CODE (operands[2]) != CONST_INT)
8107 abort ();
8108 if (INTVAL (operands[2]) == 0xff)
8109 mode = QImode;
8110 else if (INTVAL (operands[2]) == 0xffff)
8111 mode = HImode;
8112 else
8113 abort ();
8114
8115 operands[1] = gen_lowpart (mode, operands[1]);
8116 if (mode == QImode)
8117 return "movz{bq|x}\t{%1,%0|%0, %1}";
8118 else
8119 return "movz{wq|x}\t{%1,%0|%0, %1}";
8120 }
8121
8122 default:
8123 if (! rtx_equal_p (operands[0], operands[1]))
8124 abort ();
8125 if (get_attr_mode (insn) == MODE_SI)
8126 return "and{l}\t{%k2, %k0|%k0, %k2}";
8127 else
8128 return "and{q}\t{%2, %0|%0, %2}";
8129 }
8130 }
8131 [(set_attr "type" "alu,alu,alu,imovx")
8132 (set_attr "length_immediate" "*,*,*,0")
8133 (set_attr "mode" "SI,DI,DI,DI")])
8134
8135 (define_insn "*anddi_2"
8136 [(set (reg 17)
8137 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8138 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8139 (const_int 0)))
8140 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8141 (and:DI (match_dup 1) (match_dup 2)))]
8142 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8143 && ix86_binary_operator_ok (AND, DImode, operands)"
8144 "@
8145 and{l}\t{%k2, %k0|%k0, %k2}
8146 and{q}\t{%2, %0|%0, %2}
8147 and{q}\t{%2, %0|%0, %2}"
8148 [(set_attr "type" "alu")
8149 (set_attr "mode" "SI,DI,DI")])
8150
8151 (define_expand "andsi3"
8152 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8153 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8154 (match_operand:SI 2 "general_operand" "")))
8155 (clobber (reg:CC 17))]
8156 ""
8157 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8158
8159 (define_insn "*andsi_1"
8160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8161 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8162 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8163 (clobber (reg:CC 17))]
8164 "ix86_binary_operator_ok (AND, SImode, operands)"
8165 {
8166 switch (get_attr_type (insn))
8167 {
8168 case TYPE_IMOVX:
8169 {
8170 enum machine_mode mode;
8171
8172 if (GET_CODE (operands[2]) != CONST_INT)
8173 abort ();
8174 if (INTVAL (operands[2]) == 0xff)
8175 mode = QImode;
8176 else if (INTVAL (operands[2]) == 0xffff)
8177 mode = HImode;
8178 else
8179 abort ();
8180
8181 operands[1] = gen_lowpart (mode, operands[1]);
8182 if (mode == QImode)
8183 return "movz{bl|x}\t{%1,%0|%0, %1}";
8184 else
8185 return "movz{wl|x}\t{%1,%0|%0, %1}";
8186 }
8187
8188 default:
8189 if (! rtx_equal_p (operands[0], operands[1]))
8190 abort ();
8191 return "and{l}\t{%2, %0|%0, %2}";
8192 }
8193 }
8194 [(set_attr "type" "alu,alu,imovx")
8195 (set_attr "length_immediate" "*,*,0")
8196 (set_attr "mode" "SI")])
8197
8198 (define_split
8199 [(set (match_operand 0 "register_operand" "")
8200 (and (match_dup 0)
8201 (const_int -65536)))
8202 (clobber (reg:CC 17))]
8203 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8204 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8205 "operands[1] = gen_lowpart (HImode, operands[0]);")
8206
8207 (define_split
8208 [(set (match_operand 0 "ext_register_operand" "")
8209 (and (match_dup 0)
8210 (const_int -256)))
8211 (clobber (reg:CC 17))]
8212 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8213 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8214 "operands[1] = gen_lowpart (QImode, operands[0]);")
8215
8216 (define_split
8217 [(set (match_operand 0 "ext_register_operand" "")
8218 (and (match_dup 0)
8219 (const_int -65281)))
8220 (clobber (reg:CC 17))]
8221 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8222 [(parallel [(set (zero_extract:SI (match_dup 0)
8223 (const_int 8)
8224 (const_int 8))
8225 (xor:SI
8226 (zero_extract:SI (match_dup 0)
8227 (const_int 8)
8228 (const_int 8))
8229 (zero_extract:SI (match_dup 0)
8230 (const_int 8)
8231 (const_int 8))))
8232 (clobber (reg:CC 17))])]
8233 "operands[0] = gen_lowpart (SImode, operands[0]);")
8234
8235 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8236 (define_insn "*andsi_1_zext"
8237 [(set (match_operand:DI 0 "register_operand" "=r")
8238 (zero_extend:DI
8239 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8240 (match_operand:SI 2 "general_operand" "rim"))))
8241 (clobber (reg:CC 17))]
8242 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8243 "and{l}\t{%2, %k0|%k0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "mode" "SI")])
8246
8247 (define_insn "*andsi_2"
8248 [(set (reg 17)
8249 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8250 (match_operand:SI 2 "general_operand" "rim,ri"))
8251 (const_int 0)))
8252 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8253 (and:SI (match_dup 1) (match_dup 2)))]
8254 "ix86_match_ccmode (insn, CCNOmode)
8255 && ix86_binary_operator_ok (AND, SImode, operands)"
8256 "and{l}\t{%2, %0|%0, %2}"
8257 [(set_attr "type" "alu")
8258 (set_attr "mode" "SI")])
8259
8260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8261 (define_insn "*andsi_2_zext"
8262 [(set (reg 17)
8263 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8264 (match_operand:SI 2 "general_operand" "rim"))
8265 (const_int 0)))
8266 (set (match_operand:DI 0 "register_operand" "=r")
8267 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8268 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8269 && ix86_binary_operator_ok (AND, SImode, operands)"
8270 "and{l}\t{%2, %k0|%k0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "mode" "SI")])
8273
8274 (define_expand "andhi3"
8275 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8276 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8277 (match_operand:HI 2 "general_operand" "")))
8278 (clobber (reg:CC 17))]
8279 "TARGET_HIMODE_MATH"
8280 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8281
8282 (define_insn "*andhi_1"
8283 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8284 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8285 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8286 (clobber (reg:CC 17))]
8287 "ix86_binary_operator_ok (AND, HImode, operands)"
8288 {
8289 switch (get_attr_type (insn))
8290 {
8291 case TYPE_IMOVX:
8292 if (GET_CODE (operands[2]) != CONST_INT)
8293 abort ();
8294 if (INTVAL (operands[2]) == 0xff)
8295 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8296 abort ();
8297
8298 default:
8299 if (! rtx_equal_p (operands[0], operands[1]))
8300 abort ();
8301
8302 return "and{w}\t{%2, %0|%0, %2}";
8303 }
8304 }
8305 [(set_attr "type" "alu,alu,imovx")
8306 (set_attr "length_immediate" "*,*,0")
8307 (set_attr "mode" "HI,HI,SI")])
8308
8309 (define_insn "*andhi_2"
8310 [(set (reg 17)
8311 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8312 (match_operand:HI 2 "general_operand" "rim,ri"))
8313 (const_int 0)))
8314 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8315 (and:HI (match_dup 1) (match_dup 2)))]
8316 "ix86_match_ccmode (insn, CCNOmode)
8317 && ix86_binary_operator_ok (AND, HImode, operands)"
8318 "and{w}\t{%2, %0|%0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "HI")])
8321
8322 (define_expand "andqi3"
8323 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8324 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8325 (match_operand:QI 2 "general_operand" "")))
8326 (clobber (reg:CC 17))]
8327 "TARGET_QIMODE_MATH"
8328 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8329
8330 ;; %%% Potential partial reg stall on alternative 2. What to do?
8331 (define_insn "*andqi_1"
8332 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8333 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8334 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8335 (clobber (reg:CC 17))]
8336 "ix86_binary_operator_ok (AND, QImode, operands)"
8337 "@
8338 and{b}\t{%2, %0|%0, %2}
8339 and{b}\t{%2, %0|%0, %2}
8340 and{l}\t{%k2, %k0|%k0, %k2}"
8341 [(set_attr "type" "alu")
8342 (set_attr "mode" "QI,QI,SI")])
8343
8344 (define_insn "*andqi_1_slp"
8345 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8346 (and:QI (match_dup 0)
8347 (match_operand:QI 1 "general_operand" "qi,qmi")))
8348 (clobber (reg:CC 17))]
8349 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8350 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8351 "and{b}\t{%1, %0|%0, %1}"
8352 [(set_attr "type" "alu1")
8353 (set_attr "mode" "QI")])
8354
8355 (define_insn "*andqi_2"
8356 [(set (reg 17)
8357 (compare (and:QI
8358 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8359 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8360 (const_int 0)))
8361 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8362 (and:QI (match_dup 1) (match_dup 2)))]
8363 "ix86_match_ccmode (insn, CCNOmode)
8364 && ix86_binary_operator_ok (AND, QImode, operands)"
8365 {
8366 if (which_alternative == 2)
8367 {
8368 if (GET_CODE (operands[2]) == CONST_INT
8369 && (INTVAL (operands[2]) & 0xffffff00))
8370 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8371 return "and{l}\t{%2, %k0|%k0, %2}";
8372 }
8373 return "and{b}\t{%2, %0|%0, %2}";
8374 }
8375 [(set_attr "type" "alu")
8376 (set_attr "mode" "QI,QI,SI")])
8377
8378 (define_insn "*andqi_2_slp"
8379 [(set (reg 17)
8380 (compare (and:QI
8381 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8382 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8383 (const_int 0)))
8384 (set (strict_low_part (match_dup 0))
8385 (and:QI (match_dup 0) (match_dup 1)))]
8386 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8387 && ix86_match_ccmode (insn, CCNOmode)
8388 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8389 "and{b}\t{%1, %0|%0, %1}"
8390 [(set_attr "type" "alu1")
8391 (set_attr "mode" "QI")])
8392
8393 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8394 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8395 ;; for a QImode operand, which of course failed.
8396
8397 (define_insn "andqi_ext_0"
8398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8399 (const_int 8)
8400 (const_int 8))
8401 (and:SI
8402 (zero_extract:SI
8403 (match_operand 1 "ext_register_operand" "0")
8404 (const_int 8)
8405 (const_int 8))
8406 (match_operand 2 "const_int_operand" "n")))
8407 (clobber (reg:CC 17))]
8408 ""
8409 "and{b}\t{%2, %h0|%h0, %2}"
8410 [(set_attr "type" "alu")
8411 (set_attr "length_immediate" "1")
8412 (set_attr "mode" "QI")])
8413
8414 ;; Generated by peephole translating test to and. This shows up
8415 ;; often in fp comparisons.
8416
8417 (define_insn "*andqi_ext_0_cc"
8418 [(set (reg 17)
8419 (compare
8420 (and:SI
8421 (zero_extract:SI
8422 (match_operand 1 "ext_register_operand" "0")
8423 (const_int 8)
8424 (const_int 8))
8425 (match_operand 2 "const_int_operand" "n"))
8426 (const_int 0)))
8427 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8428 (const_int 8)
8429 (const_int 8))
8430 (and:SI
8431 (zero_extract:SI
8432 (match_dup 1)
8433 (const_int 8)
8434 (const_int 8))
8435 (match_dup 2)))]
8436 "ix86_match_ccmode (insn, CCNOmode)"
8437 "and{b}\t{%2, %h0|%h0, %2}"
8438 [(set_attr "type" "alu")
8439 (set_attr "length_immediate" "1")
8440 (set_attr "mode" "QI")])
8441
8442 (define_insn "*andqi_ext_1"
8443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444 (const_int 8)
8445 (const_int 8))
8446 (and:SI
8447 (zero_extract:SI
8448 (match_operand 1 "ext_register_operand" "0")
8449 (const_int 8)
8450 (const_int 8))
8451 (zero_extend:SI
8452 (match_operand:QI 2 "general_operand" "Qm"))))
8453 (clobber (reg:CC 17))]
8454 "!TARGET_64BIT"
8455 "and{b}\t{%2, %h0|%h0, %2}"
8456 [(set_attr "type" "alu")
8457 (set_attr "length_immediate" "0")
8458 (set_attr "mode" "QI")])
8459
8460 (define_insn "*andqi_ext_1_rex64"
8461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462 (const_int 8)
8463 (const_int 8))
8464 (and:SI
8465 (zero_extract:SI
8466 (match_operand 1 "ext_register_operand" "0")
8467 (const_int 8)
8468 (const_int 8))
8469 (zero_extend:SI
8470 (match_operand 2 "ext_register_operand" "Q"))))
8471 (clobber (reg:CC 17))]
8472 "TARGET_64BIT"
8473 "and{b}\t{%2, %h0|%h0, %2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "length_immediate" "0")
8476 (set_attr "mode" "QI")])
8477
8478 (define_insn "*andqi_ext_2"
8479 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8480 (const_int 8)
8481 (const_int 8))
8482 (and:SI
8483 (zero_extract:SI
8484 (match_operand 1 "ext_register_operand" "%0")
8485 (const_int 8)
8486 (const_int 8))
8487 (zero_extract:SI
8488 (match_operand 2 "ext_register_operand" "Q")
8489 (const_int 8)
8490 (const_int 8))))
8491 (clobber (reg:CC 17))]
8492 ""
8493 "and{b}\t{%h2, %h0|%h0, %h2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "length_immediate" "0")
8496 (set_attr "mode" "QI")])
8497
8498 ;; Convert wide AND instructions with immediate operand to shorter QImode
8499 ;; equivalents when possible.
8500 ;; Don't do the splitting with memory operands, since it introduces risk
8501 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8502 ;; for size, but that can (should?) be handled by generic code instead.
8503 (define_split
8504 [(set (match_operand 0 "register_operand" "")
8505 (and (match_operand 1 "register_operand" "")
8506 (match_operand 2 "const_int_operand" "")))
8507 (clobber (reg:CC 17))]
8508 "reload_completed
8509 && QI_REG_P (operands[0])
8510 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8511 && !(~INTVAL (operands[2]) & ~(255 << 8))
8512 && GET_MODE (operands[0]) != QImode"
8513 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8514 (and:SI (zero_extract:SI (match_dup 1)
8515 (const_int 8) (const_int 8))
8516 (match_dup 2)))
8517 (clobber (reg:CC 17))])]
8518 "operands[0] = gen_lowpart (SImode, operands[0]);
8519 operands[1] = gen_lowpart (SImode, operands[1]);
8520 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8521
8522 ;; Since AND can be encoded with sign extended immediate, this is only
8523 ;; profitable when 7th bit is not set.
8524 (define_split
8525 [(set (match_operand 0 "register_operand" "")
8526 (and (match_operand 1 "general_operand" "")
8527 (match_operand 2 "const_int_operand" "")))
8528 (clobber (reg:CC 17))]
8529 "reload_completed
8530 && ANY_QI_REG_P (operands[0])
8531 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8532 && !(~INTVAL (operands[2]) & ~255)
8533 && !(INTVAL (operands[2]) & 128)
8534 && GET_MODE (operands[0]) != QImode"
8535 [(parallel [(set (strict_low_part (match_dup 0))
8536 (and:QI (match_dup 1)
8537 (match_dup 2)))
8538 (clobber (reg:CC 17))])]
8539 "operands[0] = gen_lowpart (QImode, operands[0]);
8540 operands[1] = gen_lowpart (QImode, operands[1]);
8541 operands[2] = gen_lowpart (QImode, operands[2]);")
8542 \f
8543 ;; Logical inclusive OR instructions
8544
8545 ;; %%% This used to optimize known byte-wide and operations to memory.
8546 ;; If this is considered useful, it should be done with splitters.
8547
8548 (define_expand "iordi3"
8549 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8550 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8551 (match_operand:DI 2 "x86_64_general_operand" "")))
8552 (clobber (reg:CC 17))]
8553 "TARGET_64BIT"
8554 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8555
8556 (define_insn "*iordi_1_rex64"
8557 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8558 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8559 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8560 (clobber (reg:CC 17))]
8561 "TARGET_64BIT
8562 && ix86_binary_operator_ok (IOR, DImode, operands)"
8563 "or{q}\t{%2, %0|%0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "mode" "DI")])
8566
8567 (define_insn "*iordi_2_rex64"
8568 [(set (reg 17)
8569 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8570 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8571 (const_int 0)))
8572 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8573 (ior:DI (match_dup 1) (match_dup 2)))]
8574 "TARGET_64BIT
8575 && ix86_match_ccmode (insn, CCNOmode)
8576 && ix86_binary_operator_ok (IOR, DImode, operands)"
8577 "or{q}\t{%2, %0|%0, %2}"
8578 [(set_attr "type" "alu")
8579 (set_attr "mode" "DI")])
8580
8581 (define_insn "*iordi_3_rex64"
8582 [(set (reg 17)
8583 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8584 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8585 (const_int 0)))
8586 (clobber (match_scratch:DI 0 "=r"))]
8587 "TARGET_64BIT
8588 && ix86_match_ccmode (insn, CCNOmode)
8589 && ix86_binary_operator_ok (IOR, DImode, operands)"
8590 "or{q}\t{%2, %0|%0, %2}"
8591 [(set_attr "type" "alu")
8592 (set_attr "mode" "DI")])
8593
8594
8595 (define_expand "iorsi3"
8596 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8597 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8598 (match_operand:SI 2 "general_operand" "")))
8599 (clobber (reg:CC 17))]
8600 ""
8601 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8602
8603 (define_insn "*iorsi_1"
8604 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8605 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8606 (match_operand:SI 2 "general_operand" "ri,rmi")))
8607 (clobber (reg:CC 17))]
8608 "ix86_binary_operator_ok (IOR, SImode, operands)"
8609 "or{l}\t{%2, %0|%0, %2}"
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "SI")])
8612
8613 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8614 (define_insn "*iorsi_1_zext"
8615 [(set (match_operand:DI 0 "register_operand" "=rm")
8616 (zero_extend:DI
8617 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8618 (match_operand:SI 2 "general_operand" "rim"))))
8619 (clobber (reg:CC 17))]
8620 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8621 "or{l}\t{%2, %k0|%k0, %2}"
8622 [(set_attr "type" "alu")
8623 (set_attr "mode" "SI")])
8624
8625 (define_insn "*iorsi_1_zext_imm"
8626 [(set (match_operand:DI 0 "register_operand" "=rm")
8627 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8628 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8629 (clobber (reg:CC 17))]
8630 "TARGET_64BIT"
8631 "or{l}\t{%2, %k0|%k0, %2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "SI")])
8634
8635 (define_insn "*iorsi_2"
8636 [(set (reg 17)
8637 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8638 (match_operand:SI 2 "general_operand" "rim,ri"))
8639 (const_int 0)))
8640 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8641 (ior:SI (match_dup 1) (match_dup 2)))]
8642 "ix86_match_ccmode (insn, CCNOmode)
8643 && ix86_binary_operator_ok (IOR, SImode, operands)"
8644 "or{l}\t{%2, %0|%0, %2}"
8645 [(set_attr "type" "alu")
8646 (set_attr "mode" "SI")])
8647
8648 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8649 ;; ??? Special case for immediate operand is missing - it is tricky.
8650 (define_insn "*iorsi_2_zext"
8651 [(set (reg 17)
8652 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8653 (match_operand:SI 2 "general_operand" "rim"))
8654 (const_int 0)))
8655 (set (match_operand:DI 0 "register_operand" "=r")
8656 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8657 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8658 && ix86_binary_operator_ok (IOR, SImode, operands)"
8659 "or{l}\t{%2, %k0|%k0, %2}"
8660 [(set_attr "type" "alu")
8661 (set_attr "mode" "SI")])
8662
8663 (define_insn "*iorsi_2_zext_imm"
8664 [(set (reg 17)
8665 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8666 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8667 (const_int 0)))
8668 (set (match_operand:DI 0 "register_operand" "=r")
8669 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8670 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8671 && ix86_binary_operator_ok (IOR, SImode, operands)"
8672 "or{l}\t{%2, %k0|%k0, %2}"
8673 [(set_attr "type" "alu")
8674 (set_attr "mode" "SI")])
8675
8676 (define_insn "*iorsi_3"
8677 [(set (reg 17)
8678 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8679 (match_operand:SI 2 "general_operand" "rim"))
8680 (const_int 0)))
8681 (clobber (match_scratch:SI 0 "=r"))]
8682 "ix86_match_ccmode (insn, CCNOmode)
8683 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8684 "or{l}\t{%2, %0|%0, %2}"
8685 [(set_attr "type" "alu")
8686 (set_attr "mode" "SI")])
8687
8688 (define_expand "iorhi3"
8689 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8690 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8691 (match_operand:HI 2 "general_operand" "")))
8692 (clobber (reg:CC 17))]
8693 "TARGET_HIMODE_MATH"
8694 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8695
8696 (define_insn "*iorhi_1"
8697 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8698 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8699 (match_operand:HI 2 "general_operand" "rmi,ri")))
8700 (clobber (reg:CC 17))]
8701 "ix86_binary_operator_ok (IOR, HImode, operands)"
8702 "or{w}\t{%2, %0|%0, %2}"
8703 [(set_attr "type" "alu")
8704 (set_attr "mode" "HI")])
8705
8706 (define_insn "*iorhi_2"
8707 [(set (reg 17)
8708 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8709 (match_operand:HI 2 "general_operand" "rim,ri"))
8710 (const_int 0)))
8711 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8712 (ior:HI (match_dup 1) (match_dup 2)))]
8713 "ix86_match_ccmode (insn, CCNOmode)
8714 && ix86_binary_operator_ok (IOR, HImode, operands)"
8715 "or{w}\t{%2, %0|%0, %2}"
8716 [(set_attr "type" "alu")
8717 (set_attr "mode" "HI")])
8718
8719 (define_insn "*iorhi_3"
8720 [(set (reg 17)
8721 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8722 (match_operand:HI 2 "general_operand" "rim"))
8723 (const_int 0)))
8724 (clobber (match_scratch:HI 0 "=r"))]
8725 "ix86_match_ccmode (insn, CCNOmode)
8726 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8727 "or{w}\t{%2, %0|%0, %2}"
8728 [(set_attr "type" "alu")
8729 (set_attr "mode" "HI")])
8730
8731 (define_expand "iorqi3"
8732 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8733 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8734 (match_operand:QI 2 "general_operand" "")))
8735 (clobber (reg:CC 17))]
8736 "TARGET_QIMODE_MATH"
8737 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8738
8739 ;; %%% Potential partial reg stall on alternative 2. What to do?
8740 (define_insn "*iorqi_1"
8741 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8742 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8743 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8744 (clobber (reg:CC 17))]
8745 "ix86_binary_operator_ok (IOR, QImode, operands)"
8746 "@
8747 or{b}\t{%2, %0|%0, %2}
8748 or{b}\t{%2, %0|%0, %2}
8749 or{l}\t{%k2, %k0|%k0, %k2}"
8750 [(set_attr "type" "alu")
8751 (set_attr "mode" "QI,QI,SI")])
8752
8753 (define_insn "*iorqi_1_slp"
8754 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8755 (ior:QI (match_dup 0)
8756 (match_operand:QI 1 "general_operand" "qmi,qi")))
8757 (clobber (reg:CC 17))]
8758 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8759 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8760 "or{b}\t{%1, %0|%0, %1}"
8761 [(set_attr "type" "alu1")
8762 (set_attr "mode" "QI")])
8763
8764 (define_insn "*iorqi_2"
8765 [(set (reg 17)
8766 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8767 (match_operand:QI 2 "general_operand" "qim,qi"))
8768 (const_int 0)))
8769 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8770 (ior:QI (match_dup 1) (match_dup 2)))]
8771 "ix86_match_ccmode (insn, CCNOmode)
8772 && ix86_binary_operator_ok (IOR, QImode, operands)"
8773 "or{b}\t{%2, %0|%0, %2}"
8774 [(set_attr "type" "alu")
8775 (set_attr "mode" "QI")])
8776
8777 (define_insn "*iorqi_2_slp"
8778 [(set (reg 17)
8779 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8780 (match_operand:QI 1 "general_operand" "qim,qi"))
8781 (const_int 0)))
8782 (set (strict_low_part (match_dup 0))
8783 (ior:QI (match_dup 0) (match_dup 1)))]
8784 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8785 && ix86_match_ccmode (insn, CCNOmode)
8786 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8787 "or{b}\t{%1, %0|%0, %1}"
8788 [(set_attr "type" "alu1")
8789 (set_attr "mode" "QI")])
8790
8791 (define_insn "*iorqi_3"
8792 [(set (reg 17)
8793 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8794 (match_operand:QI 2 "general_operand" "qim"))
8795 (const_int 0)))
8796 (clobber (match_scratch:QI 0 "=q"))]
8797 "ix86_match_ccmode (insn, CCNOmode)
8798 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8799 "or{b}\t{%2, %0|%0, %2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "mode" "QI")])
8802
8803 (define_insn "iorqi_ext_0"
8804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8805 (const_int 8)
8806 (const_int 8))
8807 (ior:SI
8808 (zero_extract:SI
8809 (match_operand 1 "ext_register_operand" "0")
8810 (const_int 8)
8811 (const_int 8))
8812 (match_operand 2 "const_int_operand" "n")))
8813 (clobber (reg:CC 17))]
8814 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8815 "or{b}\t{%2, %h0|%h0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "length_immediate" "1")
8818 (set_attr "mode" "QI")])
8819
8820 (define_insn "*iorqi_ext_1"
8821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8822 (const_int 8)
8823 (const_int 8))
8824 (ior:SI
8825 (zero_extract:SI
8826 (match_operand 1 "ext_register_operand" "0")
8827 (const_int 8)
8828 (const_int 8))
8829 (zero_extend:SI
8830 (match_operand:QI 2 "general_operand" "Qm"))))
8831 (clobber (reg:CC 17))]
8832 "!TARGET_64BIT
8833 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8834 "or{b}\t{%2, %h0|%h0, %2}"
8835 [(set_attr "type" "alu")
8836 (set_attr "length_immediate" "0")
8837 (set_attr "mode" "QI")])
8838
8839 (define_insn "*iorqi_ext_1_rex64"
8840 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8841 (const_int 8)
8842 (const_int 8))
8843 (ior:SI
8844 (zero_extract:SI
8845 (match_operand 1 "ext_register_operand" "0")
8846 (const_int 8)
8847 (const_int 8))
8848 (zero_extend:SI
8849 (match_operand 2 "ext_register_operand" "Q"))))
8850 (clobber (reg:CC 17))]
8851 "TARGET_64BIT
8852 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8853 "or{b}\t{%2, %h0|%h0, %2}"
8854 [(set_attr "type" "alu")
8855 (set_attr "length_immediate" "0")
8856 (set_attr "mode" "QI")])
8857
8858 (define_insn "*iorqi_ext_2"
8859 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8860 (const_int 8)
8861 (const_int 8))
8862 (ior:SI
8863 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8864 (const_int 8)
8865 (const_int 8))
8866 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8867 (const_int 8)
8868 (const_int 8))))
8869 (clobber (reg:CC 17))]
8870 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8871 "ior{b}\t{%h2, %h0|%h0, %h2}"
8872 [(set_attr "type" "alu")
8873 (set_attr "length_immediate" "0")
8874 (set_attr "mode" "QI")])
8875
8876 (define_split
8877 [(set (match_operand 0 "register_operand" "")
8878 (ior (match_operand 1 "register_operand" "")
8879 (match_operand 2 "const_int_operand" "")))
8880 (clobber (reg:CC 17))]
8881 "reload_completed
8882 && QI_REG_P (operands[0])
8883 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8884 && !(INTVAL (operands[2]) & ~(255 << 8))
8885 && GET_MODE (operands[0]) != QImode"
8886 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8887 (ior:SI (zero_extract:SI (match_dup 1)
8888 (const_int 8) (const_int 8))
8889 (match_dup 2)))
8890 (clobber (reg:CC 17))])]
8891 "operands[0] = gen_lowpart (SImode, operands[0]);
8892 operands[1] = gen_lowpart (SImode, operands[1]);
8893 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8894
8895 ;; Since OR can be encoded with sign extended immediate, this is only
8896 ;; profitable when 7th bit is set.
8897 (define_split
8898 [(set (match_operand 0 "register_operand" "")
8899 (ior (match_operand 1 "general_operand" "")
8900 (match_operand 2 "const_int_operand" "")))
8901 (clobber (reg:CC 17))]
8902 "reload_completed
8903 && ANY_QI_REG_P (operands[0])
8904 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8905 && !(INTVAL (operands[2]) & ~255)
8906 && (INTVAL (operands[2]) & 128)
8907 && GET_MODE (operands[0]) != QImode"
8908 [(parallel [(set (strict_low_part (match_dup 0))
8909 (ior:QI (match_dup 1)
8910 (match_dup 2)))
8911 (clobber (reg:CC 17))])]
8912 "operands[0] = gen_lowpart (QImode, operands[0]);
8913 operands[1] = gen_lowpart (QImode, operands[1]);
8914 operands[2] = gen_lowpart (QImode, operands[2]);")
8915 \f
8916 ;; Logical XOR instructions
8917
8918 ;; %%% This used to optimize known byte-wide and operations to memory.
8919 ;; If this is considered useful, it should be done with splitters.
8920
8921 (define_expand "xordi3"
8922 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8923 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8924 (match_operand:DI 2 "x86_64_general_operand" "")))
8925 (clobber (reg:CC 17))]
8926 "TARGET_64BIT"
8927 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8928
8929 (define_insn "*xordi_1_rex64"
8930 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8931 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8932 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8933 (clobber (reg:CC 17))]
8934 "TARGET_64BIT
8935 && ix86_binary_operator_ok (XOR, DImode, operands)"
8936 "@
8937 xor{q}\t{%2, %0|%0, %2}
8938 xor{q}\t{%2, %0|%0, %2}"
8939 [(set_attr "type" "alu")
8940 (set_attr "mode" "DI,DI")])
8941
8942 (define_insn "*xordi_2_rex64"
8943 [(set (reg 17)
8944 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8945 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8946 (const_int 0)))
8947 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8948 (xor:DI (match_dup 1) (match_dup 2)))]
8949 "TARGET_64BIT
8950 && ix86_match_ccmode (insn, CCNOmode)
8951 && ix86_binary_operator_ok (XOR, DImode, operands)"
8952 "@
8953 xor{q}\t{%2, %0|%0, %2}
8954 xor{q}\t{%2, %0|%0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "DI,DI")])
8957
8958 (define_insn "*xordi_3_rex64"
8959 [(set (reg 17)
8960 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8961 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8962 (const_int 0)))
8963 (clobber (match_scratch:DI 0 "=r"))]
8964 "TARGET_64BIT
8965 && ix86_match_ccmode (insn, CCNOmode)
8966 && ix86_binary_operator_ok (XOR, DImode, operands)"
8967 "xor{q}\t{%2, %0|%0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "DI")])
8970
8971 (define_expand "xorsi3"
8972 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8973 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8974 (match_operand:SI 2 "general_operand" "")))
8975 (clobber (reg:CC 17))]
8976 ""
8977 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8978
8979 (define_insn "*xorsi_1"
8980 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8981 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8982 (match_operand:SI 2 "general_operand" "ri,rm")))
8983 (clobber (reg:CC 17))]
8984 "ix86_binary_operator_ok (XOR, SImode, operands)"
8985 "xor{l}\t{%2, %0|%0, %2}"
8986 [(set_attr "type" "alu")
8987 (set_attr "mode" "SI")])
8988
8989 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8990 ;; Add speccase for immediates
8991 (define_insn "*xorsi_1_zext"
8992 [(set (match_operand:DI 0 "register_operand" "=r")
8993 (zero_extend:DI
8994 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8995 (match_operand:SI 2 "general_operand" "rim"))))
8996 (clobber (reg:CC 17))]
8997 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8998 "xor{l}\t{%2, %k0|%k0, %2}"
8999 [(set_attr "type" "alu")
9000 (set_attr "mode" "SI")])
9001
9002 (define_insn "*xorsi_1_zext_imm"
9003 [(set (match_operand:DI 0 "register_operand" "=r")
9004 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9005 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9006 (clobber (reg:CC 17))]
9007 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9008 "xor{l}\t{%2, %k0|%k0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "SI")])
9011
9012 (define_insn "*xorsi_2"
9013 [(set (reg 17)
9014 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9015 (match_operand:SI 2 "general_operand" "rim,ri"))
9016 (const_int 0)))
9017 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9018 (xor:SI (match_dup 1) (match_dup 2)))]
9019 "ix86_match_ccmode (insn, CCNOmode)
9020 && ix86_binary_operator_ok (XOR, SImode, operands)"
9021 "xor{l}\t{%2, %0|%0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "SI")])
9024
9025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9026 ;; ??? Special case for immediate operand is missing - it is tricky.
9027 (define_insn "*xorsi_2_zext"
9028 [(set (reg 17)
9029 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9030 (match_operand:SI 2 "general_operand" "rim"))
9031 (const_int 0)))
9032 (set (match_operand:DI 0 "register_operand" "=r")
9033 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9034 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9035 && ix86_binary_operator_ok (XOR, SImode, operands)"
9036 "xor{l}\t{%2, %k0|%k0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "SI")])
9039
9040 (define_insn "*xorsi_2_zext_imm"
9041 [(set (reg 17)
9042 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9043 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9044 (const_int 0)))
9045 (set (match_operand:DI 0 "register_operand" "=r")
9046 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9047 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9048 && ix86_binary_operator_ok (XOR, SImode, operands)"
9049 "xor{l}\t{%2, %k0|%k0, %2}"
9050 [(set_attr "type" "alu")
9051 (set_attr "mode" "SI")])
9052
9053 (define_insn "*xorsi_3"
9054 [(set (reg 17)
9055 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9056 (match_operand:SI 2 "general_operand" "rim"))
9057 (const_int 0)))
9058 (clobber (match_scratch:SI 0 "=r"))]
9059 "ix86_match_ccmode (insn, CCNOmode)
9060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9061 "xor{l}\t{%2, %0|%0, %2}"
9062 [(set_attr "type" "alu")
9063 (set_attr "mode" "SI")])
9064
9065 (define_expand "xorhi3"
9066 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9067 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9068 (match_operand:HI 2 "general_operand" "")))
9069 (clobber (reg:CC 17))]
9070 "TARGET_HIMODE_MATH"
9071 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9072
9073 (define_insn "*xorhi_1"
9074 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9075 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9076 (match_operand:HI 2 "general_operand" "rmi,ri")))
9077 (clobber (reg:CC 17))]
9078 "ix86_binary_operator_ok (XOR, HImode, operands)"
9079 "xor{w}\t{%2, %0|%0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "mode" "HI")])
9082
9083 (define_insn "*xorhi_2"
9084 [(set (reg 17)
9085 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9086 (match_operand:HI 2 "general_operand" "rim,ri"))
9087 (const_int 0)))
9088 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9089 (xor:HI (match_dup 1) (match_dup 2)))]
9090 "ix86_match_ccmode (insn, CCNOmode)
9091 && ix86_binary_operator_ok (XOR, HImode, operands)"
9092 "xor{w}\t{%2, %0|%0, %2}"
9093 [(set_attr "type" "alu")
9094 (set_attr "mode" "HI")])
9095
9096 (define_insn "*xorhi_3"
9097 [(set (reg 17)
9098 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9099 (match_operand:HI 2 "general_operand" "rim"))
9100 (const_int 0)))
9101 (clobber (match_scratch:HI 0 "=r"))]
9102 "ix86_match_ccmode (insn, CCNOmode)
9103 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9104 "xor{w}\t{%2, %0|%0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "mode" "HI")])
9107
9108 (define_expand "xorqi3"
9109 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9110 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9111 (match_operand:QI 2 "general_operand" "")))
9112 (clobber (reg:CC 17))]
9113 "TARGET_QIMODE_MATH"
9114 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9115
9116 ;; %%% Potential partial reg stall on alternative 2. What to do?
9117 (define_insn "*xorqi_1"
9118 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9119 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9120 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9121 (clobber (reg:CC 17))]
9122 "ix86_binary_operator_ok (XOR, QImode, operands)"
9123 "@
9124 xor{b}\t{%2, %0|%0, %2}
9125 xor{b}\t{%2, %0|%0, %2}
9126 xor{l}\t{%k2, %k0|%k0, %k2}"
9127 [(set_attr "type" "alu")
9128 (set_attr "mode" "QI,QI,SI")])
9129
9130 (define_insn "*xorqi_1_slp"
9131 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9132 (xor:QI (match_dup 0)
9133 (match_operand:QI 1 "general_operand" "qi,qmi")))
9134 (clobber (reg:CC 17))]
9135 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9136 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9137 "xor{b}\t{%1, %0|%0, %1}"
9138 [(set_attr "type" "alu1")
9139 (set_attr "mode" "QI")])
9140
9141 (define_insn "xorqi_ext_0"
9142 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9143 (const_int 8)
9144 (const_int 8))
9145 (xor:SI
9146 (zero_extract:SI
9147 (match_operand 1 "ext_register_operand" "0")
9148 (const_int 8)
9149 (const_int 8))
9150 (match_operand 2 "const_int_operand" "n")))
9151 (clobber (reg:CC 17))]
9152 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9153 "xor{b}\t{%2, %h0|%h0, %2}"
9154 [(set_attr "type" "alu")
9155 (set_attr "length_immediate" "1")
9156 (set_attr "mode" "QI")])
9157
9158 (define_insn "*xorqi_ext_1"
9159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9160 (const_int 8)
9161 (const_int 8))
9162 (xor:SI
9163 (zero_extract:SI
9164 (match_operand 1 "ext_register_operand" "0")
9165 (const_int 8)
9166 (const_int 8))
9167 (zero_extend:SI
9168 (match_operand:QI 2 "general_operand" "Qm"))))
9169 (clobber (reg:CC 17))]
9170 "!TARGET_64BIT
9171 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9172 "xor{b}\t{%2, %h0|%h0, %2}"
9173 [(set_attr "type" "alu")
9174 (set_attr "length_immediate" "0")
9175 (set_attr "mode" "QI")])
9176
9177 (define_insn "*xorqi_ext_1_rex64"
9178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9179 (const_int 8)
9180 (const_int 8))
9181 (xor:SI
9182 (zero_extract:SI
9183 (match_operand 1 "ext_register_operand" "0")
9184 (const_int 8)
9185 (const_int 8))
9186 (zero_extend:SI
9187 (match_operand 2 "ext_register_operand" "Q"))))
9188 (clobber (reg:CC 17))]
9189 "TARGET_64BIT
9190 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9191 "xor{b}\t{%2, %h0|%h0, %2}"
9192 [(set_attr "type" "alu")
9193 (set_attr "length_immediate" "0")
9194 (set_attr "mode" "QI")])
9195
9196 (define_insn "*xorqi_ext_2"
9197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9198 (const_int 8)
9199 (const_int 8))
9200 (xor:SI
9201 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9202 (const_int 8)
9203 (const_int 8))
9204 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9205 (const_int 8)
9206 (const_int 8))))
9207 (clobber (reg:CC 17))]
9208 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9209 "xor{b}\t{%h2, %h0|%h0, %h2}"
9210 [(set_attr "type" "alu")
9211 (set_attr "length_immediate" "0")
9212 (set_attr "mode" "QI")])
9213
9214 (define_insn "*xorqi_cc_1"
9215 [(set (reg 17)
9216 (compare
9217 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9218 (match_operand:QI 2 "general_operand" "qim,qi"))
9219 (const_int 0)))
9220 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9221 (xor:QI (match_dup 1) (match_dup 2)))]
9222 "ix86_match_ccmode (insn, CCNOmode)
9223 && ix86_binary_operator_ok (XOR, QImode, operands)"
9224 "xor{b}\t{%2, %0|%0, %2}"
9225 [(set_attr "type" "alu")
9226 (set_attr "mode" "QI")])
9227
9228 (define_insn "*xorqi_2_slp"
9229 [(set (reg 17)
9230 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9231 (match_operand:QI 1 "general_operand" "qim,qi"))
9232 (const_int 0)))
9233 (set (strict_low_part (match_dup 0))
9234 (xor:QI (match_dup 0) (match_dup 1)))]
9235 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9236 && ix86_match_ccmode (insn, CCNOmode)
9237 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9238 "xor{b}\t{%1, %0|%0, %1}"
9239 [(set_attr "type" "alu1")
9240 (set_attr "mode" "QI")])
9241
9242 (define_insn "*xorqi_cc_2"
9243 [(set (reg 17)
9244 (compare
9245 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9246 (match_operand:QI 2 "general_operand" "qim"))
9247 (const_int 0)))
9248 (clobber (match_scratch:QI 0 "=q"))]
9249 "ix86_match_ccmode (insn, CCNOmode)
9250 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9251 "xor{b}\t{%2, %0|%0, %2}"
9252 [(set_attr "type" "alu")
9253 (set_attr "mode" "QI")])
9254
9255 (define_insn "*xorqi_cc_ext_1"
9256 [(set (reg 17)
9257 (compare
9258 (xor:SI
9259 (zero_extract:SI
9260 (match_operand 1 "ext_register_operand" "0")
9261 (const_int 8)
9262 (const_int 8))
9263 (match_operand:QI 2 "general_operand" "qmn"))
9264 (const_int 0)))
9265 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9266 (const_int 8)
9267 (const_int 8))
9268 (xor:SI
9269 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9270 (match_dup 2)))]
9271 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9272 "xor{b}\t{%2, %h0|%h0, %2}"
9273 [(set_attr "type" "alu")
9274 (set_attr "mode" "QI")])
9275
9276 (define_insn "*xorqi_cc_ext_1_rex64"
9277 [(set (reg 17)
9278 (compare
9279 (xor:SI
9280 (zero_extract:SI
9281 (match_operand 1 "ext_register_operand" "0")
9282 (const_int 8)
9283 (const_int 8))
9284 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9285 (const_int 0)))
9286 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9287 (const_int 8)
9288 (const_int 8))
9289 (xor:SI
9290 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9291 (match_dup 2)))]
9292 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9293 "xor{b}\t{%2, %h0|%h0, %2}"
9294 [(set_attr "type" "alu")
9295 (set_attr "mode" "QI")])
9296
9297 (define_expand "xorqi_cc_ext_1"
9298 [(parallel [
9299 (set (reg:CCNO 17)
9300 (compare:CCNO
9301 (xor:SI
9302 (zero_extract:SI
9303 (match_operand 1 "ext_register_operand" "")
9304 (const_int 8)
9305 (const_int 8))
9306 (match_operand:QI 2 "general_operand" ""))
9307 (const_int 0)))
9308 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9309 (const_int 8)
9310 (const_int 8))
9311 (xor:SI
9312 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9313 (match_dup 2)))])]
9314 ""
9315 "")
9316
9317 (define_split
9318 [(set (match_operand 0 "register_operand" "")
9319 (xor (match_operand 1 "register_operand" "")
9320 (match_operand 2 "const_int_operand" "")))
9321 (clobber (reg:CC 17))]
9322 "reload_completed
9323 && QI_REG_P (operands[0])
9324 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9325 && !(INTVAL (operands[2]) & ~(255 << 8))
9326 && GET_MODE (operands[0]) != QImode"
9327 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9328 (xor:SI (zero_extract:SI (match_dup 1)
9329 (const_int 8) (const_int 8))
9330 (match_dup 2)))
9331 (clobber (reg:CC 17))])]
9332 "operands[0] = gen_lowpart (SImode, operands[0]);
9333 operands[1] = gen_lowpart (SImode, operands[1]);
9334 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9335
9336 ;; Since XOR can be encoded with sign extended immediate, this is only
9337 ;; profitable when 7th bit is set.
9338 (define_split
9339 [(set (match_operand 0 "register_operand" "")
9340 (xor (match_operand 1 "general_operand" "")
9341 (match_operand 2 "const_int_operand" "")))
9342 (clobber (reg:CC 17))]
9343 "reload_completed
9344 && ANY_QI_REG_P (operands[0])
9345 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9346 && !(INTVAL (operands[2]) & ~255)
9347 && (INTVAL (operands[2]) & 128)
9348 && GET_MODE (operands[0]) != QImode"
9349 [(parallel [(set (strict_low_part (match_dup 0))
9350 (xor:QI (match_dup 1)
9351 (match_dup 2)))
9352 (clobber (reg:CC 17))])]
9353 "operands[0] = gen_lowpart (QImode, operands[0]);
9354 operands[1] = gen_lowpart (QImode, operands[1]);
9355 operands[2] = gen_lowpart (QImode, operands[2]);")
9356 \f
9357 ;; Negation instructions
9358
9359 (define_expand "negdi2"
9360 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9361 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9362 (clobber (reg:CC 17))])]
9363 ""
9364 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9365
9366 (define_insn "*negdi2_1"
9367 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9368 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9369 (clobber (reg:CC 17))]
9370 "!TARGET_64BIT
9371 && ix86_unary_operator_ok (NEG, DImode, operands)"
9372 "#")
9373
9374 (define_split
9375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9376 (neg:DI (match_operand:DI 1 "general_operand" "")))
9377 (clobber (reg:CC 17))]
9378 "!TARGET_64BIT && reload_completed"
9379 [(parallel
9380 [(set (reg:CCZ 17)
9381 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9382 (set (match_dup 0) (neg:SI (match_dup 2)))])
9383 (parallel
9384 [(set (match_dup 1)
9385 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9386 (match_dup 3))
9387 (const_int 0)))
9388 (clobber (reg:CC 17))])
9389 (parallel
9390 [(set (match_dup 1)
9391 (neg:SI (match_dup 1)))
9392 (clobber (reg:CC 17))])]
9393 "split_di (operands+1, 1, operands+2, operands+3);
9394 split_di (operands+0, 1, operands+0, operands+1);")
9395
9396 (define_insn "*negdi2_1_rex64"
9397 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9398 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9399 (clobber (reg:CC 17))]
9400 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9401 "neg{q}\t%0"
9402 [(set_attr "type" "negnot")
9403 (set_attr "mode" "DI")])
9404
9405 ;; The problem with neg is that it does not perform (compare x 0),
9406 ;; it really performs (compare 0 x), which leaves us with the zero
9407 ;; flag being the only useful item.
9408
9409 (define_insn "*negdi2_cmpz_rex64"
9410 [(set (reg:CCZ 17)
9411 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9412 (const_int 0)))
9413 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9414 (neg:DI (match_dup 1)))]
9415 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9416 "neg{q}\t%0"
9417 [(set_attr "type" "negnot")
9418 (set_attr "mode" "DI")])
9419
9420
9421 (define_expand "negsi2"
9422 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9423 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9424 (clobber (reg:CC 17))])]
9425 ""
9426 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9427
9428 (define_insn "*negsi2_1"
9429 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9430 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9431 (clobber (reg:CC 17))]
9432 "ix86_unary_operator_ok (NEG, SImode, operands)"
9433 "neg{l}\t%0"
9434 [(set_attr "type" "negnot")
9435 (set_attr "mode" "SI")])
9436
9437 ;; Combine is quite creative about this pattern.
9438 (define_insn "*negsi2_1_zext"
9439 [(set (match_operand:DI 0 "register_operand" "=r")
9440 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9441 (const_int 32)))
9442 (const_int 32)))
9443 (clobber (reg:CC 17))]
9444 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9445 "neg{l}\t%k0"
9446 [(set_attr "type" "negnot")
9447 (set_attr "mode" "SI")])
9448
9449 ;; The problem with neg is that it does not perform (compare x 0),
9450 ;; it really performs (compare 0 x), which leaves us with the zero
9451 ;; flag being the only useful item.
9452
9453 (define_insn "*negsi2_cmpz"
9454 [(set (reg:CCZ 17)
9455 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9456 (const_int 0)))
9457 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9458 (neg:SI (match_dup 1)))]
9459 "ix86_unary_operator_ok (NEG, SImode, operands)"
9460 "neg{l}\t%0"
9461 [(set_attr "type" "negnot")
9462 (set_attr "mode" "SI")])
9463
9464 (define_insn "*negsi2_cmpz_zext"
9465 [(set (reg:CCZ 17)
9466 (compare:CCZ (lshiftrt:DI
9467 (neg:DI (ashift:DI
9468 (match_operand:DI 1 "register_operand" "0")
9469 (const_int 32)))
9470 (const_int 32))
9471 (const_int 0)))
9472 (set (match_operand:DI 0 "register_operand" "=r")
9473 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9474 (const_int 32)))
9475 (const_int 32)))]
9476 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9477 "neg{l}\t%k0"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "SI")])
9480
9481 (define_expand "neghi2"
9482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9483 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9484 (clobber (reg:CC 17))])]
9485 "TARGET_HIMODE_MATH"
9486 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9487
9488 (define_insn "*neghi2_1"
9489 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9490 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9491 (clobber (reg:CC 17))]
9492 "ix86_unary_operator_ok (NEG, HImode, operands)"
9493 "neg{w}\t%0"
9494 [(set_attr "type" "negnot")
9495 (set_attr "mode" "HI")])
9496
9497 (define_insn "*neghi2_cmpz"
9498 [(set (reg:CCZ 17)
9499 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9500 (const_int 0)))
9501 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9502 (neg:HI (match_dup 1)))]
9503 "ix86_unary_operator_ok (NEG, HImode, operands)"
9504 "neg{w}\t%0"
9505 [(set_attr "type" "negnot")
9506 (set_attr "mode" "HI")])
9507
9508 (define_expand "negqi2"
9509 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9510 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9511 (clobber (reg:CC 17))])]
9512 "TARGET_QIMODE_MATH"
9513 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9514
9515 (define_insn "*negqi2_1"
9516 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9517 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9518 (clobber (reg:CC 17))]
9519 "ix86_unary_operator_ok (NEG, QImode, operands)"
9520 "neg{b}\t%0"
9521 [(set_attr "type" "negnot")
9522 (set_attr "mode" "QI")])
9523
9524 (define_insn "*negqi2_cmpz"
9525 [(set (reg:CCZ 17)
9526 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9527 (const_int 0)))
9528 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9529 (neg:QI (match_dup 1)))]
9530 "ix86_unary_operator_ok (NEG, QImode, operands)"
9531 "neg{b}\t%0"
9532 [(set_attr "type" "negnot")
9533 (set_attr "mode" "QI")])
9534
9535 ;; Changing of sign for FP values is doable using integer unit too.
9536
9537 (define_expand "negsf2"
9538 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9539 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9540 (clobber (reg:CC 17))])]
9541 "TARGET_80387"
9542 "if (TARGET_SSE)
9543 {
9544 /* In case operand is in memory, we will not use SSE. */
9545 if (memory_operand (operands[0], VOIDmode)
9546 && rtx_equal_p (operands[0], operands[1]))
9547 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9548 else
9549 {
9550 /* Using SSE is tricky, since we need bitwise negation of -0
9551 in register. */
9552 rtx reg = gen_reg_rtx (SFmode);
9553 rtx dest = operands[0];
9554 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9555
9556 operands[1] = force_reg (SFmode, operands[1]);
9557 operands[0] = force_reg (SFmode, operands[0]);
9558 reg = force_reg (V4SFmode,
9559 gen_rtx_CONST_VECTOR (V4SFmode,
9560 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9561 CONST0_RTX (SFmode),
9562 CONST0_RTX (SFmode))));
9563 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9564 if (dest != operands[0])
9565 emit_move_insn (dest, operands[0]);
9566 }
9567 DONE;
9568 }
9569 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9570
9571 (define_insn "negsf2_memory"
9572 [(set (match_operand:SF 0 "memory_operand" "=m")
9573 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9574 (clobber (reg:CC 17))]
9575 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9576 "#")
9577
9578 (define_insn "negsf2_ifs"
9579 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9580 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9581 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9582 (clobber (reg:CC 17))]
9583 "TARGET_SSE
9584 && (reload_in_progress || reload_completed
9585 || (register_operand (operands[0], VOIDmode)
9586 && register_operand (operands[1], VOIDmode)))"
9587 "#")
9588
9589 (define_split
9590 [(set (match_operand:SF 0 "memory_operand" "")
9591 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9592 (use (match_operand:SF 2 "" ""))
9593 (clobber (reg:CC 17))]
9594 ""
9595 [(parallel [(set (match_dup 0)
9596 (neg:SF (match_dup 1)))
9597 (clobber (reg:CC 17))])])
9598
9599 (define_split
9600 [(set (match_operand:SF 0 "register_operand" "")
9601 (neg:SF (match_operand:SF 1 "register_operand" "")))
9602 (use (match_operand:V4SF 2 "" ""))
9603 (clobber (reg:CC 17))]
9604 "reload_completed && !SSE_REG_P (operands[0])"
9605 [(parallel [(set (match_dup 0)
9606 (neg:SF (match_dup 1)))
9607 (clobber (reg:CC 17))])])
9608
9609 (define_split
9610 [(set (match_operand:SF 0 "register_operand" "")
9611 (neg:SF (match_operand:SF 1 "register_operand" "")))
9612 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9613 (clobber (reg:CC 17))]
9614 "reload_completed && SSE_REG_P (operands[0])"
9615 [(set (match_dup 0)
9616 (xor:V4SF (match_dup 1)
9617 (match_dup 2)))]
9618 {
9619 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9620 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9621 if (operands_match_p (operands[0], operands[2]))
9622 {
9623 rtx tmp;
9624 tmp = operands[1];
9625 operands[1] = operands[2];
9626 operands[2] = tmp;
9627 }
9628 })
9629
9630
9631 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9632 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9633 ;; to itself.
9634 (define_insn "*negsf2_if"
9635 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9636 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9637 (clobber (reg:CC 17))]
9638 "TARGET_80387 && !TARGET_SSE
9639 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9640 "#")
9641
9642 (define_split
9643 [(set (match_operand:SF 0 "fp_register_operand" "")
9644 (neg:SF (match_operand:SF 1 "register_operand" "")))
9645 (clobber (reg:CC 17))]
9646 "TARGET_80387 && reload_completed"
9647 [(set (match_dup 0)
9648 (neg:SF (match_dup 1)))]
9649 "")
9650
9651 (define_split
9652 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9653 (neg:SF (match_operand:SF 1 "register_operand" "")))
9654 (clobber (reg:CC 17))]
9655 "TARGET_80387 && reload_completed"
9656 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9657 (clobber (reg:CC 17))])]
9658 "operands[1] = gen_int_mode (0x80000000, SImode);
9659 operands[0] = gen_lowpart (SImode, operands[0]);")
9660
9661 (define_split
9662 [(set (match_operand 0 "memory_operand" "")
9663 (neg (match_operand 1 "memory_operand" "")))
9664 (clobber (reg:CC 17))]
9665 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9666 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9667 (clobber (reg:CC 17))])]
9668 {
9669 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9670
9671 if (GET_MODE (operands[1]) == XFmode)
9672 size = 10;
9673 operands[0] = adjust_address (operands[0], QImode, size - 1);
9674 operands[1] = gen_int_mode (0x80, QImode);
9675 })
9676
9677 (define_expand "negdf2"
9678 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9679 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9680 (clobber (reg:CC 17))])]
9681 "TARGET_80387"
9682 "if (TARGET_SSE2)
9683 {
9684 /* In case operand is in memory, we will not use SSE. */
9685 if (memory_operand (operands[0], VOIDmode)
9686 && rtx_equal_p (operands[0], operands[1]))
9687 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9688 else
9689 {
9690 /* Using SSE is tricky, since we need bitwise negation of -0
9691 in register. */
9692 rtx reg;
9693 #if HOST_BITS_PER_WIDE_INT >= 64
9694 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9695 #else
9696 rtx imm = immed_double_const (0, 0x80000000, DImode);
9697 #endif
9698 rtx dest = operands[0];
9699
9700 operands[1] = force_reg (DFmode, operands[1]);
9701 operands[0] = force_reg (DFmode, operands[0]);
9702 imm = gen_lowpart (DFmode, imm);
9703 reg = force_reg (V2DFmode,
9704 gen_rtx_CONST_VECTOR (V2DFmode,
9705 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9706 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9707 if (dest != operands[0])
9708 emit_move_insn (dest, operands[0]);
9709 }
9710 DONE;
9711 }
9712 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9713
9714 (define_insn "negdf2_memory"
9715 [(set (match_operand:DF 0 "memory_operand" "=m")
9716 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9717 (clobber (reg:CC 17))]
9718 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9719 "#")
9720
9721 (define_insn "negdf2_ifs"
9722 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9723 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9724 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9725 (clobber (reg:CC 17))]
9726 "!TARGET_64BIT && TARGET_SSE2
9727 && (reload_in_progress || reload_completed
9728 || (register_operand (operands[0], VOIDmode)
9729 && register_operand (operands[1], VOIDmode)))"
9730 "#")
9731
9732 (define_insn "*negdf2_ifs_rex64"
9733 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9734 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9735 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9736 (clobber (reg:CC 17))]
9737 "TARGET_64BIT && TARGET_SSE2
9738 && (reload_in_progress || reload_completed
9739 || (register_operand (operands[0], VOIDmode)
9740 && register_operand (operands[1], VOIDmode)))"
9741 "#")
9742
9743 (define_split
9744 [(set (match_operand:DF 0 "memory_operand" "")
9745 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9746 (use (match_operand:V2DF 2 "" ""))
9747 (clobber (reg:CC 17))]
9748 ""
9749 [(parallel [(set (match_dup 0)
9750 (neg:DF (match_dup 1)))
9751 (clobber (reg:CC 17))])])
9752
9753 (define_split
9754 [(set (match_operand:DF 0 "register_operand" "")
9755 (neg:DF (match_operand:DF 1 "register_operand" "")))
9756 (use (match_operand:V2DF 2 "" ""))
9757 (clobber (reg:CC 17))]
9758 "reload_completed && !SSE_REG_P (operands[0])
9759 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9760 [(parallel [(set (match_dup 0)
9761 (neg:DF (match_dup 1)))
9762 (clobber (reg:CC 17))])])
9763
9764 (define_split
9765 [(set (match_operand:DF 0 "register_operand" "")
9766 (neg:DF (match_operand:DF 1 "register_operand" "")))
9767 (use (match_operand:V2DF 2 "" ""))
9768 (clobber (reg:CC 17))]
9769 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9770 [(parallel [(set (match_dup 0)
9771 (xor:DI (match_dup 1) (match_dup 2)))
9772 (clobber (reg:CC 17))])]
9773 "operands[0] = gen_lowpart (DImode, operands[0]);
9774 operands[1] = gen_lowpart (DImode, operands[1]);
9775 operands[2] = gen_lowpart (DImode, operands[2]);")
9776
9777 (define_split
9778 [(set (match_operand:DF 0 "register_operand" "")
9779 (neg:DF (match_operand:DF 1 "register_operand" "")))
9780 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9781 (clobber (reg:CC 17))]
9782 "reload_completed && SSE_REG_P (operands[0])"
9783 [(set (match_dup 0)
9784 (xor:V2DF (match_dup 1)
9785 (match_dup 2)))]
9786 {
9787 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9788 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9789 /* Avoid possible reformatting on the operands. */
9790 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9791 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9792 if (operands_match_p (operands[0], operands[2]))
9793 {
9794 rtx tmp;
9795 tmp = operands[1];
9796 operands[1] = operands[2];
9797 operands[2] = tmp;
9798 }
9799 })
9800
9801 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9802 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9803 ;; to itself.
9804 (define_insn "*negdf2_if"
9805 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9806 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9807 (clobber (reg:CC 17))]
9808 "!TARGET_64BIT && TARGET_80387
9809 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9810 "#")
9811
9812 ;; FIXME: We should to allow integer registers here. Problem is that
9813 ;; we need another scratch register to get constant from.
9814 ;; Forcing constant to mem if no register available in peep2 should be
9815 ;; safe even for PIC mode, because of RIP relative addressing.
9816 (define_insn "*negdf2_if_rex64"
9817 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9818 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9819 (clobber (reg:CC 17))]
9820 "TARGET_64BIT && TARGET_80387
9821 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9822 "#")
9823
9824 (define_split
9825 [(set (match_operand:DF 0 "fp_register_operand" "")
9826 (neg:DF (match_operand:DF 1 "register_operand" "")))
9827 (clobber (reg:CC 17))]
9828 "TARGET_80387 && reload_completed"
9829 [(set (match_dup 0)
9830 (neg:DF (match_dup 1)))]
9831 "")
9832
9833 (define_split
9834 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9835 (neg:DF (match_operand:DF 1 "register_operand" "")))
9836 (clobber (reg:CC 17))]
9837 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9838 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9839 (clobber (reg:CC 17))])]
9840 "operands[4] = gen_int_mode (0x80000000, SImode);
9841 split_di (operands+0, 1, operands+2, operands+3);")
9842
9843 (define_expand "negxf2"
9844 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9845 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9846 (clobber (reg:CC 17))])]
9847 "TARGET_80387"
9848 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9849
9850 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9851 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9852 ;; to itself.
9853 (define_insn "*negxf2_if"
9854 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9855 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9856 (clobber (reg:CC 17))]
9857 "TARGET_80387
9858 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9859 "#")
9860
9861 (define_split
9862 [(set (match_operand:XF 0 "fp_register_operand" "")
9863 (neg:XF (match_operand:XF 1 "register_operand" "")))
9864 (clobber (reg:CC 17))]
9865 "TARGET_80387 && reload_completed"
9866 [(set (match_dup 0)
9867 (neg:XF (match_dup 1)))]
9868 "")
9869
9870 (define_split
9871 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9872 (neg:XF (match_operand:XF 1 "register_operand" "")))
9873 (clobber (reg:CC 17))]
9874 "TARGET_80387 && reload_completed"
9875 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9876 (clobber (reg:CC 17))])]
9877 "operands[1] = GEN_INT (0x8000);
9878 operands[0] = gen_rtx_REG (SImode,
9879 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9880
9881 ;; Conditionalize these after reload. If they matches before reload, we
9882 ;; lose the clobber and ability to use integer instructions.
9883
9884 (define_insn "*negsf2_1"
9885 [(set (match_operand:SF 0 "register_operand" "=f")
9886 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9887 "TARGET_80387 && reload_completed"
9888 "fchs"
9889 [(set_attr "type" "fsgn")
9890 (set_attr "mode" "SF")])
9891
9892 (define_insn "*negdf2_1"
9893 [(set (match_operand:DF 0 "register_operand" "=f")
9894 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9895 "TARGET_80387 && reload_completed"
9896 "fchs"
9897 [(set_attr "type" "fsgn")
9898 (set_attr "mode" "DF")])
9899
9900 (define_insn "*negextendsfdf2"
9901 [(set (match_operand:DF 0 "register_operand" "=f")
9902 (neg:DF (float_extend:DF
9903 (match_operand:SF 1 "register_operand" "0"))))]
9904 "TARGET_80387"
9905 "fchs"
9906 [(set_attr "type" "fsgn")
9907 (set_attr "mode" "DF")])
9908
9909 (define_insn "*negxf2_1"
9910 [(set (match_operand:XF 0 "register_operand" "=f")
9911 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9912 "TARGET_80387 && reload_completed"
9913 "fchs"
9914 [(set_attr "type" "fsgn")
9915 (set_attr "mode" "XF")])
9916
9917 (define_insn "*negextenddfxf2"
9918 [(set (match_operand:XF 0 "register_operand" "=f")
9919 (neg:XF (float_extend:XF
9920 (match_operand:DF 1 "register_operand" "0"))))]
9921 "TARGET_80387"
9922 "fchs"
9923 [(set_attr "type" "fsgn")
9924 (set_attr "mode" "XF")])
9925
9926 (define_insn "*negextendsfxf2"
9927 [(set (match_operand:XF 0 "register_operand" "=f")
9928 (neg:XF (float_extend:XF
9929 (match_operand:SF 1 "register_operand" "0"))))]
9930 "TARGET_80387"
9931 "fchs"
9932 [(set_attr "type" "fsgn")
9933 (set_attr "mode" "XF")])
9934 \f
9935 ;; Absolute value instructions
9936
9937 (define_expand "abssf2"
9938 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9939 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9940 (clobber (reg:CC 17))])]
9941 "TARGET_80387"
9942 "if (TARGET_SSE)
9943 {
9944 /* In case operand is in memory, we will not use SSE. */
9945 if (memory_operand (operands[0], VOIDmode)
9946 && rtx_equal_p (operands[0], operands[1]))
9947 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9948 else
9949 {
9950 /* Using SSE is tricky, since we need bitwise negation of -0
9951 in register. */
9952 rtx reg = gen_reg_rtx (V4SFmode);
9953 rtx dest = operands[0];
9954 rtx imm;
9955
9956 operands[1] = force_reg (SFmode, operands[1]);
9957 operands[0] = force_reg (SFmode, operands[0]);
9958 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9959 reg = force_reg (V4SFmode,
9960 gen_rtx_CONST_VECTOR (V4SFmode,
9961 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9962 CONST0_RTX (SFmode),
9963 CONST0_RTX (SFmode))));
9964 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9965 if (dest != operands[0])
9966 emit_move_insn (dest, operands[0]);
9967 }
9968 DONE;
9969 }
9970 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9971
9972 (define_insn "abssf2_memory"
9973 [(set (match_operand:SF 0 "memory_operand" "=m")
9974 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9975 (clobber (reg:CC 17))]
9976 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9977 "#")
9978
9979 (define_insn "abssf2_ifs"
9980 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9981 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9982 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9983 (clobber (reg:CC 17))]
9984 "TARGET_SSE
9985 && (reload_in_progress || reload_completed
9986 || (register_operand (operands[0], VOIDmode)
9987 && register_operand (operands[1], VOIDmode)))"
9988 "#")
9989
9990 (define_split
9991 [(set (match_operand:SF 0 "memory_operand" "")
9992 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9993 (use (match_operand:V4SF 2 "" ""))
9994 (clobber (reg:CC 17))]
9995 ""
9996 [(parallel [(set (match_dup 0)
9997 (abs:SF (match_dup 1)))
9998 (clobber (reg:CC 17))])])
9999
10000 (define_split
10001 [(set (match_operand:SF 0 "register_operand" "")
10002 (abs:SF (match_operand:SF 1 "register_operand" "")))
10003 (use (match_operand:V4SF 2 "" ""))
10004 (clobber (reg:CC 17))]
10005 "reload_completed && !SSE_REG_P (operands[0])"
10006 [(parallel [(set (match_dup 0)
10007 (abs:SF (match_dup 1)))
10008 (clobber (reg:CC 17))])])
10009
10010 (define_split
10011 [(set (match_operand:SF 0 "register_operand" "")
10012 (abs:SF (match_operand:SF 1 "register_operand" "")))
10013 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10014 (clobber (reg:CC 17))]
10015 "reload_completed && SSE_REG_P (operands[0])"
10016 [(set (match_dup 0)
10017 (and:V4SF (match_dup 1)
10018 (match_dup 2)))]
10019 {
10020 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10021 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10022 if (operands_match_p (operands[0], operands[2]))
10023 {
10024 rtx tmp;
10025 tmp = operands[1];
10026 operands[1] = operands[2];
10027 operands[2] = tmp;
10028 }
10029 })
10030
10031 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10032 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10033 ;; to itself.
10034 (define_insn "*abssf2_if"
10035 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10036 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10037 (clobber (reg:CC 17))]
10038 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10039 "#")
10040
10041 (define_split
10042 [(set (match_operand:SF 0 "fp_register_operand" "")
10043 (abs:SF (match_operand:SF 1 "register_operand" "")))
10044 (clobber (reg:CC 17))]
10045 "TARGET_80387 && reload_completed"
10046 [(set (match_dup 0)
10047 (abs:SF (match_dup 1)))]
10048 "")
10049
10050 (define_split
10051 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10052 (abs:SF (match_operand:SF 1 "register_operand" "")))
10053 (clobber (reg:CC 17))]
10054 "TARGET_80387 && reload_completed"
10055 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10056 (clobber (reg:CC 17))])]
10057 "operands[1] = gen_int_mode (~0x80000000, SImode);
10058 operands[0] = gen_lowpart (SImode, operands[0]);")
10059
10060 (define_split
10061 [(set (match_operand 0 "memory_operand" "")
10062 (abs (match_operand 1 "memory_operand" "")))
10063 (clobber (reg:CC 17))]
10064 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10065 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10066 (clobber (reg:CC 17))])]
10067 {
10068 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10069
10070 if (GET_MODE (operands[1]) == XFmode)
10071 size = 10;
10072 operands[0] = adjust_address (operands[0], QImode, size - 1);
10073 operands[1] = gen_int_mode (~0x80, QImode);
10074 })
10075
10076 (define_expand "absdf2"
10077 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10078 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10079 (clobber (reg:CC 17))])]
10080 "TARGET_80387"
10081 "if (TARGET_SSE2)
10082 {
10083 /* In case operand is in memory, we will not use SSE. */
10084 if (memory_operand (operands[0], VOIDmode)
10085 && rtx_equal_p (operands[0], operands[1]))
10086 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10087 else
10088 {
10089 /* Using SSE is tricky, since we need bitwise negation of -0
10090 in register. */
10091 rtx reg = gen_reg_rtx (V2DFmode);
10092 #if HOST_BITS_PER_WIDE_INT >= 64
10093 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10094 #else
10095 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10096 #endif
10097 rtx dest = operands[0];
10098
10099 operands[1] = force_reg (DFmode, operands[1]);
10100 operands[0] = force_reg (DFmode, operands[0]);
10101
10102 /* Produce LONG_DOUBLE with the proper immediate argument. */
10103 imm = gen_lowpart (DFmode, imm);
10104 reg = force_reg (V2DFmode,
10105 gen_rtx_CONST_VECTOR (V2DFmode,
10106 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10107 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10108 if (dest != operands[0])
10109 emit_move_insn (dest, operands[0]);
10110 }
10111 DONE;
10112 }
10113 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10114
10115 (define_insn "absdf2_memory"
10116 [(set (match_operand:DF 0 "memory_operand" "=m")
10117 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10118 (clobber (reg:CC 17))]
10119 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10120 "#")
10121
10122 (define_insn "absdf2_ifs"
10123 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10124 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10125 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10126 (clobber (reg:CC 17))]
10127 "!TARGET_64BIT && TARGET_SSE2
10128 && (reload_in_progress || reload_completed
10129 || (register_operand (operands[0], VOIDmode)
10130 && register_operand (operands[1], VOIDmode)))"
10131 "#")
10132
10133 (define_insn "*absdf2_ifs_rex64"
10134 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10135 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10136 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10137 (clobber (reg:CC 17))]
10138 "TARGET_64BIT && TARGET_SSE2
10139 && (reload_in_progress || reload_completed
10140 || (register_operand (operands[0], VOIDmode)
10141 && register_operand (operands[1], VOIDmode)))"
10142 "#")
10143
10144 (define_split
10145 [(set (match_operand:DF 0 "memory_operand" "")
10146 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10147 (use (match_operand:V2DF 2 "" ""))
10148 (clobber (reg:CC 17))]
10149 ""
10150 [(parallel [(set (match_dup 0)
10151 (abs:DF (match_dup 1)))
10152 (clobber (reg:CC 17))])])
10153
10154 (define_split
10155 [(set (match_operand:DF 0 "register_operand" "")
10156 (abs:DF (match_operand:DF 1 "register_operand" "")))
10157 (use (match_operand:V2DF 2 "" ""))
10158 (clobber (reg:CC 17))]
10159 "reload_completed && !SSE_REG_P (operands[0])"
10160 [(parallel [(set (match_dup 0)
10161 (abs:DF (match_dup 1)))
10162 (clobber (reg:CC 17))])])
10163
10164 (define_split
10165 [(set (match_operand:DF 0 "register_operand" "")
10166 (abs:DF (match_operand:DF 1 "register_operand" "")))
10167 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10168 (clobber (reg:CC 17))]
10169 "reload_completed && SSE_REG_P (operands[0])"
10170 [(set (match_dup 0)
10171 (and:V2DF (match_dup 1)
10172 (match_dup 2)))]
10173 {
10174 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10175 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10176 /* Avoid possible reformatting on the operands. */
10177 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10178 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10179 if (operands_match_p (operands[0], operands[2]))
10180 {
10181 rtx tmp;
10182 tmp = operands[1];
10183 operands[1] = operands[2];
10184 operands[2] = tmp;
10185 }
10186 })
10187
10188
10189 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10190 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10191 ;; to itself.
10192 (define_insn "*absdf2_if"
10193 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10194 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10195 (clobber (reg:CC 17))]
10196 "!TARGET_64BIT && TARGET_80387
10197 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10198 "#")
10199
10200 ;; FIXME: We should to allow integer registers here. Problem is that
10201 ;; we need another scratch register to get constant from.
10202 ;; Forcing constant to mem if no register available in peep2 should be
10203 ;; safe even for PIC mode, because of RIP relative addressing.
10204 (define_insn "*absdf2_if_rex64"
10205 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10206 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10207 (clobber (reg:CC 17))]
10208 "TARGET_64BIT && TARGET_80387
10209 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10210 "#")
10211
10212 (define_split
10213 [(set (match_operand:DF 0 "fp_register_operand" "")
10214 (abs:DF (match_operand:DF 1 "register_operand" "")))
10215 (clobber (reg:CC 17))]
10216 "TARGET_80387 && reload_completed"
10217 [(set (match_dup 0)
10218 (abs:DF (match_dup 1)))]
10219 "")
10220
10221 (define_split
10222 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10223 (abs:DF (match_operand:DF 1 "register_operand" "")))
10224 (clobber (reg:CC 17))]
10225 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10226 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10227 (clobber (reg:CC 17))])]
10228 "operands[4] = gen_int_mode (~0x80000000, SImode);
10229 split_di (operands+0, 1, operands+2, operands+3);")
10230
10231 (define_expand "absxf2"
10232 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10233 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10234 (clobber (reg:CC 17))])]
10235 "TARGET_80387"
10236 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10237
10238 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10239 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10240 ;; to itself.
10241 (define_insn "*absxf2_if"
10242 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10243 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10244 (clobber (reg:CC 17))]
10245 "TARGET_80387
10246 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10247 "#")
10248
10249 (define_split
10250 [(set (match_operand:XF 0 "fp_register_operand" "")
10251 (abs:XF (match_operand:XF 1 "register_operand" "")))
10252 (clobber (reg:CC 17))]
10253 "TARGET_80387 && reload_completed"
10254 [(set (match_dup 0)
10255 (abs:XF (match_dup 1)))]
10256 "")
10257
10258 (define_split
10259 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10260 (abs:XF (match_operand:XF 1 "register_operand" "")))
10261 (clobber (reg:CC 17))]
10262 "TARGET_80387 && reload_completed"
10263 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10264 (clobber (reg:CC 17))])]
10265 "operands[1] = GEN_INT (~0x8000);
10266 operands[0] = gen_rtx_REG (SImode,
10267 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10268
10269 (define_insn "*abssf2_1"
10270 [(set (match_operand:SF 0 "register_operand" "=f")
10271 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10272 "TARGET_80387 && reload_completed"
10273 "fabs"
10274 [(set_attr "type" "fsgn")
10275 (set_attr "mode" "SF")])
10276
10277 (define_insn "*absdf2_1"
10278 [(set (match_operand:DF 0 "register_operand" "=f")
10279 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10280 "TARGET_80387 && reload_completed"
10281 "fabs"
10282 [(set_attr "type" "fsgn")
10283 (set_attr "mode" "DF")])
10284
10285 (define_insn "*absextendsfdf2"
10286 [(set (match_operand:DF 0 "register_operand" "=f")
10287 (abs:DF (float_extend:DF
10288 (match_operand:SF 1 "register_operand" "0"))))]
10289 "TARGET_80387"
10290 "fabs"
10291 [(set_attr "type" "fsgn")
10292 (set_attr "mode" "DF")])
10293
10294 (define_insn "*absxf2_1"
10295 [(set (match_operand:XF 0 "register_operand" "=f")
10296 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10297 "TARGET_80387 && reload_completed"
10298 "fabs"
10299 [(set_attr "type" "fsgn")
10300 (set_attr "mode" "DF")])
10301
10302 (define_insn "*absextenddfxf2"
10303 [(set (match_operand:XF 0 "register_operand" "=f")
10304 (abs:XF (float_extend:XF
10305 (match_operand:DF 1 "register_operand" "0"))))]
10306 "TARGET_80387"
10307 "fabs"
10308 [(set_attr "type" "fsgn")
10309 (set_attr "mode" "XF")])
10310
10311 (define_insn "*absextendsfxf2"
10312 [(set (match_operand:XF 0 "register_operand" "=f")
10313 (abs:XF (float_extend:XF
10314 (match_operand:SF 1 "register_operand" "0"))))]
10315 "TARGET_80387"
10316 "fabs"
10317 [(set_attr "type" "fsgn")
10318 (set_attr "mode" "XF")])
10319 \f
10320 ;; One complement instructions
10321
10322 (define_expand "one_cmpldi2"
10323 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10324 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10325 "TARGET_64BIT"
10326 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10327
10328 (define_insn "*one_cmpldi2_1_rex64"
10329 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10330 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10331 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10332 "not{q}\t%0"
10333 [(set_attr "type" "negnot")
10334 (set_attr "mode" "DI")])
10335
10336 (define_insn "*one_cmpldi2_2_rex64"
10337 [(set (reg 17)
10338 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10339 (const_int 0)))
10340 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10341 (not:DI (match_dup 1)))]
10342 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10343 && ix86_unary_operator_ok (NOT, DImode, operands)"
10344 "#"
10345 [(set_attr "type" "alu1")
10346 (set_attr "mode" "DI")])
10347
10348 (define_split
10349 [(set (reg 17)
10350 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10351 (const_int 0)))
10352 (set (match_operand:DI 0 "nonimmediate_operand" "")
10353 (not:DI (match_dup 1)))]
10354 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10355 [(parallel [(set (reg:CCNO 17)
10356 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10357 (const_int 0)))
10358 (set (match_dup 0)
10359 (xor:DI (match_dup 1) (const_int -1)))])]
10360 "")
10361
10362 (define_expand "one_cmplsi2"
10363 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10364 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10365 ""
10366 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10367
10368 (define_insn "*one_cmplsi2_1"
10369 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10370 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10371 "ix86_unary_operator_ok (NOT, SImode, operands)"
10372 "not{l}\t%0"
10373 [(set_attr "type" "negnot")
10374 (set_attr "mode" "SI")])
10375
10376 ;; ??? Currently never generated - xor is used instead.
10377 (define_insn "*one_cmplsi2_1_zext"
10378 [(set (match_operand:DI 0 "register_operand" "=r")
10379 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10380 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10381 "not{l}\t%k0"
10382 [(set_attr "type" "negnot")
10383 (set_attr "mode" "SI")])
10384
10385 (define_insn "*one_cmplsi2_2"
10386 [(set (reg 17)
10387 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10388 (const_int 0)))
10389 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10390 (not:SI (match_dup 1)))]
10391 "ix86_match_ccmode (insn, CCNOmode)
10392 && ix86_unary_operator_ok (NOT, SImode, operands)"
10393 "#"
10394 [(set_attr "type" "alu1")
10395 (set_attr "mode" "SI")])
10396
10397 (define_split
10398 [(set (reg 17)
10399 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10400 (const_int 0)))
10401 (set (match_operand:SI 0 "nonimmediate_operand" "")
10402 (not:SI (match_dup 1)))]
10403 "ix86_match_ccmode (insn, CCNOmode)"
10404 [(parallel [(set (reg:CCNO 17)
10405 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10406 (const_int 0)))
10407 (set (match_dup 0)
10408 (xor:SI (match_dup 1) (const_int -1)))])]
10409 "")
10410
10411 ;; ??? Currently never generated - xor is used instead.
10412 (define_insn "*one_cmplsi2_2_zext"
10413 [(set (reg 17)
10414 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10415 (const_int 0)))
10416 (set (match_operand:DI 0 "register_operand" "=r")
10417 (zero_extend:DI (not:SI (match_dup 1))))]
10418 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10419 && ix86_unary_operator_ok (NOT, SImode, operands)"
10420 "#"
10421 [(set_attr "type" "alu1")
10422 (set_attr "mode" "SI")])
10423
10424 (define_split
10425 [(set (reg 17)
10426 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10427 (const_int 0)))
10428 (set (match_operand:DI 0 "register_operand" "")
10429 (zero_extend:DI (not:SI (match_dup 1))))]
10430 "ix86_match_ccmode (insn, CCNOmode)"
10431 [(parallel [(set (reg:CCNO 17)
10432 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10433 (const_int 0)))
10434 (set (match_dup 0)
10435 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10436 "")
10437
10438 (define_expand "one_cmplhi2"
10439 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10440 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10441 "TARGET_HIMODE_MATH"
10442 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10443
10444 (define_insn "*one_cmplhi2_1"
10445 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10446 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10447 "ix86_unary_operator_ok (NOT, HImode, operands)"
10448 "not{w}\t%0"
10449 [(set_attr "type" "negnot")
10450 (set_attr "mode" "HI")])
10451
10452 (define_insn "*one_cmplhi2_2"
10453 [(set (reg 17)
10454 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10455 (const_int 0)))
10456 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10457 (not:HI (match_dup 1)))]
10458 "ix86_match_ccmode (insn, CCNOmode)
10459 && ix86_unary_operator_ok (NEG, HImode, operands)"
10460 "#"
10461 [(set_attr "type" "alu1")
10462 (set_attr "mode" "HI")])
10463
10464 (define_split
10465 [(set (reg 17)
10466 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10467 (const_int 0)))
10468 (set (match_operand:HI 0 "nonimmediate_operand" "")
10469 (not:HI (match_dup 1)))]
10470 "ix86_match_ccmode (insn, CCNOmode)"
10471 [(parallel [(set (reg:CCNO 17)
10472 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10473 (const_int 0)))
10474 (set (match_dup 0)
10475 (xor:HI (match_dup 1) (const_int -1)))])]
10476 "")
10477
10478 ;; %%% Potential partial reg stall on alternative 1. What to do?
10479 (define_expand "one_cmplqi2"
10480 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10481 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10482 "TARGET_QIMODE_MATH"
10483 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10484
10485 (define_insn "*one_cmplqi2_1"
10486 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10487 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10488 "ix86_unary_operator_ok (NOT, QImode, operands)"
10489 "@
10490 not{b}\t%0
10491 not{l}\t%k0"
10492 [(set_attr "type" "negnot")
10493 (set_attr "mode" "QI,SI")])
10494
10495 (define_insn "*one_cmplqi2_2"
10496 [(set (reg 17)
10497 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10498 (const_int 0)))
10499 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10500 (not:QI (match_dup 1)))]
10501 "ix86_match_ccmode (insn, CCNOmode)
10502 && ix86_unary_operator_ok (NOT, QImode, operands)"
10503 "#"
10504 [(set_attr "type" "alu1")
10505 (set_attr "mode" "QI")])
10506
10507 (define_split
10508 [(set (reg 17)
10509 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10510 (const_int 0)))
10511 (set (match_operand:QI 0 "nonimmediate_operand" "")
10512 (not:QI (match_dup 1)))]
10513 "ix86_match_ccmode (insn, CCNOmode)"
10514 [(parallel [(set (reg:CCNO 17)
10515 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10516 (const_int 0)))
10517 (set (match_dup 0)
10518 (xor:QI (match_dup 1) (const_int -1)))])]
10519 "")
10520 \f
10521 ;; Arithmetic shift instructions
10522
10523 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10524 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10525 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10526 ;; from the assembler input.
10527 ;;
10528 ;; This instruction shifts the target reg/mem as usual, but instead of
10529 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10530 ;; is a left shift double, bits are taken from the high order bits of
10531 ;; reg, else if the insn is a shift right double, bits are taken from the
10532 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10533 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10534 ;;
10535 ;; Since sh[lr]d does not change the `reg' operand, that is done
10536 ;; separately, making all shifts emit pairs of shift double and normal
10537 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10538 ;; support a 63 bit shift, each shift where the count is in a reg expands
10539 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10540 ;;
10541 ;; If the shift count is a constant, we need never emit more than one
10542 ;; shift pair, instead using moves and sign extension for counts greater
10543 ;; than 31.
10544
10545 (define_expand "ashldi3"
10546 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10547 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10548 (match_operand:QI 2 "nonmemory_operand" "")))
10549 (clobber (reg:CC 17))])]
10550 ""
10551 {
10552 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10553 {
10554 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10555 DONE;
10556 }
10557 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10558 DONE;
10559 })
10560
10561 (define_insn "*ashldi3_1_rex64"
10562 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10563 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10564 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10565 (clobber (reg:CC 17))]
10566 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10567 {
10568 switch (get_attr_type (insn))
10569 {
10570 case TYPE_ALU:
10571 if (operands[2] != const1_rtx)
10572 abort ();
10573 if (!rtx_equal_p (operands[0], operands[1]))
10574 abort ();
10575 return "add{q}\t{%0, %0|%0, %0}";
10576
10577 case TYPE_LEA:
10578 if (GET_CODE (operands[2]) != CONST_INT
10579 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10580 abort ();
10581 operands[1] = gen_rtx_MULT (DImode, operands[1],
10582 GEN_INT (1 << INTVAL (operands[2])));
10583 return "lea{q}\t{%a1, %0|%0, %a1}";
10584
10585 default:
10586 if (REG_P (operands[2]))
10587 return "sal{q}\t{%b2, %0|%0, %b2}";
10588 else if (operands[2] == const1_rtx
10589 && (TARGET_SHIFT1 || optimize_size))
10590 return "sal{q}\t%0";
10591 else
10592 return "sal{q}\t{%2, %0|%0, %2}";
10593 }
10594 }
10595 [(set (attr "type")
10596 (cond [(eq_attr "alternative" "1")
10597 (const_string "lea")
10598 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10599 (const_int 0))
10600 (match_operand 0 "register_operand" ""))
10601 (match_operand 2 "const1_operand" ""))
10602 (const_string "alu")
10603 ]
10604 (const_string "ishift")))
10605 (set_attr "mode" "DI")])
10606
10607 ;; Convert lea to the lea pattern to avoid flags dependency.
10608 (define_split
10609 [(set (match_operand:DI 0 "register_operand" "")
10610 (ashift:DI (match_operand:DI 1 "register_operand" "")
10611 (match_operand:QI 2 "immediate_operand" "")))
10612 (clobber (reg:CC 17))]
10613 "TARGET_64BIT && reload_completed
10614 && true_regnum (operands[0]) != true_regnum (operands[1])"
10615 [(set (match_dup 0)
10616 (mult:DI (match_dup 1)
10617 (match_dup 2)))]
10618 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10619
10620 ;; This pattern can't accept a variable shift count, since shifts by
10621 ;; zero don't affect the flags. We assume that shifts by constant
10622 ;; zero are optimized away.
10623 (define_insn "*ashldi3_cmp_rex64"
10624 [(set (reg 17)
10625 (compare
10626 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10627 (match_operand:QI 2 "immediate_operand" "e"))
10628 (const_int 0)))
10629 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10630 (ashift:DI (match_dup 1) (match_dup 2)))]
10631 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10632 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10633 {
10634 switch (get_attr_type (insn))
10635 {
10636 case TYPE_ALU:
10637 if (operands[2] != const1_rtx)
10638 abort ();
10639 return "add{q}\t{%0, %0|%0, %0}";
10640
10641 default:
10642 if (REG_P (operands[2]))
10643 return "sal{q}\t{%b2, %0|%0, %b2}";
10644 else if (operands[2] == const1_rtx
10645 && (TARGET_SHIFT1 || optimize_size))
10646 return "sal{q}\t%0";
10647 else
10648 return "sal{q}\t{%2, %0|%0, %2}";
10649 }
10650 }
10651 [(set (attr "type")
10652 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10653 (const_int 0))
10654 (match_operand 0 "register_operand" ""))
10655 (match_operand 2 "const1_operand" ""))
10656 (const_string "alu")
10657 ]
10658 (const_string "ishift")))
10659 (set_attr "mode" "DI")])
10660
10661 (define_insn "ashldi3_1"
10662 [(set (match_operand:DI 0 "register_operand" "=r")
10663 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10664 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10665 (clobber (match_scratch:SI 3 "=&r"))
10666 (clobber (reg:CC 17))]
10667 "!TARGET_64BIT && TARGET_CMOVE"
10668 "#"
10669 [(set_attr "type" "multi")])
10670
10671 (define_insn "*ashldi3_2"
10672 [(set (match_operand:DI 0 "register_operand" "=r")
10673 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10674 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10675 (clobber (reg:CC 17))]
10676 "!TARGET_64BIT"
10677 "#"
10678 [(set_attr "type" "multi")])
10679
10680 (define_split
10681 [(set (match_operand:DI 0 "register_operand" "")
10682 (ashift:DI (match_operand:DI 1 "register_operand" "")
10683 (match_operand:QI 2 "nonmemory_operand" "")))
10684 (clobber (match_scratch:SI 3 ""))
10685 (clobber (reg:CC 17))]
10686 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10687 [(const_int 0)]
10688 "ix86_split_ashldi (operands, operands[3]); DONE;")
10689
10690 (define_split
10691 [(set (match_operand:DI 0 "register_operand" "")
10692 (ashift:DI (match_operand:DI 1 "register_operand" "")
10693 (match_operand:QI 2 "nonmemory_operand" "")))
10694 (clobber (reg:CC 17))]
10695 "!TARGET_64BIT && reload_completed"
10696 [(const_int 0)]
10697 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10698
10699 (define_insn "x86_shld_1"
10700 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10701 (ior:SI (ashift:SI (match_dup 0)
10702 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10703 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10704 (minus:QI (const_int 32) (match_dup 2)))))
10705 (clobber (reg:CC 17))]
10706 ""
10707 "@
10708 shld{l}\t{%2, %1, %0|%0, %1, %2}
10709 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10710 [(set_attr "type" "ishift")
10711 (set_attr "prefix_0f" "1")
10712 (set_attr "mode" "SI")
10713 (set_attr "pent_pair" "np")
10714 (set_attr "athlon_decode" "vector")])
10715
10716 (define_expand "x86_shift_adj_1"
10717 [(set (reg:CCZ 17)
10718 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10719 (const_int 32))
10720 (const_int 0)))
10721 (set (match_operand:SI 0 "register_operand" "")
10722 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10723 (match_operand:SI 1 "register_operand" "")
10724 (match_dup 0)))
10725 (set (match_dup 1)
10726 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10727 (match_operand:SI 3 "register_operand" "r")
10728 (match_dup 1)))]
10729 "TARGET_CMOVE"
10730 "")
10731
10732 (define_expand "x86_shift_adj_2"
10733 [(use (match_operand:SI 0 "register_operand" ""))
10734 (use (match_operand:SI 1 "register_operand" ""))
10735 (use (match_operand:QI 2 "register_operand" ""))]
10736 ""
10737 {
10738 rtx label = gen_label_rtx ();
10739 rtx tmp;
10740
10741 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10742
10743 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10744 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10745 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10746 gen_rtx_LABEL_REF (VOIDmode, label),
10747 pc_rtx);
10748 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10749 JUMP_LABEL (tmp) = label;
10750
10751 emit_move_insn (operands[0], operands[1]);
10752 emit_move_insn (operands[1], const0_rtx);
10753
10754 emit_label (label);
10755 LABEL_NUSES (label) = 1;
10756
10757 DONE;
10758 })
10759
10760 (define_expand "ashlsi3"
10761 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10762 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10763 (match_operand:QI 2 "nonmemory_operand" "")))
10764 (clobber (reg:CC 17))]
10765 ""
10766 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10767
10768 (define_insn "*ashlsi3_1"
10769 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10770 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10771 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10772 (clobber (reg:CC 17))]
10773 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10774 {
10775 switch (get_attr_type (insn))
10776 {
10777 case TYPE_ALU:
10778 if (operands[2] != const1_rtx)
10779 abort ();
10780 if (!rtx_equal_p (operands[0], operands[1]))
10781 abort ();
10782 return "add{l}\t{%0, %0|%0, %0}";
10783
10784 case TYPE_LEA:
10785 return "#";
10786
10787 default:
10788 if (REG_P (operands[2]))
10789 return "sal{l}\t{%b2, %0|%0, %b2}";
10790 else if (operands[2] == const1_rtx
10791 && (TARGET_SHIFT1 || optimize_size))
10792 return "sal{l}\t%0";
10793 else
10794 return "sal{l}\t{%2, %0|%0, %2}";
10795 }
10796 }
10797 [(set (attr "type")
10798 (cond [(eq_attr "alternative" "1")
10799 (const_string "lea")
10800 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10801 (const_int 0))
10802 (match_operand 0 "register_operand" ""))
10803 (match_operand 2 "const1_operand" ""))
10804 (const_string "alu")
10805 ]
10806 (const_string "ishift")))
10807 (set_attr "mode" "SI")])
10808
10809 ;; Convert lea to the lea pattern to avoid flags dependency.
10810 (define_split
10811 [(set (match_operand 0 "register_operand" "")
10812 (ashift (match_operand 1 "index_register_operand" "")
10813 (match_operand:QI 2 "const_int_operand" "")))
10814 (clobber (reg:CC 17))]
10815 "reload_completed
10816 && true_regnum (operands[0]) != true_regnum (operands[1])"
10817 [(const_int 0)]
10818 {
10819 rtx pat;
10820 operands[0] = gen_lowpart (SImode, operands[0]);
10821 operands[1] = gen_lowpart (Pmode, operands[1]);
10822 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10823 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10824 if (Pmode != SImode)
10825 pat = gen_rtx_SUBREG (SImode, pat, 0);
10826 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10827 DONE;
10828 })
10829
10830 ;; Rare case of shifting RSP is handled by generating move and shift
10831 (define_split
10832 [(set (match_operand 0 "register_operand" "")
10833 (ashift (match_operand 1 "register_operand" "")
10834 (match_operand:QI 2 "const_int_operand" "")))
10835 (clobber (reg:CC 17))]
10836 "reload_completed
10837 && true_regnum (operands[0]) != true_regnum (operands[1])"
10838 [(const_int 0)]
10839 {
10840 rtx pat, clob;
10841 emit_move_insn (operands[1], operands[0]);
10842 pat = gen_rtx_SET (VOIDmode, operands[0],
10843 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10844 operands[0], operands[2]));
10845 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10846 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10847 DONE;
10848 })
10849
10850 (define_insn "*ashlsi3_1_zext"
10851 [(set (match_operand:DI 0 "register_operand" "=r,r")
10852 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10853 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10854 (clobber (reg:CC 17))]
10855 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10856 {
10857 switch (get_attr_type (insn))
10858 {
10859 case TYPE_ALU:
10860 if (operands[2] != const1_rtx)
10861 abort ();
10862 return "add{l}\t{%k0, %k0|%k0, %k0}";
10863
10864 case TYPE_LEA:
10865 return "#";
10866
10867 default:
10868 if (REG_P (operands[2]))
10869 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10870 else if (operands[2] == const1_rtx
10871 && (TARGET_SHIFT1 || optimize_size))
10872 return "sal{l}\t%k0";
10873 else
10874 return "sal{l}\t{%2, %k0|%k0, %2}";
10875 }
10876 }
10877 [(set (attr "type")
10878 (cond [(eq_attr "alternative" "1")
10879 (const_string "lea")
10880 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10881 (const_int 0))
10882 (match_operand 2 "const1_operand" ""))
10883 (const_string "alu")
10884 ]
10885 (const_string "ishift")))
10886 (set_attr "mode" "SI")])
10887
10888 ;; Convert lea to the lea pattern to avoid flags dependency.
10889 (define_split
10890 [(set (match_operand:DI 0 "register_operand" "")
10891 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10892 (match_operand:QI 2 "const_int_operand" ""))))
10893 (clobber (reg:CC 17))]
10894 "TARGET_64BIT && reload_completed
10895 && true_regnum (operands[0]) != true_regnum (operands[1])"
10896 [(set (match_dup 0) (zero_extend:DI
10897 (subreg:SI (mult:SI (match_dup 1)
10898 (match_dup 2)) 0)))]
10899 {
10900 operands[1] = gen_lowpart (Pmode, operands[1]);
10901 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10902 })
10903
10904 ;; This pattern can't accept a variable shift count, since shifts by
10905 ;; zero don't affect the flags. We assume that shifts by constant
10906 ;; zero are optimized away.
10907 (define_insn "*ashlsi3_cmp"
10908 [(set (reg 17)
10909 (compare
10910 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10911 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10912 (const_int 0)))
10913 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10914 (ashift:SI (match_dup 1) (match_dup 2)))]
10915 "ix86_match_ccmode (insn, CCGOCmode)
10916 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10917 {
10918 switch (get_attr_type (insn))
10919 {
10920 case TYPE_ALU:
10921 if (operands[2] != const1_rtx)
10922 abort ();
10923 return "add{l}\t{%0, %0|%0, %0}";
10924
10925 default:
10926 if (REG_P (operands[2]))
10927 return "sal{l}\t{%b2, %0|%0, %b2}";
10928 else if (operands[2] == const1_rtx
10929 && (TARGET_SHIFT1 || optimize_size))
10930 return "sal{l}\t%0";
10931 else
10932 return "sal{l}\t{%2, %0|%0, %2}";
10933 }
10934 }
10935 [(set (attr "type")
10936 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10937 (const_int 0))
10938 (match_operand 0 "register_operand" ""))
10939 (match_operand 2 "const1_operand" ""))
10940 (const_string "alu")
10941 ]
10942 (const_string "ishift")))
10943 (set_attr "mode" "SI")])
10944
10945 (define_insn "*ashlsi3_cmp_zext"
10946 [(set (reg 17)
10947 (compare
10948 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10949 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10950 (const_int 0)))
10951 (set (match_operand:DI 0 "register_operand" "=r")
10952 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10953 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10954 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10955 {
10956 switch (get_attr_type (insn))
10957 {
10958 case TYPE_ALU:
10959 if (operands[2] != const1_rtx)
10960 abort ();
10961 return "add{l}\t{%k0, %k0|%k0, %k0}";
10962
10963 default:
10964 if (REG_P (operands[2]))
10965 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10966 else if (operands[2] == const1_rtx
10967 && (TARGET_SHIFT1 || optimize_size))
10968 return "sal{l}\t%k0";
10969 else
10970 return "sal{l}\t{%2, %k0|%k0, %2}";
10971 }
10972 }
10973 [(set (attr "type")
10974 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10975 (const_int 0))
10976 (match_operand 2 "const1_operand" ""))
10977 (const_string "alu")
10978 ]
10979 (const_string "ishift")))
10980 (set_attr "mode" "SI")])
10981
10982 (define_expand "ashlhi3"
10983 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10984 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10985 (match_operand:QI 2 "nonmemory_operand" "")))
10986 (clobber (reg:CC 17))]
10987 "TARGET_HIMODE_MATH"
10988 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10989
10990 (define_insn "*ashlhi3_1_lea"
10991 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10992 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10993 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10994 (clobber (reg:CC 17))]
10995 "!TARGET_PARTIAL_REG_STALL
10996 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10997 {
10998 switch (get_attr_type (insn))
10999 {
11000 case TYPE_LEA:
11001 return "#";
11002 case TYPE_ALU:
11003 if (operands[2] != const1_rtx)
11004 abort ();
11005 return "add{w}\t{%0, %0|%0, %0}";
11006
11007 default:
11008 if (REG_P (operands[2]))
11009 return "sal{w}\t{%b2, %0|%0, %b2}";
11010 else if (operands[2] == const1_rtx
11011 && (TARGET_SHIFT1 || optimize_size))
11012 return "sal{w}\t%0";
11013 else
11014 return "sal{w}\t{%2, %0|%0, %2}";
11015 }
11016 }
11017 [(set (attr "type")
11018 (cond [(eq_attr "alternative" "1")
11019 (const_string "lea")
11020 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11021 (const_int 0))
11022 (match_operand 0 "register_operand" ""))
11023 (match_operand 2 "const1_operand" ""))
11024 (const_string "alu")
11025 ]
11026 (const_string "ishift")))
11027 (set_attr "mode" "HI,SI")])
11028
11029 (define_insn "*ashlhi3_1"
11030 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11031 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11032 (match_operand:QI 2 "nonmemory_operand" "cI")))
11033 (clobber (reg:CC 17))]
11034 "TARGET_PARTIAL_REG_STALL
11035 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11036 {
11037 switch (get_attr_type (insn))
11038 {
11039 case TYPE_ALU:
11040 if (operands[2] != const1_rtx)
11041 abort ();
11042 return "add{w}\t{%0, %0|%0, %0}";
11043
11044 default:
11045 if (REG_P (operands[2]))
11046 return "sal{w}\t{%b2, %0|%0, %b2}";
11047 else if (operands[2] == const1_rtx
11048 && (TARGET_SHIFT1 || optimize_size))
11049 return "sal{w}\t%0";
11050 else
11051 return "sal{w}\t{%2, %0|%0, %2}";
11052 }
11053 }
11054 [(set (attr "type")
11055 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11056 (const_int 0))
11057 (match_operand 0 "register_operand" ""))
11058 (match_operand 2 "const1_operand" ""))
11059 (const_string "alu")
11060 ]
11061 (const_string "ishift")))
11062 (set_attr "mode" "HI")])
11063
11064 ;; This pattern can't accept a variable shift count, since shifts by
11065 ;; zero don't affect the flags. We assume that shifts by constant
11066 ;; zero are optimized away.
11067 (define_insn "*ashlhi3_cmp"
11068 [(set (reg 17)
11069 (compare
11070 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11071 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11072 (const_int 0)))
11073 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11074 (ashift:HI (match_dup 1) (match_dup 2)))]
11075 "ix86_match_ccmode (insn, CCGOCmode)
11076 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11077 {
11078 switch (get_attr_type (insn))
11079 {
11080 case TYPE_ALU:
11081 if (operands[2] != const1_rtx)
11082 abort ();
11083 return "add{w}\t{%0, %0|%0, %0}";
11084
11085 default:
11086 if (REG_P (operands[2]))
11087 return "sal{w}\t{%b2, %0|%0, %b2}";
11088 else if (operands[2] == const1_rtx
11089 && (TARGET_SHIFT1 || optimize_size))
11090 return "sal{w}\t%0";
11091 else
11092 return "sal{w}\t{%2, %0|%0, %2}";
11093 }
11094 }
11095 [(set (attr "type")
11096 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11097 (const_int 0))
11098 (match_operand 0 "register_operand" ""))
11099 (match_operand 2 "const1_operand" ""))
11100 (const_string "alu")
11101 ]
11102 (const_string "ishift")))
11103 (set_attr "mode" "HI")])
11104
11105 (define_expand "ashlqi3"
11106 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11107 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11108 (match_operand:QI 2 "nonmemory_operand" "")))
11109 (clobber (reg:CC 17))]
11110 "TARGET_QIMODE_MATH"
11111 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11112
11113 ;; %%% Potential partial reg stall on alternative 2. What to do?
11114
11115 (define_insn "*ashlqi3_1_lea"
11116 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11117 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11118 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11119 (clobber (reg:CC 17))]
11120 "!TARGET_PARTIAL_REG_STALL
11121 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11122 {
11123 switch (get_attr_type (insn))
11124 {
11125 case TYPE_LEA:
11126 return "#";
11127 case TYPE_ALU:
11128 if (operands[2] != const1_rtx)
11129 abort ();
11130 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11131 return "add{l}\t{%k0, %k0|%k0, %k0}";
11132 else
11133 return "add{b}\t{%0, %0|%0, %0}";
11134
11135 default:
11136 if (REG_P (operands[2]))
11137 {
11138 if (get_attr_mode (insn) == MODE_SI)
11139 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11140 else
11141 return "sal{b}\t{%b2, %0|%0, %b2}";
11142 }
11143 else if (operands[2] == const1_rtx
11144 && (TARGET_SHIFT1 || optimize_size))
11145 {
11146 if (get_attr_mode (insn) == MODE_SI)
11147 return "sal{l}\t%0";
11148 else
11149 return "sal{b}\t%0";
11150 }
11151 else
11152 {
11153 if (get_attr_mode (insn) == MODE_SI)
11154 return "sal{l}\t{%2, %k0|%k0, %2}";
11155 else
11156 return "sal{b}\t{%2, %0|%0, %2}";
11157 }
11158 }
11159 }
11160 [(set (attr "type")
11161 (cond [(eq_attr "alternative" "2")
11162 (const_string "lea")
11163 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11164 (const_int 0))
11165 (match_operand 0 "register_operand" ""))
11166 (match_operand 2 "const1_operand" ""))
11167 (const_string "alu")
11168 ]
11169 (const_string "ishift")))
11170 (set_attr "mode" "QI,SI,SI")])
11171
11172 (define_insn "*ashlqi3_1"
11173 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11174 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11175 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11176 (clobber (reg:CC 17))]
11177 "TARGET_PARTIAL_REG_STALL
11178 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11179 {
11180 switch (get_attr_type (insn))
11181 {
11182 case TYPE_ALU:
11183 if (operands[2] != const1_rtx)
11184 abort ();
11185 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11186 return "add{l}\t{%k0, %k0|%k0, %k0}";
11187 else
11188 return "add{b}\t{%0, %0|%0, %0}";
11189
11190 default:
11191 if (REG_P (operands[2]))
11192 {
11193 if (get_attr_mode (insn) == MODE_SI)
11194 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11195 else
11196 return "sal{b}\t{%b2, %0|%0, %b2}";
11197 }
11198 else if (operands[2] == const1_rtx
11199 && (TARGET_SHIFT1 || optimize_size))
11200 {
11201 if (get_attr_mode (insn) == MODE_SI)
11202 return "sal{l}\t%0";
11203 else
11204 return "sal{b}\t%0";
11205 }
11206 else
11207 {
11208 if (get_attr_mode (insn) == MODE_SI)
11209 return "sal{l}\t{%2, %k0|%k0, %2}";
11210 else
11211 return "sal{b}\t{%2, %0|%0, %2}";
11212 }
11213 }
11214 }
11215 [(set (attr "type")
11216 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11217 (const_int 0))
11218 (match_operand 0 "register_operand" ""))
11219 (match_operand 2 "const1_operand" ""))
11220 (const_string "alu")
11221 ]
11222 (const_string "ishift")))
11223 (set_attr "mode" "QI,SI")])
11224
11225 ;; This pattern can't accept a variable shift count, since shifts by
11226 ;; zero don't affect the flags. We assume that shifts by constant
11227 ;; zero are optimized away.
11228 (define_insn "*ashlqi3_cmp"
11229 [(set (reg 17)
11230 (compare
11231 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11232 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11233 (const_int 0)))
11234 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11235 (ashift:QI (match_dup 1) (match_dup 2)))]
11236 "ix86_match_ccmode (insn, CCGOCmode)
11237 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11238 {
11239 switch (get_attr_type (insn))
11240 {
11241 case TYPE_ALU:
11242 if (operands[2] != const1_rtx)
11243 abort ();
11244 return "add{b}\t{%0, %0|%0, %0}";
11245
11246 default:
11247 if (REG_P (operands[2]))
11248 return "sal{b}\t{%b2, %0|%0, %b2}";
11249 else if (operands[2] == const1_rtx
11250 && (TARGET_SHIFT1 || optimize_size))
11251 return "sal{b}\t%0";
11252 else
11253 return "sal{b}\t{%2, %0|%0, %2}";
11254 }
11255 }
11256 [(set (attr "type")
11257 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258 (const_int 0))
11259 (match_operand 0 "register_operand" ""))
11260 (match_operand 2 "const1_operand" ""))
11261 (const_string "alu")
11262 ]
11263 (const_string "ishift")))
11264 (set_attr "mode" "QI")])
11265
11266 ;; See comment above `ashldi3' about how this works.
11267
11268 (define_expand "ashrdi3"
11269 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11270 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11271 (match_operand:QI 2 "nonmemory_operand" "")))
11272 (clobber (reg:CC 17))])]
11273 ""
11274 {
11275 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11276 {
11277 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11278 DONE;
11279 }
11280 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11281 DONE;
11282 })
11283
11284 (define_insn "ashrdi3_63_rex64"
11285 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11286 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11287 (match_operand:DI 2 "const_int_operand" "i,i")))
11288 (clobber (reg:CC 17))]
11289 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11290 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11291 "@
11292 {cqto|cqo}
11293 sar{q}\t{%2, %0|%0, %2}"
11294 [(set_attr "type" "imovx,ishift")
11295 (set_attr "prefix_0f" "0,*")
11296 (set_attr "length_immediate" "0,*")
11297 (set_attr "modrm" "0,1")
11298 (set_attr "mode" "DI")])
11299
11300 (define_insn "*ashrdi3_1_one_bit_rex64"
11301 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11302 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11303 (match_operand:QI 2 "const1_operand" "")))
11304 (clobber (reg:CC 17))]
11305 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11306 && (TARGET_SHIFT1 || optimize_size)"
11307 "sar{q}\t%0"
11308 [(set_attr "type" "ishift")
11309 (set (attr "length")
11310 (if_then_else (match_operand:DI 0 "register_operand" "")
11311 (const_string "2")
11312 (const_string "*")))])
11313
11314 (define_insn "*ashrdi3_1_rex64"
11315 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11316 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11317 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11318 (clobber (reg:CC 17))]
11319 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11320 "@
11321 sar{q}\t{%2, %0|%0, %2}
11322 sar{q}\t{%b2, %0|%0, %b2}"
11323 [(set_attr "type" "ishift")
11324 (set_attr "mode" "DI")])
11325
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags. We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11330 [(set (reg 17)
11331 (compare
11332 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11333 (match_operand:QI 2 "const1_operand" ""))
11334 (const_int 0)))
11335 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11336 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11337 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11338 && (TARGET_SHIFT1 || optimize_size)
11339 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11340 "sar{q}\t%0"
11341 [(set_attr "type" "ishift")
11342 (set (attr "length")
11343 (if_then_else (match_operand:DI 0 "register_operand" "")
11344 (const_string "2")
11345 (const_string "*")))])
11346
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags. We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashrdi3_cmp_rex64"
11351 [(set (reg 17)
11352 (compare
11353 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11354 (match_operand:QI 2 "const_int_operand" "n"))
11355 (const_int 0)))
11356 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11357 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11358 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11359 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11360 "sar{q}\t{%2, %0|%0, %2}"
11361 [(set_attr "type" "ishift")
11362 (set_attr "mode" "DI")])
11363
11364
11365 (define_insn "ashrdi3_1"
11366 [(set (match_operand:DI 0 "register_operand" "=r")
11367 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11368 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11369 (clobber (match_scratch:SI 3 "=&r"))
11370 (clobber (reg:CC 17))]
11371 "!TARGET_64BIT && TARGET_CMOVE"
11372 "#"
11373 [(set_attr "type" "multi")])
11374
11375 (define_insn "*ashrdi3_2"
11376 [(set (match_operand:DI 0 "register_operand" "=r")
11377 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11378 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11379 (clobber (reg:CC 17))]
11380 "!TARGET_64BIT"
11381 "#"
11382 [(set_attr "type" "multi")])
11383
11384 (define_split
11385 [(set (match_operand:DI 0 "register_operand" "")
11386 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11387 (match_operand:QI 2 "nonmemory_operand" "")))
11388 (clobber (match_scratch:SI 3 ""))
11389 (clobber (reg:CC 17))]
11390 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11391 [(const_int 0)]
11392 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11393
11394 (define_split
11395 [(set (match_operand:DI 0 "register_operand" "")
11396 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11397 (match_operand:QI 2 "nonmemory_operand" "")))
11398 (clobber (reg:CC 17))]
11399 "!TARGET_64BIT && reload_completed"
11400 [(const_int 0)]
11401 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11402
11403 (define_insn "x86_shrd_1"
11404 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11405 (ior:SI (ashiftrt:SI (match_dup 0)
11406 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11407 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11408 (minus:QI (const_int 32) (match_dup 2)))))
11409 (clobber (reg:CC 17))]
11410 ""
11411 "@
11412 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11413 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11414 [(set_attr "type" "ishift")
11415 (set_attr "prefix_0f" "1")
11416 (set_attr "pent_pair" "np")
11417 (set_attr "mode" "SI")])
11418
11419 (define_expand "x86_shift_adj_3"
11420 [(use (match_operand:SI 0 "register_operand" ""))
11421 (use (match_operand:SI 1 "register_operand" ""))
11422 (use (match_operand:QI 2 "register_operand" ""))]
11423 ""
11424 {
11425 rtx label = gen_label_rtx ();
11426 rtx tmp;
11427
11428 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11429
11430 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11431 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11432 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11433 gen_rtx_LABEL_REF (VOIDmode, label),
11434 pc_rtx);
11435 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11436 JUMP_LABEL (tmp) = label;
11437
11438 emit_move_insn (operands[0], operands[1]);
11439 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11440
11441 emit_label (label);
11442 LABEL_NUSES (label) = 1;
11443
11444 DONE;
11445 })
11446
11447 (define_insn "ashrsi3_31"
11448 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11449 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11450 (match_operand:SI 2 "const_int_operand" "i,i")))
11451 (clobber (reg:CC 17))]
11452 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11453 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11454 "@
11455 {cltd|cdq}
11456 sar{l}\t{%2, %0|%0, %2}"
11457 [(set_attr "type" "imovx,ishift")
11458 (set_attr "prefix_0f" "0,*")
11459 (set_attr "length_immediate" "0,*")
11460 (set_attr "modrm" "0,1")
11461 (set_attr "mode" "SI")])
11462
11463 (define_insn "*ashrsi3_31_zext"
11464 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11465 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11466 (match_operand:SI 2 "const_int_operand" "i,i"))))
11467 (clobber (reg:CC 17))]
11468 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11469 && INTVAL (operands[2]) == 31
11470 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11471 "@
11472 {cltd|cdq}
11473 sar{l}\t{%2, %k0|%k0, %2}"
11474 [(set_attr "type" "imovx,ishift")
11475 (set_attr "prefix_0f" "0,*")
11476 (set_attr "length_immediate" "0,*")
11477 (set_attr "modrm" "0,1")
11478 (set_attr "mode" "SI")])
11479
11480 (define_expand "ashrsi3"
11481 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11482 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11483 (match_operand:QI 2 "nonmemory_operand" "")))
11484 (clobber (reg:CC 17))]
11485 ""
11486 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11487
11488 (define_insn "*ashrsi3_1_one_bit"
11489 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11490 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11491 (match_operand:QI 2 "const1_operand" "")))
11492 (clobber (reg:CC 17))]
11493 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11494 && (TARGET_SHIFT1 || optimize_size)"
11495 "sar{l}\t%0"
11496 [(set_attr "type" "ishift")
11497 (set (attr "length")
11498 (if_then_else (match_operand:SI 0 "register_operand" "")
11499 (const_string "2")
11500 (const_string "*")))])
11501
11502 (define_insn "*ashrsi3_1_one_bit_zext"
11503 [(set (match_operand:DI 0 "register_operand" "=r")
11504 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11505 (match_operand:QI 2 "const1_operand" ""))))
11506 (clobber (reg:CC 17))]
11507 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11508 && (TARGET_SHIFT1 || optimize_size)"
11509 "sar{l}\t%k0"
11510 [(set_attr "type" "ishift")
11511 (set_attr "length" "2")])
11512
11513 (define_insn "*ashrsi3_1"
11514 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11515 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11516 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11517 (clobber (reg:CC 17))]
11518 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11519 "@
11520 sar{l}\t{%2, %0|%0, %2}
11521 sar{l}\t{%b2, %0|%0, %b2}"
11522 [(set_attr "type" "ishift")
11523 (set_attr "mode" "SI")])
11524
11525 (define_insn "*ashrsi3_1_zext"
11526 [(set (match_operand:DI 0 "register_operand" "=r,r")
11527 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11528 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11529 (clobber (reg:CC 17))]
11530 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11531 "@
11532 sar{l}\t{%2, %k0|%k0, %2}
11533 sar{l}\t{%b2, %k0|%k0, %b2}"
11534 [(set_attr "type" "ishift")
11535 (set_attr "mode" "SI")])
11536
11537 ;; This pattern can't accept a variable shift count, since shifts by
11538 ;; zero don't affect the flags. We assume that shifts by constant
11539 ;; zero are optimized away.
11540 (define_insn "*ashrsi3_one_bit_cmp"
11541 [(set (reg 17)
11542 (compare
11543 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11544 (match_operand:QI 2 "const1_operand" ""))
11545 (const_int 0)))
11546 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11547 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11548 "ix86_match_ccmode (insn, CCGOCmode)
11549 && (TARGET_SHIFT1 || optimize_size)
11550 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11551 "sar{l}\t%0"
11552 [(set_attr "type" "ishift")
11553 (set (attr "length")
11554 (if_then_else (match_operand:SI 0 "register_operand" "")
11555 (const_string "2")
11556 (const_string "*")))])
11557
11558 (define_insn "*ashrsi3_one_bit_cmp_zext"
11559 [(set (reg 17)
11560 (compare
11561 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11562 (match_operand:QI 2 "const1_operand" ""))
11563 (const_int 0)))
11564 (set (match_operand:DI 0 "register_operand" "=r")
11565 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11566 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11567 && (TARGET_SHIFT1 || optimize_size)
11568 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569 "sar{l}\t%k0"
11570 [(set_attr "type" "ishift")
11571 (set_attr "length" "2")])
11572
11573 ;; This pattern can't accept a variable shift count, since shifts by
11574 ;; zero don't affect the flags. We assume that shifts by constant
11575 ;; zero are optimized away.
11576 (define_insn "*ashrsi3_cmp"
11577 [(set (reg 17)
11578 (compare
11579 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11580 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11581 (const_int 0)))
11582 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11583 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11584 "ix86_match_ccmode (insn, CCGOCmode)
11585 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11586 "sar{l}\t{%2, %0|%0, %2}"
11587 [(set_attr "type" "ishift")
11588 (set_attr "mode" "SI")])
11589
11590 (define_insn "*ashrsi3_cmp_zext"
11591 [(set (reg 17)
11592 (compare
11593 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11594 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11595 (const_int 0)))
11596 (set (match_operand:DI 0 "register_operand" "=r")
11597 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11598 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11599 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11600 "sar{l}\t{%2, %k0|%k0, %2}"
11601 [(set_attr "type" "ishift")
11602 (set_attr "mode" "SI")])
11603
11604 (define_expand "ashrhi3"
11605 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11606 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11607 (match_operand:QI 2 "nonmemory_operand" "")))
11608 (clobber (reg:CC 17))]
11609 "TARGET_HIMODE_MATH"
11610 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11611
11612 (define_insn "*ashrhi3_1_one_bit"
11613 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11614 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11615 (match_operand:QI 2 "const1_operand" "")))
11616 (clobber (reg:CC 17))]
11617 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11618 && (TARGET_SHIFT1 || optimize_size)"
11619 "sar{w}\t%0"
11620 [(set_attr "type" "ishift")
11621 (set (attr "length")
11622 (if_then_else (match_operand 0 "register_operand" "")
11623 (const_string "2")
11624 (const_string "*")))])
11625
11626 (define_insn "*ashrhi3_1"
11627 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11628 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11629 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11630 (clobber (reg:CC 17))]
11631 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11632 "@
11633 sar{w}\t{%2, %0|%0, %2}
11634 sar{w}\t{%b2, %0|%0, %b2}"
11635 [(set_attr "type" "ishift")
11636 (set_attr "mode" "HI")])
11637
11638 ;; This pattern can't accept a variable shift count, since shifts by
11639 ;; zero don't affect the flags. We assume that shifts by constant
11640 ;; zero are optimized away.
11641 (define_insn "*ashrhi3_one_bit_cmp"
11642 [(set (reg 17)
11643 (compare
11644 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11645 (match_operand:QI 2 "const1_operand" ""))
11646 (const_int 0)))
11647 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11648 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11649 "ix86_match_ccmode (insn, CCGOCmode)
11650 && (TARGET_SHIFT1 || optimize_size)
11651 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11652 "sar{w}\t%0"
11653 [(set_attr "type" "ishift")
11654 (set (attr "length")
11655 (if_then_else (match_operand 0 "register_operand" "")
11656 (const_string "2")
11657 (const_string "*")))])
11658
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags. We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*ashrhi3_cmp"
11663 [(set (reg 17)
11664 (compare
11665 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11667 (const_int 0)))
11668 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11669 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11670 "ix86_match_ccmode (insn, CCGOCmode)
11671 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11672 "sar{w}\t{%2, %0|%0, %2}"
11673 [(set_attr "type" "ishift")
11674 (set_attr "mode" "HI")])
11675
11676 (define_expand "ashrqi3"
11677 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11678 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11679 (match_operand:QI 2 "nonmemory_operand" "")))
11680 (clobber (reg:CC 17))]
11681 "TARGET_QIMODE_MATH"
11682 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11683
11684 (define_insn "*ashrqi3_1_one_bit"
11685 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11686 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11687 (match_operand:QI 2 "const1_operand" "")))
11688 (clobber (reg:CC 17))]
11689 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11690 && (TARGET_SHIFT1 || optimize_size)"
11691 "sar{b}\t%0"
11692 [(set_attr "type" "ishift")
11693 (set (attr "length")
11694 (if_then_else (match_operand 0 "register_operand" "")
11695 (const_string "2")
11696 (const_string "*")))])
11697
11698 (define_insn "*ashrqi3_1_one_bit_slp"
11699 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11700 (ashiftrt:QI (match_dup 0)
11701 (match_operand:QI 1 "const1_operand" "")))
11702 (clobber (reg:CC 17))]
11703 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11704 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11705 && (TARGET_SHIFT1 || optimize_size)"
11706 "sar{b}\t%0"
11707 [(set_attr "type" "ishift1")
11708 (set (attr "length")
11709 (if_then_else (match_operand 0 "register_operand" "")
11710 (const_string "2")
11711 (const_string "*")))])
11712
11713 (define_insn "*ashrqi3_1"
11714 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11715 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11716 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11717 (clobber (reg:CC 17))]
11718 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11719 "@
11720 sar{b}\t{%2, %0|%0, %2}
11721 sar{b}\t{%b2, %0|%0, %b2}"
11722 [(set_attr "type" "ishift")
11723 (set_attr "mode" "QI")])
11724
11725 (define_insn "*ashrqi3_1_slp"
11726 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11727 (ashiftrt:QI (match_dup 0)
11728 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11729 (clobber (reg:CC 17))]
11730 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11731 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11732 "@
11733 sar{b}\t{%1, %0|%0, %1}
11734 sar{b}\t{%b1, %0|%0, %b1}"
11735 [(set_attr "type" "ishift1")
11736 (set_attr "mode" "QI")])
11737
11738 ;; This pattern can't accept a variable shift count, since shifts by
11739 ;; zero don't affect the flags. We assume that shifts by constant
11740 ;; zero are optimized away.
11741 (define_insn "*ashrqi3_one_bit_cmp"
11742 [(set (reg 17)
11743 (compare
11744 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11745 (match_operand:QI 2 "const1_operand" "I"))
11746 (const_int 0)))
11747 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11748 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11749 "ix86_match_ccmode (insn, CCGOCmode)
11750 && (TARGET_SHIFT1 || optimize_size)
11751 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11752 "sar{b}\t%0"
11753 [(set_attr "type" "ishift")
11754 (set (attr "length")
11755 (if_then_else (match_operand 0 "register_operand" "")
11756 (const_string "2")
11757 (const_string "*")))])
11758
11759 ;; This pattern can't accept a variable shift count, since shifts by
11760 ;; zero don't affect the flags. We assume that shifts by constant
11761 ;; zero are optimized away.
11762 (define_insn "*ashrqi3_cmp"
11763 [(set (reg 17)
11764 (compare
11765 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11767 (const_int 0)))
11768 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11769 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11770 "ix86_match_ccmode (insn, CCGOCmode)
11771 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11772 "sar{b}\t{%2, %0|%0, %2}"
11773 [(set_attr "type" "ishift")
11774 (set_attr "mode" "QI")])
11775 \f
11776 ;; Logical shift instructions
11777
11778 ;; See comment above `ashldi3' about how this works.
11779
11780 (define_expand "lshrdi3"
11781 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11782 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11783 (match_operand:QI 2 "nonmemory_operand" "")))
11784 (clobber (reg:CC 17))])]
11785 ""
11786 {
11787 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11788 {
11789 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11790 DONE;
11791 }
11792 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11793 DONE;
11794 })
11795
11796 (define_insn "*lshrdi3_1_one_bit_rex64"
11797 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11798 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11799 (match_operand:QI 2 "const1_operand" "")))
11800 (clobber (reg:CC 17))]
11801 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11802 && (TARGET_SHIFT1 || optimize_size)"
11803 "shr{q}\t%0"
11804 [(set_attr "type" "ishift")
11805 (set (attr "length")
11806 (if_then_else (match_operand:DI 0 "register_operand" "")
11807 (const_string "2")
11808 (const_string "*")))])
11809
11810 (define_insn "*lshrdi3_1_rex64"
11811 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11812 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11813 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11814 (clobber (reg:CC 17))]
11815 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11816 "@
11817 shr{q}\t{%2, %0|%0, %2}
11818 shr{q}\t{%b2, %0|%0, %b2}"
11819 [(set_attr "type" "ishift")
11820 (set_attr "mode" "DI")])
11821
11822 ;; This pattern can't accept a variable shift count, since shifts by
11823 ;; zero don't affect the flags. We assume that shifts by constant
11824 ;; zero are optimized away.
11825 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11826 [(set (reg 17)
11827 (compare
11828 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11829 (match_operand:QI 2 "const1_operand" ""))
11830 (const_int 0)))
11831 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11832 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11833 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11834 && (TARGET_SHIFT1 || optimize_size)
11835 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11836 "shr{q}\t%0"
11837 [(set_attr "type" "ishift")
11838 (set (attr "length")
11839 (if_then_else (match_operand:DI 0 "register_operand" "")
11840 (const_string "2")
11841 (const_string "*")))])
11842
11843 ;; This pattern can't accept a variable shift count, since shifts by
11844 ;; zero don't affect the flags. We assume that shifts by constant
11845 ;; zero are optimized away.
11846 (define_insn "*lshrdi3_cmp_rex64"
11847 [(set (reg 17)
11848 (compare
11849 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11850 (match_operand:QI 2 "const_int_operand" "e"))
11851 (const_int 0)))
11852 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11853 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11854 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11855 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11856 "shr{q}\t{%2, %0|%0, %2}"
11857 [(set_attr "type" "ishift")
11858 (set_attr "mode" "DI")])
11859
11860 (define_insn "lshrdi3_1"
11861 [(set (match_operand:DI 0 "register_operand" "=r")
11862 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11863 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11864 (clobber (match_scratch:SI 3 "=&r"))
11865 (clobber (reg:CC 17))]
11866 "!TARGET_64BIT && TARGET_CMOVE"
11867 "#"
11868 [(set_attr "type" "multi")])
11869
11870 (define_insn "*lshrdi3_2"
11871 [(set (match_operand:DI 0 "register_operand" "=r")
11872 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11873 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11874 (clobber (reg:CC 17))]
11875 "!TARGET_64BIT"
11876 "#"
11877 [(set_attr "type" "multi")])
11878
11879 (define_split
11880 [(set (match_operand:DI 0 "register_operand" "")
11881 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11882 (match_operand:QI 2 "nonmemory_operand" "")))
11883 (clobber (match_scratch:SI 3 ""))
11884 (clobber (reg:CC 17))]
11885 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11886 [(const_int 0)]
11887 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11888
11889 (define_split
11890 [(set (match_operand:DI 0 "register_operand" "")
11891 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11892 (match_operand:QI 2 "nonmemory_operand" "")))
11893 (clobber (reg:CC 17))]
11894 "!TARGET_64BIT && reload_completed"
11895 [(const_int 0)]
11896 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11897
11898 (define_expand "lshrsi3"
11899 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11900 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11901 (match_operand:QI 2 "nonmemory_operand" "")))
11902 (clobber (reg:CC 17))]
11903 ""
11904 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11905
11906 (define_insn "*lshrsi3_1_one_bit"
11907 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11908 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11909 (match_operand:QI 2 "const1_operand" "")))
11910 (clobber (reg:CC 17))]
11911 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11912 && (TARGET_SHIFT1 || optimize_size)"
11913 "shr{l}\t%0"
11914 [(set_attr "type" "ishift")
11915 (set (attr "length")
11916 (if_then_else (match_operand:SI 0 "register_operand" "")
11917 (const_string "2")
11918 (const_string "*")))])
11919
11920 (define_insn "*lshrsi3_1_one_bit_zext"
11921 [(set (match_operand:DI 0 "register_operand" "=r")
11922 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11923 (match_operand:QI 2 "const1_operand" "")))
11924 (clobber (reg:CC 17))]
11925 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11926 && (TARGET_SHIFT1 || optimize_size)"
11927 "shr{l}\t%k0"
11928 [(set_attr "type" "ishift")
11929 (set_attr "length" "2")])
11930
11931 (define_insn "*lshrsi3_1"
11932 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11933 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11934 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11935 (clobber (reg:CC 17))]
11936 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11937 "@
11938 shr{l}\t{%2, %0|%0, %2}
11939 shr{l}\t{%b2, %0|%0, %b2}"
11940 [(set_attr "type" "ishift")
11941 (set_attr "mode" "SI")])
11942
11943 (define_insn "*lshrsi3_1_zext"
11944 [(set (match_operand:DI 0 "register_operand" "=r,r")
11945 (zero_extend:DI
11946 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11947 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11948 (clobber (reg:CC 17))]
11949 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11950 "@
11951 shr{l}\t{%2, %k0|%k0, %2}
11952 shr{l}\t{%b2, %k0|%k0, %b2}"
11953 [(set_attr "type" "ishift")
11954 (set_attr "mode" "SI")])
11955
11956 ;; This pattern can't accept a variable shift count, since shifts by
11957 ;; zero don't affect the flags. We assume that shifts by constant
11958 ;; zero are optimized away.
11959 (define_insn "*lshrsi3_one_bit_cmp"
11960 [(set (reg 17)
11961 (compare
11962 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11963 (match_operand:QI 2 "const1_operand" ""))
11964 (const_int 0)))
11965 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11966 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11967 "ix86_match_ccmode (insn, CCGOCmode)
11968 && (TARGET_SHIFT1 || optimize_size)
11969 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11970 "shr{l}\t%0"
11971 [(set_attr "type" "ishift")
11972 (set (attr "length")
11973 (if_then_else (match_operand:SI 0 "register_operand" "")
11974 (const_string "2")
11975 (const_string "*")))])
11976
11977 (define_insn "*lshrsi3_cmp_one_bit_zext"
11978 [(set (reg 17)
11979 (compare
11980 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11981 (match_operand:QI 2 "const1_operand" ""))
11982 (const_int 0)))
11983 (set (match_operand:DI 0 "register_operand" "=r")
11984 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11985 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11986 && (TARGET_SHIFT1 || optimize_size)
11987 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11988 "shr{l}\t%k0"
11989 [(set_attr "type" "ishift")
11990 (set_attr "length" "2")])
11991
11992 ;; This pattern can't accept a variable shift count, since shifts by
11993 ;; zero don't affect the flags. We assume that shifts by constant
11994 ;; zero are optimized away.
11995 (define_insn "*lshrsi3_cmp"
11996 [(set (reg 17)
11997 (compare
11998 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11999 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12000 (const_int 0)))
12001 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12002 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12003 "ix86_match_ccmode (insn, CCGOCmode)
12004 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12005 "shr{l}\t{%2, %0|%0, %2}"
12006 [(set_attr "type" "ishift")
12007 (set_attr "mode" "SI")])
12008
12009 (define_insn "*lshrsi3_cmp_zext"
12010 [(set (reg 17)
12011 (compare
12012 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12013 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12014 (const_int 0)))
12015 (set (match_operand:DI 0 "register_operand" "=r")
12016 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12017 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12018 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12019 "shr{l}\t{%2, %k0|%k0, %2}"
12020 [(set_attr "type" "ishift")
12021 (set_attr "mode" "SI")])
12022
12023 (define_expand "lshrhi3"
12024 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12025 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12026 (match_operand:QI 2 "nonmemory_operand" "")))
12027 (clobber (reg:CC 17))]
12028 "TARGET_HIMODE_MATH"
12029 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12030
12031 (define_insn "*lshrhi3_1_one_bit"
12032 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12033 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12034 (match_operand:QI 2 "const1_operand" "")))
12035 (clobber (reg:CC 17))]
12036 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12037 && (TARGET_SHIFT1 || optimize_size)"
12038 "shr{w}\t%0"
12039 [(set_attr "type" "ishift")
12040 (set (attr "length")
12041 (if_then_else (match_operand 0 "register_operand" "")
12042 (const_string "2")
12043 (const_string "*")))])
12044
12045 (define_insn "*lshrhi3_1"
12046 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12047 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12048 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12049 (clobber (reg:CC 17))]
12050 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12051 "@
12052 shr{w}\t{%2, %0|%0, %2}
12053 shr{w}\t{%b2, %0|%0, %b2}"
12054 [(set_attr "type" "ishift")
12055 (set_attr "mode" "HI")])
12056
12057 ;; This pattern can't accept a variable shift count, since shifts by
12058 ;; zero don't affect the flags. We assume that shifts by constant
12059 ;; zero are optimized away.
12060 (define_insn "*lshrhi3_one_bit_cmp"
12061 [(set (reg 17)
12062 (compare
12063 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12064 (match_operand:QI 2 "const1_operand" ""))
12065 (const_int 0)))
12066 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12067 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12068 "ix86_match_ccmode (insn, CCGOCmode)
12069 && (TARGET_SHIFT1 || optimize_size)
12070 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12071 "shr{w}\t%0"
12072 [(set_attr "type" "ishift")
12073 (set (attr "length")
12074 (if_then_else (match_operand:SI 0 "register_operand" "")
12075 (const_string "2")
12076 (const_string "*")))])
12077
12078 ;; This pattern can't accept a variable shift count, since shifts by
12079 ;; zero don't affect the flags. We assume that shifts by constant
12080 ;; zero are optimized away.
12081 (define_insn "*lshrhi3_cmp"
12082 [(set (reg 17)
12083 (compare
12084 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12085 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12086 (const_int 0)))
12087 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12088 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12089 "ix86_match_ccmode (insn, CCGOCmode)
12090 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12091 "shr{w}\t{%2, %0|%0, %2}"
12092 [(set_attr "type" "ishift")
12093 (set_attr "mode" "HI")])
12094
12095 (define_expand "lshrqi3"
12096 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12097 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12098 (match_operand:QI 2 "nonmemory_operand" "")))
12099 (clobber (reg:CC 17))]
12100 "TARGET_QIMODE_MATH"
12101 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12102
12103 (define_insn "*lshrqi3_1_one_bit"
12104 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12105 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12106 (match_operand:QI 2 "const1_operand" "")))
12107 (clobber (reg:CC 17))]
12108 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12109 && (TARGET_SHIFT1 || optimize_size)"
12110 "shr{b}\t%0"
12111 [(set_attr "type" "ishift")
12112 (set (attr "length")
12113 (if_then_else (match_operand 0 "register_operand" "")
12114 (const_string "2")
12115 (const_string "*")))])
12116
12117 (define_insn "*lshrqi3_1_one_bit_slp"
12118 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12119 (lshiftrt:QI (match_dup 0)
12120 (match_operand:QI 1 "const1_operand" "")))
12121 (clobber (reg:CC 17))]
12122 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12123 && (TARGET_SHIFT1 || optimize_size)"
12124 "shr{b}\t%0"
12125 [(set_attr "type" "ishift1")
12126 (set (attr "length")
12127 (if_then_else (match_operand 0 "register_operand" "")
12128 (const_string "2")
12129 (const_string "*")))])
12130
12131 (define_insn "*lshrqi3_1"
12132 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12133 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12134 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12135 (clobber (reg:CC 17))]
12136 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12137 "@
12138 shr{b}\t{%2, %0|%0, %2}
12139 shr{b}\t{%b2, %0|%0, %b2}"
12140 [(set_attr "type" "ishift")
12141 (set_attr "mode" "QI")])
12142
12143 (define_insn "*lshrqi3_1_slp"
12144 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12145 (lshiftrt:QI (match_dup 0)
12146 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12147 (clobber (reg:CC 17))]
12148 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12149 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12150 "@
12151 shr{b}\t{%1, %0|%0, %1}
12152 shr{b}\t{%b1, %0|%0, %b1}"
12153 [(set_attr "type" "ishift1")
12154 (set_attr "mode" "QI")])
12155
12156 ;; This pattern can't accept a variable shift count, since shifts by
12157 ;; zero don't affect the flags. We assume that shifts by constant
12158 ;; zero are optimized away.
12159 (define_insn "*lshrqi2_one_bit_cmp"
12160 [(set (reg 17)
12161 (compare
12162 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12163 (match_operand:QI 2 "const1_operand" ""))
12164 (const_int 0)))
12165 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12166 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12167 "ix86_match_ccmode (insn, CCGOCmode)
12168 && (TARGET_SHIFT1 || optimize_size)
12169 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12170 "shr{b}\t%0"
12171 [(set_attr "type" "ishift")
12172 (set (attr "length")
12173 (if_then_else (match_operand:SI 0 "register_operand" "")
12174 (const_string "2")
12175 (const_string "*")))])
12176
12177 ;; This pattern can't accept a variable shift count, since shifts by
12178 ;; zero don't affect the flags. We assume that shifts by constant
12179 ;; zero are optimized away.
12180 (define_insn "*lshrqi2_cmp"
12181 [(set (reg 17)
12182 (compare
12183 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12184 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12185 (const_int 0)))
12186 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12187 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12188 "ix86_match_ccmode (insn, CCGOCmode)
12189 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12190 "shr{b}\t{%2, %0|%0, %2}"
12191 [(set_attr "type" "ishift")
12192 (set_attr "mode" "QI")])
12193 \f
12194 ;; Rotate instructions
12195
12196 (define_expand "rotldi3"
12197 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12198 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12199 (match_operand:QI 2 "nonmemory_operand" "")))
12200 (clobber (reg:CC 17))]
12201 "TARGET_64BIT"
12202 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12203
12204 (define_insn "*rotlsi3_1_one_bit_rex64"
12205 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12206 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const1_operand" "")))
12208 (clobber (reg:CC 17))]
12209 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12210 && (TARGET_SHIFT1 || optimize_size)"
12211 "rol{q}\t%0"
12212 [(set_attr "type" "rotate")
12213 (set (attr "length")
12214 (if_then_else (match_operand:DI 0 "register_operand" "")
12215 (const_string "2")
12216 (const_string "*")))])
12217
12218 (define_insn "*rotldi3_1_rex64"
12219 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12220 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12221 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12222 (clobber (reg:CC 17))]
12223 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12224 "@
12225 rol{q}\t{%2, %0|%0, %2}
12226 rol{q}\t{%b2, %0|%0, %b2}"
12227 [(set_attr "type" "rotate")
12228 (set_attr "mode" "DI")])
12229
12230 (define_expand "rotlsi3"
12231 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12232 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12233 (match_operand:QI 2 "nonmemory_operand" "")))
12234 (clobber (reg:CC 17))]
12235 ""
12236 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12237
12238 (define_insn "*rotlsi3_1_one_bit"
12239 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12240 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12241 (match_operand:QI 2 "const1_operand" "")))
12242 (clobber (reg:CC 17))]
12243 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12244 && (TARGET_SHIFT1 || optimize_size)"
12245 "rol{l}\t%0"
12246 [(set_attr "type" "rotate")
12247 (set (attr "length")
12248 (if_then_else (match_operand:SI 0 "register_operand" "")
12249 (const_string "2")
12250 (const_string "*")))])
12251
12252 (define_insn "*rotlsi3_1_one_bit_zext"
12253 [(set (match_operand:DI 0 "register_operand" "=r")
12254 (zero_extend:DI
12255 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12256 (match_operand:QI 2 "const1_operand" ""))))
12257 (clobber (reg:CC 17))]
12258 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12259 && (TARGET_SHIFT1 || optimize_size)"
12260 "rol{l}\t%k0"
12261 [(set_attr "type" "rotate")
12262 (set_attr "length" "2")])
12263
12264 (define_insn "*rotlsi3_1"
12265 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12266 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12267 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12268 (clobber (reg:CC 17))]
12269 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12270 "@
12271 rol{l}\t{%2, %0|%0, %2}
12272 rol{l}\t{%b2, %0|%0, %b2}"
12273 [(set_attr "type" "rotate")
12274 (set_attr "mode" "SI")])
12275
12276 (define_insn "*rotlsi3_1_zext"
12277 [(set (match_operand:DI 0 "register_operand" "=r,r")
12278 (zero_extend:DI
12279 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12280 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12281 (clobber (reg:CC 17))]
12282 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12283 "@
12284 rol{l}\t{%2, %k0|%k0, %2}
12285 rol{l}\t{%b2, %k0|%k0, %b2}"
12286 [(set_attr "type" "rotate")
12287 (set_attr "mode" "SI")])
12288
12289 (define_expand "rotlhi3"
12290 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12291 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12292 (match_operand:QI 2 "nonmemory_operand" "")))
12293 (clobber (reg:CC 17))]
12294 "TARGET_HIMODE_MATH"
12295 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12296
12297 (define_insn "*rotlhi3_1_one_bit"
12298 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12299 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12300 (match_operand:QI 2 "const1_operand" "")))
12301 (clobber (reg:CC 17))]
12302 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12303 && (TARGET_SHIFT1 || optimize_size)"
12304 "rol{w}\t%0"
12305 [(set_attr "type" "rotate")
12306 (set (attr "length")
12307 (if_then_else (match_operand 0 "register_operand" "")
12308 (const_string "2")
12309 (const_string "*")))])
12310
12311 (define_insn "*rotlhi3_1"
12312 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12313 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12314 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12315 (clobber (reg:CC 17))]
12316 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12317 "@
12318 rol{w}\t{%2, %0|%0, %2}
12319 rol{w}\t{%b2, %0|%0, %b2}"
12320 [(set_attr "type" "rotate")
12321 (set_attr "mode" "HI")])
12322
12323 (define_expand "rotlqi3"
12324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12325 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12326 (match_operand:QI 2 "nonmemory_operand" "")))
12327 (clobber (reg:CC 17))]
12328 "TARGET_QIMODE_MATH"
12329 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12330
12331 (define_insn "*rotlqi3_1_one_bit_slp"
12332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12333 (rotate:QI (match_dup 0)
12334 (match_operand:QI 1 "const1_operand" "")))
12335 (clobber (reg:CC 17))]
12336 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12337 && (TARGET_SHIFT1 || optimize_size)"
12338 "rol{b}\t%0"
12339 [(set_attr "type" "rotate1")
12340 (set (attr "length")
12341 (if_then_else (match_operand 0 "register_operand" "")
12342 (const_string "2")
12343 (const_string "*")))])
12344
12345 (define_insn "*rotlqi3_1_one_bit"
12346 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12347 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12348 (match_operand:QI 2 "const1_operand" "")))
12349 (clobber (reg:CC 17))]
12350 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12351 && (TARGET_SHIFT1 || optimize_size)"
12352 "rol{b}\t%0"
12353 [(set_attr "type" "rotate")
12354 (set (attr "length")
12355 (if_then_else (match_operand 0 "register_operand" "")
12356 (const_string "2")
12357 (const_string "*")))])
12358
12359 (define_insn "*rotlqi3_1_slp"
12360 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12361 (rotate:QI (match_dup 0)
12362 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12363 (clobber (reg:CC 17))]
12364 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12365 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12366 "@
12367 rol{b}\t{%1, %0|%0, %1}
12368 rol{b}\t{%b1, %0|%0, %b1}"
12369 [(set_attr "type" "rotate1")
12370 (set_attr "mode" "QI")])
12371
12372 (define_insn "*rotlqi3_1"
12373 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12374 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12375 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12376 (clobber (reg:CC 17))]
12377 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12378 "@
12379 rol{b}\t{%2, %0|%0, %2}
12380 rol{b}\t{%b2, %0|%0, %b2}"
12381 [(set_attr "type" "rotate")
12382 (set_attr "mode" "QI")])
12383
12384 (define_expand "rotrdi3"
12385 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12386 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12387 (match_operand:QI 2 "nonmemory_operand" "")))
12388 (clobber (reg:CC 17))]
12389 "TARGET_64BIT"
12390 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12391
12392 (define_insn "*rotrdi3_1_one_bit_rex64"
12393 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12394 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12395 (match_operand:QI 2 "const1_operand" "")))
12396 (clobber (reg:CC 17))]
12397 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12398 && (TARGET_SHIFT1 || optimize_size)"
12399 "ror{q}\t%0"
12400 [(set_attr "type" "rotate")
12401 (set (attr "length")
12402 (if_then_else (match_operand:DI 0 "register_operand" "")
12403 (const_string "2")
12404 (const_string "*")))])
12405
12406 (define_insn "*rotrdi3_1_rex64"
12407 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12408 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12409 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12410 (clobber (reg:CC 17))]
12411 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12412 "@
12413 ror{q}\t{%2, %0|%0, %2}
12414 ror{q}\t{%b2, %0|%0, %b2}"
12415 [(set_attr "type" "rotate")
12416 (set_attr "mode" "DI")])
12417
12418 (define_expand "rotrsi3"
12419 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12420 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12421 (match_operand:QI 2 "nonmemory_operand" "")))
12422 (clobber (reg:CC 17))]
12423 ""
12424 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12425
12426 (define_insn "*rotrsi3_1_one_bit"
12427 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12428 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12429 (match_operand:QI 2 "const1_operand" "")))
12430 (clobber (reg:CC 17))]
12431 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12432 && (TARGET_SHIFT1 || optimize_size)"
12433 "ror{l}\t%0"
12434 [(set_attr "type" "rotate")
12435 (set (attr "length")
12436 (if_then_else (match_operand:SI 0 "register_operand" "")
12437 (const_string "2")
12438 (const_string "*")))])
12439
12440 (define_insn "*rotrsi3_1_one_bit_zext"
12441 [(set (match_operand:DI 0 "register_operand" "=r")
12442 (zero_extend:DI
12443 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12444 (match_operand:QI 2 "const1_operand" ""))))
12445 (clobber (reg:CC 17))]
12446 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12447 && (TARGET_SHIFT1 || optimize_size)"
12448 "ror{l}\t%k0"
12449 [(set_attr "type" "rotate")
12450 (set (attr "length")
12451 (if_then_else (match_operand:SI 0 "register_operand" "")
12452 (const_string "2")
12453 (const_string "*")))])
12454
12455 (define_insn "*rotrsi3_1"
12456 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12457 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12458 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12459 (clobber (reg:CC 17))]
12460 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12461 "@
12462 ror{l}\t{%2, %0|%0, %2}
12463 ror{l}\t{%b2, %0|%0, %b2}"
12464 [(set_attr "type" "rotate")
12465 (set_attr "mode" "SI")])
12466
12467 (define_insn "*rotrsi3_1_zext"
12468 [(set (match_operand:DI 0 "register_operand" "=r,r")
12469 (zero_extend:DI
12470 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12471 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12472 (clobber (reg:CC 17))]
12473 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12474 "@
12475 ror{l}\t{%2, %k0|%k0, %2}
12476 ror{l}\t{%b2, %k0|%k0, %b2}"
12477 [(set_attr "type" "rotate")
12478 (set_attr "mode" "SI")])
12479
12480 (define_expand "rotrhi3"
12481 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12482 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12483 (match_operand:QI 2 "nonmemory_operand" "")))
12484 (clobber (reg:CC 17))]
12485 "TARGET_HIMODE_MATH"
12486 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12487
12488 (define_insn "*rotrhi3_one_bit"
12489 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12490 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12491 (match_operand:QI 2 "const1_operand" "")))
12492 (clobber (reg:CC 17))]
12493 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12494 && (TARGET_SHIFT1 || optimize_size)"
12495 "ror{w}\t%0"
12496 [(set_attr "type" "rotate")
12497 (set (attr "length")
12498 (if_then_else (match_operand 0 "register_operand" "")
12499 (const_string "2")
12500 (const_string "*")))])
12501
12502 (define_insn "*rotrhi3"
12503 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12504 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12505 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12506 (clobber (reg:CC 17))]
12507 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12508 "@
12509 ror{w}\t{%2, %0|%0, %2}
12510 ror{w}\t{%b2, %0|%0, %b2}"
12511 [(set_attr "type" "rotate")
12512 (set_attr "mode" "HI")])
12513
12514 (define_expand "rotrqi3"
12515 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12516 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12517 (match_operand:QI 2 "nonmemory_operand" "")))
12518 (clobber (reg:CC 17))]
12519 "TARGET_QIMODE_MATH"
12520 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12521
12522 (define_insn "*rotrqi3_1_one_bit"
12523 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12524 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12525 (match_operand:QI 2 "const1_operand" "")))
12526 (clobber (reg:CC 17))]
12527 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12528 && (TARGET_SHIFT1 || optimize_size)"
12529 "ror{b}\t%0"
12530 [(set_attr "type" "rotate")
12531 (set (attr "length")
12532 (if_then_else (match_operand 0 "register_operand" "")
12533 (const_string "2")
12534 (const_string "*")))])
12535
12536 (define_insn "*rotrqi3_1_one_bit_slp"
12537 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12538 (rotatert:QI (match_dup 0)
12539 (match_operand:QI 1 "const1_operand" "")))
12540 (clobber (reg:CC 17))]
12541 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12542 && (TARGET_SHIFT1 || optimize_size)"
12543 "ror{b}\t%0"
12544 [(set_attr "type" "rotate1")
12545 (set (attr "length")
12546 (if_then_else (match_operand 0 "register_operand" "")
12547 (const_string "2")
12548 (const_string "*")))])
12549
12550 (define_insn "*rotrqi3_1"
12551 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12552 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12553 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12554 (clobber (reg:CC 17))]
12555 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12556 "@
12557 ror{b}\t{%2, %0|%0, %2}
12558 ror{b}\t{%b2, %0|%0, %b2}"
12559 [(set_attr "type" "rotate")
12560 (set_attr "mode" "QI")])
12561
12562 (define_insn "*rotrqi3_1_slp"
12563 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12564 (rotatert:QI (match_dup 0)
12565 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12566 (clobber (reg:CC 17))]
12567 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12568 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12569 "@
12570 ror{b}\t{%1, %0|%0, %1}
12571 ror{b}\t{%b1, %0|%0, %b1}"
12572 [(set_attr "type" "rotate1")
12573 (set_attr "mode" "QI")])
12574 \f
12575 ;; Bit set / bit test instructions
12576
12577 (define_expand "extv"
12578 [(set (match_operand:SI 0 "register_operand" "")
12579 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12580 (match_operand:SI 2 "immediate_operand" "")
12581 (match_operand:SI 3 "immediate_operand" "")))]
12582 ""
12583 {
12584 /* Handle extractions from %ah et al. */
12585 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12586 FAIL;
12587
12588 /* From mips.md: extract_bit_field doesn't verify that our source
12589 matches the predicate, so check it again here. */
12590 if (! register_operand (operands[1], VOIDmode))
12591 FAIL;
12592 })
12593
12594 (define_expand "extzv"
12595 [(set (match_operand:SI 0 "register_operand" "")
12596 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12597 (match_operand:SI 2 "immediate_operand" "")
12598 (match_operand:SI 3 "immediate_operand" "")))]
12599 ""
12600 {
12601 /* Handle extractions from %ah et al. */
12602 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12603 FAIL;
12604
12605 /* From mips.md: extract_bit_field doesn't verify that our source
12606 matches the predicate, so check it again here. */
12607 if (! register_operand (operands[1], VOIDmode))
12608 FAIL;
12609 })
12610
12611 (define_expand "insv"
12612 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12613 (match_operand:SI 1 "immediate_operand" "")
12614 (match_operand:SI 2 "immediate_operand" ""))
12615 (match_operand:SI 3 "register_operand" ""))]
12616 ""
12617 {
12618 /* Handle extractions from %ah et al. */
12619 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12620 FAIL;
12621
12622 /* From mips.md: insert_bit_field doesn't verify that our source
12623 matches the predicate, so check it again here. */
12624 if (! register_operand (operands[0], VOIDmode))
12625 FAIL;
12626 })
12627
12628 ;; %%% bts, btr, btc, bt.
12629 \f
12630 ;; Store-flag instructions.
12631
12632 ;; For all sCOND expanders, also expand the compare or test insn that
12633 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12634
12635 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12636 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12637 ;; way, which can later delete the movzx if only QImode is needed.
12638
12639 (define_expand "seq"
12640 [(set (match_operand:QI 0 "register_operand" "")
12641 (eq:QI (reg:CC 17) (const_int 0)))]
12642 ""
12643 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12644
12645 (define_expand "sne"
12646 [(set (match_operand:QI 0 "register_operand" "")
12647 (ne:QI (reg:CC 17) (const_int 0)))]
12648 ""
12649 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12650
12651 (define_expand "sgt"
12652 [(set (match_operand:QI 0 "register_operand" "")
12653 (gt:QI (reg:CC 17) (const_int 0)))]
12654 ""
12655 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12656
12657 (define_expand "sgtu"
12658 [(set (match_operand:QI 0 "register_operand" "")
12659 (gtu:QI (reg:CC 17) (const_int 0)))]
12660 ""
12661 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12662
12663 (define_expand "slt"
12664 [(set (match_operand:QI 0 "register_operand" "")
12665 (lt:QI (reg:CC 17) (const_int 0)))]
12666 ""
12667 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12668
12669 (define_expand "sltu"
12670 [(set (match_operand:QI 0 "register_operand" "")
12671 (ltu:QI (reg:CC 17) (const_int 0)))]
12672 ""
12673 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12674
12675 (define_expand "sge"
12676 [(set (match_operand:QI 0 "register_operand" "")
12677 (ge:QI (reg:CC 17) (const_int 0)))]
12678 ""
12679 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12680
12681 (define_expand "sgeu"
12682 [(set (match_operand:QI 0 "register_operand" "")
12683 (geu:QI (reg:CC 17) (const_int 0)))]
12684 ""
12685 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12686
12687 (define_expand "sle"
12688 [(set (match_operand:QI 0 "register_operand" "")
12689 (le:QI (reg:CC 17) (const_int 0)))]
12690 ""
12691 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12692
12693 (define_expand "sleu"
12694 [(set (match_operand:QI 0 "register_operand" "")
12695 (leu:QI (reg:CC 17) (const_int 0)))]
12696 ""
12697 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12698
12699 (define_expand "sunordered"
12700 [(set (match_operand:QI 0 "register_operand" "")
12701 (unordered:QI (reg:CC 17) (const_int 0)))]
12702 "TARGET_80387 || TARGET_SSE"
12703 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12704
12705 (define_expand "sordered"
12706 [(set (match_operand:QI 0 "register_operand" "")
12707 (ordered:QI (reg:CC 17) (const_int 0)))]
12708 "TARGET_80387"
12709 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12710
12711 (define_expand "suneq"
12712 [(set (match_operand:QI 0 "register_operand" "")
12713 (uneq:QI (reg:CC 17) (const_int 0)))]
12714 "TARGET_80387 || TARGET_SSE"
12715 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12716
12717 (define_expand "sunge"
12718 [(set (match_operand:QI 0 "register_operand" "")
12719 (unge:QI (reg:CC 17) (const_int 0)))]
12720 "TARGET_80387 || TARGET_SSE"
12721 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12722
12723 (define_expand "sungt"
12724 [(set (match_operand:QI 0 "register_operand" "")
12725 (ungt:QI (reg:CC 17) (const_int 0)))]
12726 "TARGET_80387 || TARGET_SSE"
12727 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12728
12729 (define_expand "sunle"
12730 [(set (match_operand:QI 0 "register_operand" "")
12731 (unle:QI (reg:CC 17) (const_int 0)))]
12732 "TARGET_80387 || TARGET_SSE"
12733 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12734
12735 (define_expand "sunlt"
12736 [(set (match_operand:QI 0 "register_operand" "")
12737 (unlt:QI (reg:CC 17) (const_int 0)))]
12738 "TARGET_80387 || TARGET_SSE"
12739 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12740
12741 (define_expand "sltgt"
12742 [(set (match_operand:QI 0 "register_operand" "")
12743 (ltgt:QI (reg:CC 17) (const_int 0)))]
12744 "TARGET_80387 || TARGET_SSE"
12745 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12746
12747 (define_insn "*setcc_1"
12748 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12749 (match_operator:QI 1 "ix86_comparison_operator"
12750 [(reg 17) (const_int 0)]))]
12751 ""
12752 "set%C1\t%0"
12753 [(set_attr "type" "setcc")
12754 (set_attr "mode" "QI")])
12755
12756 (define_insn "setcc_2"
12757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12758 (match_operator:QI 1 "ix86_comparison_operator"
12759 [(reg 17) (const_int 0)]))]
12760 ""
12761 "set%C1\t%0"
12762 [(set_attr "type" "setcc")
12763 (set_attr "mode" "QI")])
12764
12765 ;; In general it is not safe to assume too much about CCmode registers,
12766 ;; so simplify-rtx stops when it sees a second one. Under certain
12767 ;; conditions this is safe on x86, so help combine not create
12768 ;;
12769 ;; seta %al
12770 ;; testb %al, %al
12771 ;; sete %al
12772
12773 (define_split
12774 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12775 (ne:QI (match_operator 1 "ix86_comparison_operator"
12776 [(reg 17) (const_int 0)])
12777 (const_int 0)))]
12778 ""
12779 [(set (match_dup 0) (match_dup 1))]
12780 {
12781 PUT_MODE (operands[1], QImode);
12782 })
12783
12784 (define_split
12785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12786 (ne:QI (match_operator 1 "ix86_comparison_operator"
12787 [(reg 17) (const_int 0)])
12788 (const_int 0)))]
12789 ""
12790 [(set (match_dup 0) (match_dup 1))]
12791 {
12792 PUT_MODE (operands[1], QImode);
12793 })
12794
12795 (define_split
12796 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12797 (eq:QI (match_operator 1 "ix86_comparison_operator"
12798 [(reg 17) (const_int 0)])
12799 (const_int 0)))]
12800 ""
12801 [(set (match_dup 0) (match_dup 1))]
12802 {
12803 rtx new_op1 = copy_rtx (operands[1]);
12804 operands[1] = new_op1;
12805 PUT_MODE (new_op1, QImode);
12806 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12807 GET_MODE (XEXP (new_op1, 0))));
12808
12809 /* Make sure that (a) the CCmode we have for the flags is strong
12810 enough for the reversed compare or (b) we have a valid FP compare. */
12811 if (! ix86_comparison_operator (new_op1, VOIDmode))
12812 FAIL;
12813 })
12814
12815 (define_split
12816 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12817 (eq:QI (match_operator 1 "ix86_comparison_operator"
12818 [(reg 17) (const_int 0)])
12819 (const_int 0)))]
12820 ""
12821 [(set (match_dup 0) (match_dup 1))]
12822 {
12823 rtx new_op1 = copy_rtx (operands[1]);
12824 operands[1] = new_op1;
12825 PUT_MODE (new_op1, QImode);
12826 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12827 GET_MODE (XEXP (new_op1, 0))));
12828
12829 /* Make sure that (a) the CCmode we have for the flags is strong
12830 enough for the reversed compare or (b) we have a valid FP compare. */
12831 if (! ix86_comparison_operator (new_op1, VOIDmode))
12832 FAIL;
12833 })
12834
12835 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12836 ;; subsequent logical operations are used to imitate conditional moves.
12837 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12838 ;; it directly. Further holding this value in pseudo register might bring
12839 ;; problem in implicit normalization in spill code.
12840 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12841 ;; instructions after reload by splitting the conditional move patterns.
12842
12843 (define_insn "*sse_setccsf"
12844 [(set (match_operand:SF 0 "register_operand" "=x")
12845 (match_operator:SF 1 "sse_comparison_operator"
12846 [(match_operand:SF 2 "register_operand" "0")
12847 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12848 "TARGET_SSE && reload_completed"
12849 "cmp%D1ss\t{%3, %0|%0, %3}"
12850 [(set_attr "type" "ssecmp")
12851 (set_attr "mode" "SF")])
12852
12853 (define_insn "*sse_setccdf"
12854 [(set (match_operand:DF 0 "register_operand" "=Y")
12855 (match_operator:DF 1 "sse_comparison_operator"
12856 [(match_operand:DF 2 "register_operand" "0")
12857 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12858 "TARGET_SSE2 && reload_completed"
12859 "cmp%D1sd\t{%3, %0|%0, %3}"
12860 [(set_attr "type" "ssecmp")
12861 (set_attr "mode" "DF")])
12862 \f
12863 ;; Basic conditional jump instructions.
12864 ;; We ignore the overflow flag for signed branch instructions.
12865
12866 ;; For all bCOND expanders, also expand the compare or test insn that
12867 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12868
12869 (define_expand "beq"
12870 [(set (pc)
12871 (if_then_else (match_dup 1)
12872 (label_ref (match_operand 0 "" ""))
12873 (pc)))]
12874 ""
12875 "ix86_expand_branch (EQ, operands[0]); DONE;")
12876
12877 (define_expand "bne"
12878 [(set (pc)
12879 (if_then_else (match_dup 1)
12880 (label_ref (match_operand 0 "" ""))
12881 (pc)))]
12882 ""
12883 "ix86_expand_branch (NE, operands[0]); DONE;")
12884
12885 (define_expand "bgt"
12886 [(set (pc)
12887 (if_then_else (match_dup 1)
12888 (label_ref (match_operand 0 "" ""))
12889 (pc)))]
12890 ""
12891 "ix86_expand_branch (GT, operands[0]); DONE;")
12892
12893 (define_expand "bgtu"
12894 [(set (pc)
12895 (if_then_else (match_dup 1)
12896 (label_ref (match_operand 0 "" ""))
12897 (pc)))]
12898 ""
12899 "ix86_expand_branch (GTU, operands[0]); DONE;")
12900
12901 (define_expand "blt"
12902 [(set (pc)
12903 (if_then_else (match_dup 1)
12904 (label_ref (match_operand 0 "" ""))
12905 (pc)))]
12906 ""
12907 "ix86_expand_branch (LT, operands[0]); DONE;")
12908
12909 (define_expand "bltu"
12910 [(set (pc)
12911 (if_then_else (match_dup 1)
12912 (label_ref (match_operand 0 "" ""))
12913 (pc)))]
12914 ""
12915 "ix86_expand_branch (LTU, operands[0]); DONE;")
12916
12917 (define_expand "bge"
12918 [(set (pc)
12919 (if_then_else (match_dup 1)
12920 (label_ref (match_operand 0 "" ""))
12921 (pc)))]
12922 ""
12923 "ix86_expand_branch (GE, operands[0]); DONE;")
12924
12925 (define_expand "bgeu"
12926 [(set (pc)
12927 (if_then_else (match_dup 1)
12928 (label_ref (match_operand 0 "" ""))
12929 (pc)))]
12930 ""
12931 "ix86_expand_branch (GEU, operands[0]); DONE;")
12932
12933 (define_expand "ble"
12934 [(set (pc)
12935 (if_then_else (match_dup 1)
12936 (label_ref (match_operand 0 "" ""))
12937 (pc)))]
12938 ""
12939 "ix86_expand_branch (LE, operands[0]); DONE;")
12940
12941 (define_expand "bleu"
12942 [(set (pc)
12943 (if_then_else (match_dup 1)
12944 (label_ref (match_operand 0 "" ""))
12945 (pc)))]
12946 ""
12947 "ix86_expand_branch (LEU, operands[0]); DONE;")
12948
12949 (define_expand "bunordered"
12950 [(set (pc)
12951 (if_then_else (match_dup 1)
12952 (label_ref (match_operand 0 "" ""))
12953 (pc)))]
12954 "TARGET_80387 || TARGET_SSE"
12955 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12956
12957 (define_expand "bordered"
12958 [(set (pc)
12959 (if_then_else (match_dup 1)
12960 (label_ref (match_operand 0 "" ""))
12961 (pc)))]
12962 "TARGET_80387 || TARGET_SSE"
12963 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12964
12965 (define_expand "buneq"
12966 [(set (pc)
12967 (if_then_else (match_dup 1)
12968 (label_ref (match_operand 0 "" ""))
12969 (pc)))]
12970 "TARGET_80387 || TARGET_SSE"
12971 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12972
12973 (define_expand "bunge"
12974 [(set (pc)
12975 (if_then_else (match_dup 1)
12976 (label_ref (match_operand 0 "" ""))
12977 (pc)))]
12978 "TARGET_80387 || TARGET_SSE"
12979 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12980
12981 (define_expand "bungt"
12982 [(set (pc)
12983 (if_then_else (match_dup 1)
12984 (label_ref (match_operand 0 "" ""))
12985 (pc)))]
12986 "TARGET_80387 || TARGET_SSE"
12987 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12988
12989 (define_expand "bunle"
12990 [(set (pc)
12991 (if_then_else (match_dup 1)
12992 (label_ref (match_operand 0 "" ""))
12993 (pc)))]
12994 "TARGET_80387 || TARGET_SSE"
12995 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12996
12997 (define_expand "bunlt"
12998 [(set (pc)
12999 (if_then_else (match_dup 1)
13000 (label_ref (match_operand 0 "" ""))
13001 (pc)))]
13002 "TARGET_80387 || TARGET_SSE"
13003 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13004
13005 (define_expand "bltgt"
13006 [(set (pc)
13007 (if_then_else (match_dup 1)
13008 (label_ref (match_operand 0 "" ""))
13009 (pc)))]
13010 "TARGET_80387 || TARGET_SSE"
13011 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13012
13013 (define_insn "*jcc_1"
13014 [(set (pc)
13015 (if_then_else (match_operator 1 "ix86_comparison_operator"
13016 [(reg 17) (const_int 0)])
13017 (label_ref (match_operand 0 "" ""))
13018 (pc)))]
13019 ""
13020 "%+j%C1\t%l0"
13021 [(set_attr "type" "ibr")
13022 (set_attr "modrm" "0")
13023 (set (attr "length")
13024 (if_then_else (and (ge (minus (match_dup 0) (pc))
13025 (const_int -126))
13026 (lt (minus (match_dup 0) (pc))
13027 (const_int 128)))
13028 (const_int 2)
13029 (const_int 6)))])
13030
13031 (define_insn "*jcc_2"
13032 [(set (pc)
13033 (if_then_else (match_operator 1 "ix86_comparison_operator"
13034 [(reg 17) (const_int 0)])
13035 (pc)
13036 (label_ref (match_operand 0 "" ""))))]
13037 ""
13038 "%+j%c1\t%l0"
13039 [(set_attr "type" "ibr")
13040 (set_attr "modrm" "0")
13041 (set (attr "length")
13042 (if_then_else (and (ge (minus (match_dup 0) (pc))
13043 (const_int -126))
13044 (lt (minus (match_dup 0) (pc))
13045 (const_int 128)))
13046 (const_int 2)
13047 (const_int 6)))])
13048
13049 ;; In general it is not safe to assume too much about CCmode registers,
13050 ;; so simplify-rtx stops when it sees a second one. Under certain
13051 ;; conditions this is safe on x86, so help combine not create
13052 ;;
13053 ;; seta %al
13054 ;; testb %al, %al
13055 ;; je Lfoo
13056
13057 (define_split
13058 [(set (pc)
13059 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13060 [(reg 17) (const_int 0)])
13061 (const_int 0))
13062 (label_ref (match_operand 1 "" ""))
13063 (pc)))]
13064 ""
13065 [(set (pc)
13066 (if_then_else (match_dup 0)
13067 (label_ref (match_dup 1))
13068 (pc)))]
13069 {
13070 PUT_MODE (operands[0], VOIDmode);
13071 })
13072
13073 (define_split
13074 [(set (pc)
13075 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13076 [(reg 17) (const_int 0)])
13077 (const_int 0))
13078 (label_ref (match_operand 1 "" ""))
13079 (pc)))]
13080 ""
13081 [(set (pc)
13082 (if_then_else (match_dup 0)
13083 (label_ref (match_dup 1))
13084 (pc)))]
13085 {
13086 rtx new_op0 = copy_rtx (operands[0]);
13087 operands[0] = new_op0;
13088 PUT_MODE (new_op0, VOIDmode);
13089 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13090 GET_MODE (XEXP (new_op0, 0))));
13091
13092 /* Make sure that (a) the CCmode we have for the flags is strong
13093 enough for the reversed compare or (b) we have a valid FP compare. */
13094 if (! ix86_comparison_operator (new_op0, VOIDmode))
13095 FAIL;
13096 })
13097
13098 ;; Define combination compare-and-branch fp compare instructions to use
13099 ;; during early optimization. Splitting the operation apart early makes
13100 ;; for bad code when we want to reverse the operation.
13101
13102 (define_insn "*fp_jcc_1"
13103 [(set (pc)
13104 (if_then_else (match_operator 0 "comparison_operator"
13105 [(match_operand 1 "register_operand" "f")
13106 (match_operand 2 "register_operand" "f")])
13107 (label_ref (match_operand 3 "" ""))
13108 (pc)))
13109 (clobber (reg:CCFP 18))
13110 (clobber (reg:CCFP 17))]
13111 "TARGET_CMOVE && TARGET_80387
13112 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13113 && FLOAT_MODE_P (GET_MODE (operands[1]))
13114 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13115 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13116 "#")
13117
13118 (define_insn "*fp_jcc_1_sse"
13119 [(set (pc)
13120 (if_then_else (match_operator 0 "comparison_operator"
13121 [(match_operand 1 "register_operand" "f#x,x#f")
13122 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13123 (label_ref (match_operand 3 "" ""))
13124 (pc)))
13125 (clobber (reg:CCFP 18))
13126 (clobber (reg:CCFP 17))]
13127 "TARGET_80387
13128 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13129 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13130 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13131 "#")
13132
13133 (define_insn "*fp_jcc_1_sse_only"
13134 [(set (pc)
13135 (if_then_else (match_operator 0 "comparison_operator"
13136 [(match_operand 1 "register_operand" "x")
13137 (match_operand 2 "nonimmediate_operand" "xm")])
13138 (label_ref (match_operand 3 "" ""))
13139 (pc)))
13140 (clobber (reg:CCFP 18))
13141 (clobber (reg:CCFP 17))]
13142 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13143 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13144 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13145 "#")
13146
13147 (define_insn "*fp_jcc_2"
13148 [(set (pc)
13149 (if_then_else (match_operator 0 "comparison_operator"
13150 [(match_operand 1 "register_operand" "f")
13151 (match_operand 2 "register_operand" "f")])
13152 (pc)
13153 (label_ref (match_operand 3 "" ""))))
13154 (clobber (reg:CCFP 18))
13155 (clobber (reg:CCFP 17))]
13156 "TARGET_CMOVE && TARGET_80387
13157 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13158 && FLOAT_MODE_P (GET_MODE (operands[1]))
13159 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13160 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13161 "#")
13162
13163 (define_insn "*fp_jcc_2_sse"
13164 [(set (pc)
13165 (if_then_else (match_operator 0 "comparison_operator"
13166 [(match_operand 1 "register_operand" "f#x,x#f")
13167 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13168 (pc)
13169 (label_ref (match_operand 3 "" ""))))
13170 (clobber (reg:CCFP 18))
13171 (clobber (reg:CCFP 17))]
13172 "TARGET_80387
13173 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13174 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13175 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13176 "#")
13177
13178 (define_insn "*fp_jcc_2_sse_only"
13179 [(set (pc)
13180 (if_then_else (match_operator 0 "comparison_operator"
13181 [(match_operand 1 "register_operand" "x")
13182 (match_operand 2 "nonimmediate_operand" "xm")])
13183 (pc)
13184 (label_ref (match_operand 3 "" ""))))
13185 (clobber (reg:CCFP 18))
13186 (clobber (reg:CCFP 17))]
13187 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13188 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13189 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13190 "#")
13191
13192 (define_insn "*fp_jcc_3"
13193 [(set (pc)
13194 (if_then_else (match_operator 0 "comparison_operator"
13195 [(match_operand 1 "register_operand" "f")
13196 (match_operand 2 "nonimmediate_operand" "fm")])
13197 (label_ref (match_operand 3 "" ""))
13198 (pc)))
13199 (clobber (reg:CCFP 18))
13200 (clobber (reg:CCFP 17))
13201 (clobber (match_scratch:HI 4 "=a"))]
13202 "TARGET_80387
13203 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13204 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13205 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13206 && SELECT_CC_MODE (GET_CODE (operands[0]),
13207 operands[1], operands[2]) == CCFPmode
13208 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13209 "#")
13210
13211 (define_insn "*fp_jcc_4"
13212 [(set (pc)
13213 (if_then_else (match_operator 0 "comparison_operator"
13214 [(match_operand 1 "register_operand" "f")
13215 (match_operand 2 "nonimmediate_operand" "fm")])
13216 (pc)
13217 (label_ref (match_operand 3 "" ""))))
13218 (clobber (reg:CCFP 18))
13219 (clobber (reg:CCFP 17))
13220 (clobber (match_scratch:HI 4 "=a"))]
13221 "TARGET_80387
13222 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13223 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13224 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13225 && SELECT_CC_MODE (GET_CODE (operands[0]),
13226 operands[1], operands[2]) == CCFPmode
13227 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13228 "#")
13229
13230 (define_insn "*fp_jcc_5"
13231 [(set (pc)
13232 (if_then_else (match_operator 0 "comparison_operator"
13233 [(match_operand 1 "register_operand" "f")
13234 (match_operand 2 "register_operand" "f")])
13235 (label_ref (match_operand 3 "" ""))
13236 (pc)))
13237 (clobber (reg:CCFP 18))
13238 (clobber (reg:CCFP 17))
13239 (clobber (match_scratch:HI 4 "=a"))]
13240 "TARGET_80387
13241 && FLOAT_MODE_P (GET_MODE (operands[1]))
13242 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13243 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13244 "#")
13245
13246 (define_insn "*fp_jcc_6"
13247 [(set (pc)
13248 (if_then_else (match_operator 0 "comparison_operator"
13249 [(match_operand 1 "register_operand" "f")
13250 (match_operand 2 "register_operand" "f")])
13251 (pc)
13252 (label_ref (match_operand 3 "" ""))))
13253 (clobber (reg:CCFP 18))
13254 (clobber (reg:CCFP 17))
13255 (clobber (match_scratch:HI 4 "=a"))]
13256 "TARGET_80387
13257 && FLOAT_MODE_P (GET_MODE (operands[1]))
13258 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13259 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13260 "#")
13261
13262 (define_split
13263 [(set (pc)
13264 (if_then_else (match_operator 0 "comparison_operator"
13265 [(match_operand 1 "register_operand" "")
13266 (match_operand 2 "nonimmediate_operand" "")])
13267 (match_operand 3 "" "")
13268 (match_operand 4 "" "")))
13269 (clobber (reg:CCFP 18))
13270 (clobber (reg:CCFP 17))]
13271 "reload_completed"
13272 [(const_int 0)]
13273 {
13274 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13275 operands[3], operands[4], NULL_RTX);
13276 DONE;
13277 })
13278
13279 (define_split
13280 [(set (pc)
13281 (if_then_else (match_operator 0 "comparison_operator"
13282 [(match_operand 1 "register_operand" "")
13283 (match_operand 2 "nonimmediate_operand" "")])
13284 (match_operand 3 "" "")
13285 (match_operand 4 "" "")))
13286 (clobber (reg:CCFP 18))
13287 (clobber (reg:CCFP 17))
13288 (clobber (match_scratch:HI 5 "=a"))]
13289 "reload_completed"
13290 [(set (pc)
13291 (if_then_else (match_dup 6)
13292 (match_dup 3)
13293 (match_dup 4)))]
13294 {
13295 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13296 operands[3], operands[4], operands[5]);
13297 DONE;
13298 })
13299 \f
13300 ;; Unconditional and other jump instructions
13301
13302 (define_insn "jump"
13303 [(set (pc)
13304 (label_ref (match_operand 0 "" "")))]
13305 ""
13306 "jmp\t%l0"
13307 [(set_attr "type" "ibr")
13308 (set (attr "length")
13309 (if_then_else (and (ge (minus (match_dup 0) (pc))
13310 (const_int -126))
13311 (lt (minus (match_dup 0) (pc))
13312 (const_int 128)))
13313 (const_int 2)
13314 (const_int 5)))
13315 (set_attr "modrm" "0")])
13316
13317 (define_expand "indirect_jump"
13318 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13319 ""
13320 "")
13321
13322 (define_insn "*indirect_jump"
13323 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13324 "!TARGET_64BIT"
13325 "jmp\t%A0"
13326 [(set_attr "type" "ibr")
13327 (set_attr "length_immediate" "0")])
13328
13329 (define_insn "*indirect_jump_rtx64"
13330 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13331 "TARGET_64BIT"
13332 "jmp\t%A0"
13333 [(set_attr "type" "ibr")
13334 (set_attr "length_immediate" "0")])
13335
13336 (define_expand "tablejump"
13337 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13338 (use (label_ref (match_operand 1 "" "")))])]
13339 ""
13340 {
13341 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13342 relative. Convert the relative address to an absolute address. */
13343 if (flag_pic)
13344 {
13345 rtx op0, op1;
13346 enum rtx_code code;
13347
13348 if (TARGET_64BIT)
13349 {
13350 code = PLUS;
13351 op0 = operands[0];
13352 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13353 }
13354 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13355 {
13356 code = PLUS;
13357 op0 = operands[0];
13358 op1 = pic_offset_table_rtx;
13359 }
13360 else
13361 {
13362 code = MINUS;
13363 op0 = pic_offset_table_rtx;
13364 op1 = operands[0];
13365 }
13366
13367 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13368 OPTAB_DIRECT);
13369 }
13370 })
13371
13372 (define_insn "*tablejump_1"
13373 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13374 (use (label_ref (match_operand 1 "" "")))]
13375 "!TARGET_64BIT"
13376 "jmp\t%A0"
13377 [(set_attr "type" "ibr")
13378 (set_attr "length_immediate" "0")])
13379
13380 (define_insn "*tablejump_1_rtx64"
13381 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13382 (use (label_ref (match_operand 1 "" "")))]
13383 "TARGET_64BIT"
13384 "jmp\t%A0"
13385 [(set_attr "type" "ibr")
13386 (set_attr "length_immediate" "0")])
13387 \f
13388 ;; Loop instruction
13389 ;;
13390 ;; This is all complicated by the fact that since this is a jump insn
13391 ;; we must handle our own reloads.
13392
13393 (define_expand "doloop_end"
13394 [(use (match_operand 0 "" "")) ; loop pseudo
13395 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13396 (use (match_operand 2 "" "")) ; max iterations
13397 (use (match_operand 3 "" "")) ; loop level
13398 (use (match_operand 4 "" ""))] ; label
13399 "!TARGET_64BIT && TARGET_USE_LOOP"
13400 "
13401 {
13402 /* Only use cloop on innermost loops. */
13403 if (INTVAL (operands[3]) > 1)
13404 FAIL;
13405 if (GET_MODE (operands[0]) != SImode)
13406 FAIL;
13407 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13408 operands[0]));
13409 DONE;
13410 }")
13411
13412 (define_insn "doloop_end_internal"
13413 [(set (pc)
13414 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13415 (const_int 1))
13416 (label_ref (match_operand 0 "" ""))
13417 (pc)))
13418 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13419 (plus:SI (match_dup 1)
13420 (const_int -1)))
13421 (clobber (match_scratch:SI 3 "=X,X,r"))
13422 (clobber (reg:CC 17))]
13423 "!TARGET_64BIT && TARGET_USE_LOOP
13424 && (reload_in_progress || reload_completed
13425 || register_operand (operands[2], VOIDmode))"
13426 {
13427 if (which_alternative != 0)
13428 return "#";
13429 if (get_attr_length (insn) == 2)
13430 return "%+loop\t%l0";
13431 else
13432 return "dec{l}\t%1\;%+jne\t%l0";
13433 }
13434 [(set (attr "length")
13435 (if_then_else (and (eq_attr "alternative" "0")
13436 (and (ge (minus (match_dup 0) (pc))
13437 (const_int -126))
13438 (lt (minus (match_dup 0) (pc))
13439 (const_int 128))))
13440 (const_int 2)
13441 (const_int 16)))
13442 ;; We don't know the type before shorten branches. Optimistically expect
13443 ;; the loop instruction to match.
13444 (set (attr "type") (const_string "ibr"))])
13445
13446 (define_split
13447 [(set (pc)
13448 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13449 (const_int 1))
13450 (match_operand 0 "" "")
13451 (pc)))
13452 (set (match_dup 1)
13453 (plus:SI (match_dup 1)
13454 (const_int -1)))
13455 (clobber (match_scratch:SI 2 ""))
13456 (clobber (reg:CC 17))]
13457 "!TARGET_64BIT && TARGET_USE_LOOP
13458 && reload_completed
13459 && REGNO (operands[1]) != 2"
13460 [(parallel [(set (reg:CCZ 17)
13461 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13462 (const_int 0)))
13463 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13464 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13465 (match_dup 0)
13466 (pc)))]
13467 "")
13468
13469 (define_split
13470 [(set (pc)
13471 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13472 (const_int 1))
13473 (match_operand 0 "" "")
13474 (pc)))
13475 (set (match_operand:SI 2 "nonimmediate_operand" "")
13476 (plus:SI (match_dup 1)
13477 (const_int -1)))
13478 (clobber (match_scratch:SI 3 ""))
13479 (clobber (reg:CC 17))]
13480 "!TARGET_64BIT && TARGET_USE_LOOP
13481 && reload_completed
13482 && (! REG_P (operands[2])
13483 || ! rtx_equal_p (operands[1], operands[2]))"
13484 [(set (match_dup 3) (match_dup 1))
13485 (parallel [(set (reg:CCZ 17)
13486 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13487 (const_int 0)))
13488 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13489 (set (match_dup 2) (match_dup 3))
13490 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13491 (match_dup 0)
13492 (pc)))]
13493 "")
13494
13495 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13496
13497 (define_peephole2
13498 [(set (reg 17) (match_operand 0 "" ""))
13499 (set (match_operand:QI 1 "register_operand" "")
13500 (match_operator:QI 2 "ix86_comparison_operator"
13501 [(reg 17) (const_int 0)]))
13502 (set (match_operand 3 "q_regs_operand" "")
13503 (zero_extend (match_dup 1)))]
13504 "(peep2_reg_dead_p (3, operands[1])
13505 || operands_match_p (operands[1], operands[3]))
13506 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13507 [(set (match_dup 4) (match_dup 0))
13508 (set (strict_low_part (match_dup 5))
13509 (match_dup 2))]
13510 {
13511 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13512 operands[5] = gen_lowpart (QImode, operands[3]);
13513 ix86_expand_clear (operands[3]);
13514 })
13515
13516 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13517
13518 (define_peephole2
13519 [(set (reg 17) (match_operand 0 "" ""))
13520 (set (match_operand:QI 1 "register_operand" "")
13521 (match_operator:QI 2 "ix86_comparison_operator"
13522 [(reg 17) (const_int 0)]))
13523 (parallel [(set (match_operand 3 "q_regs_operand" "")
13524 (zero_extend (match_dup 1)))
13525 (clobber (reg:CC 17))])]
13526 "(peep2_reg_dead_p (3, operands[1])
13527 || operands_match_p (operands[1], operands[3]))
13528 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13529 [(set (match_dup 4) (match_dup 0))
13530 (set (strict_low_part (match_dup 5))
13531 (match_dup 2))]
13532 {
13533 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13534 operands[5] = gen_lowpart (QImode, operands[3]);
13535 ix86_expand_clear (operands[3]);
13536 })
13537 \f
13538 ;; Call instructions.
13539
13540 ;; The predicates normally associated with named expanders are not properly
13541 ;; checked for calls. This is a bug in the generic code, but it isn't that
13542 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13543
13544 ;; Call subroutine returning no value.
13545
13546 (define_expand "call_pop"
13547 [(parallel [(call (match_operand:QI 0 "" "")
13548 (match_operand:SI 1 "" ""))
13549 (set (reg:SI 7)
13550 (plus:SI (reg:SI 7)
13551 (match_operand:SI 3 "" "")))])]
13552 "!TARGET_64BIT"
13553 {
13554 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13555 DONE;
13556 })
13557
13558 (define_insn "*call_pop_0"
13559 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13560 (match_operand:SI 1 "" ""))
13561 (set (reg:SI 7) (plus:SI (reg:SI 7)
13562 (match_operand:SI 2 "immediate_operand" "")))]
13563 "!TARGET_64BIT"
13564 {
13565 if (SIBLING_CALL_P (insn))
13566 return "jmp\t%P0";
13567 else
13568 return "call\t%P0";
13569 }
13570 [(set_attr "type" "call")])
13571
13572 (define_insn "*call_pop_1"
13573 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13574 (match_operand:SI 1 "" ""))
13575 (set (reg:SI 7) (plus:SI (reg:SI 7)
13576 (match_operand:SI 2 "immediate_operand" "i")))]
13577 "!TARGET_64BIT"
13578 {
13579 if (constant_call_address_operand (operands[0], Pmode))
13580 {
13581 if (SIBLING_CALL_P (insn))
13582 return "jmp\t%P0";
13583 else
13584 return "call\t%P0";
13585 }
13586 if (SIBLING_CALL_P (insn))
13587 return "jmp\t%A0";
13588 else
13589 return "call\t%A0";
13590 }
13591 [(set_attr "type" "call")])
13592
13593 (define_expand "call"
13594 [(call (match_operand:QI 0 "" "")
13595 (match_operand 1 "" ""))
13596 (use (match_operand 2 "" ""))]
13597 ""
13598 {
13599 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13600 DONE;
13601 })
13602
13603 (define_expand "sibcall"
13604 [(call (match_operand:QI 0 "" "")
13605 (match_operand 1 "" ""))
13606 (use (match_operand 2 "" ""))]
13607 ""
13608 {
13609 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13610 DONE;
13611 })
13612
13613 (define_insn "*call_0"
13614 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13615 (match_operand 1 "" ""))]
13616 ""
13617 {
13618 if (SIBLING_CALL_P (insn))
13619 return "jmp\t%P0";
13620 else
13621 return "call\t%P0";
13622 }
13623 [(set_attr "type" "call")])
13624
13625 (define_insn "*call_1"
13626 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13627 (match_operand 1 "" ""))]
13628 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13629 {
13630 if (constant_call_address_operand (operands[0], QImode))
13631 return "call\t%P0";
13632 return "call\t%A0";
13633 }
13634 [(set_attr "type" "call")])
13635
13636 (define_insn "*sibcall_1"
13637 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13638 (match_operand 1 "" ""))]
13639 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13640 {
13641 if (constant_call_address_operand (operands[0], QImode))
13642 return "jmp\t%P0";
13643 return "jmp\t%A0";
13644 }
13645 [(set_attr "type" "call")])
13646
13647 (define_insn "*call_1_rex64"
13648 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13649 (match_operand 1 "" ""))]
13650 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13651 {
13652 if (constant_call_address_operand (operands[0], QImode))
13653 return "call\t%P0";
13654 return "call\t%A0";
13655 }
13656 [(set_attr "type" "call")])
13657
13658 (define_insn "*sibcall_1_rex64"
13659 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13660 (match_operand 1 "" ""))]
13661 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13662 "jmp\t%P0"
13663 [(set_attr "type" "call")])
13664
13665 (define_insn "*sibcall_1_rex64_v"
13666 [(call (mem:QI (reg:DI 40))
13667 (match_operand 0 "" ""))]
13668 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13669 "jmp\t*%%r11"
13670 [(set_attr "type" "call")])
13671
13672
13673 ;; Call subroutine, returning value in operand 0
13674
13675 (define_expand "call_value_pop"
13676 [(parallel [(set (match_operand 0 "" "")
13677 (call (match_operand:QI 1 "" "")
13678 (match_operand:SI 2 "" "")))
13679 (set (reg:SI 7)
13680 (plus:SI (reg:SI 7)
13681 (match_operand:SI 4 "" "")))])]
13682 "!TARGET_64BIT"
13683 {
13684 ix86_expand_call (operands[0], operands[1], operands[2],
13685 operands[3], operands[4], 0);
13686 DONE;
13687 })
13688
13689 (define_expand "call_value"
13690 [(set (match_operand 0 "" "")
13691 (call (match_operand:QI 1 "" "")
13692 (match_operand:SI 2 "" "")))
13693 (use (match_operand:SI 3 "" ""))]
13694 ;; Operand 2 not used on the i386.
13695 ""
13696 {
13697 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13698 DONE;
13699 })
13700
13701 (define_expand "sibcall_value"
13702 [(set (match_operand 0 "" "")
13703 (call (match_operand:QI 1 "" "")
13704 (match_operand:SI 2 "" "")))
13705 (use (match_operand:SI 3 "" ""))]
13706 ;; Operand 2 not used on the i386.
13707 ""
13708 {
13709 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13710 DONE;
13711 })
13712
13713 ;; Call subroutine returning any type.
13714
13715 (define_expand "untyped_call"
13716 [(parallel [(call (match_operand 0 "" "")
13717 (const_int 0))
13718 (match_operand 1 "" "")
13719 (match_operand 2 "" "")])]
13720 ""
13721 {
13722 int i;
13723
13724 /* In order to give reg-stack an easier job in validating two
13725 coprocessor registers as containing a possible return value,
13726 simply pretend the untyped call returns a complex long double
13727 value. */
13728
13729 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13730 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13731 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13732 NULL, 0);
13733
13734 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13735 {
13736 rtx set = XVECEXP (operands[2], 0, i);
13737 emit_move_insn (SET_DEST (set), SET_SRC (set));
13738 }
13739
13740 /* The optimizer does not know that the call sets the function value
13741 registers we stored in the result block. We avoid problems by
13742 claiming that all hard registers are used and clobbered at this
13743 point. */
13744 emit_insn (gen_blockage (const0_rtx));
13745
13746 DONE;
13747 })
13748 \f
13749 ;; Prologue and epilogue instructions
13750
13751 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13752 ;; all of memory. This blocks insns from being moved across this point.
13753
13754 (define_insn "blockage"
13755 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13756 ""
13757 ""
13758 [(set_attr "length" "0")])
13759
13760 ;; Insn emitted into the body of a function to return from a function.
13761 ;; This is only done if the function's epilogue is known to be simple.
13762 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13763
13764 (define_expand "return"
13765 [(return)]
13766 "ix86_can_use_return_insn_p ()"
13767 {
13768 if (current_function_pops_args)
13769 {
13770 rtx popc = GEN_INT (current_function_pops_args);
13771 emit_jump_insn (gen_return_pop_internal (popc));
13772 DONE;
13773 }
13774 })
13775
13776 (define_insn "return_internal"
13777 [(return)]
13778 "reload_completed"
13779 "ret"
13780 [(set_attr "length" "1")
13781 (set_attr "length_immediate" "0")
13782 (set_attr "modrm" "0")])
13783
13784 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13785 ;; instruction Athlon and K8 have.
13786
13787 (define_insn "return_internal_long"
13788 [(return)
13789 (unspec [(const_int 0)] UNSPEC_REP)]
13790 "reload_completed"
13791 "rep {;} ret"
13792 [(set_attr "length" "1")
13793 (set_attr "length_immediate" "0")
13794 (set_attr "prefix_rep" "1")
13795 (set_attr "modrm" "0")])
13796
13797 (define_insn "return_pop_internal"
13798 [(return)
13799 (use (match_operand:SI 0 "const_int_operand" ""))]
13800 "reload_completed"
13801 "ret\t%0"
13802 [(set_attr "length" "3")
13803 (set_attr "length_immediate" "2")
13804 (set_attr "modrm" "0")])
13805
13806 (define_insn "return_indirect_internal"
13807 [(return)
13808 (use (match_operand:SI 0 "register_operand" "r"))]
13809 "reload_completed"
13810 "jmp\t%A0"
13811 [(set_attr "type" "ibr")
13812 (set_attr "length_immediate" "0")])
13813
13814 (define_insn "nop"
13815 [(const_int 0)]
13816 ""
13817 "nop"
13818 [(set_attr "length" "1")
13819 (set_attr "length_immediate" "0")
13820 (set_attr "modrm" "0")])
13821
13822 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13823 ;; branch prediction penalty for the third jump in a 16-byte
13824 ;; block on K8.
13825
13826 (define_insn "align"
13827 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13828 ""
13829 {
13830 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13831 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13832 #else
13833 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13834 The align insn is used to avoid 3 jump instructions in the row to improve
13835 branch prediction and the benefits hardly outweight the cost of extra 8
13836 nops on the average inserted by full alignment pseudo operation. */
13837 #endif
13838 return "";
13839 }
13840 [(set_attr "length" "16")])
13841
13842 (define_expand "prologue"
13843 [(const_int 1)]
13844 ""
13845 "ix86_expand_prologue (); DONE;")
13846
13847 (define_insn "set_got"
13848 [(set (match_operand:SI 0 "register_operand" "=r")
13849 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13850 (clobber (reg:CC 17))]
13851 "!TARGET_64BIT"
13852 { return output_set_got (operands[0]); }
13853 [(set_attr "type" "multi")
13854 (set_attr "length" "12")])
13855
13856 (define_expand "epilogue"
13857 [(const_int 1)]
13858 ""
13859 "ix86_expand_epilogue (1); DONE;")
13860
13861 (define_expand "sibcall_epilogue"
13862 [(const_int 1)]
13863 ""
13864 "ix86_expand_epilogue (0); DONE;")
13865
13866 (define_expand "eh_return"
13867 [(use (match_operand 0 "register_operand" ""))]
13868 ""
13869 {
13870 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13871
13872 /* Tricky bit: we write the address of the handler to which we will
13873 be returning into someone else's stack frame, one word below the
13874 stack address we wish to restore. */
13875 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13876 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13877 tmp = gen_rtx_MEM (Pmode, tmp);
13878 emit_move_insn (tmp, ra);
13879
13880 if (Pmode == SImode)
13881 emit_insn (gen_eh_return_si (sa));
13882 else
13883 emit_insn (gen_eh_return_di (sa));
13884 emit_barrier ();
13885 DONE;
13886 })
13887
13888 (define_insn_and_split "eh_return_si"
13889 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13890 UNSPECV_EH_RETURN)]
13891 "!TARGET_64BIT"
13892 "#"
13893 "reload_completed"
13894 [(const_int 1)]
13895 "ix86_expand_epilogue (2); DONE;")
13896
13897 (define_insn_and_split "eh_return_di"
13898 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13899 UNSPECV_EH_RETURN)]
13900 "TARGET_64BIT"
13901 "#"
13902 "reload_completed"
13903 [(const_int 1)]
13904 "ix86_expand_epilogue (2); DONE;")
13905
13906 (define_insn "leave"
13907 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13908 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13909 (clobber (mem:BLK (scratch)))]
13910 "!TARGET_64BIT"
13911 "leave"
13912 [(set_attr "type" "leave")])
13913
13914 (define_insn "leave_rex64"
13915 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13916 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13917 (clobber (mem:BLK (scratch)))]
13918 "TARGET_64BIT"
13919 "leave"
13920 [(set_attr "type" "leave")])
13921 \f
13922 (define_expand "ffssi2"
13923 [(parallel
13924 [(set (match_operand:SI 0 "register_operand" "")
13925 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13926 (clobber (match_scratch:SI 2 ""))
13927 (clobber (reg:CC 17))])]
13928 ""
13929 "")
13930
13931 (define_insn_and_split "*ffs_cmove"
13932 [(set (match_operand:SI 0 "register_operand" "=r")
13933 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13934 (clobber (match_scratch:SI 2 "=&r"))
13935 (clobber (reg:CC 17))]
13936 "TARGET_CMOVE"
13937 "#"
13938 "&& reload_completed"
13939 [(set (match_dup 2) (const_int -1))
13940 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13941 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13942 (set (match_dup 0) (if_then_else:SI
13943 (eq (reg:CCZ 17) (const_int 0))
13944 (match_dup 2)
13945 (match_dup 0)))
13946 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13947 (clobber (reg:CC 17))])]
13948 "")
13949
13950 (define_insn_and_split "*ffs_no_cmove"
13951 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13952 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13953 (clobber (match_scratch:SI 2 "=&q"))
13954 (clobber (reg:CC 17))]
13955 ""
13956 "#"
13957 "reload_completed"
13958 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13959 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13960 (set (strict_low_part (match_dup 3))
13961 (eq:QI (reg:CCZ 17) (const_int 0)))
13962 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13963 (clobber (reg:CC 17))])
13964 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13965 (clobber (reg:CC 17))])
13966 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13967 (clobber (reg:CC 17))])]
13968 {
13969 operands[3] = gen_lowpart (QImode, operands[2]);
13970 ix86_expand_clear (operands[2]);
13971 })
13972
13973 (define_insn "*ffssi_1"
13974 [(set (reg:CCZ 17)
13975 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13976 (const_int 0)))
13977 (set (match_operand:SI 0 "register_operand" "=r")
13978 (ctz:SI (match_dup 1)))]
13979 ""
13980 "bsf{l}\t{%1, %0|%0, %1}"
13981 [(set_attr "prefix_0f" "1")])
13982
13983 (define_insn "ctzsi2"
13984 [(set (match_operand:SI 0 "register_operand" "=r")
13985 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13986 (clobber (reg:CC 17))]
13987 ""
13988 "bsf{l}\t{%1, %0|%0, %1}"
13989 [(set_attr "prefix_0f" "1")])
13990
13991 (define_expand "clzsi2"
13992 [(parallel
13993 [(set (match_operand:SI 0 "register_operand" "")
13994 (minus:SI (const_int 31)
13995 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13996 (clobber (reg:CC 17))])
13997 (parallel
13998 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13999 (clobber (reg:CC 17))])]
14000 ""
14001 "")
14002
14003 (define_insn "*bsr"
14004 [(set (match_operand:SI 0 "register_operand" "=r")
14005 (minus:SI (const_int 31)
14006 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14007 (clobber (reg:CC 17))]
14008 ""
14009 "bsr{l}\t{%1, %0|%0, %1}"
14010 [(set_attr "prefix_0f" "1")])
14011 \f
14012 ;; Thread-local storage patterns for ELF.
14013 ;;
14014 ;; Note that these code sequences must appear exactly as shown
14015 ;; in order to allow linker relaxation.
14016
14017 (define_insn "*tls_global_dynamic_32_gnu"
14018 [(set (match_operand:SI 0 "register_operand" "=a")
14019 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14020 (match_operand:SI 2 "tls_symbolic_operand" "")
14021 (match_operand:SI 3 "call_insn_operand" "")]
14022 UNSPEC_TLS_GD))
14023 (clobber (match_scratch:SI 4 "=d"))
14024 (clobber (match_scratch:SI 5 "=c"))
14025 (clobber (reg:CC 17))]
14026 "!TARGET_64BIT && TARGET_GNU_TLS"
14027 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14028 [(set_attr "type" "multi")
14029 (set_attr "length" "12")])
14030
14031 (define_insn "*tls_global_dynamic_32_sun"
14032 [(set (match_operand:SI 0 "register_operand" "=a")
14033 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14034 (match_operand:SI 2 "tls_symbolic_operand" "")
14035 (match_operand:SI 3 "call_insn_operand" "")]
14036 UNSPEC_TLS_GD))
14037 (clobber (match_scratch:SI 4 "=d"))
14038 (clobber (match_scratch:SI 5 "=c"))
14039 (clobber (reg:CC 17))]
14040 "!TARGET_64BIT && TARGET_SUN_TLS"
14041 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14042 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14043 [(set_attr "type" "multi")
14044 (set_attr "length" "14")])
14045
14046 (define_expand "tls_global_dynamic_32"
14047 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14048 (unspec:SI
14049 [(match_dup 2)
14050 (match_operand:SI 1 "tls_symbolic_operand" "")
14051 (match_dup 3)]
14052 UNSPEC_TLS_GD))
14053 (clobber (match_scratch:SI 4 ""))
14054 (clobber (match_scratch:SI 5 ""))
14055 (clobber (reg:CC 17))])]
14056 ""
14057 {
14058 if (flag_pic)
14059 operands[2] = pic_offset_table_rtx;
14060 else
14061 {
14062 operands[2] = gen_reg_rtx (Pmode);
14063 emit_insn (gen_set_got (operands[2]));
14064 }
14065 operands[3] = ix86_tls_get_addr ();
14066 })
14067
14068 (define_insn "*tls_global_dynamic_64"
14069 [(set (match_operand:DI 0 "register_operand" "=a")
14070 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14071 (match_operand:DI 3 "" "")))
14072 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14073 UNSPEC_TLS_GD)]
14074 "TARGET_64BIT"
14075 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14076 [(set_attr "type" "multi")
14077 (set_attr "length" "16")])
14078
14079 (define_expand "tls_global_dynamic_64"
14080 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14081 (call (mem:QI (match_dup 2)) (const_int 0)))
14082 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14083 UNSPEC_TLS_GD)])]
14084 ""
14085 {
14086 operands[2] = ix86_tls_get_addr ();
14087 })
14088
14089 (define_insn "*tls_local_dynamic_base_32_gnu"
14090 [(set (match_operand:SI 0 "register_operand" "=a")
14091 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14092 (match_operand:SI 2 "call_insn_operand" "")]
14093 UNSPEC_TLS_LD_BASE))
14094 (clobber (match_scratch:SI 3 "=d"))
14095 (clobber (match_scratch:SI 4 "=c"))
14096 (clobber (reg:CC 17))]
14097 "!TARGET_64BIT && TARGET_GNU_TLS"
14098 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14099 [(set_attr "type" "multi")
14100 (set_attr "length" "11")])
14101
14102 (define_insn "*tls_local_dynamic_base_32_sun"
14103 [(set (match_operand:SI 0 "register_operand" "=a")
14104 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14105 (match_operand:SI 2 "call_insn_operand" "")]
14106 UNSPEC_TLS_LD_BASE))
14107 (clobber (match_scratch:SI 3 "=d"))
14108 (clobber (match_scratch:SI 4 "=c"))
14109 (clobber (reg:CC 17))]
14110 "!TARGET_64BIT && TARGET_SUN_TLS"
14111 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14112 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14113 [(set_attr "type" "multi")
14114 (set_attr "length" "13")])
14115
14116 (define_expand "tls_local_dynamic_base_32"
14117 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14118 (unspec:SI [(match_dup 1) (match_dup 2)]
14119 UNSPEC_TLS_LD_BASE))
14120 (clobber (match_scratch:SI 3 ""))
14121 (clobber (match_scratch:SI 4 ""))
14122 (clobber (reg:CC 17))])]
14123 ""
14124 {
14125 if (flag_pic)
14126 operands[1] = pic_offset_table_rtx;
14127 else
14128 {
14129 operands[1] = gen_reg_rtx (Pmode);
14130 emit_insn (gen_set_got (operands[1]));
14131 }
14132 operands[2] = ix86_tls_get_addr ();
14133 })
14134
14135 (define_insn "*tls_local_dynamic_base_64"
14136 [(set (match_operand:DI 0 "register_operand" "=a")
14137 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14138 (match_operand:DI 2 "" "")))
14139 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14140 "TARGET_64BIT"
14141 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14142 [(set_attr "type" "multi")
14143 (set_attr "length" "12")])
14144
14145 (define_expand "tls_local_dynamic_base_64"
14146 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14147 (call (mem:QI (match_dup 1)) (const_int 0)))
14148 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14149 ""
14150 {
14151 operands[1] = ix86_tls_get_addr ();
14152 })
14153
14154 ;; Local dynamic of a single variable is a lose. Show combine how
14155 ;; to convert that back to global dynamic.
14156
14157 (define_insn_and_split "*tls_local_dynamic_32_once"
14158 [(set (match_operand:SI 0 "register_operand" "=a")
14159 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14160 (match_operand:SI 2 "call_insn_operand" "")]
14161 UNSPEC_TLS_LD_BASE)
14162 (const:SI (unspec:SI
14163 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14164 UNSPEC_DTPOFF))))
14165 (clobber (match_scratch:SI 4 "=d"))
14166 (clobber (match_scratch:SI 5 "=c"))
14167 (clobber (reg:CC 17))]
14168 ""
14169 "#"
14170 ""
14171 [(parallel [(set (match_dup 0)
14172 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14173 UNSPEC_TLS_GD))
14174 (clobber (match_dup 4))
14175 (clobber (match_dup 5))
14176 (clobber (reg:CC 17))])]
14177 "")
14178
14179 ;; Load and add the thread base pointer from %gs:0.
14180
14181 (define_insn "*load_tp_si"
14182 [(set (match_operand:SI 0 "register_operand" "=r")
14183 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14184 "!TARGET_64BIT"
14185 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14186 [(set_attr "type" "imov")
14187 (set_attr "modrm" "0")
14188 (set_attr "length" "7")
14189 (set_attr "memory" "load")
14190 (set_attr "imm_disp" "false")])
14191
14192 (define_insn "*add_tp_si"
14193 [(set (match_operand:SI 0 "register_operand" "=r")
14194 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14195 (match_operand:SI 1 "register_operand" "0")))
14196 (clobber (reg:CC 17))]
14197 "!TARGET_64BIT"
14198 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14199 [(set_attr "type" "alu")
14200 (set_attr "modrm" "0")
14201 (set_attr "length" "7")
14202 (set_attr "memory" "load")
14203 (set_attr "imm_disp" "false")])
14204
14205 (define_insn "*load_tp_di"
14206 [(set (match_operand:DI 0 "register_operand" "=r")
14207 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14208 "TARGET_64BIT"
14209 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14210 [(set_attr "type" "imov")
14211 (set_attr "modrm" "0")
14212 (set_attr "length" "7")
14213 (set_attr "memory" "load")
14214 (set_attr "imm_disp" "false")])
14215
14216 (define_insn "*add_tp_di"
14217 [(set (match_operand:DI 0 "register_operand" "=r")
14218 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14219 (match_operand:DI 1 "register_operand" "0")))
14220 (clobber (reg:CC 17))]
14221 "TARGET_64BIT"
14222 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14223 [(set_attr "type" "alu")
14224 (set_attr "modrm" "0")
14225 (set_attr "length" "7")
14226 (set_attr "memory" "load")
14227 (set_attr "imm_disp" "false")])
14228 \f
14229 ;; These patterns match the binary 387 instructions for addM3, subM3,
14230 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14231 ;; SFmode. The first is the normal insn, the second the same insn but
14232 ;; with one operand a conversion, and the third the same insn but with
14233 ;; the other operand a conversion. The conversion may be SFmode or
14234 ;; SImode if the target mode DFmode, but only SImode if the target mode
14235 ;; is SFmode.
14236
14237 ;; Gcc is slightly more smart about handling normal two address instructions
14238 ;; so use special patterns for add and mull.
14239 (define_insn "*fop_sf_comm_nosse"
14240 [(set (match_operand:SF 0 "register_operand" "=f")
14241 (match_operator:SF 3 "binary_fp_operator"
14242 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14243 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14244 "TARGET_80387 && !TARGET_SSE_MATH
14245 && COMMUTATIVE_ARITH_P (operands[3])
14246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14247 "* return output_387_binary_op (insn, operands);"
14248 [(set (attr "type")
14249 (if_then_else (match_operand:SF 3 "mult_operator" "")
14250 (const_string "fmul")
14251 (const_string "fop")))
14252 (set_attr "mode" "SF")])
14253
14254 (define_insn "*fop_sf_comm"
14255 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14256 (match_operator:SF 3 "binary_fp_operator"
14257 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14258 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14259 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14260 && COMMUTATIVE_ARITH_P (operands[3])
14261 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14262 "* return output_387_binary_op (insn, operands);"
14263 [(set (attr "type")
14264 (if_then_else (eq_attr "alternative" "1")
14265 (if_then_else (match_operand:SF 3 "mult_operator" "")
14266 (const_string "ssemul")
14267 (const_string "sseadd"))
14268 (if_then_else (match_operand:SF 3 "mult_operator" "")
14269 (const_string "fmul")
14270 (const_string "fop"))))
14271 (set_attr "mode" "SF")])
14272
14273 (define_insn "*fop_sf_comm_sse"
14274 [(set (match_operand:SF 0 "register_operand" "=x")
14275 (match_operator:SF 3 "binary_fp_operator"
14276 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14277 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14278 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14279 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14280 "* return output_387_binary_op (insn, operands);"
14281 [(set (attr "type")
14282 (if_then_else (match_operand:SF 3 "mult_operator" "")
14283 (const_string "ssemul")
14284 (const_string "sseadd")))
14285 (set_attr "mode" "SF")])
14286
14287 (define_insn "*fop_df_comm_nosse"
14288 [(set (match_operand:DF 0 "register_operand" "=f")
14289 (match_operator:DF 3 "binary_fp_operator"
14290 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14291 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14292 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14293 && COMMUTATIVE_ARITH_P (operands[3])
14294 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14295 "* return output_387_binary_op (insn, operands);"
14296 [(set (attr "type")
14297 (if_then_else (match_operand:SF 3 "mult_operator" "")
14298 (const_string "fmul")
14299 (const_string "fop")))
14300 (set_attr "mode" "DF")])
14301
14302 (define_insn "*fop_df_comm"
14303 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14304 (match_operator:DF 3 "binary_fp_operator"
14305 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14306 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14307 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14308 && COMMUTATIVE_ARITH_P (operands[3])
14309 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14310 "* return output_387_binary_op (insn, operands);"
14311 [(set (attr "type")
14312 (if_then_else (eq_attr "alternative" "1")
14313 (if_then_else (match_operand:SF 3 "mult_operator" "")
14314 (const_string "ssemul")
14315 (const_string "sseadd"))
14316 (if_then_else (match_operand:SF 3 "mult_operator" "")
14317 (const_string "fmul")
14318 (const_string "fop"))))
14319 (set_attr "mode" "DF")])
14320
14321 (define_insn "*fop_df_comm_sse"
14322 [(set (match_operand:DF 0 "register_operand" "=Y")
14323 (match_operator:DF 3 "binary_fp_operator"
14324 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14325 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14326 "TARGET_SSE2 && TARGET_SSE_MATH
14327 && COMMUTATIVE_ARITH_P (operands[3])
14328 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14329 "* return output_387_binary_op (insn, operands);"
14330 [(set (attr "type")
14331 (if_then_else (match_operand:SF 3 "mult_operator" "")
14332 (const_string "ssemul")
14333 (const_string "sseadd")))
14334 (set_attr "mode" "DF")])
14335
14336 (define_insn "*fop_xf_comm"
14337 [(set (match_operand:XF 0 "register_operand" "=f")
14338 (match_operator:XF 3 "binary_fp_operator"
14339 [(match_operand:XF 1 "register_operand" "%0")
14340 (match_operand:XF 2 "register_operand" "f")]))]
14341 "TARGET_80387
14342 && COMMUTATIVE_ARITH_P (operands[3])"
14343 "* return output_387_binary_op (insn, operands);"
14344 [(set (attr "type")
14345 (if_then_else (match_operand:XF 3 "mult_operator" "")
14346 (const_string "fmul")
14347 (const_string "fop")))
14348 (set_attr "mode" "XF")])
14349
14350 (define_insn "*fop_sf_1_nosse"
14351 [(set (match_operand:SF 0 "register_operand" "=f,f")
14352 (match_operator:SF 3 "binary_fp_operator"
14353 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14354 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14355 "TARGET_80387 && !TARGET_SSE_MATH
14356 && !COMMUTATIVE_ARITH_P (operands[3])
14357 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14358 "* return output_387_binary_op (insn, operands);"
14359 [(set (attr "type")
14360 (cond [(match_operand:SF 3 "mult_operator" "")
14361 (const_string "fmul")
14362 (match_operand:SF 3 "div_operator" "")
14363 (const_string "fdiv")
14364 ]
14365 (const_string "fop")))
14366 (set_attr "mode" "SF")])
14367
14368 (define_insn "*fop_sf_1"
14369 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14370 (match_operator:SF 3 "binary_fp_operator"
14371 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14372 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14373 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14374 && !COMMUTATIVE_ARITH_P (operands[3])
14375 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14376 "* return output_387_binary_op (insn, operands);"
14377 [(set (attr "type")
14378 (cond [(and (eq_attr "alternative" "2")
14379 (match_operand:SF 3 "mult_operator" ""))
14380 (const_string "ssemul")
14381 (and (eq_attr "alternative" "2")
14382 (match_operand:SF 3 "div_operator" ""))
14383 (const_string "ssediv")
14384 (eq_attr "alternative" "2")
14385 (const_string "sseadd")
14386 (match_operand:SF 3 "mult_operator" "")
14387 (const_string "fmul")
14388 (match_operand:SF 3 "div_operator" "")
14389 (const_string "fdiv")
14390 ]
14391 (const_string "fop")))
14392 (set_attr "mode" "SF")])
14393
14394 (define_insn "*fop_sf_1_sse"
14395 [(set (match_operand:SF 0 "register_operand" "=x")
14396 (match_operator:SF 3 "binary_fp_operator"
14397 [(match_operand:SF 1 "register_operand" "0")
14398 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14399 "TARGET_SSE_MATH
14400 && !COMMUTATIVE_ARITH_P (operands[3])"
14401 "* return output_387_binary_op (insn, operands);"
14402 [(set (attr "type")
14403 (cond [(match_operand:SF 3 "mult_operator" "")
14404 (const_string "ssemul")
14405 (match_operand:SF 3 "div_operator" "")
14406 (const_string "ssediv")
14407 ]
14408 (const_string "sseadd")))
14409 (set_attr "mode" "SF")])
14410
14411 ;; ??? Add SSE splitters for these!
14412 (define_insn "*fop_sf_2"
14413 [(set (match_operand:SF 0 "register_operand" "=f,f")
14414 (match_operator:SF 3 "binary_fp_operator"
14415 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14416 (match_operand:SF 2 "register_operand" "0,0")]))]
14417 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14418 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14419 [(set (attr "type")
14420 (cond [(match_operand:SF 3 "mult_operator" "")
14421 (const_string "fmul")
14422 (match_operand:SF 3 "div_operator" "")
14423 (const_string "fdiv")
14424 ]
14425 (const_string "fop")))
14426 (set_attr "fp_int_src" "true")
14427 (set_attr "mode" "SI")])
14428
14429 (define_insn "*fop_sf_3"
14430 [(set (match_operand:SF 0 "register_operand" "=f,f")
14431 (match_operator:SF 3 "binary_fp_operator"
14432 [(match_operand:SF 1 "register_operand" "0,0")
14433 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14434 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14435 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14436 [(set (attr "type")
14437 (cond [(match_operand:SF 3 "mult_operator" "")
14438 (const_string "fmul")
14439 (match_operand:SF 3 "div_operator" "")
14440 (const_string "fdiv")
14441 ]
14442 (const_string "fop")))
14443 (set_attr "fp_int_src" "true")
14444 (set_attr "mode" "SI")])
14445
14446 (define_insn "*fop_df_1_nosse"
14447 [(set (match_operand:DF 0 "register_operand" "=f,f")
14448 (match_operator:DF 3 "binary_fp_operator"
14449 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14450 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14451 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14452 && !COMMUTATIVE_ARITH_P (operands[3])
14453 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14454 "* return output_387_binary_op (insn, operands);"
14455 [(set (attr "type")
14456 (cond [(match_operand:DF 3 "mult_operator" "")
14457 (const_string "fmul")
14458 (match_operand:DF 3 "div_operator" "")
14459 (const_string "fdiv")
14460 ]
14461 (const_string "fop")))
14462 (set_attr "mode" "DF")])
14463
14464
14465 (define_insn "*fop_df_1"
14466 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14467 (match_operator:DF 3 "binary_fp_operator"
14468 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14469 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14470 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14471 && !COMMUTATIVE_ARITH_P (operands[3])
14472 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14473 "* return output_387_binary_op (insn, operands);"
14474 [(set (attr "type")
14475 (cond [(and (eq_attr "alternative" "2")
14476 (match_operand:SF 3 "mult_operator" ""))
14477 (const_string "ssemul")
14478 (and (eq_attr "alternative" "2")
14479 (match_operand:SF 3 "div_operator" ""))
14480 (const_string "ssediv")
14481 (eq_attr "alternative" "2")
14482 (const_string "sseadd")
14483 (match_operand:DF 3 "mult_operator" "")
14484 (const_string "fmul")
14485 (match_operand:DF 3 "div_operator" "")
14486 (const_string "fdiv")
14487 ]
14488 (const_string "fop")))
14489 (set_attr "mode" "DF")])
14490
14491 (define_insn "*fop_df_1_sse"
14492 [(set (match_operand:DF 0 "register_operand" "=Y")
14493 (match_operator:DF 3 "binary_fp_operator"
14494 [(match_operand:DF 1 "register_operand" "0")
14495 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14496 "TARGET_SSE2 && TARGET_SSE_MATH
14497 && !COMMUTATIVE_ARITH_P (operands[3])"
14498 "* return output_387_binary_op (insn, operands);"
14499 [(set_attr "mode" "DF")
14500 (set (attr "type")
14501 (cond [(match_operand:SF 3 "mult_operator" "")
14502 (const_string "ssemul")
14503 (match_operand:SF 3 "div_operator" "")
14504 (const_string "ssediv")
14505 ]
14506 (const_string "sseadd")))])
14507
14508 ;; ??? Add SSE splitters for these!
14509 (define_insn "*fop_df_2"
14510 [(set (match_operand:DF 0 "register_operand" "=f,f")
14511 (match_operator:DF 3 "binary_fp_operator"
14512 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14513 (match_operand:DF 2 "register_operand" "0,0")]))]
14514 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14515 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14516 [(set (attr "type")
14517 (cond [(match_operand:DF 3 "mult_operator" "")
14518 (const_string "fmul")
14519 (match_operand:DF 3 "div_operator" "")
14520 (const_string "fdiv")
14521 ]
14522 (const_string "fop")))
14523 (set_attr "fp_int_src" "true")
14524 (set_attr "mode" "SI")])
14525
14526 (define_insn "*fop_df_3"
14527 [(set (match_operand:DF 0 "register_operand" "=f,f")
14528 (match_operator:DF 3 "binary_fp_operator"
14529 [(match_operand:DF 1 "register_operand" "0,0")
14530 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14531 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14532 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14533 [(set (attr "type")
14534 (cond [(match_operand:DF 3 "mult_operator" "")
14535 (const_string "fmul")
14536 (match_operand:DF 3 "div_operator" "")
14537 (const_string "fdiv")
14538 ]
14539 (const_string "fop")))
14540 (set_attr "fp_int_src" "true")
14541 (set_attr "mode" "SI")])
14542
14543 (define_insn "*fop_df_4"
14544 [(set (match_operand:DF 0 "register_operand" "=f,f")
14545 (match_operator:DF 3 "binary_fp_operator"
14546 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14547 (match_operand:DF 2 "register_operand" "0,f")]))]
14548 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14549 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14550 "* return output_387_binary_op (insn, operands);"
14551 [(set (attr "type")
14552 (cond [(match_operand:DF 3 "mult_operator" "")
14553 (const_string "fmul")
14554 (match_operand:DF 3 "div_operator" "")
14555 (const_string "fdiv")
14556 ]
14557 (const_string "fop")))
14558 (set_attr "mode" "SF")])
14559
14560 (define_insn "*fop_df_5"
14561 [(set (match_operand:DF 0 "register_operand" "=f,f")
14562 (match_operator:DF 3 "binary_fp_operator"
14563 [(match_operand:DF 1 "register_operand" "0,f")
14564 (float_extend:DF
14565 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14566 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14567 "* return output_387_binary_op (insn, operands);"
14568 [(set (attr "type")
14569 (cond [(match_operand:DF 3 "mult_operator" "")
14570 (const_string "fmul")
14571 (match_operand:DF 3 "div_operator" "")
14572 (const_string "fdiv")
14573 ]
14574 (const_string "fop")))
14575 (set_attr "mode" "SF")])
14576
14577 (define_insn "*fop_df_6"
14578 [(set (match_operand:DF 0 "register_operand" "=f,f")
14579 (match_operator:DF 3 "binary_fp_operator"
14580 [(float_extend:DF
14581 (match_operand:SF 1 "register_operand" "0,f"))
14582 (float_extend:DF
14583 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14584 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14585 "* return output_387_binary_op (insn, operands);"
14586 [(set (attr "type")
14587 (cond [(match_operand:DF 3 "mult_operator" "")
14588 (const_string "fmul")
14589 (match_operand:DF 3 "div_operator" "")
14590 (const_string "fdiv")
14591 ]
14592 (const_string "fop")))
14593 (set_attr "mode" "SF")])
14594
14595 (define_insn "*fop_xf_1"
14596 [(set (match_operand:XF 0 "register_operand" "=f,f")
14597 (match_operator:XF 3 "binary_fp_operator"
14598 [(match_operand:XF 1 "register_operand" "0,f")
14599 (match_operand:XF 2 "register_operand" "f,0")]))]
14600 "TARGET_80387
14601 && !COMMUTATIVE_ARITH_P (operands[3])"
14602 "* return output_387_binary_op (insn, operands);"
14603 [(set (attr "type")
14604 (cond [(match_operand:XF 3 "mult_operator" "")
14605 (const_string "fmul")
14606 (match_operand:XF 3 "div_operator" "")
14607 (const_string "fdiv")
14608 ]
14609 (const_string "fop")))
14610 (set_attr "mode" "XF")])
14611
14612 (define_insn "*fop_xf_2"
14613 [(set (match_operand:XF 0 "register_operand" "=f,f")
14614 (match_operator:XF 3 "binary_fp_operator"
14615 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14616 (match_operand:XF 2 "register_operand" "0,0")]))]
14617 "TARGET_80387 && TARGET_USE_FIOP"
14618 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14619 [(set (attr "type")
14620 (cond [(match_operand:XF 3 "mult_operator" "")
14621 (const_string "fmul")
14622 (match_operand:XF 3 "div_operator" "")
14623 (const_string "fdiv")
14624 ]
14625 (const_string "fop")))
14626 (set_attr "fp_int_src" "true")
14627 (set_attr "mode" "SI")])
14628
14629 (define_insn "*fop_xf_3"
14630 [(set (match_operand:XF 0 "register_operand" "=f,f")
14631 (match_operator:XF 3 "binary_fp_operator"
14632 [(match_operand:XF 1 "register_operand" "0,0")
14633 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14634 "TARGET_80387 && TARGET_USE_FIOP"
14635 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14636 [(set (attr "type")
14637 (cond [(match_operand:XF 3 "mult_operator" "")
14638 (const_string "fmul")
14639 (match_operand:XF 3 "div_operator" "")
14640 (const_string "fdiv")
14641 ]
14642 (const_string "fop")))
14643 (set_attr "fp_int_src" "true")
14644 (set_attr "mode" "SI")])
14645
14646 (define_insn "*fop_xf_4"
14647 [(set (match_operand:XF 0 "register_operand" "=f,f")
14648 (match_operator:XF 3 "binary_fp_operator"
14649 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14650 (match_operand:XF 2 "register_operand" "0,f")]))]
14651 "TARGET_80387"
14652 "* return output_387_binary_op (insn, operands);"
14653 [(set (attr "type")
14654 (cond [(match_operand:XF 3 "mult_operator" "")
14655 (const_string "fmul")
14656 (match_operand:XF 3 "div_operator" "")
14657 (const_string "fdiv")
14658 ]
14659 (const_string "fop")))
14660 (set_attr "mode" "SF")])
14661
14662 (define_insn "*fop_xf_5"
14663 [(set (match_operand:XF 0 "register_operand" "=f,f")
14664 (match_operator:XF 3 "binary_fp_operator"
14665 [(match_operand:XF 1 "register_operand" "0,f")
14666 (float_extend:XF
14667 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14668 "TARGET_80387"
14669 "* return output_387_binary_op (insn, operands);"
14670 [(set (attr "type")
14671 (cond [(match_operand:XF 3 "mult_operator" "")
14672 (const_string "fmul")
14673 (match_operand:XF 3 "div_operator" "")
14674 (const_string "fdiv")
14675 ]
14676 (const_string "fop")))
14677 (set_attr "mode" "SF")])
14678
14679 (define_insn "*fop_xf_6"
14680 [(set (match_operand:XF 0 "register_operand" "=f,f")
14681 (match_operator:XF 3 "binary_fp_operator"
14682 [(float_extend:XF
14683 (match_operand 1 "register_operand" "0,f"))
14684 (float_extend:XF
14685 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14686 "TARGET_80387"
14687 "* return output_387_binary_op (insn, operands);"
14688 [(set (attr "type")
14689 (cond [(match_operand:XF 3 "mult_operator" "")
14690 (const_string "fmul")
14691 (match_operand:XF 3 "div_operator" "")
14692 (const_string "fdiv")
14693 ]
14694 (const_string "fop")))
14695 (set_attr "mode" "SF")])
14696
14697 (define_split
14698 [(set (match_operand 0 "register_operand" "")
14699 (match_operator 3 "binary_fp_operator"
14700 [(float (match_operand:SI 1 "register_operand" ""))
14701 (match_operand 2 "register_operand" "")]))]
14702 "TARGET_80387 && reload_completed
14703 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14704 [(const_int 0)]
14705 {
14706 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14707 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14708 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14709 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14710 GET_MODE (operands[3]),
14711 operands[4],
14712 operands[2])));
14713 ix86_free_from_memory (GET_MODE (operands[1]));
14714 DONE;
14715 })
14716
14717 (define_split
14718 [(set (match_operand 0 "register_operand" "")
14719 (match_operator 3 "binary_fp_operator"
14720 [(match_operand 1 "register_operand" "")
14721 (float (match_operand:SI 2 "register_operand" ""))]))]
14722 "TARGET_80387 && reload_completed
14723 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14724 [(const_int 0)]
14725 {
14726 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14727 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14728 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14729 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14730 GET_MODE (operands[3]),
14731 operands[1],
14732 operands[4])));
14733 ix86_free_from_memory (GET_MODE (operands[2]));
14734 DONE;
14735 })
14736 \f
14737 ;; FPU special functions.
14738
14739 (define_expand "sqrtsf2"
14740 [(set (match_operand:SF 0 "register_operand" "")
14741 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14742 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14743 {
14744 if (!TARGET_SSE_MATH)
14745 operands[1] = force_reg (SFmode, operands[1]);
14746 })
14747
14748 (define_insn "sqrtsf2_1"
14749 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14750 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14751 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14752 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14753 "@
14754 fsqrt
14755 sqrtss\t{%1, %0|%0, %1}"
14756 [(set_attr "type" "fpspc,sse")
14757 (set_attr "mode" "SF,SF")
14758 (set_attr "athlon_decode" "direct,*")])
14759
14760 (define_insn "sqrtsf2_1_sse_only"
14761 [(set (match_operand:SF 0 "register_operand" "=x")
14762 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14763 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14764 "sqrtss\t{%1, %0|%0, %1}"
14765 [(set_attr "type" "sse")
14766 (set_attr "mode" "SF")
14767 (set_attr "athlon_decode" "*")])
14768
14769 (define_insn "sqrtsf2_i387"
14770 [(set (match_operand:SF 0 "register_operand" "=f")
14771 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14772 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14773 && !TARGET_SSE_MATH"
14774 "fsqrt"
14775 [(set_attr "type" "fpspc")
14776 (set_attr "mode" "SF")
14777 (set_attr "athlon_decode" "direct")])
14778
14779 (define_expand "sqrtdf2"
14780 [(set (match_operand:DF 0 "register_operand" "")
14781 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14782 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14783 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14784 {
14785 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14786 operands[1] = force_reg (DFmode, operands[1]);
14787 })
14788
14789 (define_insn "sqrtdf2_1"
14790 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14791 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14792 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14793 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14794 "@
14795 fsqrt
14796 sqrtsd\t{%1, %0|%0, %1}"
14797 [(set_attr "type" "fpspc,sse")
14798 (set_attr "mode" "DF,DF")
14799 (set_attr "athlon_decode" "direct,*")])
14800
14801 (define_insn "sqrtdf2_1_sse_only"
14802 [(set (match_operand:DF 0 "register_operand" "=Y")
14803 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14804 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14805 "sqrtsd\t{%1, %0|%0, %1}"
14806 [(set_attr "type" "sse")
14807 (set_attr "mode" "DF")
14808 (set_attr "athlon_decode" "*")])
14809
14810 (define_insn "sqrtdf2_i387"
14811 [(set (match_operand:DF 0 "register_operand" "=f")
14812 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14813 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14814 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14815 "fsqrt"
14816 [(set_attr "type" "fpspc")
14817 (set_attr "mode" "DF")
14818 (set_attr "athlon_decode" "direct")])
14819
14820 (define_insn "*sqrtextendsfdf2"
14821 [(set (match_operand:DF 0 "register_operand" "=f")
14822 (sqrt:DF (float_extend:DF
14823 (match_operand:SF 1 "register_operand" "0"))))]
14824 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14825 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14826 "fsqrt"
14827 [(set_attr "type" "fpspc")
14828 (set_attr "mode" "DF")
14829 (set_attr "athlon_decode" "direct")])
14830
14831 (define_insn "sqrtxf2"
14832 [(set (match_operand:XF 0 "register_operand" "=f")
14833 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14834 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14835 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14836 "fsqrt"
14837 [(set_attr "type" "fpspc")
14838 (set_attr "mode" "XF")
14839 (set_attr "athlon_decode" "direct")])
14840
14841 (define_insn "*sqrtextenddfxf2"
14842 [(set (match_operand:XF 0 "register_operand" "=f")
14843 (sqrt:XF (float_extend:XF
14844 (match_operand:DF 1 "register_operand" "0"))))]
14845 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14846 "fsqrt"
14847 [(set_attr "type" "fpspc")
14848 (set_attr "mode" "XF")
14849 (set_attr "athlon_decode" "direct")])
14850
14851 (define_insn "*sqrtextendsfxf2"
14852 [(set (match_operand:XF 0 "register_operand" "=f")
14853 (sqrt:XF (float_extend:XF
14854 (match_operand:SF 1 "register_operand" "0"))))]
14855 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14856 "fsqrt"
14857 [(set_attr "type" "fpspc")
14858 (set_attr "mode" "XF")
14859 (set_attr "athlon_decode" "direct")])
14860
14861 (define_insn "*sindf2"
14862 [(set (match_operand:DF 0 "register_operand" "=f")
14863 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14864 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14865 && flag_unsafe_math_optimizations"
14866 "fsin"
14867 [(set_attr "type" "fpspc")
14868 (set_attr "mode" "DF")])
14869
14870 (define_insn "*sinsf2"
14871 [(set (match_operand:SF 0 "register_operand" "=f")
14872 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14873 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14874 && flag_unsafe_math_optimizations"
14875 "fsin"
14876 [(set_attr "type" "fpspc")
14877 (set_attr "mode" "SF")])
14878
14879 (define_insn "*sinextendsfdf2"
14880 [(set (match_operand:DF 0 "register_operand" "=f")
14881 (unspec:DF [(float_extend:DF
14882 (match_operand:SF 1 "register_operand" "0"))]
14883 UNSPEC_SIN))]
14884 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14885 && flag_unsafe_math_optimizations"
14886 "fsin"
14887 [(set_attr "type" "fpspc")
14888 (set_attr "mode" "DF")])
14889
14890 (define_insn "*sinxf2"
14891 [(set (match_operand:XF 0 "register_operand" "=f")
14892 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14893 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14894 && flag_unsafe_math_optimizations"
14895 "fsin"
14896 [(set_attr "type" "fpspc")
14897 (set_attr "mode" "XF")])
14898
14899 (define_insn "*cosdf2"
14900 [(set (match_operand:DF 0 "register_operand" "=f")
14901 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14902 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14903 && flag_unsafe_math_optimizations"
14904 "fcos"
14905 [(set_attr "type" "fpspc")
14906 (set_attr "mode" "DF")])
14907
14908 (define_insn "*cossf2"
14909 [(set (match_operand:SF 0 "register_operand" "=f")
14910 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14911 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14912 && flag_unsafe_math_optimizations"
14913 "fcos"
14914 [(set_attr "type" "fpspc")
14915 (set_attr "mode" "SF")])
14916
14917 (define_insn "*cosextendsfdf2"
14918 [(set (match_operand:DF 0 "register_operand" "=f")
14919 (unspec:DF [(float_extend:DF
14920 (match_operand:SF 1 "register_operand" "0"))]
14921 UNSPEC_COS))]
14922 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14923 && flag_unsafe_math_optimizations"
14924 "fcos"
14925 [(set_attr "type" "fpspc")
14926 (set_attr "mode" "DF")])
14927
14928 (define_insn "*cosxf2"
14929 [(set (match_operand:XF 0 "register_operand" "=f")
14930 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14931 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14932 && flag_unsafe_math_optimizations"
14933 "fcos"
14934 [(set_attr "type" "fpspc")
14935 (set_attr "mode" "XF")])
14936
14937 ;; With sincos pattern defined, sin and cos builtin function will be
14938 ;; expanded to sincos pattern with one of its outputs left unused.
14939 ;; Cse pass will detected, if two sincos patterns can be combined,
14940 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14941 ;; depending on the unused output.
14942
14943 (define_insn "sincosdf3"
14944 [(set (match_operand:DF 0 "register_operand" "=f")
14945 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14946 UNSPEC_SINCOS_COS))
14947 (set (match_operand:DF 1 "register_operand" "=u")
14948 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14949 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14950 && flag_unsafe_math_optimizations"
14951 "fsincos"
14952 [(set_attr "type" "fpspc")
14953 (set_attr "mode" "DF")])
14954
14955 (define_split
14956 [(set (match_operand:DF 0 "register_operand" "")
14957 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14958 UNSPEC_SINCOS_COS))
14959 (set (match_operand:DF 1 "register_operand" "")
14960 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14961 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14962 && !reload_completed && !reload_in_progress"
14963 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14964 "")
14965
14966 (define_split
14967 [(set (match_operand:DF 0 "register_operand" "")
14968 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14969 UNSPEC_SINCOS_COS))
14970 (set (match_operand:DF 1 "register_operand" "")
14971 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14972 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14973 && !reload_completed && !reload_in_progress"
14974 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14975 "")
14976
14977 (define_insn "sincossf3"
14978 [(set (match_operand:SF 0 "register_operand" "=f")
14979 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14980 UNSPEC_SINCOS_COS))
14981 (set (match_operand:SF 1 "register_operand" "=u")
14982 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14983 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14984 && flag_unsafe_math_optimizations"
14985 "fsincos"
14986 [(set_attr "type" "fpspc")
14987 (set_attr "mode" "SF")])
14988
14989 (define_split
14990 [(set (match_operand:SF 0 "register_operand" "")
14991 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14992 UNSPEC_SINCOS_COS))
14993 (set (match_operand:SF 1 "register_operand" "")
14994 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14995 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14996 && !reload_completed && !reload_in_progress"
14997 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14998 "")
14999
15000 (define_split
15001 [(set (match_operand:SF 0 "register_operand" "")
15002 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15003 UNSPEC_SINCOS_COS))
15004 (set (match_operand:SF 1 "register_operand" "")
15005 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15006 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15007 && !reload_completed && !reload_in_progress"
15008 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15009 "")
15010
15011 (define_insn "*sincosextendsfdf3"
15012 [(set (match_operand:DF 0 "register_operand" "=f")
15013 (unspec:DF [(float_extend:DF
15014 (match_operand:SF 2 "register_operand" "0"))]
15015 UNSPEC_SINCOS_COS))
15016 (set (match_operand:DF 1 "register_operand" "=u")
15017 (unspec:DF [(float_extend:DF
15018 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15019 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15020 && flag_unsafe_math_optimizations"
15021 "fsincos"
15022 [(set_attr "type" "fpspc")
15023 (set_attr "mode" "DF")])
15024
15025 (define_split
15026 [(set (match_operand:DF 0 "register_operand" "")
15027 (unspec:DF [(float_extend:DF
15028 (match_operand:SF 2 "register_operand" ""))]
15029 UNSPEC_SINCOS_COS))
15030 (set (match_operand:DF 1 "register_operand" "")
15031 (unspec:DF [(float_extend:DF
15032 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15033 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15034 && !reload_completed && !reload_in_progress"
15035 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15036 (match_dup 2))] UNSPEC_SIN))]
15037 "")
15038
15039 (define_split
15040 [(set (match_operand:DF 0 "register_operand" "")
15041 (unspec:DF [(float_extend:DF
15042 (match_operand:SF 2 "register_operand" ""))]
15043 UNSPEC_SINCOS_COS))
15044 (set (match_operand:DF 1 "register_operand" "")
15045 (unspec:DF [(float_extend:DF
15046 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15047 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15048 && !reload_completed && !reload_in_progress"
15049 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15050 (match_dup 2))] UNSPEC_COS))]
15051 "")
15052
15053 (define_insn "sincosxf3"
15054 [(set (match_operand:XF 0 "register_operand" "=f")
15055 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15056 UNSPEC_SINCOS_COS))
15057 (set (match_operand:XF 1 "register_operand" "=u")
15058 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15059 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15060 && flag_unsafe_math_optimizations"
15061 "fsincos"
15062 [(set_attr "type" "fpspc")
15063 (set_attr "mode" "XF")])
15064
15065 (define_split
15066 [(set (match_operand:XF 0 "register_operand" "")
15067 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15068 UNSPEC_SINCOS_COS))
15069 (set (match_operand:XF 1 "register_operand" "")
15070 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15071 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15072 && !reload_completed && !reload_in_progress"
15073 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15074 "")
15075
15076 (define_split
15077 [(set (match_operand:XF 0 "register_operand" "")
15078 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15079 UNSPEC_SINCOS_COS))
15080 (set (match_operand:XF 1 "register_operand" "")
15081 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15082 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15083 && !reload_completed && !reload_in_progress"
15084 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15085 "")
15086
15087 (define_insn "*tandf3_1"
15088 [(set (match_operand:DF 0 "register_operand" "=f")
15089 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15090 UNSPEC_TAN_ONE))
15091 (set (match_operand:DF 1 "register_operand" "=u")
15092 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15093 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15094 && flag_unsafe_math_optimizations"
15095 "fptan"
15096 [(set_attr "type" "fpspc")
15097 (set_attr "mode" "DF")])
15098
15099 ;; optimize sequence: fptan
15100 ;; fstp %st(0)
15101 ;; fld1
15102 ;; into fptan insn.
15103
15104 (define_peephole2
15105 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15106 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15107 UNSPEC_TAN_ONE))
15108 (set (match_operand:DF 1 "register_operand" "")
15109 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15110 (set (match_dup 0)
15111 (match_operand:DF 3 "immediate_operand" ""))]
15112 "standard_80387_constant_p (operands[3]) == 2"
15113 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15114 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15115 "")
15116
15117 (define_expand "tandf2"
15118 [(parallel [(set (match_dup 2)
15119 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15120 UNSPEC_TAN_ONE))
15121 (set (match_operand:DF 0 "register_operand" "")
15122 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15123 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15124 && flag_unsafe_math_optimizations"
15125 {
15126 operands[2] = gen_reg_rtx (DFmode);
15127 })
15128
15129 (define_insn "*tansf3_1"
15130 [(set (match_operand:SF 0 "register_operand" "=f")
15131 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15132 UNSPEC_TAN_ONE))
15133 (set (match_operand:SF 1 "register_operand" "=u")
15134 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15135 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15136 && flag_unsafe_math_optimizations"
15137 "fptan"
15138 [(set_attr "type" "fpspc")
15139 (set_attr "mode" "SF")])
15140
15141 ;; optimize sequence: fptan
15142 ;; fstp %st(0)
15143 ;; fld1
15144 ;; into fptan insn.
15145
15146 (define_peephole2
15147 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15148 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15149 UNSPEC_TAN_ONE))
15150 (set (match_operand:SF 1 "register_operand" "")
15151 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15152 (set (match_dup 0)
15153 (match_operand:SF 3 "immediate_operand" ""))]
15154 "standard_80387_constant_p (operands[3]) == 2"
15155 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15156 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15157 "")
15158
15159 (define_expand "tansf2"
15160 [(parallel [(set (match_dup 2)
15161 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15162 UNSPEC_TAN_ONE))
15163 (set (match_operand:SF 0 "register_operand" "")
15164 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15165 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15166 && flag_unsafe_math_optimizations"
15167 {
15168 operands[2] = gen_reg_rtx (SFmode);
15169 })
15170
15171 (define_insn "*tanxf3_1"
15172 [(set (match_operand:XF 0 "register_operand" "=f")
15173 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15174 UNSPEC_TAN_ONE))
15175 (set (match_operand:XF 1 "register_operand" "=u")
15176 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15177 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15178 && flag_unsafe_math_optimizations"
15179 "fptan"
15180 [(set_attr "type" "fpspc")
15181 (set_attr "mode" "XF")])
15182
15183 ;; optimize sequence: fptan
15184 ;; fstp %st(0)
15185 ;; fld1
15186 ;; into fptan insn.
15187
15188 (define_peephole2
15189 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15190 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15191 UNSPEC_TAN_ONE))
15192 (set (match_operand:XF 1 "register_operand" "")
15193 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15194 (set (match_dup 0)
15195 (match_operand:XF 3 "immediate_operand" ""))]
15196 "standard_80387_constant_p (operands[3]) == 2"
15197 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15198 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15199 "")
15200
15201 (define_expand "tanxf2"
15202 [(parallel [(set (match_dup 2)
15203 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15204 UNSPEC_TAN_ONE))
15205 (set (match_operand:XF 0 "register_operand" "")
15206 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15207 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15208 && flag_unsafe_math_optimizations"
15209 {
15210 operands[2] = gen_reg_rtx (XFmode);
15211 })
15212
15213 (define_insn "atan2df3_1"
15214 [(set (match_operand:DF 0 "register_operand" "=f")
15215 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15216 (match_operand:DF 1 "register_operand" "u")]
15217 UNSPEC_FPATAN))
15218 (clobber (match_scratch:DF 3 "=1"))]
15219 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15220 && flag_unsafe_math_optimizations"
15221 "fpatan"
15222 [(set_attr "type" "fpspc")
15223 (set_attr "mode" "DF")])
15224
15225 (define_expand "atan2df3"
15226 [(use (match_operand:DF 0 "register_operand" "=f"))
15227 (use (match_operand:DF 2 "register_operand" "0"))
15228 (use (match_operand:DF 1 "register_operand" "u"))]
15229 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15230 && flag_unsafe_math_optimizations"
15231 {
15232 rtx copy = gen_reg_rtx (DFmode);
15233 emit_move_insn (copy, operands[1]);
15234 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15235 DONE;
15236 })
15237
15238 (define_expand "atandf2"
15239 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15240 (unspec:DF [(match_dup 2)
15241 (match_operand:DF 1 "register_operand" "")]
15242 UNSPEC_FPATAN))
15243 (clobber (match_scratch:DF 3 ""))])]
15244 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15245 && flag_unsafe_math_optimizations"
15246 {
15247 operands[2] = gen_reg_rtx (DFmode);
15248 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15249 })
15250
15251 (define_insn "atan2sf3_1"
15252 [(set (match_operand:SF 0 "register_operand" "=f")
15253 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15254 (match_operand:SF 1 "register_operand" "u")]
15255 UNSPEC_FPATAN))
15256 (clobber (match_scratch:SF 3 "=1"))]
15257 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15258 && flag_unsafe_math_optimizations"
15259 "fpatan"
15260 [(set_attr "type" "fpspc")
15261 (set_attr "mode" "SF")])
15262
15263 (define_expand "atan2sf3"
15264 [(use (match_operand:SF 0 "register_operand" "=f"))
15265 (use (match_operand:SF 2 "register_operand" "0"))
15266 (use (match_operand:SF 1 "register_operand" "u"))]
15267 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15268 && flag_unsafe_math_optimizations"
15269 {
15270 rtx copy = gen_reg_rtx (SFmode);
15271 emit_move_insn (copy, operands[1]);
15272 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15273 DONE;
15274 })
15275
15276 (define_expand "atansf2"
15277 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15278 (unspec:SF [(match_dup 2)
15279 (match_operand:SF 1 "register_operand" "")]
15280 UNSPEC_FPATAN))
15281 (clobber (match_scratch:SF 3 ""))])]
15282 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15283 && flag_unsafe_math_optimizations"
15284 {
15285 operands[2] = gen_reg_rtx (SFmode);
15286 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15287 })
15288
15289 (define_insn "atan2xf3_1"
15290 [(set (match_operand:XF 0 "register_operand" "=f")
15291 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15292 (match_operand:XF 1 "register_operand" "u")]
15293 UNSPEC_FPATAN))
15294 (clobber (match_scratch:XF 3 "=1"))]
15295 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15296 && flag_unsafe_math_optimizations"
15297 "fpatan"
15298 [(set_attr "type" "fpspc")
15299 (set_attr "mode" "XF")])
15300
15301 (define_expand "atan2xf3"
15302 [(use (match_operand:XF 0 "register_operand" "=f"))
15303 (use (match_operand:XF 2 "register_operand" "0"))
15304 (use (match_operand:XF 1 "register_operand" "u"))]
15305 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15306 && flag_unsafe_math_optimizations"
15307 {
15308 rtx copy = gen_reg_rtx (XFmode);
15309 emit_move_insn (copy, operands[1]);
15310 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15311 DONE;
15312 })
15313
15314 (define_expand "atanxf2"
15315 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15316 (unspec:XF [(match_dup 2)
15317 (match_operand:XF 1 "register_operand" "")]
15318 UNSPEC_FPATAN))
15319 (clobber (match_scratch:XF 3 ""))])]
15320 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15321 && flag_unsafe_math_optimizations"
15322 {
15323 operands[2] = gen_reg_rtx (XFmode);
15324 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15325 })
15326
15327 (define_expand "asindf2"
15328 [(set (match_dup 2)
15329 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15330 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15331 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15332 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15333 (parallel [(set (match_dup 7)
15334 (unspec:XF [(match_dup 6) (match_dup 2)]
15335 UNSPEC_FPATAN))
15336 (clobber (match_scratch:XF 8 ""))])
15337 (set (match_operand:DF 0 "register_operand" "")
15338 (float_truncate:DF (match_dup 7)))]
15339 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15340 && flag_unsafe_math_optimizations"
15341 {
15342 int i;
15343
15344 for (i=2; i<8; i++)
15345 operands[i] = gen_reg_rtx (XFmode);
15346
15347 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15348 })
15349
15350 (define_expand "asinsf2"
15351 [(set (match_dup 2)
15352 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15353 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15354 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15355 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15356 (parallel [(set (match_dup 7)
15357 (unspec:XF [(match_dup 6) (match_dup 2)]
15358 UNSPEC_FPATAN))
15359 (clobber (match_scratch:XF 8 ""))])
15360 (set (match_operand:SF 0 "register_operand" "")
15361 (float_truncate:SF (match_dup 7)))]
15362 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15363 && flag_unsafe_math_optimizations"
15364 {
15365 int i;
15366
15367 for (i=2; i<8; i++)
15368 operands[i] = gen_reg_rtx (XFmode);
15369
15370 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15371 })
15372
15373 (define_expand "asinxf2"
15374 [(set (match_dup 2)
15375 (mult:XF (match_operand:XF 1 "register_operand" "")
15376 (match_dup 1)))
15377 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15378 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15379 (parallel [(set (match_operand:XF 0 "register_operand" "")
15380 (unspec:XF [(match_dup 5) (match_dup 1)]
15381 UNSPEC_FPATAN))
15382 (clobber (match_scratch:XF 6 ""))])]
15383 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15384 && flag_unsafe_math_optimizations"
15385 {
15386 int i;
15387
15388 for (i=2; i<6; i++)
15389 operands[i] = gen_reg_rtx (XFmode);
15390
15391 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15392 })
15393
15394 (define_expand "acosdf2"
15395 [(set (match_dup 2)
15396 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15397 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15398 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15399 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15400 (parallel [(set (match_dup 7)
15401 (unspec:XF [(match_dup 2) (match_dup 6)]
15402 UNSPEC_FPATAN))
15403 (clobber (match_scratch:XF 8 ""))])
15404 (set (match_operand:DF 0 "register_operand" "")
15405 (float_truncate:DF (match_dup 7)))]
15406 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15407 && flag_unsafe_math_optimizations"
15408 {
15409 int i;
15410
15411 for (i=2; i<8; i++)
15412 operands[i] = gen_reg_rtx (XFmode);
15413
15414 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15415 })
15416
15417 (define_expand "acossf2"
15418 [(set (match_dup 2)
15419 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15420 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15421 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15422 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15423 (parallel [(set (match_dup 7)
15424 (unspec:XF [(match_dup 2) (match_dup 6)]
15425 UNSPEC_FPATAN))
15426 (clobber (match_scratch:XF 8 ""))])
15427 (set (match_operand:SF 0 "register_operand" "")
15428 (float_truncate:SF (match_dup 7)))]
15429 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15430 && flag_unsafe_math_optimizations"
15431 {
15432 int i;
15433
15434 for (i=2; i<8; i++)
15435 operands[i] = gen_reg_rtx (XFmode);
15436
15437 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15438 })
15439
15440 (define_expand "acosxf2"
15441 [(set (match_dup 2)
15442 (mult:XF (match_operand:XF 1 "register_operand" "")
15443 (match_dup 1)))
15444 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15445 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15446 (parallel [(set (match_operand:XF 0 "register_operand" "")
15447 (unspec:XF [(match_dup 1) (match_dup 5)]
15448 UNSPEC_FPATAN))
15449 (clobber (match_scratch:XF 6 ""))])]
15450 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15451 && flag_unsafe_math_optimizations"
15452 {
15453 int i;
15454
15455 for (i=2; i<6; i++)
15456 operands[i] = gen_reg_rtx (XFmode);
15457
15458 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15459 })
15460
15461 (define_insn "*fyl2x_sfxf3"
15462 [(set (match_operand:SF 0 "register_operand" "=f")
15463 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15464 (match_operand:XF 1 "register_operand" "u")]
15465 UNSPEC_FYL2X))
15466 (clobber (match_scratch:SF 3 "=1"))]
15467 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15468 && flag_unsafe_math_optimizations"
15469 "fyl2x"
15470 [(set_attr "type" "fpspc")
15471 (set_attr "mode" "SF")])
15472
15473 (define_insn "*fyl2x_dfxf3"
15474 [(set (match_operand:DF 0 "register_operand" "=f")
15475 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15476 (match_operand:XF 1 "register_operand" "u")]
15477 UNSPEC_FYL2X))
15478 (clobber (match_scratch:DF 3 "=1"))]
15479 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15480 && flag_unsafe_math_optimizations"
15481 "fyl2x"
15482 [(set_attr "type" "fpspc")
15483 (set_attr "mode" "DF")])
15484
15485 (define_insn "*fyl2x_xf3"
15486 [(set (match_operand:XF 0 "register_operand" "=f")
15487 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15488 (match_operand:XF 1 "register_operand" "u")]
15489 UNSPEC_FYL2X))
15490 (clobber (match_scratch:XF 3 "=1"))]
15491 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15492 && flag_unsafe_math_optimizations"
15493 "fyl2x"
15494 [(set_attr "type" "fpspc")
15495 (set_attr "mode" "XF")])
15496
15497 (define_expand "logsf2"
15498 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15499 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15500 (match_dup 2)] UNSPEC_FYL2X))
15501 (clobber (match_scratch:SF 3 ""))])]
15502 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15503 && flag_unsafe_math_optimizations"
15504 {
15505 rtx temp;
15506
15507 operands[2] = gen_reg_rtx (XFmode);
15508 temp = standard_80387_constant_rtx (4); /* fldln2 */
15509 emit_move_insn (operands[2], temp);
15510 })
15511
15512 (define_expand "logdf2"
15513 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15514 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15515 (match_dup 2)] UNSPEC_FYL2X))
15516 (clobber (match_scratch:DF 3 ""))])]
15517 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15518 && flag_unsafe_math_optimizations"
15519 {
15520 rtx temp;
15521
15522 operands[2] = gen_reg_rtx (XFmode);
15523 temp = standard_80387_constant_rtx (4); /* fldln2 */
15524 emit_move_insn (operands[2], temp);
15525 })
15526
15527 (define_expand "logxf2"
15528 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15530 (match_dup 2)] UNSPEC_FYL2X))
15531 (clobber (match_scratch:XF 3 ""))])]
15532 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15533 && flag_unsafe_math_optimizations"
15534 {
15535 rtx temp;
15536
15537 operands[2] = gen_reg_rtx (XFmode);
15538 temp = standard_80387_constant_rtx (4); /* fldln2 */
15539 emit_move_insn (operands[2], temp);
15540 })
15541
15542 (define_expand "log10sf2"
15543 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15544 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15545 (match_dup 2)] UNSPEC_FYL2X))
15546 (clobber (match_scratch:SF 3 ""))])]
15547 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15548 && flag_unsafe_math_optimizations"
15549 {
15550 rtx temp;
15551
15552 operands[2] = gen_reg_rtx (XFmode);
15553 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15554 emit_move_insn (operands[2], temp);
15555 })
15556
15557 (define_expand "log10df2"
15558 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15559 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15560 (match_dup 2)] UNSPEC_FYL2X))
15561 (clobber (match_scratch:DF 3 ""))])]
15562 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15563 && flag_unsafe_math_optimizations"
15564 {
15565 rtx temp;
15566
15567 operands[2] = gen_reg_rtx (XFmode);
15568 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15569 emit_move_insn (operands[2], temp);
15570 })
15571
15572 (define_expand "log10xf2"
15573 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15574 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15575 (match_dup 2)] UNSPEC_FYL2X))
15576 (clobber (match_scratch:XF 3 ""))])]
15577 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15578 && flag_unsafe_math_optimizations"
15579 {
15580 rtx temp;
15581
15582 operands[2] = gen_reg_rtx (XFmode);
15583 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15584 emit_move_insn (operands[2], temp);
15585 })
15586
15587 (define_expand "log2sf2"
15588 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15589 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15590 (match_dup 2)] UNSPEC_FYL2X))
15591 (clobber (match_scratch:SF 3 ""))])]
15592 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15593 && flag_unsafe_math_optimizations"
15594 {
15595 operands[2] = gen_reg_rtx (XFmode);
15596 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15597
15598 })
15599
15600 (define_expand "log2df2"
15601 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15602 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15603 (match_dup 2)] UNSPEC_FYL2X))
15604 (clobber (match_scratch:DF 3 ""))])]
15605 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15606 && flag_unsafe_math_optimizations"
15607 {
15608 operands[2] = gen_reg_rtx (XFmode);
15609 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15610 })
15611
15612 (define_expand "log2xf2"
15613 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15614 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15615 (match_dup 2)] UNSPEC_FYL2X))
15616 (clobber (match_scratch:XF 3 ""))])]
15617 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15618 && flag_unsafe_math_optimizations"
15619 {
15620 operands[2] = gen_reg_rtx (XFmode);
15621 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15622 })
15623
15624 (define_insn "*fxtractdf3"
15625 [(set (match_operand:DF 0 "register_operand" "=f")
15626 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15627 UNSPEC_XTRACT_FRACT))
15628 (set (match_operand:DF 1 "register_operand" "=u")
15629 (unspec:DF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15630 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15631 && flag_unsafe_math_optimizations"
15632 "fxtract"
15633 [(set_attr "type" "fpspc")
15634 (set_attr "mode" "DF")])
15635
15636 (define_expand "logbdf2"
15637 [(parallel [(set (match_dup 2)
15638 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15639 UNSPEC_XTRACT_FRACT))
15640 (set (match_operand:DF 0 "register_operand" "")
15641 (unspec:DF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15642 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15643 && flag_unsafe_math_optimizations"
15644 {
15645 operands[2] = gen_reg_rtx (DFmode);
15646 })
15647
15648 (define_insn "*fxtractsf3"
15649 [(set (match_operand:SF 0 "register_operand" "=f")
15650 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15651 UNSPEC_XTRACT_FRACT))
15652 (set (match_operand:SF 1 "register_operand" "=u")
15653 (unspec:SF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15654 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15655 && flag_unsafe_math_optimizations"
15656 "fxtract"
15657 [(set_attr "type" "fpspc")
15658 (set_attr "mode" "SF")])
15659
15660 (define_expand "logbsf2"
15661 [(parallel [(set (match_dup 2)
15662 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15663 UNSPEC_XTRACT_FRACT))
15664 (set (match_operand:SF 0 "register_operand" "")
15665 (unspec:SF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15666 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15667 && flag_unsafe_math_optimizations"
15668 {
15669 operands[2] = gen_reg_rtx (SFmode);
15670 })
15671
15672 (define_insn "*fxtractxf3"
15673 [(set (match_operand:XF 0 "register_operand" "=f")
15674 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15675 UNSPEC_XTRACT_FRACT))
15676 (set (match_operand:XF 1 "register_operand" "=u")
15677 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15678 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15679 && flag_unsafe_math_optimizations"
15680 "fxtract"
15681 [(set_attr "type" "fpspc")
15682 (set_attr "mode" "XF")])
15683
15684 (define_expand "logbxf2"
15685 [(parallel [(set (match_dup 2)
15686 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15687 UNSPEC_XTRACT_FRACT))
15688 (set (match_operand:XF 0 "register_operand" "")
15689 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15690 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15691 && flag_unsafe_math_optimizations"
15692 {
15693 operands[2] = gen_reg_rtx (XFmode);
15694 })
15695
15696 (define_expand "ilogbsi2"
15697 [(parallel [(set (match_dup 2)
15698 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15699 UNSPEC_XTRACT_FRACT))
15700 (set (match_operand:XF 3 "register_operand" "")
15701 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15702 (parallel [(set (match_operand:SI 0 "register_operand" "")
15703 (fix:SI (match_dup 3)))
15704 (clobber (reg:CC 17))])]
15705 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15706 && flag_unsafe_math_optimizations"
15707 {
15708 operands[2] = gen_reg_rtx (XFmode);
15709 operands[3] = gen_reg_rtx (XFmode);
15710 })
15711
15712 (define_insn "*frndintxf2"
15713 [(set (match_operand:XF 0 "register_operand" "=f")
15714 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15715 UNSPEC_FRNDINT))]
15716 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15717 && flag_unsafe_math_optimizations"
15718 "frndint"
15719 [(set_attr "type" "fpspc")
15720 (set_attr "mode" "XF")])
15721
15722 (define_insn "*f2xm1xf2"
15723 [(set (match_operand:XF 0 "register_operand" "=f")
15724 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15725 UNSPEC_F2XM1))]
15726 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15727 && flag_unsafe_math_optimizations"
15728 "f2xm1"
15729 [(set_attr "type" "fpspc")
15730 (set_attr "mode" "XF")])
15731
15732 (define_insn "*fscalexf4"
15733 [(set (match_operand:XF 0 "register_operand" "=f")
15734 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15735 (match_operand:XF 3 "register_operand" "1")]
15736 UNSPEC_FSCALE_FRACT))
15737 (set (match_operand:XF 1 "register_operand" "=u")
15738 (unspec:XF [(match_dup 2) (match_dup 3)]
15739 UNSPEC_FSCALE_EXP))]
15740 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15741 && flag_unsafe_math_optimizations"
15742 "fscale"
15743 [(set_attr "type" "fpspc")
15744 (set_attr "mode" "DF")])
15745
15746 (define_expand "expsf2"
15747 [(set (match_dup 2)
15748 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15749 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15750 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15751 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15752 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15753 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15754 (parallel [(set (match_dup 10)
15755 (unspec:XF [(match_dup 9) (match_dup 5)]
15756 UNSPEC_FSCALE_FRACT))
15757 (set (match_dup 11)
15758 (unspec:XF [(match_dup 9) (match_dup 5)]
15759 UNSPEC_FSCALE_EXP))])
15760 (set (match_operand:SF 0 "register_operand" "")
15761 (float_truncate:SF (match_dup 10)))]
15762 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15763 && flag_unsafe_math_optimizations"
15764 {
15765 rtx temp;
15766 int i;
15767
15768 for (i=2; i<12; i++)
15769 operands[i] = gen_reg_rtx (XFmode);
15770 temp = standard_80387_constant_rtx (5); /* fldl2e */
15771 emit_move_insn (operands[3], temp);
15772 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15773 })
15774
15775 (define_expand "expdf2"
15776 [(set (match_dup 2)
15777 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15778 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15779 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15780 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15781 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15782 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15783 (parallel [(set (match_dup 10)
15784 (unspec:XF [(match_dup 9) (match_dup 5)]
15785 UNSPEC_FSCALE_FRACT))
15786 (set (match_dup 11)
15787 (unspec:XF [(match_dup 9) (match_dup 5)]
15788 UNSPEC_FSCALE_EXP))])
15789 (set (match_operand:DF 0 "register_operand" "")
15790 (float_truncate:DF (match_dup 10)))]
15791 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15792 && flag_unsafe_math_optimizations"
15793 {
15794 rtx temp;
15795 int i;
15796
15797 for (i=2; i<12; i++)
15798 operands[i] = gen_reg_rtx (XFmode);
15799 temp = standard_80387_constant_rtx (5); /* fldl2e */
15800 emit_move_insn (operands[3], temp);
15801 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15802 })
15803
15804 (define_expand "expxf2"
15805 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15806 (match_dup 2)))
15807 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15808 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15809 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15810 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15811 (parallel [(set (match_operand:XF 0 "register_operand" "")
15812 (unspec:XF [(match_dup 8) (match_dup 4)]
15813 UNSPEC_FSCALE_FRACT))
15814 (set (match_dup 9)
15815 (unspec:XF [(match_dup 8) (match_dup 4)]
15816 UNSPEC_FSCALE_EXP))])]
15817 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15818 && flag_unsafe_math_optimizations"
15819 {
15820 rtx temp;
15821 int i;
15822
15823 for (i=2; i<10; i++)
15824 operands[i] = gen_reg_rtx (XFmode);
15825 temp = standard_80387_constant_rtx (5); /* fldl2e */
15826 emit_move_insn (operands[2], temp);
15827 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15828 })
15829
15830 (define_expand "exp10sf2"
15831 [(set (match_dup 2)
15832 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15833 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15834 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15835 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15836 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15837 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15838 (parallel [(set (match_dup 10)
15839 (unspec:XF [(match_dup 9) (match_dup 5)]
15840 UNSPEC_FSCALE_FRACT))
15841 (set (match_dup 11)
15842 (unspec:XF [(match_dup 9) (match_dup 5)]
15843 UNSPEC_FSCALE_EXP))])
15844 (set (match_operand:SF 0 "register_operand" "")
15845 (float_truncate:SF (match_dup 10)))]
15846 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15847 && flag_unsafe_math_optimizations"
15848 {
15849 rtx temp;
15850 int i;
15851
15852 for (i=2; i<12; i++)
15853 operands[i] = gen_reg_rtx (XFmode);
15854 temp = standard_80387_constant_rtx (6); /* fldl2t */
15855 emit_move_insn (operands[3], temp);
15856 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15857 })
15858
15859 (define_expand "exp10df2"
15860 [(set (match_dup 2)
15861 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15862 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15863 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15864 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15865 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15866 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15867 (parallel [(set (match_dup 10)
15868 (unspec:XF [(match_dup 9) (match_dup 5)]
15869 UNSPEC_FSCALE_FRACT))
15870 (set (match_dup 11)
15871 (unspec:XF [(match_dup 9) (match_dup 5)]
15872 UNSPEC_FSCALE_EXP))])
15873 (set (match_operand:DF 0 "register_operand" "")
15874 (float_truncate:DF (match_dup 10)))]
15875 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15876 && flag_unsafe_math_optimizations"
15877 {
15878 rtx temp;
15879 int i;
15880
15881 for (i=2; i<12; i++)
15882 operands[i] = gen_reg_rtx (XFmode);
15883 temp = standard_80387_constant_rtx (6); /* fldl2t */
15884 emit_move_insn (operands[3], temp);
15885 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15886 })
15887
15888 (define_expand "exp10xf2"
15889 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15890 (match_dup 2)))
15891 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15892 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15893 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15894 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15895 (parallel [(set (match_operand:XF 0 "register_operand" "")
15896 (unspec:XF [(match_dup 8) (match_dup 4)]
15897 UNSPEC_FSCALE_FRACT))
15898 (set (match_dup 9)
15899 (unspec:XF [(match_dup 8) (match_dup 4)]
15900 UNSPEC_FSCALE_EXP))])]
15901 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15902 && flag_unsafe_math_optimizations"
15903 {
15904 rtx temp;
15905 int i;
15906
15907 for (i=2; i<10; i++)
15908 operands[i] = gen_reg_rtx (XFmode);
15909 temp = standard_80387_constant_rtx (6); /* fldl2t */
15910 emit_move_insn (operands[2], temp);
15911 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15912 })
15913
15914 (define_expand "exp2sf2"
15915 [(set (match_dup 2)
15916 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15917 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15918 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15919 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15920 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15921 (parallel [(set (match_dup 8)
15922 (unspec:XF [(match_dup 7) (match_dup 3)]
15923 UNSPEC_FSCALE_FRACT))
15924 (set (match_dup 9)
15925 (unspec:XF [(match_dup 7) (match_dup 3)]
15926 UNSPEC_FSCALE_EXP))])
15927 (set (match_operand:SF 0 "register_operand" "")
15928 (float_truncate:SF (match_dup 8)))]
15929 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15930 && flag_unsafe_math_optimizations"
15931 {
15932 int i;
15933
15934 for (i=2; i<10; i++)
15935 operands[i] = gen_reg_rtx (XFmode);
15936 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15937 })
15938
15939 (define_expand "exp2df2"
15940 [(set (match_dup 2)
15941 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15942 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15943 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15944 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15945 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15946 (parallel [(set (match_dup 8)
15947 (unspec:XF [(match_dup 7) (match_dup 3)]
15948 UNSPEC_FSCALE_FRACT))
15949 (set (match_dup 9)
15950 (unspec:XF [(match_dup 7) (match_dup 3)]
15951 UNSPEC_FSCALE_EXP))])
15952 (set (match_operand:DF 0 "register_operand" "")
15953 (float_truncate:DF (match_dup 8)))]
15954 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15955 && flag_unsafe_math_optimizations"
15956 {
15957 int i;
15958
15959 for (i=2; i<10; i++)
15960 operands[i] = gen_reg_rtx (XFmode);
15961 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15962 })
15963
15964 (define_expand "exp2xf2"
15965 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15966 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15967 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15968 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15969 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15970 (parallel [(set (match_operand:XF 0 "register_operand" "")
15971 (unspec:XF [(match_dup 7) (match_dup 3)]
15972 UNSPEC_FSCALE_FRACT))
15973 (set (match_dup 8)
15974 (unspec:XF [(match_dup 7) (match_dup 3)]
15975 UNSPEC_FSCALE_EXP))])]
15976 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15977 && flag_unsafe_math_optimizations"
15978 {
15979 int i;
15980
15981 for (i=2; i<9; i++)
15982 operands[i] = gen_reg_rtx (XFmode);
15983 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15984 })
15985
15986 (define_expand "expm1df2"
15987 [(set (match_dup 2)
15988 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15989 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15990 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15991 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15992 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15993 (parallel [(set (match_dup 8)
15994 (unspec:XF [(match_dup 7) (match_dup 5)]
15995 UNSPEC_FSCALE_FRACT))
15996 (set (match_dup 9)
15997 (unspec:XF [(match_dup 7) (match_dup 5)]
15998 UNSPEC_FSCALE_EXP))])
15999 (parallel [(set (match_dup 11)
16000 (unspec:XF [(match_dup 10) (match_dup 9)]
16001 UNSPEC_FSCALE_FRACT))
16002 (set (match_dup 12)
16003 (unspec:XF [(match_dup 10) (match_dup 9)]
16004 UNSPEC_FSCALE_EXP))])
16005 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16006 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16007 (set (match_operand:DF 0 "register_operand" "")
16008 (float_truncate:DF (match_dup 14)))]
16009 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16010 && flag_unsafe_math_optimizations"
16011 {
16012 rtx temp;
16013 int i;
16014
16015 for (i=2; i<15; i++)
16016 operands[i] = gen_reg_rtx (XFmode);
16017 temp = standard_80387_constant_rtx (5); /* fldl2e */
16018 emit_move_insn (operands[3], temp);
16019 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16020 })
16021
16022 (define_expand "expm1sf2"
16023 [(set (match_dup 2)
16024 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16025 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16026 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16027 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16028 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16029 (parallel [(set (match_dup 8)
16030 (unspec:XF [(match_dup 7) (match_dup 5)]
16031 UNSPEC_FSCALE_FRACT))
16032 (set (match_dup 9)
16033 (unspec:XF [(match_dup 7) (match_dup 5)]
16034 UNSPEC_FSCALE_EXP))])
16035 (parallel [(set (match_dup 11)
16036 (unspec:XF [(match_dup 10) (match_dup 9)]
16037 UNSPEC_FSCALE_FRACT))
16038 (set (match_dup 12)
16039 (unspec:XF [(match_dup 10) (match_dup 9)]
16040 UNSPEC_FSCALE_EXP))])
16041 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16042 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16043 (set (match_operand:SF 0 "register_operand" "")
16044 (float_truncate:SF (match_dup 14)))]
16045 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16046 && flag_unsafe_math_optimizations"
16047 {
16048 rtx temp;
16049 int i;
16050
16051 for (i=2; i<15; i++)
16052 operands[i] = gen_reg_rtx (XFmode);
16053 temp = standard_80387_constant_rtx (5); /* fldl2e */
16054 emit_move_insn (operands[3], temp);
16055 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16056 })
16057
16058 (define_expand "expm1xf2"
16059 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16060 (match_dup 2)))
16061 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16062 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16063 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16064 (parallel [(set (match_dup 7)
16065 (unspec:XF [(match_dup 6) (match_dup 4)]
16066 UNSPEC_FSCALE_FRACT))
16067 (set (match_dup 8)
16068 (unspec:XF [(match_dup 6) (match_dup 4)]
16069 UNSPEC_FSCALE_EXP))])
16070 (parallel [(set (match_dup 10)
16071 (unspec:XF [(match_dup 9) (match_dup 8)]
16072 UNSPEC_FSCALE_FRACT))
16073 (set (match_dup 11)
16074 (unspec:XF [(match_dup 9) (match_dup 8)]
16075 UNSPEC_FSCALE_EXP))])
16076 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16077 (set (match_operand:XF 0 "register_operand" "")
16078 (plus:XF (match_dup 12) (match_dup 7)))]
16079 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16080 && flag_unsafe_math_optimizations"
16081 {
16082 rtx temp;
16083 int i;
16084
16085 for (i=2; i<13; i++)
16086 operands[i] = gen_reg_rtx (XFmode);
16087 temp = standard_80387_constant_rtx (5); /* fldl2e */
16088 emit_move_insn (operands[2], temp);
16089 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16090 })
16091 \f
16092 ;; Block operation instructions
16093
16094 (define_insn "cld"
16095 [(set (reg:SI 19) (const_int 0))]
16096 ""
16097 "cld"
16098 [(set_attr "type" "cld")])
16099
16100 (define_expand "movstrsi"
16101 [(use (match_operand:BLK 0 "memory_operand" ""))
16102 (use (match_operand:BLK 1 "memory_operand" ""))
16103 (use (match_operand:SI 2 "nonmemory_operand" ""))
16104 (use (match_operand:SI 3 "const_int_operand" ""))]
16105 "! optimize_size"
16106 {
16107 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16108 DONE;
16109 else
16110 FAIL;
16111 })
16112
16113 (define_expand "movstrdi"
16114 [(use (match_operand:BLK 0 "memory_operand" ""))
16115 (use (match_operand:BLK 1 "memory_operand" ""))
16116 (use (match_operand:DI 2 "nonmemory_operand" ""))
16117 (use (match_operand:DI 3 "const_int_operand" ""))]
16118 "TARGET_64BIT"
16119 {
16120 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
16121 DONE;
16122 else
16123 FAIL;
16124 })
16125
16126 ;; Most CPUs don't like single string operations
16127 ;; Handle this case here to simplify previous expander.
16128
16129 (define_expand "strmov"
16130 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16131 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16132 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16133 (clobber (reg:CC 17))])
16134 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16135 (clobber (reg:CC 17))])]
16136 ""
16137 {
16138 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16139
16140 /* If .md ever supports :P for Pmode, these can be directly
16141 in the pattern above. */
16142 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16143 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16144
16145 if (TARGET_SINGLE_STRINGOP || optimize_size)
16146 {
16147 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16148 operands[2], operands[3],
16149 operands[5], operands[6]));
16150 DONE;
16151 }
16152
16153 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16154 })
16155
16156 (define_expand "strmov_singleop"
16157 [(parallel [(set (match_operand 1 "memory_operand" "")
16158 (match_operand 3 "memory_operand" ""))
16159 (set (match_operand 0 "register_operand" "")
16160 (match_operand 4 "" ""))
16161 (set (match_operand 2 "register_operand" "")
16162 (match_operand 5 "" ""))
16163 (use (reg:SI 19))])]
16164 "TARGET_SINGLE_STRINGOP || optimize_size"
16165 "")
16166
16167 (define_insn "*strmovdi_rex_1"
16168 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16169 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16170 (set (match_operand:DI 0 "register_operand" "=D")
16171 (plus:DI (match_dup 2)
16172 (const_int 8)))
16173 (set (match_operand:DI 1 "register_operand" "=S")
16174 (plus:DI (match_dup 3)
16175 (const_int 8)))
16176 (use (reg:SI 19))]
16177 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16178 "movsq"
16179 [(set_attr "type" "str")
16180 (set_attr "mode" "DI")
16181 (set_attr "memory" "both")])
16182
16183 (define_insn "*strmovsi_1"
16184 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16185 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16186 (set (match_operand:SI 0 "register_operand" "=D")
16187 (plus:SI (match_dup 2)
16188 (const_int 4)))
16189 (set (match_operand:SI 1 "register_operand" "=S")
16190 (plus:SI (match_dup 3)
16191 (const_int 4)))
16192 (use (reg:SI 19))]
16193 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16194 "{movsl|movsd}"
16195 [(set_attr "type" "str")
16196 (set_attr "mode" "SI")
16197 (set_attr "memory" "both")])
16198
16199 (define_insn "*strmovsi_rex_1"
16200 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16201 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16202 (set (match_operand:DI 0 "register_operand" "=D")
16203 (plus:DI (match_dup 2)
16204 (const_int 4)))
16205 (set (match_operand:DI 1 "register_operand" "=S")
16206 (plus:DI (match_dup 3)
16207 (const_int 4)))
16208 (use (reg:SI 19))]
16209 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16210 "{movsl|movsd}"
16211 [(set_attr "type" "str")
16212 (set_attr "mode" "SI")
16213 (set_attr "memory" "both")])
16214
16215 (define_insn "*strmovhi_1"
16216 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16217 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16218 (set (match_operand:SI 0 "register_operand" "=D")
16219 (plus:SI (match_dup 2)
16220 (const_int 2)))
16221 (set (match_operand:SI 1 "register_operand" "=S")
16222 (plus:SI (match_dup 3)
16223 (const_int 2)))
16224 (use (reg:SI 19))]
16225 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16226 "movsw"
16227 [(set_attr "type" "str")
16228 (set_attr "memory" "both")
16229 (set_attr "mode" "HI")])
16230
16231 (define_insn "*strmovhi_rex_1"
16232 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16233 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16234 (set (match_operand:DI 0 "register_operand" "=D")
16235 (plus:DI (match_dup 2)
16236 (const_int 2)))
16237 (set (match_operand:DI 1 "register_operand" "=S")
16238 (plus:DI (match_dup 3)
16239 (const_int 2)))
16240 (use (reg:SI 19))]
16241 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16242 "movsw"
16243 [(set_attr "type" "str")
16244 (set_attr "memory" "both")
16245 (set_attr "mode" "HI")])
16246
16247 (define_insn "*strmovqi_1"
16248 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16249 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16250 (set (match_operand:SI 0 "register_operand" "=D")
16251 (plus:SI (match_dup 2)
16252 (const_int 1)))
16253 (set (match_operand:SI 1 "register_operand" "=S")
16254 (plus:SI (match_dup 3)
16255 (const_int 1)))
16256 (use (reg:SI 19))]
16257 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16258 "movsb"
16259 [(set_attr "type" "str")
16260 (set_attr "memory" "both")
16261 (set_attr "mode" "QI")])
16262
16263 (define_insn "*strmovqi_rex_1"
16264 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16265 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16266 (set (match_operand:DI 0 "register_operand" "=D")
16267 (plus:DI (match_dup 2)
16268 (const_int 1)))
16269 (set (match_operand:DI 1 "register_operand" "=S")
16270 (plus:DI (match_dup 3)
16271 (const_int 1)))
16272 (use (reg:SI 19))]
16273 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16274 "movsb"
16275 [(set_attr "type" "str")
16276 (set_attr "memory" "both")
16277 (set_attr "mode" "QI")])
16278
16279 (define_expand "rep_mov"
16280 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16281 (set (match_operand 0 "register_operand" "")
16282 (match_operand 5 "" ""))
16283 (set (match_operand 2 "register_operand" "")
16284 (match_operand 6 "" ""))
16285 (set (match_operand 1 "memory_operand" "")
16286 (match_operand 3 "memory_operand" ""))
16287 (use (match_dup 4))
16288 (use (reg:SI 19))])]
16289 ""
16290 "")
16291
16292 (define_insn "*rep_movdi_rex64"
16293 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16294 (set (match_operand:DI 0 "register_operand" "=D")
16295 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16296 (const_int 3))
16297 (match_operand:DI 3 "register_operand" "0")))
16298 (set (match_operand:DI 1 "register_operand" "=S")
16299 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16300 (match_operand:DI 4 "register_operand" "1")))
16301 (set (mem:BLK (match_dup 3))
16302 (mem:BLK (match_dup 4)))
16303 (use (match_dup 5))
16304 (use (reg:SI 19))]
16305 "TARGET_64BIT"
16306 "{rep\;movsq|rep movsq}"
16307 [(set_attr "type" "str")
16308 (set_attr "prefix_rep" "1")
16309 (set_attr "memory" "both")
16310 (set_attr "mode" "DI")])
16311
16312 (define_insn "*rep_movsi"
16313 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16314 (set (match_operand:SI 0 "register_operand" "=D")
16315 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16316 (const_int 2))
16317 (match_operand:SI 3 "register_operand" "0")))
16318 (set (match_operand:SI 1 "register_operand" "=S")
16319 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16320 (match_operand:SI 4 "register_operand" "1")))
16321 (set (mem:BLK (match_dup 3))
16322 (mem:BLK (match_dup 4)))
16323 (use (match_dup 5))
16324 (use (reg:SI 19))]
16325 "!TARGET_64BIT"
16326 "{rep\;movsl|rep movsd}"
16327 [(set_attr "type" "str")
16328 (set_attr "prefix_rep" "1")
16329 (set_attr "memory" "both")
16330 (set_attr "mode" "SI")])
16331
16332 (define_insn "*rep_movsi_rex64"
16333 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16334 (set (match_operand:DI 0 "register_operand" "=D")
16335 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16336 (const_int 2))
16337 (match_operand:DI 3 "register_operand" "0")))
16338 (set (match_operand:DI 1 "register_operand" "=S")
16339 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16340 (match_operand:DI 4 "register_operand" "1")))
16341 (set (mem:BLK (match_dup 3))
16342 (mem:BLK (match_dup 4)))
16343 (use (match_dup 5))
16344 (use (reg:SI 19))]
16345 "TARGET_64BIT"
16346 "{rep\;movsl|rep movsd}"
16347 [(set_attr "type" "str")
16348 (set_attr "prefix_rep" "1")
16349 (set_attr "memory" "both")
16350 (set_attr "mode" "SI")])
16351
16352 (define_insn "*rep_movqi"
16353 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16354 (set (match_operand:SI 0 "register_operand" "=D")
16355 (plus:SI (match_operand:SI 3 "register_operand" "0")
16356 (match_operand:SI 5 "register_operand" "2")))
16357 (set (match_operand:SI 1 "register_operand" "=S")
16358 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16359 (set (mem:BLK (match_dup 3))
16360 (mem:BLK (match_dup 4)))
16361 (use (match_dup 5))
16362 (use (reg:SI 19))]
16363 "!TARGET_64BIT"
16364 "{rep\;movsb|rep movsb}"
16365 [(set_attr "type" "str")
16366 (set_attr "prefix_rep" "1")
16367 (set_attr "memory" "both")
16368 (set_attr "mode" "SI")])
16369
16370 (define_insn "*rep_movqi_rex64"
16371 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16372 (set (match_operand:DI 0 "register_operand" "=D")
16373 (plus:DI (match_operand:DI 3 "register_operand" "0")
16374 (match_operand:DI 5 "register_operand" "2")))
16375 (set (match_operand:DI 1 "register_operand" "=S")
16376 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16377 (set (mem:BLK (match_dup 3))
16378 (mem:BLK (match_dup 4)))
16379 (use (match_dup 5))
16380 (use (reg:SI 19))]
16381 "TARGET_64BIT"
16382 "{rep\;movsb|rep movsb}"
16383 [(set_attr "type" "str")
16384 (set_attr "prefix_rep" "1")
16385 (set_attr "memory" "both")
16386 (set_attr "mode" "SI")])
16387
16388 (define_expand "clrstrsi"
16389 [(use (match_operand:BLK 0 "memory_operand" ""))
16390 (use (match_operand:SI 1 "nonmemory_operand" ""))
16391 (use (match_operand 2 "const_int_operand" ""))]
16392 ""
16393 {
16394 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16395 DONE;
16396 else
16397 FAIL;
16398 })
16399
16400 (define_expand "clrstrdi"
16401 [(use (match_operand:BLK 0 "memory_operand" ""))
16402 (use (match_operand:DI 1 "nonmemory_operand" ""))
16403 (use (match_operand 2 "const_int_operand" ""))]
16404 "TARGET_64BIT"
16405 {
16406 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16407 DONE;
16408 else
16409 FAIL;
16410 })
16411
16412 ;; Most CPUs don't like single string operations
16413 ;; Handle this case here to simplify previous expander.
16414
16415 (define_expand "strset"
16416 [(set (match_operand 1 "memory_operand" "")
16417 (match_operand 2 "register_operand" ""))
16418 (parallel [(set (match_operand 0 "register_operand" "")
16419 (match_dup 3))
16420 (clobber (reg:CC 17))])]
16421 ""
16422 {
16423 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16424 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16425
16426 /* If .md ever supports :P for Pmode, this can be directly
16427 in the pattern above. */
16428 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16429 GEN_INT (GET_MODE_SIZE (GET_MODE
16430 (operands[2]))));
16431 if (TARGET_SINGLE_STRINGOP || optimize_size)
16432 {
16433 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16434 operands[3]));
16435 DONE;
16436 }
16437 })
16438
16439 (define_expand "strset_singleop"
16440 [(parallel [(set (match_operand 1 "memory_operand" "")
16441 (match_operand 2 "register_operand" ""))
16442 (set (match_operand 0 "register_operand" "")
16443 (match_operand 3 "" ""))
16444 (use (reg:SI 19))])]
16445 "TARGET_SINGLE_STRINGOP || optimize_size"
16446 "")
16447
16448 (define_insn "*strsetdi_rex_1"
16449 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16450 (match_operand:SI 2 "register_operand" "a"))
16451 (set (match_operand:DI 0 "register_operand" "=D")
16452 (plus:DI (match_dup 1)
16453 (const_int 8)))
16454 (use (reg:SI 19))]
16455 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16456 "stosq"
16457 [(set_attr "type" "str")
16458 (set_attr "memory" "store")
16459 (set_attr "mode" "DI")])
16460
16461 (define_insn "*strsetsi_1"
16462 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16463 (match_operand:SI 2 "register_operand" "a"))
16464 (set (match_operand:SI 0 "register_operand" "=D")
16465 (plus:SI (match_dup 1)
16466 (const_int 4)))
16467 (use (reg:SI 19))]
16468 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16469 "{stosl|stosd}"
16470 [(set_attr "type" "str")
16471 (set_attr "memory" "store")
16472 (set_attr "mode" "SI")])
16473
16474 (define_insn "*strsetsi_rex_1"
16475 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16476 (match_operand:SI 2 "register_operand" "a"))
16477 (set (match_operand:DI 0 "register_operand" "=D")
16478 (plus:DI (match_dup 1)
16479 (const_int 4)))
16480 (use (reg:SI 19))]
16481 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16482 "{stosl|stosd}"
16483 [(set_attr "type" "str")
16484 (set_attr "memory" "store")
16485 (set_attr "mode" "SI")])
16486
16487 (define_insn "*strsethi_1"
16488 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16489 (match_operand:HI 2 "register_operand" "a"))
16490 (set (match_operand:SI 0 "register_operand" "=D")
16491 (plus:SI (match_dup 1)
16492 (const_int 2)))
16493 (use (reg:SI 19))]
16494 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16495 "stosw"
16496 [(set_attr "type" "str")
16497 (set_attr "memory" "store")
16498 (set_attr "mode" "HI")])
16499
16500 (define_insn "*strsethi_rex_1"
16501 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16502 (match_operand:HI 2 "register_operand" "a"))
16503 (set (match_operand:DI 0 "register_operand" "=D")
16504 (plus:DI (match_dup 1)
16505 (const_int 2)))
16506 (use (reg:SI 19))]
16507 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16508 "stosw"
16509 [(set_attr "type" "str")
16510 (set_attr "memory" "store")
16511 (set_attr "mode" "HI")])
16512
16513 (define_insn "*strsetqi_1"
16514 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16515 (match_operand:QI 2 "register_operand" "a"))
16516 (set (match_operand:SI 0 "register_operand" "=D")
16517 (plus:SI (match_dup 1)
16518 (const_int 1)))
16519 (use (reg:SI 19))]
16520 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16521 "stosb"
16522 [(set_attr "type" "str")
16523 (set_attr "memory" "store")
16524 (set_attr "mode" "QI")])
16525
16526 (define_insn "*strsetqi_rex_1"
16527 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16528 (match_operand:QI 2 "register_operand" "a"))
16529 (set (match_operand:DI 0 "register_operand" "=D")
16530 (plus:DI (match_dup 1)
16531 (const_int 1)))
16532 (use (reg:SI 19))]
16533 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16534 "stosb"
16535 [(set_attr "type" "str")
16536 (set_attr "memory" "store")
16537 (set_attr "mode" "QI")])
16538
16539 (define_expand "rep_stos"
16540 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16541 (set (match_operand 0 "register_operand" "")
16542 (match_operand 4 "" ""))
16543 (set (match_operand 2 "memory_operand" "") (const_int 0))
16544 (use (match_operand 3 "register_operand" ""))
16545 (use (match_dup 1))
16546 (use (reg:SI 19))])]
16547 ""
16548 "")
16549
16550 (define_insn "*rep_stosdi_rex64"
16551 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16552 (set (match_operand:DI 0 "register_operand" "=D")
16553 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16554 (const_int 3))
16555 (match_operand:DI 3 "register_operand" "0")))
16556 (set (mem:BLK (match_dup 3))
16557 (const_int 0))
16558 (use (match_operand:DI 2 "register_operand" "a"))
16559 (use (match_dup 4))
16560 (use (reg:SI 19))]
16561 "TARGET_64BIT"
16562 "{rep\;stosq|rep stosq}"
16563 [(set_attr "type" "str")
16564 (set_attr "prefix_rep" "1")
16565 (set_attr "memory" "store")
16566 (set_attr "mode" "DI")])
16567
16568 (define_insn "*rep_stossi"
16569 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16570 (set (match_operand:SI 0 "register_operand" "=D")
16571 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16572 (const_int 2))
16573 (match_operand:SI 3 "register_operand" "0")))
16574 (set (mem:BLK (match_dup 3))
16575 (const_int 0))
16576 (use (match_operand:SI 2 "register_operand" "a"))
16577 (use (match_dup 4))
16578 (use (reg:SI 19))]
16579 "!TARGET_64BIT"
16580 "{rep\;stosl|rep stosd}"
16581 [(set_attr "type" "str")
16582 (set_attr "prefix_rep" "1")
16583 (set_attr "memory" "store")
16584 (set_attr "mode" "SI")])
16585
16586 (define_insn "*rep_stossi_rex64"
16587 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16588 (set (match_operand:DI 0 "register_operand" "=D")
16589 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16590 (const_int 2))
16591 (match_operand:DI 3 "register_operand" "0")))
16592 (set (mem:BLK (match_dup 3))
16593 (const_int 0))
16594 (use (match_operand:SI 2 "register_operand" "a"))
16595 (use (match_dup 4))
16596 (use (reg:SI 19))]
16597 "TARGET_64BIT"
16598 "{rep\;stosl|rep stosd}"
16599 [(set_attr "type" "str")
16600 (set_attr "prefix_rep" "1")
16601 (set_attr "memory" "store")
16602 (set_attr "mode" "SI")])
16603
16604 (define_insn "*rep_stosqi"
16605 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16606 (set (match_operand:SI 0 "register_operand" "=D")
16607 (plus:SI (match_operand:SI 3 "register_operand" "0")
16608 (match_operand:SI 4 "register_operand" "1")))
16609 (set (mem:BLK (match_dup 3))
16610 (const_int 0))
16611 (use (match_operand:QI 2 "register_operand" "a"))
16612 (use (match_dup 4))
16613 (use (reg:SI 19))]
16614 "!TARGET_64BIT"
16615 "{rep\;stosb|rep stosb}"
16616 [(set_attr "type" "str")
16617 (set_attr "prefix_rep" "1")
16618 (set_attr "memory" "store")
16619 (set_attr "mode" "QI")])
16620
16621 (define_insn "*rep_stosqi_rex64"
16622 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16623 (set (match_operand:DI 0 "register_operand" "=D")
16624 (plus:DI (match_operand:DI 3 "register_operand" "0")
16625 (match_operand:DI 4 "register_operand" "1")))
16626 (set (mem:BLK (match_dup 3))
16627 (const_int 0))
16628 (use (match_operand:QI 2 "register_operand" "a"))
16629 (use (match_dup 4))
16630 (use (reg:SI 19))]
16631 "TARGET_64BIT"
16632 "{rep\;stosb|rep stosb}"
16633 [(set_attr "type" "str")
16634 (set_attr "prefix_rep" "1")
16635 (set_attr "memory" "store")
16636 (set_attr "mode" "QI")])
16637
16638 (define_expand "cmpstrsi"
16639 [(set (match_operand:SI 0 "register_operand" "")
16640 (compare:SI (match_operand:BLK 1 "general_operand" "")
16641 (match_operand:BLK 2 "general_operand" "")))
16642 (use (match_operand 3 "general_operand" ""))
16643 (use (match_operand 4 "immediate_operand" ""))]
16644 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16645 {
16646 rtx addr1, addr2, out, outlow, count, countreg, align;
16647
16648 /* Can't use this if the user has appropriated esi or edi. */
16649 if (global_regs[4] || global_regs[5])
16650 FAIL;
16651
16652 out = operands[0];
16653 if (GET_CODE (out) != REG)
16654 out = gen_reg_rtx (SImode);
16655
16656 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16657 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16658 if (addr1 != XEXP (operands[1], 0))
16659 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16660 if (addr2 != XEXP (operands[2], 0))
16661 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16662
16663 count = operands[3];
16664 countreg = ix86_zero_extend_to_Pmode (count);
16665
16666 /* %%% Iff we are testing strict equality, we can use known alignment
16667 to good advantage. This may be possible with combine, particularly
16668 once cc0 is dead. */
16669 align = operands[4];
16670
16671 emit_insn (gen_cld ());
16672 if (GET_CODE (count) == CONST_INT)
16673 {
16674 if (INTVAL (count) == 0)
16675 {
16676 emit_move_insn (operands[0], const0_rtx);
16677 DONE;
16678 }
16679 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16680 operands[1], operands[2]));
16681 }
16682 else
16683 {
16684 if (TARGET_64BIT)
16685 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16686 else
16687 emit_insn (gen_cmpsi_1 (countreg, countreg));
16688 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16689 operands[1], operands[2]));
16690 }
16691
16692 outlow = gen_lowpart (QImode, out);
16693 emit_insn (gen_cmpintqi (outlow));
16694 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16695
16696 if (operands[0] != out)
16697 emit_move_insn (operands[0], out);
16698
16699 DONE;
16700 })
16701
16702 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16703
16704 (define_expand "cmpintqi"
16705 [(set (match_dup 1)
16706 (gtu:QI (reg:CC 17) (const_int 0)))
16707 (set (match_dup 2)
16708 (ltu:QI (reg:CC 17) (const_int 0)))
16709 (parallel [(set (match_operand:QI 0 "register_operand" "")
16710 (minus:QI (match_dup 1)
16711 (match_dup 2)))
16712 (clobber (reg:CC 17))])]
16713 ""
16714 "operands[1] = gen_reg_rtx (QImode);
16715 operands[2] = gen_reg_rtx (QImode);")
16716
16717 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16718 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16719
16720 (define_expand "cmpstrqi_nz_1"
16721 [(parallel [(set (reg:CC 17)
16722 (compare:CC (match_operand 4 "memory_operand" "")
16723 (match_operand 5 "memory_operand" "")))
16724 (use (match_operand 2 "register_operand" ""))
16725 (use (match_operand:SI 3 "immediate_operand" ""))
16726 (use (reg:SI 19))
16727 (clobber (match_operand 0 "register_operand" ""))
16728 (clobber (match_operand 1 "register_operand" ""))
16729 (clobber (match_dup 2))])]
16730 ""
16731 "")
16732
16733 (define_insn "*cmpstrqi_nz_1"
16734 [(set (reg:CC 17)
16735 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16736 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16737 (use (match_operand:SI 6 "register_operand" "2"))
16738 (use (match_operand:SI 3 "immediate_operand" "i"))
16739 (use (reg:SI 19))
16740 (clobber (match_operand:SI 0 "register_operand" "=S"))
16741 (clobber (match_operand:SI 1 "register_operand" "=D"))
16742 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16743 "!TARGET_64BIT"
16744 "repz{\;| }cmpsb"
16745 [(set_attr "type" "str")
16746 (set_attr "mode" "QI")
16747 (set_attr "prefix_rep" "1")])
16748
16749 (define_insn "*cmpstrqi_nz_rex_1"
16750 [(set (reg:CC 17)
16751 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16752 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16753 (use (match_operand:DI 6 "register_operand" "2"))
16754 (use (match_operand:SI 3 "immediate_operand" "i"))
16755 (use (reg:SI 19))
16756 (clobber (match_operand:DI 0 "register_operand" "=S"))
16757 (clobber (match_operand:DI 1 "register_operand" "=D"))
16758 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16759 "TARGET_64BIT"
16760 "repz{\;| }cmpsb"
16761 [(set_attr "type" "str")
16762 (set_attr "mode" "QI")
16763 (set_attr "prefix_rep" "1")])
16764
16765 ;; The same, but the count is not known to not be zero.
16766
16767 (define_expand "cmpstrqi_1"
16768 [(parallel [(set (reg:CC 17)
16769 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16770 (const_int 0))
16771 (compare:CC (match_operand 4 "memory_operand" "")
16772 (match_operand 5 "memory_operand" ""))
16773 (const_int 0)))
16774 (use (match_operand:SI 3 "immediate_operand" ""))
16775 (use (reg:CC 17))
16776 (use (reg:SI 19))
16777 (clobber (match_operand 0 "register_operand" ""))
16778 (clobber (match_operand 1 "register_operand" ""))
16779 (clobber (match_dup 2))])]
16780 ""
16781 "")
16782
16783 (define_insn "*cmpstrqi_1"
16784 [(set (reg:CC 17)
16785 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16786 (const_int 0))
16787 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16788 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16789 (const_int 0)))
16790 (use (match_operand:SI 3 "immediate_operand" "i"))
16791 (use (reg:CC 17))
16792 (use (reg:SI 19))
16793 (clobber (match_operand:SI 0 "register_operand" "=S"))
16794 (clobber (match_operand:SI 1 "register_operand" "=D"))
16795 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16796 "!TARGET_64BIT"
16797 "repz{\;| }cmpsb"
16798 [(set_attr "type" "str")
16799 (set_attr "mode" "QI")
16800 (set_attr "prefix_rep" "1")])
16801
16802 (define_insn "*cmpstrqi_rex_1"
16803 [(set (reg:CC 17)
16804 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16805 (const_int 0))
16806 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16807 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16808 (const_int 0)))
16809 (use (match_operand:SI 3 "immediate_operand" "i"))
16810 (use (reg:CC 17))
16811 (use (reg:SI 19))
16812 (clobber (match_operand:DI 0 "register_operand" "=S"))
16813 (clobber (match_operand:DI 1 "register_operand" "=D"))
16814 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16815 "TARGET_64BIT"
16816 "repz{\;| }cmpsb"
16817 [(set_attr "type" "str")
16818 (set_attr "mode" "QI")
16819 (set_attr "prefix_rep" "1")])
16820
16821 (define_expand "strlensi"
16822 [(set (match_operand:SI 0 "register_operand" "")
16823 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16824 (match_operand:QI 2 "immediate_operand" "")
16825 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16826 ""
16827 {
16828 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16829 DONE;
16830 else
16831 FAIL;
16832 })
16833
16834 (define_expand "strlendi"
16835 [(set (match_operand:DI 0 "register_operand" "")
16836 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16837 (match_operand:QI 2 "immediate_operand" "")
16838 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16839 ""
16840 {
16841 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16842 DONE;
16843 else
16844 FAIL;
16845 })
16846
16847 (define_expand "strlenqi_1"
16848 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16849 (use (reg:SI 19))
16850 (clobber (match_operand 1 "register_operand" ""))
16851 (clobber (reg:CC 17))])]
16852 ""
16853 "")
16854
16855 (define_insn "*strlenqi_1"
16856 [(set (match_operand:SI 0 "register_operand" "=&c")
16857 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16858 (match_operand:QI 2 "register_operand" "a")
16859 (match_operand:SI 3 "immediate_operand" "i")
16860 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16861 (use (reg:SI 19))
16862 (clobber (match_operand:SI 1 "register_operand" "=D"))
16863 (clobber (reg:CC 17))]
16864 "!TARGET_64BIT"
16865 "repnz{\;| }scasb"
16866 [(set_attr "type" "str")
16867 (set_attr "mode" "QI")
16868 (set_attr "prefix_rep" "1")])
16869
16870 (define_insn "*strlenqi_rex_1"
16871 [(set (match_operand:DI 0 "register_operand" "=&c")
16872 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16873 (match_operand:QI 2 "register_operand" "a")
16874 (match_operand:DI 3 "immediate_operand" "i")
16875 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16876 (use (reg:SI 19))
16877 (clobber (match_operand:DI 1 "register_operand" "=D"))
16878 (clobber (reg:CC 17))]
16879 "TARGET_64BIT"
16880 "repnz{\;| }scasb"
16881 [(set_attr "type" "str")
16882 (set_attr "mode" "QI")
16883 (set_attr "prefix_rep" "1")])
16884
16885 ;; Peephole optimizations to clean up after cmpstr*. This should be
16886 ;; handled in combine, but it is not currently up to the task.
16887 ;; When used for their truth value, the cmpstr* expanders generate
16888 ;; code like this:
16889 ;;
16890 ;; repz cmpsb
16891 ;; seta %al
16892 ;; setb %dl
16893 ;; cmpb %al, %dl
16894 ;; jcc label
16895 ;;
16896 ;; The intermediate three instructions are unnecessary.
16897
16898 ;; This one handles cmpstr*_nz_1...
16899 (define_peephole2
16900 [(parallel[
16901 (set (reg:CC 17)
16902 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16903 (mem:BLK (match_operand 5 "register_operand" ""))))
16904 (use (match_operand 6 "register_operand" ""))
16905 (use (match_operand:SI 3 "immediate_operand" ""))
16906 (use (reg:SI 19))
16907 (clobber (match_operand 0 "register_operand" ""))
16908 (clobber (match_operand 1 "register_operand" ""))
16909 (clobber (match_operand 2 "register_operand" ""))])
16910 (set (match_operand:QI 7 "register_operand" "")
16911 (gtu:QI (reg:CC 17) (const_int 0)))
16912 (set (match_operand:QI 8 "register_operand" "")
16913 (ltu:QI (reg:CC 17) (const_int 0)))
16914 (set (reg 17)
16915 (compare (match_dup 7) (match_dup 8)))
16916 ]
16917 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16918 [(parallel[
16919 (set (reg:CC 17)
16920 (compare:CC (mem:BLK (match_dup 4))
16921 (mem:BLK (match_dup 5))))
16922 (use (match_dup 6))
16923 (use (match_dup 3))
16924 (use (reg:SI 19))
16925 (clobber (match_dup 0))
16926 (clobber (match_dup 1))
16927 (clobber (match_dup 2))])]
16928 "")
16929
16930 ;; ...and this one handles cmpstr*_1.
16931 (define_peephole2
16932 [(parallel[
16933 (set (reg:CC 17)
16934 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16935 (const_int 0))
16936 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16937 (mem:BLK (match_operand 5 "register_operand" "")))
16938 (const_int 0)))
16939 (use (match_operand:SI 3 "immediate_operand" ""))
16940 (use (reg:CC 17))
16941 (use (reg:SI 19))
16942 (clobber (match_operand 0 "register_operand" ""))
16943 (clobber (match_operand 1 "register_operand" ""))
16944 (clobber (match_operand 2 "register_operand" ""))])
16945 (set (match_operand:QI 7 "register_operand" "")
16946 (gtu:QI (reg:CC 17) (const_int 0)))
16947 (set (match_operand:QI 8 "register_operand" "")
16948 (ltu:QI (reg:CC 17) (const_int 0)))
16949 (set (reg 17)
16950 (compare (match_dup 7) (match_dup 8)))
16951 ]
16952 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16953 [(parallel[
16954 (set (reg:CC 17)
16955 (if_then_else:CC (ne (match_dup 6)
16956 (const_int 0))
16957 (compare:CC (mem:BLK (match_dup 4))
16958 (mem:BLK (match_dup 5)))
16959 (const_int 0)))
16960 (use (match_dup 3))
16961 (use (reg:CC 17))
16962 (use (reg:SI 19))
16963 (clobber (match_dup 0))
16964 (clobber (match_dup 1))
16965 (clobber (match_dup 2))])]
16966 "")
16967
16968
16969 \f
16970 ;; Conditional move instructions.
16971
16972 (define_expand "movdicc"
16973 [(set (match_operand:DI 0 "register_operand" "")
16974 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16975 (match_operand:DI 2 "general_operand" "")
16976 (match_operand:DI 3 "general_operand" "")))]
16977 "TARGET_64BIT"
16978 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16979
16980 (define_insn "x86_movdicc_0_m1_rex64"
16981 [(set (match_operand:DI 0 "register_operand" "=r")
16982 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16983 (const_int -1)
16984 (const_int 0)))
16985 (clobber (reg:CC 17))]
16986 "TARGET_64BIT"
16987 "sbb{q}\t%0, %0"
16988 ; Since we don't have the proper number of operands for an alu insn,
16989 ; fill in all the blanks.
16990 [(set_attr "type" "alu")
16991 (set_attr "pent_pair" "pu")
16992 (set_attr "memory" "none")
16993 (set_attr "imm_disp" "false")
16994 (set_attr "mode" "DI")
16995 (set_attr "length_immediate" "0")])
16996
16997 (define_insn "movdicc_c_rex64"
16998 [(set (match_operand:DI 0 "register_operand" "=r,r")
16999 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17000 [(reg 17) (const_int 0)])
17001 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17002 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17003 "TARGET_64BIT && TARGET_CMOVE
17004 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17005 "@
17006 cmov%O2%C1\t{%2, %0|%0, %2}
17007 cmov%O2%c1\t{%3, %0|%0, %3}"
17008 [(set_attr "type" "icmov")
17009 (set_attr "mode" "DI")])
17010
17011 (define_expand "movsicc"
17012 [(set (match_operand:SI 0 "register_operand" "")
17013 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17014 (match_operand:SI 2 "general_operand" "")
17015 (match_operand:SI 3 "general_operand" "")))]
17016 ""
17017 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17018
17019 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17020 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17021 ;; So just document what we're doing explicitly.
17022
17023 (define_insn "x86_movsicc_0_m1"
17024 [(set (match_operand:SI 0 "register_operand" "=r")
17025 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17026 (const_int -1)
17027 (const_int 0)))
17028 (clobber (reg:CC 17))]
17029 ""
17030 "sbb{l}\t%0, %0"
17031 ; Since we don't have the proper number of operands for an alu insn,
17032 ; fill in all the blanks.
17033 [(set_attr "type" "alu")
17034 (set_attr "pent_pair" "pu")
17035 (set_attr "memory" "none")
17036 (set_attr "imm_disp" "false")
17037 (set_attr "mode" "SI")
17038 (set_attr "length_immediate" "0")])
17039
17040 (define_insn "*movsicc_noc"
17041 [(set (match_operand:SI 0 "register_operand" "=r,r")
17042 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17043 [(reg 17) (const_int 0)])
17044 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17045 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17046 "TARGET_CMOVE
17047 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17048 "@
17049 cmov%O2%C1\t{%2, %0|%0, %2}
17050 cmov%O2%c1\t{%3, %0|%0, %3}"
17051 [(set_attr "type" "icmov")
17052 (set_attr "mode" "SI")])
17053
17054 (define_expand "movhicc"
17055 [(set (match_operand:HI 0 "register_operand" "")
17056 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17057 (match_operand:HI 2 "general_operand" "")
17058 (match_operand:HI 3 "general_operand" "")))]
17059 "TARGET_HIMODE_MATH"
17060 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17061
17062 (define_insn "*movhicc_noc"
17063 [(set (match_operand:HI 0 "register_operand" "=r,r")
17064 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17065 [(reg 17) (const_int 0)])
17066 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17067 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17068 "TARGET_CMOVE
17069 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17070 "@
17071 cmov%O2%C1\t{%2, %0|%0, %2}
17072 cmov%O2%c1\t{%3, %0|%0, %3}"
17073 [(set_attr "type" "icmov")
17074 (set_attr "mode" "HI")])
17075
17076 (define_expand "movqicc"
17077 [(set (match_operand:QI 0 "register_operand" "")
17078 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17079 (match_operand:QI 2 "general_operand" "")
17080 (match_operand:QI 3 "general_operand" "")))]
17081 "TARGET_QIMODE_MATH"
17082 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17083
17084 (define_insn_and_split "*movqicc_noc"
17085 [(set (match_operand:QI 0 "register_operand" "=r,r")
17086 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17087 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17088 (match_operand:QI 2 "register_operand" "r,0")
17089 (match_operand:QI 3 "register_operand" "0,r")))]
17090 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17091 "#"
17092 "&& reload_completed"
17093 [(set (match_dup 0)
17094 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17095 (match_dup 2)
17096 (match_dup 3)))]
17097 "operands[0] = gen_lowpart (SImode, operands[0]);
17098 operands[2] = gen_lowpart (SImode, operands[2]);
17099 operands[3] = gen_lowpart (SImode, operands[3]);"
17100 [(set_attr "type" "icmov")
17101 (set_attr "mode" "SI")])
17102
17103 (define_expand "movsfcc"
17104 [(set (match_operand:SF 0 "register_operand" "")
17105 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17106 (match_operand:SF 2 "register_operand" "")
17107 (match_operand:SF 3 "register_operand" "")))]
17108 "TARGET_CMOVE"
17109 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17110
17111 (define_insn "*movsfcc_1"
17112 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17113 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17114 [(reg 17) (const_int 0)])
17115 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17116 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17117 "TARGET_CMOVE
17118 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17119 "@
17120 fcmov%F1\t{%2, %0|%0, %2}
17121 fcmov%f1\t{%3, %0|%0, %3}
17122 cmov%O2%C1\t{%2, %0|%0, %2}
17123 cmov%O2%c1\t{%3, %0|%0, %3}"
17124 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17125 (set_attr "mode" "SF,SF,SI,SI")])
17126
17127 (define_expand "movdfcc"
17128 [(set (match_operand:DF 0 "register_operand" "")
17129 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17130 (match_operand:DF 2 "register_operand" "")
17131 (match_operand:DF 3 "register_operand" "")))]
17132 "TARGET_CMOVE"
17133 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17134
17135 (define_insn "*movdfcc_1"
17136 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17137 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17138 [(reg 17) (const_int 0)])
17139 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17140 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17141 "!TARGET_64BIT && TARGET_CMOVE
17142 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17143 "@
17144 fcmov%F1\t{%2, %0|%0, %2}
17145 fcmov%f1\t{%3, %0|%0, %3}
17146 #
17147 #"
17148 [(set_attr "type" "fcmov,fcmov,multi,multi")
17149 (set_attr "mode" "DF")])
17150
17151 (define_insn "*movdfcc_1_rex64"
17152 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17153 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17154 [(reg 17) (const_int 0)])
17155 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17156 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17157 "TARGET_64BIT && TARGET_CMOVE
17158 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17159 "@
17160 fcmov%F1\t{%2, %0|%0, %2}
17161 fcmov%f1\t{%3, %0|%0, %3}
17162 cmov%O2%C1\t{%2, %0|%0, %2}
17163 cmov%O2%c1\t{%3, %0|%0, %3}"
17164 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17165 (set_attr "mode" "DF")])
17166
17167 (define_split
17168 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17169 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17170 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17171 (match_operand:DF 2 "nonimmediate_operand" "")
17172 (match_operand:DF 3 "nonimmediate_operand" "")))]
17173 "!TARGET_64BIT && reload_completed"
17174 [(set (match_dup 2)
17175 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17176 (match_dup 5)
17177 (match_dup 7)))
17178 (set (match_dup 3)
17179 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17180 (match_dup 6)
17181 (match_dup 8)))]
17182 "split_di (operands+2, 1, operands+5, operands+6);
17183 split_di (operands+3, 1, operands+7, operands+8);
17184 split_di (operands, 1, operands+2, operands+3);")
17185
17186 (define_expand "movxfcc"
17187 [(set (match_operand:XF 0 "register_operand" "")
17188 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17189 (match_operand:XF 2 "register_operand" "")
17190 (match_operand:XF 3 "register_operand" "")))]
17191 "TARGET_CMOVE"
17192 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17193
17194 (define_insn "*movxfcc_1"
17195 [(set (match_operand:XF 0 "register_operand" "=f,f")
17196 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17197 [(reg 17) (const_int 0)])
17198 (match_operand:XF 2 "register_operand" "f,0")
17199 (match_operand:XF 3 "register_operand" "0,f")))]
17200 "TARGET_CMOVE"
17201 "@
17202 fcmov%F1\t{%2, %0|%0, %2}
17203 fcmov%f1\t{%3, %0|%0, %3}"
17204 [(set_attr "type" "fcmov")
17205 (set_attr "mode" "XF")])
17206
17207 (define_expand "minsf3"
17208 [(parallel [
17209 (set (match_operand:SF 0 "register_operand" "")
17210 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17211 (match_operand:SF 2 "nonimmediate_operand" ""))
17212 (match_dup 1)
17213 (match_dup 2)))
17214 (clobber (reg:CC 17))])]
17215 "TARGET_SSE"
17216 "")
17217
17218 (define_insn "*minsf"
17219 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17220 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17221 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17222 (match_dup 1)
17223 (match_dup 2)))
17224 (clobber (reg:CC 17))]
17225 "TARGET_SSE && TARGET_IEEE_FP"
17226 "#")
17227
17228 (define_insn "*minsf_nonieee"
17229 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17230 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17231 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17232 (match_dup 1)
17233 (match_dup 2)))
17234 (clobber (reg:CC 17))]
17235 "TARGET_SSE && !TARGET_IEEE_FP
17236 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17237 "#")
17238
17239 (define_split
17240 [(set (match_operand:SF 0 "register_operand" "")
17241 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17242 (match_operand:SF 2 "nonimmediate_operand" ""))
17243 (match_operand:SF 3 "register_operand" "")
17244 (match_operand:SF 4 "nonimmediate_operand" "")))
17245 (clobber (reg:CC 17))]
17246 "SSE_REG_P (operands[0]) && reload_completed
17247 && ((operands_match_p (operands[1], operands[3])
17248 && operands_match_p (operands[2], operands[4]))
17249 || (operands_match_p (operands[1], operands[4])
17250 && operands_match_p (operands[2], operands[3])))"
17251 [(set (match_dup 0)
17252 (if_then_else:SF (lt (match_dup 1)
17253 (match_dup 2))
17254 (match_dup 1)
17255 (match_dup 2)))])
17256
17257 ;; Conditional addition patterns
17258 (define_expand "addqicc"
17259 [(match_operand:QI 0 "register_operand" "")
17260 (match_operand 1 "comparison_operator" "")
17261 (match_operand:QI 2 "register_operand" "")
17262 (match_operand:QI 3 "const_int_operand" "")]
17263 ""
17264 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17265
17266 (define_expand "addhicc"
17267 [(match_operand:HI 0 "register_operand" "")
17268 (match_operand 1 "comparison_operator" "")
17269 (match_operand:HI 2 "register_operand" "")
17270 (match_operand:HI 3 "const_int_operand" "")]
17271 ""
17272 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17273
17274 (define_expand "addsicc"
17275 [(match_operand:SI 0 "register_operand" "")
17276 (match_operand 1 "comparison_operator" "")
17277 (match_operand:SI 2 "register_operand" "")
17278 (match_operand:SI 3 "const_int_operand" "")]
17279 ""
17280 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17281
17282 (define_expand "adddicc"
17283 [(match_operand:DI 0 "register_operand" "")
17284 (match_operand 1 "comparison_operator" "")
17285 (match_operand:DI 2 "register_operand" "")
17286 (match_operand:DI 3 "const_int_operand" "")]
17287 "TARGET_64BIT"
17288 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17289
17290 ;; We can't represent the LT test directly. Do this by swapping the operands.
17291
17292 (define_split
17293 [(set (match_operand:SF 0 "fp_register_operand" "")
17294 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17295 (match_operand:SF 2 "register_operand" ""))
17296 (match_operand:SF 3 "register_operand" "")
17297 (match_operand:SF 4 "register_operand" "")))
17298 (clobber (reg:CC 17))]
17299 "reload_completed
17300 && ((operands_match_p (operands[1], operands[3])
17301 && operands_match_p (operands[2], operands[4]))
17302 || (operands_match_p (operands[1], operands[4])
17303 && operands_match_p (operands[2], operands[3])))"
17304 [(set (reg:CCFP 17)
17305 (compare:CCFP (match_dup 2)
17306 (match_dup 1)))
17307 (set (match_dup 0)
17308 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17309 (match_dup 1)
17310 (match_dup 2)))])
17311
17312 (define_insn "*minsf_sse"
17313 [(set (match_operand:SF 0 "register_operand" "=x")
17314 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17315 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17316 (match_dup 1)
17317 (match_dup 2)))]
17318 "TARGET_SSE && reload_completed"
17319 "minss\t{%2, %0|%0, %2}"
17320 [(set_attr "type" "sse")
17321 (set_attr "mode" "SF")])
17322
17323 (define_expand "mindf3"
17324 [(parallel [
17325 (set (match_operand:DF 0 "register_operand" "")
17326 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17327 (match_operand:DF 2 "nonimmediate_operand" ""))
17328 (match_dup 1)
17329 (match_dup 2)))
17330 (clobber (reg:CC 17))])]
17331 "TARGET_SSE2 && TARGET_SSE_MATH"
17332 "#")
17333
17334 (define_insn "*mindf"
17335 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17336 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17337 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17338 (match_dup 1)
17339 (match_dup 2)))
17340 (clobber (reg:CC 17))]
17341 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17342 "#")
17343
17344 (define_insn "*mindf_nonieee"
17345 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17346 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17347 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17348 (match_dup 1)
17349 (match_dup 2)))
17350 (clobber (reg:CC 17))]
17351 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17353 "#")
17354
17355 (define_split
17356 [(set (match_operand:DF 0 "register_operand" "")
17357 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17358 (match_operand:DF 2 "nonimmediate_operand" ""))
17359 (match_operand:DF 3 "register_operand" "")
17360 (match_operand:DF 4 "nonimmediate_operand" "")))
17361 (clobber (reg:CC 17))]
17362 "SSE_REG_P (operands[0]) && reload_completed
17363 && ((operands_match_p (operands[1], operands[3])
17364 && operands_match_p (operands[2], operands[4]))
17365 || (operands_match_p (operands[1], operands[4])
17366 && operands_match_p (operands[2], operands[3])))"
17367 [(set (match_dup 0)
17368 (if_then_else:DF (lt (match_dup 1)
17369 (match_dup 2))
17370 (match_dup 1)
17371 (match_dup 2)))])
17372
17373 ;; We can't represent the LT test directly. Do this by swapping the operands.
17374 (define_split
17375 [(set (match_operand:DF 0 "fp_register_operand" "")
17376 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17377 (match_operand:DF 2 "register_operand" ""))
17378 (match_operand:DF 3 "register_operand" "")
17379 (match_operand:DF 4 "register_operand" "")))
17380 (clobber (reg:CC 17))]
17381 "reload_completed
17382 && ((operands_match_p (operands[1], operands[3])
17383 && operands_match_p (operands[2], operands[4]))
17384 || (operands_match_p (operands[1], operands[4])
17385 && operands_match_p (operands[2], operands[3])))"
17386 [(set (reg:CCFP 17)
17387 (compare:CCFP (match_dup 2)
17388 (match_dup 1)))
17389 (set (match_dup 0)
17390 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17391 (match_dup 1)
17392 (match_dup 2)))])
17393
17394 (define_insn "*mindf_sse"
17395 [(set (match_operand:DF 0 "register_operand" "=Y")
17396 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17397 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17398 (match_dup 1)
17399 (match_dup 2)))]
17400 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17401 "minsd\t{%2, %0|%0, %2}"
17402 [(set_attr "type" "sse")
17403 (set_attr "mode" "DF")])
17404
17405 (define_expand "maxsf3"
17406 [(parallel [
17407 (set (match_operand:SF 0 "register_operand" "")
17408 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17409 (match_operand:SF 2 "nonimmediate_operand" ""))
17410 (match_dup 1)
17411 (match_dup 2)))
17412 (clobber (reg:CC 17))])]
17413 "TARGET_SSE"
17414 "#")
17415
17416 (define_insn "*maxsf"
17417 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17418 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17419 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17420 (match_dup 1)
17421 (match_dup 2)))
17422 (clobber (reg:CC 17))]
17423 "TARGET_SSE && TARGET_IEEE_FP"
17424 "#")
17425
17426 (define_insn "*maxsf_nonieee"
17427 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17428 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17429 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17430 (match_dup 1)
17431 (match_dup 2)))
17432 (clobber (reg:CC 17))]
17433 "TARGET_SSE && !TARGET_IEEE_FP
17434 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17435 "#")
17436
17437 (define_split
17438 [(set (match_operand:SF 0 "register_operand" "")
17439 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17440 (match_operand:SF 2 "nonimmediate_operand" ""))
17441 (match_operand:SF 3 "register_operand" "")
17442 (match_operand:SF 4 "nonimmediate_operand" "")))
17443 (clobber (reg:CC 17))]
17444 "SSE_REG_P (operands[0]) && reload_completed
17445 && ((operands_match_p (operands[1], operands[3])
17446 && operands_match_p (operands[2], operands[4]))
17447 || (operands_match_p (operands[1], operands[4])
17448 && operands_match_p (operands[2], operands[3])))"
17449 [(set (match_dup 0)
17450 (if_then_else:SF (gt (match_dup 1)
17451 (match_dup 2))
17452 (match_dup 1)
17453 (match_dup 2)))])
17454
17455 (define_split
17456 [(set (match_operand:SF 0 "fp_register_operand" "")
17457 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17458 (match_operand:SF 2 "register_operand" ""))
17459 (match_operand:SF 3 "register_operand" "")
17460 (match_operand:SF 4 "register_operand" "")))
17461 (clobber (reg:CC 17))]
17462 "reload_completed
17463 && ((operands_match_p (operands[1], operands[3])
17464 && operands_match_p (operands[2], operands[4]))
17465 || (operands_match_p (operands[1], operands[4])
17466 && operands_match_p (operands[2], operands[3])))"
17467 [(set (reg:CCFP 17)
17468 (compare:CCFP (match_dup 1)
17469 (match_dup 2)))
17470 (set (match_dup 0)
17471 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17472 (match_dup 1)
17473 (match_dup 2)))])
17474
17475 (define_insn "*maxsf_sse"
17476 [(set (match_operand:SF 0 "register_operand" "=x")
17477 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17478 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17479 (match_dup 1)
17480 (match_dup 2)))]
17481 "TARGET_SSE && reload_completed"
17482 "maxss\t{%2, %0|%0, %2}"
17483 [(set_attr "type" "sse")
17484 (set_attr "mode" "SF")])
17485
17486 (define_expand "maxdf3"
17487 [(parallel [
17488 (set (match_operand:DF 0 "register_operand" "")
17489 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17490 (match_operand:DF 2 "nonimmediate_operand" ""))
17491 (match_dup 1)
17492 (match_dup 2)))
17493 (clobber (reg:CC 17))])]
17494 "TARGET_SSE2 && TARGET_SSE_MATH"
17495 "#")
17496
17497 (define_insn "*maxdf"
17498 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17499 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17500 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17501 (match_dup 1)
17502 (match_dup 2)))
17503 (clobber (reg:CC 17))]
17504 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17505 "#")
17506
17507 (define_insn "*maxdf_nonieee"
17508 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17509 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17510 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17511 (match_dup 1)
17512 (match_dup 2)))
17513 (clobber (reg:CC 17))]
17514 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17515 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17516 "#")
17517
17518 (define_split
17519 [(set (match_operand:DF 0 "register_operand" "")
17520 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17521 (match_operand:DF 2 "nonimmediate_operand" ""))
17522 (match_operand:DF 3 "register_operand" "")
17523 (match_operand:DF 4 "nonimmediate_operand" "")))
17524 (clobber (reg:CC 17))]
17525 "SSE_REG_P (operands[0]) && reload_completed
17526 && ((operands_match_p (operands[1], operands[3])
17527 && operands_match_p (operands[2], operands[4]))
17528 || (operands_match_p (operands[1], operands[4])
17529 && operands_match_p (operands[2], operands[3])))"
17530 [(set (match_dup 0)
17531 (if_then_else:DF (gt (match_dup 1)
17532 (match_dup 2))
17533 (match_dup 1)
17534 (match_dup 2)))])
17535
17536 (define_split
17537 [(set (match_operand:DF 0 "fp_register_operand" "")
17538 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17539 (match_operand:DF 2 "register_operand" ""))
17540 (match_operand:DF 3 "register_operand" "")
17541 (match_operand:DF 4 "register_operand" "")))
17542 (clobber (reg:CC 17))]
17543 "reload_completed
17544 && ((operands_match_p (operands[1], operands[3])
17545 && operands_match_p (operands[2], operands[4]))
17546 || (operands_match_p (operands[1], operands[4])
17547 && operands_match_p (operands[2], operands[3])))"
17548 [(set (reg:CCFP 17)
17549 (compare:CCFP (match_dup 1)
17550 (match_dup 2)))
17551 (set (match_dup 0)
17552 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17553 (match_dup 1)
17554 (match_dup 2)))])
17555
17556 (define_insn "*maxdf_sse"
17557 [(set (match_operand:DF 0 "register_operand" "=Y")
17558 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17559 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17560 (match_dup 1)
17561 (match_dup 2)))]
17562 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17563 "maxsd\t{%2, %0|%0, %2}"
17564 [(set_attr "type" "sse")
17565 (set_attr "mode" "DF")])
17566 \f
17567 ;; Misc patterns (?)
17568
17569 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17570 ;; Otherwise there will be nothing to keep
17571 ;;
17572 ;; [(set (reg ebp) (reg esp))]
17573 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17574 ;; (clobber (eflags)]
17575 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17576 ;;
17577 ;; in proper program order.
17578 (define_insn "pro_epilogue_adjust_stack_1"
17579 [(set (match_operand:SI 0 "register_operand" "=r,r")
17580 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17581 (match_operand:SI 2 "immediate_operand" "i,i")))
17582 (clobber (reg:CC 17))
17583 (clobber (mem:BLK (scratch)))]
17584 "!TARGET_64BIT"
17585 {
17586 switch (get_attr_type (insn))
17587 {
17588 case TYPE_IMOV:
17589 return "mov{l}\t{%1, %0|%0, %1}";
17590
17591 case TYPE_ALU:
17592 if (GET_CODE (operands[2]) == CONST_INT
17593 && (INTVAL (operands[2]) == 128
17594 || (INTVAL (operands[2]) < 0
17595 && INTVAL (operands[2]) != -128)))
17596 {
17597 operands[2] = GEN_INT (-INTVAL (operands[2]));
17598 return "sub{l}\t{%2, %0|%0, %2}";
17599 }
17600 return "add{l}\t{%2, %0|%0, %2}";
17601
17602 case TYPE_LEA:
17603 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17604 return "lea{l}\t{%a2, %0|%0, %a2}";
17605
17606 default:
17607 abort ();
17608 }
17609 }
17610 [(set (attr "type")
17611 (cond [(eq_attr "alternative" "0")
17612 (const_string "alu")
17613 (match_operand:SI 2 "const0_operand" "")
17614 (const_string "imov")
17615 ]
17616 (const_string "lea")))
17617 (set_attr "mode" "SI")])
17618
17619 (define_insn "pro_epilogue_adjust_stack_rex64"
17620 [(set (match_operand:DI 0 "register_operand" "=r,r")
17621 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17622 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17623 (clobber (reg:CC 17))
17624 (clobber (mem:BLK (scratch)))]
17625 "TARGET_64BIT"
17626 {
17627 switch (get_attr_type (insn))
17628 {
17629 case TYPE_IMOV:
17630 return "mov{q}\t{%1, %0|%0, %1}";
17631
17632 case TYPE_ALU:
17633 if (GET_CODE (operands[2]) == CONST_INT
17634 /* Avoid overflows. */
17635 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17636 && (INTVAL (operands[2]) == 128
17637 || (INTVAL (operands[2]) < 0
17638 && INTVAL (operands[2]) != -128)))
17639 {
17640 operands[2] = GEN_INT (-INTVAL (operands[2]));
17641 return "sub{q}\t{%2, %0|%0, %2}";
17642 }
17643 return "add{q}\t{%2, %0|%0, %2}";
17644
17645 case TYPE_LEA:
17646 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17647 return "lea{q}\t{%a2, %0|%0, %a2}";
17648
17649 default:
17650 abort ();
17651 }
17652 }
17653 [(set (attr "type")
17654 (cond [(eq_attr "alternative" "0")
17655 (const_string "alu")
17656 (match_operand:DI 2 "const0_operand" "")
17657 (const_string "imov")
17658 ]
17659 (const_string "lea")))
17660 (set_attr "mode" "DI")])
17661
17662 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17663 [(set (match_operand:DI 0 "register_operand" "=r,r")
17664 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17665 (match_operand:DI 3 "immediate_operand" "i,i")))
17666 (use (match_operand:DI 2 "register_operand" "r,r"))
17667 (clobber (reg:CC 17))
17668 (clobber (mem:BLK (scratch)))]
17669 "TARGET_64BIT"
17670 {
17671 switch (get_attr_type (insn))
17672 {
17673 case TYPE_ALU:
17674 return "add{q}\t{%2, %0|%0, %2}";
17675
17676 case TYPE_LEA:
17677 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17678 return "lea{q}\t{%a2, %0|%0, %a2}";
17679
17680 default:
17681 abort ();
17682 }
17683 }
17684 [(set_attr "type" "alu,lea")
17685 (set_attr "mode" "DI")])
17686
17687 ;; Placeholder for the conditional moves. This one is split either to SSE
17688 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17689 ;; fact is that compares supported by the cmp??ss instructions are exactly
17690 ;; swapped of those supported by cmove sequence.
17691 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17692 ;; supported by i387 comparisons and we do need to emit two conditional moves
17693 ;; in tandem.
17694
17695 (define_insn "sse_movsfcc"
17696 [(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")
17697 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17698 [(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")
17699 (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")])
17700 (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")
17701 (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")))
17702 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17703 (clobber (reg:CC 17))]
17704 "TARGET_SSE
17705 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17706 /* Avoid combine from being smart and converting min/max
17707 instruction patterns into conditional moves. */
17708 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17709 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17710 || !rtx_equal_p (operands[4], operands[2])
17711 || !rtx_equal_p (operands[5], operands[3]))
17712 && (!TARGET_IEEE_FP
17713 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17714 "#")
17715
17716 (define_insn "sse_movsfcc_eq"
17717 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17718 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17719 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17720 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17721 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17722 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17723 (clobber (reg:CC 17))]
17724 "TARGET_SSE
17725 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17726 "#")
17727
17728 (define_insn "sse_movdfcc"
17729 [(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")
17730 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17731 [(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")
17732 (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")])
17733 (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")
17734 (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")))
17735 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17736 (clobber (reg:CC 17))]
17737 "TARGET_SSE2
17738 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17739 /* Avoid combine from being smart and converting min/max
17740 instruction patterns into conditional moves. */
17741 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17742 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17743 || !rtx_equal_p (operands[4], operands[2])
17744 || !rtx_equal_p (operands[5], operands[3]))
17745 && (!TARGET_IEEE_FP
17746 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17747 "#")
17748
17749 (define_insn "sse_movdfcc_eq"
17750 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17751 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17752 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17753 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17754 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17755 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17756 (clobber (reg:CC 17))]
17757 "TARGET_SSE
17758 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17759 "#")
17760
17761 ;; For non-sse moves just expand the usual cmove sequence.
17762 (define_split
17763 [(set (match_operand 0 "register_operand" "")
17764 (if_then_else (match_operator 1 "comparison_operator"
17765 [(match_operand 4 "nonimmediate_operand" "")
17766 (match_operand 5 "register_operand" "")])
17767 (match_operand 2 "nonimmediate_operand" "")
17768 (match_operand 3 "nonimmediate_operand" "")))
17769 (clobber (match_operand 6 "" ""))
17770 (clobber (reg:CC 17))]
17771 "!SSE_REG_P (operands[0]) && reload_completed
17772 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17773 [(const_int 0)]
17774 {
17775 ix86_compare_op0 = operands[5];
17776 ix86_compare_op1 = operands[4];
17777 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17778 VOIDmode, operands[5], operands[4]);
17779 ix86_expand_fp_movcc (operands);
17780 DONE;
17781 })
17782
17783 ;; Split SSE based conditional move into sequence:
17784 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17785 ;; and op2, op0 - zero op2 if comparison was false
17786 ;; nand op0, op3 - load op3 to op0 if comparison was false
17787 ;; or op2, op0 - get the nonzero one into the result.
17788 (define_split
17789 [(set (match_operand:SF 0 "register_operand" "")
17790 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
17791 [(match_operand:SF 4 "register_operand" "")
17792 (match_operand:SF 5 "nonimmediate_operand" "")])
17793 (match_operand:SF 2 "register_operand" "")
17794 (match_operand:SF 3 "register_operand" "")))
17795 (clobber (match_operand 6 "" ""))
17796 (clobber (reg:CC 17))]
17797 "SSE_REG_P (operands[0]) && reload_completed"
17798 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17799 (set (match_dup 2) (and:V4SF (match_dup 2)
17800 (match_dup 8)))
17801 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17802 (match_dup 3)))
17803 (set (match_dup 0) (ior:V4SF (match_dup 6)
17804 (match_dup 7)))]
17805 {
17806 /* If op2 == op3, op3 would be clobbered before it is used. */
17807 if (operands_match_p (operands[2], operands[3]))
17808 {
17809 emit_move_insn (operands[0], operands[2]);
17810 DONE;
17811 }
17812
17813 PUT_MODE (operands[1], GET_MODE (operands[0]));
17814 if (operands_match_p (operands[0], operands[4]))
17815 operands[6] = operands[4], operands[7] = operands[2];
17816 else
17817 operands[6] = operands[2], operands[7] = operands[4];
17818 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17819 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17820 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17821 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17822 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17823 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17824 })
17825
17826 (define_split
17827 [(set (match_operand:DF 0 "register_operand" "")
17828 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
17829 [(match_operand:DF 4 "register_operand" "")
17830 (match_operand:DF 5 "nonimmediate_operand" "")])
17831 (match_operand:DF 2 "register_operand" "")
17832 (match_operand:DF 3 "register_operand" "")))
17833 (clobber (match_operand 6 "" ""))
17834 (clobber (reg:CC 17))]
17835 "SSE_REG_P (operands[0]) && reload_completed"
17836 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17837 (set (match_dup 2) (and:V2DF (match_dup 2)
17838 (match_dup 8)))
17839 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17840 (match_dup 3)))
17841 (set (match_dup 0) (ior:V2DF (match_dup 6)
17842 (match_dup 7)))]
17843 {
17844 if (GET_MODE (operands[2]) == DFmode
17845 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17846 {
17847 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17848 emit_insn (gen_sse2_unpcklpd (op, op, op));
17849 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17850 emit_insn (gen_sse2_unpcklpd (op, op, op));
17851 }
17852
17853 /* If op2 == op3, op3 would be clobbered before it is used. */
17854 if (operands_match_p (operands[2], operands[3]))
17855 {
17856 emit_move_insn (operands[0], operands[2]);
17857 DONE;
17858 }
17859
17860 PUT_MODE (operands[1], GET_MODE (operands[0]));
17861 if (operands_match_p (operands[0], operands[4]))
17862 operands[6] = operands[4], operands[7] = operands[2];
17863 else
17864 operands[6] = operands[2], operands[7] = operands[4];
17865 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17866 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17867 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17868 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17869 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17870 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17871 })
17872
17873 ;; Special case of conditional move we can handle effectively.
17874 ;; Do not brother with the integer/floating point case, since these are
17875 ;; bot considerably slower, unlike in the generic case.
17876 (define_insn "*sse_movsfcc_const0_1"
17877 [(set (match_operand:SF 0 "register_operand" "=&x")
17878 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17879 [(match_operand:SF 4 "register_operand" "0")
17880 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17881 (match_operand:SF 2 "register_operand" "x")
17882 (match_operand:SF 3 "const0_operand" "X")))]
17883 "TARGET_SSE"
17884 "#")
17885
17886 (define_insn "*sse_movsfcc_const0_2"
17887 [(set (match_operand:SF 0 "register_operand" "=&x")
17888 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17889 [(match_operand:SF 4 "register_operand" "0")
17890 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17891 (match_operand:SF 2 "const0_operand" "X")
17892 (match_operand:SF 3 "register_operand" "x")))]
17893 "TARGET_SSE"
17894 "#")
17895
17896 (define_insn "*sse_movsfcc_const0_3"
17897 [(set (match_operand:SF 0 "register_operand" "=&x")
17898 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17899 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17900 (match_operand:SF 5 "register_operand" "0")])
17901 (match_operand:SF 2 "register_operand" "x")
17902 (match_operand:SF 3 "const0_operand" "X")))]
17903 "TARGET_SSE"
17904 "#")
17905
17906 (define_insn "*sse_movsfcc_const0_4"
17907 [(set (match_operand:SF 0 "register_operand" "=&x")
17908 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17909 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17910 (match_operand:SF 5 "register_operand" "0")])
17911 (match_operand:SF 2 "const0_operand" "X")
17912 (match_operand:SF 3 "register_operand" "x")))]
17913 "TARGET_SSE"
17914 "#")
17915
17916 (define_insn "*sse_movdfcc_const0_1"
17917 [(set (match_operand:DF 0 "register_operand" "=&Y")
17918 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17919 [(match_operand:DF 4 "register_operand" "0")
17920 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17921 (match_operand:DF 2 "register_operand" "Y")
17922 (match_operand:DF 3 "const0_operand" "X")))]
17923 "TARGET_SSE2"
17924 "#")
17925
17926 (define_insn "*sse_movdfcc_const0_2"
17927 [(set (match_operand:DF 0 "register_operand" "=&Y")
17928 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17929 [(match_operand:DF 4 "register_operand" "0")
17930 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17931 (match_operand:DF 2 "const0_operand" "X")
17932 (match_operand:DF 3 "register_operand" "Y")))]
17933 "TARGET_SSE2"
17934 "#")
17935
17936 (define_insn "*sse_movdfcc_const0_3"
17937 [(set (match_operand:DF 0 "register_operand" "=&Y")
17938 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17939 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17940 (match_operand:DF 5 "register_operand" "0")])
17941 (match_operand:DF 2 "register_operand" "Y")
17942 (match_operand:DF 3 "const0_operand" "X")))]
17943 "TARGET_SSE2"
17944 "#")
17945
17946 (define_insn "*sse_movdfcc_const0_4"
17947 [(set (match_operand:DF 0 "register_operand" "=&Y")
17948 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17949 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17950 (match_operand:DF 5 "register_operand" "0")])
17951 (match_operand:DF 2 "const0_operand" "X")
17952 (match_operand:DF 3 "register_operand" "Y")))]
17953 "TARGET_SSE2"
17954 "#")
17955
17956 (define_split
17957 [(set (match_operand:SF 0 "register_operand" "")
17958 (if_then_else (match_operator:SF 1 "comparison_operator"
17959 [(match_operand:SF 4 "nonimmediate_operand" "")
17960 (match_operand:SF 5 "nonimmediate_operand" "")])
17961 (match_operand:SF 2 "nonmemory_operand" "")
17962 (match_operand:SF 3 "nonmemory_operand" "")))]
17963 "SSE_REG_P (operands[0]) && reload_completed
17964 && (const0_operand (operands[2], GET_MODE (operands[0]))
17965 || const0_operand (operands[3], GET_MODE (operands[0])))"
17966 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17967 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17968 {
17969 PUT_MODE (operands[1], GET_MODE (operands[0]));
17970 if (!sse_comparison_operator (operands[1], VOIDmode)
17971 || !rtx_equal_p (operands[0], operands[4]))
17972 {
17973 rtx tmp = operands[5];
17974 operands[5] = operands[4];
17975 operands[4] = tmp;
17976 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17977 }
17978 if (!rtx_equal_p (operands[0], operands[4]))
17979 abort ();
17980 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17981 if (const0_operand (operands[2], GET_MODE (operands[2])))
17982 {
17983 operands[7] = operands[3];
17984 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17985 }
17986 else
17987 {
17988 operands[7] = operands[2];
17989 operands[6] = operands[0];
17990 }
17991 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17992 })
17993
17994 (define_split
17995 [(set (match_operand:DF 0 "register_operand" "")
17996 (if_then_else (match_operator:DF 1 "comparison_operator"
17997 [(match_operand:DF 4 "nonimmediate_operand" "")
17998 (match_operand:DF 5 "nonimmediate_operand" "")])
17999 (match_operand:DF 2 "nonmemory_operand" "")
18000 (match_operand:DF 3 "nonmemory_operand" "")))]
18001 "SSE_REG_P (operands[0]) && reload_completed
18002 && (const0_operand (operands[2], GET_MODE (operands[0]))
18003 || const0_operand (operands[3], GET_MODE (operands[0])))"
18004 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18005 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18006 {
18007 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18008 && GET_MODE (operands[2]) == DFmode)
18009 {
18010 if (REG_P (operands[2]))
18011 {
18012 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18013 emit_insn (gen_sse2_unpcklpd (op, op, op));
18014 }
18015 if (REG_P (operands[3]))
18016 {
18017 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18018 emit_insn (gen_sse2_unpcklpd (op, op, op));
18019 }
18020 }
18021 PUT_MODE (operands[1], GET_MODE (operands[0]));
18022 if (!sse_comparison_operator (operands[1], VOIDmode)
18023 || !rtx_equal_p (operands[0], operands[4]))
18024 {
18025 rtx tmp = operands[5];
18026 operands[5] = operands[4];
18027 operands[4] = tmp;
18028 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18029 }
18030 if (!rtx_equal_p (operands[0], operands[4]))
18031 abort ();
18032 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18033 if (const0_operand (operands[2], GET_MODE (operands[2])))
18034 {
18035 operands[7] = operands[3];
18036 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18037 }
18038 else
18039 {
18040 operands[7] = operands[2];
18041 operands[6] = operands[8];
18042 }
18043 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18044 })
18045
18046 (define_expand "allocate_stack_worker"
18047 [(match_operand:SI 0 "register_operand" "")]
18048 "TARGET_STACK_PROBE"
18049 {
18050 if (reload_completed)
18051 {
18052 if (TARGET_64BIT)
18053 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18054 else
18055 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18056 }
18057 else
18058 {
18059 if (TARGET_64BIT)
18060 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18061 else
18062 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18063 }
18064 DONE;
18065 })
18066
18067 (define_insn "allocate_stack_worker_1"
18068 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18069 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
18070 (clobber (match_scratch:SI 1 "=0"))
18071 (clobber (reg:CC 17))]
18072 "!TARGET_64BIT && TARGET_STACK_PROBE"
18073 "call\t__alloca"
18074 [(set_attr "type" "multi")
18075 (set_attr "length" "5")])
18076
18077 (define_expand "allocate_stack_worker_postreload"
18078 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
18079 UNSPEC_STACK_PROBE)
18080 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
18081 (clobber (match_dup 0))
18082 (clobber (reg:CC 17))])]
18083 ""
18084 "")
18085
18086 (define_insn "allocate_stack_worker_rex64"
18087 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
18088 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
18089 (clobber (match_scratch:DI 1 "=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_expand "allocate_stack_worker_rex64_postreload"
18097 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
18098 UNSPEC_STACK_PROBE)
18099 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
18100 (clobber (match_dup 0))
18101 (clobber (reg:CC 17))])]
18102 ""
18103 "")
18104
18105 (define_expand "allocate_stack"
18106 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18107 (minus:SI (reg:SI 7)
18108 (match_operand:SI 1 "general_operand" "")))
18109 (clobber (reg:CC 17))])
18110 (parallel [(set (reg:SI 7)
18111 (minus:SI (reg:SI 7) (match_dup 1)))
18112 (clobber (reg:CC 17))])]
18113 "TARGET_STACK_PROBE"
18114 {
18115 #ifdef CHECK_STACK_LIMIT
18116 if (GET_CODE (operands[1]) == CONST_INT
18117 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18118 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18119 operands[1]));
18120 else
18121 #endif
18122 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18123 operands[1])));
18124
18125 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18126 DONE;
18127 })
18128
18129 (define_expand "builtin_setjmp_receiver"
18130 [(label_ref (match_operand 0 "" ""))]
18131 "!TARGET_64BIT && flag_pic"
18132 {
18133 emit_insn (gen_set_got (pic_offset_table_rtx));
18134 DONE;
18135 })
18136 \f
18137 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18138
18139 (define_split
18140 [(set (match_operand 0 "register_operand" "")
18141 (match_operator 3 "promotable_binary_operator"
18142 [(match_operand 1 "register_operand" "")
18143 (match_operand 2 "aligned_operand" "")]))
18144 (clobber (reg:CC 17))]
18145 "! TARGET_PARTIAL_REG_STALL && reload_completed
18146 && ((GET_MODE (operands[0]) == HImode
18147 && ((!optimize_size && !TARGET_FAST_PREFIX)
18148 || GET_CODE (operands[2]) != CONST_INT
18149 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18150 || (GET_MODE (operands[0]) == QImode
18151 && (TARGET_PROMOTE_QImode || optimize_size)))"
18152 [(parallel [(set (match_dup 0)
18153 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18154 (clobber (reg:CC 17))])]
18155 "operands[0] = gen_lowpart (SImode, operands[0]);
18156 operands[1] = gen_lowpart (SImode, operands[1]);
18157 if (GET_CODE (operands[3]) != ASHIFT)
18158 operands[2] = gen_lowpart (SImode, operands[2]);
18159 PUT_MODE (operands[3], SImode);")
18160
18161 ; Promote the QImode tests, as i386 has encoding of the AND
18162 ; instruction with 32-bit sign-extended immediate and thus the
18163 ; instruction size is unchanged, except in the %eax case for
18164 ; which it is increased by one byte, hence the ! optimize_size.
18165 (define_split
18166 [(set (reg 17)
18167 (compare (and (match_operand 1 "aligned_operand" "")
18168 (match_operand 2 "const_int_operand" ""))
18169 (const_int 0)))
18170 (set (match_operand 0 "register_operand" "")
18171 (and (match_dup 1) (match_dup 2)))]
18172 "! TARGET_PARTIAL_REG_STALL && reload_completed
18173 /* Ensure that the operand will remain sign-extended immediate. */
18174 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18175 && ! optimize_size
18176 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18177 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18178 [(parallel [(set (reg:CCNO 17)
18179 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18180 (const_int 0)))
18181 (set (match_dup 0)
18182 (and:SI (match_dup 1) (match_dup 2)))])]
18183 "operands[2]
18184 = gen_int_mode (INTVAL (operands[2])
18185 & GET_MODE_MASK (GET_MODE (operands[0])),
18186 SImode);
18187 operands[0] = gen_lowpart (SImode, operands[0]);
18188 operands[1] = gen_lowpart (SImode, operands[1]);")
18189
18190 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18191 ; the TEST instruction with 32-bit sign-extended immediate and thus
18192 ; the instruction size would at least double, which is not what we
18193 ; want even with ! optimize_size.
18194 (define_split
18195 [(set (reg 17)
18196 (compare (and (match_operand:HI 0 "aligned_operand" "")
18197 (match_operand:HI 1 "const_int_operand" ""))
18198 (const_int 0)))]
18199 "! TARGET_PARTIAL_REG_STALL && reload_completed
18200 /* Ensure that the operand will remain sign-extended immediate. */
18201 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18202 && ! TARGET_FAST_PREFIX
18203 && ! optimize_size"
18204 [(set (reg:CCNO 17)
18205 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18206 (const_int 0)))]
18207 "operands[1]
18208 = gen_int_mode (INTVAL (operands[1])
18209 & GET_MODE_MASK (GET_MODE (operands[0])),
18210 SImode);
18211 operands[0] = gen_lowpart (SImode, operands[0]);")
18212
18213 (define_split
18214 [(set (match_operand 0 "register_operand" "")
18215 (neg (match_operand 1 "register_operand" "")))
18216 (clobber (reg:CC 17))]
18217 "! TARGET_PARTIAL_REG_STALL && reload_completed
18218 && (GET_MODE (operands[0]) == HImode
18219 || (GET_MODE (operands[0]) == QImode
18220 && (TARGET_PROMOTE_QImode || optimize_size)))"
18221 [(parallel [(set (match_dup 0)
18222 (neg:SI (match_dup 1)))
18223 (clobber (reg:CC 17))])]
18224 "operands[0] = gen_lowpart (SImode, operands[0]);
18225 operands[1] = gen_lowpart (SImode, operands[1]);")
18226
18227 (define_split
18228 [(set (match_operand 0 "register_operand" "")
18229 (not (match_operand 1 "register_operand" "")))]
18230 "! TARGET_PARTIAL_REG_STALL && reload_completed
18231 && (GET_MODE (operands[0]) == HImode
18232 || (GET_MODE (operands[0]) == QImode
18233 && (TARGET_PROMOTE_QImode || optimize_size)))"
18234 [(set (match_dup 0)
18235 (not:SI (match_dup 1)))]
18236 "operands[0] = gen_lowpart (SImode, operands[0]);
18237 operands[1] = gen_lowpart (SImode, operands[1]);")
18238
18239 (define_split
18240 [(set (match_operand 0 "register_operand" "")
18241 (if_then_else (match_operator 1 "comparison_operator"
18242 [(reg 17) (const_int 0)])
18243 (match_operand 2 "register_operand" "")
18244 (match_operand 3 "register_operand" "")))]
18245 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18246 && (GET_MODE (operands[0]) == HImode
18247 || (GET_MODE (operands[0]) == QImode
18248 && (TARGET_PROMOTE_QImode || optimize_size)))"
18249 [(set (match_dup 0)
18250 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18251 "operands[0] = gen_lowpart (SImode, operands[0]);
18252 operands[2] = gen_lowpart (SImode, operands[2]);
18253 operands[3] = gen_lowpart (SImode, operands[3]);")
18254
18255 \f
18256 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18257 ;; transform a complex memory operation into two memory to register operations.
18258
18259 ;; Don't push memory operands
18260 (define_peephole2
18261 [(set (match_operand:SI 0 "push_operand" "")
18262 (match_operand:SI 1 "memory_operand" ""))
18263 (match_scratch:SI 2 "r")]
18264 "! optimize_size && ! TARGET_PUSH_MEMORY"
18265 [(set (match_dup 2) (match_dup 1))
18266 (set (match_dup 0) (match_dup 2))]
18267 "")
18268
18269 (define_peephole2
18270 [(set (match_operand:DI 0 "push_operand" "")
18271 (match_operand:DI 1 "memory_operand" ""))
18272 (match_scratch:DI 2 "r")]
18273 "! optimize_size && ! TARGET_PUSH_MEMORY"
18274 [(set (match_dup 2) (match_dup 1))
18275 (set (match_dup 0) (match_dup 2))]
18276 "")
18277
18278 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18279 ;; SImode pushes.
18280 (define_peephole2
18281 [(set (match_operand:SF 0 "push_operand" "")
18282 (match_operand:SF 1 "memory_operand" ""))
18283 (match_scratch:SF 2 "r")]
18284 "! optimize_size && ! TARGET_PUSH_MEMORY"
18285 [(set (match_dup 2) (match_dup 1))
18286 (set (match_dup 0) (match_dup 2))]
18287 "")
18288
18289 (define_peephole2
18290 [(set (match_operand:HI 0 "push_operand" "")
18291 (match_operand:HI 1 "memory_operand" ""))
18292 (match_scratch:HI 2 "r")]
18293 "! optimize_size && ! TARGET_PUSH_MEMORY"
18294 [(set (match_dup 2) (match_dup 1))
18295 (set (match_dup 0) (match_dup 2))]
18296 "")
18297
18298 (define_peephole2
18299 [(set (match_operand:QI 0 "push_operand" "")
18300 (match_operand:QI 1 "memory_operand" ""))
18301 (match_scratch:QI 2 "q")]
18302 "! optimize_size && ! TARGET_PUSH_MEMORY"
18303 [(set (match_dup 2) (match_dup 1))
18304 (set (match_dup 0) (match_dup 2))]
18305 "")
18306
18307 ;; Don't move an immediate directly to memory when the instruction
18308 ;; gets too big.
18309 (define_peephole2
18310 [(match_scratch:SI 1 "r")
18311 (set (match_operand:SI 0 "memory_operand" "")
18312 (const_int 0))]
18313 "! optimize_size
18314 && ! TARGET_USE_MOV0
18315 && TARGET_SPLIT_LONG_MOVES
18316 && get_attr_length (insn) >= ix86_cost->large_insn
18317 && peep2_regno_dead_p (0, FLAGS_REG)"
18318 [(parallel [(set (match_dup 1) (const_int 0))
18319 (clobber (reg:CC 17))])
18320 (set (match_dup 0) (match_dup 1))]
18321 "")
18322
18323 (define_peephole2
18324 [(match_scratch:HI 1 "r")
18325 (set (match_operand:HI 0 "memory_operand" "")
18326 (const_int 0))]
18327 "! optimize_size
18328 && ! TARGET_USE_MOV0
18329 && TARGET_SPLIT_LONG_MOVES
18330 && get_attr_length (insn) >= ix86_cost->large_insn
18331 && peep2_regno_dead_p (0, FLAGS_REG)"
18332 [(parallel [(set (match_dup 2) (const_int 0))
18333 (clobber (reg:CC 17))])
18334 (set (match_dup 0) (match_dup 1))]
18335 "operands[2] = gen_lowpart (SImode, operands[1]);")
18336
18337 (define_peephole2
18338 [(match_scratch:QI 1 "q")
18339 (set (match_operand:QI 0 "memory_operand" "")
18340 (const_int 0))]
18341 "! optimize_size
18342 && ! TARGET_USE_MOV0
18343 && TARGET_SPLIT_LONG_MOVES
18344 && get_attr_length (insn) >= ix86_cost->large_insn
18345 && peep2_regno_dead_p (0, FLAGS_REG)"
18346 [(parallel [(set (match_dup 2) (const_int 0))
18347 (clobber (reg:CC 17))])
18348 (set (match_dup 0) (match_dup 1))]
18349 "operands[2] = gen_lowpart (SImode, operands[1]);")
18350
18351 (define_peephole2
18352 [(match_scratch:SI 2 "r")
18353 (set (match_operand:SI 0 "memory_operand" "")
18354 (match_operand:SI 1 "immediate_operand" ""))]
18355 "! optimize_size
18356 && get_attr_length (insn) >= ix86_cost->large_insn
18357 && TARGET_SPLIT_LONG_MOVES"
18358 [(set (match_dup 2) (match_dup 1))
18359 (set (match_dup 0) (match_dup 2))]
18360 "")
18361
18362 (define_peephole2
18363 [(match_scratch:HI 2 "r")
18364 (set (match_operand:HI 0 "memory_operand" "")
18365 (match_operand:HI 1 "immediate_operand" ""))]
18366 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18367 && TARGET_SPLIT_LONG_MOVES"
18368 [(set (match_dup 2) (match_dup 1))
18369 (set (match_dup 0) (match_dup 2))]
18370 "")
18371
18372 (define_peephole2
18373 [(match_scratch:QI 2 "q")
18374 (set (match_operand:QI 0 "memory_operand" "")
18375 (match_operand:QI 1 "immediate_operand" ""))]
18376 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18377 && TARGET_SPLIT_LONG_MOVES"
18378 [(set (match_dup 2) (match_dup 1))
18379 (set (match_dup 0) (match_dup 2))]
18380 "")
18381
18382 ;; Don't compare memory with zero, load and use a test instead.
18383 (define_peephole2
18384 [(set (reg 17)
18385 (compare (match_operand:SI 0 "memory_operand" "")
18386 (const_int 0)))
18387 (match_scratch:SI 3 "r")]
18388 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18389 [(set (match_dup 3) (match_dup 0))
18390 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18391 "")
18392
18393 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18394 ;; Don't split NOTs with a displacement operand, because resulting XOR
18395 ;; will not be pairable anyway.
18396 ;;
18397 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18398 ;; represented using a modRM byte. The XOR replacement is long decoded,
18399 ;; so this split helps here as well.
18400 ;;
18401 ;; Note: Can't do this as a regular split because we can't get proper
18402 ;; lifetime information then.
18403
18404 (define_peephole2
18405 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18406 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18407 "!optimize_size
18408 && peep2_regno_dead_p (0, FLAGS_REG)
18409 && ((TARGET_PENTIUM
18410 && (GET_CODE (operands[0]) != MEM
18411 || !memory_displacement_operand (operands[0], SImode)))
18412 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18413 [(parallel [(set (match_dup 0)
18414 (xor:SI (match_dup 1) (const_int -1)))
18415 (clobber (reg:CC 17))])]
18416 "")
18417
18418 (define_peephole2
18419 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18420 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18421 "!optimize_size
18422 && peep2_regno_dead_p (0, FLAGS_REG)
18423 && ((TARGET_PENTIUM
18424 && (GET_CODE (operands[0]) != MEM
18425 || !memory_displacement_operand (operands[0], HImode)))
18426 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18427 [(parallel [(set (match_dup 0)
18428 (xor:HI (match_dup 1) (const_int -1)))
18429 (clobber (reg:CC 17))])]
18430 "")
18431
18432 (define_peephole2
18433 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18434 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18435 "!optimize_size
18436 && peep2_regno_dead_p (0, FLAGS_REG)
18437 && ((TARGET_PENTIUM
18438 && (GET_CODE (operands[0]) != MEM
18439 || !memory_displacement_operand (operands[0], QImode)))
18440 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18441 [(parallel [(set (match_dup 0)
18442 (xor:QI (match_dup 1) (const_int -1)))
18443 (clobber (reg:CC 17))])]
18444 "")
18445
18446 ;; Non pairable "test imm, reg" instructions can be translated to
18447 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18448 ;; byte opcode instead of two, have a short form for byte operands),
18449 ;; so do it for other CPUs as well. Given that the value was dead,
18450 ;; this should not create any new dependencies. Pass on the sub-word
18451 ;; versions if we're concerned about partial register stalls.
18452
18453 (define_peephole2
18454 [(set (reg 17)
18455 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18456 (match_operand:SI 1 "immediate_operand" ""))
18457 (const_int 0)))]
18458 "ix86_match_ccmode (insn, CCNOmode)
18459 && (true_regnum (operands[0]) != 0
18460 || (GET_CODE (operands[1]) == CONST_INT
18461 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18462 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18463 [(parallel
18464 [(set (reg:CCNO 17)
18465 (compare:CCNO (and:SI (match_dup 0)
18466 (match_dup 1))
18467 (const_int 0)))
18468 (set (match_dup 0)
18469 (and:SI (match_dup 0) (match_dup 1)))])]
18470 "")
18471
18472 ;; We don't need to handle HImode case, because it will be promoted to SImode
18473 ;; on ! TARGET_PARTIAL_REG_STALL
18474
18475 (define_peephole2
18476 [(set (reg 17)
18477 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18478 (match_operand:QI 1 "immediate_operand" ""))
18479 (const_int 0)))]
18480 "! TARGET_PARTIAL_REG_STALL
18481 && ix86_match_ccmode (insn, CCNOmode)
18482 && true_regnum (operands[0]) != 0
18483 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18484 [(parallel
18485 [(set (reg:CCNO 17)
18486 (compare:CCNO (and:QI (match_dup 0)
18487 (match_dup 1))
18488 (const_int 0)))
18489 (set (match_dup 0)
18490 (and:QI (match_dup 0) (match_dup 1)))])]
18491 "")
18492
18493 (define_peephole2
18494 [(set (reg 17)
18495 (compare
18496 (and:SI
18497 (zero_extract:SI
18498 (match_operand 0 "ext_register_operand" "")
18499 (const_int 8)
18500 (const_int 8))
18501 (match_operand 1 "const_int_operand" ""))
18502 (const_int 0)))]
18503 "! TARGET_PARTIAL_REG_STALL
18504 && ix86_match_ccmode (insn, CCNOmode)
18505 && true_regnum (operands[0]) != 0
18506 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18507 [(parallel [(set (reg:CCNO 17)
18508 (compare:CCNO
18509 (and:SI
18510 (zero_extract:SI
18511 (match_dup 0)
18512 (const_int 8)
18513 (const_int 8))
18514 (match_dup 1))
18515 (const_int 0)))
18516 (set (zero_extract:SI (match_dup 0)
18517 (const_int 8)
18518 (const_int 8))
18519 (and:SI
18520 (zero_extract:SI
18521 (match_dup 0)
18522 (const_int 8)
18523 (const_int 8))
18524 (match_dup 1)))])]
18525 "")
18526
18527 ;; Don't do logical operations with memory inputs.
18528 (define_peephole2
18529 [(match_scratch:SI 2 "r")
18530 (parallel [(set (match_operand:SI 0 "register_operand" "")
18531 (match_operator:SI 3 "arith_or_logical_operator"
18532 [(match_dup 0)
18533 (match_operand:SI 1 "memory_operand" "")]))
18534 (clobber (reg:CC 17))])]
18535 "! optimize_size && ! TARGET_READ_MODIFY"
18536 [(set (match_dup 2) (match_dup 1))
18537 (parallel [(set (match_dup 0)
18538 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18539 (clobber (reg:CC 17))])]
18540 "")
18541
18542 (define_peephole2
18543 [(match_scratch:SI 2 "r")
18544 (parallel [(set (match_operand:SI 0 "register_operand" "")
18545 (match_operator:SI 3 "arith_or_logical_operator"
18546 [(match_operand:SI 1 "memory_operand" "")
18547 (match_dup 0)]))
18548 (clobber (reg:CC 17))])]
18549 "! optimize_size && ! TARGET_READ_MODIFY"
18550 [(set (match_dup 2) (match_dup 1))
18551 (parallel [(set (match_dup 0)
18552 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18553 (clobber (reg:CC 17))])]
18554 "")
18555
18556 ; Don't do logical operations with memory outputs
18557 ;
18558 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18559 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18560 ; the same decoder scheduling characteristics as the original.
18561
18562 (define_peephole2
18563 [(match_scratch:SI 2 "r")
18564 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18565 (match_operator:SI 3 "arith_or_logical_operator"
18566 [(match_dup 0)
18567 (match_operand:SI 1 "nonmemory_operand" "")]))
18568 (clobber (reg:CC 17))])]
18569 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18570 [(set (match_dup 2) (match_dup 0))
18571 (parallel [(set (match_dup 2)
18572 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18573 (clobber (reg:CC 17))])
18574 (set (match_dup 0) (match_dup 2))]
18575 "")
18576
18577 (define_peephole2
18578 [(match_scratch:SI 2 "r")
18579 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18580 (match_operator:SI 3 "arith_or_logical_operator"
18581 [(match_operand:SI 1 "nonmemory_operand" "")
18582 (match_dup 0)]))
18583 (clobber (reg:CC 17))])]
18584 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18585 [(set (match_dup 2) (match_dup 0))
18586 (parallel [(set (match_dup 2)
18587 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18588 (clobber (reg:CC 17))])
18589 (set (match_dup 0) (match_dup 2))]
18590 "")
18591
18592 ;; Attempt to always use XOR for zeroing registers.
18593 (define_peephole2
18594 [(set (match_operand 0 "register_operand" "")
18595 (const_int 0))]
18596 "(GET_MODE (operands[0]) == QImode
18597 || GET_MODE (operands[0]) == HImode
18598 || GET_MODE (operands[0]) == SImode
18599 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18600 && (! TARGET_USE_MOV0 || optimize_size)
18601 && peep2_regno_dead_p (0, FLAGS_REG)"
18602 [(parallel [(set (match_dup 0) (const_int 0))
18603 (clobber (reg:CC 17))])]
18604 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18605 operands[0]);")
18606
18607 (define_peephole2
18608 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18609 (const_int 0))]
18610 "(GET_MODE (operands[0]) == QImode
18611 || GET_MODE (operands[0]) == HImode)
18612 && (! TARGET_USE_MOV0 || optimize_size)
18613 && peep2_regno_dead_p (0, FLAGS_REG)"
18614 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18615 (clobber (reg:CC 17))])])
18616
18617 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18618 (define_peephole2
18619 [(set (match_operand 0 "register_operand" "")
18620 (const_int -1))]
18621 "(GET_MODE (operands[0]) == HImode
18622 || GET_MODE (operands[0]) == SImode
18623 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18624 && (optimize_size || TARGET_PENTIUM)
18625 && peep2_regno_dead_p (0, FLAGS_REG)"
18626 [(parallel [(set (match_dup 0) (const_int -1))
18627 (clobber (reg:CC 17))])]
18628 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18629 operands[0]);")
18630
18631 ;; Attempt to convert simple leas to adds. These can be created by
18632 ;; move expanders.
18633 (define_peephole2
18634 [(set (match_operand:SI 0 "register_operand" "")
18635 (plus:SI (match_dup 0)
18636 (match_operand:SI 1 "nonmemory_operand" "")))]
18637 "peep2_regno_dead_p (0, FLAGS_REG)"
18638 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18639 (clobber (reg:CC 17))])]
18640 "")
18641
18642 (define_peephole2
18643 [(set (match_operand:SI 0 "register_operand" "")
18644 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18645 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18646 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18647 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18648 (clobber (reg:CC 17))])]
18649 "operands[2] = gen_lowpart (SImode, operands[2]);")
18650
18651 (define_peephole2
18652 [(set (match_operand:DI 0 "register_operand" "")
18653 (plus:DI (match_dup 0)
18654 (match_operand:DI 1 "x86_64_general_operand" "")))]
18655 "peep2_regno_dead_p (0, FLAGS_REG)"
18656 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18657 (clobber (reg:CC 17))])]
18658 "")
18659
18660 (define_peephole2
18661 [(set (match_operand:SI 0 "register_operand" "")
18662 (mult:SI (match_dup 0)
18663 (match_operand:SI 1 "const_int_operand" "")))]
18664 "exact_log2 (INTVAL (operands[1])) >= 0
18665 && peep2_regno_dead_p (0, FLAGS_REG)"
18666 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18667 (clobber (reg:CC 17))])]
18668 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18669
18670 (define_peephole2
18671 [(set (match_operand:DI 0 "register_operand" "")
18672 (mult:DI (match_dup 0)
18673 (match_operand:DI 1 "const_int_operand" "")))]
18674 "exact_log2 (INTVAL (operands[1])) >= 0
18675 && peep2_regno_dead_p (0, FLAGS_REG)"
18676 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18677 (clobber (reg:CC 17))])]
18678 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18679
18680 (define_peephole2
18681 [(set (match_operand:SI 0 "register_operand" "")
18682 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18683 (match_operand:DI 2 "const_int_operand" "")) 0))]
18684 "exact_log2 (INTVAL (operands[2])) >= 0
18685 && REGNO (operands[0]) == REGNO (operands[1])
18686 && peep2_regno_dead_p (0, FLAGS_REG)"
18687 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18688 (clobber (reg:CC 17))])]
18689 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18690
18691 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18692 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18693 ;; many CPUs it is also faster, since special hardware to avoid esp
18694 ;; dependencies is present.
18695
18696 ;; While some of these conversions may be done using splitters, we use peepholes
18697 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18698
18699 ;; Convert prologue esp subtractions to push.
18700 ;; We need register to push. In order to keep verify_flow_info happy we have
18701 ;; two choices
18702 ;; - use scratch and clobber it in order to avoid dependencies
18703 ;; - use already live register
18704 ;; We can't use the second way right now, since there is no reliable way how to
18705 ;; verify that given register is live. First choice will also most likely in
18706 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18707 ;; call clobbered registers are dead. We may want to use base pointer as an
18708 ;; alternative when no register is available later.
18709
18710 (define_peephole2
18711 [(match_scratch:SI 0 "r")
18712 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18713 (clobber (reg:CC 17))
18714 (clobber (mem:BLK (scratch)))])]
18715 "optimize_size || !TARGET_SUB_ESP_4"
18716 [(clobber (match_dup 0))
18717 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18718 (clobber (mem:BLK (scratch)))])])
18719
18720 (define_peephole2
18721 [(match_scratch:SI 0 "r")
18722 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18723 (clobber (reg:CC 17))
18724 (clobber (mem:BLK (scratch)))])]
18725 "optimize_size || !TARGET_SUB_ESP_8"
18726 [(clobber (match_dup 0))
18727 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18728 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18729 (clobber (mem:BLK (scratch)))])])
18730
18731 ;; Convert esp subtractions to push.
18732 (define_peephole2
18733 [(match_scratch:SI 0 "r")
18734 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18735 (clobber (reg:CC 17))])]
18736 "optimize_size || !TARGET_SUB_ESP_4"
18737 [(clobber (match_dup 0))
18738 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18739
18740 (define_peephole2
18741 [(match_scratch:SI 0 "r")
18742 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18743 (clobber (reg:CC 17))])]
18744 "optimize_size || !TARGET_SUB_ESP_8"
18745 [(clobber (match_dup 0))
18746 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18747 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18748
18749 ;; Convert epilogue deallocator to pop.
18750 (define_peephole2
18751 [(match_scratch:SI 0 "r")
18752 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18753 (clobber (reg:CC 17))
18754 (clobber (mem:BLK (scratch)))])]
18755 "optimize_size || !TARGET_ADD_ESP_4"
18756 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18757 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18758 (clobber (mem:BLK (scratch)))])]
18759 "")
18760
18761 ;; Two pops case is tricky, since pop causes dependency on destination register.
18762 ;; We use two registers if available.
18763 (define_peephole2
18764 [(match_scratch:SI 0 "r")
18765 (match_scratch:SI 1 "r")
18766 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18767 (clobber (reg:CC 17))
18768 (clobber (mem:BLK (scratch)))])]
18769 "optimize_size || !TARGET_ADD_ESP_8"
18770 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18771 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18772 (clobber (mem:BLK (scratch)))])
18773 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18774 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18775 "")
18776
18777 (define_peephole2
18778 [(match_scratch:SI 0 "r")
18779 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18780 (clobber (reg:CC 17))
18781 (clobber (mem:BLK (scratch)))])]
18782 "optimize_size"
18783 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18784 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18785 (clobber (mem:BLK (scratch)))])
18786 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18787 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18788 "")
18789
18790 ;; Convert esp additions to pop.
18791 (define_peephole2
18792 [(match_scratch:SI 0 "r")
18793 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18794 (clobber (reg:CC 17))])]
18795 ""
18796 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18797 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18798 "")
18799
18800 ;; Two pops case is tricky, since pop causes dependency on destination register.
18801 ;; We use two registers if available.
18802 (define_peephole2
18803 [(match_scratch:SI 0 "r")
18804 (match_scratch:SI 1 "r")
18805 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18806 (clobber (reg:CC 17))])]
18807 ""
18808 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18809 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18810 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18811 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18812 "")
18813
18814 (define_peephole2
18815 [(match_scratch:SI 0 "r")
18816 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18817 (clobber (reg:CC 17))])]
18818 "optimize_size"
18819 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18820 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18821 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18822 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18823 "")
18824 \f
18825 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18826 ;; required and register dies.
18827 (define_peephole2
18828 [(set (reg 17)
18829 (compare (match_operand:SI 0 "register_operand" "")
18830 (match_operand:SI 1 "incdec_operand" "")))]
18831 "ix86_match_ccmode (insn, CCGCmode)
18832 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18833 [(parallel [(set (reg:CCGC 17)
18834 (compare:CCGC (match_dup 0)
18835 (match_dup 1)))
18836 (clobber (match_dup 0))])]
18837 "")
18838
18839 (define_peephole2
18840 [(set (reg 17)
18841 (compare (match_operand:HI 0 "register_operand" "")
18842 (match_operand:HI 1 "incdec_operand" "")))]
18843 "ix86_match_ccmode (insn, CCGCmode)
18844 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18845 [(parallel [(set (reg:CCGC 17)
18846 (compare:CCGC (match_dup 0)
18847 (match_dup 1)))
18848 (clobber (match_dup 0))])]
18849 "")
18850
18851 (define_peephole2
18852 [(set (reg 17)
18853 (compare (match_operand:QI 0 "register_operand" "")
18854 (match_operand:QI 1 "incdec_operand" "")))]
18855 "ix86_match_ccmode (insn, CCGCmode)
18856 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18857 [(parallel [(set (reg:CCGC 17)
18858 (compare:CCGC (match_dup 0)
18859 (match_dup 1)))
18860 (clobber (match_dup 0))])]
18861 "")
18862
18863 ;; Convert compares with 128 to shorter add -128
18864 (define_peephole2
18865 [(set (reg 17)
18866 (compare (match_operand:SI 0 "register_operand" "")
18867 (const_int 128)))]
18868 "ix86_match_ccmode (insn, CCGCmode)
18869 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18870 [(parallel [(set (reg:CCGC 17)
18871 (compare:CCGC (match_dup 0)
18872 (const_int 128)))
18873 (clobber (match_dup 0))])]
18874 "")
18875
18876 (define_peephole2
18877 [(set (reg 17)
18878 (compare (match_operand:HI 0 "register_operand" "")
18879 (const_int 128)))]
18880 "ix86_match_ccmode (insn, CCGCmode)
18881 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18882 [(parallel [(set (reg:CCGC 17)
18883 (compare:CCGC (match_dup 0)
18884 (const_int 128)))
18885 (clobber (match_dup 0))])]
18886 "")
18887 \f
18888 (define_peephole2
18889 [(match_scratch:DI 0 "r")
18890 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18891 (clobber (reg:CC 17))
18892 (clobber (mem:BLK (scratch)))])]
18893 "optimize_size || !TARGET_SUB_ESP_4"
18894 [(clobber (match_dup 0))
18895 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18896 (clobber (mem:BLK (scratch)))])])
18897
18898 (define_peephole2
18899 [(match_scratch:DI 0 "r")
18900 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18901 (clobber (reg:CC 17))
18902 (clobber (mem:BLK (scratch)))])]
18903 "optimize_size || !TARGET_SUB_ESP_8"
18904 [(clobber (match_dup 0))
18905 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18906 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18907 (clobber (mem:BLK (scratch)))])])
18908
18909 ;; Convert esp subtractions to push.
18910 (define_peephole2
18911 [(match_scratch:DI 0 "r")
18912 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18913 (clobber (reg:CC 17))])]
18914 "optimize_size || !TARGET_SUB_ESP_4"
18915 [(clobber (match_dup 0))
18916 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18917
18918 (define_peephole2
18919 [(match_scratch:DI 0 "r")
18920 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18921 (clobber (reg:CC 17))])]
18922 "optimize_size || !TARGET_SUB_ESP_8"
18923 [(clobber (match_dup 0))
18924 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18925 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18926
18927 ;; Convert epilogue deallocator to pop.
18928 (define_peephole2
18929 [(match_scratch:DI 0 "r")
18930 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18931 (clobber (reg:CC 17))
18932 (clobber (mem:BLK (scratch)))])]
18933 "optimize_size || !TARGET_ADD_ESP_4"
18934 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18935 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18936 (clobber (mem:BLK (scratch)))])]
18937 "")
18938
18939 ;; Two pops case is tricky, since pop causes dependency on destination register.
18940 ;; We use two registers if available.
18941 (define_peephole2
18942 [(match_scratch:DI 0 "r")
18943 (match_scratch:DI 1 "r")
18944 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18945 (clobber (reg:CC 17))
18946 (clobber (mem:BLK (scratch)))])]
18947 "optimize_size || !TARGET_ADD_ESP_8"
18948 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18949 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18950 (clobber (mem:BLK (scratch)))])
18951 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18952 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18953 "")
18954
18955 (define_peephole2
18956 [(match_scratch:DI 0 "r")
18957 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18958 (clobber (reg:CC 17))
18959 (clobber (mem:BLK (scratch)))])]
18960 "optimize_size"
18961 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18962 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18963 (clobber (mem:BLK (scratch)))])
18964 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18965 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18966 "")
18967
18968 ;; Convert esp additions to pop.
18969 (define_peephole2
18970 [(match_scratch:DI 0 "r")
18971 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18972 (clobber (reg:CC 17))])]
18973 ""
18974 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18975 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18976 "")
18977
18978 ;; Two pops case is tricky, since pop causes dependency on destination register.
18979 ;; We use two registers if available.
18980 (define_peephole2
18981 [(match_scratch:DI 0 "r")
18982 (match_scratch:DI 1 "r")
18983 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18984 (clobber (reg:CC 17))])]
18985 ""
18986 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18987 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18988 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18989 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18990 "")
18991
18992 (define_peephole2
18993 [(match_scratch:DI 0 "r")
18994 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18995 (clobber (reg:CC 17))])]
18996 "optimize_size"
18997 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18998 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18999 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
19000 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
19001 "")
19002 \f
19003 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19004 ;; imul $32bit_imm, reg, reg is direct decoded.
19005 (define_peephole2
19006 [(match_scratch:DI 3 "r")
19007 (parallel [(set (match_operand:DI 0 "register_operand" "")
19008 (mult:DI (match_operand:DI 1 "memory_operand" "")
19009 (match_operand:DI 2 "immediate_operand" "")))
19010 (clobber (reg:CC 17))])]
19011 "TARGET_K8 && !optimize_size
19012 && (GET_CODE (operands[2]) != CONST_INT
19013 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19014 [(set (match_dup 3) (match_dup 1))
19015 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19016 (clobber (reg:CC 17))])]
19017 "")
19018
19019 (define_peephole2
19020 [(match_scratch:SI 3 "r")
19021 (parallel [(set (match_operand:SI 0 "register_operand" "")
19022 (mult:SI (match_operand:SI 1 "memory_operand" "")
19023 (match_operand:SI 2 "immediate_operand" "")))
19024 (clobber (reg:CC 17))])]
19025 "TARGET_K8 && !optimize_size
19026 && (GET_CODE (operands[2]) != CONST_INT
19027 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19028 [(set (match_dup 3) (match_dup 1))
19029 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19030 (clobber (reg:CC 17))])]
19031 "")
19032
19033 (define_peephole2
19034 [(match_scratch:SI 3 "r")
19035 (parallel [(set (match_operand:DI 0 "register_operand" "")
19036 (zero_extend:DI
19037 (mult:SI (match_operand:SI 1 "memory_operand" "")
19038 (match_operand:SI 2 "immediate_operand" ""))))
19039 (clobber (reg:CC 17))])]
19040 "TARGET_K8 && !optimize_size
19041 && (GET_CODE (operands[2]) != CONST_INT
19042 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19043 [(set (match_dup 3) (match_dup 1))
19044 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19045 (clobber (reg:CC 17))])]
19046 "")
19047
19048 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19049 ;; Convert it into imul reg, reg
19050 ;; It would be better to force assembler to encode instruction using long
19051 ;; immediate, but there is apparently no way to do so.
19052 (define_peephole2
19053 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19054 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19055 (match_operand:DI 2 "const_int_operand" "")))
19056 (clobber (reg:CC 17))])
19057 (match_scratch:DI 3 "r")]
19058 "TARGET_K8 && !optimize_size
19059 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19060 [(set (match_dup 3) (match_dup 2))
19061 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19062 (clobber (reg:CC 17))])]
19063 {
19064 if (!rtx_equal_p (operands[0], operands[1]))
19065 emit_move_insn (operands[0], operands[1]);
19066 })
19067
19068 (define_peephole2
19069 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19070 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19071 (match_operand:SI 2 "const_int_operand" "")))
19072 (clobber (reg:CC 17))])
19073 (match_scratch:SI 3 "r")]
19074 "TARGET_K8 && !optimize_size
19075 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19076 [(set (match_dup 3) (match_dup 2))
19077 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19078 (clobber (reg:CC 17))])]
19079 {
19080 if (!rtx_equal_p (operands[0], operands[1]))
19081 emit_move_insn (operands[0], operands[1]);
19082 })
19083
19084 (define_peephole2
19085 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19086 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19087 (match_operand:HI 2 "immediate_operand" "")))
19088 (clobber (reg:CC 17))])
19089 (match_scratch:HI 3 "r")]
19090 "TARGET_K8 && !optimize_size"
19091 [(set (match_dup 3) (match_dup 2))
19092 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19093 (clobber (reg:CC 17))])]
19094 {
19095 if (!rtx_equal_p (operands[0], operands[1]))
19096 emit_move_insn (operands[0], operands[1]);
19097 })
19098 \f
19099 ;; Call-value patterns last so that the wildcard operand does not
19100 ;; disrupt insn-recog's switch tables.
19101
19102 (define_insn "*call_value_pop_0"
19103 [(set (match_operand 0 "" "")
19104 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19105 (match_operand:SI 2 "" "")))
19106 (set (reg:SI 7) (plus:SI (reg:SI 7)
19107 (match_operand:SI 3 "immediate_operand" "")))]
19108 "!TARGET_64BIT"
19109 {
19110 if (SIBLING_CALL_P (insn))
19111 return "jmp\t%P1";
19112 else
19113 return "call\t%P1";
19114 }
19115 [(set_attr "type" "callv")])
19116
19117 (define_insn "*call_value_pop_1"
19118 [(set (match_operand 0 "" "")
19119 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19120 (match_operand:SI 2 "" "")))
19121 (set (reg:SI 7) (plus:SI (reg:SI 7)
19122 (match_operand:SI 3 "immediate_operand" "i")))]
19123 "!TARGET_64BIT"
19124 {
19125 if (constant_call_address_operand (operands[1], QImode))
19126 {
19127 if (SIBLING_CALL_P (insn))
19128 return "jmp\t%P1";
19129 else
19130 return "call\t%P1";
19131 }
19132 if (SIBLING_CALL_P (insn))
19133 return "jmp\t%A1";
19134 else
19135 return "call\t%A1";
19136 }
19137 [(set_attr "type" "callv")])
19138
19139 (define_insn "*call_value_0"
19140 [(set (match_operand 0 "" "")
19141 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19142 (match_operand:SI 2 "" "")))]
19143 "!TARGET_64BIT"
19144 {
19145 if (SIBLING_CALL_P (insn))
19146 return "jmp\t%P1";
19147 else
19148 return "call\t%P1";
19149 }
19150 [(set_attr "type" "callv")])
19151
19152 (define_insn "*call_value_0_rex64"
19153 [(set (match_operand 0 "" "")
19154 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19155 (match_operand:DI 2 "const_int_operand" "")))]
19156 "TARGET_64BIT"
19157 {
19158 if (SIBLING_CALL_P (insn))
19159 return "jmp\t%P1";
19160 else
19161 return "call\t%P1";
19162 }
19163 [(set_attr "type" "callv")])
19164
19165 (define_insn "*call_value_1"
19166 [(set (match_operand 0 "" "")
19167 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19168 (match_operand:SI 2 "" "")))]
19169 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19170 {
19171 if (constant_call_address_operand (operands[1], QImode))
19172 return "call\t%P1";
19173 return "call\t%*%1";
19174 }
19175 [(set_attr "type" "callv")])
19176
19177 (define_insn "*sibcall_value_1"
19178 [(set (match_operand 0 "" "")
19179 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19180 (match_operand:SI 2 "" "")))]
19181 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19182 {
19183 if (constant_call_address_operand (operands[1], QImode))
19184 return "jmp\t%P1";
19185 return "jmp\t%*%1";
19186 }
19187 [(set_attr "type" "callv")])
19188
19189 (define_insn "*call_value_1_rex64"
19190 [(set (match_operand 0 "" "")
19191 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19192 (match_operand:DI 2 "" "")))]
19193 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19194 {
19195 if (constant_call_address_operand (operands[1], QImode))
19196 return "call\t%P1";
19197 return "call\t%A1";
19198 }
19199 [(set_attr "type" "callv")])
19200
19201 (define_insn "*sibcall_value_1_rex64"
19202 [(set (match_operand 0 "" "")
19203 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19204 (match_operand:DI 2 "" "")))]
19205 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19206 "jmp\t%P1"
19207 [(set_attr "type" "callv")])
19208
19209 (define_insn "*sibcall_value_1_rex64_v"
19210 [(set (match_operand 0 "" "")
19211 (call (mem:QI (reg:DI 40))
19212 (match_operand:DI 1 "" "")))]
19213 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19214 "jmp\t*%%r11"
19215 [(set_attr "type" "callv")])
19216 \f
19217 (define_insn "trap"
19218 [(trap_if (const_int 1) (const_int 5))]
19219 ""
19220 "int\t$5")
19221
19222 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19223 ;;; for the sake of bounds checking. By emitting bounds checks as
19224 ;;; conditional traps rather than as conditional jumps around
19225 ;;; unconditional traps we avoid introducing spurious basic-block
19226 ;;; boundaries and facilitate elimination of redundant checks. In
19227 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19228 ;;; interrupt 5.
19229 ;;;
19230 ;;; FIXME: Static branch prediction rules for ix86 are such that
19231 ;;; forward conditional branches predict as untaken. As implemented
19232 ;;; below, pseudo conditional traps violate that rule. We should use
19233 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19234 ;;; section loaded at the end of the text segment and branch forward
19235 ;;; there on bounds-failure, and then jump back immediately (in case
19236 ;;; the system chooses to ignore bounds violations, or to report
19237 ;;; violations and continue execution).
19238
19239 (define_expand "conditional_trap"
19240 [(trap_if (match_operator 0 "comparison_operator"
19241 [(match_dup 2) (const_int 0)])
19242 (match_operand 1 "const_int_operand" ""))]
19243 ""
19244 {
19245 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19246 ix86_expand_compare (GET_CODE (operands[0]),
19247 NULL, NULL),
19248 operands[1]));
19249 DONE;
19250 })
19251
19252 (define_insn "*conditional_trap_1"
19253 [(trap_if (match_operator 0 "comparison_operator"
19254 [(reg 17) (const_int 0)])
19255 (match_operand 1 "const_int_operand" ""))]
19256 ""
19257 {
19258 operands[2] = gen_label_rtx ();
19259 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19260 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19261 CODE_LABEL_NUMBER (operands[2]));
19262 RET;
19263 })
19264
19265 ;; Pentium III SIMD instructions.
19266
19267 ;; Moves for SSE/MMX regs.
19268
19269 (define_insn "movv4sf_internal"
19270 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19271 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19272 "TARGET_SSE"
19273 "@
19274 xorps\t%0, %0
19275 movaps\t{%1, %0|%0, %1}
19276 movaps\t{%1, %0|%0, %1}"
19277 [(set_attr "type" "ssemov")
19278 (set_attr "mode" "V4SF")])
19279
19280 (define_split
19281 [(set (match_operand:V4SF 0 "register_operand" "")
19282 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19283 "TARGET_SSE"
19284 [(set (match_dup 0)
19285 (vec_merge:V4SF
19286 (vec_duplicate:V4SF (match_dup 1))
19287 (match_dup 2)
19288 (const_int 1)))]
19289 {
19290 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19291 operands[2] = CONST0_RTX (V4SFmode);
19292 })
19293
19294 (define_insn "movv4si_internal"
19295 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19296 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19297 "TARGET_SSE"
19298 {
19299 switch (which_alternative)
19300 {
19301 case 0:
19302 if (get_attr_mode (insn) == MODE_V4SF)
19303 return "xorps\t%0, %0";
19304 else
19305 return "pxor\t%0, %0";
19306 case 1:
19307 case 2:
19308 if (get_attr_mode (insn) == MODE_V4SF)
19309 return "movaps\t{%1, %0|%0, %1}";
19310 else
19311 return "movdqa\t{%1, %0|%0, %1}";
19312 default:
19313 abort ();
19314 }
19315 }
19316 [(set_attr "type" "ssemov")
19317 (set (attr "mode")
19318 (cond [(eq_attr "alternative" "0,1")
19319 (if_then_else
19320 (ne (symbol_ref "optimize_size")
19321 (const_int 0))
19322 (const_string "V4SF")
19323 (const_string "TI"))
19324 (eq_attr "alternative" "2")
19325 (if_then_else
19326 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19327 (const_int 0))
19328 (ne (symbol_ref "optimize_size")
19329 (const_int 0)))
19330 (const_string "V4SF")
19331 (const_string "TI"))]
19332 (const_string "TI")))])
19333
19334 (define_insn "movv2di_internal"
19335 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19336 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19337 "TARGET_SSE"
19338 {
19339 switch (which_alternative)
19340 {
19341 case 0:
19342 if (get_attr_mode (insn) == MODE_V4SF)
19343 return "xorps\t%0, %0";
19344 else
19345 return "pxor\t%0, %0";
19346 case 1:
19347 case 2:
19348 if (get_attr_mode (insn) == MODE_V4SF)
19349 return "movaps\t{%1, %0|%0, %1}";
19350 else
19351 return "movdqa\t{%1, %0|%0, %1}";
19352 default:
19353 abort ();
19354 }
19355 }
19356 [(set_attr "type" "ssemov")
19357 (set (attr "mode")
19358 (cond [(eq_attr "alternative" "0,1")
19359 (if_then_else
19360 (ne (symbol_ref "optimize_size")
19361 (const_int 0))
19362 (const_string "V4SF")
19363 (const_string "TI"))
19364 (eq_attr "alternative" "2")
19365 (if_then_else
19366 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19367 (const_int 0))
19368 (ne (symbol_ref "optimize_size")
19369 (const_int 0)))
19370 (const_string "V4SF")
19371 (const_string "TI"))]
19372 (const_string "TI")))])
19373
19374 (define_split
19375 [(set (match_operand:V2DF 0 "register_operand" "")
19376 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19377 "TARGET_SSE2"
19378 [(set (match_dup 0)
19379 (vec_merge:V2DF
19380 (vec_duplicate:V2DF (match_dup 1))
19381 (match_dup 2)
19382 (const_int 1)))]
19383 {
19384 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19385 operands[2] = CONST0_RTX (V2DFmode);
19386 })
19387
19388 (define_insn "movv8qi_internal"
19389 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19390 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19391 "TARGET_MMX
19392 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19393 "@
19394 pxor\t%0, %0
19395 movq\t{%1, %0|%0, %1}
19396 movq\t{%1, %0|%0, %1}"
19397 [(set_attr "type" "mmxmov")
19398 (set_attr "mode" "DI")])
19399
19400 (define_insn "movv4hi_internal"
19401 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19402 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19403 "TARGET_MMX
19404 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19405 "@
19406 pxor\t%0, %0
19407 movq\t{%1, %0|%0, %1}
19408 movq\t{%1, %0|%0, %1}"
19409 [(set_attr "type" "mmxmov")
19410 (set_attr "mode" "DI")])
19411
19412 (define_insn "movv2si_internal"
19413 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19414 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19415 "TARGET_MMX
19416 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19417 "@
19418 pxor\t%0, %0
19419 movq\t{%1, %0|%0, %1}
19420 movq\t{%1, %0|%0, %1}"
19421 [(set_attr "type" "mmxcvt")
19422 (set_attr "mode" "DI")])
19423
19424 (define_insn "movv2sf_internal"
19425 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19426 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19427 "TARGET_3DNOW
19428 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19429 "@
19430 pxor\t%0, %0
19431 movq\t{%1, %0|%0, %1}
19432 movq\t{%1, %0|%0, %1}"
19433 [(set_attr "type" "mmxcvt")
19434 (set_attr "mode" "DI")])
19435
19436 (define_expand "movti"
19437 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19438 (match_operand:TI 1 "nonimmediate_operand" ""))]
19439 "TARGET_SSE || TARGET_64BIT"
19440 {
19441 if (TARGET_64BIT)
19442 ix86_expand_move (TImode, operands);
19443 else
19444 ix86_expand_vector_move (TImode, operands);
19445 DONE;
19446 })
19447
19448 (define_expand "movtf"
19449 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19450 (match_operand:TF 1 "nonimmediate_operand" ""))]
19451 "TARGET_64BIT"
19452 {
19453 if (TARGET_64BIT)
19454 ix86_expand_move (TFmode, operands);
19455 else
19456 ix86_expand_vector_move (TFmode, operands);
19457 DONE;
19458 })
19459
19460 (define_insn "movv2df_internal"
19461 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19462 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19463 "TARGET_SSE2
19464 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19465 {
19466 switch (which_alternative)
19467 {
19468 case 0:
19469 if (get_attr_mode (insn) == MODE_V4SF)
19470 return "xorps\t%0, %0";
19471 else
19472 return "xorpd\t%0, %0";
19473 case 1:
19474 case 2:
19475 if (get_attr_mode (insn) == MODE_V4SF)
19476 return "movaps\t{%1, %0|%0, %1}";
19477 else
19478 return "movapd\t{%1, %0|%0, %1}";
19479 default:
19480 abort ();
19481 }
19482 }
19483 [(set_attr "type" "ssemov")
19484 (set (attr "mode")
19485 (cond [(eq_attr "alternative" "0,1")
19486 (if_then_else
19487 (ne (symbol_ref "optimize_size")
19488 (const_int 0))
19489 (const_string "V4SF")
19490 (const_string "V2DF"))
19491 (eq_attr "alternative" "2")
19492 (if_then_else
19493 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19494 (const_int 0))
19495 (ne (symbol_ref "optimize_size")
19496 (const_int 0)))
19497 (const_string "V4SF")
19498 (const_string "V2DF"))]
19499 (const_string "V2DF")))])
19500
19501 (define_insn "movv8hi_internal"
19502 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19503 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19504 "TARGET_SSE2
19505 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19506 {
19507 switch (which_alternative)
19508 {
19509 case 0:
19510 if (get_attr_mode (insn) == MODE_V4SF)
19511 return "xorps\t%0, %0";
19512 else
19513 return "pxor\t%0, %0";
19514 case 1:
19515 case 2:
19516 if (get_attr_mode (insn) == MODE_V4SF)
19517 return "movaps\t{%1, %0|%0, %1}";
19518 else
19519 return "movdqa\t{%1, %0|%0, %1}";
19520 default:
19521 abort ();
19522 }
19523 }
19524 [(set_attr "type" "ssemov")
19525 (set (attr "mode")
19526 (cond [(eq_attr "alternative" "0,1")
19527 (if_then_else
19528 (ne (symbol_ref "optimize_size")
19529 (const_int 0))
19530 (const_string "V4SF")
19531 (const_string "TI"))
19532 (eq_attr "alternative" "2")
19533 (if_then_else
19534 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19535 (const_int 0))
19536 (ne (symbol_ref "optimize_size")
19537 (const_int 0)))
19538 (const_string "V4SF")
19539 (const_string "TI"))]
19540 (const_string "TI")))])
19541
19542 (define_insn "movv16qi_internal"
19543 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19544 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19545 "TARGET_SSE2
19546 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19547 {
19548 switch (which_alternative)
19549 {
19550 case 0:
19551 if (get_attr_mode (insn) == MODE_V4SF)
19552 return "xorps\t%0, %0";
19553 else
19554 return "pxor\t%0, %0";
19555 case 1:
19556 case 2:
19557 if (get_attr_mode (insn) == MODE_V4SF)
19558 return "movaps\t{%1, %0|%0, %1}";
19559 else
19560 return "movdqa\t{%1, %0|%0, %1}";
19561 default:
19562 abort ();
19563 }
19564 }
19565 [(set_attr "type" "ssemov")
19566 (set (attr "mode")
19567 (cond [(eq_attr "alternative" "0,1")
19568 (if_then_else
19569 (ne (symbol_ref "optimize_size")
19570 (const_int 0))
19571 (const_string "V4SF")
19572 (const_string "TI"))
19573 (eq_attr "alternative" "2")
19574 (if_then_else
19575 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19576 (const_int 0))
19577 (ne (symbol_ref "optimize_size")
19578 (const_int 0)))
19579 (const_string "V4SF")
19580 (const_string "TI"))]
19581 (const_string "TI")))])
19582
19583 (define_expand "movv2df"
19584 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19585 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19586 "TARGET_SSE2"
19587 {
19588 ix86_expand_vector_move (V2DFmode, operands);
19589 DONE;
19590 })
19591
19592 (define_expand "movv8hi"
19593 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19594 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19595 "TARGET_SSE2"
19596 {
19597 ix86_expand_vector_move (V8HImode, operands);
19598 DONE;
19599 })
19600
19601 (define_expand "movv16qi"
19602 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19603 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19604 "TARGET_SSE2"
19605 {
19606 ix86_expand_vector_move (V16QImode, operands);
19607 DONE;
19608 })
19609
19610 (define_expand "movv4sf"
19611 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19612 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19613 "TARGET_SSE"
19614 {
19615 ix86_expand_vector_move (V4SFmode, operands);
19616 DONE;
19617 })
19618
19619 (define_expand "movv4si"
19620 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19621 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19622 "TARGET_SSE"
19623 {
19624 ix86_expand_vector_move (V4SImode, operands);
19625 DONE;
19626 })
19627
19628 (define_expand "movv2di"
19629 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19630 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19631 "TARGET_SSE"
19632 {
19633 ix86_expand_vector_move (V2DImode, operands);
19634 DONE;
19635 })
19636
19637 (define_expand "movv2si"
19638 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19639 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19640 "TARGET_MMX"
19641 {
19642 ix86_expand_vector_move (V2SImode, operands);
19643 DONE;
19644 })
19645
19646 (define_expand "movv4hi"
19647 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19648 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19649 "TARGET_MMX"
19650 {
19651 ix86_expand_vector_move (V4HImode, operands);
19652 DONE;
19653 })
19654
19655 (define_expand "movv8qi"
19656 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19657 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19658 "TARGET_MMX"
19659 {
19660 ix86_expand_vector_move (V8QImode, operands);
19661 DONE;
19662 })
19663
19664 (define_expand "movv2sf"
19665 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19666 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19667 "TARGET_3DNOW"
19668 {
19669 ix86_expand_vector_move (V2SFmode, operands);
19670 DONE;
19671 })
19672
19673 (define_insn "*pushti"
19674 [(set (match_operand:TI 0 "push_operand" "=<")
19675 (match_operand:TI 1 "register_operand" "x"))]
19676 "TARGET_SSE"
19677 "#")
19678
19679 (define_insn "*pushv2df"
19680 [(set (match_operand:V2DF 0 "push_operand" "=<")
19681 (match_operand:V2DF 1 "register_operand" "x"))]
19682 "TARGET_SSE"
19683 "#")
19684
19685 (define_insn "*pushv2di"
19686 [(set (match_operand:V2DI 0 "push_operand" "=<")
19687 (match_operand:V2DI 1 "register_operand" "x"))]
19688 "TARGET_SSE2"
19689 "#")
19690
19691 (define_insn "*pushv8hi"
19692 [(set (match_operand:V8HI 0 "push_operand" "=<")
19693 (match_operand:V8HI 1 "register_operand" "x"))]
19694 "TARGET_SSE2"
19695 "#")
19696
19697 (define_insn "*pushv16qi"
19698 [(set (match_operand:V16QI 0 "push_operand" "=<")
19699 (match_operand:V16QI 1 "register_operand" "x"))]
19700 "TARGET_SSE2"
19701 "#")
19702
19703 (define_insn "*pushv4sf"
19704 [(set (match_operand:V4SF 0 "push_operand" "=<")
19705 (match_operand:V4SF 1 "register_operand" "x"))]
19706 "TARGET_SSE"
19707 "#")
19708
19709 (define_insn "*pushv4si"
19710 [(set (match_operand:V4SI 0 "push_operand" "=<")
19711 (match_operand:V4SI 1 "register_operand" "x"))]
19712 "TARGET_SSE2"
19713 "#")
19714
19715 (define_insn "*pushv2si"
19716 [(set (match_operand:V2SI 0 "push_operand" "=<")
19717 (match_operand:V2SI 1 "register_operand" "y"))]
19718 "TARGET_MMX"
19719 "#")
19720
19721 (define_insn "*pushv4hi"
19722 [(set (match_operand:V4HI 0 "push_operand" "=<")
19723 (match_operand:V4HI 1 "register_operand" "y"))]
19724 "TARGET_MMX"
19725 "#")
19726
19727 (define_insn "*pushv8qi"
19728 [(set (match_operand:V8QI 0 "push_operand" "=<")
19729 (match_operand:V8QI 1 "register_operand" "y"))]
19730 "TARGET_MMX"
19731 "#")
19732
19733 (define_insn "*pushv2sf"
19734 [(set (match_operand:V2SF 0 "push_operand" "=<")
19735 (match_operand:V2SF 1 "register_operand" "y"))]
19736 "TARGET_3DNOW"
19737 "#")
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:SI 7) (plus:SI (reg:SI 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 (define_split
19751 [(set (match_operand 0 "push_operand" "")
19752 (match_operand 1 "register_operand" ""))]
19753 "TARGET_64BIT && reload_completed
19754 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19755 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19756 (set (match_dup 2) (match_dup 1))]
19757 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19758 stack_pointer_rtx);
19759 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19760
19761
19762 (define_insn "movti_internal"
19763 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19764 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19765 "TARGET_SSE && !TARGET_64BIT
19766 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19767 {
19768 switch (which_alternative)
19769 {
19770 case 0:
19771 if (get_attr_mode (insn) == MODE_V4SF)
19772 return "xorps\t%0, %0";
19773 else
19774 return "pxor\t%0, %0";
19775 case 1:
19776 case 2:
19777 if (get_attr_mode (insn) == MODE_V4SF)
19778 return "movaps\t{%1, %0|%0, %1}";
19779 else
19780 return "movdqa\t{%1, %0|%0, %1}";
19781 default:
19782 abort ();
19783 }
19784 }
19785 [(set_attr "type" "ssemov,ssemov,ssemov")
19786 (set (attr "mode")
19787 (cond [(eq_attr "alternative" "0,1")
19788 (if_then_else
19789 (ne (symbol_ref "optimize_size")
19790 (const_int 0))
19791 (const_string "V4SF")
19792 (const_string "TI"))
19793 (eq_attr "alternative" "2")
19794 (if_then_else
19795 (ne (symbol_ref "optimize_size")
19796 (const_int 0))
19797 (const_string "V4SF")
19798 (const_string "TI"))]
19799 (const_string "TI")))])
19800
19801 (define_insn "*movti_rex64"
19802 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19803 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19804 "TARGET_64BIT
19805 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19806 {
19807 switch (which_alternative)
19808 {
19809 case 0:
19810 case 1:
19811 return "#";
19812 case 2:
19813 if (get_attr_mode (insn) == MODE_V4SF)
19814 return "xorps\t%0, %0";
19815 else
19816 return "pxor\t%0, %0";
19817 case 3:
19818 case 4:
19819 if (get_attr_mode (insn) == MODE_V4SF)
19820 return "movaps\t{%1, %0|%0, %1}";
19821 else
19822 return "movdqa\t{%1, %0|%0, %1}";
19823 default:
19824 abort ();
19825 }
19826 }
19827 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19828 (set (attr "mode")
19829 (cond [(eq_attr "alternative" "2,3")
19830 (if_then_else
19831 (ne (symbol_ref "optimize_size")
19832 (const_int 0))
19833 (const_string "V4SF")
19834 (const_string "TI"))
19835 (eq_attr "alternative" "4")
19836 (if_then_else
19837 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19838 (const_int 0))
19839 (ne (symbol_ref "optimize_size")
19840 (const_int 0)))
19841 (const_string "V4SF")
19842 (const_string "TI"))]
19843 (const_string "DI")))])
19844
19845 (define_insn "*movtf_rex64"
19846 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19847 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19848 "TARGET_64BIT
19849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19850 {
19851 switch (which_alternative)
19852 {
19853 case 0:
19854 case 1:
19855 return "#";
19856 case 2:
19857 if (get_attr_mode (insn) == MODE_V4SF)
19858 return "xorps\t%0, %0";
19859 else
19860 return "pxor\t%0, %0";
19861 case 3:
19862 case 4:
19863 if (get_attr_mode (insn) == MODE_V4SF)
19864 return "movaps\t{%1, %0|%0, %1}";
19865 else
19866 return "movdqa\t{%1, %0|%0, %1}";
19867 default:
19868 abort ();
19869 }
19870 }
19871 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19872 (set (attr "mode")
19873 (cond [(eq_attr "alternative" "2,3")
19874 (if_then_else
19875 (ne (symbol_ref "optimize_size")
19876 (const_int 0))
19877 (const_string "V4SF")
19878 (const_string "TI"))
19879 (eq_attr "alternative" "4")
19880 (if_then_else
19881 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19882 (const_int 0))
19883 (ne (symbol_ref "optimize_size")
19884 (const_int 0)))
19885 (const_string "V4SF")
19886 (const_string "TI"))]
19887 (const_string "DI")))])
19888
19889 (define_split
19890 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19891 (match_operand:TI 1 "general_operand" ""))]
19892 "reload_completed && !SSE_REG_P (operands[0])
19893 && !SSE_REG_P (operands[1])"
19894 [(const_int 0)]
19895 "ix86_split_long_move (operands); DONE;")
19896
19897 (define_split
19898 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19899 (match_operand:TF 1 "general_operand" ""))]
19900 "reload_completed && !SSE_REG_P (operands[0])
19901 && !SSE_REG_P (operands[1])"
19902 [(const_int 0)]
19903 "ix86_split_long_move (operands); DONE;")
19904
19905 ;; These two patterns are useful for specifying exactly whether to use
19906 ;; movaps or movups
19907 (define_expand "sse_movaps"
19908 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19909 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19910 UNSPEC_MOVA))]
19911 "TARGET_SSE"
19912 {
19913 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19914 {
19915 rtx tmp = gen_reg_rtx (V4SFmode);
19916 emit_insn (gen_sse_movaps (tmp, operands[1]));
19917 emit_move_insn (operands[0], tmp);
19918 DONE;
19919 }
19920 })
19921
19922 (define_insn "*sse_movaps_1"
19923 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19924 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19925 UNSPEC_MOVA))]
19926 "TARGET_SSE
19927 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19928 "movaps\t{%1, %0|%0, %1}"
19929 [(set_attr "type" "ssemov,ssemov")
19930 (set_attr "mode" "V4SF")])
19931
19932 (define_expand "sse_movups"
19933 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19934 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19935 UNSPEC_MOVU))]
19936 "TARGET_SSE"
19937 {
19938 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19939 {
19940 rtx tmp = gen_reg_rtx (V4SFmode);
19941 emit_insn (gen_sse_movups (tmp, operands[1]));
19942 emit_move_insn (operands[0], tmp);
19943 DONE;
19944 }
19945 })
19946
19947 (define_insn "*sse_movups_1"
19948 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19949 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19950 UNSPEC_MOVU))]
19951 "TARGET_SSE
19952 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19953 "movups\t{%1, %0|%0, %1}"
19954 [(set_attr "type" "ssecvt,ssecvt")
19955 (set_attr "mode" "V4SF")])
19956
19957 ;; SSE Strange Moves.
19958
19959 (define_insn "sse_movmskps"
19960 [(set (match_operand:SI 0 "register_operand" "=r")
19961 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19962 UNSPEC_MOVMSK))]
19963 "TARGET_SSE"
19964 "movmskps\t{%1, %0|%0, %1}"
19965 [(set_attr "type" "ssecvt")
19966 (set_attr "mode" "V4SF")])
19967
19968 (define_insn "mmx_pmovmskb"
19969 [(set (match_operand:SI 0 "register_operand" "=r")
19970 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19971 UNSPEC_MOVMSK))]
19972 "TARGET_SSE || TARGET_3DNOW_A"
19973 "pmovmskb\t{%1, %0|%0, %1}"
19974 [(set_attr "type" "ssecvt")
19975 (set_attr "mode" "V4SF")])
19976
19977
19978 (define_insn "mmx_maskmovq"
19979 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19980 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19981 (match_operand:V8QI 2 "register_operand" "y")]
19982 UNSPEC_MASKMOV))]
19983 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19984 ;; @@@ check ordering of operands in intel/nonintel syntax
19985 "maskmovq\t{%2, %1|%1, %2}"
19986 [(set_attr "type" "mmxcvt")
19987 (set_attr "mode" "DI")])
19988
19989 (define_insn "mmx_maskmovq_rex"
19990 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19991 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19992 (match_operand:V8QI 2 "register_operand" "y")]
19993 UNSPEC_MASKMOV))]
19994 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19995 ;; @@@ check ordering of operands in intel/nonintel syntax
19996 "maskmovq\t{%2, %1|%1, %2}"
19997 [(set_attr "type" "mmxcvt")
19998 (set_attr "mode" "DI")])
19999
20000 (define_insn "sse_movntv4sf"
20001 [(set (match_operand:V4SF 0 "memory_operand" "=m")
20002 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20003 UNSPEC_MOVNT))]
20004 "TARGET_SSE"
20005 "movntps\t{%1, %0|%0, %1}"
20006 [(set_attr "type" "ssemov")
20007 (set_attr "mode" "V4SF")])
20008
20009 (define_insn "sse_movntdi"
20010 [(set (match_operand:DI 0 "memory_operand" "=m")
20011 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20012 UNSPEC_MOVNT))]
20013 "TARGET_SSE || TARGET_3DNOW_A"
20014 "movntq\t{%1, %0|%0, %1}"
20015 [(set_attr "type" "mmxmov")
20016 (set_attr "mode" "DI")])
20017
20018 (define_insn "sse_movhlps"
20019 [(set (match_operand:V4SF 0 "register_operand" "=x")
20020 (vec_merge:V4SF
20021 (match_operand:V4SF 1 "register_operand" "0")
20022 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20023 (parallel [(const_int 2)
20024 (const_int 3)
20025 (const_int 0)
20026 (const_int 1)]))
20027 (const_int 3)))]
20028 "TARGET_SSE"
20029 "movhlps\t{%2, %0|%0, %2}"
20030 [(set_attr "type" "ssecvt")
20031 (set_attr "mode" "V4SF")])
20032
20033 (define_insn "sse_movlhps"
20034 [(set (match_operand:V4SF 0 "register_operand" "=x")
20035 (vec_merge:V4SF
20036 (match_operand:V4SF 1 "register_operand" "0")
20037 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20038 (parallel [(const_int 2)
20039 (const_int 3)
20040 (const_int 0)
20041 (const_int 1)]))
20042 (const_int 12)))]
20043 "TARGET_SSE"
20044 "movlhps\t{%2, %0|%0, %2}"
20045 [(set_attr "type" "ssecvt")
20046 (set_attr "mode" "V4SF")])
20047
20048 (define_insn "sse_movhps"
20049 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20050 (vec_merge:V4SF
20051 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20052 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20053 (const_int 12)))]
20054 "TARGET_SSE
20055 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20056 "movhps\t{%2, %0|%0, %2}"
20057 [(set_attr "type" "ssecvt")
20058 (set_attr "mode" "V4SF")])
20059
20060 (define_insn "sse_movlps"
20061 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20062 (vec_merge:V4SF
20063 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20064 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20065 (const_int 3)))]
20066 "TARGET_SSE
20067 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20068 "movlps\t{%2, %0|%0, %2}"
20069 [(set_attr "type" "ssecvt")
20070 (set_attr "mode" "V4SF")])
20071
20072 (define_expand "sse_loadss"
20073 [(match_operand:V4SF 0 "register_operand" "")
20074 (match_operand:SF 1 "memory_operand" "")]
20075 "TARGET_SSE"
20076 {
20077 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20078 CONST0_RTX (V4SFmode)));
20079 DONE;
20080 })
20081
20082 (define_insn "sse_loadss_1"
20083 [(set (match_operand:V4SF 0 "register_operand" "=x")
20084 (vec_merge:V4SF
20085 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20086 (match_operand:V4SF 2 "const0_operand" "X")
20087 (const_int 1)))]
20088 "TARGET_SSE"
20089 "movss\t{%1, %0|%0, %1}"
20090 [(set_attr "type" "ssemov")
20091 (set_attr "mode" "SF")])
20092
20093 (define_insn "sse_movss"
20094 [(set (match_operand:V4SF 0 "register_operand" "=x")
20095 (vec_merge:V4SF
20096 (match_operand:V4SF 1 "register_operand" "0")
20097 (match_operand:V4SF 2 "register_operand" "x")
20098 (const_int 1)))]
20099 "TARGET_SSE"
20100 "movss\t{%2, %0|%0, %2}"
20101 [(set_attr "type" "ssemov")
20102 (set_attr "mode" "SF")])
20103
20104 (define_insn "sse_storess"
20105 [(set (match_operand:SF 0 "memory_operand" "=m")
20106 (vec_select:SF
20107 (match_operand:V4SF 1 "register_operand" "x")
20108 (parallel [(const_int 0)])))]
20109 "TARGET_SSE"
20110 "movss\t{%1, %0|%0, %1}"
20111 [(set_attr "type" "ssemov")
20112 (set_attr "mode" "SF")])
20113
20114 (define_insn "sse_shufps"
20115 [(set (match_operand:V4SF 0 "register_operand" "=x")
20116 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20117 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20118 (match_operand:SI 3 "immediate_operand" "i")]
20119 UNSPEC_SHUFFLE))]
20120 "TARGET_SSE"
20121 ;; @@@ check operand order for intel/nonintel syntax
20122 "shufps\t{%3, %2, %0|%0, %2, %3}"
20123 [(set_attr "type" "ssecvt")
20124 (set_attr "mode" "V4SF")])
20125
20126
20127 ;; SSE arithmetic
20128
20129 (define_insn "addv4sf3"
20130 [(set (match_operand:V4SF 0 "register_operand" "=x")
20131 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20132 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20133 "TARGET_SSE"
20134 "addps\t{%2, %0|%0, %2}"
20135 [(set_attr "type" "sseadd")
20136 (set_attr "mode" "V4SF")])
20137
20138 (define_insn "vmaddv4sf3"
20139 [(set (match_operand:V4SF 0 "register_operand" "=x")
20140 (vec_merge:V4SF
20141 (plus: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 "addss\t{%2, %0|%0, %2}"
20147 [(set_attr "type" "sseadd")
20148 (set_attr "mode" "SF")])
20149
20150 (define_insn "subv4sf3"
20151 [(set (match_operand:V4SF 0 "register_operand" "=x")
20152 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20153 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20154 "TARGET_SSE"
20155 "subps\t{%2, %0|%0, %2}"
20156 [(set_attr "type" "sseadd")
20157 (set_attr "mode" "V4SF")])
20158
20159 (define_insn "vmsubv4sf3"
20160 [(set (match_operand:V4SF 0 "register_operand" "=x")
20161 (vec_merge:V4SF
20162 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20163 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20164 (match_dup 1)
20165 (const_int 1)))]
20166 "TARGET_SSE"
20167 "subss\t{%2, %0|%0, %2}"
20168 [(set_attr "type" "sseadd")
20169 (set_attr "mode" "SF")])
20170
20171 (define_insn "mulv4sf3"
20172 [(set (match_operand:V4SF 0 "register_operand" "=x")
20173 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20174 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20175 "TARGET_SSE"
20176 "mulps\t{%2, %0|%0, %2}"
20177 [(set_attr "type" "ssemul")
20178 (set_attr "mode" "V4SF")])
20179
20180 (define_insn "vmmulv4sf3"
20181 [(set (match_operand:V4SF 0 "register_operand" "=x")
20182 (vec_merge:V4SF
20183 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20184 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20185 (match_dup 1)
20186 (const_int 1)))]
20187 "TARGET_SSE"
20188 "mulss\t{%2, %0|%0, %2}"
20189 [(set_attr "type" "ssemul")
20190 (set_attr "mode" "SF")])
20191
20192 (define_insn "divv4sf3"
20193 [(set (match_operand:V4SF 0 "register_operand" "=x")
20194 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20195 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20196 "TARGET_SSE"
20197 "divps\t{%2, %0|%0, %2}"
20198 [(set_attr "type" "ssediv")
20199 (set_attr "mode" "V4SF")])
20200
20201 (define_insn "vmdivv4sf3"
20202 [(set (match_operand:V4SF 0 "register_operand" "=x")
20203 (vec_merge:V4SF
20204 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20205 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20206 (match_dup 1)
20207 (const_int 1)))]
20208 "TARGET_SSE"
20209 "divss\t{%2, %0|%0, %2}"
20210 [(set_attr "type" "ssediv")
20211 (set_attr "mode" "SF")])
20212
20213
20214 ;; SSE square root/reciprocal
20215
20216 (define_insn "rcpv4sf2"
20217 [(set (match_operand:V4SF 0 "register_operand" "=x")
20218 (unspec:V4SF
20219 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20220 "TARGET_SSE"
20221 "rcpps\t{%1, %0|%0, %1}"
20222 [(set_attr "type" "sse")
20223 (set_attr "mode" "V4SF")])
20224
20225 (define_insn "vmrcpv4sf2"
20226 [(set (match_operand:V4SF 0 "register_operand" "=x")
20227 (vec_merge:V4SF
20228 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20229 UNSPEC_RCP)
20230 (match_operand:V4SF 2 "register_operand" "0")
20231 (const_int 1)))]
20232 "TARGET_SSE"
20233 "rcpss\t{%1, %0|%0, %1}"
20234 [(set_attr "type" "sse")
20235 (set_attr "mode" "SF")])
20236
20237 (define_insn "rsqrtv4sf2"
20238 [(set (match_operand:V4SF 0 "register_operand" "=x")
20239 (unspec:V4SF
20240 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20241 "TARGET_SSE"
20242 "rsqrtps\t{%1, %0|%0, %1}"
20243 [(set_attr "type" "sse")
20244 (set_attr "mode" "V4SF")])
20245
20246 (define_insn "vmrsqrtv4sf2"
20247 [(set (match_operand:V4SF 0 "register_operand" "=x")
20248 (vec_merge:V4SF
20249 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20250 UNSPEC_RSQRT)
20251 (match_operand:V4SF 2 "register_operand" "0")
20252 (const_int 1)))]
20253 "TARGET_SSE"
20254 "rsqrtss\t{%1, %0|%0, %1}"
20255 [(set_attr "type" "sse")
20256 (set_attr "mode" "SF")])
20257
20258 (define_insn "sqrtv4sf2"
20259 [(set (match_operand:V4SF 0 "register_operand" "=x")
20260 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20261 "TARGET_SSE"
20262 "sqrtps\t{%1, %0|%0, %1}"
20263 [(set_attr "type" "sse")
20264 (set_attr "mode" "V4SF")])
20265
20266 (define_insn "vmsqrtv4sf2"
20267 [(set (match_operand:V4SF 0 "register_operand" "=x")
20268 (vec_merge:V4SF
20269 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20270 (match_operand:V4SF 2 "register_operand" "0")
20271 (const_int 1)))]
20272 "TARGET_SSE"
20273 "sqrtss\t{%1, %0|%0, %1}"
20274 [(set_attr "type" "sse")
20275 (set_attr "mode" "SF")])
20276
20277 ;; SSE logical operations.
20278
20279 ;; SSE defines logical operations on floating point values. This brings
20280 ;; interesting challenge to RTL representation where logicals are only valid
20281 ;; on integral types. We deal with this by representing the floating point
20282 ;; logical as logical on arguments casted to TImode as this is what hardware
20283 ;; really does. Unfortunately hardware requires the type information to be
20284 ;; present and thus we must avoid subregs from being simplified and eliminated
20285 ;; in later compilation phases.
20286 ;;
20287 ;; We have following variants from each instruction:
20288 ;; sse_andsf3 - the operation taking V4SF vector operands
20289 ;; and doing TImode cast on them
20290 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20291 ;; TImode, since backend insist on eliminating casts
20292 ;; on memory operands
20293 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20294 ;; We can not accept memory operand here as instruction reads
20295 ;; whole scalar. This is generated only post reload by GCC
20296 ;; scalar float operations that expands to logicals (fabs)
20297 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20298 ;; memory operand. Eventually combine can be able
20299 ;; to synthesize these using splitter.
20300 ;; sse2_anddf3, *sse2_anddf3_memory
20301 ;;
20302 ;;
20303 ;; These are not called andti3 etc. because we really really don't want
20304 ;; the compiler to widen DImode ands to TImode ands and then try to move
20305 ;; into DImode subregs of SSE registers, and them together, and move out
20306 ;; of DImode subregs again!
20307 ;; SSE1 single precision floating point logical operation
20308 (define_expand "sse_andv4sf3"
20309 [(set (match_operand:V4SF 0 "register_operand" "")
20310 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20311 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20312 "TARGET_SSE"
20313 "")
20314
20315 (define_insn "*sse_andv4sf3"
20316 [(set (match_operand:V4SF 0 "register_operand" "=x")
20317 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20318 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20319 "TARGET_SSE
20320 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20321 "andps\t{%2, %0|%0, %2}"
20322 [(set_attr "type" "sselog")
20323 (set_attr "mode" "V4SF")])
20324
20325 (define_expand "sse_nandv4sf3"
20326 [(set (match_operand:V4SF 0 "register_operand" "")
20327 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20328 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20329 "TARGET_SSE"
20330 "")
20331
20332 (define_insn "*sse_nandv4sf3"
20333 [(set (match_operand:V4SF 0 "register_operand" "=x")
20334 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20335 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20336 "TARGET_SSE"
20337 "andnps\t{%2, %0|%0, %2}"
20338 [(set_attr "type" "sselog")
20339 (set_attr "mode" "V4SF")])
20340
20341 (define_expand "sse_iorv4sf3"
20342 [(set (match_operand:V4SF 0 "register_operand" "")
20343 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20344 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20345 "TARGET_SSE"
20346 "")
20347
20348 (define_insn "*sse_iorv4sf3"
20349 [(set (match_operand:V4SF 0 "register_operand" "=x")
20350 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20351 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20352 "TARGET_SSE
20353 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20354 "orps\t{%2, %0|%0, %2}"
20355 [(set_attr "type" "sselog")
20356 (set_attr "mode" "V4SF")])
20357
20358 (define_expand "sse_xorv4sf3"
20359 [(set (match_operand:V4SF 0 "register_operand" "")
20360 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20361 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20362 "TARGET_SSE"
20363 "")
20364
20365 (define_insn "*sse_xorv4sf3"
20366 [(set (match_operand:V4SF 0 "register_operand" "=x")
20367 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20368 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20369 "TARGET_SSE
20370 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20371 "xorps\t{%2, %0|%0, %2}"
20372 [(set_attr "type" "sselog")
20373 (set_attr "mode" "V4SF")])
20374
20375 ;; SSE2 double precision floating point logical operation
20376
20377 (define_expand "sse2_andv2df3"
20378 [(set (match_operand:V2DF 0 "register_operand" "")
20379 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20380 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20381 "TARGET_SSE2"
20382 "")
20383
20384 (define_insn "*sse2_andv2df3"
20385 [(set (match_operand:V2DF 0 "register_operand" "=x")
20386 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20387 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20388 "TARGET_SSE2
20389 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20390 "andpd\t{%2, %0|%0, %2}"
20391 [(set_attr "type" "sselog")
20392 (set_attr "mode" "V2DF")])
20393
20394 (define_expand "sse2_nandv2df3"
20395 [(set (match_operand:V2DF 0 "register_operand" "")
20396 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20397 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20398 "TARGET_SSE2"
20399 "")
20400
20401 (define_insn "*sse2_nandv2df3"
20402 [(set (match_operand:V2DF 0 "register_operand" "=x")
20403 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20404 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20405 "TARGET_SSE2"
20406 "andnpd\t{%2, %0|%0, %2}"
20407 [(set_attr "type" "sselog")
20408 (set_attr "mode" "V2DF")])
20409
20410 (define_expand "sse2_iorv2df3"
20411 [(set (match_operand:V2DF 0 "register_operand" "")
20412 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20413 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20414 "TARGET_SSE2"
20415 "")
20416
20417 (define_insn "*sse2_iorv2df3"
20418 [(set (match_operand:V2DF 0 "register_operand" "=x")
20419 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20420 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20421 "TARGET_SSE2
20422 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20423 "orpd\t{%2, %0|%0, %2}"
20424 [(set_attr "type" "sselog")
20425 (set_attr "mode" "V2DF")])
20426
20427 (define_expand "sse2_xorv2df3"
20428 [(set (match_operand:V2DF 0 "register_operand" "")
20429 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20430 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20431 "TARGET_SSE2"
20432 "")
20433
20434 (define_insn "*sse2_xorv2df3"
20435 [(set (match_operand:V2DF 0 "register_operand" "=x")
20436 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20437 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20438 "TARGET_SSE2
20439 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20440 "xorpd\t{%2, %0|%0, %2}"
20441 [(set_attr "type" "sselog")
20442 (set_attr "mode" "V2DF")])
20443
20444 ;; SSE2 integral logicals. These patterns must always come after floating
20445 ;; point ones since we don't want compiler to use integer opcodes on floating
20446 ;; point SSE values to avoid matching of subregs in the match_operand.
20447 (define_insn "*sse2_andti3"
20448 [(set (match_operand:TI 0 "register_operand" "=x")
20449 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20450 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20451 "TARGET_SSE2
20452 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20453 "pand\t{%2, %0|%0, %2}"
20454 [(set_attr "type" "sselog")
20455 (set_attr "mode" "TI")])
20456
20457 (define_insn "sse2_andv2di3"
20458 [(set (match_operand:V2DI 0 "register_operand" "=x")
20459 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20460 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20461 "TARGET_SSE2
20462 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20463 "pand\t{%2, %0|%0, %2}"
20464 [(set_attr "type" "sselog")
20465 (set_attr "mode" "TI")])
20466
20467 (define_insn "*sse2_nandti3"
20468 [(set (match_operand:TI 0 "register_operand" "=x")
20469 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20470 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20471 "TARGET_SSE2"
20472 "pandn\t{%2, %0|%0, %2}"
20473 [(set_attr "type" "sselog")
20474 (set_attr "mode" "TI")])
20475
20476 (define_insn "sse2_nandv2di3"
20477 [(set (match_operand:V2DI 0 "register_operand" "=x")
20478 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20479 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20480 "TARGET_SSE2
20481 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20482 "pandn\t{%2, %0|%0, %2}"
20483 [(set_attr "type" "sselog")
20484 (set_attr "mode" "TI")])
20485
20486 (define_insn "*sse2_iorti3"
20487 [(set (match_operand:TI 0 "register_operand" "=x")
20488 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20489 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20490 "TARGET_SSE2
20491 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20492 "por\t{%2, %0|%0, %2}"
20493 [(set_attr "type" "sselog")
20494 (set_attr "mode" "TI")])
20495
20496 (define_insn "sse2_iorv2di3"
20497 [(set (match_operand:V2DI 0 "register_operand" "=x")
20498 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20499 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20500 "TARGET_SSE2
20501 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20502 "por\t{%2, %0|%0, %2}"
20503 [(set_attr "type" "sselog")
20504 (set_attr "mode" "TI")])
20505
20506 (define_insn "*sse2_xorti3"
20507 [(set (match_operand:TI 0 "register_operand" "=x")
20508 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20509 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20510 "TARGET_SSE2
20511 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20512 "pxor\t{%2, %0|%0, %2}"
20513 [(set_attr "type" "sselog")
20514 (set_attr "mode" "TI")])
20515
20516 (define_insn "sse2_xorv2di3"
20517 [(set (match_operand:V2DI 0 "register_operand" "=x")
20518 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20519 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20520 "TARGET_SSE2
20521 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20522 "pxor\t{%2, %0|%0, %2}"
20523 [(set_attr "type" "sselog")
20524 (set_attr "mode" "TI")])
20525
20526 ;; Use xor, but don't show input operands so they aren't live before
20527 ;; this insn.
20528 (define_insn "sse_clrv4sf"
20529 [(set (match_operand:V4SF 0 "register_operand" "=x")
20530 (match_operand:V4SF 1 "const0_operand" "X"))]
20531 "TARGET_SSE"
20532 {
20533 if (get_attr_mode (insn) == MODE_TI)
20534 return "pxor\t{%0, %0|%0, %0}";
20535 else
20536 return "xorps\t{%0, %0|%0, %0}";
20537 }
20538 [(set_attr "type" "sselog")
20539 (set_attr "memory" "none")
20540 (set (attr "mode")
20541 (if_then_else
20542 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20543 (const_int 0))
20544 (ne (symbol_ref "TARGET_SSE2")
20545 (const_int 0)))
20546 (eq (symbol_ref "optimize_size")
20547 (const_int 0)))
20548 (const_string "TI")
20549 (const_string "V4SF")))])
20550
20551 ;; Use xor, but don't show input operands so they aren't live before
20552 ;; this insn.
20553 (define_insn "sse_clrv2df"
20554 [(set (match_operand:V2DF 0 "register_operand" "=x")
20555 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20556 "TARGET_SSE2"
20557 "xorpd\t{%0, %0|%0, %0}"
20558 [(set_attr "type" "sselog")
20559 (set_attr "memory" "none")
20560 (set_attr "mode" "V4SF")])
20561
20562 ;; SSE mask-generating compares
20563
20564 (define_insn "maskcmpv4sf3"
20565 [(set (match_operand:V4SI 0 "register_operand" "=x")
20566 (match_operator:V4SI 3 "sse_comparison_operator"
20567 [(match_operand:V4SF 1 "register_operand" "0")
20568 (match_operand:V4SF 2 "register_operand" "x")]))]
20569 "TARGET_SSE"
20570 "cmp%D3ps\t{%2, %0|%0, %2}"
20571 [(set_attr "type" "ssecmp")
20572 (set_attr "mode" "V4SF")])
20573
20574 (define_insn "maskncmpv4sf3"
20575 [(set (match_operand:V4SI 0 "register_operand" "=x")
20576 (not:V4SI
20577 (match_operator:V4SI 3 "sse_comparison_operator"
20578 [(match_operand:V4SF 1 "register_operand" "0")
20579 (match_operand:V4SF 2 "register_operand" "x")])))]
20580 "TARGET_SSE"
20581 {
20582 if (GET_CODE (operands[3]) == UNORDERED)
20583 return "cmpordps\t{%2, %0|%0, %2}";
20584 else
20585 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20586 }
20587 [(set_attr "type" "ssecmp")
20588 (set_attr "mode" "V4SF")])
20589
20590 (define_insn "vmmaskcmpv4sf3"
20591 [(set (match_operand:V4SI 0 "register_operand" "=x")
20592 (vec_merge: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 (subreg:V4SI (match_dup 1) 0)
20597 (const_int 1)))]
20598 "TARGET_SSE"
20599 "cmp%D3ss\t{%2, %0|%0, %2}"
20600 [(set_attr "type" "ssecmp")
20601 (set_attr "mode" "SF")])
20602
20603 (define_insn "vmmaskncmpv4sf3"
20604 [(set (match_operand:V4SI 0 "register_operand" "=x")
20605 (vec_merge:V4SI
20606 (not:V4SI
20607 (match_operator:V4SI 3 "sse_comparison_operator"
20608 [(match_operand:V4SF 1 "register_operand" "0")
20609 (match_operand:V4SF 2 "register_operand" "x")]))
20610 (subreg:V4SI (match_dup 1) 0)
20611 (const_int 1)))]
20612 "TARGET_SSE"
20613 {
20614 if (GET_CODE (operands[3]) == UNORDERED)
20615 return "cmpordss\t{%2, %0|%0, %2}";
20616 else
20617 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20618 }
20619 [(set_attr "type" "ssecmp")
20620 (set_attr "mode" "SF")])
20621
20622 (define_insn "sse_comi"
20623 [(set (reg:CCFP 17)
20624 (compare:CCFP (vec_select:SF
20625 (match_operand:V4SF 0 "register_operand" "x")
20626 (parallel [(const_int 0)]))
20627 (vec_select:SF
20628 (match_operand:V4SF 1 "register_operand" "x")
20629 (parallel [(const_int 0)]))))]
20630 "TARGET_SSE"
20631 "comiss\t{%1, %0|%0, %1}"
20632 [(set_attr "type" "ssecomi")
20633 (set_attr "mode" "SF")])
20634
20635 (define_insn "sse_ucomi"
20636 [(set (reg:CCFPU 17)
20637 (compare:CCFPU (vec_select:SF
20638 (match_operand:V4SF 0 "register_operand" "x")
20639 (parallel [(const_int 0)]))
20640 (vec_select:SF
20641 (match_operand:V4SF 1 "register_operand" "x")
20642 (parallel [(const_int 0)]))))]
20643 "TARGET_SSE"
20644 "ucomiss\t{%1, %0|%0, %1}"
20645 [(set_attr "type" "ssecomi")
20646 (set_attr "mode" "SF")])
20647
20648
20649 ;; SSE unpack
20650
20651 (define_insn "sse_unpckhps"
20652 [(set (match_operand:V4SF 0 "register_operand" "=x")
20653 (vec_merge:V4SF
20654 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20655 (parallel [(const_int 2)
20656 (const_int 0)
20657 (const_int 3)
20658 (const_int 1)]))
20659 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20660 (parallel [(const_int 0)
20661 (const_int 2)
20662 (const_int 1)
20663 (const_int 3)]))
20664 (const_int 5)))]
20665 "TARGET_SSE"
20666 "unpckhps\t{%2, %0|%0, %2}"
20667 [(set_attr "type" "ssecvt")
20668 (set_attr "mode" "V4SF")])
20669
20670 (define_insn "sse_unpcklps"
20671 [(set (match_operand:V4SF 0 "register_operand" "=x")
20672 (vec_merge:V4SF
20673 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20674 (parallel [(const_int 0)
20675 (const_int 2)
20676 (const_int 1)
20677 (const_int 3)]))
20678 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20679 (parallel [(const_int 2)
20680 (const_int 0)
20681 (const_int 3)
20682 (const_int 1)]))
20683 (const_int 5)))]
20684 "TARGET_SSE"
20685 "unpcklps\t{%2, %0|%0, %2}"
20686 [(set_attr "type" "ssecvt")
20687 (set_attr "mode" "V4SF")])
20688
20689
20690 ;; SSE min/max
20691
20692 (define_insn "smaxv4sf3"
20693 [(set (match_operand:V4SF 0 "register_operand" "=x")
20694 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20695 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20696 "TARGET_SSE"
20697 "maxps\t{%2, %0|%0, %2}"
20698 [(set_attr "type" "sse")
20699 (set_attr "mode" "V4SF")])
20700
20701 (define_insn "vmsmaxv4sf3"
20702 [(set (match_operand:V4SF 0 "register_operand" "=x")
20703 (vec_merge:V4SF
20704 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20705 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20706 (match_dup 1)
20707 (const_int 1)))]
20708 "TARGET_SSE"
20709 "maxss\t{%2, %0|%0, %2}"
20710 [(set_attr "type" "sse")
20711 (set_attr "mode" "SF")])
20712
20713 (define_insn "sminv4sf3"
20714 [(set (match_operand:V4SF 0 "register_operand" "=x")
20715 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20716 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20717 "TARGET_SSE"
20718 "minps\t{%2, %0|%0, %2}"
20719 [(set_attr "type" "sse")
20720 (set_attr "mode" "V4SF")])
20721
20722 (define_insn "vmsminv4sf3"
20723 [(set (match_operand:V4SF 0 "register_operand" "=x")
20724 (vec_merge:V4SF
20725 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20726 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20727 (match_dup 1)
20728 (const_int 1)))]
20729 "TARGET_SSE"
20730 "minss\t{%2, %0|%0, %2}"
20731 [(set_attr "type" "sse")
20732 (set_attr "mode" "SF")])
20733
20734 ;; SSE <-> integer/MMX conversions
20735
20736 (define_insn "cvtpi2ps"
20737 [(set (match_operand:V4SF 0 "register_operand" "=x")
20738 (vec_merge:V4SF
20739 (match_operand:V4SF 1 "register_operand" "0")
20740 (vec_duplicate:V4SF
20741 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20742 (const_int 12)))]
20743 "TARGET_SSE"
20744 "cvtpi2ps\t{%2, %0|%0, %2}"
20745 [(set_attr "type" "ssecvt")
20746 (set_attr "mode" "V4SF")])
20747
20748 (define_insn "cvtps2pi"
20749 [(set (match_operand:V2SI 0 "register_operand" "=y")
20750 (vec_select:V2SI
20751 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20752 (parallel [(const_int 0) (const_int 1)])))]
20753 "TARGET_SSE"
20754 "cvtps2pi\t{%1, %0|%0, %1}"
20755 [(set_attr "type" "ssecvt")
20756 (set_attr "mode" "V4SF")])
20757
20758 (define_insn "cvttps2pi"
20759 [(set (match_operand:V2SI 0 "register_operand" "=y")
20760 (vec_select:V2SI
20761 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20762 UNSPEC_FIX)
20763 (parallel [(const_int 0) (const_int 1)])))]
20764 "TARGET_SSE"
20765 "cvttps2pi\t{%1, %0|%0, %1}"
20766 [(set_attr "type" "ssecvt")
20767 (set_attr "mode" "SF")])
20768
20769 (define_insn "cvtsi2ss"
20770 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20771 (vec_merge:V4SF
20772 (match_operand:V4SF 1 "register_operand" "0,0")
20773 (vec_duplicate:V4SF
20774 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20775 (const_int 14)))]
20776 "TARGET_SSE"
20777 "cvtsi2ss\t{%2, %0|%0, %2}"
20778 [(set_attr "type" "sseicvt")
20779 (set_attr "athlon_decode" "vector,double")
20780 (set_attr "mode" "SF")])
20781
20782 (define_insn "cvtsi2ssq"
20783 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20784 (vec_merge:V4SF
20785 (match_operand:V4SF 1 "register_operand" "0,0")
20786 (vec_duplicate:V4SF
20787 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20788 (const_int 14)))]
20789 "TARGET_SSE && TARGET_64BIT"
20790 "cvtsi2ssq\t{%2, %0|%0, %2}"
20791 [(set_attr "type" "sseicvt")
20792 (set_attr "athlon_decode" "vector,double")
20793 (set_attr "mode" "SF")])
20794
20795 (define_insn "cvtss2si"
20796 [(set (match_operand:SI 0 "register_operand" "=r,r")
20797 (vec_select:SI
20798 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20799 (parallel [(const_int 0)])))]
20800 "TARGET_SSE"
20801 "cvtss2si\t{%1, %0|%0, %1}"
20802 [(set_attr "type" "sseicvt")
20803 (set_attr "athlon_decode" "double,vector")
20804 (set_attr "mode" "SI")])
20805
20806 (define_insn "cvtss2siq"
20807 [(set (match_operand:DI 0 "register_operand" "=r,r")
20808 (vec_select:DI
20809 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20810 (parallel [(const_int 0)])))]
20811 "TARGET_SSE"
20812 "cvtss2siq\t{%1, %0|%0, %1}"
20813 [(set_attr "type" "sseicvt")
20814 (set_attr "athlon_decode" "double,vector")
20815 (set_attr "mode" "DI")])
20816
20817 (define_insn "cvttss2si"
20818 [(set (match_operand:SI 0 "register_operand" "=r,r")
20819 (vec_select:SI
20820 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20821 UNSPEC_FIX)
20822 (parallel [(const_int 0)])))]
20823 "TARGET_SSE"
20824 "cvttss2si\t{%1, %0|%0, %1}"
20825 [(set_attr "type" "sseicvt")
20826 (set_attr "mode" "SF")
20827 (set_attr "athlon_decode" "double,vector")])
20828
20829 (define_insn "cvttss2siq"
20830 [(set (match_operand:DI 0 "register_operand" "=r,r")
20831 (vec_select:DI
20832 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20833 UNSPEC_FIX)
20834 (parallel [(const_int 0)])))]
20835 "TARGET_SSE && TARGET_64BIT"
20836 "cvttss2siq\t{%1, %0|%0, %1}"
20837 [(set_attr "type" "sseicvt")
20838 (set_attr "mode" "SF")
20839 (set_attr "athlon_decode" "double,vector")])
20840
20841
20842 ;; MMX insns
20843
20844 ;; MMX arithmetic
20845
20846 (define_insn "addv8qi3"
20847 [(set (match_operand:V8QI 0 "register_operand" "=y")
20848 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20849 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20850 "TARGET_MMX"
20851 "paddb\t{%2, %0|%0, %2}"
20852 [(set_attr "type" "mmxadd")
20853 (set_attr "mode" "DI")])
20854
20855 (define_insn "addv4hi3"
20856 [(set (match_operand:V4HI 0 "register_operand" "=y")
20857 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20858 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20859 "TARGET_MMX"
20860 "paddw\t{%2, %0|%0, %2}"
20861 [(set_attr "type" "mmxadd")
20862 (set_attr "mode" "DI")])
20863
20864 (define_insn "addv2si3"
20865 [(set (match_operand:V2SI 0 "register_operand" "=y")
20866 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20867 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20868 "TARGET_MMX"
20869 "paddd\t{%2, %0|%0, %2}"
20870 [(set_attr "type" "mmxadd")
20871 (set_attr "mode" "DI")])
20872
20873 (define_insn "mmx_adddi3"
20874 [(set (match_operand:DI 0 "register_operand" "=y")
20875 (unspec:DI
20876 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20877 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20878 UNSPEC_NOP))]
20879 "TARGET_MMX"
20880 "paddq\t{%2, %0|%0, %2}"
20881 [(set_attr "type" "mmxadd")
20882 (set_attr "mode" "DI")])
20883
20884 (define_insn "ssaddv8qi3"
20885 [(set (match_operand:V8QI 0 "register_operand" "=y")
20886 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20887 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20888 "TARGET_MMX"
20889 "paddsb\t{%2, %0|%0, %2}"
20890 [(set_attr "type" "mmxadd")
20891 (set_attr "mode" "DI")])
20892
20893 (define_insn "ssaddv4hi3"
20894 [(set (match_operand:V4HI 0 "register_operand" "=y")
20895 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20896 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20897 "TARGET_MMX"
20898 "paddsw\t{%2, %0|%0, %2}"
20899 [(set_attr "type" "mmxadd")
20900 (set_attr "mode" "DI")])
20901
20902 (define_insn "usaddv8qi3"
20903 [(set (match_operand:V8QI 0 "register_operand" "=y")
20904 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20905 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20906 "TARGET_MMX"
20907 "paddusb\t{%2, %0|%0, %2}"
20908 [(set_attr "type" "mmxadd")
20909 (set_attr "mode" "DI")])
20910
20911 (define_insn "usaddv4hi3"
20912 [(set (match_operand:V4HI 0 "register_operand" "=y")
20913 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20914 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20915 "TARGET_MMX"
20916 "paddusw\t{%2, %0|%0, %2}"
20917 [(set_attr "type" "mmxadd")
20918 (set_attr "mode" "DI")])
20919
20920 (define_insn "subv8qi3"
20921 [(set (match_operand:V8QI 0 "register_operand" "=y")
20922 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20923 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20924 "TARGET_MMX"
20925 "psubb\t{%2, %0|%0, %2}"
20926 [(set_attr "type" "mmxadd")
20927 (set_attr "mode" "DI")])
20928
20929 (define_insn "subv4hi3"
20930 [(set (match_operand:V4HI 0 "register_operand" "=y")
20931 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20932 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20933 "TARGET_MMX"
20934 "psubw\t{%2, %0|%0, %2}"
20935 [(set_attr "type" "mmxadd")
20936 (set_attr "mode" "DI")])
20937
20938 (define_insn "subv2si3"
20939 [(set (match_operand:V2SI 0 "register_operand" "=y")
20940 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20941 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20942 "TARGET_MMX"
20943 "psubd\t{%2, %0|%0, %2}"
20944 [(set_attr "type" "mmxadd")
20945 (set_attr "mode" "DI")])
20946
20947 (define_insn "mmx_subdi3"
20948 [(set (match_operand:DI 0 "register_operand" "=y")
20949 (unspec:DI
20950 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20951 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20952 UNSPEC_NOP))]
20953 "TARGET_MMX"
20954 "psubq\t{%2, %0|%0, %2}"
20955 [(set_attr "type" "mmxadd")
20956 (set_attr "mode" "DI")])
20957
20958 (define_insn "sssubv8qi3"
20959 [(set (match_operand:V8QI 0 "register_operand" "=y")
20960 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20961 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20962 "TARGET_MMX"
20963 "psubsb\t{%2, %0|%0, %2}"
20964 [(set_attr "type" "mmxadd")
20965 (set_attr "mode" "DI")])
20966
20967 (define_insn "sssubv4hi3"
20968 [(set (match_operand:V4HI 0 "register_operand" "=y")
20969 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20970 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20971 "TARGET_MMX"
20972 "psubsw\t{%2, %0|%0, %2}"
20973 [(set_attr "type" "mmxadd")
20974 (set_attr "mode" "DI")])
20975
20976 (define_insn "ussubv8qi3"
20977 [(set (match_operand:V8QI 0 "register_operand" "=y")
20978 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20979 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20980 "TARGET_MMX"
20981 "psubusb\t{%2, %0|%0, %2}"
20982 [(set_attr "type" "mmxadd")
20983 (set_attr "mode" "DI")])
20984
20985 (define_insn "ussubv4hi3"
20986 [(set (match_operand:V4HI 0 "register_operand" "=y")
20987 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20988 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20989 "TARGET_MMX"
20990 "psubusw\t{%2, %0|%0, %2}"
20991 [(set_attr "type" "mmxadd")
20992 (set_attr "mode" "DI")])
20993
20994 (define_insn "mulv4hi3"
20995 [(set (match_operand:V4HI 0 "register_operand" "=y")
20996 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20997 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20998 "TARGET_MMX"
20999 "pmullw\t{%2, %0|%0, %2}"
21000 [(set_attr "type" "mmxmul")
21001 (set_attr "mode" "DI")])
21002
21003 (define_insn "smulv4hi3_highpart"
21004 [(set (match_operand:V4HI 0 "register_operand" "=y")
21005 (truncate:V4HI
21006 (lshiftrt:V4SI
21007 (mult:V4SI (sign_extend:V4SI
21008 (match_operand:V4HI 1 "register_operand" "0"))
21009 (sign_extend:V4SI
21010 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21011 (const_int 16))))]
21012 "TARGET_MMX"
21013 "pmulhw\t{%2, %0|%0, %2}"
21014 [(set_attr "type" "mmxmul")
21015 (set_attr "mode" "DI")])
21016
21017 (define_insn "umulv4hi3_highpart"
21018 [(set (match_operand:V4HI 0 "register_operand" "=y")
21019 (truncate:V4HI
21020 (lshiftrt:V4SI
21021 (mult:V4SI (zero_extend:V4SI
21022 (match_operand:V4HI 1 "register_operand" "0"))
21023 (zero_extend:V4SI
21024 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21025 (const_int 16))))]
21026 "TARGET_SSE || TARGET_3DNOW_A"
21027 "pmulhuw\t{%2, %0|%0, %2}"
21028 [(set_attr "type" "mmxmul")
21029 (set_attr "mode" "DI")])
21030
21031 (define_insn "mmx_pmaddwd"
21032 [(set (match_operand:V2SI 0 "register_operand" "=y")
21033 (plus:V2SI
21034 (mult:V2SI
21035 (sign_extend:V2SI
21036 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21037 (parallel [(const_int 0) (const_int 2)])))
21038 (sign_extend:V2SI
21039 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21040 (parallel [(const_int 0) (const_int 2)]))))
21041 (mult:V2SI
21042 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21043 (parallel [(const_int 1)
21044 (const_int 3)])))
21045 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21046 (parallel [(const_int 1)
21047 (const_int 3)]))))))]
21048 "TARGET_MMX"
21049 "pmaddwd\t{%2, %0|%0, %2}"
21050 [(set_attr "type" "mmxmul")
21051 (set_attr "mode" "DI")])
21052
21053
21054 ;; MMX logical operations
21055 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21056 ;; normal code that also wants to use the FPU from getting broken.
21057 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21058 (define_insn "mmx_iordi3"
21059 [(set (match_operand:DI 0 "register_operand" "=y")
21060 (unspec:DI
21061 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21062 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21063 UNSPEC_NOP))]
21064 "TARGET_MMX"
21065 "por\t{%2, %0|%0, %2}"
21066 [(set_attr "type" "mmxadd")
21067 (set_attr "mode" "DI")])
21068
21069 (define_insn "mmx_xordi3"
21070 [(set (match_operand:DI 0 "register_operand" "=y")
21071 (unspec:DI
21072 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21073 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21074 UNSPEC_NOP))]
21075 "TARGET_MMX"
21076 "pxor\t{%2, %0|%0, %2}"
21077 [(set_attr "type" "mmxadd")
21078 (set_attr "mode" "DI")
21079 (set_attr "memory" "none")])
21080
21081 ;; Same as pxor, but don't show input operands so that we don't think
21082 ;; they are live.
21083 (define_insn "mmx_clrdi"
21084 [(set (match_operand:DI 0 "register_operand" "=y")
21085 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21086 "TARGET_MMX"
21087 "pxor\t{%0, %0|%0, %0}"
21088 [(set_attr "type" "mmxadd")
21089 (set_attr "mode" "DI")
21090 (set_attr "memory" "none")])
21091
21092 (define_insn "mmx_anddi3"
21093 [(set (match_operand:DI 0 "register_operand" "=y")
21094 (unspec:DI
21095 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21096 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21097 UNSPEC_NOP))]
21098 "TARGET_MMX"
21099 "pand\t{%2, %0|%0, %2}"
21100 [(set_attr "type" "mmxadd")
21101 (set_attr "mode" "DI")])
21102
21103 (define_insn "mmx_nanddi3"
21104 [(set (match_operand:DI 0 "register_operand" "=y")
21105 (unspec:DI
21106 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21107 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21108 UNSPEC_NOP))]
21109 "TARGET_MMX"
21110 "pandn\t{%2, %0|%0, %2}"
21111 [(set_attr "type" "mmxadd")
21112 (set_attr "mode" "DI")])
21113
21114
21115 ;; MMX unsigned averages/sum of absolute differences
21116
21117 (define_insn "mmx_uavgv8qi3"
21118 [(set (match_operand:V8QI 0 "register_operand" "=y")
21119 (ashiftrt:V8QI
21120 (plus:V8QI (plus:V8QI
21121 (match_operand:V8QI 1 "register_operand" "0")
21122 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21123 (const_vector:V8QI [(const_int 1)
21124 (const_int 1)
21125 (const_int 1)
21126 (const_int 1)
21127 (const_int 1)
21128 (const_int 1)
21129 (const_int 1)
21130 (const_int 1)]))
21131 (const_int 1)))]
21132 "TARGET_SSE || TARGET_3DNOW_A"
21133 "pavgb\t{%2, %0|%0, %2}"
21134 [(set_attr "type" "mmxshft")
21135 (set_attr "mode" "DI")])
21136
21137 (define_insn "mmx_uavgv4hi3"
21138 [(set (match_operand:V4HI 0 "register_operand" "=y")
21139 (ashiftrt:V4HI
21140 (plus:V4HI (plus:V4HI
21141 (match_operand:V4HI 1 "register_operand" "0")
21142 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21143 (const_vector:V4HI [(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 "pavgw\t{%2, %0|%0, %2}"
21150 [(set_attr "type" "mmxshft")
21151 (set_attr "mode" "DI")])
21152
21153 (define_insn "mmx_psadbw"
21154 [(set (match_operand:DI 0 "register_operand" "=y")
21155 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21156 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21157 UNSPEC_PSADBW))]
21158 "TARGET_SSE || TARGET_3DNOW_A"
21159 "psadbw\t{%2, %0|%0, %2}"
21160 [(set_attr "type" "mmxshft")
21161 (set_attr "mode" "DI")])
21162
21163
21164 ;; MMX insert/extract/shuffle
21165
21166 (define_insn "mmx_pinsrw"
21167 [(set (match_operand:V4HI 0 "register_operand" "=y")
21168 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21169 (vec_duplicate:V4HI
21170 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21171 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21172 "TARGET_SSE || TARGET_3DNOW_A"
21173 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21174 [(set_attr "type" "mmxcvt")
21175 (set_attr "mode" "DI")])
21176
21177 (define_insn "mmx_pextrw"
21178 [(set (match_operand:SI 0 "register_operand" "=r")
21179 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21180 (parallel
21181 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21182 "TARGET_SSE || TARGET_3DNOW_A"
21183 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21184 [(set_attr "type" "mmxcvt")
21185 (set_attr "mode" "DI")])
21186
21187 (define_insn "mmx_pshufw"
21188 [(set (match_operand:V4HI 0 "register_operand" "=y")
21189 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21190 (match_operand:SI 2 "immediate_operand" "i")]
21191 UNSPEC_SHUFFLE))]
21192 "TARGET_SSE || TARGET_3DNOW_A"
21193 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21194 [(set_attr "type" "mmxcvt")
21195 (set_attr "mode" "DI")])
21196
21197
21198 ;; MMX mask-generating comparisons
21199
21200 (define_insn "eqv8qi3"
21201 [(set (match_operand:V8QI 0 "register_operand" "=y")
21202 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21203 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21204 "TARGET_MMX"
21205 "pcmpeqb\t{%2, %0|%0, %2}"
21206 [(set_attr "type" "mmxcmp")
21207 (set_attr "mode" "DI")])
21208
21209 (define_insn "eqv4hi3"
21210 [(set (match_operand:V4HI 0 "register_operand" "=y")
21211 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21212 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21213 "TARGET_MMX"
21214 "pcmpeqw\t{%2, %0|%0, %2}"
21215 [(set_attr "type" "mmxcmp")
21216 (set_attr "mode" "DI")])
21217
21218 (define_insn "eqv2si3"
21219 [(set (match_operand:V2SI 0 "register_operand" "=y")
21220 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21221 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21222 "TARGET_MMX"
21223 "pcmpeqd\t{%2, %0|%0, %2}"
21224 [(set_attr "type" "mmxcmp")
21225 (set_attr "mode" "DI")])
21226
21227 (define_insn "gtv8qi3"
21228 [(set (match_operand:V8QI 0 "register_operand" "=y")
21229 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21230 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21231 "TARGET_MMX"
21232 "pcmpgtb\t{%2, %0|%0, %2}"
21233 [(set_attr "type" "mmxcmp")
21234 (set_attr "mode" "DI")])
21235
21236 (define_insn "gtv4hi3"
21237 [(set (match_operand:V4HI 0 "register_operand" "=y")
21238 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21239 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21240 "TARGET_MMX"
21241 "pcmpgtw\t{%2, %0|%0, %2}"
21242 [(set_attr "type" "mmxcmp")
21243 (set_attr "mode" "DI")])
21244
21245 (define_insn "gtv2si3"
21246 [(set (match_operand:V2SI 0 "register_operand" "=y")
21247 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21248 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21249 "TARGET_MMX"
21250 "pcmpgtd\t{%2, %0|%0, %2}"
21251 [(set_attr "type" "mmxcmp")
21252 (set_attr "mode" "DI")])
21253
21254
21255 ;; MMX max/min insns
21256
21257 (define_insn "umaxv8qi3"
21258 [(set (match_operand:V8QI 0 "register_operand" "=y")
21259 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21260 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21261 "TARGET_SSE || TARGET_3DNOW_A"
21262 "pmaxub\t{%2, %0|%0, %2}"
21263 [(set_attr "type" "mmxadd")
21264 (set_attr "mode" "DI")])
21265
21266 (define_insn "smaxv4hi3"
21267 [(set (match_operand:V4HI 0 "register_operand" "=y")
21268 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21269 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21270 "TARGET_SSE || TARGET_3DNOW_A"
21271 "pmaxsw\t{%2, %0|%0, %2}"
21272 [(set_attr "type" "mmxadd")
21273 (set_attr "mode" "DI")])
21274
21275 (define_insn "uminv8qi3"
21276 [(set (match_operand:V8QI 0 "register_operand" "=y")
21277 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21278 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21279 "TARGET_SSE || TARGET_3DNOW_A"
21280 "pminub\t{%2, %0|%0, %2}"
21281 [(set_attr "type" "mmxadd")
21282 (set_attr "mode" "DI")])
21283
21284 (define_insn "sminv4hi3"
21285 [(set (match_operand:V4HI 0 "register_operand" "=y")
21286 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21287 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21288 "TARGET_SSE || TARGET_3DNOW_A"
21289 "pminsw\t{%2, %0|%0, %2}"
21290 [(set_attr "type" "mmxadd")
21291 (set_attr "mode" "DI")])
21292
21293
21294 ;; MMX shifts
21295
21296 (define_insn "ashrv4hi3"
21297 [(set (match_operand:V4HI 0 "register_operand" "=y")
21298 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21299 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21300 "TARGET_MMX"
21301 "psraw\t{%2, %0|%0, %2}"
21302 [(set_attr "type" "mmxshft")
21303 (set_attr "mode" "DI")])
21304
21305 (define_insn "ashrv2si3"
21306 [(set (match_operand:V2SI 0 "register_operand" "=y")
21307 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21308 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21309 "TARGET_MMX"
21310 "psrad\t{%2, %0|%0, %2}"
21311 [(set_attr "type" "mmxshft")
21312 (set_attr "mode" "DI")])
21313
21314 (define_insn "lshrv4hi3"
21315 [(set (match_operand:V4HI 0 "register_operand" "=y")
21316 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21317 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21318 "TARGET_MMX"
21319 "psrlw\t{%2, %0|%0, %2}"
21320 [(set_attr "type" "mmxshft")
21321 (set_attr "mode" "DI")])
21322
21323 (define_insn "lshrv2si3"
21324 [(set (match_operand:V2SI 0 "register_operand" "=y")
21325 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21326 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21327 "TARGET_MMX"
21328 "psrld\t{%2, %0|%0, %2}"
21329 [(set_attr "type" "mmxshft")
21330 (set_attr "mode" "DI")])
21331
21332 ;; See logical MMX insns.
21333 (define_insn "mmx_lshrdi3"
21334 [(set (match_operand:DI 0 "register_operand" "=y")
21335 (unspec:DI
21336 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21337 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21338 UNSPEC_NOP))]
21339 "TARGET_MMX"
21340 "psrlq\t{%2, %0|%0, %2}"
21341 [(set_attr "type" "mmxshft")
21342 (set_attr "mode" "DI")])
21343
21344 (define_insn "ashlv4hi3"
21345 [(set (match_operand:V4HI 0 "register_operand" "=y")
21346 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21347 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21348 "TARGET_MMX"
21349 "psllw\t{%2, %0|%0, %2}"
21350 [(set_attr "type" "mmxshft")
21351 (set_attr "mode" "DI")])
21352
21353 (define_insn "ashlv2si3"
21354 [(set (match_operand:V2SI 0 "register_operand" "=y")
21355 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21356 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21357 "TARGET_MMX"
21358 "pslld\t{%2, %0|%0, %2}"
21359 [(set_attr "type" "mmxshft")
21360 (set_attr "mode" "DI")])
21361
21362 ;; See logical MMX insns.
21363 (define_insn "mmx_ashldi3"
21364 [(set (match_operand:DI 0 "register_operand" "=y")
21365 (unspec:DI
21366 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21367 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21368 UNSPEC_NOP))]
21369 "TARGET_MMX"
21370 "psllq\t{%2, %0|%0, %2}"
21371 [(set_attr "type" "mmxshft")
21372 (set_attr "mode" "DI")])
21373
21374
21375 ;; MMX pack/unpack insns.
21376
21377 (define_insn "mmx_packsswb"
21378 [(set (match_operand:V8QI 0 "register_operand" "=y")
21379 (vec_concat:V8QI
21380 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21381 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21382 "TARGET_MMX"
21383 "packsswb\t{%2, %0|%0, %2}"
21384 [(set_attr "type" "mmxshft")
21385 (set_attr "mode" "DI")])
21386
21387 (define_insn "mmx_packssdw"
21388 [(set (match_operand:V4HI 0 "register_operand" "=y")
21389 (vec_concat:V4HI
21390 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21391 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21392 "TARGET_MMX"
21393 "packssdw\t{%2, %0|%0, %2}"
21394 [(set_attr "type" "mmxshft")
21395 (set_attr "mode" "DI")])
21396
21397 (define_insn "mmx_packuswb"
21398 [(set (match_operand:V8QI 0 "register_operand" "=y")
21399 (vec_concat:V8QI
21400 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21401 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21402 "TARGET_MMX"
21403 "packuswb\t{%2, %0|%0, %2}"
21404 [(set_attr "type" "mmxshft")
21405 (set_attr "mode" "DI")])
21406
21407 (define_insn "mmx_punpckhbw"
21408 [(set (match_operand:V8QI 0 "register_operand" "=y")
21409 (vec_merge:V8QI
21410 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21411 (parallel [(const_int 4)
21412 (const_int 0)
21413 (const_int 5)
21414 (const_int 1)
21415 (const_int 6)
21416 (const_int 2)
21417 (const_int 7)
21418 (const_int 3)]))
21419 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21420 (parallel [(const_int 0)
21421 (const_int 4)
21422 (const_int 1)
21423 (const_int 5)
21424 (const_int 2)
21425 (const_int 6)
21426 (const_int 3)
21427 (const_int 7)]))
21428 (const_int 85)))]
21429 "TARGET_MMX"
21430 "punpckhbw\t{%2, %0|%0, %2}"
21431 [(set_attr "type" "mmxcvt")
21432 (set_attr "mode" "DI")])
21433
21434 (define_insn "mmx_punpckhwd"
21435 [(set (match_operand:V4HI 0 "register_operand" "=y")
21436 (vec_merge:V4HI
21437 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21438 (parallel [(const_int 0)
21439 (const_int 2)
21440 (const_int 1)
21441 (const_int 3)]))
21442 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21443 (parallel [(const_int 2)
21444 (const_int 0)
21445 (const_int 3)
21446 (const_int 1)]))
21447 (const_int 5)))]
21448 "TARGET_MMX"
21449 "punpckhwd\t{%2, %0|%0, %2}"
21450 [(set_attr "type" "mmxcvt")
21451 (set_attr "mode" "DI")])
21452
21453 (define_insn "mmx_punpckhdq"
21454 [(set (match_operand:V2SI 0 "register_operand" "=y")
21455 (vec_merge:V2SI
21456 (match_operand:V2SI 1 "register_operand" "0")
21457 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21458 (parallel [(const_int 1)
21459 (const_int 0)]))
21460 (const_int 1)))]
21461 "TARGET_MMX"
21462 "punpckhdq\t{%2, %0|%0, %2}"
21463 [(set_attr "type" "mmxcvt")
21464 (set_attr "mode" "DI")])
21465
21466 (define_insn "mmx_punpcklbw"
21467 [(set (match_operand:V8QI 0 "register_operand" "=y")
21468 (vec_merge:V8QI
21469 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21470 (parallel [(const_int 0)
21471 (const_int 4)
21472 (const_int 1)
21473 (const_int 5)
21474 (const_int 2)
21475 (const_int 6)
21476 (const_int 3)
21477 (const_int 7)]))
21478 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21479 (parallel [(const_int 4)
21480 (const_int 0)
21481 (const_int 5)
21482 (const_int 1)
21483 (const_int 6)
21484 (const_int 2)
21485 (const_int 7)
21486 (const_int 3)]))
21487 (const_int 85)))]
21488 "TARGET_MMX"
21489 "punpcklbw\t{%2, %0|%0, %2}"
21490 [(set_attr "type" "mmxcvt")
21491 (set_attr "mode" "DI")])
21492
21493 (define_insn "mmx_punpcklwd"
21494 [(set (match_operand:V4HI 0 "register_operand" "=y")
21495 (vec_merge:V4HI
21496 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21497 (parallel [(const_int 2)
21498 (const_int 0)
21499 (const_int 3)
21500 (const_int 1)]))
21501 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21502 (parallel [(const_int 0)
21503 (const_int 2)
21504 (const_int 1)
21505 (const_int 3)]))
21506 (const_int 5)))]
21507 "TARGET_MMX"
21508 "punpcklwd\t{%2, %0|%0, %2}"
21509 [(set_attr "type" "mmxcvt")
21510 (set_attr "mode" "DI")])
21511
21512 (define_insn "mmx_punpckldq"
21513 [(set (match_operand:V2SI 0 "register_operand" "=y")
21514 (vec_merge:V2SI
21515 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21516 (parallel [(const_int 1)
21517 (const_int 0)]))
21518 (match_operand:V2SI 2 "register_operand" "y")
21519 (const_int 1)))]
21520 "TARGET_MMX"
21521 "punpckldq\t{%2, %0|%0, %2}"
21522 [(set_attr "type" "mmxcvt")
21523 (set_attr "mode" "DI")])
21524
21525
21526 ;; Miscellaneous stuff
21527
21528 (define_insn "emms"
21529 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21530 (clobber (reg:XF 8))
21531 (clobber (reg:XF 9))
21532 (clobber (reg:XF 10))
21533 (clobber (reg:XF 11))
21534 (clobber (reg:XF 12))
21535 (clobber (reg:XF 13))
21536 (clobber (reg:XF 14))
21537 (clobber (reg:XF 15))
21538 (clobber (reg:DI 29))
21539 (clobber (reg:DI 30))
21540 (clobber (reg:DI 31))
21541 (clobber (reg:DI 32))
21542 (clobber (reg:DI 33))
21543 (clobber (reg:DI 34))
21544 (clobber (reg:DI 35))
21545 (clobber (reg:DI 36))]
21546 "TARGET_MMX"
21547 "emms"
21548 [(set_attr "type" "mmx")
21549 (set_attr "memory" "unknown")])
21550
21551 (define_insn "ldmxcsr"
21552 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21553 UNSPECV_LDMXCSR)]
21554 "TARGET_SSE"
21555 "ldmxcsr\t%0"
21556 [(set_attr "type" "sse")
21557 (set_attr "memory" "load")])
21558
21559 (define_insn "stmxcsr"
21560 [(set (match_operand:SI 0 "memory_operand" "=m")
21561 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21562 "TARGET_SSE"
21563 "stmxcsr\t%0"
21564 [(set_attr "type" "sse")
21565 (set_attr "memory" "store")])
21566
21567 (define_expand "sfence"
21568 [(set (match_dup 0)
21569 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21570 "TARGET_SSE || TARGET_3DNOW_A"
21571 {
21572 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21573 MEM_VOLATILE_P (operands[0]) = 1;
21574 })
21575
21576 (define_insn "*sfence_insn"
21577 [(set (match_operand:BLK 0 "" "")
21578 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21579 "TARGET_SSE || TARGET_3DNOW_A"
21580 "sfence"
21581 [(set_attr "type" "sse")
21582 (set_attr "memory" "unknown")])
21583
21584 (define_expand "sse_prologue_save"
21585 [(parallel [(set (match_operand:BLK 0 "" "")
21586 (unspec:BLK [(reg:DI 21)
21587 (reg:DI 22)
21588 (reg:DI 23)
21589 (reg:DI 24)
21590 (reg:DI 25)
21591 (reg:DI 26)
21592 (reg:DI 27)
21593 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21594 (use (match_operand:DI 1 "register_operand" ""))
21595 (use (match_operand:DI 2 "immediate_operand" ""))
21596 (use (label_ref:DI (match_operand 3 "" "")))])]
21597 "TARGET_64BIT"
21598 "")
21599
21600 (define_insn "*sse_prologue_save_insn"
21601 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21602 (match_operand:DI 4 "const_int_operand" "n")))
21603 (unspec:BLK [(reg:DI 21)
21604 (reg:DI 22)
21605 (reg:DI 23)
21606 (reg:DI 24)
21607 (reg:DI 25)
21608 (reg:DI 26)
21609 (reg:DI 27)
21610 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21611 (use (match_operand:DI 1 "register_operand" "r"))
21612 (use (match_operand:DI 2 "const_int_operand" "i"))
21613 (use (label_ref:DI (match_operand 3 "" "X")))]
21614 "TARGET_64BIT
21615 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21616 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21617 "*
21618 {
21619 int i;
21620 operands[0] = gen_rtx_MEM (Pmode,
21621 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21622 output_asm_insn (\"jmp\\t%A1\", operands);
21623 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21624 {
21625 operands[4] = adjust_address (operands[0], DImode, i*16);
21626 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21627 PUT_MODE (operands[4], TImode);
21628 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21629 output_asm_insn (\"rex\", operands);
21630 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21631 }
21632 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21633 CODE_LABEL_NUMBER (operands[3]));
21634 RET;
21635 }
21636 "
21637 [(set_attr "type" "other")
21638 (set_attr "length_immediate" "0")
21639 (set_attr "length_address" "0")
21640 (set_attr "length" "135")
21641 (set_attr "memory" "store")
21642 (set_attr "modrm" "0")
21643 (set_attr "mode" "DI")])
21644
21645 ;; 3Dnow! instructions
21646
21647 (define_insn "addv2sf3"
21648 [(set (match_operand:V2SF 0 "register_operand" "=y")
21649 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21650 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21651 "TARGET_3DNOW"
21652 "pfadd\\t{%2, %0|%0, %2}"
21653 [(set_attr "type" "mmxadd")
21654 (set_attr "mode" "V2SF")])
21655
21656 (define_insn "subv2sf3"
21657 [(set (match_operand:V2SF 0 "register_operand" "=y")
21658 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21659 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21660 "TARGET_3DNOW"
21661 "pfsub\\t{%2, %0|%0, %2}"
21662 [(set_attr "type" "mmxadd")
21663 (set_attr "mode" "V2SF")])
21664
21665 (define_insn "subrv2sf3"
21666 [(set (match_operand:V2SF 0 "register_operand" "=y")
21667 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21668 (match_operand:V2SF 1 "register_operand" "0")))]
21669 "TARGET_3DNOW"
21670 "pfsubr\\t{%2, %0|%0, %2}"
21671 [(set_attr "type" "mmxadd")
21672 (set_attr "mode" "V2SF")])
21673
21674 (define_insn "gtv2sf3"
21675 [(set (match_operand:V2SI 0 "register_operand" "=y")
21676 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21677 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21678 "TARGET_3DNOW"
21679 "pfcmpgt\\t{%2, %0|%0, %2}"
21680 [(set_attr "type" "mmxcmp")
21681 (set_attr "mode" "V2SF")])
21682
21683 (define_insn "gev2sf3"
21684 [(set (match_operand:V2SI 0 "register_operand" "=y")
21685 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21686 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21687 "TARGET_3DNOW"
21688 "pfcmpge\\t{%2, %0|%0, %2}"
21689 [(set_attr "type" "mmxcmp")
21690 (set_attr "mode" "V2SF")])
21691
21692 (define_insn "eqv2sf3"
21693 [(set (match_operand:V2SI 0 "register_operand" "=y")
21694 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21695 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21696 "TARGET_3DNOW"
21697 "pfcmpeq\\t{%2, %0|%0, %2}"
21698 [(set_attr "type" "mmxcmp")
21699 (set_attr "mode" "V2SF")])
21700
21701 (define_insn "pfmaxv2sf3"
21702 [(set (match_operand:V2SF 0 "register_operand" "=y")
21703 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21704 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21705 "TARGET_3DNOW"
21706 "pfmax\\t{%2, %0|%0, %2}"
21707 [(set_attr "type" "mmxadd")
21708 (set_attr "mode" "V2SF")])
21709
21710 (define_insn "pfminv2sf3"
21711 [(set (match_operand:V2SF 0 "register_operand" "=y")
21712 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21713 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21714 "TARGET_3DNOW"
21715 "pfmin\\t{%2, %0|%0, %2}"
21716 [(set_attr "type" "mmxadd")
21717 (set_attr "mode" "V2SF")])
21718
21719 (define_insn "mulv2sf3"
21720 [(set (match_operand:V2SF 0 "register_operand" "=y")
21721 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21722 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21723 "TARGET_3DNOW"
21724 "pfmul\\t{%2, %0|%0, %2}"
21725 [(set_attr "type" "mmxmul")
21726 (set_attr "mode" "V2SF")])
21727
21728 (define_insn "femms"
21729 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21730 (clobber (reg:XF 8))
21731 (clobber (reg:XF 9))
21732 (clobber (reg:XF 10))
21733 (clobber (reg:XF 11))
21734 (clobber (reg:XF 12))
21735 (clobber (reg:XF 13))
21736 (clobber (reg:XF 14))
21737 (clobber (reg:XF 15))
21738 (clobber (reg:DI 29))
21739 (clobber (reg:DI 30))
21740 (clobber (reg:DI 31))
21741 (clobber (reg:DI 32))
21742 (clobber (reg:DI 33))
21743 (clobber (reg:DI 34))
21744 (clobber (reg:DI 35))
21745 (clobber (reg:DI 36))]
21746 "TARGET_3DNOW"
21747 "femms"
21748 [(set_attr "type" "mmx")
21749 (set_attr "memory" "none")])
21750
21751 (define_insn "pf2id"
21752 [(set (match_operand:V2SI 0 "register_operand" "=y")
21753 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21754 "TARGET_3DNOW"
21755 "pf2id\\t{%1, %0|%0, %1}"
21756 [(set_attr "type" "mmxcvt")
21757 (set_attr "mode" "V2SF")])
21758
21759 (define_insn "pf2iw"
21760 [(set (match_operand:V2SI 0 "register_operand" "=y")
21761 (sign_extend:V2SI
21762 (ss_truncate:V2HI
21763 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21764 "TARGET_3DNOW_A"
21765 "pf2iw\\t{%1, %0|%0, %1}"
21766 [(set_attr "type" "mmxcvt")
21767 (set_attr "mode" "V2SF")])
21768
21769 (define_insn "pfacc"
21770 [(set (match_operand:V2SF 0 "register_operand" "=y")
21771 (vec_concat:V2SF
21772 (plus:SF
21773 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21774 (parallel [(const_int 0)]))
21775 (vec_select:SF (match_dup 1)
21776 (parallel [(const_int 1)])))
21777 (plus:SF
21778 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21779 (parallel [(const_int 0)]))
21780 (vec_select:SF (match_dup 2)
21781 (parallel [(const_int 1)])))))]
21782 "TARGET_3DNOW"
21783 "pfacc\\t{%2, %0|%0, %2}"
21784 [(set_attr "type" "mmxadd")
21785 (set_attr "mode" "V2SF")])
21786
21787 (define_insn "pfnacc"
21788 [(set (match_operand:V2SF 0 "register_operand" "=y")
21789 (vec_concat:V2SF
21790 (minus:SF
21791 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21792 (parallel [(const_int 0)]))
21793 (vec_select:SF (match_dup 1)
21794 (parallel [(const_int 1)])))
21795 (minus:SF
21796 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21797 (parallel [(const_int 0)]))
21798 (vec_select:SF (match_dup 2)
21799 (parallel [(const_int 1)])))))]
21800 "TARGET_3DNOW_A"
21801 "pfnacc\\t{%2, %0|%0, %2}"
21802 [(set_attr "type" "mmxadd")
21803 (set_attr "mode" "V2SF")])
21804
21805 (define_insn "pfpnacc"
21806 [(set (match_operand:V2SF 0 "register_operand" "=y")
21807 (vec_concat:V2SF
21808 (minus:SF
21809 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21810 (parallel [(const_int 0)]))
21811 (vec_select:SF (match_dup 1)
21812 (parallel [(const_int 1)])))
21813 (plus:SF
21814 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21815 (parallel [(const_int 0)]))
21816 (vec_select:SF (match_dup 2)
21817 (parallel [(const_int 1)])))))]
21818 "TARGET_3DNOW_A"
21819 "pfpnacc\\t{%2, %0|%0, %2}"
21820 [(set_attr "type" "mmxadd")
21821 (set_attr "mode" "V2SF")])
21822
21823 (define_insn "pi2fw"
21824 [(set (match_operand:V2SF 0 "register_operand" "=y")
21825 (float:V2SF
21826 (vec_concat:V2SI
21827 (sign_extend:SI
21828 (truncate:HI
21829 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21830 (parallel [(const_int 0)]))))
21831 (sign_extend:SI
21832 (truncate:HI
21833 (vec_select:SI (match_dup 1)
21834 (parallel [(const_int 1)])))))))]
21835 "TARGET_3DNOW_A"
21836 "pi2fw\\t{%1, %0|%0, %1}"
21837 [(set_attr "type" "mmxcvt")
21838 (set_attr "mode" "V2SF")])
21839
21840 (define_insn "floatv2si2"
21841 [(set (match_operand:V2SF 0 "register_operand" "=y")
21842 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21843 "TARGET_3DNOW"
21844 "pi2fd\\t{%1, %0|%0, %1}"
21845 [(set_attr "type" "mmxcvt")
21846 (set_attr "mode" "V2SF")])
21847
21848 ;; This insn is identical to pavgb in operation, but the opcode is
21849 ;; different. To avoid accidentally matching pavgb, use an unspec.
21850
21851 (define_insn "pavgusb"
21852 [(set (match_operand:V8QI 0 "register_operand" "=y")
21853 (unspec:V8QI
21854 [(match_operand:V8QI 1 "register_operand" "0")
21855 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21856 UNSPEC_PAVGUSB))]
21857 "TARGET_3DNOW"
21858 "pavgusb\\t{%2, %0|%0, %2}"
21859 [(set_attr "type" "mmxshft")
21860 (set_attr "mode" "TI")])
21861
21862 ;; 3DNow reciprocal and sqrt
21863
21864 (define_insn "pfrcpv2sf2"
21865 [(set (match_operand:V2SF 0 "register_operand" "=y")
21866 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21867 UNSPEC_PFRCP))]
21868 "TARGET_3DNOW"
21869 "pfrcp\\t{%1, %0|%0, %1}"
21870 [(set_attr "type" "mmx")
21871 (set_attr "mode" "TI")])
21872
21873 (define_insn "pfrcpit1v2sf3"
21874 [(set (match_operand:V2SF 0 "register_operand" "=y")
21875 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21876 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21877 UNSPEC_PFRCPIT1))]
21878 "TARGET_3DNOW"
21879 "pfrcpit1\\t{%2, %0|%0, %2}"
21880 [(set_attr "type" "mmx")
21881 (set_attr "mode" "TI")])
21882
21883 (define_insn "pfrcpit2v2sf3"
21884 [(set (match_operand:V2SF 0 "register_operand" "=y")
21885 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21886 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21887 UNSPEC_PFRCPIT2))]
21888 "TARGET_3DNOW"
21889 "pfrcpit2\\t{%2, %0|%0, %2}"
21890 [(set_attr "type" "mmx")
21891 (set_attr "mode" "TI")])
21892
21893 (define_insn "pfrsqrtv2sf2"
21894 [(set (match_operand:V2SF 0 "register_operand" "=y")
21895 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21896 UNSPEC_PFRSQRT))]
21897 "TARGET_3DNOW"
21898 "pfrsqrt\\t{%1, %0|%0, %1}"
21899 [(set_attr "type" "mmx")
21900 (set_attr "mode" "TI")])
21901
21902 (define_insn "pfrsqit1v2sf3"
21903 [(set (match_operand:V2SF 0 "register_operand" "=y")
21904 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21905 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21906 UNSPEC_PFRSQIT1))]
21907 "TARGET_3DNOW"
21908 "pfrsqit1\\t{%2, %0|%0, %2}"
21909 [(set_attr "type" "mmx")
21910 (set_attr "mode" "TI")])
21911
21912 (define_insn "pmulhrwv4hi3"
21913 [(set (match_operand:V4HI 0 "register_operand" "=y")
21914 (truncate:V4HI
21915 (lshiftrt:V4SI
21916 (plus:V4SI
21917 (mult:V4SI
21918 (sign_extend:V4SI
21919 (match_operand:V4HI 1 "register_operand" "0"))
21920 (sign_extend:V4SI
21921 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21922 (const_vector:V4SI [(const_int 32768)
21923 (const_int 32768)
21924 (const_int 32768)
21925 (const_int 32768)]))
21926 (const_int 16))))]
21927 "TARGET_3DNOW"
21928 "pmulhrw\\t{%2, %0|%0, %2}"
21929 [(set_attr "type" "mmxmul")
21930 (set_attr "mode" "TI")])
21931
21932 (define_insn "pswapdv2si2"
21933 [(set (match_operand:V2SI 0 "register_operand" "=y")
21934 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21935 (parallel [(const_int 1) (const_int 0)])))]
21936 "TARGET_3DNOW_A"
21937 "pswapd\\t{%1, %0|%0, %1}"
21938 [(set_attr "type" "mmxcvt")
21939 (set_attr "mode" "TI")])
21940
21941 (define_insn "pswapdv2sf2"
21942 [(set (match_operand:V2SF 0 "register_operand" "=y")
21943 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21944 (parallel [(const_int 1) (const_int 0)])))]
21945 "TARGET_3DNOW_A"
21946 "pswapd\\t{%1, %0|%0, %1}"
21947 [(set_attr "type" "mmxcvt")
21948 (set_attr "mode" "TI")])
21949
21950 (define_expand "prefetch"
21951 [(prefetch (match_operand 0 "address_operand" "")
21952 (match_operand:SI 1 "const_int_operand" "")
21953 (match_operand:SI 2 "const_int_operand" ""))]
21954 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21955 {
21956 int rw = INTVAL (operands[1]);
21957 int locality = INTVAL (operands[2]);
21958
21959 if (rw != 0 && rw != 1)
21960 abort ();
21961 if (locality < 0 || locality > 3)
21962 abort ();
21963 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21964 abort ();
21965
21966 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21967 suported by SSE counterpart or the SSE prefetch is not available
21968 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21969 of locality. */
21970 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21971 operands[2] = GEN_INT (3);
21972 else
21973 operands[1] = const0_rtx;
21974 })
21975
21976 (define_insn "*prefetch_sse"
21977 [(prefetch (match_operand:SI 0 "address_operand" "p")
21978 (const_int 0)
21979 (match_operand:SI 1 "const_int_operand" ""))]
21980 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21981 {
21982 static const char * const patterns[4] = {
21983 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21984 };
21985
21986 int locality = INTVAL (operands[1]);
21987 if (locality < 0 || locality > 3)
21988 abort ();
21989
21990 return patterns[locality];
21991 }
21992 [(set_attr "type" "sse")
21993 (set_attr "memory" "none")])
21994
21995 (define_insn "*prefetch_sse_rex"
21996 [(prefetch (match_operand:DI 0 "address_operand" "p")
21997 (const_int 0)
21998 (match_operand:SI 1 "const_int_operand" ""))]
21999 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22000 {
22001 static const char * const patterns[4] = {
22002 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22003 };
22004
22005 int locality = INTVAL (operands[1]);
22006 if (locality < 0 || locality > 3)
22007 abort ();
22008
22009 return patterns[locality];
22010 }
22011 [(set_attr "type" "sse")
22012 (set_attr "memory" "none")])
22013
22014 (define_insn "*prefetch_3dnow"
22015 [(prefetch (match_operand:SI 0 "address_operand" "p")
22016 (match_operand:SI 1 "const_int_operand" "n")
22017 (const_int 3))]
22018 "TARGET_3DNOW && !TARGET_64BIT"
22019 {
22020 if (INTVAL (operands[1]) == 0)
22021 return "prefetch\t%a0";
22022 else
22023 return "prefetchw\t%a0";
22024 }
22025 [(set_attr "type" "mmx")
22026 (set_attr "memory" "none")])
22027
22028 (define_insn "*prefetch_3dnow_rex"
22029 [(prefetch (match_operand:DI 0 "address_operand" "p")
22030 (match_operand:SI 1 "const_int_operand" "n")
22031 (const_int 3))]
22032 "TARGET_3DNOW && TARGET_64BIT"
22033 {
22034 if (INTVAL (operands[1]) == 0)
22035 return "prefetch\t%a0";
22036 else
22037 return "prefetchw\t%a0";
22038 }
22039 [(set_attr "type" "mmx")
22040 (set_attr "memory" "none")])
22041
22042 ;; SSE2 support
22043
22044 (define_insn "addv2df3"
22045 [(set (match_operand:V2DF 0 "register_operand" "=x")
22046 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22047 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22048 "TARGET_SSE2"
22049 "addpd\t{%2, %0|%0, %2}"
22050 [(set_attr "type" "sseadd")
22051 (set_attr "mode" "V2DF")])
22052
22053 (define_insn "vmaddv2df3"
22054 [(set (match_operand:V2DF 0 "register_operand" "=x")
22055 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22056 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22057 (match_dup 1)
22058 (const_int 1)))]
22059 "TARGET_SSE2"
22060 "addsd\t{%2, %0|%0, %2}"
22061 [(set_attr "type" "sseadd")
22062 (set_attr "mode" "DF")])
22063
22064 (define_insn "subv2df3"
22065 [(set (match_operand:V2DF 0 "register_operand" "=x")
22066 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22067 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22068 "TARGET_SSE2"
22069 "subpd\t{%2, %0|%0, %2}"
22070 [(set_attr "type" "sseadd")
22071 (set_attr "mode" "V2DF")])
22072
22073 (define_insn "vmsubv2df3"
22074 [(set (match_operand:V2DF 0 "register_operand" "=x")
22075 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22076 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22077 (match_dup 1)
22078 (const_int 1)))]
22079 "TARGET_SSE2"
22080 "subsd\t{%2, %0|%0, %2}"
22081 [(set_attr "type" "sseadd")
22082 (set_attr "mode" "DF")])
22083
22084 (define_insn "mulv2df3"
22085 [(set (match_operand:V2DF 0 "register_operand" "=x")
22086 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22087 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22088 "TARGET_SSE2"
22089 "mulpd\t{%2, %0|%0, %2}"
22090 [(set_attr "type" "ssemul")
22091 (set_attr "mode" "V2DF")])
22092
22093 (define_insn "vmmulv2df3"
22094 [(set (match_operand:V2DF 0 "register_operand" "=x")
22095 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22096 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22097 (match_dup 1)
22098 (const_int 1)))]
22099 "TARGET_SSE2"
22100 "mulsd\t{%2, %0|%0, %2}"
22101 [(set_attr "type" "ssemul")
22102 (set_attr "mode" "DF")])
22103
22104 (define_insn "divv2df3"
22105 [(set (match_operand:V2DF 0 "register_operand" "=x")
22106 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22107 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22108 "TARGET_SSE2"
22109 "divpd\t{%2, %0|%0, %2}"
22110 [(set_attr "type" "ssediv")
22111 (set_attr "mode" "V2DF")])
22112
22113 (define_insn "vmdivv2df3"
22114 [(set (match_operand:V2DF 0 "register_operand" "=x")
22115 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22116 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22117 (match_dup 1)
22118 (const_int 1)))]
22119 "TARGET_SSE2"
22120 "divsd\t{%2, %0|%0, %2}"
22121 [(set_attr "type" "ssediv")
22122 (set_attr "mode" "DF")])
22123
22124 ;; SSE min/max
22125
22126 (define_insn "smaxv2df3"
22127 [(set (match_operand:V2DF 0 "register_operand" "=x")
22128 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22129 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22130 "TARGET_SSE2"
22131 "maxpd\t{%2, %0|%0, %2}"
22132 [(set_attr "type" "sseadd")
22133 (set_attr "mode" "V2DF")])
22134
22135 (define_insn "vmsmaxv2df3"
22136 [(set (match_operand:V2DF 0 "register_operand" "=x")
22137 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22138 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22139 (match_dup 1)
22140 (const_int 1)))]
22141 "TARGET_SSE2"
22142 "maxsd\t{%2, %0|%0, %2}"
22143 [(set_attr "type" "sseadd")
22144 (set_attr "mode" "DF")])
22145
22146 (define_insn "sminv2df3"
22147 [(set (match_operand:V2DF 0 "register_operand" "=x")
22148 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22149 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22150 "TARGET_SSE2"
22151 "minpd\t{%2, %0|%0, %2}"
22152 [(set_attr "type" "sseadd")
22153 (set_attr "mode" "V2DF")])
22154
22155 (define_insn "vmsminv2df3"
22156 [(set (match_operand:V2DF 0 "register_operand" "=x")
22157 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22158 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22159 (match_dup 1)
22160 (const_int 1)))]
22161 "TARGET_SSE2"
22162 "minsd\t{%2, %0|%0, %2}"
22163 [(set_attr "type" "sseadd")
22164 (set_attr "mode" "DF")])
22165 ;; SSE2 square root. There doesn't appear to be an extension for the
22166 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22167
22168 (define_insn "sqrtv2df2"
22169 [(set (match_operand:V2DF 0 "register_operand" "=x")
22170 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22171 "TARGET_SSE2"
22172 "sqrtpd\t{%1, %0|%0, %1}"
22173 [(set_attr "type" "sse")
22174 (set_attr "mode" "V2DF")])
22175
22176 (define_insn "vmsqrtv2df2"
22177 [(set (match_operand:V2DF 0 "register_operand" "=x")
22178 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22179 (match_operand:V2DF 2 "register_operand" "0")
22180 (const_int 1)))]
22181 "TARGET_SSE2"
22182 "sqrtsd\t{%1, %0|%0, %1}"
22183 [(set_attr "type" "sse")
22184 (set_attr "mode" "SF")])
22185
22186 ;; SSE mask-generating compares
22187
22188 (define_insn "maskcmpv2df3"
22189 [(set (match_operand:V2DI 0 "register_operand" "=x")
22190 (match_operator:V2DI 3 "sse_comparison_operator"
22191 [(match_operand:V2DF 1 "register_operand" "0")
22192 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22193 "TARGET_SSE2"
22194 "cmp%D3pd\t{%2, %0|%0, %2}"
22195 [(set_attr "type" "ssecmp")
22196 (set_attr "mode" "V2DF")])
22197
22198 (define_insn "maskncmpv2df3"
22199 [(set (match_operand:V2DI 0 "register_operand" "=x")
22200 (not:V2DI
22201 (match_operator:V2DI 3 "sse_comparison_operator"
22202 [(match_operand:V2DF 1 "register_operand" "0")
22203 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22204 "TARGET_SSE2"
22205 {
22206 if (GET_CODE (operands[3]) == UNORDERED)
22207 return "cmpordps\t{%2, %0|%0, %2}";
22208 else
22209 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22210 }
22211 [(set_attr "type" "ssecmp")
22212 (set_attr "mode" "V2DF")])
22213
22214 (define_insn "vmmaskcmpv2df3"
22215 [(set (match_operand:V2DI 0 "register_operand" "=x")
22216 (vec_merge: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 (subreg:V2DI (match_dup 1) 0)
22221 (const_int 1)))]
22222 "TARGET_SSE2"
22223 "cmp%D3sd\t{%2, %0|%0, %2}"
22224 [(set_attr "type" "ssecmp")
22225 (set_attr "mode" "DF")])
22226
22227 (define_insn "vmmaskncmpv2df3"
22228 [(set (match_operand:V2DI 0 "register_operand" "=x")
22229 (vec_merge:V2DI
22230 (not:V2DI
22231 (match_operator:V2DI 3 "sse_comparison_operator"
22232 [(match_operand:V2DF 1 "register_operand" "0")
22233 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22234 (subreg:V2DI (match_dup 1) 0)
22235 (const_int 1)))]
22236 "TARGET_SSE2"
22237 {
22238 if (GET_CODE (operands[3]) == UNORDERED)
22239 return "cmpordsd\t{%2, %0|%0, %2}";
22240 else
22241 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22242 }
22243 [(set_attr "type" "ssecmp")
22244 (set_attr "mode" "DF")])
22245
22246 (define_insn "sse2_comi"
22247 [(set (reg:CCFP 17)
22248 (compare:CCFP (vec_select:DF
22249 (match_operand:V2DF 0 "register_operand" "x")
22250 (parallel [(const_int 0)]))
22251 (vec_select:DF
22252 (match_operand:V2DF 1 "register_operand" "x")
22253 (parallel [(const_int 0)]))))]
22254 "TARGET_SSE2"
22255 "comisd\t{%1, %0|%0, %1}"
22256 [(set_attr "type" "ssecomi")
22257 (set_attr "mode" "DF")])
22258
22259 (define_insn "sse2_ucomi"
22260 [(set (reg:CCFPU 17)
22261 (compare:CCFPU (vec_select:DF
22262 (match_operand:V2DF 0 "register_operand" "x")
22263 (parallel [(const_int 0)]))
22264 (vec_select:DF
22265 (match_operand:V2DF 1 "register_operand" "x")
22266 (parallel [(const_int 0)]))))]
22267 "TARGET_SSE2"
22268 "ucomisd\t{%1, %0|%0, %1}"
22269 [(set_attr "type" "ssecomi")
22270 (set_attr "mode" "DF")])
22271
22272 ;; SSE Strange Moves.
22273
22274 (define_insn "sse2_movmskpd"
22275 [(set (match_operand:SI 0 "register_operand" "=r")
22276 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22277 UNSPEC_MOVMSK))]
22278 "TARGET_SSE2"
22279 "movmskpd\t{%1, %0|%0, %1}"
22280 [(set_attr "type" "ssecvt")
22281 (set_attr "mode" "V2DF")])
22282
22283 (define_insn "sse2_pmovmskb"
22284 [(set (match_operand:SI 0 "register_operand" "=r")
22285 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22286 UNSPEC_MOVMSK))]
22287 "TARGET_SSE2"
22288 "pmovmskb\t{%1, %0|%0, %1}"
22289 [(set_attr "type" "ssecvt")
22290 (set_attr "mode" "V2DF")])
22291
22292 (define_insn "sse2_maskmovdqu"
22293 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22294 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22295 (match_operand:V16QI 2 "register_operand" "x")]
22296 UNSPEC_MASKMOV))]
22297 "TARGET_SSE2"
22298 ;; @@@ check ordering of operands in intel/nonintel syntax
22299 "maskmovdqu\t{%2, %1|%1, %2}"
22300 [(set_attr "type" "ssecvt")
22301 (set_attr "mode" "TI")])
22302
22303 (define_insn "sse2_maskmovdqu_rex64"
22304 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22305 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22306 (match_operand:V16QI 2 "register_operand" "x")]
22307 UNSPEC_MASKMOV))]
22308 "TARGET_SSE2"
22309 ;; @@@ check ordering of operands in intel/nonintel syntax
22310 "maskmovdqu\t{%2, %1|%1, %2}"
22311 [(set_attr "type" "ssecvt")
22312 (set_attr "mode" "TI")])
22313
22314 (define_insn "sse2_movntv2df"
22315 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22316 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22317 UNSPEC_MOVNT))]
22318 "TARGET_SSE2"
22319 "movntpd\t{%1, %0|%0, %1}"
22320 [(set_attr "type" "ssecvt")
22321 (set_attr "mode" "V2DF")])
22322
22323 (define_insn "sse2_movntv2di"
22324 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22325 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22326 UNSPEC_MOVNT))]
22327 "TARGET_SSE2"
22328 "movntdq\t{%1, %0|%0, %1}"
22329 [(set_attr "type" "ssecvt")
22330 (set_attr "mode" "TI")])
22331
22332 (define_insn "sse2_movntsi"
22333 [(set (match_operand:SI 0 "memory_operand" "=m")
22334 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22335 UNSPEC_MOVNT))]
22336 "TARGET_SSE2"
22337 "movnti\t{%1, %0|%0, %1}"
22338 [(set_attr "type" "ssecvt")
22339 (set_attr "mode" "V2DF")])
22340
22341 ;; SSE <-> integer/MMX conversions
22342
22343 ;; Conversions between SI and SF
22344
22345 (define_insn "cvtdq2ps"
22346 [(set (match_operand:V4SF 0 "register_operand" "=x")
22347 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22348 "TARGET_SSE2"
22349 "cvtdq2ps\t{%1, %0|%0, %1}"
22350 [(set_attr "type" "ssecvt")
22351 (set_attr "mode" "V2DF")])
22352
22353 (define_insn "cvtps2dq"
22354 [(set (match_operand:V4SI 0 "register_operand" "=x")
22355 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22356 "TARGET_SSE2"
22357 "cvtps2dq\t{%1, %0|%0, %1}"
22358 [(set_attr "type" "ssecvt")
22359 (set_attr "mode" "TI")])
22360
22361 (define_insn "cvttps2dq"
22362 [(set (match_operand:V4SI 0 "register_operand" "=x")
22363 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22364 UNSPEC_FIX))]
22365 "TARGET_SSE2"
22366 "cvttps2dq\t{%1, %0|%0, %1}"
22367 [(set_attr "type" "ssecvt")
22368 (set_attr "mode" "TI")])
22369
22370 ;; Conversions between SI and DF
22371
22372 (define_insn "cvtdq2pd"
22373 [(set (match_operand:V2DF 0 "register_operand" "=x")
22374 (float:V2DF (vec_select:V2SI
22375 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22376 (parallel
22377 [(const_int 0)
22378 (const_int 1)]))))]
22379 "TARGET_SSE2"
22380 "cvtdq2pd\t{%1, %0|%0, %1}"
22381 [(set_attr "type" "ssecvt")
22382 (set_attr "mode" "V2DF")])
22383
22384 (define_insn "cvtpd2dq"
22385 [(set (match_operand:V4SI 0 "register_operand" "=x")
22386 (vec_concat:V4SI
22387 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22388 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22389 "TARGET_SSE2"
22390 "cvtpd2dq\t{%1, %0|%0, %1}"
22391 [(set_attr "type" "ssecvt")
22392 (set_attr "mode" "TI")])
22393
22394 (define_insn "cvttpd2dq"
22395 [(set (match_operand:V4SI 0 "register_operand" "=x")
22396 (vec_concat:V4SI
22397 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22398 UNSPEC_FIX)
22399 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22400 "TARGET_SSE2"
22401 "cvttpd2dq\t{%1, %0|%0, %1}"
22402 [(set_attr "type" "ssecvt")
22403 (set_attr "mode" "TI")])
22404
22405 (define_insn "cvtpd2pi"
22406 [(set (match_operand:V2SI 0 "register_operand" "=y")
22407 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22408 "TARGET_SSE2"
22409 "cvtpd2pi\t{%1, %0|%0, %1}"
22410 [(set_attr "type" "ssecvt")
22411 (set_attr "mode" "TI")])
22412
22413 (define_insn "cvttpd2pi"
22414 [(set (match_operand:V2SI 0 "register_operand" "=y")
22415 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22416 UNSPEC_FIX))]
22417 "TARGET_SSE2"
22418 "cvttpd2pi\t{%1, %0|%0, %1}"
22419 [(set_attr "type" "ssecvt")
22420 (set_attr "mode" "TI")])
22421
22422 (define_insn "cvtpi2pd"
22423 [(set (match_operand:V2DF 0 "register_operand" "=x")
22424 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22425 "TARGET_SSE2"
22426 "cvtpi2pd\t{%1, %0|%0, %1}"
22427 [(set_attr "type" "ssecvt")
22428 (set_attr "mode" "TI")])
22429
22430 ;; Conversions between SI and DF
22431
22432 (define_insn "cvtsd2si"
22433 [(set (match_operand:SI 0 "register_operand" "=r,r")
22434 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22435 (parallel [(const_int 0)]))))]
22436 "TARGET_SSE2"
22437 "cvtsd2si\t{%1, %0|%0, %1}"
22438 [(set_attr "type" "sseicvt")
22439 (set_attr "athlon_decode" "double,vector")
22440 (set_attr "mode" "SI")])
22441
22442 (define_insn "cvtsd2siq"
22443 [(set (match_operand:DI 0 "register_operand" "=r,r")
22444 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22445 (parallel [(const_int 0)]))))]
22446 "TARGET_SSE2 && TARGET_64BIT"
22447 "cvtsd2siq\t{%1, %0|%0, %1}"
22448 [(set_attr "type" "sseicvt")
22449 (set_attr "athlon_decode" "double,vector")
22450 (set_attr "mode" "DI")])
22451
22452 (define_insn "cvttsd2si"
22453 [(set (match_operand:SI 0 "register_operand" "=r,r")
22454 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22455 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22456 "TARGET_SSE2"
22457 "cvttsd2si\t{%1, %0|%0, %1}"
22458 [(set_attr "type" "sseicvt")
22459 (set_attr "mode" "SI")
22460 (set_attr "athlon_decode" "double,vector")])
22461
22462 (define_insn "cvttsd2siq"
22463 [(set (match_operand:DI 0 "register_operand" "=r,r")
22464 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22465 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22466 "TARGET_SSE2 && TARGET_64BIT"
22467 "cvttsd2siq\t{%1, %0|%0, %1}"
22468 [(set_attr "type" "sseicvt")
22469 (set_attr "mode" "DI")
22470 (set_attr "athlon_decode" "double,vector")])
22471
22472 (define_insn "cvtsi2sd"
22473 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22474 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22475 (vec_duplicate:V2DF
22476 (float:DF
22477 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22478 (const_int 2)))]
22479 "TARGET_SSE2"
22480 "cvtsi2sd\t{%2, %0|%0, %2}"
22481 [(set_attr "type" "sseicvt")
22482 (set_attr "mode" "DF")
22483 (set_attr "athlon_decode" "double,direct")])
22484
22485 (define_insn "cvtsi2sdq"
22486 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22487 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22488 (vec_duplicate:V2DF
22489 (float:DF
22490 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22491 (const_int 2)))]
22492 "TARGET_SSE2 && TARGET_64BIT"
22493 "cvtsi2sdq\t{%2, %0|%0, %2}"
22494 [(set_attr "type" "sseicvt")
22495 (set_attr "mode" "DF")
22496 (set_attr "athlon_decode" "double,direct")])
22497
22498 ;; Conversions between SF and DF
22499
22500 (define_insn "cvtsd2ss"
22501 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22502 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22503 (vec_duplicate:V4SF
22504 (float_truncate:V2SF
22505 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22506 (const_int 14)))]
22507 "TARGET_SSE2"
22508 "cvtsd2ss\t{%2, %0|%0, %2}"
22509 [(set_attr "type" "ssecvt")
22510 (set_attr "athlon_decode" "vector,double")
22511 (set_attr "mode" "SF")])
22512
22513 (define_insn "cvtss2sd"
22514 [(set (match_operand:V2DF 0 "register_operand" "=x")
22515 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22516 (float_extend:V2DF
22517 (vec_select:V2SF
22518 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22519 (parallel [(const_int 0)
22520 (const_int 1)])))
22521 (const_int 2)))]
22522 "TARGET_SSE2"
22523 "cvtss2sd\t{%2, %0|%0, %2}"
22524 [(set_attr "type" "ssecvt")
22525 (set_attr "mode" "DF")])
22526
22527 (define_insn "cvtpd2ps"
22528 [(set (match_operand:V4SF 0 "register_operand" "=x")
22529 (subreg:V4SF
22530 (vec_concat:V4SI
22531 (subreg:V2SI (float_truncate:V2SF
22532 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22533 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22534 "TARGET_SSE2"
22535 "cvtpd2ps\t{%1, %0|%0, %1}"
22536 [(set_attr "type" "ssecvt")
22537 (set_attr "mode" "V4SF")])
22538
22539 (define_insn "cvtps2pd"
22540 [(set (match_operand:V2DF 0 "register_operand" "=x")
22541 (float_extend:V2DF
22542 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22543 (parallel [(const_int 0)
22544 (const_int 1)]))))]
22545 "TARGET_SSE2"
22546 "cvtps2pd\t{%1, %0|%0, %1}"
22547 [(set_attr "type" "ssecvt")
22548 (set_attr "mode" "V2DF")])
22549
22550 ;; SSE2 variants of MMX insns
22551
22552 ;; MMX arithmetic
22553
22554 (define_insn "addv16qi3"
22555 [(set (match_operand:V16QI 0 "register_operand" "=x")
22556 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22557 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22558 "TARGET_SSE2"
22559 "paddb\t{%2, %0|%0, %2}"
22560 [(set_attr "type" "sseiadd")
22561 (set_attr "mode" "TI")])
22562
22563 (define_insn "addv8hi3"
22564 [(set (match_operand:V8HI 0 "register_operand" "=x")
22565 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22566 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22567 "TARGET_SSE2"
22568 "paddw\t{%2, %0|%0, %2}"
22569 [(set_attr "type" "sseiadd")
22570 (set_attr "mode" "TI")])
22571
22572 (define_insn "addv4si3"
22573 [(set (match_operand:V4SI 0 "register_operand" "=x")
22574 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22575 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22576 "TARGET_SSE2"
22577 "paddd\t{%2, %0|%0, %2}"
22578 [(set_attr "type" "sseiadd")
22579 (set_attr "mode" "TI")])
22580
22581 (define_insn "addv2di3"
22582 [(set (match_operand:V2DI 0 "register_operand" "=x")
22583 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22584 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22585 "TARGET_SSE2"
22586 "paddq\t{%2, %0|%0, %2}"
22587 [(set_attr "type" "sseiadd")
22588 (set_attr "mode" "TI")])
22589
22590 (define_insn "ssaddv16qi3"
22591 [(set (match_operand:V16QI 0 "register_operand" "=x")
22592 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22593 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22594 "TARGET_SSE2"
22595 "paddsb\t{%2, %0|%0, %2}"
22596 [(set_attr "type" "sseiadd")
22597 (set_attr "mode" "TI")])
22598
22599 (define_insn "ssaddv8hi3"
22600 [(set (match_operand:V8HI 0 "register_operand" "=x")
22601 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22602 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22603 "TARGET_SSE2"
22604 "paddsw\t{%2, %0|%0, %2}"
22605 [(set_attr "type" "sseiadd")
22606 (set_attr "mode" "TI")])
22607
22608 (define_insn "usaddv16qi3"
22609 [(set (match_operand:V16QI 0 "register_operand" "=x")
22610 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22611 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22612 "TARGET_SSE2"
22613 "paddusb\t{%2, %0|%0, %2}"
22614 [(set_attr "type" "sseiadd")
22615 (set_attr "mode" "TI")])
22616
22617 (define_insn "usaddv8hi3"
22618 [(set (match_operand:V8HI 0 "register_operand" "=x")
22619 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22620 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22621 "TARGET_SSE2"
22622 "paddusw\t{%2, %0|%0, %2}"
22623 [(set_attr "type" "sseiadd")
22624 (set_attr "mode" "TI")])
22625
22626 (define_insn "subv16qi3"
22627 [(set (match_operand:V16QI 0 "register_operand" "=x")
22628 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22629 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22630 "TARGET_SSE2"
22631 "psubb\t{%2, %0|%0, %2}"
22632 [(set_attr "type" "sseiadd")
22633 (set_attr "mode" "TI")])
22634
22635 (define_insn "subv8hi3"
22636 [(set (match_operand:V8HI 0 "register_operand" "=x")
22637 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22638 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22639 "TARGET_SSE2"
22640 "psubw\t{%2, %0|%0, %2}"
22641 [(set_attr "type" "sseiadd")
22642 (set_attr "mode" "TI")])
22643
22644 (define_insn "subv4si3"
22645 [(set (match_operand:V4SI 0 "register_operand" "=x")
22646 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22647 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22648 "TARGET_SSE2"
22649 "psubd\t{%2, %0|%0, %2}"
22650 [(set_attr "type" "sseiadd")
22651 (set_attr "mode" "TI")])
22652
22653 (define_insn "subv2di3"
22654 [(set (match_operand:V2DI 0 "register_operand" "=x")
22655 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22656 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22657 "TARGET_SSE2"
22658 "psubq\t{%2, %0|%0, %2}"
22659 [(set_attr "type" "sseiadd")
22660 (set_attr "mode" "TI")])
22661
22662 (define_insn "sssubv16qi3"
22663 [(set (match_operand:V16QI 0 "register_operand" "=x")
22664 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22665 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22666 "TARGET_SSE2"
22667 "psubsb\t{%2, %0|%0, %2}"
22668 [(set_attr "type" "sseiadd")
22669 (set_attr "mode" "TI")])
22670
22671 (define_insn "sssubv8hi3"
22672 [(set (match_operand:V8HI 0 "register_operand" "=x")
22673 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22674 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22675 "TARGET_SSE2"
22676 "psubsw\t{%2, %0|%0, %2}"
22677 [(set_attr "type" "sseiadd")
22678 (set_attr "mode" "TI")])
22679
22680 (define_insn "ussubv16qi3"
22681 [(set (match_operand:V16QI 0 "register_operand" "=x")
22682 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22683 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22684 "TARGET_SSE2"
22685 "psubusb\t{%2, %0|%0, %2}"
22686 [(set_attr "type" "sseiadd")
22687 (set_attr "mode" "TI")])
22688
22689 (define_insn "ussubv8hi3"
22690 [(set (match_operand:V8HI 0 "register_operand" "=x")
22691 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22692 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22693 "TARGET_SSE2"
22694 "psubusw\t{%2, %0|%0, %2}"
22695 [(set_attr "type" "sseiadd")
22696 (set_attr "mode" "TI")])
22697
22698 (define_insn "mulv8hi3"
22699 [(set (match_operand:V8HI 0 "register_operand" "=x")
22700 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22701 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22702 "TARGET_SSE2"
22703 "pmullw\t{%2, %0|%0, %2}"
22704 [(set_attr "type" "sseimul")
22705 (set_attr "mode" "TI")])
22706
22707 (define_insn "smulv8hi3_highpart"
22708 [(set (match_operand:V8HI 0 "register_operand" "=x")
22709 (truncate:V8HI
22710 (lshiftrt:V8SI
22711 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22712 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22713 (const_int 16))))]
22714 "TARGET_SSE2"
22715 "pmulhw\t{%2, %0|%0, %2}"
22716 [(set_attr "type" "sseimul")
22717 (set_attr "mode" "TI")])
22718
22719 (define_insn "umulv8hi3_highpart"
22720 [(set (match_operand:V8HI 0 "register_operand" "=x")
22721 (truncate:V8HI
22722 (lshiftrt:V8SI
22723 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22724 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22725 (const_int 16))))]
22726 "TARGET_SSE2"
22727 "pmulhuw\t{%2, %0|%0, %2}"
22728 [(set_attr "type" "sseimul")
22729 (set_attr "mode" "TI")])
22730
22731 (define_insn "sse2_umulsidi3"
22732 [(set (match_operand:DI 0 "register_operand" "=y")
22733 (mult:DI (zero_extend:DI (vec_select:SI
22734 (match_operand:V2SI 1 "register_operand" "0")
22735 (parallel [(const_int 0)])))
22736 (zero_extend:DI (vec_select:SI
22737 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22738 (parallel [(const_int 0)])))))]
22739 "TARGET_SSE2"
22740 "pmuludq\t{%2, %0|%0, %2}"
22741 [(set_attr "type" "sseimul")
22742 (set_attr "mode" "TI")])
22743
22744 (define_insn "sse2_umulv2siv2di3"
22745 [(set (match_operand:V2DI 0 "register_operand" "=x")
22746 (mult:V2DI (zero_extend:V2DI
22747 (vec_select:V2SI
22748 (match_operand:V4SI 1 "register_operand" "0")
22749 (parallel [(const_int 0) (const_int 2)])))
22750 (zero_extend:V2DI
22751 (vec_select:V2SI
22752 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22753 (parallel [(const_int 0) (const_int 2)])))))]
22754 "TARGET_SSE2"
22755 "pmuludq\t{%2, %0|%0, %2}"
22756 [(set_attr "type" "sseimul")
22757 (set_attr "mode" "TI")])
22758
22759 (define_insn "sse2_pmaddwd"
22760 [(set (match_operand:V4SI 0 "register_operand" "=x")
22761 (plus:V4SI
22762 (mult:V4SI
22763 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22764 (parallel [(const_int 0)
22765 (const_int 2)
22766 (const_int 4)
22767 (const_int 6)])))
22768 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22769 (parallel [(const_int 0)
22770 (const_int 2)
22771 (const_int 4)
22772 (const_int 6)]))))
22773 (mult:V4SI
22774 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22775 (parallel [(const_int 1)
22776 (const_int 3)
22777 (const_int 5)
22778 (const_int 7)])))
22779 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22780 (parallel [(const_int 1)
22781 (const_int 3)
22782 (const_int 5)
22783 (const_int 7)]))))))]
22784 "TARGET_SSE2"
22785 "pmaddwd\t{%2, %0|%0, %2}"
22786 [(set_attr "type" "sseiadd")
22787 (set_attr "mode" "TI")])
22788
22789 ;; Same as pxor, but don't show input operands so that we don't think
22790 ;; they are live.
22791 (define_insn "sse2_clrti"
22792 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22793 "TARGET_SSE2"
22794 {
22795 if (get_attr_mode (insn) == MODE_TI)
22796 return "pxor\t%0, %0";
22797 else
22798 return "xorps\t%0, %0";
22799 }
22800 [(set_attr "type" "ssemov")
22801 (set_attr "memory" "none")
22802 (set (attr "mode")
22803 (if_then_else
22804 (ne (symbol_ref "optimize_size")
22805 (const_int 0))
22806 (const_string "V4SF")
22807 (const_string "TI")))])
22808
22809 ;; MMX unsigned averages/sum of absolute differences
22810
22811 (define_insn "sse2_uavgv16qi3"
22812 [(set (match_operand:V16QI 0 "register_operand" "=x")
22813 (ashiftrt:V16QI
22814 (plus:V16QI (plus:V16QI
22815 (match_operand:V16QI 1 "register_operand" "0")
22816 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22817 (const_vector:V16QI [(const_int 1) (const_int 1)
22818 (const_int 1) (const_int 1)
22819 (const_int 1) (const_int 1)
22820 (const_int 1) (const_int 1)
22821 (const_int 1) (const_int 1)
22822 (const_int 1) (const_int 1)
22823 (const_int 1) (const_int 1)
22824 (const_int 1) (const_int 1)]))
22825 (const_int 1)))]
22826 "TARGET_SSE2"
22827 "pavgb\t{%2, %0|%0, %2}"
22828 [(set_attr "type" "sseiadd")
22829 (set_attr "mode" "TI")])
22830
22831 (define_insn "sse2_uavgv8hi3"
22832 [(set (match_operand:V8HI 0 "register_operand" "=x")
22833 (ashiftrt:V8HI
22834 (plus:V8HI (plus:V8HI
22835 (match_operand:V8HI 1 "register_operand" "0")
22836 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22837 (const_vector:V8HI [(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 "pavgw\t{%2, %0|%0, %2}"
22844 [(set_attr "type" "sseiadd")
22845 (set_attr "mode" "TI")])
22846
22847 ;; @@@ this isn't the right representation.
22848 (define_insn "sse2_psadbw"
22849 [(set (match_operand:V2DI 0 "register_operand" "=x")
22850 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22851 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22852 UNSPEC_PSADBW))]
22853 "TARGET_SSE2"
22854 "psadbw\t{%2, %0|%0, %2}"
22855 [(set_attr "type" "sseiadd")
22856 (set_attr "mode" "TI")])
22857
22858
22859 ;; MMX insert/extract/shuffle
22860
22861 (define_insn "sse2_pinsrw"
22862 [(set (match_operand:V8HI 0 "register_operand" "=x")
22863 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22864 (vec_duplicate:V8HI
22865 (truncate:HI
22866 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22867 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22868 "TARGET_SSE2"
22869 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22870 [(set_attr "type" "ssecvt")
22871 (set_attr "mode" "TI")])
22872
22873 (define_insn "sse2_pextrw"
22874 [(set (match_operand:SI 0 "register_operand" "=r")
22875 (zero_extend:SI
22876 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22877 (parallel
22878 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22879 "TARGET_SSE2"
22880 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22881 [(set_attr "type" "ssecvt")
22882 (set_attr "mode" "TI")])
22883
22884 (define_insn "sse2_pshufd"
22885 [(set (match_operand:V4SI 0 "register_operand" "=x")
22886 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
22887 (match_operand:SI 2 "immediate_operand" "i")]
22888 UNSPEC_SHUFFLE))]
22889 "TARGET_SSE2"
22890 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22891 [(set_attr "type" "ssecvt")
22892 (set_attr "mode" "TI")])
22893
22894 (define_insn "sse2_pshuflw"
22895 [(set (match_operand:V8HI 0 "register_operand" "=x")
22896 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
22897 (match_operand:SI 2 "immediate_operand" "i")]
22898 UNSPEC_PSHUFLW))]
22899 "TARGET_SSE2"
22900 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22901 [(set_attr "type" "ssecvt")
22902 (set_attr "mode" "TI")])
22903
22904 (define_insn "sse2_pshufhw"
22905 [(set (match_operand:V8HI 0 "register_operand" "=x")
22906 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
22907 (match_operand:SI 2 "immediate_operand" "i")]
22908 UNSPEC_PSHUFHW))]
22909 "TARGET_SSE2"
22910 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22911 [(set_attr "type" "ssecvt")
22912 (set_attr "mode" "TI")])
22913
22914 ;; MMX mask-generating comparisons
22915
22916 (define_insn "eqv16qi3"
22917 [(set (match_operand:V16QI 0 "register_operand" "=x")
22918 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22919 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22920 "TARGET_SSE2"
22921 "pcmpeqb\t{%2, %0|%0, %2}"
22922 [(set_attr "type" "ssecmp")
22923 (set_attr "mode" "TI")])
22924
22925 (define_insn "eqv8hi3"
22926 [(set (match_operand:V8HI 0 "register_operand" "=x")
22927 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22928 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22929 "TARGET_SSE2"
22930 "pcmpeqw\t{%2, %0|%0, %2}"
22931 [(set_attr "type" "ssecmp")
22932 (set_attr "mode" "TI")])
22933
22934 (define_insn "eqv4si3"
22935 [(set (match_operand:V4SI 0 "register_operand" "=x")
22936 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22937 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22938 "TARGET_SSE2"
22939 "pcmpeqd\t{%2, %0|%0, %2}"
22940 [(set_attr "type" "ssecmp")
22941 (set_attr "mode" "TI")])
22942
22943 (define_insn "gtv16qi3"
22944 [(set (match_operand:V16QI 0 "register_operand" "=x")
22945 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22946 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22947 "TARGET_SSE2"
22948 "pcmpgtb\t{%2, %0|%0, %2}"
22949 [(set_attr "type" "ssecmp")
22950 (set_attr "mode" "TI")])
22951
22952 (define_insn "gtv8hi3"
22953 [(set (match_operand:V8HI 0 "register_operand" "=x")
22954 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22955 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22956 "TARGET_SSE2"
22957 "pcmpgtw\t{%2, %0|%0, %2}"
22958 [(set_attr "type" "ssecmp")
22959 (set_attr "mode" "TI")])
22960
22961 (define_insn "gtv4si3"
22962 [(set (match_operand:V4SI 0 "register_operand" "=x")
22963 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22964 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22965 "TARGET_SSE2"
22966 "pcmpgtd\t{%2, %0|%0, %2}"
22967 [(set_attr "type" "ssecmp")
22968 (set_attr "mode" "TI")])
22969
22970
22971 ;; MMX max/min insns
22972
22973 (define_insn "umaxv16qi3"
22974 [(set (match_operand:V16QI 0 "register_operand" "=x")
22975 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22976 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22977 "TARGET_SSE2"
22978 "pmaxub\t{%2, %0|%0, %2}"
22979 [(set_attr "type" "sseiadd")
22980 (set_attr "mode" "TI")])
22981
22982 (define_insn "smaxv8hi3"
22983 [(set (match_operand:V8HI 0 "register_operand" "=x")
22984 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22985 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22986 "TARGET_SSE2"
22987 "pmaxsw\t{%2, %0|%0, %2}"
22988 [(set_attr "type" "sseiadd")
22989 (set_attr "mode" "TI")])
22990
22991 (define_insn "uminv16qi3"
22992 [(set (match_operand:V16QI 0 "register_operand" "=x")
22993 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22994 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22995 "TARGET_SSE2"
22996 "pminub\t{%2, %0|%0, %2}"
22997 [(set_attr "type" "sseiadd")
22998 (set_attr "mode" "TI")])
22999
23000 (define_insn "sminv8hi3"
23001 [(set (match_operand:V8HI 0 "register_operand" "=x")
23002 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23003 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23004 "TARGET_SSE2"
23005 "pminsw\t{%2, %0|%0, %2}"
23006 [(set_attr "type" "sseiadd")
23007 (set_attr "mode" "TI")])
23008
23009
23010 ;; MMX shifts
23011
23012 (define_insn "ashrv8hi3"
23013 [(set (match_operand:V8HI 0 "register_operand" "=x")
23014 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23015 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23016 "TARGET_SSE2"
23017 "psraw\t{%2, %0|%0, %2}"
23018 [(set_attr "type" "sseishft")
23019 (set_attr "mode" "TI")])
23020
23021 (define_insn "ashrv4si3"
23022 [(set (match_operand:V4SI 0 "register_operand" "=x")
23023 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23024 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23025 "TARGET_SSE2"
23026 "psrad\t{%2, %0|%0, %2}"
23027 [(set_attr "type" "sseishft")
23028 (set_attr "mode" "TI")])
23029
23030 (define_insn "lshrv8hi3"
23031 [(set (match_operand:V8HI 0 "register_operand" "=x")
23032 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23033 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23034 "TARGET_SSE2"
23035 "psrlw\t{%2, %0|%0, %2}"
23036 [(set_attr "type" "sseishft")
23037 (set_attr "mode" "TI")])
23038
23039 (define_insn "lshrv4si3"
23040 [(set (match_operand:V4SI 0 "register_operand" "=x")
23041 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23042 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23043 "TARGET_SSE2"
23044 "psrld\t{%2, %0|%0, %2}"
23045 [(set_attr "type" "sseishft")
23046 (set_attr "mode" "TI")])
23047
23048 (define_insn "lshrv2di3"
23049 [(set (match_operand:V2DI 0 "register_operand" "=x")
23050 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23051 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23052 "TARGET_SSE2"
23053 "psrlq\t{%2, %0|%0, %2}"
23054 [(set_attr "type" "sseishft")
23055 (set_attr "mode" "TI")])
23056
23057 (define_insn "ashlv8hi3"
23058 [(set (match_operand:V8HI 0 "register_operand" "=x")
23059 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23060 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23061 "TARGET_SSE2"
23062 "psllw\t{%2, %0|%0, %2}"
23063 [(set_attr "type" "sseishft")
23064 (set_attr "mode" "TI")])
23065
23066 (define_insn "ashlv4si3"
23067 [(set (match_operand:V4SI 0 "register_operand" "=x")
23068 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23069 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23070 "TARGET_SSE2"
23071 "pslld\t{%2, %0|%0, %2}"
23072 [(set_attr "type" "sseishft")
23073 (set_attr "mode" "TI")])
23074
23075 (define_insn "ashlv2di3"
23076 [(set (match_operand:V2DI 0 "register_operand" "=x")
23077 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23078 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23079 "TARGET_SSE2"
23080 "psllq\t{%2, %0|%0, %2}"
23081 [(set_attr "type" "sseishft")
23082 (set_attr "mode" "TI")])
23083
23084 (define_insn "ashrv8hi3_ti"
23085 [(set (match_operand:V8HI 0 "register_operand" "=x")
23086 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23087 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23088 "TARGET_SSE2"
23089 "psraw\t{%2, %0|%0, %2}"
23090 [(set_attr "type" "sseishft")
23091 (set_attr "mode" "TI")])
23092
23093 (define_insn "ashrv4si3_ti"
23094 [(set (match_operand:V4SI 0 "register_operand" "=x")
23095 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23096 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23097 "TARGET_SSE2"
23098 "psrad\t{%2, %0|%0, %2}"
23099 [(set_attr "type" "sseishft")
23100 (set_attr "mode" "TI")])
23101
23102 (define_insn "lshrv8hi3_ti"
23103 [(set (match_operand:V8HI 0 "register_operand" "=x")
23104 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23105 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23106 "TARGET_SSE2"
23107 "psrlw\t{%2, %0|%0, %2}"
23108 [(set_attr "type" "sseishft")
23109 (set_attr "mode" "TI")])
23110
23111 (define_insn "lshrv4si3_ti"
23112 [(set (match_operand:V4SI 0 "register_operand" "=x")
23113 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23114 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23115 "TARGET_SSE2"
23116 "psrld\t{%2, %0|%0, %2}"
23117 [(set_attr "type" "sseishft")
23118 (set_attr "mode" "TI")])
23119
23120 (define_insn "lshrv2di3_ti"
23121 [(set (match_operand:V2DI 0 "register_operand" "=x")
23122 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23123 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23124 "TARGET_SSE2"
23125 "psrlq\t{%2, %0|%0, %2}"
23126 [(set_attr "type" "sseishft")
23127 (set_attr "mode" "TI")])
23128
23129 (define_insn "ashlv8hi3_ti"
23130 [(set (match_operand:V8HI 0 "register_operand" "=x")
23131 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23132 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23133 "TARGET_SSE2"
23134 "psllw\t{%2, %0|%0, %2}"
23135 [(set_attr "type" "sseishft")
23136 (set_attr "mode" "TI")])
23137
23138 (define_insn "ashlv4si3_ti"
23139 [(set (match_operand:V4SI 0 "register_operand" "=x")
23140 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23141 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23142 "TARGET_SSE2"
23143 "pslld\t{%2, %0|%0, %2}"
23144 [(set_attr "type" "sseishft")
23145 (set_attr "mode" "TI")])
23146
23147 (define_insn "ashlv2di3_ti"
23148 [(set (match_operand:V2DI 0 "register_operand" "=x")
23149 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23150 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23151 "TARGET_SSE2"
23152 "psllq\t{%2, %0|%0, %2}"
23153 [(set_attr "type" "sseishft")
23154 (set_attr "mode" "TI")])
23155
23156 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23157 ;; we wouldn't need here it since we never generate TImode arithmetic.
23158
23159 ;; There has to be some kind of prize for the weirdest new instruction...
23160 (define_insn "sse2_ashlti3"
23161 [(set (match_operand:TI 0 "register_operand" "=x")
23162 (unspec:TI
23163 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23164 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23165 (const_int 8)))] UNSPEC_NOP))]
23166 "TARGET_SSE2"
23167 "pslldq\t{%2, %0|%0, %2}"
23168 [(set_attr "type" "sseishft")
23169 (set_attr "mode" "TI")])
23170
23171 (define_insn "sse2_lshrti3"
23172 [(set (match_operand:TI 0 "register_operand" "=x")
23173 (unspec:TI
23174 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23175 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23176 (const_int 8)))] UNSPEC_NOP))]
23177 "TARGET_SSE2"
23178 "psrldq\t{%2, %0|%0, %2}"
23179 [(set_attr "type" "sseishft")
23180 (set_attr "mode" "TI")])
23181
23182 ;; SSE unpack
23183
23184 (define_insn "sse2_unpckhpd"
23185 [(set (match_operand:V2DF 0 "register_operand" "=x")
23186 (vec_concat:V2DF
23187 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23188 (parallel [(const_int 1)]))
23189 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23190 (parallel [(const_int 1)]))))]
23191 "TARGET_SSE2"
23192 "unpckhpd\t{%2, %0|%0, %2}"
23193 [(set_attr "type" "ssecvt")
23194 (set_attr "mode" "V2DF")])
23195
23196 (define_insn "sse2_unpcklpd"
23197 [(set (match_operand:V2DF 0 "register_operand" "=x")
23198 (vec_concat:V2DF
23199 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23200 (parallel [(const_int 0)]))
23201 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23202 (parallel [(const_int 0)]))))]
23203 "TARGET_SSE2"
23204 "unpcklpd\t{%2, %0|%0, %2}"
23205 [(set_attr "type" "ssecvt")
23206 (set_attr "mode" "V2DF")])
23207
23208 ;; MMX pack/unpack insns.
23209
23210 (define_insn "sse2_packsswb"
23211 [(set (match_operand:V16QI 0 "register_operand" "=x")
23212 (vec_concat:V16QI
23213 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23214 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23215 "TARGET_SSE2"
23216 "packsswb\t{%2, %0|%0, %2}"
23217 [(set_attr "type" "ssecvt")
23218 (set_attr "mode" "TI")])
23219
23220 (define_insn "sse2_packssdw"
23221 [(set (match_operand:V8HI 0 "register_operand" "=x")
23222 (vec_concat:V8HI
23223 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23224 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23225 "TARGET_SSE2"
23226 "packssdw\t{%2, %0|%0, %2}"
23227 [(set_attr "type" "ssecvt")
23228 (set_attr "mode" "TI")])
23229
23230 (define_insn "sse2_packuswb"
23231 [(set (match_operand:V16QI 0 "register_operand" "=x")
23232 (vec_concat:V16QI
23233 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23234 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23235 "TARGET_SSE2"
23236 "packuswb\t{%2, %0|%0, %2}"
23237 [(set_attr "type" "ssecvt")
23238 (set_attr "mode" "TI")])
23239
23240 (define_insn "sse2_punpckhbw"
23241 [(set (match_operand:V16QI 0 "register_operand" "=x")
23242 (vec_merge:V16QI
23243 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23244 (parallel [(const_int 8) (const_int 0)
23245 (const_int 9) (const_int 1)
23246 (const_int 10) (const_int 2)
23247 (const_int 11) (const_int 3)
23248 (const_int 12) (const_int 4)
23249 (const_int 13) (const_int 5)
23250 (const_int 14) (const_int 6)
23251 (const_int 15) (const_int 7)]))
23252 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23253 (parallel [(const_int 0) (const_int 8)
23254 (const_int 1) (const_int 9)
23255 (const_int 2) (const_int 10)
23256 (const_int 3) (const_int 11)
23257 (const_int 4) (const_int 12)
23258 (const_int 5) (const_int 13)
23259 (const_int 6) (const_int 14)
23260 (const_int 7) (const_int 15)]))
23261 (const_int 21845)))]
23262 "TARGET_SSE2"
23263 "punpckhbw\t{%2, %0|%0, %2}"
23264 [(set_attr "type" "ssecvt")
23265 (set_attr "mode" "TI")])
23266
23267 (define_insn "sse2_punpckhwd"
23268 [(set (match_operand:V8HI 0 "register_operand" "=x")
23269 (vec_merge:V8HI
23270 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23271 (parallel [(const_int 4) (const_int 0)
23272 (const_int 5) (const_int 1)
23273 (const_int 6) (const_int 2)
23274 (const_int 7) (const_int 3)]))
23275 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23276 (parallel [(const_int 0) (const_int 4)
23277 (const_int 1) (const_int 5)
23278 (const_int 2) (const_int 6)
23279 (const_int 3) (const_int 7)]))
23280 (const_int 85)))]
23281 "TARGET_SSE2"
23282 "punpckhwd\t{%2, %0|%0, %2}"
23283 [(set_attr "type" "ssecvt")
23284 (set_attr "mode" "TI")])
23285
23286 (define_insn "sse2_punpckhdq"
23287 [(set (match_operand:V4SI 0 "register_operand" "=x")
23288 (vec_merge:V4SI
23289 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23290 (parallel [(const_int 2) (const_int 0)
23291 (const_int 3) (const_int 1)]))
23292 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23293 (parallel [(const_int 0) (const_int 2)
23294 (const_int 1) (const_int 3)]))
23295 (const_int 5)))]
23296 "TARGET_SSE2"
23297 "punpckhdq\t{%2, %0|%0, %2}"
23298 [(set_attr "type" "ssecvt")
23299 (set_attr "mode" "TI")])
23300
23301 (define_insn "sse2_punpcklbw"
23302 [(set (match_operand:V16QI 0 "register_operand" "=x")
23303 (vec_merge:V16QI
23304 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23305 (parallel [(const_int 0) (const_int 8)
23306 (const_int 1) (const_int 9)
23307 (const_int 2) (const_int 10)
23308 (const_int 3) (const_int 11)
23309 (const_int 4) (const_int 12)
23310 (const_int 5) (const_int 13)
23311 (const_int 6) (const_int 14)
23312 (const_int 7) (const_int 15)]))
23313 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23314 (parallel [(const_int 8) (const_int 0)
23315 (const_int 9) (const_int 1)
23316 (const_int 10) (const_int 2)
23317 (const_int 11) (const_int 3)
23318 (const_int 12) (const_int 4)
23319 (const_int 13) (const_int 5)
23320 (const_int 14) (const_int 6)
23321 (const_int 15) (const_int 7)]))
23322 (const_int 21845)))]
23323 "TARGET_SSE2"
23324 "punpcklbw\t{%2, %0|%0, %2}"
23325 [(set_attr "type" "ssecvt")
23326 (set_attr "mode" "TI")])
23327
23328 (define_insn "sse2_punpcklwd"
23329 [(set (match_operand:V8HI 0 "register_operand" "=x")
23330 (vec_merge:V8HI
23331 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23332 (parallel [(const_int 0) (const_int 4)
23333 (const_int 1) (const_int 5)
23334 (const_int 2) (const_int 6)
23335 (const_int 3) (const_int 7)]))
23336 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23337 (parallel [(const_int 4) (const_int 0)
23338 (const_int 5) (const_int 1)
23339 (const_int 6) (const_int 2)
23340 (const_int 7) (const_int 3)]))
23341 (const_int 85)))]
23342 "TARGET_SSE2"
23343 "punpcklwd\t{%2, %0|%0, %2}"
23344 [(set_attr "type" "ssecvt")
23345 (set_attr "mode" "TI")])
23346
23347 (define_insn "sse2_punpckldq"
23348 [(set (match_operand:V4SI 0 "register_operand" "=x")
23349 (vec_merge:V4SI
23350 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23351 (parallel [(const_int 0) (const_int 2)
23352 (const_int 1) (const_int 3)]))
23353 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23354 (parallel [(const_int 2) (const_int 0)
23355 (const_int 3) (const_int 1)]))
23356 (const_int 5)))]
23357 "TARGET_SSE2"
23358 "punpckldq\t{%2, %0|%0, %2}"
23359 [(set_attr "type" "ssecvt")
23360 (set_attr "mode" "TI")])
23361
23362 (define_insn "sse2_punpcklqdq"
23363 [(set (match_operand:V2DI 0 "register_operand" "=x")
23364 (vec_merge:V2DI
23365 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23366 (parallel [(const_int 1)
23367 (const_int 0)]))
23368 (match_operand:V2DI 1 "register_operand" "0")
23369 (const_int 1)))]
23370 "TARGET_SSE2"
23371 "punpcklqdq\t{%2, %0|%0, %2}"
23372 [(set_attr "type" "ssecvt")
23373 (set_attr "mode" "TI")])
23374
23375 (define_insn "sse2_punpckhqdq"
23376 [(set (match_operand:V2DI 0 "register_operand" "=x")
23377 (vec_merge:V2DI
23378 (match_operand:V2DI 1 "register_operand" "0")
23379 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23380 (parallel [(const_int 1)
23381 (const_int 0)]))
23382 (const_int 1)))]
23383 "TARGET_SSE2"
23384 "punpckhqdq\t{%2, %0|%0, %2}"
23385 [(set_attr "type" "ssecvt")
23386 (set_attr "mode" "TI")])
23387
23388 ;; SSE2 moves
23389
23390 (define_insn "sse2_movapd"
23391 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23392 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23393 UNSPEC_MOVA))]
23394 "TARGET_SSE2
23395 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23396 "movapd\t{%1, %0|%0, %1}"
23397 [(set_attr "type" "ssemov")
23398 (set_attr "mode" "V2DF")])
23399
23400 (define_insn "sse2_movupd"
23401 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23402 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23403 UNSPEC_MOVU))]
23404 "TARGET_SSE2
23405 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23406 "movupd\t{%1, %0|%0, %1}"
23407 [(set_attr "type" "ssecvt")
23408 (set_attr "mode" "V2DF")])
23409
23410 (define_insn "sse2_movdqa"
23411 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23412 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23413 UNSPEC_MOVA))]
23414 "TARGET_SSE2
23415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23416 "movdqa\t{%1, %0|%0, %1}"
23417 [(set_attr "type" "ssemov")
23418 (set_attr "mode" "TI")])
23419
23420 (define_insn "sse2_movdqu"
23421 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23422 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23423 UNSPEC_MOVU))]
23424 "TARGET_SSE2
23425 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23426 "movdqu\t{%1, %0|%0, %1}"
23427 [(set_attr "type" "ssecvt")
23428 (set_attr "mode" "TI")])
23429
23430 (define_insn "sse2_movdq2q"
23431 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23432 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23433 (parallel [(const_int 0)])))]
23434 "TARGET_SSE2 && !TARGET_64BIT"
23435 "@
23436 movq\t{%1, %0|%0, %1}
23437 movdq2q\t{%1, %0|%0, %1}"
23438 [(set_attr "type" "ssecvt")
23439 (set_attr "mode" "TI")])
23440
23441 (define_insn "sse2_movdq2q_rex64"
23442 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23443 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23444 (parallel [(const_int 0)])))]
23445 "TARGET_SSE2 && TARGET_64BIT"
23446 "@
23447 movq\t{%1, %0|%0, %1}
23448 movdq2q\t{%1, %0|%0, %1}
23449 movd\t{%1, %0|%0, %1}"
23450 [(set_attr "type" "ssecvt")
23451 (set_attr "mode" "TI")])
23452
23453 (define_insn "sse2_movq2dq"
23454 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23455 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23456 (const_int 0)))]
23457 "TARGET_SSE2 && !TARGET_64BIT"
23458 "@
23459 movq\t{%1, %0|%0, %1}
23460 movq2dq\t{%1, %0|%0, %1}"
23461 [(set_attr "type" "ssecvt,ssemov")
23462 (set_attr "mode" "TI")])
23463
23464 (define_insn "sse2_movq2dq_rex64"
23465 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23466 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23467 (const_int 0)))]
23468 "TARGET_SSE2 && TARGET_64BIT"
23469 "@
23470 movq\t{%1, %0|%0, %1}
23471 movq2dq\t{%1, %0|%0, %1}
23472 movd\t{%1, %0|%0, %1}"
23473 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23474 (set_attr "mode" "TI")])
23475
23476 (define_insn "sse2_movq"
23477 [(set (match_operand:V2DI 0 "register_operand" "=x")
23478 (vec_concat:V2DI (vec_select:DI
23479 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23480 (parallel [(const_int 0)]))
23481 (const_int 0)))]
23482 "TARGET_SSE2"
23483 "movq\t{%1, %0|%0, %1}"
23484 [(set_attr "type" "ssemov")
23485 (set_attr "mode" "TI")])
23486
23487 (define_insn "sse2_loadd"
23488 [(set (match_operand:V4SI 0 "register_operand" "=x")
23489 (vec_merge:V4SI
23490 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23491 (const_vector:V4SI [(const_int 0)
23492 (const_int 0)
23493 (const_int 0)
23494 (const_int 0)])
23495 (const_int 1)))]
23496 "TARGET_SSE2"
23497 "movd\t{%1, %0|%0, %1}"
23498 [(set_attr "type" "ssemov")
23499 (set_attr "mode" "TI")])
23500
23501 (define_insn "sse2_stored"
23502 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23503 (vec_select:SI
23504 (match_operand:V4SI 1 "register_operand" "x")
23505 (parallel [(const_int 0)])))]
23506 "TARGET_SSE2"
23507 "movd\t{%1, %0|%0, %1}"
23508 [(set_attr "type" "ssemov")
23509 (set_attr "mode" "TI")])
23510
23511 (define_insn "sse2_movhpd"
23512 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23513 (vec_merge:V2DF
23514 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23515 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23516 (const_int 2)))]
23517 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23518 "movhpd\t{%2, %0|%0, %2}"
23519 [(set_attr "type" "ssecvt")
23520 (set_attr "mode" "V2DF")])
23521
23522 (define_expand "sse2_loadsd"
23523 [(match_operand:V2DF 0 "register_operand" "")
23524 (match_operand:DF 1 "memory_operand" "")]
23525 "TARGET_SSE2"
23526 {
23527 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23528 CONST0_RTX (V2DFmode)));
23529 DONE;
23530 })
23531
23532 (define_insn "sse2_loadsd_1"
23533 [(set (match_operand:V2DF 0 "register_operand" "=x")
23534 (vec_merge:V2DF
23535 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23536 (match_operand:V2DF 2 "const0_operand" "X")
23537 (const_int 1)))]
23538 "TARGET_SSE2"
23539 "movsd\t{%1, %0|%0, %1}"
23540 [(set_attr "type" "ssecvt")
23541 (set_attr "mode" "DF")])
23542
23543 (define_insn "sse2_movsd"
23544 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23545 (vec_merge:V2DF
23546 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23547 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23548 (const_int 1)))]
23549 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
23550 "@movsd\t{%2, %0|%0, %2}
23551 movlpd\t{%2, %0|%0, %2}
23552 movlpd\t{%2, %0|%0, %2}"
23553 [(set_attr "type" "ssecvt")
23554 (set_attr "mode" "DF,V2DF,V2DF")])
23555
23556 (define_insn "sse2_storesd"
23557 [(set (match_operand:DF 0 "memory_operand" "=m")
23558 (vec_select:DF
23559 (match_operand:V2DF 1 "register_operand" "x")
23560 (parallel [(const_int 0)])))]
23561 "TARGET_SSE2"
23562 "movsd\t{%1, %0|%0, %1}"
23563 [(set_attr "type" "ssecvt")
23564 (set_attr "mode" "DF")])
23565
23566 (define_insn "sse2_shufpd"
23567 [(set (match_operand:V2DF 0 "register_operand" "=x")
23568 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23569 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23570 (match_operand:SI 3 "immediate_operand" "i")]
23571 UNSPEC_SHUFFLE))]
23572 "TARGET_SSE2"
23573 ;; @@@ check operand order for intel/nonintel syntax
23574 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23575 [(set_attr "type" "ssecvt")
23576 (set_attr "mode" "V2DF")])
23577
23578 (define_insn "sse2_clflush"
23579 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23580 UNSPECV_CLFLUSH)]
23581 "TARGET_SSE2"
23582 "clflush %0"
23583 [(set_attr "type" "sse")
23584 (set_attr "memory" "unknown")])
23585
23586 (define_expand "sse2_mfence"
23587 [(set (match_dup 0)
23588 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23589 "TARGET_SSE2"
23590 {
23591 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23592 MEM_VOLATILE_P (operands[0]) = 1;
23593 })
23594
23595 (define_insn "*mfence_insn"
23596 [(set (match_operand:BLK 0 "" "")
23597 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23598 "TARGET_SSE2"
23599 "mfence"
23600 [(set_attr "type" "sse")
23601 (set_attr "memory" "unknown")])
23602
23603 (define_expand "sse2_lfence"
23604 [(set (match_dup 0)
23605 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23606 "TARGET_SSE2"
23607 {
23608 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23609 MEM_VOLATILE_P (operands[0]) = 1;
23610 })
23611
23612 (define_insn "*lfence_insn"
23613 [(set (match_operand:BLK 0 "" "")
23614 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23615 "TARGET_SSE2"
23616 "lfence"
23617 [(set_attr "type" "sse")
23618 (set_attr "memory" "unknown")])
23619
23620 ;; SSE3
23621
23622 (define_insn "mwait"
23623 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23624 (match_operand:SI 1 "register_operand" "c")]
23625 UNSPECV_MWAIT)]
23626 "TARGET_SSE3"
23627 "mwait\t%0, %1"
23628 [(set_attr "length" "3")])
23629
23630 (define_insn "monitor"
23631 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23632 (match_operand:SI 1 "register_operand" "c")
23633 (match_operand:SI 2 "register_operand" "d")]
23634 UNSPECV_MONITOR)]
23635 "TARGET_SSE3"
23636 "monitor\t%0, %1, %2"
23637 [(set_attr "length" "3")])
23638
23639 ;; SSE3 arithmetic
23640
23641 (define_insn "addsubv4sf3"
23642 [(set (match_operand:V4SF 0 "register_operand" "=x")
23643 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23644 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23645 UNSPEC_ADDSUB))]
23646 "TARGET_SSE3"
23647 "addsubps\t{%2, %0|%0, %2}"
23648 [(set_attr "type" "sseadd")
23649 (set_attr "mode" "V4SF")])
23650
23651 (define_insn "addsubv2df3"
23652 [(set (match_operand:V2DF 0 "register_operand" "=x")
23653 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23654 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23655 UNSPEC_ADDSUB))]
23656 "TARGET_SSE3"
23657 "addsubpd\t{%2, %0|%0, %2}"
23658 [(set_attr "type" "sseadd")
23659 (set_attr "mode" "V2DF")])
23660
23661 (define_insn "haddv4sf3"
23662 [(set (match_operand:V4SF 0 "register_operand" "=x")
23663 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23664 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23665 UNSPEC_HADD))]
23666 "TARGET_SSE3"
23667 "haddps\t{%2, %0|%0, %2}"
23668 [(set_attr "type" "sseadd")
23669 (set_attr "mode" "V4SF")])
23670
23671 (define_insn "haddv2df3"
23672 [(set (match_operand:V2DF 0 "register_operand" "=x")
23673 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23674 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23675 UNSPEC_HADD))]
23676 "TARGET_SSE3"
23677 "haddpd\t{%2, %0|%0, %2}"
23678 [(set_attr "type" "sseadd")
23679 (set_attr "mode" "V2DF")])
23680
23681 (define_insn "hsubv4sf3"
23682 [(set (match_operand:V4SF 0 "register_operand" "=x")
23683 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23684 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23685 UNSPEC_HSUB))]
23686 "TARGET_SSE3"
23687 "hsubps\t{%2, %0|%0, %2}"
23688 [(set_attr "type" "sseadd")
23689 (set_attr "mode" "V4SF")])
23690
23691 (define_insn "hsubv2df3"
23692 [(set (match_operand:V2DF 0 "register_operand" "=x")
23693 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23694 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23695 UNSPEC_HSUB))]
23696 "TARGET_SSE3"
23697 "hsubpd\t{%2, %0|%0, %2}"
23698 [(set_attr "type" "sseadd")
23699 (set_attr "mode" "V2DF")])
23700
23701 (define_insn "movshdup"
23702 [(set (match_operand:V4SF 0 "register_operand" "=x")
23703 (unspec:V4SF
23704 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23705 "TARGET_SSE3"
23706 "movshdup\t{%1, %0|%0, %1}"
23707 [(set_attr "type" "sse")
23708 (set_attr "mode" "V4SF")])
23709
23710 (define_insn "movsldup"
23711 [(set (match_operand:V4SF 0 "register_operand" "=x")
23712 (unspec:V4SF
23713 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23714 "TARGET_SSE3"
23715 "movsldup\t{%1, %0|%0, %1}"
23716 [(set_attr "type" "sse")
23717 (set_attr "mode" "V4SF")])
23718
23719 (define_insn "lddqu"
23720 [(set (match_operand:V16QI 0 "register_operand" "=x")
23721 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23722 UNSPEC_LDQQU))]
23723 "TARGET_SSE3"
23724 "lddqu\t{%1, %0|%0, %1}"
23725 [(set_attr "type" "ssecvt")
23726 (set_attr "mode" "TI")])
23727
23728 (define_insn "loadddup"
23729 [(set (match_operand:V2DF 0 "register_operand" "=x")
23730 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23731 "TARGET_SSE3"
23732 "movddup\t{%1, %0|%0, %1}"
23733 [(set_attr "type" "ssecvt")
23734 (set_attr "mode" "DF")])
23735
23736 (define_insn "movddup"
23737 [(set (match_operand:V2DF 0 "register_operand" "=x")
23738 (vec_duplicate:V2DF
23739 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23740 (parallel [(const_int 0)]))))]
23741 "TARGET_SSE3"
23742 "movddup\t{%1, %0|%0, %1}"
23743 [(set_attr "type" "ssecvt")
23744 (set_attr "mode" "DF")])