optabs.h (enum optab_index): Add new OTI_logb and OTI_ilogb.
[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_FSCALE 67)
121 (UNSPEC_FRNDINT 68)
122 (UNSPEC_F2XM1 69)
123
124 ; x87 Double output FP
125 (UNSPEC_SINCOS_COS 80)
126 (UNSPEC_SINCOS_SIN 81)
127 (UNSPEC_TAN_ONE 82)
128 (UNSPEC_TAN_TAN 83)
129 (UNSPEC_XTRACT_FRACT 84)
130 (UNSPEC_XTRACT_EXP 85)
131
132 ; REP instruction
133 (UNSPEC_REP 75)
134 ])
135
136 (define_constants
137 [(UNSPECV_BLOCKAGE 0)
138 (UNSPECV_EH_RETURN 13)
139 (UNSPECV_EMMS 31)
140 (UNSPECV_LDMXCSR 37)
141 (UNSPECV_STMXCSR 40)
142 (UNSPECV_FEMMS 46)
143 (UNSPECV_CLFLUSH 57)
144 (UNSPECV_ALIGN 68)
145 (UNSPECV_MONITOR 69)
146 (UNSPECV_MWAIT 70)
147 ])
148
149 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
150 ;; from i386.c.
151
152 ;; In C guard expressions, put expressions which may be compile-time
153 ;; constants first. This allows for better optimization. For
154 ;; example, write "TARGET_64BIT && reload_completed", not
155 ;; "reload_completed && TARGET_64BIT".
156
157 \f
158 ;; Processor type. This attribute must exactly match the processor_type
159 ;; enumeration in i386.h.
160 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
161 (const (symbol_ref "ix86_tune")))
162
163 ;; A basic instruction type. Refinements due to arguments to be
164 ;; provided in other attributes.
165 (define_attr "type"
166 "other,multi,
167 alu,alu1,negnot,imov,imovx,lea,
168 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
169 icmp,test,ibr,setcc,icmov,
170 push,pop,call,callv,leave,
171 str,cld,
172 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
173 sselog,sseiadd,sseishft,sseimul,
174 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
175 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
176 (const_string "other"))
177
178 ;; Main data type used by the insn
179 (define_attr "mode"
180 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
181 (const_string "unknown"))
182
183 ;; The CPU unit operations uses.
184 (define_attr "unit" "integer,i387,sse,mmx,unknown"
185 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
186 (const_string "i387")
187 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
188 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
189 (const_string "sse")
190 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
191 (const_string "mmx")
192 (eq_attr "type" "other")
193 (const_string "unknown")]
194 (const_string "integer")))
195
196 ;; The (bounding maximum) length of an instruction immediate.
197 (define_attr "length_immediate" ""
198 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
199 (const_int 0)
200 (eq_attr "unit" "i387,sse,mmx")
201 (const_int 0)
202 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
203 imul,icmp,push,pop")
204 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
205 (eq_attr "type" "imov,test")
206 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
207 (eq_attr "type" "call")
208 (if_then_else (match_operand 0 "constant_call_address_operand" "")
209 (const_int 4)
210 (const_int 0))
211 (eq_attr "type" "callv")
212 (if_then_else (match_operand 1 "constant_call_address_operand" "")
213 (const_int 4)
214 (const_int 0))
215 ;; We don't know the size before shorten_branches. Expect
216 ;; the instruction to fit for better scheduling.
217 (eq_attr "type" "ibr")
218 (const_int 1)
219 ]
220 (symbol_ref "/* Update immediate_length and other attributes! */
221 abort(),1")))
222
223 ;; The (bounding maximum) length of an instruction address.
224 (define_attr "length_address" ""
225 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
226 (const_int 0)
227 (and (eq_attr "type" "call")
228 (match_operand 0 "constant_call_address_operand" ""))
229 (const_int 0)
230 (and (eq_attr "type" "callv")
231 (match_operand 1 "constant_call_address_operand" ""))
232 (const_int 0)
233 ]
234 (symbol_ref "ix86_attr_length_address_default (insn)")))
235
236 ;; Set when length prefix is used.
237 (define_attr "prefix_data16" ""
238 (if_then_else (ior (eq_attr "mode" "HI")
239 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
240 (const_int 1)
241 (const_int 0)))
242
243 ;; Set when string REP prefix is used.
244 (define_attr "prefix_rep" ""
245 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
246 (const_int 1)
247 (const_int 0)))
248
249 ;; Set when 0f opcode prefix is used.
250 (define_attr "prefix_0f" ""
251 (if_then_else
252 (ior (eq_attr "type" "imovx,setcc,icmov")
253 (eq_attr "unit" "sse,mmx"))
254 (const_int 1)
255 (const_int 0)))
256
257 ;; Set when REX opcode prefix is used.
258 (define_attr "prefix_rex" ""
259 (cond [(and (eq_attr "mode" "DI")
260 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
261 (const_int 1)
262 (and (eq_attr "mode" "QI")
263 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
264 (const_int 0)))
265 (const_int 1)
266 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
267 (const_int 0))
268 (const_int 1)
269 ]
270 (const_int 0)))
271
272 ;; Set when modrm byte is used.
273 (define_attr "modrm" ""
274 (cond [(eq_attr "type" "str,cld,leave")
275 (const_int 0)
276 (eq_attr "unit" "i387")
277 (const_int 0)
278 (and (eq_attr "type" "incdec")
279 (ior (match_operand:SI 1 "register_operand" "")
280 (match_operand:HI 1 "register_operand" "")))
281 (const_int 0)
282 (and (eq_attr "type" "push")
283 (not (match_operand 1 "memory_operand" "")))
284 (const_int 0)
285 (and (eq_attr "type" "pop")
286 (not (match_operand 0 "memory_operand" "")))
287 (const_int 0)
288 (and (eq_attr "type" "imov")
289 (and (match_operand 0 "register_operand" "")
290 (match_operand 1 "immediate_operand" "")))
291 (const_int 0)
292 (and (eq_attr "type" "call")
293 (match_operand 0 "constant_call_address_operand" ""))
294 (const_int 0)
295 (and (eq_attr "type" "callv")
296 (match_operand 1 "constant_call_address_operand" ""))
297 (const_int 0)
298 ]
299 (const_int 1)))
300
301 ;; The (bounding maximum) length of an instruction in bytes.
302 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
303 ;; to split it and compute proper length as for other insns.
304 (define_attr "length" ""
305 (cond [(eq_attr "type" "other,multi,fistp")
306 (const_int 16)
307 (eq_attr "type" "fcmp")
308 (const_int 4)
309 (eq_attr "unit" "i387")
310 (plus (const_int 2)
311 (plus (attr "prefix_data16")
312 (attr "length_address")))]
313 (plus (plus (attr "modrm")
314 (plus (attr "prefix_0f")
315 (plus (attr "prefix_rex")
316 (const_int 1))))
317 (plus (attr "prefix_rep")
318 (plus (attr "prefix_data16")
319 (plus (attr "length_immediate")
320 (attr "length_address")))))))
321
322 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
323 ;; `store' if there is a simple memory reference therein, or `unknown'
324 ;; if the instruction is complex.
325
326 (define_attr "memory" "none,load,store,both,unknown"
327 (cond [(eq_attr "type" "other,multi,str")
328 (const_string "unknown")
329 (eq_attr "type" "lea,fcmov,fpspc,cld")
330 (const_string "none")
331 (eq_attr "type" "fistp,leave")
332 (const_string "both")
333 (eq_attr "type" "push")
334 (if_then_else (match_operand 1 "memory_operand" "")
335 (const_string "both")
336 (const_string "store"))
337 (eq_attr "type" "pop")
338 (if_then_else (match_operand 0 "memory_operand" "")
339 (const_string "both")
340 (const_string "load"))
341 (eq_attr "type" "setcc")
342 (if_then_else (match_operand 0 "memory_operand" "")
343 (const_string "store")
344 (const_string "none"))
345 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
346 (if_then_else (ior (match_operand 0 "memory_operand" "")
347 (match_operand 1 "memory_operand" ""))
348 (const_string "load")
349 (const_string "none"))
350 (eq_attr "type" "ibr")
351 (if_then_else (match_operand 0 "memory_operand" "")
352 (const_string "load")
353 (const_string "none"))
354 (eq_attr "type" "call")
355 (if_then_else (match_operand 0 "constant_call_address_operand" "")
356 (const_string "none")
357 (const_string "load"))
358 (eq_attr "type" "callv")
359 (if_then_else (match_operand 1 "constant_call_address_operand" "")
360 (const_string "none")
361 (const_string "load"))
362 (and (eq_attr "type" "alu1,negnot,ishift1")
363 (match_operand 1 "memory_operand" ""))
364 (const_string "both")
365 (and (match_operand 0 "memory_operand" "")
366 (match_operand 1 "memory_operand" ""))
367 (const_string "both")
368 (match_operand 0 "memory_operand" "")
369 (const_string "store")
370 (match_operand 1 "memory_operand" "")
371 (const_string "load")
372 (and (eq_attr "type"
373 "!alu1,negnot,ishift1,
374 imov,imovx,icmp,test,
375 fmov,fcmp,fsgn,
376 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
377 mmx,mmxmov,mmxcmp,mmxcvt")
378 (match_operand 2 "memory_operand" ""))
379 (const_string "load")
380 (and (eq_attr "type" "icmov")
381 (match_operand 3 "memory_operand" ""))
382 (const_string "load")
383 ]
384 (const_string "none")))
385
386 ;; Indicates if an instruction has both an immediate and a displacement.
387
388 (define_attr "imm_disp" "false,true,unknown"
389 (cond [(eq_attr "type" "other,multi")
390 (const_string "unknown")
391 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
392 (and (match_operand 0 "memory_displacement_operand" "")
393 (match_operand 1 "immediate_operand" "")))
394 (const_string "true")
395 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
396 (and (match_operand 0 "memory_displacement_operand" "")
397 (match_operand 2 "immediate_operand" "")))
398 (const_string "true")
399 ]
400 (const_string "false")))
401
402 ;; Indicates if an FP operation has an integer source.
403
404 (define_attr "fp_int_src" "false,true"
405 (const_string "false"))
406
407 ;; Describe a user's asm statement.
408 (define_asm_attributes
409 [(set_attr "length" "128")
410 (set_attr "type" "multi")])
411 \f
412 (include "pentium.md")
413 (include "ppro.md")
414 (include "k6.md")
415 (include "athlon.md")
416 \f
417 ;; Compare instructions.
418
419 ;; All compare insns have expanders that save the operands away without
420 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
421 ;; after the cmp) will actually emit the cmpM.
422
423 (define_expand "cmpdi"
424 [(set (reg:CC 17)
425 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
426 (match_operand:DI 1 "x86_64_general_operand" "")))]
427 ""
428 {
429 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
430 operands[0] = force_reg (DImode, operands[0]);
431 ix86_compare_op0 = operands[0];
432 ix86_compare_op1 = operands[1];
433 DONE;
434 })
435
436 (define_expand "cmpsi"
437 [(set (reg:CC 17)
438 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
439 (match_operand:SI 1 "general_operand" "")))]
440 ""
441 {
442 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
443 operands[0] = force_reg (SImode, operands[0]);
444 ix86_compare_op0 = operands[0];
445 ix86_compare_op1 = operands[1];
446 DONE;
447 })
448
449 (define_expand "cmphi"
450 [(set (reg:CC 17)
451 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
452 (match_operand:HI 1 "general_operand" "")))]
453 ""
454 {
455 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
456 operands[0] = force_reg (HImode, operands[0]);
457 ix86_compare_op0 = operands[0];
458 ix86_compare_op1 = operands[1];
459 DONE;
460 })
461
462 (define_expand "cmpqi"
463 [(set (reg:CC 17)
464 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
465 (match_operand:QI 1 "general_operand" "")))]
466 "TARGET_QIMODE_MATH"
467 {
468 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
469 operands[0] = force_reg (QImode, operands[0]);
470 ix86_compare_op0 = operands[0];
471 ix86_compare_op1 = operands[1];
472 DONE;
473 })
474
475 (define_insn "cmpdi_ccno_1_rex64"
476 [(set (reg 17)
477 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
478 (match_operand:DI 1 "const0_operand" "n,n")))]
479 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
480 "@
481 test{q}\t{%0, %0|%0, %0}
482 cmp{q}\t{%1, %0|%0, %1}"
483 [(set_attr "type" "test,icmp")
484 (set_attr "length_immediate" "0,1")
485 (set_attr "mode" "DI")])
486
487 (define_insn "*cmpdi_minus_1_rex64"
488 [(set (reg 17)
489 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
490 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
491 (const_int 0)))]
492 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
493 "cmp{q}\t{%1, %0|%0, %1}"
494 [(set_attr "type" "icmp")
495 (set_attr "mode" "DI")])
496
497 (define_expand "cmpdi_1_rex64"
498 [(set (reg:CC 17)
499 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
500 (match_operand:DI 1 "general_operand" "")))]
501 "TARGET_64BIT"
502 "")
503
504 (define_insn "cmpdi_1_insn_rex64"
505 [(set (reg 17)
506 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
507 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
508 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
509 "cmp{q}\t{%1, %0|%0, %1}"
510 [(set_attr "type" "icmp")
511 (set_attr "mode" "DI")])
512
513
514 (define_insn "*cmpsi_ccno_1"
515 [(set (reg 17)
516 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
517 (match_operand:SI 1 "const0_operand" "n,n")))]
518 "ix86_match_ccmode (insn, CCNOmode)"
519 "@
520 test{l}\t{%0, %0|%0, %0}
521 cmp{l}\t{%1, %0|%0, %1}"
522 [(set_attr "type" "test,icmp")
523 (set_attr "length_immediate" "0,1")
524 (set_attr "mode" "SI")])
525
526 (define_insn "*cmpsi_minus_1"
527 [(set (reg 17)
528 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
529 (match_operand:SI 1 "general_operand" "ri,mr"))
530 (const_int 0)))]
531 "ix86_match_ccmode (insn, CCGOCmode)"
532 "cmp{l}\t{%1, %0|%0, %1}"
533 [(set_attr "type" "icmp")
534 (set_attr "mode" "SI")])
535
536 (define_expand "cmpsi_1"
537 [(set (reg:CC 17)
538 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
539 (match_operand:SI 1 "general_operand" "ri,mr")))]
540 ""
541 "")
542
543 (define_insn "*cmpsi_1_insn"
544 [(set (reg 17)
545 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
546 (match_operand:SI 1 "general_operand" "ri,mr")))]
547 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
548 && ix86_match_ccmode (insn, CCmode)"
549 "cmp{l}\t{%1, %0|%0, %1}"
550 [(set_attr "type" "icmp")
551 (set_attr "mode" "SI")])
552
553 (define_insn "*cmphi_ccno_1"
554 [(set (reg 17)
555 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
556 (match_operand:HI 1 "const0_operand" "n,n")))]
557 "ix86_match_ccmode (insn, CCNOmode)"
558 "@
559 test{w}\t{%0, %0|%0, %0}
560 cmp{w}\t{%1, %0|%0, %1}"
561 [(set_attr "type" "test,icmp")
562 (set_attr "length_immediate" "0,1")
563 (set_attr "mode" "HI")])
564
565 (define_insn "*cmphi_minus_1"
566 [(set (reg 17)
567 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
568 (match_operand:HI 1 "general_operand" "ri,mr"))
569 (const_int 0)))]
570 "ix86_match_ccmode (insn, CCGOCmode)"
571 "cmp{w}\t{%1, %0|%0, %1}"
572 [(set_attr "type" "icmp")
573 (set_attr "mode" "HI")])
574
575 (define_insn "*cmphi_1"
576 [(set (reg 17)
577 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
578 (match_operand:HI 1 "general_operand" "ri,mr")))]
579 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
580 && ix86_match_ccmode (insn, CCmode)"
581 "cmp{w}\t{%1, %0|%0, %1}"
582 [(set_attr "type" "icmp")
583 (set_attr "mode" "HI")])
584
585 (define_insn "*cmpqi_ccno_1"
586 [(set (reg 17)
587 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
588 (match_operand:QI 1 "const0_operand" "n,n")))]
589 "ix86_match_ccmode (insn, CCNOmode)"
590 "@
591 test{b}\t{%0, %0|%0, %0}
592 cmp{b}\t{$0, %0|%0, 0}"
593 [(set_attr "type" "test,icmp")
594 (set_attr "length_immediate" "0,1")
595 (set_attr "mode" "QI")])
596
597 (define_insn "*cmpqi_1"
598 [(set (reg 17)
599 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
600 (match_operand:QI 1 "general_operand" "qi,mq")))]
601 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
602 && ix86_match_ccmode (insn, CCmode)"
603 "cmp{b}\t{%1, %0|%0, %1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "QI")])
606
607 (define_insn "*cmpqi_minus_1"
608 [(set (reg 17)
609 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
610 (match_operand:QI 1 "general_operand" "qi,mq"))
611 (const_int 0)))]
612 "ix86_match_ccmode (insn, CCGOCmode)"
613 "cmp{b}\t{%1, %0|%0, %1}"
614 [(set_attr "type" "icmp")
615 (set_attr "mode" "QI")])
616
617 (define_insn "*cmpqi_ext_1"
618 [(set (reg 17)
619 (compare
620 (match_operand:QI 0 "general_operand" "Qm")
621 (subreg:QI
622 (zero_extract:SI
623 (match_operand 1 "ext_register_operand" "Q")
624 (const_int 8)
625 (const_int 8)) 0)))]
626 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
627 "cmp{b}\t{%h1, %0|%0, %h1}"
628 [(set_attr "type" "icmp")
629 (set_attr "mode" "QI")])
630
631 (define_insn "*cmpqi_ext_1_rex64"
632 [(set (reg 17)
633 (compare
634 (match_operand:QI 0 "register_operand" "Q")
635 (subreg:QI
636 (zero_extract:SI
637 (match_operand 1 "ext_register_operand" "Q")
638 (const_int 8)
639 (const_int 8)) 0)))]
640 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
641 "cmp{b}\t{%h1, %0|%0, %h1}"
642 [(set_attr "type" "icmp")
643 (set_attr "mode" "QI")])
644
645 (define_insn "*cmpqi_ext_2"
646 [(set (reg 17)
647 (compare
648 (subreg:QI
649 (zero_extract:SI
650 (match_operand 0 "ext_register_operand" "Q")
651 (const_int 8)
652 (const_int 8)) 0)
653 (match_operand:QI 1 "const0_operand" "n")))]
654 "ix86_match_ccmode (insn, CCNOmode)"
655 "test{b}\t%h0, %h0"
656 [(set_attr "type" "test")
657 (set_attr "length_immediate" "0")
658 (set_attr "mode" "QI")])
659
660 (define_expand "cmpqi_ext_3"
661 [(set (reg:CC 17)
662 (compare:CC
663 (subreg:QI
664 (zero_extract:SI
665 (match_operand 0 "ext_register_operand" "")
666 (const_int 8)
667 (const_int 8)) 0)
668 (match_operand:QI 1 "general_operand" "")))]
669 ""
670 "")
671
672 (define_insn "cmpqi_ext_3_insn"
673 [(set (reg 17)
674 (compare
675 (subreg:QI
676 (zero_extract:SI
677 (match_operand 0 "ext_register_operand" "Q")
678 (const_int 8)
679 (const_int 8)) 0)
680 (match_operand:QI 1 "general_operand" "Qmn")))]
681 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
682 "cmp{b}\t{%1, %h0|%h0, %1}"
683 [(set_attr "type" "icmp")
684 (set_attr "mode" "QI")])
685
686 (define_insn "cmpqi_ext_3_insn_rex64"
687 [(set (reg 17)
688 (compare
689 (subreg:QI
690 (zero_extract:SI
691 (match_operand 0 "ext_register_operand" "Q")
692 (const_int 8)
693 (const_int 8)) 0)
694 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
695 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
696 "cmp{b}\t{%1, %h0|%h0, %1}"
697 [(set_attr "type" "icmp")
698 (set_attr "mode" "QI")])
699
700 (define_insn "*cmpqi_ext_4"
701 [(set (reg 17)
702 (compare
703 (subreg:QI
704 (zero_extract:SI
705 (match_operand 0 "ext_register_operand" "Q")
706 (const_int 8)
707 (const_int 8)) 0)
708 (subreg:QI
709 (zero_extract:SI
710 (match_operand 1 "ext_register_operand" "Q")
711 (const_int 8)
712 (const_int 8)) 0)))]
713 "ix86_match_ccmode (insn, CCmode)"
714 "cmp{b}\t{%h1, %h0|%h0, %h1}"
715 [(set_attr "type" "icmp")
716 (set_attr "mode" "QI")])
717
718 ;; These implement float point compares.
719 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
720 ;; which would allow mix and match FP modes on the compares. Which is what
721 ;; the old patterns did, but with many more of them.
722
723 (define_expand "cmpxf"
724 [(set (reg:CC 17)
725 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
726 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
727 "TARGET_80387"
728 {
729 ix86_compare_op0 = operands[0];
730 ix86_compare_op1 = operands[1];
731 DONE;
732 })
733
734 (define_expand "cmpdf"
735 [(set (reg:CC 17)
736 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
737 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
738 "TARGET_80387 || TARGET_SSE2"
739 {
740 ix86_compare_op0 = operands[0];
741 ix86_compare_op1 = operands[1];
742 DONE;
743 })
744
745 (define_expand "cmpsf"
746 [(set (reg:CC 17)
747 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
748 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
749 "TARGET_80387 || TARGET_SSE"
750 {
751 ix86_compare_op0 = operands[0];
752 ix86_compare_op1 = operands[1];
753 DONE;
754 })
755
756 ;; FP compares, step 1:
757 ;; Set the FP condition codes.
758 ;;
759 ;; CCFPmode compare with exceptions
760 ;; CCFPUmode compare with no exceptions
761
762 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
763 ;; and that fp moves clobber the condition codes, and that there is
764 ;; currently no way to describe this fact to reg-stack. So there are
765 ;; no splitters yet for this.
766
767 ;; %%% YIKES! This scheme does not retain a strong connection between
768 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
769 ;; work! Only allow tos/mem with tos in op 0.
770 ;;
771 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
772 ;; things aren't as bad as they sound...
773
774 (define_insn "*cmpfp_0"
775 [(set (match_operand:HI 0 "register_operand" "=a")
776 (unspec:HI
777 [(compare:CCFP (match_operand 1 "register_operand" "f")
778 (match_operand 2 "const0_operand" "X"))]
779 UNSPEC_FNSTSW))]
780 "TARGET_80387
781 && FLOAT_MODE_P (GET_MODE (operands[1]))
782 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
783 {
784 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
785 return "ftst\;fnstsw\t%0\;fstp\t%y0";
786 else
787 return "ftst\;fnstsw\t%0";
788 }
789 [(set_attr "type" "multi")
790 (set (attr "mode")
791 (cond [(match_operand:SF 1 "" "")
792 (const_string "SF")
793 (match_operand:DF 1 "" "")
794 (const_string "DF")
795 ]
796 (const_string "XF")))])
797
798 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
799 ;; used to manage the reg stack popping would not be preserved.
800
801 (define_insn "*cmpfp_2_sf"
802 [(set (reg:CCFP 18)
803 (compare:CCFP
804 (match_operand:SF 0 "register_operand" "f")
805 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
806 "TARGET_80387"
807 "* return output_fp_compare (insn, operands, 0, 0);"
808 [(set_attr "type" "fcmp")
809 (set_attr "mode" "SF")])
810
811 (define_insn "*cmpfp_2_sf_1"
812 [(set (match_operand:HI 0 "register_operand" "=a")
813 (unspec:HI
814 [(compare:CCFP
815 (match_operand:SF 1 "register_operand" "f")
816 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
817 UNSPEC_FNSTSW))]
818 "TARGET_80387"
819 "* return output_fp_compare (insn, operands, 2, 0);"
820 [(set_attr "type" "fcmp")
821 (set_attr "mode" "SF")])
822
823 (define_insn "*cmpfp_2_df"
824 [(set (reg:CCFP 18)
825 (compare:CCFP
826 (match_operand:DF 0 "register_operand" "f")
827 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
828 "TARGET_80387"
829 "* return output_fp_compare (insn, operands, 0, 0);"
830 [(set_attr "type" "fcmp")
831 (set_attr "mode" "DF")])
832
833 (define_insn "*cmpfp_2_df_1"
834 [(set (match_operand:HI 0 "register_operand" "=a")
835 (unspec:HI
836 [(compare:CCFP
837 (match_operand:DF 1 "register_operand" "f")
838 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
839 UNSPEC_FNSTSW))]
840 "TARGET_80387"
841 "* return output_fp_compare (insn, operands, 2, 0);"
842 [(set_attr "type" "multi")
843 (set_attr "mode" "DF")])
844
845 (define_insn "*cmpfp_2_xf"
846 [(set (reg:CCFP 18)
847 (compare:CCFP
848 (match_operand:XF 0 "register_operand" "f")
849 (match_operand:XF 1 "register_operand" "f")))]
850 "TARGET_80387"
851 "* return output_fp_compare (insn, operands, 0, 0);"
852 [(set_attr "type" "fcmp")
853 (set_attr "mode" "XF")])
854
855 (define_insn "*cmpfp_2_xf_1"
856 [(set (match_operand:HI 0 "register_operand" "=a")
857 (unspec:HI
858 [(compare:CCFP
859 (match_operand:XF 1 "register_operand" "f")
860 (match_operand:XF 2 "register_operand" "f"))]
861 UNSPEC_FNSTSW))]
862 "TARGET_80387"
863 "* return output_fp_compare (insn, operands, 2, 0);"
864 [(set_attr "type" "multi")
865 (set_attr "mode" "XF")])
866
867 (define_insn "*cmpfp_2u"
868 [(set (reg:CCFPU 18)
869 (compare:CCFPU
870 (match_operand 0 "register_operand" "f")
871 (match_operand 1 "register_operand" "f")))]
872 "TARGET_80387
873 && FLOAT_MODE_P (GET_MODE (operands[0]))
874 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
875 "* return output_fp_compare (insn, operands, 0, 1);"
876 [(set_attr "type" "fcmp")
877 (set (attr "mode")
878 (cond [(match_operand:SF 1 "" "")
879 (const_string "SF")
880 (match_operand:DF 1 "" "")
881 (const_string "DF")
882 ]
883 (const_string "XF")))])
884
885 (define_insn "*cmpfp_2u_1"
886 [(set (match_operand:HI 0 "register_operand" "=a")
887 (unspec:HI
888 [(compare:CCFPU
889 (match_operand 1 "register_operand" "f")
890 (match_operand 2 "register_operand" "f"))]
891 UNSPEC_FNSTSW))]
892 "TARGET_80387
893 && FLOAT_MODE_P (GET_MODE (operands[1]))
894 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
895 "* return output_fp_compare (insn, operands, 2, 1);"
896 [(set_attr "type" "multi")
897 (set (attr "mode")
898 (cond [(match_operand:SF 1 "" "")
899 (const_string "SF")
900 (match_operand:DF 1 "" "")
901 (const_string "DF")
902 ]
903 (const_string "XF")))])
904
905 ;; Patterns to match the SImode-in-memory ficom instructions.
906 ;;
907 ;; %%% Play games with accepting gp registers, as otherwise we have to
908 ;; force them to memory during rtl generation, which is no good. We
909 ;; can get rid of this once we teach reload to do memory input reloads
910 ;; via pushes.
911
912 (define_insn "*ficom_1"
913 [(set (reg:CCFP 18)
914 (compare:CCFP
915 (match_operand 0 "register_operand" "f,f")
916 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
917 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
918 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
919 "#")
920
921 ;; Split the not-really-implemented gp register case into a
922 ;; push-op-pop sequence.
923 ;;
924 ;; %%% This is most efficient, but am I gonna get in trouble
925 ;; for separating cc0_setter and cc0_user?
926
927 (define_split
928 [(set (reg:CCFP 18)
929 (compare:CCFP
930 (match_operand:SF 0 "register_operand" "")
931 (float (match_operand:SI 1 "register_operand" ""))))]
932 "0 && TARGET_80387 && reload_completed"
933 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
934 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
935 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
936 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
937 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
938 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
939
940 ;; FP compares, step 2
941 ;; Move the fpsw to ax.
942
943 (define_insn "*x86_fnstsw_1"
944 [(set (match_operand:HI 0 "register_operand" "=a")
945 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
946 "TARGET_80387"
947 "fnstsw\t%0"
948 [(set_attr "length" "2")
949 (set_attr "mode" "SI")
950 (set_attr "unit" "i387")])
951
952 ;; FP compares, step 3
953 ;; Get ax into flags, general case.
954
955 (define_insn "x86_sahf_1"
956 [(set (reg:CC 17)
957 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
958 "!TARGET_64BIT"
959 "sahf"
960 [(set_attr "length" "1")
961 (set_attr "athlon_decode" "vector")
962 (set_attr "mode" "SI")])
963
964 ;; Pentium Pro can do steps 1 through 3 in one go.
965
966 (define_insn "*cmpfp_i"
967 [(set (reg:CCFP 17)
968 (compare:CCFP (match_operand 0 "register_operand" "f")
969 (match_operand 1 "register_operand" "f")))]
970 "TARGET_80387 && TARGET_CMOVE
971 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
972 && FLOAT_MODE_P (GET_MODE (operands[0]))
973 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
974 "* return output_fp_compare (insn, operands, 1, 0);"
975 [(set_attr "type" "fcmp")
976 (set (attr "mode")
977 (cond [(match_operand:SF 1 "" "")
978 (const_string "SF")
979 (match_operand:DF 1 "" "")
980 (const_string "DF")
981 ]
982 (const_string "XF")))
983 (set_attr "athlon_decode" "vector")])
984
985 (define_insn "*cmpfp_i_sse"
986 [(set (reg:CCFP 17)
987 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
988 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
989 "TARGET_80387
990 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
992 "* return output_fp_compare (insn, operands, 1, 0);"
993 [(set_attr "type" "fcmp,ssecomi")
994 (set (attr "mode")
995 (if_then_else (match_operand:SF 1 "" "")
996 (const_string "SF")
997 (const_string "DF")))
998 (set_attr "athlon_decode" "vector")])
999
1000 (define_insn "*cmpfp_i_sse_only"
1001 [(set (reg:CCFP 17)
1002 (compare:CCFP (match_operand 0 "register_operand" "x")
1003 (match_operand 1 "nonimmediate_operand" "xm")))]
1004 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "ssecomi")
1008 (set (attr "mode")
1009 (if_then_else (match_operand:SF 1 "" "")
1010 (const_string "SF")
1011 (const_string "DF")))
1012 (set_attr "athlon_decode" "vector")])
1013
1014 (define_insn "*cmpfp_iu"
1015 [(set (reg:CCFPU 17)
1016 (compare:CCFPU (match_operand 0 "register_operand" "f")
1017 (match_operand 1 "register_operand" "f")))]
1018 "TARGET_80387 && TARGET_CMOVE
1019 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1020 && FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 1);"
1023 [(set_attr "type" "fcmp")
1024 (set (attr "mode")
1025 (cond [(match_operand:SF 1 "" "")
1026 (const_string "SF")
1027 (match_operand:DF 1 "" "")
1028 (const_string "DF")
1029 ]
1030 (const_string "XF")))
1031 (set_attr "athlon_decode" "vector")])
1032
1033 (define_insn "*cmpfp_iu_sse"
1034 [(set (reg:CCFPU 17)
1035 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1036 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1037 "TARGET_80387
1038 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "fcmp,ssecomi")
1042 (set (attr "mode")
1043 (if_then_else (match_operand:SF 1 "" "")
1044 (const_string "SF")
1045 (const_string "DF")))
1046 (set_attr "athlon_decode" "vector")])
1047
1048 (define_insn "*cmpfp_iu_sse_only"
1049 [(set (reg:CCFPU 17)
1050 (compare:CCFPU (match_operand 0 "register_operand" "x")
1051 (match_operand 1 "nonimmediate_operand" "xm")))]
1052 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1053 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1054 "* return output_fp_compare (insn, operands, 1, 1);"
1055 [(set_attr "type" "ssecomi")
1056 (set (attr "mode")
1057 (if_then_else (match_operand:SF 1 "" "")
1058 (const_string "SF")
1059 (const_string "DF")))
1060 (set_attr "athlon_decode" "vector")])
1061 \f
1062 ;; Move instructions.
1063
1064 ;; General case of fullword move.
1065
1066 (define_expand "movsi"
1067 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1068 (match_operand:SI 1 "general_operand" ""))]
1069 ""
1070 "ix86_expand_move (SImode, operands); DONE;")
1071
1072 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1073 ;; general_operand.
1074 ;;
1075 ;; %%% We don't use a post-inc memory reference because x86 is not a
1076 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1077 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1078 ;; targets without our curiosities, and it is just as easy to represent
1079 ;; this differently.
1080
1081 (define_insn "*pushsi2"
1082 [(set (match_operand:SI 0 "push_operand" "=<")
1083 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1084 "!TARGET_64BIT"
1085 "push{l}\t%1"
1086 [(set_attr "type" "push")
1087 (set_attr "mode" "SI")])
1088
1089 ;; For 64BIT abi we always round up to 8 bytes.
1090 (define_insn "*pushsi2_rex64"
1091 [(set (match_operand:SI 0 "push_operand" "=X")
1092 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1093 "TARGET_64BIT"
1094 "push{q}\t%q1"
1095 [(set_attr "type" "push")
1096 (set_attr "mode" "SI")])
1097
1098 (define_insn "*pushsi2_prologue"
1099 [(set (match_operand:SI 0 "push_operand" "=<")
1100 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1101 (clobber (mem:BLK (scratch)))]
1102 "!TARGET_64BIT"
1103 "push{l}\t%1"
1104 [(set_attr "type" "push")
1105 (set_attr "mode" "SI")])
1106
1107 (define_insn "*popsi1_epilogue"
1108 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1109 (mem:SI (reg:SI 7)))
1110 (set (reg:SI 7)
1111 (plus:SI (reg:SI 7) (const_int 4)))
1112 (clobber (mem:BLK (scratch)))]
1113 "!TARGET_64BIT"
1114 "pop{l}\t%0"
1115 [(set_attr "type" "pop")
1116 (set_attr "mode" "SI")])
1117
1118 (define_insn "popsi1"
1119 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1120 (mem:SI (reg:SI 7)))
1121 (set (reg:SI 7)
1122 (plus:SI (reg:SI 7) (const_int 4)))]
1123 "!TARGET_64BIT"
1124 "pop{l}\t%0"
1125 [(set_attr "type" "pop")
1126 (set_attr "mode" "SI")])
1127
1128 (define_insn "*movsi_xor"
1129 [(set (match_operand:SI 0 "register_operand" "=r")
1130 (match_operand:SI 1 "const0_operand" "i"))
1131 (clobber (reg:CC 17))]
1132 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1133 "xor{l}\t{%0, %0|%0, %0}"
1134 [(set_attr "type" "alu1")
1135 (set_attr "mode" "SI")
1136 (set_attr "length_immediate" "0")])
1137
1138 (define_insn "*movsi_or"
1139 [(set (match_operand:SI 0 "register_operand" "=r")
1140 (match_operand:SI 1 "immediate_operand" "i"))
1141 (clobber (reg:CC 17))]
1142 "reload_completed
1143 && operands[1] == constm1_rtx
1144 && (TARGET_PENTIUM || optimize_size)"
1145 {
1146 operands[1] = constm1_rtx;
1147 return "or{l}\t{%1, %0|%0, %1}";
1148 }
1149 [(set_attr "type" "alu1")
1150 (set_attr "mode" "SI")
1151 (set_attr "length_immediate" "1")])
1152
1153 (define_insn "*movsi_1"
1154 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1155 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1156 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1157 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1158 {
1159 switch (get_attr_type (insn))
1160 {
1161 case TYPE_SSEMOV:
1162 if (get_attr_mode (insn) == MODE_TI)
1163 return "movdqa\t{%1, %0|%0, %1}";
1164 return "movd\t{%1, %0|%0, %1}";
1165
1166 case TYPE_MMXMOV:
1167 if (get_attr_mode (insn) == MODE_DI)
1168 return "movq\t{%1, %0|%0, %1}";
1169 return "movd\t{%1, %0|%0, %1}";
1170
1171 case TYPE_LEA:
1172 return "lea{l}\t{%1, %0|%0, %1}";
1173
1174 default:
1175 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1176 abort();
1177 return "mov{l}\t{%1, %0|%0, %1}";
1178 }
1179 }
1180 [(set (attr "type")
1181 (cond [(eq_attr "alternative" "2,3,4")
1182 (const_string "mmxmov")
1183 (eq_attr "alternative" "5,6,7")
1184 (const_string "ssemov")
1185 (and (ne (symbol_ref "flag_pic") (const_int 0))
1186 (match_operand:SI 1 "symbolic_operand" ""))
1187 (const_string "lea")
1188 ]
1189 (const_string "imov")))
1190 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1191
1192 (define_insn "*movsi_1_nointernunit"
1193 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1194 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1195 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1196 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1197 {
1198 switch (get_attr_type (insn))
1199 {
1200 case TYPE_SSEMOV:
1201 if (get_attr_mode (insn) == MODE_TI)
1202 return "movdqa\t{%1, %0|%0, %1}";
1203 return "movd\t{%1, %0|%0, %1}";
1204
1205 case TYPE_MMXMOV:
1206 if (get_attr_mode (insn) == MODE_DI)
1207 return "movq\t{%1, %0|%0, %1}";
1208 return "movd\t{%1, %0|%0, %1}";
1209
1210 case TYPE_LEA:
1211 return "lea{l}\t{%1, %0|%0, %1}";
1212
1213 default:
1214 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1215 abort();
1216 return "mov{l}\t{%1, %0|%0, %1}";
1217 }
1218 }
1219 [(set (attr "type")
1220 (cond [(eq_attr "alternative" "2,3,4")
1221 (const_string "mmxmov")
1222 (eq_attr "alternative" "5,6,7")
1223 (const_string "ssemov")
1224 (and (ne (symbol_ref "flag_pic") (const_int 0))
1225 (match_operand:SI 1 "symbolic_operand" ""))
1226 (const_string "lea")
1227 ]
1228 (const_string "imov")))
1229 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1230
1231 ;; Stores and loads of ax to arbitrary constant address.
1232 ;; We fake an second form of instruction to force reload to load address
1233 ;; into register when rax is not available
1234 (define_insn "*movabssi_1_rex64"
1235 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1236 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1237 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1238 "@
1239 movabs{l}\t{%1, %P0|%P0, %1}
1240 mov{l}\t{%1, %a0|%a0, %1}"
1241 [(set_attr "type" "imov")
1242 (set_attr "modrm" "0,*")
1243 (set_attr "length_address" "8,0")
1244 (set_attr "length_immediate" "0,*")
1245 (set_attr "memory" "store")
1246 (set_attr "mode" "SI")])
1247
1248 (define_insn "*movabssi_2_rex64"
1249 [(set (match_operand:SI 0 "register_operand" "=a,r")
1250 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1251 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1252 "@
1253 movabs{l}\t{%P1, %0|%0, %P1}
1254 mov{l}\t{%a1, %0|%0, %a1}"
1255 [(set_attr "type" "imov")
1256 (set_attr "modrm" "0,*")
1257 (set_attr "length_address" "8,0")
1258 (set_attr "length_immediate" "0")
1259 (set_attr "memory" "load")
1260 (set_attr "mode" "SI")])
1261
1262 (define_insn "*swapsi"
1263 [(set (match_operand:SI 0 "register_operand" "+r")
1264 (match_operand:SI 1 "register_operand" "+r"))
1265 (set (match_dup 1)
1266 (match_dup 0))]
1267 ""
1268 "xchg{l}\t%1, %0"
1269 [(set_attr "type" "imov")
1270 (set_attr "pent_pair" "np")
1271 (set_attr "athlon_decode" "vector")
1272 (set_attr "mode" "SI")
1273 (set_attr "modrm" "0")])
1274
1275 (define_expand "movhi"
1276 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1277 (match_operand:HI 1 "general_operand" ""))]
1278 ""
1279 "ix86_expand_move (HImode, operands); DONE;")
1280
1281 (define_insn "*pushhi2"
1282 [(set (match_operand:HI 0 "push_operand" "=<,<")
1283 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1284 "!TARGET_64BIT"
1285 "@
1286 push{w}\t{|WORD PTR }%1
1287 push{w}\t%1"
1288 [(set_attr "type" "push")
1289 (set_attr "mode" "HI")])
1290
1291 ;; For 64BIT abi we always round up to 8 bytes.
1292 (define_insn "*pushhi2_rex64"
1293 [(set (match_operand:HI 0 "push_operand" "=X")
1294 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1295 "TARGET_64BIT"
1296 "push{q}\t%q1"
1297 [(set_attr "type" "push")
1298 (set_attr "mode" "QI")])
1299
1300 (define_insn "*movhi_1"
1301 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1302 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1303 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1304 {
1305 switch (get_attr_type (insn))
1306 {
1307 case TYPE_IMOVX:
1308 /* movzwl is faster than movw on p2 due to partial word stalls,
1309 though not as fast as an aligned movl. */
1310 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1311 default:
1312 if (get_attr_mode (insn) == MODE_SI)
1313 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1314 else
1315 return "mov{w}\t{%1, %0|%0, %1}";
1316 }
1317 }
1318 [(set (attr "type")
1319 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1320 (const_string "imov")
1321 (and (eq_attr "alternative" "0")
1322 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1323 (const_int 0))
1324 (eq (symbol_ref "TARGET_HIMODE_MATH")
1325 (const_int 0))))
1326 (const_string "imov")
1327 (and (eq_attr "alternative" "1,2")
1328 (match_operand:HI 1 "aligned_operand" ""))
1329 (const_string "imov")
1330 (and (ne (symbol_ref "TARGET_MOVX")
1331 (const_int 0))
1332 (eq_attr "alternative" "0,2"))
1333 (const_string "imovx")
1334 ]
1335 (const_string "imov")))
1336 (set (attr "mode")
1337 (cond [(eq_attr "type" "imovx")
1338 (const_string "SI")
1339 (and (eq_attr "alternative" "1,2")
1340 (match_operand:HI 1 "aligned_operand" ""))
1341 (const_string "SI")
1342 (and (eq_attr "alternative" "0")
1343 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1344 (const_int 0))
1345 (eq (symbol_ref "TARGET_HIMODE_MATH")
1346 (const_int 0))))
1347 (const_string "SI")
1348 ]
1349 (const_string "HI")))])
1350
1351 ;; Stores and loads of ax to arbitrary constant address.
1352 ;; We fake an second form of instruction to force reload to load address
1353 ;; into register when rax is not available
1354 (define_insn "*movabshi_1_rex64"
1355 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1356 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1357 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1358 "@
1359 movabs{w}\t{%1, %P0|%P0, %1}
1360 mov{w}\t{%1, %a0|%a0, %1}"
1361 [(set_attr "type" "imov")
1362 (set_attr "modrm" "0,*")
1363 (set_attr "length_address" "8,0")
1364 (set_attr "length_immediate" "0,*")
1365 (set_attr "memory" "store")
1366 (set_attr "mode" "HI")])
1367
1368 (define_insn "*movabshi_2_rex64"
1369 [(set (match_operand:HI 0 "register_operand" "=a,r")
1370 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1371 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1372 "@
1373 movabs{w}\t{%P1, %0|%0, %P1}
1374 mov{w}\t{%a1, %0|%0, %a1}"
1375 [(set_attr "type" "imov")
1376 (set_attr "modrm" "0,*")
1377 (set_attr "length_address" "8,0")
1378 (set_attr "length_immediate" "0")
1379 (set_attr "memory" "load")
1380 (set_attr "mode" "HI")])
1381
1382 (define_insn "*swaphi_1"
1383 [(set (match_operand:HI 0 "register_operand" "+r")
1384 (match_operand:HI 1 "register_operand" "+r"))
1385 (set (match_dup 1)
1386 (match_dup 0))]
1387 "TARGET_PARTIAL_REG_STALL"
1388 "xchg{w}\t%1, %0"
1389 [(set_attr "type" "imov")
1390 (set_attr "pent_pair" "np")
1391 (set_attr "mode" "HI")
1392 (set_attr "modrm" "0")])
1393
1394 (define_insn "*swaphi_2"
1395 [(set (match_operand:HI 0 "register_operand" "+r")
1396 (match_operand:HI 1 "register_operand" "+r"))
1397 (set (match_dup 1)
1398 (match_dup 0))]
1399 "! TARGET_PARTIAL_REG_STALL"
1400 "xchg{l}\t%k1, %k0"
1401 [(set_attr "type" "imov")
1402 (set_attr "pent_pair" "np")
1403 (set_attr "mode" "SI")
1404 (set_attr "modrm" "0")])
1405
1406 (define_expand "movstricthi"
1407 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1408 (match_operand:HI 1 "general_operand" ""))]
1409 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1410 {
1411 /* Don't generate memory->memory moves, go through a register */
1412 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1413 operands[1] = force_reg (HImode, operands[1]);
1414 })
1415
1416 (define_insn "*movstricthi_1"
1417 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1418 (match_operand:HI 1 "general_operand" "rn,m"))]
1419 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1420 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1421 "mov{w}\t{%1, %0|%0, %1}"
1422 [(set_attr "type" "imov")
1423 (set_attr "mode" "HI")])
1424
1425 (define_insn "*movstricthi_xor"
1426 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1427 (match_operand:HI 1 "const0_operand" "i"))
1428 (clobber (reg:CC 17))]
1429 "reload_completed
1430 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1431 "xor{w}\t{%0, %0|%0, %0}"
1432 [(set_attr "type" "alu1")
1433 (set_attr "mode" "HI")
1434 (set_attr "length_immediate" "0")])
1435
1436 (define_expand "movqi"
1437 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1438 (match_operand:QI 1 "general_operand" ""))]
1439 ""
1440 "ix86_expand_move (QImode, operands); DONE;")
1441
1442 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1443 ;; "push a byte". But actually we use pushw, which has the effect
1444 ;; of rounding the amount pushed up to a halfword.
1445
1446 (define_insn "*pushqi2"
1447 [(set (match_operand:QI 0 "push_operand" "=X,X")
1448 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1449 "!TARGET_64BIT"
1450 "@
1451 push{w}\t{|word ptr }%1
1452 push{w}\t%w1"
1453 [(set_attr "type" "push")
1454 (set_attr "mode" "HI")])
1455
1456 ;; For 64BIT abi we always round up to 8 bytes.
1457 (define_insn "*pushqi2_rex64"
1458 [(set (match_operand:QI 0 "push_operand" "=X")
1459 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1460 "TARGET_64BIT"
1461 "push{q}\t%q1"
1462 [(set_attr "type" "push")
1463 (set_attr "mode" "QI")])
1464
1465 ;; Situation is quite tricky about when to choose full sized (SImode) move
1466 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1467 ;; partial register dependency machines (such as AMD Athlon), where QImode
1468 ;; moves issue extra dependency and for partial register stalls machines
1469 ;; that don't use QImode patterns (and QImode move cause stall on the next
1470 ;; instruction).
1471 ;;
1472 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1473 ;; register stall machines with, where we use QImode instructions, since
1474 ;; partial register stall can be caused there. Then we use movzx.
1475 (define_insn "*movqi_1"
1476 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1477 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1478 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1479 {
1480 switch (get_attr_type (insn))
1481 {
1482 case TYPE_IMOVX:
1483 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1484 abort ();
1485 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1486 default:
1487 if (get_attr_mode (insn) == MODE_SI)
1488 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1489 else
1490 return "mov{b}\t{%1, %0|%0, %1}";
1491 }
1492 }
1493 [(set (attr "type")
1494 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1495 (const_string "imov")
1496 (and (eq_attr "alternative" "3")
1497 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1498 (const_int 0))
1499 (eq (symbol_ref "TARGET_QIMODE_MATH")
1500 (const_int 0))))
1501 (const_string "imov")
1502 (eq_attr "alternative" "3,5")
1503 (const_string "imovx")
1504 (and (ne (symbol_ref "TARGET_MOVX")
1505 (const_int 0))
1506 (eq_attr "alternative" "2"))
1507 (const_string "imovx")
1508 ]
1509 (const_string "imov")))
1510 (set (attr "mode")
1511 (cond [(eq_attr "alternative" "3,4,5")
1512 (const_string "SI")
1513 (eq_attr "alternative" "6")
1514 (const_string "QI")
1515 (eq_attr "type" "imovx")
1516 (const_string "SI")
1517 (and (eq_attr "type" "imov")
1518 (and (eq_attr "alternative" "0,1,2")
1519 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1520 (const_int 0))))
1521 (const_string "SI")
1522 ;; Avoid partial register stalls when not using QImode arithmetic
1523 (and (eq_attr "type" "imov")
1524 (and (eq_attr "alternative" "0,1,2")
1525 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526 (const_int 0))
1527 (eq (symbol_ref "TARGET_QIMODE_MATH")
1528 (const_int 0)))))
1529 (const_string "SI")
1530 ]
1531 (const_string "QI")))])
1532
1533 (define_expand "reload_outqi"
1534 [(parallel [(match_operand:QI 0 "" "=m")
1535 (match_operand:QI 1 "register_operand" "r")
1536 (match_operand:QI 2 "register_operand" "=&q")])]
1537 ""
1538 {
1539 rtx op0, op1, op2;
1540 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1541
1542 if (reg_overlap_mentioned_p (op2, op0))
1543 abort ();
1544 if (! q_regs_operand (op1, QImode))
1545 {
1546 emit_insn (gen_movqi (op2, op1));
1547 op1 = op2;
1548 }
1549 emit_insn (gen_movqi (op0, op1));
1550 DONE;
1551 })
1552
1553 (define_insn "*swapqi"
1554 [(set (match_operand:QI 0 "register_operand" "+r")
1555 (match_operand:QI 1 "register_operand" "+r"))
1556 (set (match_dup 1)
1557 (match_dup 0))]
1558 ""
1559 "xchg{b}\t%1, %0"
1560 [(set_attr "type" "imov")
1561 (set_attr "pent_pair" "np")
1562 (set_attr "mode" "QI")
1563 (set_attr "modrm" "0")])
1564
1565 (define_expand "movstrictqi"
1566 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1567 (match_operand:QI 1 "general_operand" ""))]
1568 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1569 {
1570 /* Don't generate memory->memory moves, go through a register. */
1571 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1572 operands[1] = force_reg (QImode, operands[1]);
1573 })
1574
1575 (define_insn "*movstrictqi_1"
1576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1577 (match_operand:QI 1 "general_operand" "*qn,m"))]
1578 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1579 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1580 "mov{b}\t{%1, %0|%0, %1}"
1581 [(set_attr "type" "imov")
1582 (set_attr "mode" "QI")])
1583
1584 (define_insn "*movstrictqi_xor"
1585 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1586 (match_operand:QI 1 "const0_operand" "i"))
1587 (clobber (reg:CC 17))]
1588 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1589 "xor{b}\t{%0, %0|%0, %0}"
1590 [(set_attr "type" "alu1")
1591 (set_attr "mode" "QI")
1592 (set_attr "length_immediate" "0")])
1593
1594 (define_insn "*movsi_extv_1"
1595 [(set (match_operand:SI 0 "register_operand" "=R")
1596 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1597 (const_int 8)
1598 (const_int 8)))]
1599 ""
1600 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1601 [(set_attr "type" "imovx")
1602 (set_attr "mode" "SI")])
1603
1604 (define_insn "*movhi_extv_1"
1605 [(set (match_operand:HI 0 "register_operand" "=R")
1606 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1607 (const_int 8)
1608 (const_int 8)))]
1609 ""
1610 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1611 [(set_attr "type" "imovx")
1612 (set_attr "mode" "SI")])
1613
1614 (define_insn "*movqi_extv_1"
1615 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1616 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1617 (const_int 8)
1618 (const_int 8)))]
1619 "!TARGET_64BIT"
1620 {
1621 switch (get_attr_type (insn))
1622 {
1623 case TYPE_IMOVX:
1624 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1625 default:
1626 return "mov{b}\t{%h1, %0|%0, %h1}";
1627 }
1628 }
1629 [(set (attr "type")
1630 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1631 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1632 (ne (symbol_ref "TARGET_MOVX")
1633 (const_int 0))))
1634 (const_string "imovx")
1635 (const_string "imov")))
1636 (set (attr "mode")
1637 (if_then_else (eq_attr "type" "imovx")
1638 (const_string "SI")
1639 (const_string "QI")))])
1640
1641 (define_insn "*movqi_extv_1_rex64"
1642 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1643 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1644 (const_int 8)
1645 (const_int 8)))]
1646 "TARGET_64BIT"
1647 {
1648 switch (get_attr_type (insn))
1649 {
1650 case TYPE_IMOVX:
1651 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652 default:
1653 return "mov{b}\t{%h1, %0|%0, %h1}";
1654 }
1655 }
1656 [(set (attr "type")
1657 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1658 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1659 (ne (symbol_ref "TARGET_MOVX")
1660 (const_int 0))))
1661 (const_string "imovx")
1662 (const_string "imov")))
1663 (set (attr "mode")
1664 (if_then_else (eq_attr "type" "imovx")
1665 (const_string "SI")
1666 (const_string "QI")))])
1667
1668 ;; Stores and loads of ax to arbitrary constant address.
1669 ;; We fake an second form of instruction to force reload to load address
1670 ;; into register when rax is not available
1671 (define_insn "*movabsqi_1_rex64"
1672 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1673 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1674 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1675 "@
1676 movabs{b}\t{%1, %P0|%P0, %1}
1677 mov{b}\t{%1, %a0|%a0, %1}"
1678 [(set_attr "type" "imov")
1679 (set_attr "modrm" "0,*")
1680 (set_attr "length_address" "8,0")
1681 (set_attr "length_immediate" "0,*")
1682 (set_attr "memory" "store")
1683 (set_attr "mode" "QI")])
1684
1685 (define_insn "*movabsqi_2_rex64"
1686 [(set (match_operand:QI 0 "register_operand" "=a,r")
1687 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1688 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1689 "@
1690 movabs{b}\t{%P1, %0|%0, %P1}
1691 mov{b}\t{%a1, %0|%0, %a1}"
1692 [(set_attr "type" "imov")
1693 (set_attr "modrm" "0,*")
1694 (set_attr "length_address" "8,0")
1695 (set_attr "length_immediate" "0")
1696 (set_attr "memory" "load")
1697 (set_attr "mode" "QI")])
1698
1699 (define_insn "*movsi_extzv_1"
1700 [(set (match_operand:SI 0 "register_operand" "=R")
1701 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1702 (const_int 8)
1703 (const_int 8)))]
1704 ""
1705 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1706 [(set_attr "type" "imovx")
1707 (set_attr "mode" "SI")])
1708
1709 (define_insn "*movqi_extzv_2"
1710 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1711 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1712 (const_int 8)
1713 (const_int 8)) 0))]
1714 "!TARGET_64BIT"
1715 {
1716 switch (get_attr_type (insn))
1717 {
1718 case TYPE_IMOVX:
1719 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1720 default:
1721 return "mov{b}\t{%h1, %0|%0, %h1}";
1722 }
1723 }
1724 [(set (attr "type")
1725 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1726 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1727 (ne (symbol_ref "TARGET_MOVX")
1728 (const_int 0))))
1729 (const_string "imovx")
1730 (const_string "imov")))
1731 (set (attr "mode")
1732 (if_then_else (eq_attr "type" "imovx")
1733 (const_string "SI")
1734 (const_string "QI")))])
1735
1736 (define_insn "*movqi_extzv_2_rex64"
1737 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1738 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1739 (const_int 8)
1740 (const_int 8)) 0))]
1741 "TARGET_64BIT"
1742 {
1743 switch (get_attr_type (insn))
1744 {
1745 case TYPE_IMOVX:
1746 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1747 default:
1748 return "mov{b}\t{%h1, %0|%0, %h1}";
1749 }
1750 }
1751 [(set (attr "type")
1752 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1753 (ne (symbol_ref "TARGET_MOVX")
1754 (const_int 0)))
1755 (const_string "imovx")
1756 (const_string "imov")))
1757 (set (attr "mode")
1758 (if_then_else (eq_attr "type" "imovx")
1759 (const_string "SI")
1760 (const_string "QI")))])
1761
1762 (define_insn "movsi_insv_1"
1763 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1764 (const_int 8)
1765 (const_int 8))
1766 (match_operand:SI 1 "general_operand" "Qmn"))]
1767 "!TARGET_64BIT"
1768 "mov{b}\t{%b1, %h0|%h0, %b1}"
1769 [(set_attr "type" "imov")
1770 (set_attr "mode" "QI")])
1771
1772 (define_insn "*movsi_insv_1_rex64"
1773 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1774 (const_int 8)
1775 (const_int 8))
1776 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1777 "TARGET_64BIT"
1778 "mov{b}\t{%b1, %h0|%h0, %b1}"
1779 [(set_attr "type" "imov")
1780 (set_attr "mode" "QI")])
1781
1782 (define_insn "*movqi_insv_2"
1783 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784 (const_int 8)
1785 (const_int 8))
1786 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1787 (const_int 8)))]
1788 ""
1789 "mov{b}\t{%h1, %h0|%h0, %h1}"
1790 [(set_attr "type" "imov")
1791 (set_attr "mode" "QI")])
1792
1793 (define_expand "movdi"
1794 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1795 (match_operand:DI 1 "general_operand" ""))]
1796 ""
1797 "ix86_expand_move (DImode, operands); DONE;")
1798
1799 (define_insn "*pushdi"
1800 [(set (match_operand:DI 0 "push_operand" "=<")
1801 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1802 "!TARGET_64BIT"
1803 "#")
1804
1805 (define_insn "pushdi2_rex64"
1806 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1807 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1808 "TARGET_64BIT"
1809 "@
1810 push{q}\t%1
1811 #"
1812 [(set_attr "type" "push,multi")
1813 (set_attr "mode" "DI")])
1814
1815 ;; Convert impossible pushes of immediate to existing instructions.
1816 ;; First try to get scratch register and go through it. In case this
1817 ;; fails, push sign extended lower part first and then overwrite
1818 ;; upper part by 32bit move.
1819 (define_peephole2
1820 [(match_scratch:DI 2 "r")
1821 (set (match_operand:DI 0 "push_operand" "")
1822 (match_operand:DI 1 "immediate_operand" ""))]
1823 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1824 && !x86_64_immediate_operand (operands[1], DImode)"
1825 [(set (match_dup 2) (match_dup 1))
1826 (set (match_dup 0) (match_dup 2))]
1827 "")
1828
1829 ;; We need to define this as both peepholer and splitter for case
1830 ;; peephole2 pass is not run.
1831 (define_peephole2
1832 [(set (match_operand:DI 0 "push_operand" "")
1833 (match_operand:DI 1 "immediate_operand" ""))]
1834 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1835 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1836 [(set (match_dup 0) (match_dup 1))
1837 (set (match_dup 2) (match_dup 3))]
1838 "split_di (operands + 1, 1, operands + 2, operands + 3);
1839 operands[1] = gen_lowpart (DImode, operands[2]);
1840 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1841 GEN_INT (4)));
1842 ")
1843
1844 (define_split
1845 [(set (match_operand:DI 0 "push_operand" "")
1846 (match_operand:DI 1 "immediate_operand" ""))]
1847 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1848 && !symbolic_operand (operands[1], DImode)
1849 && !x86_64_immediate_operand (operands[1], DImode)"
1850 [(set (match_dup 0) (match_dup 1))
1851 (set (match_dup 2) (match_dup 3))]
1852 "split_di (operands + 1, 1, operands + 2, operands + 3);
1853 operands[1] = gen_lowpart (DImode, operands[2]);
1854 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1855 GEN_INT (4)));
1856 ")
1857
1858 (define_insn "*pushdi2_prologue_rex64"
1859 [(set (match_operand:DI 0 "push_operand" "=<")
1860 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1861 (clobber (mem:BLK (scratch)))]
1862 "TARGET_64BIT"
1863 "push{q}\t%1"
1864 [(set_attr "type" "push")
1865 (set_attr "mode" "DI")])
1866
1867 (define_insn "*popdi1_epilogue_rex64"
1868 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1869 (mem:DI (reg:DI 7)))
1870 (set (reg:DI 7)
1871 (plus:DI (reg:DI 7) (const_int 8)))
1872 (clobber (mem:BLK (scratch)))]
1873 "TARGET_64BIT"
1874 "pop{q}\t%0"
1875 [(set_attr "type" "pop")
1876 (set_attr "mode" "DI")])
1877
1878 (define_insn "popdi1"
1879 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1880 (mem:DI (reg:DI 7)))
1881 (set (reg:DI 7)
1882 (plus:DI (reg:DI 7) (const_int 8)))]
1883 "TARGET_64BIT"
1884 "pop{q}\t%0"
1885 [(set_attr "type" "pop")
1886 (set_attr "mode" "DI")])
1887
1888 (define_insn "*movdi_xor_rex64"
1889 [(set (match_operand:DI 0 "register_operand" "=r")
1890 (match_operand:DI 1 "const0_operand" "i"))
1891 (clobber (reg:CC 17))]
1892 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1893 && reload_completed"
1894 "xor{l}\t{%k0, %k0|%k0, %k0}"
1895 [(set_attr "type" "alu1")
1896 (set_attr "mode" "SI")
1897 (set_attr "length_immediate" "0")])
1898
1899 (define_insn "*movdi_or_rex64"
1900 [(set (match_operand:DI 0 "register_operand" "=r")
1901 (match_operand:DI 1 "const_int_operand" "i"))
1902 (clobber (reg:CC 17))]
1903 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1904 && reload_completed
1905 && operands[1] == constm1_rtx"
1906 {
1907 operands[1] = constm1_rtx;
1908 return "or{q}\t{%1, %0|%0, %1}";
1909 }
1910 [(set_attr "type" "alu1")
1911 (set_attr "mode" "DI")
1912 (set_attr "length_immediate" "1")])
1913
1914 (define_insn "*movdi_2"
1915 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1916 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1917 "!TARGET_64BIT
1918 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1919 "@
1920 #
1921 #
1922 movq\t{%1, %0|%0, %1}
1923 movq\t{%1, %0|%0, %1}
1924 movq\t{%1, %0|%0, %1}
1925 movdqa\t{%1, %0|%0, %1}
1926 movq\t{%1, %0|%0, %1}"
1927 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1928 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1929
1930 (define_split
1931 [(set (match_operand:DI 0 "push_operand" "")
1932 (match_operand:DI 1 "general_operand" ""))]
1933 "!TARGET_64BIT && reload_completed
1934 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1935 [(const_int 0)]
1936 "ix86_split_long_move (operands); DONE;")
1937
1938 ;; %%% This multiword shite has got to go.
1939 (define_split
1940 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1941 (match_operand:DI 1 "general_operand" ""))]
1942 "!TARGET_64BIT && reload_completed
1943 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1944 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1945 [(const_int 0)]
1946 "ix86_split_long_move (operands); DONE;")
1947
1948 (define_insn "*movdi_1_rex64"
1949 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1950 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1951 "TARGET_64BIT
1952 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1953 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1954 {
1955 switch (get_attr_type (insn))
1956 {
1957 case TYPE_SSEMOV:
1958 if (get_attr_mode (insn) == MODE_TI)
1959 return "movdqa\t{%1, %0|%0, %1}";
1960 /* FALLTHRU */
1961 case TYPE_MMXMOV:
1962 /* Moves from and into integer register is done using movd opcode with
1963 REX prefix. */
1964 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1965 return "movd\t{%1, %0|%0, %1}";
1966 return "movq\t{%1, %0|%0, %1}";
1967 case TYPE_MULTI:
1968 return "#";
1969 case TYPE_LEA:
1970 return "lea{q}\t{%a1, %0|%0, %a1}";
1971 default:
1972 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1973 abort ();
1974 if (get_attr_mode (insn) == MODE_SI)
1975 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1976 else if (which_alternative == 2)
1977 return "movabs{q}\t{%1, %0|%0, %1}";
1978 else
1979 return "mov{q}\t{%1, %0|%0, %1}";
1980 }
1981 }
1982 [(set (attr "type")
1983 (cond [(eq_attr "alternative" "5,6,7")
1984 (const_string "mmxmov")
1985 (eq_attr "alternative" "8,9,10")
1986 (const_string "ssemov")
1987 (eq_attr "alternative" "4")
1988 (const_string "multi")
1989 (and (ne (symbol_ref "flag_pic") (const_int 0))
1990 (match_operand:DI 1 "symbolic_operand" ""))
1991 (const_string "lea")
1992 ]
1993 (const_string "imov")))
1994 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1995 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1996 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1997
1998 (define_insn "*movdi_1_rex64_nointerunit"
1999 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2000 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2001 "TARGET_64BIT
2002 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2003 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2004 {
2005 switch (get_attr_type (insn))
2006 {
2007 case TYPE_SSEMOV:
2008 if (get_attr_mode (insn) == MODE_TI)
2009 return "movdqa\t{%1, %0|%0, %1}";
2010 /* FALLTHRU */
2011 case TYPE_MMXMOV:
2012 return "movq\t{%1, %0|%0, %1}";
2013 case TYPE_MULTI:
2014 return "#";
2015 case TYPE_LEA:
2016 return "lea{q}\t{%a1, %0|%0, %a1}";
2017 default:
2018 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2019 abort ();
2020 if (get_attr_mode (insn) == MODE_SI)
2021 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2022 else if (which_alternative == 2)
2023 return "movabs{q}\t{%1, %0|%0, %1}";
2024 else
2025 return "mov{q}\t{%1, %0|%0, %1}";
2026 }
2027 }
2028 [(set (attr "type")
2029 (cond [(eq_attr "alternative" "5,6,7")
2030 (const_string "mmxmov")
2031 (eq_attr "alternative" "8,9,10")
2032 (const_string "ssemov")
2033 (eq_attr "alternative" "4")
2034 (const_string "multi")
2035 (and (ne (symbol_ref "flag_pic") (const_int 0))
2036 (match_operand:DI 1 "symbolic_operand" ""))
2037 (const_string "lea")
2038 ]
2039 (const_string "imov")))
2040 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2041 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2042 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2043
2044 ;; Stores and loads of ax to arbitrary constant address.
2045 ;; We fake an second form of instruction to force reload to load address
2046 ;; into register when rax is not available
2047 (define_insn "*movabsdi_1_rex64"
2048 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2049 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2050 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2051 "@
2052 movabs{q}\t{%1, %P0|%P0, %1}
2053 mov{q}\t{%1, %a0|%a0, %1}"
2054 [(set_attr "type" "imov")
2055 (set_attr "modrm" "0,*")
2056 (set_attr "length_address" "8,0")
2057 (set_attr "length_immediate" "0,*")
2058 (set_attr "memory" "store")
2059 (set_attr "mode" "DI")])
2060
2061 (define_insn "*movabsdi_2_rex64"
2062 [(set (match_operand:DI 0 "register_operand" "=a,r")
2063 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2064 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2065 "@
2066 movabs{q}\t{%P1, %0|%0, %P1}
2067 mov{q}\t{%a1, %0|%0, %a1}"
2068 [(set_attr "type" "imov")
2069 (set_attr "modrm" "0,*")
2070 (set_attr "length_address" "8,0")
2071 (set_attr "length_immediate" "0")
2072 (set_attr "memory" "load")
2073 (set_attr "mode" "DI")])
2074
2075 ;; Convert impossible stores of immediate to existing instructions.
2076 ;; First try to get scratch register and go through it. In case this
2077 ;; fails, move by 32bit parts.
2078 (define_peephole2
2079 [(match_scratch:DI 2 "r")
2080 (set (match_operand:DI 0 "memory_operand" "")
2081 (match_operand:DI 1 "immediate_operand" ""))]
2082 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2083 && !x86_64_immediate_operand (operands[1], DImode)"
2084 [(set (match_dup 2) (match_dup 1))
2085 (set (match_dup 0) (match_dup 2))]
2086 "")
2087
2088 ;; We need to define this as both peepholer and splitter for case
2089 ;; peephole2 pass is not run.
2090 (define_peephole2
2091 [(set (match_operand:DI 0 "memory_operand" "")
2092 (match_operand:DI 1 "immediate_operand" ""))]
2093 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2094 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2095 [(set (match_dup 2) (match_dup 3))
2096 (set (match_dup 4) (match_dup 5))]
2097 "split_di (operands, 2, operands + 2, operands + 4);")
2098
2099 (define_split
2100 [(set (match_operand:DI 0 "memory_operand" "")
2101 (match_operand:DI 1 "immediate_operand" ""))]
2102 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2103 && !symbolic_operand (operands[1], DImode)
2104 && !x86_64_immediate_operand (operands[1], DImode)"
2105 [(set (match_dup 2) (match_dup 3))
2106 (set (match_dup 4) (match_dup 5))]
2107 "split_di (operands, 2, operands + 2, operands + 4);")
2108
2109 (define_insn "*swapdi_rex64"
2110 [(set (match_operand:DI 0 "register_operand" "+r")
2111 (match_operand:DI 1 "register_operand" "+r"))
2112 (set (match_dup 1)
2113 (match_dup 0))]
2114 "TARGET_64BIT"
2115 "xchg{q}\t%1, %0"
2116 [(set_attr "type" "imov")
2117 (set_attr "pent_pair" "np")
2118 (set_attr "athlon_decode" "vector")
2119 (set_attr "mode" "DI")
2120 (set_attr "modrm" "0")])
2121
2122
2123 (define_expand "movsf"
2124 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2125 (match_operand:SF 1 "general_operand" ""))]
2126 ""
2127 "ix86_expand_move (SFmode, operands); DONE;")
2128
2129 (define_insn "*pushsf"
2130 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2131 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2132 "!TARGET_64BIT"
2133 {
2134 switch (which_alternative)
2135 {
2136 case 1:
2137 return "push{l}\t%1";
2138
2139 default:
2140 /* This insn should be already split before reg-stack. */
2141 abort ();
2142 }
2143 }
2144 [(set_attr "type" "multi,push,multi")
2145 (set_attr "mode" "SF,SI,SF")])
2146
2147 (define_insn "*pushsf_rex64"
2148 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2149 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2150 "TARGET_64BIT"
2151 {
2152 switch (which_alternative)
2153 {
2154 case 1:
2155 return "push{q}\t%q1";
2156
2157 default:
2158 /* This insn should be already split before reg-stack. */
2159 abort ();
2160 }
2161 }
2162 [(set_attr "type" "multi,push,multi")
2163 (set_attr "mode" "SF,DI,SF")])
2164
2165 (define_split
2166 [(set (match_operand:SF 0 "push_operand" "")
2167 (match_operand:SF 1 "memory_operand" ""))]
2168 "reload_completed
2169 && GET_CODE (operands[1]) == MEM
2170 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2171 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2172 [(set (match_dup 0)
2173 (match_dup 1))]
2174 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2175
2176
2177 ;; %%% Kill this when call knows how to work this out.
2178 (define_split
2179 [(set (match_operand:SF 0 "push_operand" "")
2180 (match_operand:SF 1 "any_fp_register_operand" ""))]
2181 "!TARGET_64BIT"
2182 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2183 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2184
2185 (define_split
2186 [(set (match_operand:SF 0 "push_operand" "")
2187 (match_operand:SF 1 "any_fp_register_operand" ""))]
2188 "TARGET_64BIT"
2189 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2190 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2191
2192 (define_insn "*movsf_1"
2193 [(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")
2194 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2195 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2196 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2197 && (reload_in_progress || reload_completed
2198 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2199 || GET_CODE (operands[1]) != CONST_DOUBLE
2200 || memory_operand (operands[0], SFmode))"
2201 {
2202 switch (which_alternative)
2203 {
2204 case 0:
2205 return output_387_reg_move (insn, operands);
2206
2207 case 1:
2208 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2209 return "fstp%z0\t%y0";
2210 else
2211 return "fst%z0\t%y0";
2212
2213 case 2:
2214 return standard_80387_constant_opcode (operands[1]);
2215
2216 case 3:
2217 case 4:
2218 return "mov{l}\t{%1, %0|%0, %1}";
2219 case 5:
2220 if (get_attr_mode (insn) == MODE_TI)
2221 return "pxor\t%0, %0";
2222 else
2223 return "xorps\t%0, %0";
2224 case 6:
2225 if (get_attr_mode (insn) == MODE_V4SF)
2226 return "movaps\t{%1, %0|%0, %1}";
2227 else
2228 return "movss\t{%1, %0|%0, %1}";
2229 case 7:
2230 case 8:
2231 return "movss\t{%1, %0|%0, %1}";
2232
2233 case 9:
2234 case 10:
2235 return "movd\t{%1, %0|%0, %1}";
2236
2237 case 11:
2238 return "movq\t{%1, %0|%0, %1}";
2239
2240 default:
2241 abort();
2242 }
2243 }
2244 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2245 (set (attr "mode")
2246 (cond [(eq_attr "alternative" "3,4,9,10")
2247 (const_string "SI")
2248 (eq_attr "alternative" "5")
2249 (if_then_else
2250 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2251 (const_int 0))
2252 (ne (symbol_ref "TARGET_SSE2")
2253 (const_int 0)))
2254 (eq (symbol_ref "optimize_size")
2255 (const_int 0)))
2256 (const_string "TI")
2257 (const_string "V4SF"))
2258 /* For architectures resolving dependencies on
2259 whole SSE registers use APS move to break dependency
2260 chains, otherwise use short move to avoid extra work.
2261
2262 Do the same for architectures resolving dependencies on
2263 the parts. While in DF mode it is better to always handle
2264 just register parts, the SF mode is different due to lack
2265 of instructions to load just part of the register. It is
2266 better to maintain the whole registers in single format
2267 to avoid problems on using packed logical operations. */
2268 (eq_attr "alternative" "6")
2269 (if_then_else
2270 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2271 (const_int 0))
2272 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2273 (const_int 0)))
2274 (const_string "V4SF")
2275 (const_string "SF"))
2276 (eq_attr "alternative" "11")
2277 (const_string "DI")]
2278 (const_string "SF")))])
2279
2280 (define_insn "*movsf_1_nointerunit"
2281 [(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")
2282 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2283 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2284 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2285 && (reload_in_progress || reload_completed
2286 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2287 || GET_CODE (operands[1]) != CONST_DOUBLE
2288 || memory_operand (operands[0], SFmode))"
2289 {
2290 switch (which_alternative)
2291 {
2292 case 0:
2293 return output_387_reg_move (insn, operands);
2294
2295 case 1:
2296 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2297 return "fstp%z0\t%y0";
2298 else
2299 return "fst%z0\t%y0";
2300
2301 case 2:
2302 return standard_80387_constant_opcode (operands[1]);
2303
2304 case 3:
2305 case 4:
2306 return "mov{l}\t{%1, %0|%0, %1}";
2307 case 5:
2308 if (get_attr_mode (insn) == MODE_TI)
2309 return "pxor\t%0, %0";
2310 else
2311 return "xorps\t%0, %0";
2312 case 6:
2313 if (get_attr_mode (insn) == MODE_V4SF)
2314 return "movaps\t{%1, %0|%0, %1}";
2315 else
2316 return "movss\t{%1, %0|%0, %1}";
2317 case 7:
2318 case 8:
2319 return "movss\t{%1, %0|%0, %1}";
2320
2321 case 9:
2322 case 10:
2323 return "movd\t{%1, %0|%0, %1}";
2324
2325 case 11:
2326 return "movq\t{%1, %0|%0, %1}";
2327
2328 default:
2329 abort();
2330 }
2331 }
2332 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2333 (set (attr "mode")
2334 (cond [(eq_attr "alternative" "3,4,9,10")
2335 (const_string "SI")
2336 (eq_attr "alternative" "5")
2337 (if_then_else
2338 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2339 (const_int 0))
2340 (ne (symbol_ref "TARGET_SSE2")
2341 (const_int 0)))
2342 (eq (symbol_ref "optimize_size")
2343 (const_int 0)))
2344 (const_string "TI")
2345 (const_string "V4SF"))
2346 /* For architectures resolving dependencies on
2347 whole SSE registers use APS move to break dependency
2348 chains, otherwise use short move to avoid extra work.
2349
2350 Do the same for architectures resolving dependencies on
2351 the parts. While in DF mode it is better to always handle
2352 just register parts, the SF mode is different due to lack
2353 of instructions to load just part of the register. It is
2354 better to maintain the whole registers in single format
2355 to avoid problems on using packed logical operations. */
2356 (eq_attr "alternative" "6")
2357 (if_then_else
2358 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2359 (const_int 0))
2360 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2361 (const_int 0)))
2362 (const_string "V4SF")
2363 (const_string "SF"))
2364 (eq_attr "alternative" "11")
2365 (const_string "DI")]
2366 (const_string "SF")))])
2367
2368 (define_insn "*swapsf"
2369 [(set (match_operand:SF 0 "register_operand" "+f")
2370 (match_operand:SF 1 "register_operand" "+f"))
2371 (set (match_dup 1)
2372 (match_dup 0))]
2373 "reload_completed || !TARGET_SSE"
2374 {
2375 if (STACK_TOP_P (operands[0]))
2376 return "fxch\t%1";
2377 else
2378 return "fxch\t%0";
2379 }
2380 [(set_attr "type" "fxch")
2381 (set_attr "mode" "SF")])
2382
2383 (define_expand "movdf"
2384 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2385 (match_operand:DF 1 "general_operand" ""))]
2386 ""
2387 "ix86_expand_move (DFmode, operands); DONE;")
2388
2389 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2390 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2391 ;; On the average, pushdf using integers can be still shorter. Allow this
2392 ;; pattern for optimize_size too.
2393
2394 (define_insn "*pushdf_nointeger"
2395 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2396 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2397 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2398 {
2399 /* This insn should be already split before reg-stack. */
2400 abort ();
2401 }
2402 [(set_attr "type" "multi")
2403 (set_attr "mode" "DF,SI,SI,DF")])
2404
2405 (define_insn "*pushdf_integer"
2406 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2407 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2408 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2409 {
2410 /* This insn should be already split before reg-stack. */
2411 abort ();
2412 }
2413 [(set_attr "type" "multi")
2414 (set_attr "mode" "DF,SI,DF")])
2415
2416 ;; %%% Kill this when call knows how to work this out.
2417 (define_split
2418 [(set (match_operand:DF 0 "push_operand" "")
2419 (match_operand:DF 1 "any_fp_register_operand" ""))]
2420 "!TARGET_64BIT && reload_completed"
2421 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2422 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2423 "")
2424
2425 (define_split
2426 [(set (match_operand:DF 0 "push_operand" "")
2427 (match_operand:DF 1 "any_fp_register_operand" ""))]
2428 "TARGET_64BIT && reload_completed"
2429 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2430 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2431 "")
2432
2433 (define_split
2434 [(set (match_operand:DF 0 "push_operand" "")
2435 (match_operand:DF 1 "general_operand" ""))]
2436 "reload_completed"
2437 [(const_int 0)]
2438 "ix86_split_long_move (operands); DONE;")
2439
2440 ;; Moving is usually shorter when only FP registers are used. This separate
2441 ;; movdf pattern avoids the use of integer registers for FP operations
2442 ;; when optimizing for size.
2443
2444 (define_insn "*movdf_nointeger"
2445 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2446 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2447 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449 && (reload_in_progress || reload_completed
2450 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451 || GET_CODE (operands[1]) != CONST_DOUBLE
2452 || memory_operand (operands[0], DFmode))"
2453 {
2454 switch (which_alternative)
2455 {
2456 case 0:
2457 return output_387_reg_move (insn, operands);
2458
2459 case 1:
2460 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461 return "fstp%z0\t%y0";
2462 else
2463 return "fst%z0\t%y0";
2464
2465 case 2:
2466 return standard_80387_constant_opcode (operands[1]);
2467
2468 case 3:
2469 case 4:
2470 return "#";
2471 case 5:
2472 switch (get_attr_mode (insn))
2473 {
2474 case MODE_V4SF:
2475 return "xorps\t%0, %0";
2476 case MODE_V2DF:
2477 return "xorpd\t%0, %0";
2478 case MODE_TI:
2479 return "pxor\t%0, %0";
2480 default:
2481 abort ();
2482 }
2483 case 6:
2484 switch (get_attr_mode (insn))
2485 {
2486 case MODE_V4SF:
2487 return "movaps\t{%1, %0|%0, %1}";
2488 case MODE_V2DF:
2489 return "movapd\t{%1, %0|%0, %1}";
2490 case MODE_DF:
2491 return "movsd\t{%1, %0|%0, %1}";
2492 default:
2493 abort ();
2494 }
2495 case 7:
2496 if (get_attr_mode (insn) == MODE_V2DF)
2497 return "movlpd\t{%1, %0|%0, %1}";
2498 else
2499 return "movsd\t{%1, %0|%0, %1}";
2500 case 8:
2501 return "movsd\t{%1, %0|%0, %1}";
2502
2503 default:
2504 abort();
2505 }
2506 }
2507 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2508 (set (attr "mode")
2509 (cond [(eq_attr "alternative" "3,4")
2510 (const_string "SI")
2511 /* xorps is one byte shorter. */
2512 (eq_attr "alternative" "5")
2513 (cond [(ne (symbol_ref "optimize_size")
2514 (const_int 0))
2515 (const_string "V4SF")
2516 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2517 (const_int 0))
2518 (const_string "TI")]
2519 (const_string "V2DF"))
2520 /* For architectures resolving dependencies on
2521 whole SSE registers use APD move to break dependency
2522 chains, otherwise use short move to avoid extra work.
2523
2524 movaps encodes one byte shorter. */
2525 (eq_attr "alternative" "6")
2526 (cond
2527 [(ne (symbol_ref "optimize_size")
2528 (const_int 0))
2529 (const_string "V4SF")
2530 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2531 (const_int 0))
2532 (const_string "V2DF")]
2533 (const_string "DF"))
2534 /* For architectures resolving dependencies on register
2535 parts we may avoid extra work to zero out upper part
2536 of register. */
2537 (eq_attr "alternative" "7")
2538 (if_then_else
2539 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2540 (const_int 0))
2541 (const_string "V2DF")
2542 (const_string "DF"))]
2543 (const_string "DF")))])
2544
2545 (define_insn "*movdf_integer"
2546 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2547 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2548 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2549 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2550 && (reload_in_progress || reload_completed
2551 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2552 || GET_CODE (operands[1]) != CONST_DOUBLE
2553 || memory_operand (operands[0], DFmode))"
2554 {
2555 switch (which_alternative)
2556 {
2557 case 0:
2558 return output_387_reg_move (insn, operands);
2559
2560 case 1:
2561 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2562 return "fstp%z0\t%y0";
2563 else
2564 return "fst%z0\t%y0";
2565
2566 case 2:
2567 return standard_80387_constant_opcode (operands[1]);
2568
2569 case 3:
2570 case 4:
2571 return "#";
2572
2573 case 5:
2574 switch (get_attr_mode (insn))
2575 {
2576 case MODE_V4SF:
2577 return "xorps\t%0, %0";
2578 case MODE_V2DF:
2579 return "xorpd\t%0, %0";
2580 case MODE_TI:
2581 return "pxor\t%0, %0";
2582 default:
2583 abort ();
2584 }
2585 case 6:
2586 switch (get_attr_mode (insn))
2587 {
2588 case MODE_V4SF:
2589 return "movaps\t{%1, %0|%0, %1}";
2590 case MODE_V2DF:
2591 return "movapd\t{%1, %0|%0, %1}";
2592 case MODE_DF:
2593 return "movsd\t{%1, %0|%0, %1}";
2594 default:
2595 abort ();
2596 }
2597 case 7:
2598 if (get_attr_mode (insn) == MODE_V2DF)
2599 return "movlpd\t{%1, %0|%0, %1}";
2600 else
2601 return "movsd\t{%1, %0|%0, %1}";
2602 case 8:
2603 return "movsd\t{%1, %0|%0, %1}";
2604
2605 default:
2606 abort();
2607 }
2608 }
2609 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2610 (set (attr "mode")
2611 (cond [(eq_attr "alternative" "3,4")
2612 (const_string "SI")
2613 /* xorps is one byte shorter. */
2614 (eq_attr "alternative" "5")
2615 (cond [(ne (symbol_ref "optimize_size")
2616 (const_int 0))
2617 (const_string "V4SF")
2618 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2619 (const_int 0))
2620 (const_string "TI")]
2621 (const_string "V2DF"))
2622 /* For architectures resolving dependencies on
2623 whole SSE registers use APD move to break dependency
2624 chains, otherwise use short move to avoid extra work.
2625
2626 movaps encodes one byte shorter. */
2627 (eq_attr "alternative" "6")
2628 (cond
2629 [(ne (symbol_ref "optimize_size")
2630 (const_int 0))
2631 (const_string "V4SF")
2632 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2633 (const_int 0))
2634 (const_string "V2DF")]
2635 (const_string "DF"))
2636 /* For architectures resolving dependencies on register
2637 parts we may avoid extra work to zero out upper part
2638 of register. */
2639 (eq_attr "alternative" "7")
2640 (if_then_else
2641 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2642 (const_int 0))
2643 (const_string "V2DF")
2644 (const_string "DF"))]
2645 (const_string "DF")))])
2646
2647 (define_split
2648 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2649 (match_operand:DF 1 "general_operand" ""))]
2650 "reload_completed
2651 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2652 && ! (ANY_FP_REG_P (operands[0]) ||
2653 (GET_CODE (operands[0]) == SUBREG
2654 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2655 && ! (ANY_FP_REG_P (operands[1]) ||
2656 (GET_CODE (operands[1]) == SUBREG
2657 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2658 [(const_int 0)]
2659 "ix86_split_long_move (operands); DONE;")
2660
2661 (define_insn "*swapdf"
2662 [(set (match_operand:DF 0 "register_operand" "+f")
2663 (match_operand:DF 1 "register_operand" "+f"))
2664 (set (match_dup 1)
2665 (match_dup 0))]
2666 "reload_completed || !TARGET_SSE2"
2667 {
2668 if (STACK_TOP_P (operands[0]))
2669 return "fxch\t%1";
2670 else
2671 return "fxch\t%0";
2672 }
2673 [(set_attr "type" "fxch")
2674 (set_attr "mode" "DF")])
2675
2676 (define_expand "movxf"
2677 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2678 (match_operand:XF 1 "general_operand" ""))]
2679 ""
2680 "ix86_expand_move (XFmode, operands); DONE;")
2681
2682 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2683 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2684 ;; Pushing using integer instructions is longer except for constants
2685 ;; and direct memory references.
2686 ;; (assuming that any given constant is pushed only once, but this ought to be
2687 ;; handled elsewhere).
2688
2689 (define_insn "*pushxf_nointeger"
2690 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2691 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2692 "optimize_size"
2693 {
2694 /* This insn should be already split before reg-stack. */
2695 abort ();
2696 }
2697 [(set_attr "type" "multi")
2698 (set_attr "mode" "XF,SI,SI")])
2699
2700 (define_insn "*pushxf_integer"
2701 [(set (match_operand:XF 0 "push_operand" "=<,<")
2702 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2703 "!optimize_size"
2704 {
2705 /* This insn should be already split before reg-stack. */
2706 abort ();
2707 }
2708 [(set_attr "type" "multi")
2709 (set_attr "mode" "XF,SI")])
2710
2711 (define_split
2712 [(set (match_operand 0 "push_operand" "")
2713 (match_operand 1 "general_operand" ""))]
2714 "reload_completed
2715 && (GET_MODE (operands[0]) == XFmode
2716 || GET_MODE (operands[0]) == DFmode)
2717 && !ANY_FP_REG_P (operands[1])"
2718 [(const_int 0)]
2719 "ix86_split_long_move (operands); DONE;")
2720
2721 (define_split
2722 [(set (match_operand:XF 0 "push_operand" "")
2723 (match_operand:XF 1 "any_fp_register_operand" ""))]
2724 "!TARGET_64BIT"
2725 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2726 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2727 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2728
2729 (define_split
2730 [(set (match_operand:XF 0 "push_operand" "")
2731 (match_operand:XF 1 "any_fp_register_operand" ""))]
2732 "TARGET_64BIT"
2733 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2734 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2735 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2736
2737 ;; Do not use integer registers when optimizing for size
2738 (define_insn "*movxf_nointeger"
2739 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2740 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2741 "optimize_size
2742 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2743 && (reload_in_progress || reload_completed
2744 || GET_CODE (operands[1]) != CONST_DOUBLE
2745 || memory_operand (operands[0], XFmode))"
2746 {
2747 switch (which_alternative)
2748 {
2749 case 0:
2750 return output_387_reg_move (insn, operands);
2751
2752 case 1:
2753 /* There is no non-popping store to memory for XFmode. So if
2754 we need one, follow the store with a load. */
2755 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2756 return "fstp%z0\t%y0\;fld%z0\t%y0";
2757 else
2758 return "fstp%z0\t%y0";
2759
2760 case 2:
2761 return standard_80387_constant_opcode (operands[1]);
2762
2763 case 3: case 4:
2764 return "#";
2765 }
2766 abort();
2767 }
2768 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2769 (set_attr "mode" "XF,XF,XF,SI,SI")])
2770
2771 (define_insn "*movxf_integer"
2772 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2773 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2774 "!optimize_size
2775 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2776 && (reload_in_progress || reload_completed
2777 || GET_CODE (operands[1]) != CONST_DOUBLE
2778 || memory_operand (operands[0], XFmode))"
2779 {
2780 switch (which_alternative)
2781 {
2782 case 0:
2783 return output_387_reg_move (insn, operands);
2784
2785 case 1:
2786 /* There is no non-popping store to memory for XFmode. So if
2787 we need one, follow the store with a load. */
2788 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2789 return "fstp%z0\t%y0\;fld%z0\t%y0";
2790 else
2791 return "fstp%z0\t%y0";
2792
2793 case 2:
2794 return standard_80387_constant_opcode (operands[1]);
2795
2796 case 3: case 4:
2797 return "#";
2798 }
2799 abort();
2800 }
2801 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2802 (set_attr "mode" "XF,XF,XF,SI,SI")])
2803
2804 (define_split
2805 [(set (match_operand 0 "nonimmediate_operand" "")
2806 (match_operand 1 "general_operand" ""))]
2807 "reload_completed
2808 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2809 && GET_MODE (operands[0]) == XFmode
2810 && ! (ANY_FP_REG_P (operands[0]) ||
2811 (GET_CODE (operands[0]) == SUBREG
2812 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2813 && ! (ANY_FP_REG_P (operands[1]) ||
2814 (GET_CODE (operands[1]) == SUBREG
2815 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2816 [(const_int 0)]
2817 "ix86_split_long_move (operands); DONE;")
2818
2819 (define_split
2820 [(set (match_operand 0 "register_operand" "")
2821 (match_operand 1 "memory_operand" ""))]
2822 "reload_completed
2823 && GET_CODE (operands[1]) == MEM
2824 && (GET_MODE (operands[0]) == XFmode
2825 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2826 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2827 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2828 [(set (match_dup 0) (match_dup 1))]
2829 {
2830 rtx c = get_pool_constant (XEXP (operands[1], 0));
2831 rtx r = operands[0];
2832
2833 if (GET_CODE (r) == SUBREG)
2834 r = SUBREG_REG (r);
2835
2836 if (SSE_REG_P (r))
2837 {
2838 if (!standard_sse_constant_p (c))
2839 FAIL;
2840 }
2841 else if (FP_REG_P (r))
2842 {
2843 if (!standard_80387_constant_p (c))
2844 FAIL;
2845 }
2846 else if (MMX_REG_P (r))
2847 FAIL;
2848
2849 operands[1] = c;
2850 })
2851
2852 (define_insn "swapxf"
2853 [(set (match_operand:XF 0 "register_operand" "+f")
2854 (match_operand:XF 1 "register_operand" "+f"))
2855 (set (match_dup 1)
2856 (match_dup 0))]
2857 ""
2858 {
2859 if (STACK_TOP_P (operands[0]))
2860 return "fxch\t%1";
2861 else
2862 return "fxch\t%0";
2863 }
2864 [(set_attr "type" "fxch")
2865 (set_attr "mode" "XF")])
2866 \f
2867 ;; Zero extension instructions
2868
2869 (define_expand "zero_extendhisi2"
2870 [(set (match_operand:SI 0 "register_operand" "")
2871 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2872 ""
2873 {
2874 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2875 {
2876 operands[1] = force_reg (HImode, operands[1]);
2877 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2878 DONE;
2879 }
2880 })
2881
2882 (define_insn "zero_extendhisi2_and"
2883 [(set (match_operand:SI 0 "register_operand" "=r")
2884 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2885 (clobber (reg:CC 17))]
2886 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2887 "#"
2888 [(set_attr "type" "alu1")
2889 (set_attr "mode" "SI")])
2890
2891 (define_split
2892 [(set (match_operand:SI 0 "register_operand" "")
2893 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2894 (clobber (reg:CC 17))]
2895 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2896 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2897 (clobber (reg:CC 17))])]
2898 "")
2899
2900 (define_insn "*zero_extendhisi2_movzwl"
2901 [(set (match_operand:SI 0 "register_operand" "=r")
2902 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2903 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2904 "movz{wl|x}\t{%1, %0|%0, %1}"
2905 [(set_attr "type" "imovx")
2906 (set_attr "mode" "SI")])
2907
2908 (define_expand "zero_extendqihi2"
2909 [(parallel
2910 [(set (match_operand:HI 0 "register_operand" "")
2911 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2912 (clobber (reg:CC 17))])]
2913 ""
2914 "")
2915
2916 (define_insn "*zero_extendqihi2_and"
2917 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2918 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2919 (clobber (reg:CC 17))]
2920 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2921 "#"
2922 [(set_attr "type" "alu1")
2923 (set_attr "mode" "HI")])
2924
2925 (define_insn "*zero_extendqihi2_movzbw_and"
2926 [(set (match_operand:HI 0 "register_operand" "=r,r")
2927 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2928 (clobber (reg:CC 17))]
2929 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2930 "#"
2931 [(set_attr "type" "imovx,alu1")
2932 (set_attr "mode" "HI")])
2933
2934 (define_insn "*zero_extendqihi2_movzbw"
2935 [(set (match_operand:HI 0 "register_operand" "=r")
2936 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2937 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2938 "movz{bw|x}\t{%1, %0|%0, %1}"
2939 [(set_attr "type" "imovx")
2940 (set_attr "mode" "HI")])
2941
2942 ;; For the movzbw case strip only the clobber
2943 (define_split
2944 [(set (match_operand:HI 0 "register_operand" "")
2945 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2946 (clobber (reg:CC 17))]
2947 "reload_completed
2948 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2949 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2950 [(set (match_operand:HI 0 "register_operand" "")
2951 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2952
2953 ;; When source and destination does not overlap, clear destination
2954 ;; first and then do the movb
2955 (define_split
2956 [(set (match_operand:HI 0 "register_operand" "")
2957 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2958 (clobber (reg:CC 17))]
2959 "reload_completed
2960 && ANY_QI_REG_P (operands[0])
2961 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2962 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2963 [(set (match_dup 0) (const_int 0))
2964 (set (strict_low_part (match_dup 2)) (match_dup 1))]
2965 "operands[2] = gen_lowpart (QImode, operands[0]);")
2966
2967 ;; Rest is handled by single and.
2968 (define_split
2969 [(set (match_operand:HI 0 "register_operand" "")
2970 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
2971 (clobber (reg:CC 17))]
2972 "reload_completed
2973 && true_regnum (operands[0]) == true_regnum (operands[1])"
2974 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
2975 (clobber (reg:CC 17))])]
2976 "")
2977
2978 (define_expand "zero_extendqisi2"
2979 [(parallel
2980 [(set (match_operand:SI 0 "register_operand" "")
2981 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
2982 (clobber (reg:CC 17))])]
2983 ""
2984 "")
2985
2986 (define_insn "*zero_extendqisi2_and"
2987 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
2988 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2989 (clobber (reg:CC 17))]
2990 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2991 "#"
2992 [(set_attr "type" "alu1")
2993 (set_attr "mode" "SI")])
2994
2995 (define_insn "*zero_extendqisi2_movzbw_and"
2996 [(set (match_operand:SI 0 "register_operand" "=r,r")
2997 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2998 (clobber (reg:CC 17))]
2999 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3000 "#"
3001 [(set_attr "type" "imovx,alu1")
3002 (set_attr "mode" "SI")])
3003
3004 (define_insn "*zero_extendqisi2_movzbw"
3005 [(set (match_operand:SI 0 "register_operand" "=r")
3006 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3007 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3008 "movz{bl|x}\t{%1, %0|%0, %1}"
3009 [(set_attr "type" "imovx")
3010 (set_attr "mode" "SI")])
3011
3012 ;; For the movzbl case strip only the clobber
3013 (define_split
3014 [(set (match_operand:SI 0 "register_operand" "")
3015 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3016 (clobber (reg:CC 17))]
3017 "reload_completed
3018 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3019 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3020 [(set (match_dup 0)
3021 (zero_extend:SI (match_dup 1)))])
3022
3023 ;; When source and destination does not overlap, clear destination
3024 ;; first and then do the movb
3025 (define_split
3026 [(set (match_operand:SI 0 "register_operand" "")
3027 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3028 (clobber (reg:CC 17))]
3029 "reload_completed
3030 && ANY_QI_REG_P (operands[0])
3031 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3032 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3033 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3034 [(set (match_dup 0) (const_int 0))
3035 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3036 "operands[2] = gen_lowpart (QImode, operands[0]);")
3037
3038 ;; Rest is handled by single and.
3039 (define_split
3040 [(set (match_operand:SI 0 "register_operand" "")
3041 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3042 (clobber (reg:CC 17))]
3043 "reload_completed
3044 && true_regnum (operands[0]) == true_regnum (operands[1])"
3045 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3046 (clobber (reg:CC 17))])]
3047 "")
3048
3049 ;; %%% Kill me once multi-word ops are sane.
3050 (define_expand "zero_extendsidi2"
3051 [(set (match_operand:DI 0 "register_operand" "=r")
3052 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3053 ""
3054 "if (!TARGET_64BIT)
3055 {
3056 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3057 DONE;
3058 }
3059 ")
3060
3061 (define_insn "zero_extendsidi2_32"
3062 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3063 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3064 (clobber (reg:CC 17))]
3065 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3066 "@
3067 #
3068 #
3069 #
3070 movd\t{%1, %0|%0, %1}
3071 movd\t{%1, %0|%0, %1}"
3072 [(set_attr "mode" "SI,SI,SI,DI,TI")
3073 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3074
3075 (define_insn "*zero_extendsidi2_32_1"
3076 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3077 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3078 (clobber (reg:CC 17))]
3079 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3080 "@
3081 #
3082 #
3083 #
3084 movd\t{%1, %0|%0, %1}
3085 movd\t{%1, %0|%0, %1}"
3086 [(set_attr "mode" "SI,SI,SI,DI,TI")
3087 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3088
3089 (define_insn "zero_extendsidi2_rex64"
3090 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3091 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3092 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3093 "@
3094 mov\t{%k1, %k0|%k0, %k1}
3095 #
3096 movd\t{%1, %0|%0, %1}
3097 movd\t{%1, %0|%0, %1}"
3098 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3099 (set_attr "mode" "SI,DI,DI,TI")])
3100
3101 (define_insn "*zero_extendsidi2_rex64_1"
3102 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3103 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3104 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3105 "@
3106 mov\t{%k1, %k0|%k0, %k1}
3107 #
3108 movd\t{%1, %0|%0, %1}
3109 movd\t{%1, %0|%0, %1}"
3110 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3111 (set_attr "mode" "SI,DI,SI,SI")])
3112
3113 (define_split
3114 [(set (match_operand:DI 0 "memory_operand" "")
3115 (zero_extend:DI (match_dup 0)))]
3116 "TARGET_64BIT"
3117 [(set (match_dup 4) (const_int 0))]
3118 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3119
3120 (define_split
3121 [(set (match_operand:DI 0 "register_operand" "")
3122 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3123 (clobber (reg:CC 17))]
3124 "!TARGET_64BIT && reload_completed
3125 && true_regnum (operands[0]) == true_regnum (operands[1])"
3126 [(set (match_dup 4) (const_int 0))]
3127 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3128
3129 (define_split
3130 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3131 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3132 (clobber (reg:CC 17))]
3133 "!TARGET_64BIT && reload_completed
3134 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3135 [(set (match_dup 3) (match_dup 1))
3136 (set (match_dup 4) (const_int 0))]
3137 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3138
3139 (define_insn "zero_extendhidi2"
3140 [(set (match_operand:DI 0 "register_operand" "=r,r")
3141 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3142 "TARGET_64BIT"
3143 "@
3144 movz{wl|x}\t{%1, %k0|%k0, %1}
3145 movz{wq|x}\t{%1, %0|%0, %1}"
3146 [(set_attr "type" "imovx")
3147 (set_attr "mode" "SI,DI")])
3148
3149 (define_insn "zero_extendqidi2"
3150 [(set (match_operand:DI 0 "register_operand" "=r,r")
3151 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3152 "TARGET_64BIT"
3153 "@
3154 movz{bl|x}\t{%1, %k0|%k0, %1}
3155 movz{bq|x}\t{%1, %0|%0, %1}"
3156 [(set_attr "type" "imovx")
3157 (set_attr "mode" "SI,DI")])
3158 \f
3159 ;; Sign extension instructions
3160
3161 (define_expand "extendsidi2"
3162 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3163 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3164 (clobber (reg:CC 17))
3165 (clobber (match_scratch:SI 2 ""))])]
3166 ""
3167 {
3168 if (TARGET_64BIT)
3169 {
3170 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3171 DONE;
3172 }
3173 })
3174
3175 (define_insn "*extendsidi2_1"
3176 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3177 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3178 (clobber (reg:CC 17))
3179 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3180 "!TARGET_64BIT"
3181 "#")
3182
3183 (define_insn "extendsidi2_rex64"
3184 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3185 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3186 "TARGET_64BIT"
3187 "@
3188 {cltq|cdqe}
3189 movs{lq|x}\t{%1,%0|%0, %1}"
3190 [(set_attr "type" "imovx")
3191 (set_attr "mode" "DI")
3192 (set_attr "prefix_0f" "0")
3193 (set_attr "modrm" "0,1")])
3194
3195 (define_insn "extendhidi2"
3196 [(set (match_operand:DI 0 "register_operand" "=r")
3197 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3198 "TARGET_64BIT"
3199 "movs{wq|x}\t{%1,%0|%0, %1}"
3200 [(set_attr "type" "imovx")
3201 (set_attr "mode" "DI")])
3202
3203 (define_insn "extendqidi2"
3204 [(set (match_operand:DI 0 "register_operand" "=r")
3205 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3206 "TARGET_64BIT"
3207 "movs{bq|x}\t{%1,%0|%0, %1}"
3208 [(set_attr "type" "imovx")
3209 (set_attr "mode" "DI")])
3210
3211 ;; Extend to memory case when source register does die.
3212 (define_split
3213 [(set (match_operand:DI 0 "memory_operand" "")
3214 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3215 (clobber (reg:CC 17))
3216 (clobber (match_operand:SI 2 "register_operand" ""))]
3217 "(reload_completed
3218 && dead_or_set_p (insn, operands[1])
3219 && !reg_mentioned_p (operands[1], operands[0]))"
3220 [(set (match_dup 3) (match_dup 1))
3221 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3222 (clobber (reg:CC 17))])
3223 (set (match_dup 4) (match_dup 1))]
3224 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3225
3226 ;; Extend to memory case when source register does not die.
3227 (define_split
3228 [(set (match_operand:DI 0 "memory_operand" "")
3229 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3230 (clobber (reg:CC 17))
3231 (clobber (match_operand:SI 2 "register_operand" ""))]
3232 "reload_completed"
3233 [(const_int 0)]
3234 {
3235 split_di (&operands[0], 1, &operands[3], &operands[4]);
3236
3237 emit_move_insn (operands[3], operands[1]);
3238
3239 /* Generate a cltd if possible and doing so it profitable. */
3240 if (true_regnum (operands[1]) == 0
3241 && true_regnum (operands[2]) == 1
3242 && (optimize_size || TARGET_USE_CLTD))
3243 {
3244 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3245 }
3246 else
3247 {
3248 emit_move_insn (operands[2], operands[1]);
3249 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3250 }
3251 emit_move_insn (operands[4], operands[2]);
3252 DONE;
3253 })
3254
3255 ;; Extend to register case. Optimize case where source and destination
3256 ;; registers match and cases where we can use cltd.
3257 (define_split
3258 [(set (match_operand:DI 0 "register_operand" "")
3259 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3260 (clobber (reg:CC 17))
3261 (clobber (match_scratch:SI 2 ""))]
3262 "reload_completed"
3263 [(const_int 0)]
3264 {
3265 split_di (&operands[0], 1, &operands[3], &operands[4]);
3266
3267 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3268 emit_move_insn (operands[3], operands[1]);
3269
3270 /* Generate a cltd if possible and doing so it profitable. */
3271 if (true_regnum (operands[3]) == 0
3272 && (optimize_size || TARGET_USE_CLTD))
3273 {
3274 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3275 DONE;
3276 }
3277
3278 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3279 emit_move_insn (operands[4], operands[1]);
3280
3281 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3282 DONE;
3283 })
3284
3285 (define_insn "extendhisi2"
3286 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3287 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3288 ""
3289 {
3290 switch (get_attr_prefix_0f (insn))
3291 {
3292 case 0:
3293 return "{cwtl|cwde}";
3294 default:
3295 return "movs{wl|x}\t{%1,%0|%0, %1}";
3296 }
3297 }
3298 [(set_attr "type" "imovx")
3299 (set_attr "mode" "SI")
3300 (set (attr "prefix_0f")
3301 ;; movsx is short decodable while cwtl is vector decoded.
3302 (if_then_else (and (eq_attr "cpu" "!k6")
3303 (eq_attr "alternative" "0"))
3304 (const_string "0")
3305 (const_string "1")))
3306 (set (attr "modrm")
3307 (if_then_else (eq_attr "prefix_0f" "0")
3308 (const_string "0")
3309 (const_string "1")))])
3310
3311 (define_insn "*extendhisi2_zext"
3312 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3313 (zero_extend:DI
3314 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3315 "TARGET_64BIT"
3316 {
3317 switch (get_attr_prefix_0f (insn))
3318 {
3319 case 0:
3320 return "{cwtl|cwde}";
3321 default:
3322 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3323 }
3324 }
3325 [(set_attr "type" "imovx")
3326 (set_attr "mode" "SI")
3327 (set (attr "prefix_0f")
3328 ;; movsx is short decodable while cwtl is vector decoded.
3329 (if_then_else (and (eq_attr "cpu" "!k6")
3330 (eq_attr "alternative" "0"))
3331 (const_string "0")
3332 (const_string "1")))
3333 (set (attr "modrm")
3334 (if_then_else (eq_attr "prefix_0f" "0")
3335 (const_string "0")
3336 (const_string "1")))])
3337
3338 (define_insn "extendqihi2"
3339 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3340 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3341 ""
3342 {
3343 switch (get_attr_prefix_0f (insn))
3344 {
3345 case 0:
3346 return "{cbtw|cbw}";
3347 default:
3348 return "movs{bw|x}\t{%1,%0|%0, %1}";
3349 }
3350 }
3351 [(set_attr "type" "imovx")
3352 (set_attr "mode" "HI")
3353 (set (attr "prefix_0f")
3354 ;; movsx is short decodable while cwtl is vector decoded.
3355 (if_then_else (and (eq_attr "cpu" "!k6")
3356 (eq_attr "alternative" "0"))
3357 (const_string "0")
3358 (const_string "1")))
3359 (set (attr "modrm")
3360 (if_then_else (eq_attr "prefix_0f" "0")
3361 (const_string "0")
3362 (const_string "1")))])
3363
3364 (define_insn "extendqisi2"
3365 [(set (match_operand:SI 0 "register_operand" "=r")
3366 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3367 ""
3368 "movs{bl|x}\t{%1,%0|%0, %1}"
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")])
3371
3372 (define_insn "*extendqisi2_zext"
3373 [(set (match_operand:DI 0 "register_operand" "=r")
3374 (zero_extend:DI
3375 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3376 "TARGET_64BIT"
3377 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3378 [(set_attr "type" "imovx")
3379 (set_attr "mode" "SI")])
3380 \f
3381 ;; Conversions between float and double.
3382
3383 ;; These are all no-ops in the model used for the 80387. So just
3384 ;; emit moves.
3385
3386 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3387 (define_insn "*dummy_extendsfdf2"
3388 [(set (match_operand:DF 0 "push_operand" "=<")
3389 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3390 "0"
3391 "#")
3392
3393 (define_split
3394 [(set (match_operand:DF 0 "push_operand" "")
3395 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3396 "!TARGET_64BIT"
3397 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3398 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3399
3400 (define_split
3401 [(set (match_operand:DF 0 "push_operand" "")
3402 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3403 "TARGET_64BIT"
3404 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3405 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3406
3407 (define_insn "*dummy_extendsfxf2"
3408 [(set (match_operand:XF 0 "push_operand" "=<")
3409 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3410 "0"
3411 "#")
3412
3413 (define_split
3414 [(set (match_operand:XF 0 "push_operand" "")
3415 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3416 ""
3417 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3418 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3419 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3420
3421 (define_split
3422 [(set (match_operand:XF 0 "push_operand" "")
3423 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3424 "TARGET_64BIT"
3425 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3426 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3427 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3428
3429 (define_split
3430 [(set (match_operand:XF 0 "push_operand" "")
3431 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3432 ""
3433 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3434 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3435 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3436
3437 (define_split
3438 [(set (match_operand:XF 0 "push_operand" "")
3439 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3440 "TARGET_64BIT"
3441 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3442 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3443 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3444
3445 (define_expand "extendsfdf2"
3446 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3447 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3448 "TARGET_80387 || TARGET_SSE2"
3449 {
3450 /* ??? Needed for compress_float_constant since all fp constants
3451 are LEGITIMATE_CONSTANT_P. */
3452 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3453 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3454 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3455 operands[1] = force_reg (SFmode, operands[1]);
3456 })
3457
3458 (define_insn "*extendsfdf2_1"
3459 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3460 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3461 "(TARGET_80387 || TARGET_SSE2)
3462 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3463 {
3464 switch (which_alternative)
3465 {
3466 case 0:
3467 return output_387_reg_move (insn, operands);
3468
3469 case 1:
3470 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3471 return "fstp%z0\t%y0";
3472 else
3473 return "fst%z0\t%y0";
3474
3475 case 2:
3476 return "cvtss2sd\t{%1, %0|%0, %1}";
3477
3478 default:
3479 abort ();
3480 }
3481 }
3482 [(set_attr "type" "fmov,fmov,ssecvt")
3483 (set_attr "mode" "SF,XF,DF")])
3484
3485 (define_insn "*extendsfdf2_1_sse_only"
3486 [(set (match_operand:DF 0 "register_operand" "=Y")
3487 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3488 "!TARGET_80387 && TARGET_SSE2
3489 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3490 "cvtss2sd\t{%1, %0|%0, %1}"
3491 [(set_attr "type" "ssecvt")
3492 (set_attr "mode" "DF")])
3493
3494 (define_expand "extendsfxf2"
3495 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3496 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3497 "TARGET_80387"
3498 {
3499 /* ??? Needed for compress_float_constant since all fp constants
3500 are LEGITIMATE_CONSTANT_P. */
3501 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3502 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3503 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3504 operands[1] = force_reg (SFmode, operands[1]);
3505 })
3506
3507 (define_insn "*extendsfxf2_1"
3508 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3509 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3510 "TARGET_80387
3511 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3512 {
3513 switch (which_alternative)
3514 {
3515 case 0:
3516 return output_387_reg_move (insn, operands);
3517
3518 case 1:
3519 /* There is no non-popping store to memory for XFmode. So if
3520 we need one, follow the store with a load. */
3521 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3522 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3523 else
3524 return "fstp%z0\t%y0";
3525
3526 default:
3527 abort ();
3528 }
3529 }
3530 [(set_attr "type" "fmov")
3531 (set_attr "mode" "SF,XF")])
3532
3533 (define_expand "extenddfxf2"
3534 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3535 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3536 "TARGET_80387"
3537 {
3538 /* ??? Needed for compress_float_constant since all fp constants
3539 are LEGITIMATE_CONSTANT_P. */
3540 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3541 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3542 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3543 operands[1] = force_reg (DFmode, operands[1]);
3544 })
3545
3546 (define_insn "*extenddfxf2_1"
3547 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3548 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3549 "TARGET_80387
3550 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3551 {
3552 switch (which_alternative)
3553 {
3554 case 0:
3555 return output_387_reg_move (insn, operands);
3556
3557 case 1:
3558 /* There is no non-popping store to memory for XFmode. So if
3559 we need one, follow the store with a load. */
3560 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3561 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3562 else
3563 return "fstp%z0\t%y0";
3564
3565 default:
3566 abort ();
3567 }
3568 }
3569 [(set_attr "type" "fmov")
3570 (set_attr "mode" "DF,XF")])
3571
3572 ;; %%% This seems bad bad news.
3573 ;; This cannot output into an f-reg because there is no way to be sure
3574 ;; of truncating in that case. Otherwise this is just like a simple move
3575 ;; insn. So we pretend we can output to a reg in order to get better
3576 ;; register preferencing, but we really use a stack slot.
3577
3578 (define_expand "truncdfsf2"
3579 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3580 (float_truncate:SF
3581 (match_operand:DF 1 "register_operand" "")))
3582 (clobber (match_dup 2))])]
3583 "TARGET_80387 || TARGET_SSE2"
3584 "
3585 if (!TARGET_80387)
3586 {
3587 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3588 DONE;
3589 }
3590 else if (flag_unsafe_math_optimizations)
3591 {
3592 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3593 emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3594 if (reg != operands[0])
3595 emit_move_insn (operands[0], reg);
3596 DONE;
3597 }
3598 else
3599 operands[2] = assign_386_stack_local (SFmode, 0);
3600 ")
3601
3602 (define_insn "truncdfsf2_noop"
3603 [(set (match_operand:SF 0 "register_operand" "=f")
3604 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3605 "TARGET_80387 && flag_unsafe_math_optimizations"
3606 {
3607 return output_387_reg_move (insn, operands);
3608 }
3609 [(set_attr "type" "fmov")
3610 (set_attr "mode" "SF")])
3611
3612 (define_insn "*truncdfsf2_1"
3613 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3614 (float_truncate:SF
3615 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3616 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3617 "TARGET_80387 && !TARGET_SSE2"
3618 {
3619 switch (which_alternative)
3620 {
3621 case 0:
3622 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3623 return "fstp%z0\t%y0";
3624 else
3625 return "fst%z0\t%y0";
3626 default:
3627 abort ();
3628 }
3629 }
3630 [(set_attr "type" "fmov,multi,multi,multi")
3631 (set_attr "mode" "SF,SF,SF,SF")])
3632
3633 (define_insn "*truncdfsf2_1_sse"
3634 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3635 (float_truncate:SF
3636 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3637 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3638 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3639 {
3640 switch (which_alternative)
3641 {
3642 case 0:
3643 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3644 return "fstp%z0\t%y0";
3645 else
3646 return "fst%z0\t%y0";
3647 case 4:
3648 return "#";
3649 default:
3650 abort ();
3651 }
3652 }
3653 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3654 (set_attr "mode" "SF,SF,SF,SF,DF")])
3655
3656 (define_insn "*truncdfsf2_1_sse_nooverlap"
3657 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3658 (float_truncate:SF
3659 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3660 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3661 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3662 {
3663 switch (which_alternative)
3664 {
3665 case 0:
3666 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3667 return "fstp%z0\t%y0";
3668 else
3669 return "fst%z0\t%y0";
3670 case 4:
3671 return "#";
3672 default:
3673 abort ();
3674 }
3675 }
3676 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3677 (set_attr "mode" "SF,SF,SF,SF,DF")])
3678
3679 (define_insn "*truncdfsf2_2"
3680 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3681 (float_truncate:SF
3682 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3683 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3684 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3685 {
3686 switch (which_alternative)
3687 {
3688 case 0:
3689 case 1:
3690 return "cvtsd2ss\t{%1, %0|%0, %1}";
3691 case 2:
3692 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3693 return "fstp%z0\t%y0";
3694 else
3695 return "fst%z0\t%y0";
3696 default:
3697 abort ();
3698 }
3699 }
3700 [(set_attr "type" "ssecvt,ssecvt,fmov")
3701 (set_attr "athlon_decode" "vector,double,*")
3702 (set_attr "mode" "SF,SF,SF")])
3703
3704 (define_insn "*truncdfsf2_2_nooverlap"
3705 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3706 (float_truncate:SF
3707 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3708 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3709 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3710 {
3711 switch (which_alternative)
3712 {
3713 case 0:
3714 return "#";
3715 case 1:
3716 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3717 return "fstp%z0\t%y0";
3718 else
3719 return "fst%z0\t%y0";
3720 default:
3721 abort ();
3722 }
3723 }
3724 [(set_attr "type" "ssecvt,fmov")
3725 (set_attr "mode" "DF,SF")])
3726
3727 (define_insn "*truncdfsf2_3"
3728 [(set (match_operand:SF 0 "memory_operand" "=m")
3729 (float_truncate:SF
3730 (match_operand:DF 1 "register_operand" "f")))]
3731 "TARGET_80387"
3732 {
3733 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3734 return "fstp%z0\t%y0";
3735 else
3736 return "fst%z0\t%y0";
3737 }
3738 [(set_attr "type" "fmov")
3739 (set_attr "mode" "SF")])
3740
3741 (define_insn "truncdfsf2_sse_only"
3742 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3743 (float_truncate:SF
3744 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3745 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3746 "cvtsd2ss\t{%1, %0|%0, %1}"
3747 [(set_attr "type" "ssecvt")
3748 (set_attr "athlon_decode" "vector,double")
3749 (set_attr "mode" "SF")])
3750
3751 (define_insn "*truncdfsf2_sse_only_nooverlap"
3752 [(set (match_operand:SF 0 "register_operand" "=&Y")
3753 (float_truncate:SF
3754 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3755 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3756 "#"
3757 [(set_attr "type" "ssecvt")
3758 (set_attr "mode" "DF")])
3759
3760 (define_split
3761 [(set (match_operand:SF 0 "memory_operand" "")
3762 (float_truncate:SF
3763 (match_operand:DF 1 "register_operand" "")))
3764 (clobber (match_operand:SF 2 "memory_operand" ""))]
3765 "TARGET_80387"
3766 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3767 "")
3768
3769 ; Avoid possible reformatting penalty on the destination by first
3770 ; zeroing it out
3771 (define_split
3772 [(set (match_operand:SF 0 "register_operand" "")
3773 (float_truncate:SF
3774 (match_operand:DF 1 "nonimmediate_operand" "")))
3775 (clobber (match_operand 2 "" ""))]
3776 "TARGET_80387 && reload_completed
3777 && SSE_REG_P (operands[0])
3778 && !STACK_REG_P (operands[1])"
3779 [(const_int 0)]
3780 {
3781 rtx src, dest;
3782 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3783 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3784 else
3785 {
3786 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3787 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3788 /* simplify_gen_subreg refuses to widen memory references. */
3789 if (GET_CODE (src) == SUBREG)
3790 alter_subreg (&src);
3791 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3792 abort ();
3793 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3794 emit_insn (gen_cvtsd2ss (dest, dest, src));
3795 }
3796 DONE;
3797 })
3798
3799 (define_split
3800 [(set (match_operand:SF 0 "register_operand" "")
3801 (float_truncate:SF
3802 (match_operand:DF 1 "nonimmediate_operand" "")))]
3803 "TARGET_80387 && reload_completed
3804 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3805 [(const_int 0)]
3806 {
3807 rtx src, dest;
3808 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3809 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3810 /* simplify_gen_subreg refuses to widen memory references. */
3811 if (GET_CODE (src) == SUBREG)
3812 alter_subreg (&src);
3813 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3814 abort ();
3815 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3816 emit_insn (gen_cvtsd2ss (dest, dest, src));
3817 DONE;
3818 })
3819
3820 (define_split
3821 [(set (match_operand:SF 0 "register_operand" "")
3822 (float_truncate:SF
3823 (match_operand:DF 1 "fp_register_operand" "")))
3824 (clobber (match_operand:SF 2 "memory_operand" ""))]
3825 "TARGET_80387 && reload_completed"
3826 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3827 (set (match_dup 0) (match_dup 2))]
3828 "")
3829
3830 (define_expand "truncxfsf2"
3831 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3832 (float_truncate:SF
3833 (match_operand:XF 1 "register_operand" "")))
3834 (clobber (match_dup 2))])]
3835 "TARGET_80387"
3836 "
3837 if (flag_unsafe_math_optimizations)
3838 {
3839 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3840 emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3841 if (reg != operands[0])
3842 emit_move_insn (operands[0], reg);
3843 DONE;
3844 }
3845 else
3846 operands[2] = assign_386_stack_local (SFmode, 0);
3847 ")
3848
3849 (define_insn "truncxfsf2_noop"
3850 [(set (match_operand:SF 0 "register_operand" "=f")
3851 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3852 "TARGET_80387 && flag_unsafe_math_optimizations"
3853 {
3854 return output_387_reg_move (insn, operands);
3855 }
3856 [(set_attr "type" "fmov")
3857 (set_attr "mode" "SF")])
3858
3859 (define_insn "*truncxfsf2_1"
3860 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3861 (float_truncate:SF
3862 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3863 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3864 "TARGET_80387"
3865 {
3866 switch (which_alternative)
3867 {
3868 case 0:
3869 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3870 return "fstp%z0\t%y0";
3871 else
3872 return "fst%z0\t%y0";
3873 default:
3874 abort();
3875 }
3876 }
3877 [(set_attr "type" "fmov,multi,multi,multi")
3878 (set_attr "mode" "SF")])
3879
3880 (define_insn "*truncxfsf2_2"
3881 [(set (match_operand:SF 0 "memory_operand" "=m")
3882 (float_truncate:SF
3883 (match_operand:XF 1 "register_operand" "f")))]
3884 "TARGET_80387"
3885 {
3886 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3887 return "fstp%z0\t%y0";
3888 else
3889 return "fst%z0\t%y0";
3890 }
3891 [(set_attr "type" "fmov")
3892 (set_attr "mode" "SF")])
3893
3894 (define_split
3895 [(set (match_operand:SF 0 "memory_operand" "")
3896 (float_truncate:SF
3897 (match_operand:XF 1 "register_operand" "")))
3898 (clobber (match_operand:SF 2 "memory_operand" ""))]
3899 "TARGET_80387"
3900 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3901 "")
3902
3903 (define_split
3904 [(set (match_operand:SF 0 "register_operand" "")
3905 (float_truncate:SF
3906 (match_operand:XF 1 "register_operand" "")))
3907 (clobber (match_operand:SF 2 "memory_operand" ""))]
3908 "TARGET_80387 && reload_completed"
3909 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3910 (set (match_dup 0) (match_dup 2))]
3911 "")
3912
3913 (define_expand "truncxfdf2"
3914 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3915 (float_truncate:DF
3916 (match_operand:XF 1 "register_operand" "")))
3917 (clobber (match_dup 2))])]
3918 "TARGET_80387"
3919 "
3920 if (flag_unsafe_math_optimizations)
3921 {
3922 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3923 emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3924 if (reg != operands[0])
3925 emit_move_insn (operands[0], reg);
3926 DONE;
3927 }
3928 else
3929 operands[2] = assign_386_stack_local (DFmode, 0);
3930 ")
3931
3932 (define_insn "truncxfdf2_noop"
3933 [(set (match_operand:DF 0 "register_operand" "=f")
3934 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3935 "TARGET_80387 && flag_unsafe_math_optimizations"
3936 {
3937 return output_387_reg_move (insn, operands);
3938 }
3939 [(set_attr "type" "fmov")
3940 (set_attr "mode" "DF")])
3941
3942 (define_insn "*truncxfdf2_1"
3943 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3944 (float_truncate:DF
3945 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3946 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3947 "TARGET_80387"
3948 {
3949 switch (which_alternative)
3950 {
3951 case 0:
3952 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3953 return "fstp%z0\t%y0";
3954 else
3955 return "fst%z0\t%y0";
3956 default:
3957 abort();
3958 }
3959 abort ();
3960 }
3961 [(set_attr "type" "fmov,multi,multi,multi")
3962 (set_attr "mode" "DF")])
3963
3964 (define_insn "*truncxfdf2_2"
3965 [(set (match_operand:DF 0 "memory_operand" "=m")
3966 (float_truncate:DF
3967 (match_operand:XF 1 "register_operand" "f")))]
3968 "TARGET_80387"
3969 {
3970 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3971 return "fstp%z0\t%y0";
3972 else
3973 return "fst%z0\t%y0";
3974 }
3975 [(set_attr "type" "fmov")
3976 (set_attr "mode" "DF")])
3977
3978 (define_split
3979 [(set (match_operand:DF 0 "memory_operand" "")
3980 (float_truncate:DF
3981 (match_operand:XF 1 "register_operand" "")))
3982 (clobber (match_operand:DF 2 "memory_operand" ""))]
3983 "TARGET_80387"
3984 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3985 "")
3986
3987 (define_split
3988 [(set (match_operand:DF 0 "register_operand" "")
3989 (float_truncate:DF
3990 (match_operand:XF 1 "register_operand" "")))
3991 (clobber (match_operand:DF 2 "memory_operand" ""))]
3992 "TARGET_80387 && reload_completed"
3993 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3994 (set (match_dup 0) (match_dup 2))]
3995 "")
3996
3997 \f
3998 ;; %%% Break up all these bad boys.
3999
4000 ;; Signed conversion to DImode.
4001
4002 (define_expand "fix_truncxfdi2"
4003 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4004 (fix:DI (match_operand:XF 1 "register_operand" "")))
4005 (clobber (reg:CC 17))])]
4006 "TARGET_80387"
4007 "")
4008
4009 (define_expand "fix_truncdfdi2"
4010 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4011 (fix:DI (match_operand:DF 1 "register_operand" "")))
4012 (clobber (reg:CC 17))])]
4013 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4014 {
4015 if (TARGET_64BIT && TARGET_SSE2)
4016 {
4017 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4018 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4019 if (out != operands[0])
4020 emit_move_insn (operands[0], out);
4021 DONE;
4022 }
4023 })
4024
4025 (define_expand "fix_truncsfdi2"
4026 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4027 (fix:DI (match_operand:SF 1 "register_operand" "")))
4028 (clobber (reg:CC 17))])]
4029 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4030 {
4031 if (TARGET_SSE && TARGET_64BIT)
4032 {
4033 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4034 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4035 if (out != operands[0])
4036 emit_move_insn (operands[0], out);
4037 DONE;
4038 }
4039 })
4040
4041 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4042 ;; of the machinery.
4043 (define_insn_and_split "*fix_truncdi_1"
4044 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4045 (fix:DI (match_operand 1 "register_operand" "f,f")))
4046 (clobber (reg:CC 17))]
4047 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4048 && !reload_completed && !reload_in_progress
4049 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4050 "#"
4051 "&& 1"
4052 [(const_int 0)]
4053 {
4054 ix86_optimize_mode_switching = 1;
4055 operands[2] = assign_386_stack_local (HImode, 1);
4056 operands[3] = assign_386_stack_local (HImode, 2);
4057 if (memory_operand (operands[0], VOIDmode))
4058 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4059 operands[2], operands[3]));
4060 else
4061 {
4062 operands[4] = assign_386_stack_local (DImode, 0);
4063 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4064 operands[2], operands[3],
4065 operands[4]));
4066 }
4067 DONE;
4068 }
4069 [(set_attr "type" "fistp")
4070 (set_attr "mode" "DI")])
4071
4072 (define_insn "fix_truncdi_nomemory"
4073 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4074 (fix:DI (match_operand 1 "register_operand" "f,f")))
4075 (use (match_operand:HI 2 "memory_operand" "m,m"))
4076 (use (match_operand:HI 3 "memory_operand" "m,m"))
4077 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4078 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4079 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4080 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4081 "#"
4082 [(set_attr "type" "fistp")
4083 (set_attr "mode" "DI")])
4084
4085 (define_insn "fix_truncdi_memory"
4086 [(set (match_operand:DI 0 "memory_operand" "=m")
4087 (fix:DI (match_operand 1 "register_operand" "f")))
4088 (use (match_operand:HI 2 "memory_operand" "m"))
4089 (use (match_operand:HI 3 "memory_operand" "m"))
4090 (clobber (match_scratch:DF 4 "=&1f"))]
4091 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4092 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4093 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4094 [(set_attr "type" "fistp")
4095 (set_attr "mode" "DI")])
4096
4097 (define_split
4098 [(set (match_operand:DI 0 "register_operand" "")
4099 (fix:DI (match_operand 1 "register_operand" "")))
4100 (use (match_operand:HI 2 "memory_operand" ""))
4101 (use (match_operand:HI 3 "memory_operand" ""))
4102 (clobber (match_operand:DI 4 "memory_operand" ""))
4103 (clobber (match_scratch 5 ""))]
4104 "reload_completed"
4105 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4106 (use (match_dup 2))
4107 (use (match_dup 3))
4108 (clobber (match_dup 5))])
4109 (set (match_dup 0) (match_dup 4))]
4110 "")
4111
4112 (define_split
4113 [(set (match_operand:DI 0 "memory_operand" "")
4114 (fix:DI (match_operand 1 "register_operand" "")))
4115 (use (match_operand:HI 2 "memory_operand" ""))
4116 (use (match_operand:HI 3 "memory_operand" ""))
4117 (clobber (match_operand:DI 4 "memory_operand" ""))
4118 (clobber (match_scratch 5 ""))]
4119 "reload_completed"
4120 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4121 (use (match_dup 2))
4122 (use (match_dup 3))
4123 (clobber (match_dup 5))])]
4124 "")
4125
4126 ;; When SSE available, it is always faster to use it!
4127 (define_insn "fix_truncsfdi_sse"
4128 [(set (match_operand:DI 0 "register_operand" "=r,r")
4129 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4130 "TARGET_64BIT && TARGET_SSE"
4131 "cvttss2si{q}\t{%1, %0|%0, %1}"
4132 [(set_attr "type" "sseicvt")
4133 (set_attr "mode" "SF")
4134 (set_attr "athlon_decode" "double,vector")])
4135
4136 ;; Avoid vector decoded form of the instruction.
4137 (define_peephole2
4138 [(match_scratch:SF 2 "x")
4139 (set (match_operand:DI 0 "register_operand" "")
4140 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4141 "TARGET_K8 && !optimize_size"
4142 [(set (match_dup 2) (match_dup 1))
4143 (set (match_dup 0) (fix:DI (match_dup 2)))]
4144 "")
4145
4146 (define_insn "fix_truncdfdi_sse"
4147 [(set (match_operand:DI 0 "register_operand" "=r,r")
4148 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4149 "TARGET_64BIT && TARGET_SSE2"
4150 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4151 [(set_attr "type" "sseicvt,sseicvt")
4152 (set_attr "mode" "DF")
4153 (set_attr "athlon_decode" "double,vector")])
4154
4155 ;; Avoid vector decoded form of the instruction.
4156 (define_peephole2
4157 [(match_scratch:DF 2 "Y")
4158 (set (match_operand:DI 0 "register_operand" "")
4159 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4160 "TARGET_K8 && !optimize_size"
4161 [(set (match_dup 2) (match_dup 1))
4162 (set (match_dup 0) (fix:DI (match_dup 2)))]
4163 "")
4164
4165 ;; Signed conversion to SImode.
4166
4167 (define_expand "fix_truncxfsi2"
4168 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4169 (fix:SI (match_operand:XF 1 "register_operand" "")))
4170 (clobber (reg:CC 17))])]
4171 "TARGET_80387"
4172 "")
4173
4174 (define_expand "fix_truncdfsi2"
4175 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4176 (fix:SI (match_operand:DF 1 "register_operand" "")))
4177 (clobber (reg:CC 17))])]
4178 "TARGET_80387 || TARGET_SSE2"
4179 {
4180 if (TARGET_SSE2)
4181 {
4182 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4183 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4184 if (out != operands[0])
4185 emit_move_insn (operands[0], out);
4186 DONE;
4187 }
4188 })
4189
4190 (define_expand "fix_truncsfsi2"
4191 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4192 (fix:SI (match_operand:SF 1 "register_operand" "")))
4193 (clobber (reg:CC 17))])]
4194 "TARGET_80387 || TARGET_SSE"
4195 {
4196 if (TARGET_SSE)
4197 {
4198 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4199 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4200 if (out != operands[0])
4201 emit_move_insn (operands[0], out);
4202 DONE;
4203 }
4204 })
4205
4206 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4207 ;; of the machinery.
4208 (define_insn_and_split "*fix_truncsi_1"
4209 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4210 (fix:SI (match_operand 1 "register_operand" "f,f")))
4211 (clobber (reg:CC 17))]
4212 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4213 && !reload_completed && !reload_in_progress
4214 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4215 "#"
4216 "&& 1"
4217 [(const_int 0)]
4218 {
4219 ix86_optimize_mode_switching = 1;
4220 operands[2] = assign_386_stack_local (HImode, 1);
4221 operands[3] = assign_386_stack_local (HImode, 2);
4222 if (memory_operand (operands[0], VOIDmode))
4223 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4224 operands[2], operands[3]));
4225 else
4226 {
4227 operands[4] = assign_386_stack_local (SImode, 0);
4228 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4229 operands[2], operands[3],
4230 operands[4]));
4231 }
4232 DONE;
4233 }
4234 [(set_attr "type" "fistp")
4235 (set_attr "mode" "SI")])
4236
4237 (define_insn "fix_truncsi_nomemory"
4238 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4239 (fix:SI (match_operand 1 "register_operand" "f,f")))
4240 (use (match_operand:HI 2 "memory_operand" "m,m"))
4241 (use (match_operand:HI 3 "memory_operand" "m,m"))
4242 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4243 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4244 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4245 "#"
4246 [(set_attr "type" "fistp")
4247 (set_attr "mode" "SI")])
4248
4249 (define_insn "fix_truncsi_memory"
4250 [(set (match_operand:SI 0 "memory_operand" "=m")
4251 (fix:SI (match_operand 1 "register_operand" "f")))
4252 (use (match_operand:HI 2 "memory_operand" "m"))
4253 (use (match_operand:HI 3 "memory_operand" "m"))]
4254 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4255 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4256 "* return output_fix_trunc (insn, operands);"
4257 [(set_attr "type" "fistp")
4258 (set_attr "mode" "SI")])
4259
4260 ;; When SSE available, it is always faster to use it!
4261 (define_insn "fix_truncsfsi_sse"
4262 [(set (match_operand:SI 0 "register_operand" "=r,r")
4263 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4264 "TARGET_SSE"
4265 "cvttss2si\t{%1, %0|%0, %1}"
4266 [(set_attr "type" "sseicvt")
4267 (set_attr "mode" "DF")
4268 (set_attr "athlon_decode" "double,vector")])
4269
4270 ;; Avoid vector decoded form of the instruction.
4271 (define_peephole2
4272 [(match_scratch:SF 2 "x")
4273 (set (match_operand:SI 0 "register_operand" "")
4274 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4275 "TARGET_K8 && !optimize_size"
4276 [(set (match_dup 2) (match_dup 1))
4277 (set (match_dup 0) (fix:SI (match_dup 2)))]
4278 "")
4279
4280 (define_insn "fix_truncdfsi_sse"
4281 [(set (match_operand:SI 0 "register_operand" "=r,r")
4282 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4283 "TARGET_SSE2"
4284 "cvttsd2si\t{%1, %0|%0, %1}"
4285 [(set_attr "type" "sseicvt")
4286 (set_attr "mode" "DF")
4287 (set_attr "athlon_decode" "double,vector")])
4288
4289 ;; Avoid vector decoded form of the instruction.
4290 (define_peephole2
4291 [(match_scratch:DF 2 "Y")
4292 (set (match_operand:SI 0 "register_operand" "")
4293 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4294 "TARGET_K8 && !optimize_size"
4295 [(set (match_dup 2) (match_dup 1))
4296 (set (match_dup 0) (fix:SI (match_dup 2)))]
4297 "")
4298
4299 (define_split
4300 [(set (match_operand:SI 0 "register_operand" "")
4301 (fix:SI (match_operand 1 "register_operand" "")))
4302 (use (match_operand:HI 2 "memory_operand" ""))
4303 (use (match_operand:HI 3 "memory_operand" ""))
4304 (clobber (match_operand:SI 4 "memory_operand" ""))]
4305 "reload_completed"
4306 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4307 (use (match_dup 2))
4308 (use (match_dup 3))])
4309 (set (match_dup 0) (match_dup 4))]
4310 "")
4311
4312 (define_split
4313 [(set (match_operand:SI 0 "memory_operand" "")
4314 (fix:SI (match_operand 1 "register_operand" "")))
4315 (use (match_operand:HI 2 "memory_operand" ""))
4316 (use (match_operand:HI 3 "memory_operand" ""))
4317 (clobber (match_operand:SI 4 "memory_operand" ""))]
4318 "reload_completed"
4319 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4320 (use (match_dup 2))
4321 (use (match_dup 3))])]
4322 "")
4323
4324 ;; Signed conversion to HImode.
4325
4326 (define_expand "fix_truncxfhi2"
4327 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4328 (fix:HI (match_operand:XF 1 "register_operand" "")))
4329 (clobber (reg:CC 17))])]
4330 "TARGET_80387"
4331 "")
4332
4333 (define_expand "fix_truncdfhi2"
4334 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335 (fix:HI (match_operand:DF 1 "register_operand" "")))
4336 (clobber (reg:CC 17))])]
4337 "TARGET_80387 && !TARGET_SSE2"
4338 "")
4339
4340 (define_expand "fix_truncsfhi2"
4341 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4342 (fix:HI (match_operand:SF 1 "register_operand" "")))
4343 (clobber (reg:CC 17))])]
4344 "TARGET_80387 && !TARGET_SSE"
4345 "")
4346
4347 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4348 ;; of the machinery.
4349 (define_insn_and_split "*fix_trunchi_1"
4350 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4351 (fix:HI (match_operand 1 "register_operand" "f,f")))
4352 (clobber (reg:CC 17))]
4353 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4354 && !reload_completed && !reload_in_progress
4355 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4356 "#"
4357 ""
4358 [(const_int 0)]
4359 {
4360 ix86_optimize_mode_switching = 1;
4361 operands[2] = assign_386_stack_local (HImode, 1);
4362 operands[3] = assign_386_stack_local (HImode, 2);
4363 if (memory_operand (operands[0], VOIDmode))
4364 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4365 operands[2], operands[3]));
4366 else
4367 {
4368 operands[4] = assign_386_stack_local (HImode, 0);
4369 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4370 operands[2], operands[3],
4371 operands[4]));
4372 }
4373 DONE;
4374 }
4375 [(set_attr "type" "fistp")
4376 (set_attr "mode" "HI")])
4377
4378 (define_insn "fix_trunchi_nomemory"
4379 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4380 (fix:HI (match_operand 1 "register_operand" "f,f")))
4381 (use (match_operand:HI 2 "memory_operand" "m,m"))
4382 (use (match_operand:HI 3 "memory_operand" "m,m"))
4383 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4384 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4385 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4386 "#"
4387 [(set_attr "type" "fistp")
4388 (set_attr "mode" "HI")])
4389
4390 (define_insn "fix_trunchi_memory"
4391 [(set (match_operand:HI 0 "memory_operand" "=m")
4392 (fix:HI (match_operand 1 "register_operand" "f")))
4393 (use (match_operand:HI 2 "memory_operand" "m"))
4394 (use (match_operand:HI 3 "memory_operand" "m"))]
4395 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4396 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4397 "* return output_fix_trunc (insn, operands);"
4398 [(set_attr "type" "fistp")
4399 (set_attr "mode" "HI")])
4400
4401 (define_split
4402 [(set (match_operand:HI 0 "memory_operand" "")
4403 (fix:HI (match_operand 1 "register_operand" "")))
4404 (use (match_operand:HI 2 "memory_operand" ""))
4405 (use (match_operand:HI 3 "memory_operand" ""))
4406 (clobber (match_operand:HI 4 "memory_operand" ""))]
4407 "reload_completed"
4408 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4409 (use (match_dup 2))
4410 (use (match_dup 3))])]
4411 "")
4412
4413 (define_split
4414 [(set (match_operand:HI 0 "register_operand" "")
4415 (fix:HI (match_operand 1 "register_operand" "")))
4416 (use (match_operand:HI 2 "memory_operand" ""))
4417 (use (match_operand:HI 3 "memory_operand" ""))
4418 (clobber (match_operand:HI 4 "memory_operand" ""))]
4419 "reload_completed"
4420 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4421 (use (match_dup 2))
4422 (use (match_dup 3))
4423 (clobber (match_dup 4))])
4424 (set (match_dup 0) (match_dup 4))]
4425 "")
4426
4427 ;; %% Not used yet.
4428 (define_insn "x86_fnstcw_1"
4429 [(set (match_operand:HI 0 "memory_operand" "=m")
4430 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4431 "TARGET_80387"
4432 "fnstcw\t%0"
4433 [(set_attr "length" "2")
4434 (set_attr "mode" "HI")
4435 (set_attr "unit" "i387")])
4436
4437 (define_insn "x86_fldcw_1"
4438 [(set (reg:HI 18)
4439 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4440 "TARGET_80387"
4441 "fldcw\t%0"
4442 [(set_attr "length" "2")
4443 (set_attr "mode" "HI")
4444 (set_attr "unit" "i387")
4445 (set_attr "athlon_decode" "vector")])
4446 \f
4447 ;; Conversion between fixed point and floating point.
4448
4449 ;; Even though we only accept memory inputs, the backend _really_
4450 ;; wants to be able to do this between registers.
4451
4452 (define_expand "floathisf2"
4453 [(set (match_operand:SF 0 "register_operand" "")
4454 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4455 "TARGET_SSE || TARGET_80387"
4456 {
4457 if (TARGET_SSE && TARGET_SSE_MATH)
4458 {
4459 emit_insn (gen_floatsisf2 (operands[0],
4460 convert_to_mode (SImode, operands[1], 0)));
4461 DONE;
4462 }
4463 })
4464
4465 (define_insn "*floathisf2_1"
4466 [(set (match_operand:SF 0 "register_operand" "=f,f")
4467 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4468 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4469 "@
4470 fild%z1\t%1
4471 #"
4472 [(set_attr "type" "fmov,multi")
4473 (set_attr "mode" "SF")
4474 (set_attr "fp_int_src" "true")])
4475
4476 (define_expand "floatsisf2"
4477 [(set (match_operand:SF 0 "register_operand" "")
4478 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4479 "TARGET_SSE || TARGET_80387"
4480 "")
4481
4482 (define_insn "*floatsisf2_i387"
4483 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4484 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4485 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4486 "@
4487 fild%z1\t%1
4488 #
4489 cvtsi2ss\t{%1, %0|%0, %1}
4490 cvtsi2ss\t{%1, %0|%0, %1}"
4491 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4492 (set_attr "mode" "SF")
4493 (set_attr "athlon_decode" "*,*,vector,double")
4494 (set_attr "fp_int_src" "true")])
4495
4496 (define_insn "*floatsisf2_sse"
4497 [(set (match_operand:SF 0 "register_operand" "=x,x")
4498 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4499 "TARGET_SSE"
4500 "cvtsi2ss\t{%1, %0|%0, %1}"
4501 [(set_attr "type" "sseicvt")
4502 (set_attr "mode" "SF")
4503 (set_attr "athlon_decode" "vector,double")
4504 (set_attr "fp_int_src" "true")])
4505
4506 ; Avoid possible reformatting penalty on the destination by first
4507 ; zeroing it out
4508 (define_split
4509 [(set (match_operand:SF 0 "register_operand" "")
4510 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4511 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4512 && SSE_REG_P (operands[0])"
4513 [(const_int 0)]
4514 {
4515 rtx dest;
4516 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4517 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4518 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4519 DONE;
4520 })
4521
4522 (define_expand "floatdisf2"
4523 [(set (match_operand:SF 0 "register_operand" "")
4524 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4525 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4526 "")
4527
4528 (define_insn "*floatdisf2_i387_only"
4529 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4530 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4531 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4532 "@
4533 fild%z1\t%1
4534 #"
4535 [(set_attr "type" "fmov,multi")
4536 (set_attr "mode" "SF")
4537 (set_attr "fp_int_src" "true")])
4538
4539 (define_insn "*floatdisf2_i387"
4540 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4541 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4542 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4543 "@
4544 fild%z1\t%1
4545 #
4546 cvtsi2ss{q}\t{%1, %0|%0, %1}
4547 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4548 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4549 (set_attr "mode" "SF")
4550 (set_attr "athlon_decode" "*,*,vector,double")
4551 (set_attr "fp_int_src" "true")])
4552
4553 (define_insn "*floatdisf2_sse"
4554 [(set (match_operand:SF 0 "register_operand" "=x,x")
4555 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4556 "TARGET_64BIT && TARGET_SSE"
4557 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4558 [(set_attr "type" "sseicvt")
4559 (set_attr "mode" "SF")
4560 (set_attr "athlon_decode" "vector,double")
4561 (set_attr "fp_int_src" "true")])
4562
4563 ; Avoid possible reformatting penalty on the destination by first
4564 ; zeroing it out
4565 (define_split
4566 [(set (match_operand:SF 0 "register_operand" "")
4567 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4568 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4569 && SSE_REG_P (operands[0])"
4570 [(const_int 0)]
4571 {
4572 rtx dest;
4573 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4574 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4575 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4576 DONE;
4577 })
4578
4579 (define_expand "floathidf2"
4580 [(set (match_operand:DF 0 "register_operand" "")
4581 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4582 "TARGET_SSE2 || TARGET_80387"
4583 {
4584 if (TARGET_SSE && TARGET_SSE_MATH)
4585 {
4586 emit_insn (gen_floatsidf2 (operands[0],
4587 convert_to_mode (SImode, operands[1], 0)));
4588 DONE;
4589 }
4590 })
4591
4592 (define_insn "*floathidf2_1"
4593 [(set (match_operand:DF 0 "register_operand" "=f,f")
4594 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4595 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4596 "@
4597 fild%z1\t%1
4598 #"
4599 [(set_attr "type" "fmov,multi")
4600 (set_attr "mode" "DF")
4601 (set_attr "fp_int_src" "true")])
4602
4603 (define_expand "floatsidf2"
4604 [(set (match_operand:DF 0 "register_operand" "")
4605 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4606 "TARGET_80387 || TARGET_SSE2"
4607 "")
4608
4609 (define_insn "*floatsidf2_i387"
4610 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4611 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4612 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4613 "@
4614 fild%z1\t%1
4615 #
4616 cvtsi2sd\t{%1, %0|%0, %1}
4617 cvtsi2sd\t{%1, %0|%0, %1}"
4618 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4619 (set_attr "mode" "DF")
4620 (set_attr "athlon_decode" "*,*,double,direct")
4621 (set_attr "fp_int_src" "true")])
4622
4623 (define_insn "*floatsidf2_sse"
4624 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4625 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4626 "TARGET_SSE2"
4627 "cvtsi2sd\t{%1, %0|%0, %1}"
4628 [(set_attr "type" "sseicvt")
4629 (set_attr "mode" "DF")
4630 (set_attr "athlon_decode" "double,direct")
4631 (set_attr "fp_int_src" "true")])
4632
4633 (define_expand "floatdidf2"
4634 [(set (match_operand:DF 0 "register_operand" "")
4635 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4636 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4637 "")
4638
4639 (define_insn "*floatdidf2_i387_only"
4640 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4641 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4642 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4643 "@
4644 fild%z1\t%1
4645 #"
4646 [(set_attr "type" "fmov,multi")
4647 (set_attr "mode" "DF")
4648 (set_attr "fp_int_src" "true")])
4649
4650 (define_insn "*floatdidf2_i387"
4651 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4652 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4653 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4654 "@
4655 fild%z1\t%1
4656 #
4657 cvtsi2sd{q}\t{%1, %0|%0, %1}
4658 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4659 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4660 (set_attr "mode" "DF")
4661 (set_attr "athlon_decode" "*,*,double,direct")
4662 (set_attr "fp_int_src" "true")])
4663
4664 (define_insn "*floatdidf2_sse"
4665 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4666 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4667 "TARGET_SSE2"
4668 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4669 [(set_attr "type" "sseicvt")
4670 (set_attr "mode" "DF")
4671 (set_attr "athlon_decode" "double,direct")
4672 (set_attr "fp_int_src" "true")])
4673
4674 (define_insn "floathixf2"
4675 [(set (match_operand:XF 0 "register_operand" "=f,f")
4676 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4677 "TARGET_80387"
4678 "@
4679 fild%z1\t%1
4680 #"
4681 [(set_attr "type" "fmov,multi")
4682 (set_attr "mode" "XF")
4683 (set_attr "fp_int_src" "true")])
4684
4685 (define_insn "floatsixf2"
4686 [(set (match_operand:XF 0 "register_operand" "=f,f")
4687 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4688 "TARGET_80387"
4689 "@
4690 fild%z1\t%1
4691 #"
4692 [(set_attr "type" "fmov,multi")
4693 (set_attr "mode" "XF")
4694 (set_attr "fp_int_src" "true")])
4695
4696 (define_insn "floatdixf2"
4697 [(set (match_operand:XF 0 "register_operand" "=f,f")
4698 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4699 "TARGET_80387"
4700 "@
4701 fild%z1\t%1
4702 #"
4703 [(set_attr "type" "fmov,multi")
4704 (set_attr "mode" "XF")
4705 (set_attr "fp_int_src" "true")])
4706
4707 ;; %%% Kill these when reload knows how to do it.
4708 (define_split
4709 [(set (match_operand 0 "fp_register_operand" "")
4710 (float (match_operand 1 "register_operand" "")))]
4711 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4712 [(const_int 0)]
4713 {
4714 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4715 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4716 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4717 ix86_free_from_memory (GET_MODE (operands[1]));
4718 DONE;
4719 })
4720
4721 (define_expand "floatunssisf2"
4722 [(use (match_operand:SF 0 "register_operand" ""))
4723 (use (match_operand:SI 1 "register_operand" ""))]
4724 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4725 "x86_emit_floatuns (operands); DONE;")
4726
4727 (define_expand "floatunsdisf2"
4728 [(use (match_operand:SF 0 "register_operand" ""))
4729 (use (match_operand:DI 1 "register_operand" ""))]
4730 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4731 "x86_emit_floatuns (operands); DONE;")
4732
4733 (define_expand "floatunsdidf2"
4734 [(use (match_operand:DF 0 "register_operand" ""))
4735 (use (match_operand:DI 1 "register_operand" ""))]
4736 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4737 "x86_emit_floatuns (operands); DONE;")
4738 \f
4739 ;; SSE extract/set expanders
4740
4741 (define_expand "vec_setv2df"
4742 [(match_operand:V2DF 0 "register_operand" "")
4743 (match_operand:DF 1 "register_operand" "")
4744 (match_operand 2 "const_int_operand" "")]
4745 "TARGET_SSE2"
4746 {
4747 switch (INTVAL (operands[2]))
4748 {
4749 case 0:
4750 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4751 simplify_gen_subreg (V2DFmode, operands[1],
4752 DFmode, 0)));
4753 break;
4754 case 1:
4755 {
4756 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4757
4758 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4759 }
4760 break;
4761 default:
4762 abort ();
4763 }
4764 DONE;
4765 })
4766
4767 (define_expand "vec_extractv2df"
4768 [(match_operand:DF 0 "register_operand" "")
4769 (match_operand:V2DF 1 "register_operand" "")
4770 (match_operand 2 "const_int_operand" "")]
4771 "TARGET_SSE2"
4772 {
4773 switch (INTVAL (operands[2]))
4774 {
4775 case 0:
4776 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4777 break;
4778 case 1:
4779 {
4780 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4781
4782 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4783 }
4784 break;
4785 default:
4786 abort ();
4787 }
4788 DONE;
4789 })
4790
4791 (define_expand "vec_initv2df"
4792 [(match_operand:V2DF 0 "register_operand" "")
4793 (match_operand 1 "" "")]
4794 "TARGET_SSE2"
4795 {
4796 ix86_expand_vector_init (operands[0], operands[1]);
4797 DONE;
4798 })
4799
4800 (define_expand "vec_setv4sf"
4801 [(match_operand:V4SF 0 "register_operand" "")
4802 (match_operand:SF 1 "register_operand" "")
4803 (match_operand 2 "const_int_operand" "")]
4804 "TARGET_SSE"
4805 {
4806 switch (INTVAL (operands[2]))
4807 {
4808 case 0:
4809 emit_insn (gen_sse_movss (operands[0], operands[0],
4810 simplify_gen_subreg (V4SFmode, operands[1],
4811 SFmode, 0)));
4812 break;
4813 case 1:
4814 {
4815 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4816 rtx tmp = gen_reg_rtx (V4SFmode);
4817
4818 emit_move_insn (tmp, operands[0]);
4819 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4820 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4821 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4822 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4823 }
4824 case 2:
4825 {
4826 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4827 rtx tmp = gen_reg_rtx (V4SFmode);
4828
4829 emit_move_insn (tmp, operands[0]);
4830 emit_insn (gen_sse_movss (tmp, tmp, op1));
4831 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4832 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4833 }
4834 break;
4835 case 3:
4836 {
4837 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4838 rtx tmp = gen_reg_rtx (V4SFmode);
4839
4840 emit_move_insn (tmp, operands[0]);
4841 emit_insn (gen_sse_movss (tmp, tmp, op1));
4842 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4843 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4844 }
4845 break;
4846 default:
4847 abort ();
4848 }
4849 DONE;
4850 })
4851
4852 (define_expand "vec_extractv4sf"
4853 [(match_operand:SF 0 "register_operand" "")
4854 (match_operand:V4SF 1 "register_operand" "")
4855 (match_operand 2 "const_int_operand" "")]
4856 "TARGET_SSE"
4857 {
4858 switch (INTVAL (operands[2]))
4859 {
4860 case 0:
4861 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4862 break;
4863 case 1:
4864 {
4865 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4866 rtx tmp = gen_reg_rtx (V4SFmode);
4867
4868 emit_move_insn (tmp, operands[1]);
4869 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4870 const1_rtx));
4871 }
4872 case 2:
4873 {
4874 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4875 rtx tmp = gen_reg_rtx (V4SFmode);
4876
4877 emit_move_insn (tmp, operands[1]);
4878 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4879 }
4880 case 3:
4881 {
4882 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4883 rtx tmp = gen_reg_rtx (V4SFmode);
4884
4885 emit_move_insn (tmp, operands[1]);
4886 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4887 GEN_INT (3)));
4888 }
4889 default:
4890 abort ();
4891 }
4892 DONE;
4893 })
4894
4895 (define_expand "vec_initv4sf"
4896 [(match_operand:V4SF 0 "register_operand" "")
4897 (match_operand 1 "" "")]
4898 "TARGET_SSE"
4899 {
4900 ix86_expand_vector_init (operands[0], operands[1]);
4901 DONE;
4902 })
4903 \f
4904 ;; Add instructions
4905
4906 ;; %%% splits for addsidi3
4907 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4908 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4909 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4910
4911 (define_expand "adddi3"
4912 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4913 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4914 (match_operand:DI 2 "x86_64_general_operand" "")))
4915 (clobber (reg:CC 17))]
4916 ""
4917 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4918
4919 (define_insn "*adddi3_1"
4920 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4921 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4922 (match_operand:DI 2 "general_operand" "roiF,riF")))
4923 (clobber (reg:CC 17))]
4924 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4925 "#")
4926
4927 (define_split
4928 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4929 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4930 (match_operand:DI 2 "general_operand" "")))
4931 (clobber (reg:CC 17))]
4932 "!TARGET_64BIT && reload_completed"
4933 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4934 UNSPEC_ADD_CARRY))
4935 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4936 (parallel [(set (match_dup 3)
4937 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4938 (match_dup 4))
4939 (match_dup 5)))
4940 (clobber (reg:CC 17))])]
4941 "split_di (operands+0, 1, operands+0, operands+3);
4942 split_di (operands+1, 1, operands+1, operands+4);
4943 split_di (operands+2, 1, operands+2, operands+5);")
4944
4945 (define_insn "adddi3_carry_rex64"
4946 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4947 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4948 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4949 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4950 (clobber (reg:CC 17))]
4951 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4952 "adc{q}\t{%2, %0|%0, %2}"
4953 [(set_attr "type" "alu")
4954 (set_attr "pent_pair" "pu")
4955 (set_attr "mode" "DI")])
4956
4957 (define_insn "*adddi3_cc_rex64"
4958 [(set (reg:CC 17)
4959 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4960 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4961 UNSPEC_ADD_CARRY))
4962 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4963 (plus:DI (match_dup 1) (match_dup 2)))]
4964 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4965 "add{q}\t{%2, %0|%0, %2}"
4966 [(set_attr "type" "alu")
4967 (set_attr "mode" "DI")])
4968
4969 (define_insn "addqi3_carry"
4970 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4971 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4972 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4973 (match_operand:QI 2 "general_operand" "qi,qm")))
4974 (clobber (reg:CC 17))]
4975 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4976 "adc{b}\t{%2, %0|%0, %2}"
4977 [(set_attr "type" "alu")
4978 (set_attr "pent_pair" "pu")
4979 (set_attr "mode" "QI")])
4980
4981 (define_insn "addhi3_carry"
4982 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4983 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4984 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4985 (match_operand:HI 2 "general_operand" "ri,rm")))
4986 (clobber (reg:CC 17))]
4987 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4988 "adc{w}\t{%2, %0|%0, %2}"
4989 [(set_attr "type" "alu")
4990 (set_attr "pent_pair" "pu")
4991 (set_attr "mode" "HI")])
4992
4993 (define_insn "addsi3_carry"
4994 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4995 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4996 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4997 (match_operand:SI 2 "general_operand" "ri,rm")))
4998 (clobber (reg:CC 17))]
4999 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5000 "adc{l}\t{%2, %0|%0, %2}"
5001 [(set_attr "type" "alu")
5002 (set_attr "pent_pair" "pu")
5003 (set_attr "mode" "SI")])
5004
5005 (define_insn "*addsi3_carry_zext"
5006 [(set (match_operand:DI 0 "register_operand" "=r")
5007 (zero_extend:DI
5008 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5009 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5010 (match_operand:SI 2 "general_operand" "rim"))))
5011 (clobber (reg:CC 17))]
5012 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5013 "adc{l}\t{%2, %k0|%k0, %2}"
5014 [(set_attr "type" "alu")
5015 (set_attr "pent_pair" "pu")
5016 (set_attr "mode" "SI")])
5017
5018 (define_insn "*addsi3_cc"
5019 [(set (reg:CC 17)
5020 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5021 (match_operand:SI 2 "general_operand" "ri,rm")]
5022 UNSPEC_ADD_CARRY))
5023 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5024 (plus:SI (match_dup 1) (match_dup 2)))]
5025 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5026 "add{l}\t{%2, %0|%0, %2}"
5027 [(set_attr "type" "alu")
5028 (set_attr "mode" "SI")])
5029
5030 (define_insn "addqi3_cc"
5031 [(set (reg:CC 17)
5032 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5033 (match_operand:QI 2 "general_operand" "qi,qm")]
5034 UNSPEC_ADD_CARRY))
5035 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5036 (plus:QI (match_dup 1) (match_dup 2)))]
5037 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5038 "add{b}\t{%2, %0|%0, %2}"
5039 [(set_attr "type" "alu")
5040 (set_attr "mode" "QI")])
5041
5042 (define_expand "addsi3"
5043 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5044 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5045 (match_operand:SI 2 "general_operand" "")))
5046 (clobber (reg:CC 17))])]
5047 ""
5048 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5049
5050 (define_insn "*lea_1"
5051 [(set (match_operand:SI 0 "register_operand" "=r")
5052 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5053 "!TARGET_64BIT"
5054 "lea{l}\t{%a1, %0|%0, %a1}"
5055 [(set_attr "type" "lea")
5056 (set_attr "mode" "SI")])
5057
5058 (define_insn "*lea_1_rex64"
5059 [(set (match_operand:SI 0 "register_operand" "=r")
5060 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5061 "TARGET_64BIT"
5062 "lea{l}\t{%a1, %0|%0, %a1}"
5063 [(set_attr "type" "lea")
5064 (set_attr "mode" "SI")])
5065
5066 (define_insn "*lea_1_zext"
5067 [(set (match_operand:DI 0 "register_operand" "=r")
5068 (zero_extend:DI
5069 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5070 "TARGET_64BIT"
5071 "lea{l}\t{%a1, %k0|%k0, %a1}"
5072 [(set_attr "type" "lea")
5073 (set_attr "mode" "SI")])
5074
5075 (define_insn "*lea_2_rex64"
5076 [(set (match_operand:DI 0 "register_operand" "=r")
5077 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5078 "TARGET_64BIT"
5079 "lea{q}\t{%a1, %0|%0, %a1}"
5080 [(set_attr "type" "lea")
5081 (set_attr "mode" "DI")])
5082
5083 ;; The lea patterns for non-Pmodes needs to be matched by several
5084 ;; insns converted to real lea by splitters.
5085
5086 (define_insn_and_split "*lea_general_1"
5087 [(set (match_operand 0 "register_operand" "=r")
5088 (plus (plus (match_operand 1 "index_register_operand" "r")
5089 (match_operand 2 "register_operand" "r"))
5090 (match_operand 3 "immediate_operand" "i")))]
5091 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5092 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5093 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5094 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5095 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5096 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5097 || GET_MODE (operands[3]) == VOIDmode)"
5098 "#"
5099 "&& reload_completed"
5100 [(const_int 0)]
5101 {
5102 rtx pat;
5103 operands[0] = gen_lowpart (SImode, operands[0]);
5104 operands[1] = gen_lowpart (Pmode, operands[1]);
5105 operands[2] = gen_lowpart (Pmode, operands[2]);
5106 operands[3] = gen_lowpart (Pmode, operands[3]);
5107 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5108 operands[3]);
5109 if (Pmode != SImode)
5110 pat = gen_rtx_SUBREG (SImode, pat, 0);
5111 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5112 DONE;
5113 }
5114 [(set_attr "type" "lea")
5115 (set_attr "mode" "SI")])
5116
5117 (define_insn_and_split "*lea_general_1_zext"
5118 [(set (match_operand:DI 0 "register_operand" "=r")
5119 (zero_extend:DI
5120 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5121 (match_operand:SI 2 "register_operand" "r"))
5122 (match_operand:SI 3 "immediate_operand" "i"))))]
5123 "TARGET_64BIT"
5124 "#"
5125 "&& reload_completed"
5126 [(set (match_dup 0)
5127 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5128 (match_dup 2))
5129 (match_dup 3)) 0)))]
5130 {
5131 operands[1] = gen_lowpart (Pmode, operands[1]);
5132 operands[2] = gen_lowpart (Pmode, operands[2]);
5133 operands[3] = gen_lowpart (Pmode, operands[3]);
5134 }
5135 [(set_attr "type" "lea")
5136 (set_attr "mode" "SI")])
5137
5138 (define_insn_and_split "*lea_general_2"
5139 [(set (match_operand 0 "register_operand" "=r")
5140 (plus (mult (match_operand 1 "index_register_operand" "r")
5141 (match_operand 2 "const248_operand" "i"))
5142 (match_operand 3 "nonmemory_operand" "ri")))]
5143 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5144 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5145 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5146 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5147 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5148 || GET_MODE (operands[3]) == VOIDmode)"
5149 "#"
5150 "&& reload_completed"
5151 [(const_int 0)]
5152 {
5153 rtx pat;
5154 operands[0] = gen_lowpart (SImode, operands[0]);
5155 operands[1] = gen_lowpart (Pmode, operands[1]);
5156 operands[3] = gen_lowpart (Pmode, operands[3]);
5157 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5158 operands[3]);
5159 if (Pmode != SImode)
5160 pat = gen_rtx_SUBREG (SImode, pat, 0);
5161 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5162 DONE;
5163 }
5164 [(set_attr "type" "lea")
5165 (set_attr "mode" "SI")])
5166
5167 (define_insn_and_split "*lea_general_2_zext"
5168 [(set (match_operand:DI 0 "register_operand" "=r")
5169 (zero_extend:DI
5170 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5171 (match_operand:SI 2 "const248_operand" "n"))
5172 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5173 "TARGET_64BIT"
5174 "#"
5175 "&& reload_completed"
5176 [(set (match_dup 0)
5177 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5178 (match_dup 2))
5179 (match_dup 3)) 0)))]
5180 {
5181 operands[1] = gen_lowpart (Pmode, operands[1]);
5182 operands[3] = gen_lowpart (Pmode, operands[3]);
5183 }
5184 [(set_attr "type" "lea")
5185 (set_attr "mode" "SI")])
5186
5187 (define_insn_and_split "*lea_general_3"
5188 [(set (match_operand 0 "register_operand" "=r")
5189 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5190 (match_operand 2 "const248_operand" "i"))
5191 (match_operand 3 "register_operand" "r"))
5192 (match_operand 4 "immediate_operand" "i")))]
5193 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5194 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5195 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5196 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5197 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5198 "#"
5199 "&& reload_completed"
5200 [(const_int 0)]
5201 {
5202 rtx pat;
5203 operands[0] = gen_lowpart (SImode, operands[0]);
5204 operands[1] = gen_lowpart (Pmode, operands[1]);
5205 operands[3] = gen_lowpart (Pmode, operands[3]);
5206 operands[4] = gen_lowpart (Pmode, operands[4]);
5207 pat = gen_rtx_PLUS (Pmode,
5208 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5209 operands[2]),
5210 operands[3]),
5211 operands[4]);
5212 if (Pmode != SImode)
5213 pat = gen_rtx_SUBREG (SImode, pat, 0);
5214 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5215 DONE;
5216 }
5217 [(set_attr "type" "lea")
5218 (set_attr "mode" "SI")])
5219
5220 (define_insn_and_split "*lea_general_3_zext"
5221 [(set (match_operand:DI 0 "register_operand" "=r")
5222 (zero_extend:DI
5223 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5224 (match_operand:SI 2 "const248_operand" "n"))
5225 (match_operand:SI 3 "register_operand" "r"))
5226 (match_operand:SI 4 "immediate_operand" "i"))))]
5227 "TARGET_64BIT"
5228 "#"
5229 "&& reload_completed"
5230 [(set (match_dup 0)
5231 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5232 (match_dup 2))
5233 (match_dup 3))
5234 (match_dup 4)) 0)))]
5235 {
5236 operands[1] = gen_lowpart (Pmode, operands[1]);
5237 operands[3] = gen_lowpart (Pmode, operands[3]);
5238 operands[4] = gen_lowpart (Pmode, operands[4]);
5239 }
5240 [(set_attr "type" "lea")
5241 (set_attr "mode" "SI")])
5242
5243 (define_insn "*adddi_1_rex64"
5244 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5245 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5246 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5247 (clobber (reg:CC 17))]
5248 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5249 {
5250 switch (get_attr_type (insn))
5251 {
5252 case TYPE_LEA:
5253 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5254 return "lea{q}\t{%a2, %0|%0, %a2}";
5255
5256 case TYPE_INCDEC:
5257 if (! rtx_equal_p (operands[0], operands[1]))
5258 abort ();
5259 if (operands[2] == const1_rtx)
5260 return "inc{q}\t%0";
5261 else if (operands[2] == constm1_rtx)
5262 return "dec{q}\t%0";
5263 else
5264 abort ();
5265
5266 default:
5267 if (! rtx_equal_p (operands[0], operands[1]))
5268 abort ();
5269
5270 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5271 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5272 if (GET_CODE (operands[2]) == CONST_INT
5273 /* Avoid overflows. */
5274 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5275 && (INTVAL (operands[2]) == 128
5276 || (INTVAL (operands[2]) < 0
5277 && INTVAL (operands[2]) != -128)))
5278 {
5279 operands[2] = GEN_INT (-INTVAL (operands[2]));
5280 return "sub{q}\t{%2, %0|%0, %2}";
5281 }
5282 return "add{q}\t{%2, %0|%0, %2}";
5283 }
5284 }
5285 [(set (attr "type")
5286 (cond [(eq_attr "alternative" "2")
5287 (const_string "lea")
5288 ; Current assemblers are broken and do not allow @GOTOFF in
5289 ; ought but a memory context.
5290 (match_operand:DI 2 "pic_symbolic_operand" "")
5291 (const_string "lea")
5292 (match_operand:DI 2 "incdec_operand" "")
5293 (const_string "incdec")
5294 ]
5295 (const_string "alu")))
5296 (set_attr "mode" "DI")])
5297
5298 ;; Convert lea to the lea pattern to avoid flags dependency.
5299 (define_split
5300 [(set (match_operand:DI 0 "register_operand" "")
5301 (plus:DI (match_operand:DI 1 "register_operand" "")
5302 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5303 (clobber (reg:CC 17))]
5304 "TARGET_64BIT && reload_completed
5305 && true_regnum (operands[0]) != true_regnum (operands[1])"
5306 [(set (match_dup 0)
5307 (plus:DI (match_dup 1)
5308 (match_dup 2)))]
5309 "")
5310
5311 (define_insn "*adddi_2_rex64"
5312 [(set (reg 17)
5313 (compare
5314 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5315 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5316 (const_int 0)))
5317 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5318 (plus:DI (match_dup 1) (match_dup 2)))]
5319 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5320 && ix86_binary_operator_ok (PLUS, DImode, operands)
5321 /* Current assemblers are broken and do not allow @GOTOFF in
5322 ought but a memory context. */
5323 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5324 {
5325 switch (get_attr_type (insn))
5326 {
5327 case TYPE_INCDEC:
5328 if (! rtx_equal_p (operands[0], operands[1]))
5329 abort ();
5330 if (operands[2] == const1_rtx)
5331 return "inc{q}\t%0";
5332 else if (operands[2] == constm1_rtx)
5333 return "dec{q}\t%0";
5334 else
5335 abort ();
5336
5337 default:
5338 if (! rtx_equal_p (operands[0], operands[1]))
5339 abort ();
5340 /* ???? We ought to handle there the 32bit case too
5341 - do we need new constraint? */
5342 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5343 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5344 if (GET_CODE (operands[2]) == CONST_INT
5345 /* Avoid overflows. */
5346 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5347 && (INTVAL (operands[2]) == 128
5348 || (INTVAL (operands[2]) < 0
5349 && INTVAL (operands[2]) != -128)))
5350 {
5351 operands[2] = GEN_INT (-INTVAL (operands[2]));
5352 return "sub{q}\t{%2, %0|%0, %2}";
5353 }
5354 return "add{q}\t{%2, %0|%0, %2}";
5355 }
5356 }
5357 [(set (attr "type")
5358 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5359 (const_string "incdec")
5360 (const_string "alu")))
5361 (set_attr "mode" "DI")])
5362
5363 (define_insn "*adddi_3_rex64"
5364 [(set (reg 17)
5365 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5366 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5367 (clobber (match_scratch:DI 0 "=r"))]
5368 "TARGET_64BIT
5369 && ix86_match_ccmode (insn, CCZmode)
5370 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5371 /* Current assemblers are broken and do not allow @GOTOFF in
5372 ought but a memory context. */
5373 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5374 {
5375 switch (get_attr_type (insn))
5376 {
5377 case TYPE_INCDEC:
5378 if (! rtx_equal_p (operands[0], operands[1]))
5379 abort ();
5380 if (operands[2] == const1_rtx)
5381 return "inc{q}\t%0";
5382 else if (operands[2] == constm1_rtx)
5383 return "dec{q}\t%0";
5384 else
5385 abort ();
5386
5387 default:
5388 if (! rtx_equal_p (operands[0], operands[1]))
5389 abort ();
5390 /* ???? We ought to handle there the 32bit case too
5391 - do we need new constraint? */
5392 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5393 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5394 if (GET_CODE (operands[2]) == CONST_INT
5395 /* Avoid overflows. */
5396 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5397 && (INTVAL (operands[2]) == 128
5398 || (INTVAL (operands[2]) < 0
5399 && INTVAL (operands[2]) != -128)))
5400 {
5401 operands[2] = GEN_INT (-INTVAL (operands[2]));
5402 return "sub{q}\t{%2, %0|%0, %2}";
5403 }
5404 return "add{q}\t{%2, %0|%0, %2}";
5405 }
5406 }
5407 [(set (attr "type")
5408 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5409 (const_string "incdec")
5410 (const_string "alu")))
5411 (set_attr "mode" "DI")])
5412
5413 ; For comparisons against 1, -1 and 128, we may generate better code
5414 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5415 ; is matched then. We can't accept general immediate, because for
5416 ; case of overflows, the result is messed up.
5417 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5418 ; when negated.
5419 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5420 ; only for comparisons not depending on it.
5421 (define_insn "*adddi_4_rex64"
5422 [(set (reg 17)
5423 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5424 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5425 (clobber (match_scratch:DI 0 "=rm"))]
5426 "TARGET_64BIT
5427 && ix86_match_ccmode (insn, CCGCmode)"
5428 {
5429 switch (get_attr_type (insn))
5430 {
5431 case TYPE_INCDEC:
5432 if (operands[2] == constm1_rtx)
5433 return "inc{q}\t%0";
5434 else if (operands[2] == const1_rtx)
5435 return "dec{q}\t%0";
5436 else
5437 abort();
5438
5439 default:
5440 if (! rtx_equal_p (operands[0], operands[1]))
5441 abort ();
5442 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5443 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5444 if ((INTVAL (operands[2]) == -128
5445 || (INTVAL (operands[2]) > 0
5446 && INTVAL (operands[2]) != 128))
5447 /* Avoid overflows. */
5448 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5449 return "sub{q}\t{%2, %0|%0, %2}";
5450 operands[2] = GEN_INT (-INTVAL (operands[2]));
5451 return "add{q}\t{%2, %0|%0, %2}";
5452 }
5453 }
5454 [(set (attr "type")
5455 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5456 (const_string "incdec")
5457 (const_string "alu")))
5458 (set_attr "mode" "DI")])
5459
5460 (define_insn "*adddi_5_rex64"
5461 [(set (reg 17)
5462 (compare
5463 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5464 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5465 (const_int 0)))
5466 (clobber (match_scratch:DI 0 "=r"))]
5467 "TARGET_64BIT
5468 && ix86_match_ccmode (insn, CCGOCmode)
5469 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5470 /* Current assemblers are broken and do not allow @GOTOFF in
5471 ought but a memory context. */
5472 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5473 {
5474 switch (get_attr_type (insn))
5475 {
5476 case TYPE_INCDEC:
5477 if (! rtx_equal_p (operands[0], operands[1]))
5478 abort ();
5479 if (operands[2] == const1_rtx)
5480 return "inc{q}\t%0";
5481 else if (operands[2] == constm1_rtx)
5482 return "dec{q}\t%0";
5483 else
5484 abort();
5485
5486 default:
5487 if (! rtx_equal_p (operands[0], operands[1]))
5488 abort ();
5489 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5490 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5491 if (GET_CODE (operands[2]) == CONST_INT
5492 /* Avoid overflows. */
5493 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5494 && (INTVAL (operands[2]) == 128
5495 || (INTVAL (operands[2]) < 0
5496 && INTVAL (operands[2]) != -128)))
5497 {
5498 operands[2] = GEN_INT (-INTVAL (operands[2]));
5499 return "sub{q}\t{%2, %0|%0, %2}";
5500 }
5501 return "add{q}\t{%2, %0|%0, %2}";
5502 }
5503 }
5504 [(set (attr "type")
5505 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5506 (const_string "incdec")
5507 (const_string "alu")))
5508 (set_attr "mode" "DI")])
5509
5510
5511 (define_insn "*addsi_1"
5512 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5513 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5514 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5515 (clobber (reg:CC 17))]
5516 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5517 {
5518 switch (get_attr_type (insn))
5519 {
5520 case TYPE_LEA:
5521 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5522 return "lea{l}\t{%a2, %0|%0, %a2}";
5523
5524 case TYPE_INCDEC:
5525 if (! rtx_equal_p (operands[0], operands[1]))
5526 abort ();
5527 if (operands[2] == const1_rtx)
5528 return "inc{l}\t%0";
5529 else if (operands[2] == constm1_rtx)
5530 return "dec{l}\t%0";
5531 else
5532 abort();
5533
5534 default:
5535 if (! rtx_equal_p (operands[0], operands[1]))
5536 abort ();
5537
5538 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5539 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5540 if (GET_CODE (operands[2]) == CONST_INT
5541 && (INTVAL (operands[2]) == 128
5542 || (INTVAL (operands[2]) < 0
5543 && INTVAL (operands[2]) != -128)))
5544 {
5545 operands[2] = GEN_INT (-INTVAL (operands[2]));
5546 return "sub{l}\t{%2, %0|%0, %2}";
5547 }
5548 return "add{l}\t{%2, %0|%0, %2}";
5549 }
5550 }
5551 [(set (attr "type")
5552 (cond [(eq_attr "alternative" "2")
5553 (const_string "lea")
5554 ; Current assemblers are broken and do not allow @GOTOFF in
5555 ; ought but a memory context.
5556 (match_operand:SI 2 "pic_symbolic_operand" "")
5557 (const_string "lea")
5558 (match_operand:SI 2 "incdec_operand" "")
5559 (const_string "incdec")
5560 ]
5561 (const_string "alu")))
5562 (set_attr "mode" "SI")])
5563
5564 ;; Convert lea to the lea pattern to avoid flags dependency.
5565 (define_split
5566 [(set (match_operand 0 "register_operand" "")
5567 (plus (match_operand 1 "register_operand" "")
5568 (match_operand 2 "nonmemory_operand" "")))
5569 (clobber (reg:CC 17))]
5570 "reload_completed
5571 && true_regnum (operands[0]) != true_regnum (operands[1])"
5572 [(const_int 0)]
5573 {
5574 rtx pat;
5575 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5576 may confuse gen_lowpart. */
5577 if (GET_MODE (operands[0]) != Pmode)
5578 {
5579 operands[1] = gen_lowpart (Pmode, operands[1]);
5580 operands[2] = gen_lowpart (Pmode, operands[2]);
5581 }
5582 operands[0] = gen_lowpart (SImode, operands[0]);
5583 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5584 if (Pmode != SImode)
5585 pat = gen_rtx_SUBREG (SImode, pat, 0);
5586 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5587 DONE;
5588 })
5589
5590 ;; It may seem that nonimmediate operand is proper one for operand 1.
5591 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5592 ;; we take care in ix86_binary_operator_ok to not allow two memory
5593 ;; operands so proper swapping will be done in reload. This allow
5594 ;; patterns constructed from addsi_1 to match.
5595 (define_insn "addsi_1_zext"
5596 [(set (match_operand:DI 0 "register_operand" "=r,r")
5597 (zero_extend:DI
5598 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5599 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5600 (clobber (reg:CC 17))]
5601 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5602 {
5603 switch (get_attr_type (insn))
5604 {
5605 case TYPE_LEA:
5606 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5607 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5608
5609 case TYPE_INCDEC:
5610 if (operands[2] == const1_rtx)
5611 return "inc{l}\t%k0";
5612 else if (operands[2] == constm1_rtx)
5613 return "dec{l}\t%k0";
5614 else
5615 abort();
5616
5617 default:
5618 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5619 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5620 if (GET_CODE (operands[2]) == CONST_INT
5621 && (INTVAL (operands[2]) == 128
5622 || (INTVAL (operands[2]) < 0
5623 && INTVAL (operands[2]) != -128)))
5624 {
5625 operands[2] = GEN_INT (-INTVAL (operands[2]));
5626 return "sub{l}\t{%2, %k0|%k0, %2}";
5627 }
5628 return "add{l}\t{%2, %k0|%k0, %2}";
5629 }
5630 }
5631 [(set (attr "type")
5632 (cond [(eq_attr "alternative" "1")
5633 (const_string "lea")
5634 ; Current assemblers are broken and do not allow @GOTOFF in
5635 ; ought but a memory context.
5636 (match_operand:SI 2 "pic_symbolic_operand" "")
5637 (const_string "lea")
5638 (match_operand:SI 2 "incdec_operand" "")
5639 (const_string "incdec")
5640 ]
5641 (const_string "alu")))
5642 (set_attr "mode" "SI")])
5643
5644 ;; Convert lea to the lea pattern to avoid flags dependency.
5645 (define_split
5646 [(set (match_operand:DI 0 "register_operand" "")
5647 (zero_extend:DI
5648 (plus:SI (match_operand:SI 1 "register_operand" "")
5649 (match_operand:SI 2 "nonmemory_operand" ""))))
5650 (clobber (reg:CC 17))]
5651 "TARGET_64BIT && reload_completed
5652 && true_regnum (operands[0]) != true_regnum (operands[1])"
5653 [(set (match_dup 0)
5654 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5655 {
5656 operands[1] = gen_lowpart (Pmode, operands[1]);
5657 operands[2] = gen_lowpart (Pmode, operands[2]);
5658 })
5659
5660 (define_insn "*addsi_2"
5661 [(set (reg 17)
5662 (compare
5663 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5664 (match_operand:SI 2 "general_operand" "rmni,rni"))
5665 (const_int 0)))
5666 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5667 (plus:SI (match_dup 1) (match_dup 2)))]
5668 "ix86_match_ccmode (insn, CCGOCmode)
5669 && ix86_binary_operator_ok (PLUS, SImode, operands)
5670 /* Current assemblers are broken and do not allow @GOTOFF in
5671 ought but a memory context. */
5672 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5673 {
5674 switch (get_attr_type (insn))
5675 {
5676 case TYPE_INCDEC:
5677 if (! rtx_equal_p (operands[0], operands[1]))
5678 abort ();
5679 if (operands[2] == const1_rtx)
5680 return "inc{l}\t%0";
5681 else if (operands[2] == constm1_rtx)
5682 return "dec{l}\t%0";
5683 else
5684 abort();
5685
5686 default:
5687 if (! rtx_equal_p (operands[0], operands[1]))
5688 abort ();
5689 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5691 if (GET_CODE (operands[2]) == CONST_INT
5692 && (INTVAL (operands[2]) == 128
5693 || (INTVAL (operands[2]) < 0
5694 && INTVAL (operands[2]) != -128)))
5695 {
5696 operands[2] = GEN_INT (-INTVAL (operands[2]));
5697 return "sub{l}\t{%2, %0|%0, %2}";
5698 }
5699 return "add{l}\t{%2, %0|%0, %2}";
5700 }
5701 }
5702 [(set (attr "type")
5703 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5704 (const_string "incdec")
5705 (const_string "alu")))
5706 (set_attr "mode" "SI")])
5707
5708 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5709 (define_insn "*addsi_2_zext"
5710 [(set (reg 17)
5711 (compare
5712 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5713 (match_operand:SI 2 "general_operand" "rmni"))
5714 (const_int 0)))
5715 (set (match_operand:DI 0 "register_operand" "=r")
5716 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5717 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5718 && ix86_binary_operator_ok (PLUS, SImode, operands)
5719 /* Current assemblers are broken and do not allow @GOTOFF in
5720 ought but a memory context. */
5721 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5722 {
5723 switch (get_attr_type (insn))
5724 {
5725 case TYPE_INCDEC:
5726 if (operands[2] == const1_rtx)
5727 return "inc{l}\t%k0";
5728 else if (operands[2] == constm1_rtx)
5729 return "dec{l}\t%k0";
5730 else
5731 abort();
5732
5733 default:
5734 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5735 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5736 if (GET_CODE (operands[2]) == CONST_INT
5737 && (INTVAL (operands[2]) == 128
5738 || (INTVAL (operands[2]) < 0
5739 && INTVAL (operands[2]) != -128)))
5740 {
5741 operands[2] = GEN_INT (-INTVAL (operands[2]));
5742 return "sub{l}\t{%2, %k0|%k0, %2}";
5743 }
5744 return "add{l}\t{%2, %k0|%k0, %2}";
5745 }
5746 }
5747 [(set (attr "type")
5748 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5749 (const_string "incdec")
5750 (const_string "alu")))
5751 (set_attr "mode" "SI")])
5752
5753 (define_insn "*addsi_3"
5754 [(set (reg 17)
5755 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5756 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5757 (clobber (match_scratch:SI 0 "=r"))]
5758 "ix86_match_ccmode (insn, CCZmode)
5759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5760 /* Current assemblers are broken and do not allow @GOTOFF in
5761 ought but a memory context. */
5762 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5763 {
5764 switch (get_attr_type (insn))
5765 {
5766 case TYPE_INCDEC:
5767 if (! rtx_equal_p (operands[0], operands[1]))
5768 abort ();
5769 if (operands[2] == const1_rtx)
5770 return "inc{l}\t%0";
5771 else if (operands[2] == constm1_rtx)
5772 return "dec{l}\t%0";
5773 else
5774 abort();
5775
5776 default:
5777 if (! rtx_equal_p (operands[0], operands[1]))
5778 abort ();
5779 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5780 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5781 if (GET_CODE (operands[2]) == CONST_INT
5782 && (INTVAL (operands[2]) == 128
5783 || (INTVAL (operands[2]) < 0
5784 && INTVAL (operands[2]) != -128)))
5785 {
5786 operands[2] = GEN_INT (-INTVAL (operands[2]));
5787 return "sub{l}\t{%2, %0|%0, %2}";
5788 }
5789 return "add{l}\t{%2, %0|%0, %2}";
5790 }
5791 }
5792 [(set (attr "type")
5793 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5794 (const_string "incdec")
5795 (const_string "alu")))
5796 (set_attr "mode" "SI")])
5797
5798 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5799 (define_insn "*addsi_3_zext"
5800 [(set (reg 17)
5801 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5802 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5803 (set (match_operand:DI 0 "register_operand" "=r")
5804 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5805 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5806 && ix86_binary_operator_ok (PLUS, SImode, operands)
5807 /* Current assemblers are broken and do not allow @GOTOFF in
5808 ought but a memory context. */
5809 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5810 {
5811 switch (get_attr_type (insn))
5812 {
5813 case TYPE_INCDEC:
5814 if (operands[2] == const1_rtx)
5815 return "inc{l}\t%k0";
5816 else if (operands[2] == constm1_rtx)
5817 return "dec{l}\t%k0";
5818 else
5819 abort();
5820
5821 default:
5822 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5823 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5824 if (GET_CODE (operands[2]) == CONST_INT
5825 && (INTVAL (operands[2]) == 128
5826 || (INTVAL (operands[2]) < 0
5827 && INTVAL (operands[2]) != -128)))
5828 {
5829 operands[2] = GEN_INT (-INTVAL (operands[2]));
5830 return "sub{l}\t{%2, %k0|%k0, %2}";
5831 }
5832 return "add{l}\t{%2, %k0|%k0, %2}";
5833 }
5834 }
5835 [(set (attr "type")
5836 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5837 (const_string "incdec")
5838 (const_string "alu")))
5839 (set_attr "mode" "SI")])
5840
5841 ; For comparisons against 1, -1 and 128, we may generate better code
5842 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5843 ; is matched then. We can't accept general immediate, because for
5844 ; case of overflows, the result is messed up.
5845 ; This pattern also don't hold of 0x80000000, since the value overflows
5846 ; when negated.
5847 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5848 ; only for comparisons not depending on it.
5849 (define_insn "*addsi_4"
5850 [(set (reg 17)
5851 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5852 (match_operand:SI 2 "const_int_operand" "n")))
5853 (clobber (match_scratch:SI 0 "=rm"))]
5854 "ix86_match_ccmode (insn, CCGCmode)
5855 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5856 {
5857 switch (get_attr_type (insn))
5858 {
5859 case TYPE_INCDEC:
5860 if (operands[2] == constm1_rtx)
5861 return "inc{l}\t%0";
5862 else if (operands[2] == const1_rtx)
5863 return "dec{l}\t%0";
5864 else
5865 abort();
5866
5867 default:
5868 if (! rtx_equal_p (operands[0], operands[1]))
5869 abort ();
5870 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5871 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5872 if ((INTVAL (operands[2]) == -128
5873 || (INTVAL (operands[2]) > 0
5874 && INTVAL (operands[2]) != 128)))
5875 return "sub{l}\t{%2, %0|%0, %2}";
5876 operands[2] = GEN_INT (-INTVAL (operands[2]));
5877 return "add{l}\t{%2, %0|%0, %2}";
5878 }
5879 }
5880 [(set (attr "type")
5881 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5882 (const_string "incdec")
5883 (const_string "alu")))
5884 (set_attr "mode" "SI")])
5885
5886 (define_insn "*addsi_5"
5887 [(set (reg 17)
5888 (compare
5889 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5890 (match_operand:SI 2 "general_operand" "rmni"))
5891 (const_int 0)))
5892 (clobber (match_scratch:SI 0 "=r"))]
5893 "ix86_match_ccmode (insn, CCGOCmode)
5894 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5895 /* Current assemblers are broken and do not allow @GOTOFF in
5896 ought but a memory context. */
5897 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5898 {
5899 switch (get_attr_type (insn))
5900 {
5901 case TYPE_INCDEC:
5902 if (! rtx_equal_p (operands[0], operands[1]))
5903 abort ();
5904 if (operands[2] == const1_rtx)
5905 return "inc{l}\t%0";
5906 else if (operands[2] == constm1_rtx)
5907 return "dec{l}\t%0";
5908 else
5909 abort();
5910
5911 default:
5912 if (! rtx_equal_p (operands[0], operands[1]))
5913 abort ();
5914 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5916 if (GET_CODE (operands[2]) == CONST_INT
5917 && (INTVAL (operands[2]) == 128
5918 || (INTVAL (operands[2]) < 0
5919 && INTVAL (operands[2]) != -128)))
5920 {
5921 operands[2] = GEN_INT (-INTVAL (operands[2]));
5922 return "sub{l}\t{%2, %0|%0, %2}";
5923 }
5924 return "add{l}\t{%2, %0|%0, %2}";
5925 }
5926 }
5927 [(set (attr "type")
5928 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5929 (const_string "incdec")
5930 (const_string "alu")))
5931 (set_attr "mode" "SI")])
5932
5933 (define_expand "addhi3"
5934 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5935 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5936 (match_operand:HI 2 "general_operand" "")))
5937 (clobber (reg:CC 17))])]
5938 "TARGET_HIMODE_MATH"
5939 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5940
5941 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5942 ;; type optimizations enabled by define-splits. This is not important
5943 ;; for PII, and in fact harmful because of partial register stalls.
5944
5945 (define_insn "*addhi_1_lea"
5946 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5947 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5948 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5949 (clobber (reg:CC 17))]
5950 "!TARGET_PARTIAL_REG_STALL
5951 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5952 {
5953 switch (get_attr_type (insn))
5954 {
5955 case TYPE_LEA:
5956 return "#";
5957 case TYPE_INCDEC:
5958 if (operands[2] == const1_rtx)
5959 return "inc{w}\t%0";
5960 else if (operands[2] == constm1_rtx)
5961 return "dec{w}\t%0";
5962 abort();
5963
5964 default:
5965 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5966 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5967 if (GET_CODE (operands[2]) == CONST_INT
5968 && (INTVAL (operands[2]) == 128
5969 || (INTVAL (operands[2]) < 0
5970 && INTVAL (operands[2]) != -128)))
5971 {
5972 operands[2] = GEN_INT (-INTVAL (operands[2]));
5973 return "sub{w}\t{%2, %0|%0, %2}";
5974 }
5975 return "add{w}\t{%2, %0|%0, %2}";
5976 }
5977 }
5978 [(set (attr "type")
5979 (if_then_else (eq_attr "alternative" "2")
5980 (const_string "lea")
5981 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5982 (const_string "incdec")
5983 (const_string "alu"))))
5984 (set_attr "mode" "HI,HI,SI")])
5985
5986 (define_insn "*addhi_1"
5987 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5988 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5989 (match_operand:HI 2 "general_operand" "ri,rm")))
5990 (clobber (reg:CC 17))]
5991 "TARGET_PARTIAL_REG_STALL
5992 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5993 {
5994 switch (get_attr_type (insn))
5995 {
5996 case TYPE_INCDEC:
5997 if (operands[2] == const1_rtx)
5998 return "inc{w}\t%0";
5999 else if (operands[2] == constm1_rtx)
6000 return "dec{w}\t%0";
6001 abort();
6002
6003 default:
6004 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6005 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6006 if (GET_CODE (operands[2]) == CONST_INT
6007 && (INTVAL (operands[2]) == 128
6008 || (INTVAL (operands[2]) < 0
6009 && INTVAL (operands[2]) != -128)))
6010 {
6011 operands[2] = GEN_INT (-INTVAL (operands[2]));
6012 return "sub{w}\t{%2, %0|%0, %2}";
6013 }
6014 return "add{w}\t{%2, %0|%0, %2}";
6015 }
6016 }
6017 [(set (attr "type")
6018 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6019 (const_string "incdec")
6020 (const_string "alu")))
6021 (set_attr "mode" "HI")])
6022
6023 (define_insn "*addhi_2"
6024 [(set (reg 17)
6025 (compare
6026 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6027 (match_operand:HI 2 "general_operand" "rmni,rni"))
6028 (const_int 0)))
6029 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6030 (plus:HI (match_dup 1) (match_dup 2)))]
6031 "ix86_match_ccmode (insn, CCGOCmode)
6032 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6033 {
6034 switch (get_attr_type (insn))
6035 {
6036 case TYPE_INCDEC:
6037 if (operands[2] == const1_rtx)
6038 return "inc{w}\t%0";
6039 else if (operands[2] == constm1_rtx)
6040 return "dec{w}\t%0";
6041 abort();
6042
6043 default:
6044 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6045 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6046 if (GET_CODE (operands[2]) == CONST_INT
6047 && (INTVAL (operands[2]) == 128
6048 || (INTVAL (operands[2]) < 0
6049 && INTVAL (operands[2]) != -128)))
6050 {
6051 operands[2] = GEN_INT (-INTVAL (operands[2]));
6052 return "sub{w}\t{%2, %0|%0, %2}";
6053 }
6054 return "add{w}\t{%2, %0|%0, %2}";
6055 }
6056 }
6057 [(set (attr "type")
6058 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6059 (const_string "incdec")
6060 (const_string "alu")))
6061 (set_attr "mode" "HI")])
6062
6063 (define_insn "*addhi_3"
6064 [(set (reg 17)
6065 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6066 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6067 (clobber (match_scratch:HI 0 "=r"))]
6068 "ix86_match_ccmode (insn, CCZmode)
6069 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6070 {
6071 switch (get_attr_type (insn))
6072 {
6073 case TYPE_INCDEC:
6074 if (operands[2] == const1_rtx)
6075 return "inc{w}\t%0";
6076 else if (operands[2] == constm1_rtx)
6077 return "dec{w}\t%0";
6078 abort();
6079
6080 default:
6081 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6082 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6083 if (GET_CODE (operands[2]) == CONST_INT
6084 && (INTVAL (operands[2]) == 128
6085 || (INTVAL (operands[2]) < 0
6086 && INTVAL (operands[2]) != -128)))
6087 {
6088 operands[2] = GEN_INT (-INTVAL (operands[2]));
6089 return "sub{w}\t{%2, %0|%0, %2}";
6090 }
6091 return "add{w}\t{%2, %0|%0, %2}";
6092 }
6093 }
6094 [(set (attr "type")
6095 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6096 (const_string "incdec")
6097 (const_string "alu")))
6098 (set_attr "mode" "HI")])
6099
6100 ; See comments above addsi_3_imm for details.
6101 (define_insn "*addhi_4"
6102 [(set (reg 17)
6103 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6104 (match_operand:HI 2 "const_int_operand" "n")))
6105 (clobber (match_scratch:HI 0 "=rm"))]
6106 "ix86_match_ccmode (insn, CCGCmode)
6107 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6108 {
6109 switch (get_attr_type (insn))
6110 {
6111 case TYPE_INCDEC:
6112 if (operands[2] == constm1_rtx)
6113 return "inc{w}\t%0";
6114 else if (operands[2] == const1_rtx)
6115 return "dec{w}\t%0";
6116 else
6117 abort();
6118
6119 default:
6120 if (! rtx_equal_p (operands[0], operands[1]))
6121 abort ();
6122 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6123 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6124 if ((INTVAL (operands[2]) == -128
6125 || (INTVAL (operands[2]) > 0
6126 && INTVAL (operands[2]) != 128)))
6127 return "sub{w}\t{%2, %0|%0, %2}";
6128 operands[2] = GEN_INT (-INTVAL (operands[2]));
6129 return "add{w}\t{%2, %0|%0, %2}";
6130 }
6131 }
6132 [(set (attr "type")
6133 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6134 (const_string "incdec")
6135 (const_string "alu")))
6136 (set_attr "mode" "SI")])
6137
6138
6139 (define_insn "*addhi_5"
6140 [(set (reg 17)
6141 (compare
6142 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6143 (match_operand:HI 2 "general_operand" "rmni"))
6144 (const_int 0)))
6145 (clobber (match_scratch:HI 0 "=r"))]
6146 "ix86_match_ccmode (insn, CCGOCmode)
6147 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6148 {
6149 switch (get_attr_type (insn))
6150 {
6151 case TYPE_INCDEC:
6152 if (operands[2] == const1_rtx)
6153 return "inc{w}\t%0";
6154 else if (operands[2] == constm1_rtx)
6155 return "dec{w}\t%0";
6156 abort();
6157
6158 default:
6159 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6161 if (GET_CODE (operands[2]) == CONST_INT
6162 && (INTVAL (operands[2]) == 128
6163 || (INTVAL (operands[2]) < 0
6164 && INTVAL (operands[2]) != -128)))
6165 {
6166 operands[2] = GEN_INT (-INTVAL (operands[2]));
6167 return "sub{w}\t{%2, %0|%0, %2}";
6168 }
6169 return "add{w}\t{%2, %0|%0, %2}";
6170 }
6171 }
6172 [(set (attr "type")
6173 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6174 (const_string "incdec")
6175 (const_string "alu")))
6176 (set_attr "mode" "HI")])
6177
6178 (define_expand "addqi3"
6179 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6180 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6181 (match_operand:QI 2 "general_operand" "")))
6182 (clobber (reg:CC 17))])]
6183 "TARGET_QIMODE_MATH"
6184 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6185
6186 ;; %%% Potential partial reg stall on alternative 2. What to do?
6187 (define_insn "*addqi_1_lea"
6188 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6189 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6190 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6191 (clobber (reg:CC 17))]
6192 "!TARGET_PARTIAL_REG_STALL
6193 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6194 {
6195 int widen = (which_alternative == 2);
6196 switch (get_attr_type (insn))
6197 {
6198 case TYPE_LEA:
6199 return "#";
6200 case TYPE_INCDEC:
6201 if (operands[2] == const1_rtx)
6202 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6203 else if (operands[2] == constm1_rtx)
6204 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6205 abort();
6206
6207 default:
6208 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6209 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6210 if (GET_CODE (operands[2]) == CONST_INT
6211 && (INTVAL (operands[2]) == 128
6212 || (INTVAL (operands[2]) < 0
6213 && INTVAL (operands[2]) != -128)))
6214 {
6215 operands[2] = GEN_INT (-INTVAL (operands[2]));
6216 if (widen)
6217 return "sub{l}\t{%2, %k0|%k0, %2}";
6218 else
6219 return "sub{b}\t{%2, %0|%0, %2}";
6220 }
6221 if (widen)
6222 return "add{l}\t{%k2, %k0|%k0, %k2}";
6223 else
6224 return "add{b}\t{%2, %0|%0, %2}";
6225 }
6226 }
6227 [(set (attr "type")
6228 (if_then_else (eq_attr "alternative" "3")
6229 (const_string "lea")
6230 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6231 (const_string "incdec")
6232 (const_string "alu"))))
6233 (set_attr "mode" "QI,QI,SI,SI")])
6234
6235 (define_insn "*addqi_1"
6236 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6237 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6238 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6239 (clobber (reg:CC 17))]
6240 "TARGET_PARTIAL_REG_STALL
6241 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6242 {
6243 int widen = (which_alternative == 2);
6244 switch (get_attr_type (insn))
6245 {
6246 case TYPE_INCDEC:
6247 if (operands[2] == const1_rtx)
6248 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6249 else if (operands[2] == constm1_rtx)
6250 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6251 abort();
6252
6253 default:
6254 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6255 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6256 if (GET_CODE (operands[2]) == CONST_INT
6257 && (INTVAL (operands[2]) == 128
6258 || (INTVAL (operands[2]) < 0
6259 && INTVAL (operands[2]) != -128)))
6260 {
6261 operands[2] = GEN_INT (-INTVAL (operands[2]));
6262 if (widen)
6263 return "sub{l}\t{%2, %k0|%k0, %2}";
6264 else
6265 return "sub{b}\t{%2, %0|%0, %2}";
6266 }
6267 if (widen)
6268 return "add{l}\t{%k2, %k0|%k0, %k2}";
6269 else
6270 return "add{b}\t{%2, %0|%0, %2}";
6271 }
6272 }
6273 [(set (attr "type")
6274 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6275 (const_string "incdec")
6276 (const_string "alu")))
6277 (set_attr "mode" "QI,QI,SI")])
6278
6279 (define_insn "*addqi_1_slp"
6280 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6281 (plus:QI (match_dup 0)
6282 (match_operand:QI 1 "general_operand" "qn,qnm")))
6283 (clobber (reg:CC 17))]
6284 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6285 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6286 {
6287 switch (get_attr_type (insn))
6288 {
6289 case TYPE_INCDEC:
6290 if (operands[1] == const1_rtx)
6291 return "inc{b}\t%0";
6292 else if (operands[1] == constm1_rtx)
6293 return "dec{b}\t%0";
6294 abort();
6295
6296 default:
6297 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6298 if (GET_CODE (operands[1]) == CONST_INT
6299 && INTVAL (operands[1]) < 0)
6300 {
6301 operands[1] = GEN_INT (-INTVAL (operands[1]));
6302 return "sub{b}\t{%1, %0|%0, %1}";
6303 }
6304 return "add{b}\t{%1, %0|%0, %1}";
6305 }
6306 }
6307 [(set (attr "type")
6308 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6309 (const_string "incdec")
6310 (const_string "alu1")))
6311 (set_attr "mode" "QI")])
6312
6313 (define_insn "*addqi_2"
6314 [(set (reg 17)
6315 (compare
6316 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6317 (match_operand:QI 2 "general_operand" "qmni,qni"))
6318 (const_int 0)))
6319 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6320 (plus:QI (match_dup 1) (match_dup 2)))]
6321 "ix86_match_ccmode (insn, CCGOCmode)
6322 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6323 {
6324 switch (get_attr_type (insn))
6325 {
6326 case TYPE_INCDEC:
6327 if (operands[2] == const1_rtx)
6328 return "inc{b}\t%0";
6329 else if (operands[2] == constm1_rtx
6330 || (GET_CODE (operands[2]) == CONST_INT
6331 && INTVAL (operands[2]) == 255))
6332 return "dec{b}\t%0";
6333 abort();
6334
6335 default:
6336 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6337 if (GET_CODE (operands[2]) == CONST_INT
6338 && INTVAL (operands[2]) < 0)
6339 {
6340 operands[2] = GEN_INT (-INTVAL (operands[2]));
6341 return "sub{b}\t{%2, %0|%0, %2}";
6342 }
6343 return "add{b}\t{%2, %0|%0, %2}";
6344 }
6345 }
6346 [(set (attr "type")
6347 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6348 (const_string "incdec")
6349 (const_string "alu")))
6350 (set_attr "mode" "QI")])
6351
6352 (define_insn "*addqi_3"
6353 [(set (reg 17)
6354 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6355 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6356 (clobber (match_scratch:QI 0 "=q"))]
6357 "ix86_match_ccmode (insn, CCZmode)
6358 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6359 {
6360 switch (get_attr_type (insn))
6361 {
6362 case TYPE_INCDEC:
6363 if (operands[2] == const1_rtx)
6364 return "inc{b}\t%0";
6365 else if (operands[2] == constm1_rtx
6366 || (GET_CODE (operands[2]) == CONST_INT
6367 && INTVAL (operands[2]) == 255))
6368 return "dec{b}\t%0";
6369 abort();
6370
6371 default:
6372 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6373 if (GET_CODE (operands[2]) == CONST_INT
6374 && INTVAL (operands[2]) < 0)
6375 {
6376 operands[2] = GEN_INT (-INTVAL (operands[2]));
6377 return "sub{b}\t{%2, %0|%0, %2}";
6378 }
6379 return "add{b}\t{%2, %0|%0, %2}";
6380 }
6381 }
6382 [(set (attr "type")
6383 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6384 (const_string "incdec")
6385 (const_string "alu")))
6386 (set_attr "mode" "QI")])
6387
6388 ; See comments above addsi_3_imm for details.
6389 (define_insn "*addqi_4"
6390 [(set (reg 17)
6391 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6392 (match_operand:QI 2 "const_int_operand" "n")))
6393 (clobber (match_scratch:QI 0 "=qm"))]
6394 "ix86_match_ccmode (insn, CCGCmode)
6395 && (INTVAL (operands[2]) & 0xff) != 0x80"
6396 {
6397 switch (get_attr_type (insn))
6398 {
6399 case TYPE_INCDEC:
6400 if (operands[2] == constm1_rtx
6401 || (GET_CODE (operands[2]) == CONST_INT
6402 && INTVAL (operands[2]) == 255))
6403 return "inc{b}\t%0";
6404 else if (operands[2] == const1_rtx)
6405 return "dec{b}\t%0";
6406 else
6407 abort();
6408
6409 default:
6410 if (! rtx_equal_p (operands[0], operands[1]))
6411 abort ();
6412 if (INTVAL (operands[2]) < 0)
6413 {
6414 operands[2] = GEN_INT (-INTVAL (operands[2]));
6415 return "add{b}\t{%2, %0|%0, %2}";
6416 }
6417 return "sub{b}\t{%2, %0|%0, %2}";
6418 }
6419 }
6420 [(set (attr "type")
6421 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6422 (const_string "incdec")
6423 (const_string "alu")))
6424 (set_attr "mode" "QI")])
6425
6426
6427 (define_insn "*addqi_5"
6428 [(set (reg 17)
6429 (compare
6430 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6431 (match_operand:QI 2 "general_operand" "qmni"))
6432 (const_int 0)))
6433 (clobber (match_scratch:QI 0 "=q"))]
6434 "ix86_match_ccmode (insn, CCGOCmode)
6435 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6436 {
6437 switch (get_attr_type (insn))
6438 {
6439 case TYPE_INCDEC:
6440 if (operands[2] == const1_rtx)
6441 return "inc{b}\t%0";
6442 else if (operands[2] == constm1_rtx
6443 || (GET_CODE (operands[2]) == CONST_INT
6444 && INTVAL (operands[2]) == 255))
6445 return "dec{b}\t%0";
6446 abort();
6447
6448 default:
6449 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6450 if (GET_CODE (operands[2]) == CONST_INT
6451 && INTVAL (operands[2]) < 0)
6452 {
6453 operands[2] = GEN_INT (-INTVAL (operands[2]));
6454 return "sub{b}\t{%2, %0|%0, %2}";
6455 }
6456 return "add{b}\t{%2, %0|%0, %2}";
6457 }
6458 }
6459 [(set (attr "type")
6460 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6461 (const_string "incdec")
6462 (const_string "alu")))
6463 (set_attr "mode" "QI")])
6464
6465
6466 (define_insn "addqi_ext_1"
6467 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6468 (const_int 8)
6469 (const_int 8))
6470 (plus:SI
6471 (zero_extract:SI
6472 (match_operand 1 "ext_register_operand" "0")
6473 (const_int 8)
6474 (const_int 8))
6475 (match_operand:QI 2 "general_operand" "Qmn")))
6476 (clobber (reg:CC 17))]
6477 "!TARGET_64BIT"
6478 {
6479 switch (get_attr_type (insn))
6480 {
6481 case TYPE_INCDEC:
6482 if (operands[2] == const1_rtx)
6483 return "inc{b}\t%h0";
6484 else if (operands[2] == constm1_rtx
6485 || (GET_CODE (operands[2]) == CONST_INT
6486 && INTVAL (operands[2]) == 255))
6487 return "dec{b}\t%h0";
6488 abort();
6489
6490 default:
6491 return "add{b}\t{%2, %h0|%h0, %2}";
6492 }
6493 }
6494 [(set (attr "type")
6495 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6496 (const_string "incdec")
6497 (const_string "alu")))
6498 (set_attr "mode" "QI")])
6499
6500 (define_insn "*addqi_ext_1_rex64"
6501 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6502 (const_int 8)
6503 (const_int 8))
6504 (plus:SI
6505 (zero_extract:SI
6506 (match_operand 1 "ext_register_operand" "0")
6507 (const_int 8)
6508 (const_int 8))
6509 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6510 (clobber (reg:CC 17))]
6511 "TARGET_64BIT"
6512 {
6513 switch (get_attr_type (insn))
6514 {
6515 case TYPE_INCDEC:
6516 if (operands[2] == const1_rtx)
6517 return "inc{b}\t%h0";
6518 else if (operands[2] == constm1_rtx
6519 || (GET_CODE (operands[2]) == CONST_INT
6520 && INTVAL (operands[2]) == 255))
6521 return "dec{b}\t%h0";
6522 abort();
6523
6524 default:
6525 return "add{b}\t{%2, %h0|%h0, %2}";
6526 }
6527 }
6528 [(set (attr "type")
6529 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6530 (const_string "incdec")
6531 (const_string "alu")))
6532 (set_attr "mode" "QI")])
6533
6534 (define_insn "*addqi_ext_2"
6535 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6536 (const_int 8)
6537 (const_int 8))
6538 (plus:SI
6539 (zero_extract:SI
6540 (match_operand 1 "ext_register_operand" "%0")
6541 (const_int 8)
6542 (const_int 8))
6543 (zero_extract:SI
6544 (match_operand 2 "ext_register_operand" "Q")
6545 (const_int 8)
6546 (const_int 8))))
6547 (clobber (reg:CC 17))]
6548 ""
6549 "add{b}\t{%h2, %h0|%h0, %h2}"
6550 [(set_attr "type" "alu")
6551 (set_attr "mode" "QI")])
6552
6553 ;; The patterns that match these are at the end of this file.
6554
6555 (define_expand "addxf3"
6556 [(set (match_operand:XF 0 "register_operand" "")
6557 (plus:XF (match_operand:XF 1 "register_operand" "")
6558 (match_operand:XF 2 "register_operand" "")))]
6559 "TARGET_80387"
6560 "")
6561
6562 (define_expand "adddf3"
6563 [(set (match_operand:DF 0 "register_operand" "")
6564 (plus:DF (match_operand:DF 1 "register_operand" "")
6565 (match_operand:DF 2 "nonimmediate_operand" "")))]
6566 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6567 "")
6568
6569 (define_expand "addsf3"
6570 [(set (match_operand:SF 0 "register_operand" "")
6571 (plus:SF (match_operand:SF 1 "register_operand" "")
6572 (match_operand:SF 2 "nonimmediate_operand" "")))]
6573 "TARGET_80387 || TARGET_SSE_MATH"
6574 "")
6575 \f
6576 ;; Subtract instructions
6577
6578 ;; %%% splits for subsidi3
6579
6580 (define_expand "subdi3"
6581 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6582 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6583 (match_operand:DI 2 "x86_64_general_operand" "")))
6584 (clobber (reg:CC 17))])]
6585 ""
6586 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6587
6588 (define_insn "*subdi3_1"
6589 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6590 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6591 (match_operand:DI 2 "general_operand" "roiF,riF")))
6592 (clobber (reg:CC 17))]
6593 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6594 "#")
6595
6596 (define_split
6597 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6598 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6599 (match_operand:DI 2 "general_operand" "")))
6600 (clobber (reg:CC 17))]
6601 "!TARGET_64BIT && reload_completed"
6602 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6603 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6604 (parallel [(set (match_dup 3)
6605 (minus:SI (match_dup 4)
6606 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6607 (match_dup 5))))
6608 (clobber (reg:CC 17))])]
6609 "split_di (operands+0, 1, operands+0, operands+3);
6610 split_di (operands+1, 1, operands+1, operands+4);
6611 split_di (operands+2, 1, operands+2, operands+5);")
6612
6613 (define_insn "subdi3_carry_rex64"
6614 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6615 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6616 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6617 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6618 (clobber (reg:CC 17))]
6619 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6620 "sbb{q}\t{%2, %0|%0, %2}"
6621 [(set_attr "type" "alu")
6622 (set_attr "pent_pair" "pu")
6623 (set_attr "mode" "DI")])
6624
6625 (define_insn "*subdi_1_rex64"
6626 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6627 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6628 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6629 (clobber (reg:CC 17))]
6630 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6631 "sub{q}\t{%2, %0|%0, %2}"
6632 [(set_attr "type" "alu")
6633 (set_attr "mode" "DI")])
6634
6635 (define_insn "*subdi_2_rex64"
6636 [(set (reg 17)
6637 (compare
6638 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6639 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6640 (const_int 0)))
6641 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6642 (minus:DI (match_dup 1) (match_dup 2)))]
6643 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6644 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6645 "sub{q}\t{%2, %0|%0, %2}"
6646 [(set_attr "type" "alu")
6647 (set_attr "mode" "DI")])
6648
6649 (define_insn "*subdi_3_rex63"
6650 [(set (reg 17)
6651 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6652 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6653 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6654 (minus:DI (match_dup 1) (match_dup 2)))]
6655 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6656 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6657 "sub{q}\t{%2, %0|%0, %2}"
6658 [(set_attr "type" "alu")
6659 (set_attr "mode" "DI")])
6660
6661 (define_insn "subqi3_carry"
6662 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6663 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6664 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6665 (match_operand:QI 2 "general_operand" "qi,qm"))))
6666 (clobber (reg:CC 17))]
6667 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6668 "sbb{b}\t{%2, %0|%0, %2}"
6669 [(set_attr "type" "alu")
6670 (set_attr "pent_pair" "pu")
6671 (set_attr "mode" "QI")])
6672
6673 (define_insn "subhi3_carry"
6674 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6675 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6676 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6677 (match_operand:HI 2 "general_operand" "ri,rm"))))
6678 (clobber (reg:CC 17))]
6679 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6680 "sbb{w}\t{%2, %0|%0, %2}"
6681 [(set_attr "type" "alu")
6682 (set_attr "pent_pair" "pu")
6683 (set_attr "mode" "HI")])
6684
6685 (define_insn "subsi3_carry"
6686 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6687 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6689 (match_operand:SI 2 "general_operand" "ri,rm"))))
6690 (clobber (reg:CC 17))]
6691 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6692 "sbb{l}\t{%2, %0|%0, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "pent_pair" "pu")
6695 (set_attr "mode" "SI")])
6696
6697 (define_insn "subsi3_carry_zext"
6698 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6699 (zero_extend:DI
6700 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6701 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6702 (match_operand:SI 2 "general_operand" "ri,rm")))))
6703 (clobber (reg:CC 17))]
6704 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705 "sbb{l}\t{%2, %k0|%k0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "pent_pair" "pu")
6708 (set_attr "mode" "SI")])
6709
6710 (define_expand "subsi3"
6711 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6712 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6713 (match_operand:SI 2 "general_operand" "")))
6714 (clobber (reg:CC 17))])]
6715 ""
6716 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6717
6718 (define_insn "*subsi_1"
6719 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6720 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6721 (match_operand:SI 2 "general_operand" "ri,rm")))
6722 (clobber (reg:CC 17))]
6723 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6724 "sub{l}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "SI")])
6727
6728 (define_insn "*subsi_1_zext"
6729 [(set (match_operand:DI 0 "register_operand" "=r")
6730 (zero_extend:DI
6731 (minus:SI (match_operand:SI 1 "register_operand" "0")
6732 (match_operand:SI 2 "general_operand" "rim"))))
6733 (clobber (reg:CC 17))]
6734 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6738
6739 (define_insn "*subsi_2"
6740 [(set (reg 17)
6741 (compare
6742 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6743 (match_operand:SI 2 "general_operand" "ri,rm"))
6744 (const_int 0)))
6745 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6746 (minus:SI (match_dup 1) (match_dup 2)))]
6747 "ix86_match_ccmode (insn, CCGOCmode)
6748 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6749 "sub{l}\t{%2, %0|%0, %2}"
6750 [(set_attr "type" "alu")
6751 (set_attr "mode" "SI")])
6752
6753 (define_insn "*subsi_2_zext"
6754 [(set (reg 17)
6755 (compare
6756 (minus:SI (match_operand:SI 1 "register_operand" "0")
6757 (match_operand:SI 2 "general_operand" "rim"))
6758 (const_int 0)))
6759 (set (match_operand:DI 0 "register_operand" "=r")
6760 (zero_extend:DI
6761 (minus:SI (match_dup 1)
6762 (match_dup 2))))]
6763 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6764 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6765 "sub{l}\t{%2, %k0|%k0, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "mode" "SI")])
6768
6769 (define_insn "*subsi_3"
6770 [(set (reg 17)
6771 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6772 (match_operand:SI 2 "general_operand" "ri,rm")))
6773 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6774 (minus:SI (match_dup 1) (match_dup 2)))]
6775 "ix86_match_ccmode (insn, CCmode)
6776 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777 "sub{l}\t{%2, %0|%0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "mode" "SI")])
6780
6781 (define_insn "*subsi_3_zext"
6782 [(set (reg 17)
6783 (compare (match_operand:SI 1 "register_operand" "0")
6784 (match_operand:SI 2 "general_operand" "rim")))
6785 (set (match_operand:DI 0 "register_operand" "=r")
6786 (zero_extend:DI
6787 (minus:SI (match_dup 1)
6788 (match_dup 2))))]
6789 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6790 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6791 "sub{q}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "DI")])
6794
6795 (define_expand "subhi3"
6796 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6797 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6798 (match_operand:HI 2 "general_operand" "")))
6799 (clobber (reg:CC 17))])]
6800 "TARGET_HIMODE_MATH"
6801 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6802
6803 (define_insn "*subhi_1"
6804 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6805 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6806 (match_operand:HI 2 "general_operand" "ri,rm")))
6807 (clobber (reg:CC 17))]
6808 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6809 "sub{w}\t{%2, %0|%0, %2}"
6810 [(set_attr "type" "alu")
6811 (set_attr "mode" "HI")])
6812
6813 (define_insn "*subhi_2"
6814 [(set (reg 17)
6815 (compare
6816 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6817 (match_operand:HI 2 "general_operand" "ri,rm"))
6818 (const_int 0)))
6819 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6820 (minus:HI (match_dup 1) (match_dup 2)))]
6821 "ix86_match_ccmode (insn, CCGOCmode)
6822 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6823 "sub{w}\t{%2, %0|%0, %2}"
6824 [(set_attr "type" "alu")
6825 (set_attr "mode" "HI")])
6826
6827 (define_insn "*subhi_3"
6828 [(set (reg 17)
6829 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6830 (match_operand:HI 2 "general_operand" "ri,rm")))
6831 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6832 (minus:HI (match_dup 1) (match_dup 2)))]
6833 "ix86_match_ccmode (insn, CCmode)
6834 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6835 "sub{w}\t{%2, %0|%0, %2}"
6836 [(set_attr "type" "alu")
6837 (set_attr "mode" "HI")])
6838
6839 (define_expand "subqi3"
6840 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6841 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6842 (match_operand:QI 2 "general_operand" "")))
6843 (clobber (reg:CC 17))])]
6844 "TARGET_QIMODE_MATH"
6845 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6846
6847 (define_insn "*subqi_1"
6848 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6849 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6850 (match_operand:QI 2 "general_operand" "qn,qmn")))
6851 (clobber (reg:CC 17))]
6852 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6853 "sub{b}\t{%2, %0|%0, %2}"
6854 [(set_attr "type" "alu")
6855 (set_attr "mode" "QI")])
6856
6857 (define_insn "*subqi_1_slp"
6858 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6859 (minus:QI (match_dup 0)
6860 (match_operand:QI 1 "general_operand" "qn,qmn")))
6861 (clobber (reg:CC 17))]
6862 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6863 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6864 "sub{b}\t{%1, %0|%0, %1}"
6865 [(set_attr "type" "alu1")
6866 (set_attr "mode" "QI")])
6867
6868 (define_insn "*subqi_2"
6869 [(set (reg 17)
6870 (compare
6871 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6872 (match_operand:QI 2 "general_operand" "qi,qm"))
6873 (const_int 0)))
6874 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6875 (minus:HI (match_dup 1) (match_dup 2)))]
6876 "ix86_match_ccmode (insn, CCGOCmode)
6877 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6878 "sub{b}\t{%2, %0|%0, %2}"
6879 [(set_attr "type" "alu")
6880 (set_attr "mode" "QI")])
6881
6882 (define_insn "*subqi_3"
6883 [(set (reg 17)
6884 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6885 (match_operand:QI 2 "general_operand" "qi,qm")))
6886 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6887 (minus:HI (match_dup 1) (match_dup 2)))]
6888 "ix86_match_ccmode (insn, CCmode)
6889 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6890 "sub{b}\t{%2, %0|%0, %2}"
6891 [(set_attr "type" "alu")
6892 (set_attr "mode" "QI")])
6893
6894 ;; The patterns that match these are at the end of this file.
6895
6896 (define_expand "subxf3"
6897 [(set (match_operand:XF 0 "register_operand" "")
6898 (minus:XF (match_operand:XF 1 "register_operand" "")
6899 (match_operand:XF 2 "register_operand" "")))]
6900 "TARGET_80387"
6901 "")
6902
6903 (define_expand "subdf3"
6904 [(set (match_operand:DF 0 "register_operand" "")
6905 (minus:DF (match_operand:DF 1 "register_operand" "")
6906 (match_operand:DF 2 "nonimmediate_operand" "")))]
6907 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6908 "")
6909
6910 (define_expand "subsf3"
6911 [(set (match_operand:SF 0 "register_operand" "")
6912 (minus:SF (match_operand:SF 1 "register_operand" "")
6913 (match_operand:SF 2 "nonimmediate_operand" "")))]
6914 "TARGET_80387 || TARGET_SSE_MATH"
6915 "")
6916 \f
6917 ;; Multiply instructions
6918
6919 (define_expand "muldi3"
6920 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6921 (mult:DI (match_operand:DI 1 "register_operand" "")
6922 (match_operand:DI 2 "x86_64_general_operand" "")))
6923 (clobber (reg:CC 17))])]
6924 "TARGET_64BIT"
6925 "")
6926
6927 (define_insn "*muldi3_1_rex64"
6928 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6929 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6930 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6931 (clobber (reg:CC 17))]
6932 "TARGET_64BIT
6933 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6934 "@
6935 imul{q}\t{%2, %1, %0|%0, %1, %2}
6936 imul{q}\t{%2, %1, %0|%0, %1, %2}
6937 imul{q}\t{%2, %0|%0, %2}"
6938 [(set_attr "type" "imul")
6939 (set_attr "prefix_0f" "0,0,1")
6940 (set (attr "athlon_decode")
6941 (cond [(eq_attr "cpu" "athlon")
6942 (const_string "vector")
6943 (eq_attr "alternative" "1")
6944 (const_string "vector")
6945 (and (eq_attr "alternative" "2")
6946 (match_operand 1 "memory_operand" ""))
6947 (const_string "vector")]
6948 (const_string "direct")))
6949 (set_attr "mode" "DI")])
6950
6951 (define_expand "mulsi3"
6952 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6953 (mult:SI (match_operand:SI 1 "register_operand" "")
6954 (match_operand:SI 2 "general_operand" "")))
6955 (clobber (reg:CC 17))])]
6956 ""
6957 "")
6958
6959 (define_insn "*mulsi3_1"
6960 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6961 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6962 (match_operand:SI 2 "general_operand" "K,i,mr")))
6963 (clobber (reg:CC 17))]
6964 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6965 "@
6966 imul{l}\t{%2, %1, %0|%0, %1, %2}
6967 imul{l}\t{%2, %1, %0|%0, %1, %2}
6968 imul{l}\t{%2, %0|%0, %2}"
6969 [(set_attr "type" "imul")
6970 (set_attr "prefix_0f" "0,0,1")
6971 (set (attr "athlon_decode")
6972 (cond [(eq_attr "cpu" "athlon")
6973 (const_string "vector")
6974 (eq_attr "alternative" "1")
6975 (const_string "vector")
6976 (and (eq_attr "alternative" "2")
6977 (match_operand 1 "memory_operand" ""))
6978 (const_string "vector")]
6979 (const_string "direct")))
6980 (set_attr "mode" "SI")])
6981
6982 (define_insn "*mulsi3_1_zext"
6983 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6984 (zero_extend:DI
6985 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6986 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6987 (clobber (reg:CC 17))]
6988 "TARGET_64BIT
6989 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6990 "@
6991 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6992 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6993 imul{l}\t{%2, %k0|%k0, %2}"
6994 [(set_attr "type" "imul")
6995 (set_attr "prefix_0f" "0,0,1")
6996 (set (attr "athlon_decode")
6997 (cond [(eq_attr "cpu" "athlon")
6998 (const_string "vector")
6999 (eq_attr "alternative" "1")
7000 (const_string "vector")
7001 (and (eq_attr "alternative" "2")
7002 (match_operand 1 "memory_operand" ""))
7003 (const_string "vector")]
7004 (const_string "direct")))
7005 (set_attr "mode" "SI")])
7006
7007 (define_expand "mulhi3"
7008 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7009 (mult:HI (match_operand:HI 1 "register_operand" "")
7010 (match_operand:HI 2 "general_operand" "")))
7011 (clobber (reg:CC 17))])]
7012 "TARGET_HIMODE_MATH"
7013 "")
7014
7015 (define_insn "*mulhi3_1"
7016 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7017 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7018 (match_operand:HI 2 "general_operand" "K,i,mr")))
7019 (clobber (reg:CC 17))]
7020 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7021 "@
7022 imul{w}\t{%2, %1, %0|%0, %1, %2}
7023 imul{w}\t{%2, %1, %0|%0, %1, %2}
7024 imul{w}\t{%2, %0|%0, %2}"
7025 [(set_attr "type" "imul")
7026 (set_attr "prefix_0f" "0,0,1")
7027 (set (attr "athlon_decode")
7028 (cond [(eq_attr "cpu" "athlon")
7029 (const_string "vector")
7030 (eq_attr "alternative" "1,2")
7031 (const_string "vector")]
7032 (const_string "direct")))
7033 (set_attr "mode" "HI")])
7034
7035 (define_expand "mulqi3"
7036 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7037 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7038 (match_operand:QI 2 "register_operand" "")))
7039 (clobber (reg:CC 17))])]
7040 "TARGET_QIMODE_MATH"
7041 "")
7042
7043 (define_insn "*mulqi3_1"
7044 [(set (match_operand:QI 0 "register_operand" "=a")
7045 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7046 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7047 (clobber (reg:CC 17))]
7048 "TARGET_QIMODE_MATH
7049 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7050 "mul{b}\t%2"
7051 [(set_attr "type" "imul")
7052 (set_attr "length_immediate" "0")
7053 (set (attr "athlon_decode")
7054 (if_then_else (eq_attr "cpu" "athlon")
7055 (const_string "vector")
7056 (const_string "direct")))
7057 (set_attr "mode" "QI")])
7058
7059 (define_expand "umulqihi3"
7060 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7061 (mult:HI (zero_extend:HI
7062 (match_operand:QI 1 "nonimmediate_operand" ""))
7063 (zero_extend:HI
7064 (match_operand:QI 2 "register_operand" ""))))
7065 (clobber (reg:CC 17))])]
7066 "TARGET_QIMODE_MATH"
7067 "")
7068
7069 (define_insn "*umulqihi3_1"
7070 [(set (match_operand:HI 0 "register_operand" "=a")
7071 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7072 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7073 (clobber (reg:CC 17))]
7074 "TARGET_QIMODE_MATH
7075 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7076 "mul{b}\t%2"
7077 [(set_attr "type" "imul")
7078 (set_attr "length_immediate" "0")
7079 (set (attr "athlon_decode")
7080 (if_then_else (eq_attr "cpu" "athlon")
7081 (const_string "vector")
7082 (const_string "direct")))
7083 (set_attr "mode" "QI")])
7084
7085 (define_expand "mulqihi3"
7086 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7087 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7088 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7089 (clobber (reg:CC 17))])]
7090 "TARGET_QIMODE_MATH"
7091 "")
7092
7093 (define_insn "*mulqihi3_insn"
7094 [(set (match_operand:HI 0 "register_operand" "=a")
7095 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7096 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7097 (clobber (reg:CC 17))]
7098 "TARGET_QIMODE_MATH
7099 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7100 "imul{b}\t%2"
7101 [(set_attr "type" "imul")
7102 (set_attr "length_immediate" "0")
7103 (set (attr "athlon_decode")
7104 (if_then_else (eq_attr "cpu" "athlon")
7105 (const_string "vector")
7106 (const_string "direct")))
7107 (set_attr "mode" "QI")])
7108
7109 (define_expand "umulditi3"
7110 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7111 (mult:TI (zero_extend:TI
7112 (match_operand:DI 1 "nonimmediate_operand" ""))
7113 (zero_extend:TI
7114 (match_operand:DI 2 "register_operand" ""))))
7115 (clobber (reg:CC 17))])]
7116 "TARGET_64BIT"
7117 "")
7118
7119 (define_insn "*umulditi3_insn"
7120 [(set (match_operand:TI 0 "register_operand" "=A")
7121 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7122 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7123 (clobber (reg:CC 17))]
7124 "TARGET_64BIT
7125 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7126 "mul{q}\t%2"
7127 [(set_attr "type" "imul")
7128 (set_attr "length_immediate" "0")
7129 (set (attr "athlon_decode")
7130 (if_then_else (eq_attr "cpu" "athlon")
7131 (const_string "vector")
7132 (const_string "double")))
7133 (set_attr "mode" "DI")])
7134
7135 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7136 (define_expand "umulsidi3"
7137 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7138 (mult:DI (zero_extend:DI
7139 (match_operand:SI 1 "nonimmediate_operand" ""))
7140 (zero_extend:DI
7141 (match_operand:SI 2 "register_operand" ""))))
7142 (clobber (reg:CC 17))])]
7143 "!TARGET_64BIT"
7144 "")
7145
7146 (define_insn "*umulsidi3_insn"
7147 [(set (match_operand:DI 0 "register_operand" "=A")
7148 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7149 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7150 (clobber (reg:CC 17))]
7151 "!TARGET_64BIT
7152 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7153 "mul{l}\t%2"
7154 [(set_attr "type" "imul")
7155 (set_attr "length_immediate" "0")
7156 (set (attr "athlon_decode")
7157 (if_then_else (eq_attr "cpu" "athlon")
7158 (const_string "vector")
7159 (const_string "double")))
7160 (set_attr "mode" "SI")])
7161
7162 (define_expand "mulditi3"
7163 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7164 (mult:TI (sign_extend:TI
7165 (match_operand:DI 1 "nonimmediate_operand" ""))
7166 (sign_extend:TI
7167 (match_operand:DI 2 "register_operand" ""))))
7168 (clobber (reg:CC 17))])]
7169 "TARGET_64BIT"
7170 "")
7171
7172 (define_insn "*mulditi3_insn"
7173 [(set (match_operand:TI 0 "register_operand" "=A")
7174 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7175 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7176 (clobber (reg:CC 17))]
7177 "TARGET_64BIT
7178 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7179 "imul{q}\t%2"
7180 [(set_attr "type" "imul")
7181 (set_attr "length_immediate" "0")
7182 (set (attr "athlon_decode")
7183 (if_then_else (eq_attr "cpu" "athlon")
7184 (const_string "vector")
7185 (const_string "double")))
7186 (set_attr "mode" "DI")])
7187
7188 (define_expand "mulsidi3"
7189 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7190 (mult:DI (sign_extend:DI
7191 (match_operand:SI 1 "nonimmediate_operand" ""))
7192 (sign_extend:DI
7193 (match_operand:SI 2 "register_operand" ""))))
7194 (clobber (reg:CC 17))])]
7195 "!TARGET_64BIT"
7196 "")
7197
7198 (define_insn "*mulsidi3_insn"
7199 [(set (match_operand:DI 0 "register_operand" "=A")
7200 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7201 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7202 (clobber (reg:CC 17))]
7203 "!TARGET_64BIT
7204 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7205 "imul{l}\t%2"
7206 [(set_attr "type" "imul")
7207 (set_attr "length_immediate" "0")
7208 (set (attr "athlon_decode")
7209 (if_then_else (eq_attr "cpu" "athlon")
7210 (const_string "vector")
7211 (const_string "double")))
7212 (set_attr "mode" "SI")])
7213
7214 (define_expand "umuldi3_highpart"
7215 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7216 (truncate:DI
7217 (lshiftrt:TI
7218 (mult:TI (zero_extend:TI
7219 (match_operand:DI 1 "nonimmediate_operand" ""))
7220 (zero_extend:TI
7221 (match_operand:DI 2 "register_operand" "")))
7222 (const_int 64))))
7223 (clobber (match_scratch:DI 3 ""))
7224 (clobber (reg:CC 17))])]
7225 "TARGET_64BIT"
7226 "")
7227
7228 (define_insn "*umuldi3_highpart_rex64"
7229 [(set (match_operand:DI 0 "register_operand" "=d")
7230 (truncate:DI
7231 (lshiftrt:TI
7232 (mult:TI (zero_extend:TI
7233 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7234 (zero_extend:TI
7235 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7236 (const_int 64))))
7237 (clobber (match_scratch:DI 3 "=1"))
7238 (clobber (reg:CC 17))]
7239 "TARGET_64BIT
7240 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7241 "mul{q}\t%2"
7242 [(set_attr "type" "imul")
7243 (set_attr "length_immediate" "0")
7244 (set (attr "athlon_decode")
7245 (if_then_else (eq_attr "cpu" "athlon")
7246 (const_string "vector")
7247 (const_string "double")))
7248 (set_attr "mode" "DI")])
7249
7250 (define_expand "umulsi3_highpart"
7251 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7252 (truncate:SI
7253 (lshiftrt:DI
7254 (mult:DI (zero_extend:DI
7255 (match_operand:SI 1 "nonimmediate_operand" ""))
7256 (zero_extend:DI
7257 (match_operand:SI 2 "register_operand" "")))
7258 (const_int 32))))
7259 (clobber (match_scratch:SI 3 ""))
7260 (clobber (reg:CC 17))])]
7261 ""
7262 "")
7263
7264 (define_insn "*umulsi3_highpart_insn"
7265 [(set (match_operand:SI 0 "register_operand" "=d")
7266 (truncate:SI
7267 (lshiftrt:DI
7268 (mult:DI (zero_extend:DI
7269 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7270 (zero_extend:DI
7271 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7272 (const_int 32))))
7273 (clobber (match_scratch:SI 3 "=1"))
7274 (clobber (reg:CC 17))]
7275 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7276 "mul{l}\t%2"
7277 [(set_attr "type" "imul")
7278 (set_attr "length_immediate" "0")
7279 (set (attr "athlon_decode")
7280 (if_then_else (eq_attr "cpu" "athlon")
7281 (const_string "vector")
7282 (const_string "double")))
7283 (set_attr "mode" "SI")])
7284
7285 (define_insn "*umulsi3_highpart_zext"
7286 [(set (match_operand:DI 0 "register_operand" "=d")
7287 (zero_extend:DI (truncate:SI
7288 (lshiftrt:DI
7289 (mult:DI (zero_extend:DI
7290 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7291 (zero_extend:DI
7292 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7293 (const_int 32)))))
7294 (clobber (match_scratch:SI 3 "=1"))
7295 (clobber (reg:CC 17))]
7296 "TARGET_64BIT
7297 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7298 "mul{l}\t%2"
7299 [(set_attr "type" "imul")
7300 (set_attr "length_immediate" "0")
7301 (set (attr "athlon_decode")
7302 (if_then_else (eq_attr "cpu" "athlon")
7303 (const_string "vector")
7304 (const_string "double")))
7305 (set_attr "mode" "SI")])
7306
7307 (define_expand "smuldi3_highpart"
7308 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7309 (truncate:DI
7310 (lshiftrt:TI
7311 (mult:TI (sign_extend:TI
7312 (match_operand:DI 1 "nonimmediate_operand" ""))
7313 (sign_extend:TI
7314 (match_operand:DI 2 "register_operand" "")))
7315 (const_int 64))))
7316 (clobber (match_scratch:DI 3 ""))
7317 (clobber (reg:CC 17))])]
7318 "TARGET_64BIT"
7319 "")
7320
7321 (define_insn "*smuldi3_highpart_rex64"
7322 [(set (match_operand:DI 0 "register_operand" "=d")
7323 (truncate:DI
7324 (lshiftrt:TI
7325 (mult:TI (sign_extend:TI
7326 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7327 (sign_extend:TI
7328 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7329 (const_int 64))))
7330 (clobber (match_scratch:DI 3 "=1"))
7331 (clobber (reg:CC 17))]
7332 "TARGET_64BIT
7333 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7334 "imul{q}\t%2"
7335 [(set_attr "type" "imul")
7336 (set (attr "athlon_decode")
7337 (if_then_else (eq_attr "cpu" "athlon")
7338 (const_string "vector")
7339 (const_string "double")))
7340 (set_attr "mode" "DI")])
7341
7342 (define_expand "smulsi3_highpart"
7343 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7344 (truncate:SI
7345 (lshiftrt:DI
7346 (mult:DI (sign_extend:DI
7347 (match_operand:SI 1 "nonimmediate_operand" ""))
7348 (sign_extend:DI
7349 (match_operand:SI 2 "register_operand" "")))
7350 (const_int 32))))
7351 (clobber (match_scratch:SI 3 ""))
7352 (clobber (reg:CC 17))])]
7353 ""
7354 "")
7355
7356 (define_insn "*smulsi3_highpart_insn"
7357 [(set (match_operand:SI 0 "register_operand" "=d")
7358 (truncate:SI
7359 (lshiftrt:DI
7360 (mult:DI (sign_extend:DI
7361 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7362 (sign_extend:DI
7363 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7364 (const_int 32))))
7365 (clobber (match_scratch:SI 3 "=1"))
7366 (clobber (reg:CC 17))]
7367 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7368 "imul{l}\t%2"
7369 [(set_attr "type" "imul")
7370 (set (attr "athlon_decode")
7371 (if_then_else (eq_attr "cpu" "athlon")
7372 (const_string "vector")
7373 (const_string "double")))
7374 (set_attr "mode" "SI")])
7375
7376 (define_insn "*smulsi3_highpart_zext"
7377 [(set (match_operand:DI 0 "register_operand" "=d")
7378 (zero_extend:DI (truncate:SI
7379 (lshiftrt:DI
7380 (mult:DI (sign_extend:DI
7381 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7382 (sign_extend:DI
7383 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7384 (const_int 32)))))
7385 (clobber (match_scratch:SI 3 "=1"))
7386 (clobber (reg:CC 17))]
7387 "TARGET_64BIT
7388 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7389 "imul{l}\t%2"
7390 [(set_attr "type" "imul")
7391 (set (attr "athlon_decode")
7392 (if_then_else (eq_attr "cpu" "athlon")
7393 (const_string "vector")
7394 (const_string "double")))
7395 (set_attr "mode" "SI")])
7396
7397 ;; The patterns that match these are at the end of this file.
7398
7399 (define_expand "mulxf3"
7400 [(set (match_operand:XF 0 "register_operand" "")
7401 (mult:XF (match_operand:XF 1 "register_operand" "")
7402 (match_operand:XF 2 "register_operand" "")))]
7403 "TARGET_80387"
7404 "")
7405
7406 (define_expand "muldf3"
7407 [(set (match_operand:DF 0 "register_operand" "")
7408 (mult:DF (match_operand:DF 1 "register_operand" "")
7409 (match_operand:DF 2 "nonimmediate_operand" "")))]
7410 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7411 "")
7412
7413 (define_expand "mulsf3"
7414 [(set (match_operand:SF 0 "register_operand" "")
7415 (mult:SF (match_operand:SF 1 "register_operand" "")
7416 (match_operand:SF 2 "nonimmediate_operand" "")))]
7417 "TARGET_80387 || TARGET_SSE_MATH"
7418 "")
7419 \f
7420 ;; Divide instructions
7421
7422 (define_insn "divqi3"
7423 [(set (match_operand:QI 0 "register_operand" "=a")
7424 (div:QI (match_operand:HI 1 "register_operand" "0")
7425 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7426 (clobber (reg:CC 17))]
7427 "TARGET_QIMODE_MATH"
7428 "idiv{b}\t%2"
7429 [(set_attr "type" "idiv")
7430 (set_attr "mode" "QI")])
7431
7432 (define_insn "udivqi3"
7433 [(set (match_operand:QI 0 "register_operand" "=a")
7434 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7435 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7436 (clobber (reg:CC 17))]
7437 "TARGET_QIMODE_MATH"
7438 "div{b}\t%2"
7439 [(set_attr "type" "idiv")
7440 (set_attr "mode" "QI")])
7441
7442 ;; The patterns that match these are at the end of this file.
7443
7444 (define_expand "divxf3"
7445 [(set (match_operand:XF 0 "register_operand" "")
7446 (div:XF (match_operand:XF 1 "register_operand" "")
7447 (match_operand:XF 2 "register_operand" "")))]
7448 "TARGET_80387"
7449 "")
7450
7451 (define_expand "divdf3"
7452 [(set (match_operand:DF 0 "register_operand" "")
7453 (div:DF (match_operand:DF 1 "register_operand" "")
7454 (match_operand:DF 2 "nonimmediate_operand" "")))]
7455 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7456 "")
7457
7458 (define_expand "divsf3"
7459 [(set (match_operand:SF 0 "register_operand" "")
7460 (div:SF (match_operand:SF 1 "register_operand" "")
7461 (match_operand:SF 2 "nonimmediate_operand" "")))]
7462 "TARGET_80387 || TARGET_SSE_MATH"
7463 "")
7464 \f
7465 ;; Remainder instructions.
7466
7467 (define_expand "divmoddi4"
7468 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7469 (div:DI (match_operand:DI 1 "register_operand" "")
7470 (match_operand:DI 2 "nonimmediate_operand" "")))
7471 (set (match_operand:DI 3 "register_operand" "")
7472 (mod:DI (match_dup 1) (match_dup 2)))
7473 (clobber (reg:CC 17))])]
7474 "TARGET_64BIT"
7475 "")
7476
7477 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7478 ;; Penalize eax case slightly because it results in worse scheduling
7479 ;; of code.
7480 (define_insn "*divmoddi4_nocltd_rex64"
7481 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7482 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7483 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7484 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7485 (mod:DI (match_dup 2) (match_dup 3)))
7486 (clobber (reg:CC 17))]
7487 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7488 "#"
7489 [(set_attr "type" "multi")])
7490
7491 (define_insn "*divmoddi4_cltd_rex64"
7492 [(set (match_operand:DI 0 "register_operand" "=a")
7493 (div:DI (match_operand:DI 2 "register_operand" "a")
7494 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7495 (set (match_operand:DI 1 "register_operand" "=&d")
7496 (mod:DI (match_dup 2) (match_dup 3)))
7497 (clobber (reg:CC 17))]
7498 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7499 "#"
7500 [(set_attr "type" "multi")])
7501
7502 (define_insn "*divmoddi_noext_rex64"
7503 [(set (match_operand:DI 0 "register_operand" "=a")
7504 (div:DI (match_operand:DI 1 "register_operand" "0")
7505 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7506 (set (match_operand:DI 3 "register_operand" "=d")
7507 (mod:DI (match_dup 1) (match_dup 2)))
7508 (use (match_operand:DI 4 "register_operand" "3"))
7509 (clobber (reg:CC 17))]
7510 "TARGET_64BIT"
7511 "idiv{q}\t%2"
7512 [(set_attr "type" "idiv")
7513 (set_attr "mode" "DI")])
7514
7515 (define_split
7516 [(set (match_operand:DI 0 "register_operand" "")
7517 (div:DI (match_operand:DI 1 "register_operand" "")
7518 (match_operand:DI 2 "nonimmediate_operand" "")))
7519 (set (match_operand:DI 3 "register_operand" "")
7520 (mod:DI (match_dup 1) (match_dup 2)))
7521 (clobber (reg:CC 17))]
7522 "TARGET_64BIT && reload_completed"
7523 [(parallel [(set (match_dup 3)
7524 (ashiftrt:DI (match_dup 4) (const_int 63)))
7525 (clobber (reg:CC 17))])
7526 (parallel [(set (match_dup 0)
7527 (div:DI (reg:DI 0) (match_dup 2)))
7528 (set (match_dup 3)
7529 (mod:DI (reg:DI 0) (match_dup 2)))
7530 (use (match_dup 3))
7531 (clobber (reg:CC 17))])]
7532 {
7533 /* Avoid use of cltd in favor of a mov+shift. */
7534 if (!TARGET_USE_CLTD && !optimize_size)
7535 {
7536 if (true_regnum (operands[1]))
7537 emit_move_insn (operands[0], operands[1]);
7538 else
7539 emit_move_insn (operands[3], operands[1]);
7540 operands[4] = operands[3];
7541 }
7542 else
7543 {
7544 if (true_regnum (operands[1]))
7545 abort();
7546 operands[4] = operands[1];
7547 }
7548 })
7549
7550
7551 (define_expand "divmodsi4"
7552 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7553 (div:SI (match_operand:SI 1 "register_operand" "")
7554 (match_operand:SI 2 "nonimmediate_operand" "")))
7555 (set (match_operand:SI 3 "register_operand" "")
7556 (mod:SI (match_dup 1) (match_dup 2)))
7557 (clobber (reg:CC 17))])]
7558 ""
7559 "")
7560
7561 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7562 ;; Penalize eax case slightly because it results in worse scheduling
7563 ;; of code.
7564 (define_insn "*divmodsi4_nocltd"
7565 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7566 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7567 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7568 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7569 (mod:SI (match_dup 2) (match_dup 3)))
7570 (clobber (reg:CC 17))]
7571 "!optimize_size && !TARGET_USE_CLTD"
7572 "#"
7573 [(set_attr "type" "multi")])
7574
7575 (define_insn "*divmodsi4_cltd"
7576 [(set (match_operand:SI 0 "register_operand" "=a")
7577 (div:SI (match_operand:SI 2 "register_operand" "a")
7578 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7579 (set (match_operand:SI 1 "register_operand" "=&d")
7580 (mod:SI (match_dup 2) (match_dup 3)))
7581 (clobber (reg:CC 17))]
7582 "optimize_size || TARGET_USE_CLTD"
7583 "#"
7584 [(set_attr "type" "multi")])
7585
7586 (define_insn "*divmodsi_noext"
7587 [(set (match_operand:SI 0 "register_operand" "=a")
7588 (div:SI (match_operand:SI 1 "register_operand" "0")
7589 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7590 (set (match_operand:SI 3 "register_operand" "=d")
7591 (mod:SI (match_dup 1) (match_dup 2)))
7592 (use (match_operand:SI 4 "register_operand" "3"))
7593 (clobber (reg:CC 17))]
7594 ""
7595 "idiv{l}\t%2"
7596 [(set_attr "type" "idiv")
7597 (set_attr "mode" "SI")])
7598
7599 (define_split
7600 [(set (match_operand:SI 0 "register_operand" "")
7601 (div:SI (match_operand:SI 1 "register_operand" "")
7602 (match_operand:SI 2 "nonimmediate_operand" "")))
7603 (set (match_operand:SI 3 "register_operand" "")
7604 (mod:SI (match_dup 1) (match_dup 2)))
7605 (clobber (reg:CC 17))]
7606 "reload_completed"
7607 [(parallel [(set (match_dup 3)
7608 (ashiftrt:SI (match_dup 4) (const_int 31)))
7609 (clobber (reg:CC 17))])
7610 (parallel [(set (match_dup 0)
7611 (div:SI (reg:SI 0) (match_dup 2)))
7612 (set (match_dup 3)
7613 (mod:SI (reg:SI 0) (match_dup 2)))
7614 (use (match_dup 3))
7615 (clobber (reg:CC 17))])]
7616 {
7617 /* Avoid use of cltd in favor of a mov+shift. */
7618 if (!TARGET_USE_CLTD && !optimize_size)
7619 {
7620 if (true_regnum (operands[1]))
7621 emit_move_insn (operands[0], operands[1]);
7622 else
7623 emit_move_insn (operands[3], operands[1]);
7624 operands[4] = operands[3];
7625 }
7626 else
7627 {
7628 if (true_regnum (operands[1]))
7629 abort();
7630 operands[4] = operands[1];
7631 }
7632 })
7633 ;; %%% Split me.
7634 (define_insn "divmodhi4"
7635 [(set (match_operand:HI 0 "register_operand" "=a")
7636 (div:HI (match_operand:HI 1 "register_operand" "0")
7637 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7638 (set (match_operand:HI 3 "register_operand" "=&d")
7639 (mod:HI (match_dup 1) (match_dup 2)))
7640 (clobber (reg:CC 17))]
7641 "TARGET_HIMODE_MATH"
7642 "cwtd\;idiv{w}\t%2"
7643 [(set_attr "type" "multi")
7644 (set_attr "length_immediate" "0")
7645 (set_attr "mode" "SI")])
7646
7647 (define_insn "udivmoddi4"
7648 [(set (match_operand:DI 0 "register_operand" "=a")
7649 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7650 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7651 (set (match_operand:DI 3 "register_operand" "=&d")
7652 (umod:DI (match_dup 1) (match_dup 2)))
7653 (clobber (reg:CC 17))]
7654 "TARGET_64BIT"
7655 "xor{q}\t%3, %3\;div{q}\t%2"
7656 [(set_attr "type" "multi")
7657 (set_attr "length_immediate" "0")
7658 (set_attr "mode" "DI")])
7659
7660 (define_insn "*udivmoddi4_noext"
7661 [(set (match_operand:DI 0 "register_operand" "=a")
7662 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7663 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7664 (set (match_operand:DI 3 "register_operand" "=d")
7665 (umod:DI (match_dup 1) (match_dup 2)))
7666 (use (match_dup 3))
7667 (clobber (reg:CC 17))]
7668 "TARGET_64BIT"
7669 "div{q}\t%2"
7670 [(set_attr "type" "idiv")
7671 (set_attr "mode" "DI")])
7672
7673 (define_split
7674 [(set (match_operand:DI 0 "register_operand" "")
7675 (udiv:DI (match_operand:DI 1 "register_operand" "")
7676 (match_operand:DI 2 "nonimmediate_operand" "")))
7677 (set (match_operand:DI 3 "register_operand" "")
7678 (umod:DI (match_dup 1) (match_dup 2)))
7679 (clobber (reg:CC 17))]
7680 "TARGET_64BIT && reload_completed"
7681 [(set (match_dup 3) (const_int 0))
7682 (parallel [(set (match_dup 0)
7683 (udiv:DI (match_dup 1) (match_dup 2)))
7684 (set (match_dup 3)
7685 (umod:DI (match_dup 1) (match_dup 2)))
7686 (use (match_dup 3))
7687 (clobber (reg:CC 17))])]
7688 "")
7689
7690 (define_insn "udivmodsi4"
7691 [(set (match_operand:SI 0 "register_operand" "=a")
7692 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7693 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7694 (set (match_operand:SI 3 "register_operand" "=&d")
7695 (umod:SI (match_dup 1) (match_dup 2)))
7696 (clobber (reg:CC 17))]
7697 ""
7698 "xor{l}\t%3, %3\;div{l}\t%2"
7699 [(set_attr "type" "multi")
7700 (set_attr "length_immediate" "0")
7701 (set_attr "mode" "SI")])
7702
7703 (define_insn "*udivmodsi4_noext"
7704 [(set (match_operand:SI 0 "register_operand" "=a")
7705 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7706 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7707 (set (match_operand:SI 3 "register_operand" "=d")
7708 (umod:SI (match_dup 1) (match_dup 2)))
7709 (use (match_dup 3))
7710 (clobber (reg:CC 17))]
7711 ""
7712 "div{l}\t%2"
7713 [(set_attr "type" "idiv")
7714 (set_attr "mode" "SI")])
7715
7716 (define_split
7717 [(set (match_operand:SI 0 "register_operand" "")
7718 (udiv:SI (match_operand:SI 1 "register_operand" "")
7719 (match_operand:SI 2 "nonimmediate_operand" "")))
7720 (set (match_operand:SI 3 "register_operand" "")
7721 (umod:SI (match_dup 1) (match_dup 2)))
7722 (clobber (reg:CC 17))]
7723 "reload_completed"
7724 [(set (match_dup 3) (const_int 0))
7725 (parallel [(set (match_dup 0)
7726 (udiv:SI (match_dup 1) (match_dup 2)))
7727 (set (match_dup 3)
7728 (umod:SI (match_dup 1) (match_dup 2)))
7729 (use (match_dup 3))
7730 (clobber (reg:CC 17))])]
7731 "")
7732
7733 (define_expand "udivmodhi4"
7734 [(set (match_dup 4) (const_int 0))
7735 (parallel [(set (match_operand:HI 0 "register_operand" "")
7736 (udiv:HI (match_operand:HI 1 "register_operand" "")
7737 (match_operand:HI 2 "nonimmediate_operand" "")))
7738 (set (match_operand:HI 3 "register_operand" "")
7739 (umod:HI (match_dup 1) (match_dup 2)))
7740 (use (match_dup 4))
7741 (clobber (reg:CC 17))])]
7742 "TARGET_HIMODE_MATH"
7743 "operands[4] = gen_reg_rtx (HImode);")
7744
7745 (define_insn "*udivmodhi_noext"
7746 [(set (match_operand:HI 0 "register_operand" "=a")
7747 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7748 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7749 (set (match_operand:HI 3 "register_operand" "=d")
7750 (umod:HI (match_dup 1) (match_dup 2)))
7751 (use (match_operand:HI 4 "register_operand" "3"))
7752 (clobber (reg:CC 17))]
7753 ""
7754 "div{w}\t%2"
7755 [(set_attr "type" "idiv")
7756 (set_attr "mode" "HI")])
7757
7758 ;; We can not use div/idiv for double division, because it causes
7759 ;; "division by zero" on the overflow and that's not what we expect
7760 ;; from truncate. Because true (non truncating) double division is
7761 ;; never generated, we can't create this insn anyway.
7762 ;
7763 ;(define_insn ""
7764 ; [(set (match_operand:SI 0 "register_operand" "=a")
7765 ; (truncate:SI
7766 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7767 ; (zero_extend:DI
7768 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7769 ; (set (match_operand:SI 3 "register_operand" "=d")
7770 ; (truncate:SI
7771 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7772 ; (clobber (reg:CC 17))]
7773 ; ""
7774 ; "div{l}\t{%2, %0|%0, %2}"
7775 ; [(set_attr "type" "idiv")])
7776 \f
7777 ;;- Logical AND instructions
7778
7779 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7780 ;; Note that this excludes ah.
7781
7782 (define_insn "*testdi_1_rex64"
7783 [(set (reg 17)
7784 (compare
7785 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7786 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7787 (const_int 0)))]
7788 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7789 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7790 "@
7791 test{l}\t{%k1, %k0|%k0, %k1}
7792 test{l}\t{%k1, %k0|%k0, %k1}
7793 test{q}\t{%1, %0|%0, %1}
7794 test{q}\t{%1, %0|%0, %1}
7795 test{q}\t{%1, %0|%0, %1}"
7796 [(set_attr "type" "test")
7797 (set_attr "modrm" "0,1,0,1,1")
7798 (set_attr "mode" "SI,SI,DI,DI,DI")
7799 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7800
7801 (define_insn "testsi_1"
7802 [(set (reg 17)
7803 (compare
7804 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7805 (match_operand:SI 1 "general_operand" "in,in,rin"))
7806 (const_int 0)))]
7807 "ix86_match_ccmode (insn, CCNOmode)
7808 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7809 "test{l}\t{%1, %0|%0, %1}"
7810 [(set_attr "type" "test")
7811 (set_attr "modrm" "0,1,1")
7812 (set_attr "mode" "SI")
7813 (set_attr "pent_pair" "uv,np,uv")])
7814
7815 (define_expand "testsi_ccno_1"
7816 [(set (reg:CCNO 17)
7817 (compare:CCNO
7818 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7819 (match_operand:SI 1 "nonmemory_operand" ""))
7820 (const_int 0)))]
7821 ""
7822 "")
7823
7824 (define_insn "*testhi_1"
7825 [(set (reg 17)
7826 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7827 (match_operand:HI 1 "general_operand" "n,n,rn"))
7828 (const_int 0)))]
7829 "ix86_match_ccmode (insn, CCNOmode)
7830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7831 "test{w}\t{%1, %0|%0, %1}"
7832 [(set_attr "type" "test")
7833 (set_attr "modrm" "0,1,1")
7834 (set_attr "mode" "HI")
7835 (set_attr "pent_pair" "uv,np,uv")])
7836
7837 (define_expand "testqi_ccz_1"
7838 [(set (reg:CCZ 17)
7839 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7840 (match_operand:QI 1 "nonmemory_operand" ""))
7841 (const_int 0)))]
7842 ""
7843 "")
7844
7845 (define_insn "*testqi_1"
7846 [(set (reg 17)
7847 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7848 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7849 (const_int 0)))]
7850 "ix86_match_ccmode (insn, CCNOmode)
7851 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7852 {
7853 if (which_alternative == 3)
7854 {
7855 if (GET_CODE (operands[1]) == CONST_INT
7856 && (INTVAL (operands[1]) & 0xffffff00))
7857 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7858 return "test{l}\t{%1, %k0|%k0, %1}";
7859 }
7860 return "test{b}\t{%1, %0|%0, %1}";
7861 }
7862 [(set_attr "type" "test")
7863 (set_attr "modrm" "0,1,1,1")
7864 (set_attr "mode" "QI,QI,QI,SI")
7865 (set_attr "pent_pair" "uv,np,uv,np")])
7866
7867 (define_expand "testqi_ext_ccno_0"
7868 [(set (reg:CCNO 17)
7869 (compare:CCNO
7870 (and:SI
7871 (zero_extract:SI
7872 (match_operand 0 "ext_register_operand" "")
7873 (const_int 8)
7874 (const_int 8))
7875 (match_operand 1 "const_int_operand" ""))
7876 (const_int 0)))]
7877 ""
7878 "")
7879
7880 (define_insn "*testqi_ext_0"
7881 [(set (reg 17)
7882 (compare
7883 (and:SI
7884 (zero_extract:SI
7885 (match_operand 0 "ext_register_operand" "Q")
7886 (const_int 8)
7887 (const_int 8))
7888 (match_operand 1 "const_int_operand" "n"))
7889 (const_int 0)))]
7890 "ix86_match_ccmode (insn, CCNOmode)"
7891 "test{b}\t{%1, %h0|%h0, %1}"
7892 [(set_attr "type" "test")
7893 (set_attr "mode" "QI")
7894 (set_attr "length_immediate" "1")
7895 (set_attr "pent_pair" "np")])
7896
7897 (define_insn "*testqi_ext_1"
7898 [(set (reg 17)
7899 (compare
7900 (and:SI
7901 (zero_extract:SI
7902 (match_operand 0 "ext_register_operand" "Q")
7903 (const_int 8)
7904 (const_int 8))
7905 (zero_extend:SI
7906 (match_operand:QI 1 "general_operand" "Qm")))
7907 (const_int 0)))]
7908 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7909 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7910 "test{b}\t{%1, %h0|%h0, %1}"
7911 [(set_attr "type" "test")
7912 (set_attr "mode" "QI")])
7913
7914 (define_insn "*testqi_ext_1_rex64"
7915 [(set (reg 17)
7916 (compare
7917 (and:SI
7918 (zero_extract:SI
7919 (match_operand 0 "ext_register_operand" "Q")
7920 (const_int 8)
7921 (const_int 8))
7922 (zero_extend:SI
7923 (match_operand:QI 1 "register_operand" "Q")))
7924 (const_int 0)))]
7925 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7926 "test{b}\t{%1, %h0|%h0, %1}"
7927 [(set_attr "type" "test")
7928 (set_attr "mode" "QI")])
7929
7930 (define_insn "*testqi_ext_2"
7931 [(set (reg 17)
7932 (compare
7933 (and:SI
7934 (zero_extract:SI
7935 (match_operand 0 "ext_register_operand" "Q")
7936 (const_int 8)
7937 (const_int 8))
7938 (zero_extract:SI
7939 (match_operand 1 "ext_register_operand" "Q")
7940 (const_int 8)
7941 (const_int 8)))
7942 (const_int 0)))]
7943 "ix86_match_ccmode (insn, CCNOmode)"
7944 "test{b}\t{%h1, %h0|%h0, %h1}"
7945 [(set_attr "type" "test")
7946 (set_attr "mode" "QI")])
7947
7948 ;; Combine likes to form bit extractions for some tests. Humor it.
7949 (define_insn "*testqi_ext_3"
7950 [(set (reg 17)
7951 (compare (zero_extract:SI
7952 (match_operand 0 "nonimmediate_operand" "rm")
7953 (match_operand:SI 1 "const_int_operand" "")
7954 (match_operand:SI 2 "const_int_operand" ""))
7955 (const_int 0)))]
7956 "ix86_match_ccmode (insn, CCNOmode)
7957 && (GET_MODE (operands[0]) == SImode
7958 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7959 || GET_MODE (operands[0]) == HImode
7960 || GET_MODE (operands[0]) == QImode)"
7961 "#")
7962
7963 (define_insn "*testqi_ext_3_rex64"
7964 [(set (reg 17)
7965 (compare (zero_extract:DI
7966 (match_operand 0 "nonimmediate_operand" "rm")
7967 (match_operand:DI 1 "const_int_operand" "")
7968 (match_operand:DI 2 "const_int_operand" ""))
7969 (const_int 0)))]
7970 "TARGET_64BIT
7971 && ix86_match_ccmode (insn, CCNOmode)
7972 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7973 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7974 /* Ensure that resulting mask is zero or sign extended operand. */
7975 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7976 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7977 && INTVAL (operands[1]) > 32))
7978 && (GET_MODE (operands[0]) == SImode
7979 || GET_MODE (operands[0]) == DImode
7980 || GET_MODE (operands[0]) == HImode
7981 || GET_MODE (operands[0]) == QImode)"
7982 "#")
7983
7984 (define_split
7985 [(set (reg 17)
7986 (compare (zero_extract
7987 (match_operand 0 "nonimmediate_operand" "")
7988 (match_operand 1 "const_int_operand" "")
7989 (match_operand 2 "const_int_operand" ""))
7990 (const_int 0)))]
7991 "ix86_match_ccmode (insn, CCNOmode)"
7992 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7993 {
7994 HOST_WIDE_INT len = INTVAL (operands[1]);
7995 HOST_WIDE_INT pos = INTVAL (operands[2]);
7996 HOST_WIDE_INT mask;
7997 enum machine_mode mode, submode;
7998
7999 mode = GET_MODE (operands[0]);
8000 if (GET_CODE (operands[0]) == MEM)
8001 {
8002 /* ??? Combine likes to put non-volatile mem extractions in QImode
8003 no matter the size of the test. So find a mode that works. */
8004 if (! MEM_VOLATILE_P (operands[0]))
8005 {
8006 mode = smallest_mode_for_size (pos + len, MODE_INT);
8007 operands[0] = adjust_address (operands[0], mode, 0);
8008 }
8009 }
8010 else if (GET_CODE (operands[0]) == SUBREG
8011 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8012 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8013 && pos + len <= GET_MODE_BITSIZE (submode))
8014 {
8015 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8016 mode = submode;
8017 operands[0] = SUBREG_REG (operands[0]);
8018 }
8019 else if (mode == HImode && pos + len <= 8)
8020 {
8021 /* Small HImode tests can be converted to QImode. */
8022 mode = QImode;
8023 operands[0] = gen_lowpart (QImode, operands[0]);
8024 }
8025
8026 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8027 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8028
8029 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8030 })
8031
8032 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8033 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8034 ;; this is relatively important trick.
8035 ;; Do the conversion only post-reload to avoid limiting of the register class
8036 ;; to QI regs.
8037 (define_split
8038 [(set (reg 17)
8039 (compare
8040 (and (match_operand 0 "register_operand" "")
8041 (match_operand 1 "const_int_operand" ""))
8042 (const_int 0)))]
8043 "reload_completed
8044 && QI_REG_P (operands[0])
8045 && ((ix86_match_ccmode (insn, CCZmode)
8046 && !(INTVAL (operands[1]) & ~(255 << 8)))
8047 || (ix86_match_ccmode (insn, CCNOmode)
8048 && !(INTVAL (operands[1]) & ~(127 << 8))))
8049 && GET_MODE (operands[0]) != QImode"
8050 [(set (reg:CCNO 17)
8051 (compare:CCNO
8052 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8053 (match_dup 1))
8054 (const_int 0)))]
8055 "operands[0] = gen_lowpart (SImode, operands[0]);
8056 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8057
8058 (define_split
8059 [(set (reg 17)
8060 (compare
8061 (and (match_operand 0 "nonimmediate_operand" "")
8062 (match_operand 1 "const_int_operand" ""))
8063 (const_int 0)))]
8064 "reload_completed
8065 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8066 && ((ix86_match_ccmode (insn, CCZmode)
8067 && !(INTVAL (operands[1]) & ~255))
8068 || (ix86_match_ccmode (insn, CCNOmode)
8069 && !(INTVAL (operands[1]) & ~127)))
8070 && GET_MODE (operands[0]) != QImode"
8071 [(set (reg:CCNO 17)
8072 (compare:CCNO
8073 (and:QI (match_dup 0)
8074 (match_dup 1))
8075 (const_int 0)))]
8076 "operands[0] = gen_lowpart (QImode, operands[0]);
8077 operands[1] = gen_lowpart (QImode, operands[1]);")
8078
8079
8080 ;; %%% This used to optimize known byte-wide and operations to memory,
8081 ;; and sometimes to QImode registers. If this is considered useful,
8082 ;; it should be done with splitters.
8083
8084 (define_expand "anddi3"
8085 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8086 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8087 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8088 (clobber (reg:CC 17))]
8089 "TARGET_64BIT"
8090 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8091
8092 (define_insn "*anddi_1_rex64"
8093 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8094 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8095 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8096 (clobber (reg:CC 17))]
8097 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8098 {
8099 switch (get_attr_type (insn))
8100 {
8101 case TYPE_IMOVX:
8102 {
8103 enum machine_mode mode;
8104
8105 if (GET_CODE (operands[2]) != CONST_INT)
8106 abort ();
8107 if (INTVAL (operands[2]) == 0xff)
8108 mode = QImode;
8109 else if (INTVAL (operands[2]) == 0xffff)
8110 mode = HImode;
8111 else
8112 abort ();
8113
8114 operands[1] = gen_lowpart (mode, operands[1]);
8115 if (mode == QImode)
8116 return "movz{bq|x}\t{%1,%0|%0, %1}";
8117 else
8118 return "movz{wq|x}\t{%1,%0|%0, %1}";
8119 }
8120
8121 default:
8122 if (! rtx_equal_p (operands[0], operands[1]))
8123 abort ();
8124 if (get_attr_mode (insn) == MODE_SI)
8125 return "and{l}\t{%k2, %k0|%k0, %k2}";
8126 else
8127 return "and{q}\t{%2, %0|%0, %2}";
8128 }
8129 }
8130 [(set_attr "type" "alu,alu,alu,imovx")
8131 (set_attr "length_immediate" "*,*,*,0")
8132 (set_attr "mode" "SI,DI,DI,DI")])
8133
8134 (define_insn "*anddi_2"
8135 [(set (reg 17)
8136 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8137 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8138 (const_int 0)))
8139 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8140 (and:DI (match_dup 1) (match_dup 2)))]
8141 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8142 && ix86_binary_operator_ok (AND, DImode, operands)"
8143 "@
8144 and{l}\t{%k2, %k0|%k0, %k2}
8145 and{q}\t{%2, %0|%0, %2}
8146 and{q}\t{%2, %0|%0, %2}"
8147 [(set_attr "type" "alu")
8148 (set_attr "mode" "SI,DI,DI")])
8149
8150 (define_expand "andsi3"
8151 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8152 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8153 (match_operand:SI 2 "general_operand" "")))
8154 (clobber (reg:CC 17))]
8155 ""
8156 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8157
8158 (define_insn "*andsi_1"
8159 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8160 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8161 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8162 (clobber (reg:CC 17))]
8163 "ix86_binary_operator_ok (AND, SImode, operands)"
8164 {
8165 switch (get_attr_type (insn))
8166 {
8167 case TYPE_IMOVX:
8168 {
8169 enum machine_mode mode;
8170
8171 if (GET_CODE (operands[2]) != CONST_INT)
8172 abort ();
8173 if (INTVAL (operands[2]) == 0xff)
8174 mode = QImode;
8175 else if (INTVAL (operands[2]) == 0xffff)
8176 mode = HImode;
8177 else
8178 abort ();
8179
8180 operands[1] = gen_lowpart (mode, operands[1]);
8181 if (mode == QImode)
8182 return "movz{bl|x}\t{%1,%0|%0, %1}";
8183 else
8184 return "movz{wl|x}\t{%1,%0|%0, %1}";
8185 }
8186
8187 default:
8188 if (! rtx_equal_p (operands[0], operands[1]))
8189 abort ();
8190 return "and{l}\t{%2, %0|%0, %2}";
8191 }
8192 }
8193 [(set_attr "type" "alu,alu,imovx")
8194 (set_attr "length_immediate" "*,*,0")
8195 (set_attr "mode" "SI")])
8196
8197 (define_split
8198 [(set (match_operand 0 "register_operand" "")
8199 (and (match_dup 0)
8200 (const_int -65536)))
8201 (clobber (reg:CC 17))]
8202 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8203 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8204 "operands[1] = gen_lowpart (HImode, operands[0]);")
8205
8206 (define_split
8207 [(set (match_operand 0 "ext_register_operand" "")
8208 (and (match_dup 0)
8209 (const_int -256)))
8210 (clobber (reg:CC 17))]
8211 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8212 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8213 "operands[1] = gen_lowpart (QImode, operands[0]);")
8214
8215 (define_split
8216 [(set (match_operand 0 "ext_register_operand" "")
8217 (and (match_dup 0)
8218 (const_int -65281)))
8219 (clobber (reg:CC 17))]
8220 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8221 [(parallel [(set (zero_extract:SI (match_dup 0)
8222 (const_int 8)
8223 (const_int 8))
8224 (xor:SI
8225 (zero_extract:SI (match_dup 0)
8226 (const_int 8)
8227 (const_int 8))
8228 (zero_extract:SI (match_dup 0)
8229 (const_int 8)
8230 (const_int 8))))
8231 (clobber (reg:CC 17))])]
8232 "operands[0] = gen_lowpart (SImode, operands[0]);")
8233
8234 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8235 (define_insn "*andsi_1_zext"
8236 [(set (match_operand:DI 0 "register_operand" "=r")
8237 (zero_extend:DI
8238 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8239 (match_operand:SI 2 "general_operand" "rim"))))
8240 (clobber (reg:CC 17))]
8241 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8242 "and{l}\t{%2, %k0|%k0, %2}"
8243 [(set_attr "type" "alu")
8244 (set_attr "mode" "SI")])
8245
8246 (define_insn "*andsi_2"
8247 [(set (reg 17)
8248 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8249 (match_operand:SI 2 "general_operand" "rim,ri"))
8250 (const_int 0)))
8251 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8252 (and:SI (match_dup 1) (match_dup 2)))]
8253 "ix86_match_ccmode (insn, CCNOmode)
8254 && ix86_binary_operator_ok (AND, SImode, operands)"
8255 "and{l}\t{%2, %0|%0, %2}"
8256 [(set_attr "type" "alu")
8257 (set_attr "mode" "SI")])
8258
8259 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8260 (define_insn "*andsi_2_zext"
8261 [(set (reg 17)
8262 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8263 (match_operand:SI 2 "general_operand" "rim"))
8264 (const_int 0)))
8265 (set (match_operand:DI 0 "register_operand" "=r")
8266 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8267 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8268 && ix86_binary_operator_ok (AND, SImode, operands)"
8269 "and{l}\t{%2, %k0|%k0, %2}"
8270 [(set_attr "type" "alu")
8271 (set_attr "mode" "SI")])
8272
8273 (define_expand "andhi3"
8274 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8275 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8276 (match_operand:HI 2 "general_operand" "")))
8277 (clobber (reg:CC 17))]
8278 "TARGET_HIMODE_MATH"
8279 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8280
8281 (define_insn "*andhi_1"
8282 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8283 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8284 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8285 (clobber (reg:CC 17))]
8286 "ix86_binary_operator_ok (AND, HImode, operands)"
8287 {
8288 switch (get_attr_type (insn))
8289 {
8290 case TYPE_IMOVX:
8291 if (GET_CODE (operands[2]) != CONST_INT)
8292 abort ();
8293 if (INTVAL (operands[2]) == 0xff)
8294 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8295 abort ();
8296
8297 default:
8298 if (! rtx_equal_p (operands[0], operands[1]))
8299 abort ();
8300
8301 return "and{w}\t{%2, %0|%0, %2}";
8302 }
8303 }
8304 [(set_attr "type" "alu,alu,imovx")
8305 (set_attr "length_immediate" "*,*,0")
8306 (set_attr "mode" "HI,HI,SI")])
8307
8308 (define_insn "*andhi_2"
8309 [(set (reg 17)
8310 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8311 (match_operand:HI 2 "general_operand" "rim,ri"))
8312 (const_int 0)))
8313 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8314 (and:HI (match_dup 1) (match_dup 2)))]
8315 "ix86_match_ccmode (insn, CCNOmode)
8316 && ix86_binary_operator_ok (AND, HImode, operands)"
8317 "and{w}\t{%2, %0|%0, %2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "HI")])
8320
8321 (define_expand "andqi3"
8322 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8323 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8324 (match_operand:QI 2 "general_operand" "")))
8325 (clobber (reg:CC 17))]
8326 "TARGET_QIMODE_MATH"
8327 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8328
8329 ;; %%% Potential partial reg stall on alternative 2. What to do?
8330 (define_insn "*andqi_1"
8331 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8332 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8333 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8334 (clobber (reg:CC 17))]
8335 "ix86_binary_operator_ok (AND, QImode, operands)"
8336 "@
8337 and{b}\t{%2, %0|%0, %2}
8338 and{b}\t{%2, %0|%0, %2}
8339 and{l}\t{%k2, %k0|%k0, %k2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "mode" "QI,QI,SI")])
8342
8343 (define_insn "*andqi_1_slp"
8344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8345 (and:QI (match_dup 0)
8346 (match_operand:QI 1 "general_operand" "qi,qmi")))
8347 (clobber (reg:CC 17))]
8348 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8349 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350 "and{b}\t{%1, %0|%0, %1}"
8351 [(set_attr "type" "alu1")
8352 (set_attr "mode" "QI")])
8353
8354 (define_insn "*andqi_2"
8355 [(set (reg 17)
8356 (compare (and:QI
8357 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8359 (const_int 0)))
8360 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8361 (and:QI (match_dup 1) (match_dup 2)))]
8362 "ix86_match_ccmode (insn, CCNOmode)
8363 && ix86_binary_operator_ok (AND, QImode, operands)"
8364 {
8365 if (which_alternative == 2)
8366 {
8367 if (GET_CODE (operands[2]) == CONST_INT
8368 && (INTVAL (operands[2]) & 0xffffff00))
8369 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8370 return "and{l}\t{%2, %k0|%k0, %2}";
8371 }
8372 return "and{b}\t{%2, %0|%0, %2}";
8373 }
8374 [(set_attr "type" "alu")
8375 (set_attr "mode" "QI,QI,SI")])
8376
8377 (define_insn "*andqi_2_slp"
8378 [(set (reg 17)
8379 (compare (and:QI
8380 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8381 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8382 (const_int 0)))
8383 (set (strict_low_part (match_dup 0))
8384 (and:QI (match_dup 0) (match_dup 1)))]
8385 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8386 && ix86_match_ccmode (insn, CCNOmode)
8387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8388 "and{b}\t{%1, %0|%0, %1}"
8389 [(set_attr "type" "alu1")
8390 (set_attr "mode" "QI")])
8391
8392 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8393 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8394 ;; for a QImode operand, which of course failed.
8395
8396 (define_insn "andqi_ext_0"
8397 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8398 (const_int 8)
8399 (const_int 8))
8400 (and:SI
8401 (zero_extract:SI
8402 (match_operand 1 "ext_register_operand" "0")
8403 (const_int 8)
8404 (const_int 8))
8405 (match_operand 2 "const_int_operand" "n")))
8406 (clobber (reg:CC 17))]
8407 ""
8408 "and{b}\t{%2, %h0|%h0, %2}"
8409 [(set_attr "type" "alu")
8410 (set_attr "length_immediate" "1")
8411 (set_attr "mode" "QI")])
8412
8413 ;; Generated by peephole translating test to and. This shows up
8414 ;; often in fp comparisons.
8415
8416 (define_insn "*andqi_ext_0_cc"
8417 [(set (reg 17)
8418 (compare
8419 (and:SI
8420 (zero_extract:SI
8421 (match_operand 1 "ext_register_operand" "0")
8422 (const_int 8)
8423 (const_int 8))
8424 (match_operand 2 "const_int_operand" "n"))
8425 (const_int 0)))
8426 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8427 (const_int 8)
8428 (const_int 8))
8429 (and:SI
8430 (zero_extract:SI
8431 (match_dup 1)
8432 (const_int 8)
8433 (const_int 8))
8434 (match_dup 2)))]
8435 "ix86_match_ccmode (insn, CCNOmode)"
8436 "and{b}\t{%2, %h0|%h0, %2}"
8437 [(set_attr "type" "alu")
8438 (set_attr "length_immediate" "1")
8439 (set_attr "mode" "QI")])
8440
8441 (define_insn "*andqi_ext_1"
8442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8443 (const_int 8)
8444 (const_int 8))
8445 (and:SI
8446 (zero_extract:SI
8447 (match_operand 1 "ext_register_operand" "0")
8448 (const_int 8)
8449 (const_int 8))
8450 (zero_extend:SI
8451 (match_operand:QI 2 "general_operand" "Qm"))))
8452 (clobber (reg:CC 17))]
8453 "!TARGET_64BIT"
8454 "and{b}\t{%2, %h0|%h0, %2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "0")
8457 (set_attr "mode" "QI")])
8458
8459 (define_insn "*andqi_ext_1_rex64"
8460 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8461 (const_int 8)
8462 (const_int 8))
8463 (and:SI
8464 (zero_extract:SI
8465 (match_operand 1 "ext_register_operand" "0")
8466 (const_int 8)
8467 (const_int 8))
8468 (zero_extend:SI
8469 (match_operand 2 "ext_register_operand" "Q"))))
8470 (clobber (reg:CC 17))]
8471 "TARGET_64BIT"
8472 "and{b}\t{%2, %h0|%h0, %2}"
8473 [(set_attr "type" "alu")
8474 (set_attr "length_immediate" "0")
8475 (set_attr "mode" "QI")])
8476
8477 (define_insn "*andqi_ext_2"
8478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479 (const_int 8)
8480 (const_int 8))
8481 (and:SI
8482 (zero_extract:SI
8483 (match_operand 1 "ext_register_operand" "%0")
8484 (const_int 8)
8485 (const_int 8))
8486 (zero_extract:SI
8487 (match_operand 2 "ext_register_operand" "Q")
8488 (const_int 8)
8489 (const_int 8))))
8490 (clobber (reg:CC 17))]
8491 ""
8492 "and{b}\t{%h2, %h0|%h0, %h2}"
8493 [(set_attr "type" "alu")
8494 (set_attr "length_immediate" "0")
8495 (set_attr "mode" "QI")])
8496
8497 ;; Convert wide AND instructions with immediate operand to shorter QImode
8498 ;; equivalents when possible.
8499 ;; Don't do the splitting with memory operands, since it introduces risk
8500 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8501 ;; for size, but that can (should?) be handled by generic code instead.
8502 (define_split
8503 [(set (match_operand 0 "register_operand" "")
8504 (and (match_operand 1 "register_operand" "")
8505 (match_operand 2 "const_int_operand" "")))
8506 (clobber (reg:CC 17))]
8507 "reload_completed
8508 && QI_REG_P (operands[0])
8509 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8510 && !(~INTVAL (operands[2]) & ~(255 << 8))
8511 && GET_MODE (operands[0]) != QImode"
8512 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8513 (and:SI (zero_extract:SI (match_dup 1)
8514 (const_int 8) (const_int 8))
8515 (match_dup 2)))
8516 (clobber (reg:CC 17))])]
8517 "operands[0] = gen_lowpart (SImode, operands[0]);
8518 operands[1] = gen_lowpart (SImode, operands[1]);
8519 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8520
8521 ;; Since AND can be encoded with sign extended immediate, this is only
8522 ;; profitable when 7th bit is not set.
8523 (define_split
8524 [(set (match_operand 0 "register_operand" "")
8525 (and (match_operand 1 "general_operand" "")
8526 (match_operand 2 "const_int_operand" "")))
8527 (clobber (reg:CC 17))]
8528 "reload_completed
8529 && ANY_QI_REG_P (operands[0])
8530 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8531 && !(~INTVAL (operands[2]) & ~255)
8532 && !(INTVAL (operands[2]) & 128)
8533 && GET_MODE (operands[0]) != QImode"
8534 [(parallel [(set (strict_low_part (match_dup 0))
8535 (and:QI (match_dup 1)
8536 (match_dup 2)))
8537 (clobber (reg:CC 17))])]
8538 "operands[0] = gen_lowpart (QImode, operands[0]);
8539 operands[1] = gen_lowpart (QImode, operands[1]);
8540 operands[2] = gen_lowpart (QImode, operands[2]);")
8541 \f
8542 ;; Logical inclusive OR instructions
8543
8544 ;; %%% This used to optimize known byte-wide and operations to memory.
8545 ;; If this is considered useful, it should be done with splitters.
8546
8547 (define_expand "iordi3"
8548 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8549 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8550 (match_operand:DI 2 "x86_64_general_operand" "")))
8551 (clobber (reg:CC 17))]
8552 "TARGET_64BIT"
8553 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8554
8555 (define_insn "*iordi_1_rex64"
8556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8557 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8558 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8559 (clobber (reg:CC 17))]
8560 "TARGET_64BIT
8561 && ix86_binary_operator_ok (IOR, DImode, operands)"
8562 "or{q}\t{%2, %0|%0, %2}"
8563 [(set_attr "type" "alu")
8564 (set_attr "mode" "DI")])
8565
8566 (define_insn "*iordi_2_rex64"
8567 [(set (reg 17)
8568 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8569 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8570 (const_int 0)))
8571 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8572 (ior:DI (match_dup 1) (match_dup 2)))]
8573 "TARGET_64BIT
8574 && ix86_match_ccmode (insn, CCNOmode)
8575 && ix86_binary_operator_ok (IOR, DImode, operands)"
8576 "or{q}\t{%2, %0|%0, %2}"
8577 [(set_attr "type" "alu")
8578 (set_attr "mode" "DI")])
8579
8580 (define_insn "*iordi_3_rex64"
8581 [(set (reg 17)
8582 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8583 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8584 (const_int 0)))
8585 (clobber (match_scratch:DI 0 "=r"))]
8586 "TARGET_64BIT
8587 && ix86_match_ccmode (insn, CCNOmode)
8588 && ix86_binary_operator_ok (IOR, DImode, operands)"
8589 "or{q}\t{%2, %0|%0, %2}"
8590 [(set_attr "type" "alu")
8591 (set_attr "mode" "DI")])
8592
8593
8594 (define_expand "iorsi3"
8595 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8596 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8597 (match_operand:SI 2 "general_operand" "")))
8598 (clobber (reg:CC 17))]
8599 ""
8600 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8601
8602 (define_insn "*iorsi_1"
8603 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8604 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8605 (match_operand:SI 2 "general_operand" "ri,rmi")))
8606 (clobber (reg:CC 17))]
8607 "ix86_binary_operator_ok (IOR, SImode, operands)"
8608 "or{l}\t{%2, %0|%0, %2}"
8609 [(set_attr "type" "alu")
8610 (set_attr "mode" "SI")])
8611
8612 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8613 (define_insn "*iorsi_1_zext"
8614 [(set (match_operand:DI 0 "register_operand" "=rm")
8615 (zero_extend:DI
8616 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8617 (match_operand:SI 2 "general_operand" "rim"))))
8618 (clobber (reg:CC 17))]
8619 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8620 "or{l}\t{%2, %k0|%k0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "mode" "SI")])
8623
8624 (define_insn "*iorsi_1_zext_imm"
8625 [(set (match_operand:DI 0 "register_operand" "=rm")
8626 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8627 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8628 (clobber (reg:CC 17))]
8629 "TARGET_64BIT"
8630 "or{l}\t{%2, %k0|%k0, %2}"
8631 [(set_attr "type" "alu")
8632 (set_attr "mode" "SI")])
8633
8634 (define_insn "*iorsi_2"
8635 [(set (reg 17)
8636 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8637 (match_operand:SI 2 "general_operand" "rim,ri"))
8638 (const_int 0)))
8639 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8640 (ior:SI (match_dup 1) (match_dup 2)))]
8641 "ix86_match_ccmode (insn, CCNOmode)
8642 && ix86_binary_operator_ok (IOR, SImode, operands)"
8643 "or{l}\t{%2, %0|%0, %2}"
8644 [(set_attr "type" "alu")
8645 (set_attr "mode" "SI")])
8646
8647 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8648 ;; ??? Special case for immediate operand is missing - it is tricky.
8649 (define_insn "*iorsi_2_zext"
8650 [(set (reg 17)
8651 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8652 (match_operand:SI 2 "general_operand" "rim"))
8653 (const_int 0)))
8654 (set (match_operand:DI 0 "register_operand" "=r")
8655 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8656 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8657 && ix86_binary_operator_ok (IOR, SImode, operands)"
8658 "or{l}\t{%2, %k0|%k0, %2}"
8659 [(set_attr "type" "alu")
8660 (set_attr "mode" "SI")])
8661
8662 (define_insn "*iorsi_2_zext_imm"
8663 [(set (reg 17)
8664 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8665 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8666 (const_int 0)))
8667 (set (match_operand:DI 0 "register_operand" "=r")
8668 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8669 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8670 && ix86_binary_operator_ok (IOR, SImode, operands)"
8671 "or{l}\t{%2, %k0|%k0, %2}"
8672 [(set_attr "type" "alu")
8673 (set_attr "mode" "SI")])
8674
8675 (define_insn "*iorsi_3"
8676 [(set (reg 17)
8677 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678 (match_operand:SI 2 "general_operand" "rim"))
8679 (const_int 0)))
8680 (clobber (match_scratch:SI 0 "=r"))]
8681 "ix86_match_ccmode (insn, CCNOmode)
8682 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8683 "or{l}\t{%2, %0|%0, %2}"
8684 [(set_attr "type" "alu")
8685 (set_attr "mode" "SI")])
8686
8687 (define_expand "iorhi3"
8688 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8689 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8690 (match_operand:HI 2 "general_operand" "")))
8691 (clobber (reg:CC 17))]
8692 "TARGET_HIMODE_MATH"
8693 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8694
8695 (define_insn "*iorhi_1"
8696 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8697 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8698 (match_operand:HI 2 "general_operand" "rmi,ri")))
8699 (clobber (reg:CC 17))]
8700 "ix86_binary_operator_ok (IOR, HImode, operands)"
8701 "or{w}\t{%2, %0|%0, %2}"
8702 [(set_attr "type" "alu")
8703 (set_attr "mode" "HI")])
8704
8705 (define_insn "*iorhi_2"
8706 [(set (reg 17)
8707 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8708 (match_operand:HI 2 "general_operand" "rim,ri"))
8709 (const_int 0)))
8710 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8711 (ior:HI (match_dup 1) (match_dup 2)))]
8712 "ix86_match_ccmode (insn, CCNOmode)
8713 && ix86_binary_operator_ok (IOR, HImode, operands)"
8714 "or{w}\t{%2, %0|%0, %2}"
8715 [(set_attr "type" "alu")
8716 (set_attr "mode" "HI")])
8717
8718 (define_insn "*iorhi_3"
8719 [(set (reg 17)
8720 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8721 (match_operand:HI 2 "general_operand" "rim"))
8722 (const_int 0)))
8723 (clobber (match_scratch:HI 0 "=r"))]
8724 "ix86_match_ccmode (insn, CCNOmode)
8725 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8726 "or{w}\t{%2, %0|%0, %2}"
8727 [(set_attr "type" "alu")
8728 (set_attr "mode" "HI")])
8729
8730 (define_expand "iorqi3"
8731 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8732 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8733 (match_operand:QI 2 "general_operand" "")))
8734 (clobber (reg:CC 17))]
8735 "TARGET_QIMODE_MATH"
8736 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8737
8738 ;; %%% Potential partial reg stall on alternative 2. What to do?
8739 (define_insn "*iorqi_1"
8740 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8741 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8742 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8743 (clobber (reg:CC 17))]
8744 "ix86_binary_operator_ok (IOR, QImode, operands)"
8745 "@
8746 or{b}\t{%2, %0|%0, %2}
8747 or{b}\t{%2, %0|%0, %2}
8748 or{l}\t{%k2, %k0|%k0, %k2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "mode" "QI,QI,SI")])
8751
8752 (define_insn "*iorqi_1_slp"
8753 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8754 (ior:QI (match_dup 0)
8755 (match_operand:QI 1 "general_operand" "qmi,qi")))
8756 (clobber (reg:CC 17))]
8757 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8758 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8759 "or{b}\t{%1, %0|%0, %1}"
8760 [(set_attr "type" "alu1")
8761 (set_attr "mode" "QI")])
8762
8763 (define_insn "*iorqi_2"
8764 [(set (reg 17)
8765 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8766 (match_operand:QI 2 "general_operand" "qim,qi"))
8767 (const_int 0)))
8768 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8769 (ior:QI (match_dup 1) (match_dup 2)))]
8770 "ix86_match_ccmode (insn, CCNOmode)
8771 && ix86_binary_operator_ok (IOR, QImode, operands)"
8772 "or{b}\t{%2, %0|%0, %2}"
8773 [(set_attr "type" "alu")
8774 (set_attr "mode" "QI")])
8775
8776 (define_insn "*iorqi_2_slp"
8777 [(set (reg 17)
8778 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8779 (match_operand:QI 1 "general_operand" "qim,qi"))
8780 (const_int 0)))
8781 (set (strict_low_part (match_dup 0))
8782 (ior:QI (match_dup 0) (match_dup 1)))]
8783 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8784 && ix86_match_ccmode (insn, CCNOmode)
8785 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8786 "or{b}\t{%1, %0|%0, %1}"
8787 [(set_attr "type" "alu1")
8788 (set_attr "mode" "QI")])
8789
8790 (define_insn "*iorqi_3"
8791 [(set (reg 17)
8792 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8793 (match_operand:QI 2 "general_operand" "qim"))
8794 (const_int 0)))
8795 (clobber (match_scratch:QI 0 "=q"))]
8796 "ix86_match_ccmode (insn, CCNOmode)
8797 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8798 "or{b}\t{%2, %0|%0, %2}"
8799 [(set_attr "type" "alu")
8800 (set_attr "mode" "QI")])
8801
8802 (define_insn "iorqi_ext_0"
8803 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8804 (const_int 8)
8805 (const_int 8))
8806 (ior:SI
8807 (zero_extract:SI
8808 (match_operand 1 "ext_register_operand" "0")
8809 (const_int 8)
8810 (const_int 8))
8811 (match_operand 2 "const_int_operand" "n")))
8812 (clobber (reg:CC 17))]
8813 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8814 "or{b}\t{%2, %h0|%h0, %2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "length_immediate" "1")
8817 (set_attr "mode" "QI")])
8818
8819 (define_insn "*iorqi_ext_1"
8820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821 (const_int 8)
8822 (const_int 8))
8823 (ior:SI
8824 (zero_extract:SI
8825 (match_operand 1 "ext_register_operand" "0")
8826 (const_int 8)
8827 (const_int 8))
8828 (zero_extend:SI
8829 (match_operand:QI 2 "general_operand" "Qm"))))
8830 (clobber (reg:CC 17))]
8831 "!TARGET_64BIT
8832 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8833 "or{b}\t{%2, %h0|%h0, %2}"
8834 [(set_attr "type" "alu")
8835 (set_attr "length_immediate" "0")
8836 (set_attr "mode" "QI")])
8837
8838 (define_insn "*iorqi_ext_1_rex64"
8839 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8840 (const_int 8)
8841 (const_int 8))
8842 (ior:SI
8843 (zero_extract:SI
8844 (match_operand 1 "ext_register_operand" "0")
8845 (const_int 8)
8846 (const_int 8))
8847 (zero_extend:SI
8848 (match_operand 2 "ext_register_operand" "Q"))))
8849 (clobber (reg:CC 17))]
8850 "TARGET_64BIT
8851 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8852 "or{b}\t{%2, %h0|%h0, %2}"
8853 [(set_attr "type" "alu")
8854 (set_attr "length_immediate" "0")
8855 (set_attr "mode" "QI")])
8856
8857 (define_insn "*iorqi_ext_2"
8858 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8859 (const_int 8)
8860 (const_int 8))
8861 (ior:SI
8862 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8863 (const_int 8)
8864 (const_int 8))
8865 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8866 (const_int 8)
8867 (const_int 8))))
8868 (clobber (reg:CC 17))]
8869 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8870 "ior{b}\t{%h2, %h0|%h0, %h2}"
8871 [(set_attr "type" "alu")
8872 (set_attr "length_immediate" "0")
8873 (set_attr "mode" "QI")])
8874
8875 (define_split
8876 [(set (match_operand 0 "register_operand" "")
8877 (ior (match_operand 1 "register_operand" "")
8878 (match_operand 2 "const_int_operand" "")))
8879 (clobber (reg:CC 17))]
8880 "reload_completed
8881 && QI_REG_P (operands[0])
8882 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8883 && !(INTVAL (operands[2]) & ~(255 << 8))
8884 && GET_MODE (operands[0]) != QImode"
8885 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8886 (ior:SI (zero_extract:SI (match_dup 1)
8887 (const_int 8) (const_int 8))
8888 (match_dup 2)))
8889 (clobber (reg:CC 17))])]
8890 "operands[0] = gen_lowpart (SImode, operands[0]);
8891 operands[1] = gen_lowpart (SImode, operands[1]);
8892 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8893
8894 ;; Since OR can be encoded with sign extended immediate, this is only
8895 ;; profitable when 7th bit is set.
8896 (define_split
8897 [(set (match_operand 0 "register_operand" "")
8898 (ior (match_operand 1 "general_operand" "")
8899 (match_operand 2 "const_int_operand" "")))
8900 (clobber (reg:CC 17))]
8901 "reload_completed
8902 && ANY_QI_REG_P (operands[0])
8903 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8904 && !(INTVAL (operands[2]) & ~255)
8905 && (INTVAL (operands[2]) & 128)
8906 && GET_MODE (operands[0]) != QImode"
8907 [(parallel [(set (strict_low_part (match_dup 0))
8908 (ior:QI (match_dup 1)
8909 (match_dup 2)))
8910 (clobber (reg:CC 17))])]
8911 "operands[0] = gen_lowpart (QImode, operands[0]);
8912 operands[1] = gen_lowpart (QImode, operands[1]);
8913 operands[2] = gen_lowpart (QImode, operands[2]);")
8914 \f
8915 ;; Logical XOR instructions
8916
8917 ;; %%% This used to optimize known byte-wide and operations to memory.
8918 ;; If this is considered useful, it should be done with splitters.
8919
8920 (define_expand "xordi3"
8921 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8922 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8923 (match_operand:DI 2 "x86_64_general_operand" "")))
8924 (clobber (reg:CC 17))]
8925 "TARGET_64BIT"
8926 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8927
8928 (define_insn "*xordi_1_rex64"
8929 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8930 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8931 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8932 (clobber (reg:CC 17))]
8933 "TARGET_64BIT
8934 && ix86_binary_operator_ok (XOR, DImode, operands)"
8935 "@
8936 xor{q}\t{%2, %0|%0, %2}
8937 xor{q}\t{%2, %0|%0, %2}"
8938 [(set_attr "type" "alu")
8939 (set_attr "mode" "DI,DI")])
8940
8941 (define_insn "*xordi_2_rex64"
8942 [(set (reg 17)
8943 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8944 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8945 (const_int 0)))
8946 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8947 (xor:DI (match_dup 1) (match_dup 2)))]
8948 "TARGET_64BIT
8949 && ix86_match_ccmode (insn, CCNOmode)
8950 && ix86_binary_operator_ok (XOR, DImode, operands)"
8951 "@
8952 xor{q}\t{%2, %0|%0, %2}
8953 xor{q}\t{%2, %0|%0, %2}"
8954 [(set_attr "type" "alu")
8955 (set_attr "mode" "DI,DI")])
8956
8957 (define_insn "*xordi_3_rex64"
8958 [(set (reg 17)
8959 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8960 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8961 (const_int 0)))
8962 (clobber (match_scratch:DI 0 "=r"))]
8963 "TARGET_64BIT
8964 && ix86_match_ccmode (insn, CCNOmode)
8965 && ix86_binary_operator_ok (XOR, DImode, operands)"
8966 "xor{q}\t{%2, %0|%0, %2}"
8967 [(set_attr "type" "alu")
8968 (set_attr "mode" "DI")])
8969
8970 (define_expand "xorsi3"
8971 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8972 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8973 (match_operand:SI 2 "general_operand" "")))
8974 (clobber (reg:CC 17))]
8975 ""
8976 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8977
8978 (define_insn "*xorsi_1"
8979 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8980 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8981 (match_operand:SI 2 "general_operand" "ri,rm")))
8982 (clobber (reg:CC 17))]
8983 "ix86_binary_operator_ok (XOR, SImode, operands)"
8984 "xor{l}\t{%2, %0|%0, %2}"
8985 [(set_attr "type" "alu")
8986 (set_attr "mode" "SI")])
8987
8988 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8989 ;; Add speccase for immediates
8990 (define_insn "*xorsi_1_zext"
8991 [(set (match_operand:DI 0 "register_operand" "=r")
8992 (zero_extend:DI
8993 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8994 (match_operand:SI 2 "general_operand" "rim"))))
8995 (clobber (reg:CC 17))]
8996 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8997 "xor{l}\t{%2, %k0|%k0, %2}"
8998 [(set_attr "type" "alu")
8999 (set_attr "mode" "SI")])
9000
9001 (define_insn "*xorsi_1_zext_imm"
9002 [(set (match_operand:DI 0 "register_operand" "=r")
9003 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9004 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9005 (clobber (reg:CC 17))]
9006 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9007 "xor{l}\t{%2, %k0|%k0, %2}"
9008 [(set_attr "type" "alu")
9009 (set_attr "mode" "SI")])
9010
9011 (define_insn "*xorsi_2"
9012 [(set (reg 17)
9013 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9014 (match_operand:SI 2 "general_operand" "rim,ri"))
9015 (const_int 0)))
9016 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9017 (xor:SI (match_dup 1) (match_dup 2)))]
9018 "ix86_match_ccmode (insn, CCNOmode)
9019 && ix86_binary_operator_ok (XOR, SImode, operands)"
9020 "xor{l}\t{%2, %0|%0, %2}"
9021 [(set_attr "type" "alu")
9022 (set_attr "mode" "SI")])
9023
9024 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9025 ;; ??? Special case for immediate operand is missing - it is tricky.
9026 (define_insn "*xorsi_2_zext"
9027 [(set (reg 17)
9028 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9029 (match_operand:SI 2 "general_operand" "rim"))
9030 (const_int 0)))
9031 (set (match_operand:DI 0 "register_operand" "=r")
9032 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9033 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9034 && ix86_binary_operator_ok (XOR, SImode, operands)"
9035 "xor{l}\t{%2, %k0|%k0, %2}"
9036 [(set_attr "type" "alu")
9037 (set_attr "mode" "SI")])
9038
9039 (define_insn "*xorsi_2_zext_imm"
9040 [(set (reg 17)
9041 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9042 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9043 (const_int 0)))
9044 (set (match_operand:DI 0 "register_operand" "=r")
9045 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9046 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9047 && ix86_binary_operator_ok (XOR, SImode, operands)"
9048 "xor{l}\t{%2, %k0|%k0, %2}"
9049 [(set_attr "type" "alu")
9050 (set_attr "mode" "SI")])
9051
9052 (define_insn "*xorsi_3"
9053 [(set (reg 17)
9054 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055 (match_operand:SI 2 "general_operand" "rim"))
9056 (const_int 0)))
9057 (clobber (match_scratch:SI 0 "=r"))]
9058 "ix86_match_ccmode (insn, CCNOmode)
9059 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9060 "xor{l}\t{%2, %0|%0, %2}"
9061 [(set_attr "type" "alu")
9062 (set_attr "mode" "SI")])
9063
9064 (define_expand "xorhi3"
9065 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9066 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9067 (match_operand:HI 2 "general_operand" "")))
9068 (clobber (reg:CC 17))]
9069 "TARGET_HIMODE_MATH"
9070 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9071
9072 (define_insn "*xorhi_1"
9073 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9074 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9075 (match_operand:HI 2 "general_operand" "rmi,ri")))
9076 (clobber (reg:CC 17))]
9077 "ix86_binary_operator_ok (XOR, HImode, operands)"
9078 "xor{w}\t{%2, %0|%0, %2}"
9079 [(set_attr "type" "alu")
9080 (set_attr "mode" "HI")])
9081
9082 (define_insn "*xorhi_2"
9083 [(set (reg 17)
9084 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9085 (match_operand:HI 2 "general_operand" "rim,ri"))
9086 (const_int 0)))
9087 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9088 (xor:HI (match_dup 1) (match_dup 2)))]
9089 "ix86_match_ccmode (insn, CCNOmode)
9090 && ix86_binary_operator_ok (XOR, HImode, operands)"
9091 "xor{w}\t{%2, %0|%0, %2}"
9092 [(set_attr "type" "alu")
9093 (set_attr "mode" "HI")])
9094
9095 (define_insn "*xorhi_3"
9096 [(set (reg 17)
9097 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9098 (match_operand:HI 2 "general_operand" "rim"))
9099 (const_int 0)))
9100 (clobber (match_scratch:HI 0 "=r"))]
9101 "ix86_match_ccmode (insn, CCNOmode)
9102 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9103 "xor{w}\t{%2, %0|%0, %2}"
9104 [(set_attr "type" "alu")
9105 (set_attr "mode" "HI")])
9106
9107 (define_expand "xorqi3"
9108 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9109 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9110 (match_operand:QI 2 "general_operand" "")))
9111 (clobber (reg:CC 17))]
9112 "TARGET_QIMODE_MATH"
9113 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9114
9115 ;; %%% Potential partial reg stall on alternative 2. What to do?
9116 (define_insn "*xorqi_1"
9117 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9118 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9119 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9120 (clobber (reg:CC 17))]
9121 "ix86_binary_operator_ok (XOR, QImode, operands)"
9122 "@
9123 xor{b}\t{%2, %0|%0, %2}
9124 xor{b}\t{%2, %0|%0, %2}
9125 xor{l}\t{%k2, %k0|%k0, %k2}"
9126 [(set_attr "type" "alu")
9127 (set_attr "mode" "QI,QI,SI")])
9128
9129 (define_insn "*xorqi_1_slp"
9130 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9131 (xor:QI (match_dup 0)
9132 (match_operand:QI 1 "general_operand" "qi,qmi")))
9133 (clobber (reg:CC 17))]
9134 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9136 "xor{b}\t{%1, %0|%0, %1}"
9137 [(set_attr "type" "alu1")
9138 (set_attr "mode" "QI")])
9139
9140 (define_insn "xorqi_ext_0"
9141 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9142 (const_int 8)
9143 (const_int 8))
9144 (xor:SI
9145 (zero_extract:SI
9146 (match_operand 1 "ext_register_operand" "0")
9147 (const_int 8)
9148 (const_int 8))
9149 (match_operand 2 "const_int_operand" "n")))
9150 (clobber (reg:CC 17))]
9151 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9152 "xor{b}\t{%2, %h0|%h0, %2}"
9153 [(set_attr "type" "alu")
9154 (set_attr "length_immediate" "1")
9155 (set_attr "mode" "QI")])
9156
9157 (define_insn "*xorqi_ext_1"
9158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159 (const_int 8)
9160 (const_int 8))
9161 (xor:SI
9162 (zero_extract:SI
9163 (match_operand 1 "ext_register_operand" "0")
9164 (const_int 8)
9165 (const_int 8))
9166 (zero_extend:SI
9167 (match_operand:QI 2 "general_operand" "Qm"))))
9168 (clobber (reg:CC 17))]
9169 "!TARGET_64BIT
9170 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9171 "xor{b}\t{%2, %h0|%h0, %2}"
9172 [(set_attr "type" "alu")
9173 (set_attr "length_immediate" "0")
9174 (set_attr "mode" "QI")])
9175
9176 (define_insn "*xorqi_ext_1_rex64"
9177 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9178 (const_int 8)
9179 (const_int 8))
9180 (xor:SI
9181 (zero_extract:SI
9182 (match_operand 1 "ext_register_operand" "0")
9183 (const_int 8)
9184 (const_int 8))
9185 (zero_extend:SI
9186 (match_operand 2 "ext_register_operand" "Q"))))
9187 (clobber (reg:CC 17))]
9188 "TARGET_64BIT
9189 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9190 "xor{b}\t{%2, %h0|%h0, %2}"
9191 [(set_attr "type" "alu")
9192 (set_attr "length_immediate" "0")
9193 (set_attr "mode" "QI")])
9194
9195 (define_insn "*xorqi_ext_2"
9196 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9197 (const_int 8)
9198 (const_int 8))
9199 (xor:SI
9200 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9201 (const_int 8)
9202 (const_int 8))
9203 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9204 (const_int 8)
9205 (const_int 8))))
9206 (clobber (reg:CC 17))]
9207 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9208 "xor{b}\t{%h2, %h0|%h0, %h2}"
9209 [(set_attr "type" "alu")
9210 (set_attr "length_immediate" "0")
9211 (set_attr "mode" "QI")])
9212
9213 (define_insn "*xorqi_cc_1"
9214 [(set (reg 17)
9215 (compare
9216 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9217 (match_operand:QI 2 "general_operand" "qim,qi"))
9218 (const_int 0)))
9219 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9220 (xor:QI (match_dup 1) (match_dup 2)))]
9221 "ix86_match_ccmode (insn, CCNOmode)
9222 && ix86_binary_operator_ok (XOR, QImode, operands)"
9223 "xor{b}\t{%2, %0|%0, %2}"
9224 [(set_attr "type" "alu")
9225 (set_attr "mode" "QI")])
9226
9227 (define_insn "*xorqi_2_slp"
9228 [(set (reg 17)
9229 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9230 (match_operand:QI 1 "general_operand" "qim,qi"))
9231 (const_int 0)))
9232 (set (strict_low_part (match_dup 0))
9233 (xor:QI (match_dup 0) (match_dup 1)))]
9234 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9235 && ix86_match_ccmode (insn, CCNOmode)
9236 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9237 "xor{b}\t{%1, %0|%0, %1}"
9238 [(set_attr "type" "alu1")
9239 (set_attr "mode" "QI")])
9240
9241 (define_insn "*xorqi_cc_2"
9242 [(set (reg 17)
9243 (compare
9244 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9245 (match_operand:QI 2 "general_operand" "qim"))
9246 (const_int 0)))
9247 (clobber (match_scratch:QI 0 "=q"))]
9248 "ix86_match_ccmode (insn, CCNOmode)
9249 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9250 "xor{b}\t{%2, %0|%0, %2}"
9251 [(set_attr "type" "alu")
9252 (set_attr "mode" "QI")])
9253
9254 (define_insn "*xorqi_cc_ext_1"
9255 [(set (reg 17)
9256 (compare
9257 (xor:SI
9258 (zero_extract:SI
9259 (match_operand 1 "ext_register_operand" "0")
9260 (const_int 8)
9261 (const_int 8))
9262 (match_operand:QI 2 "general_operand" "qmn"))
9263 (const_int 0)))
9264 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9265 (const_int 8)
9266 (const_int 8))
9267 (xor:SI
9268 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9269 (match_dup 2)))]
9270 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9271 "xor{b}\t{%2, %h0|%h0, %2}"
9272 [(set_attr "type" "alu")
9273 (set_attr "mode" "QI")])
9274
9275 (define_insn "*xorqi_cc_ext_1_rex64"
9276 [(set (reg 17)
9277 (compare
9278 (xor:SI
9279 (zero_extract:SI
9280 (match_operand 1 "ext_register_operand" "0")
9281 (const_int 8)
9282 (const_int 8))
9283 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9284 (const_int 0)))
9285 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9286 (const_int 8)
9287 (const_int 8))
9288 (xor:SI
9289 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9290 (match_dup 2)))]
9291 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9292 "xor{b}\t{%2, %h0|%h0, %2}"
9293 [(set_attr "type" "alu")
9294 (set_attr "mode" "QI")])
9295
9296 (define_expand "xorqi_cc_ext_1"
9297 [(parallel [
9298 (set (reg:CCNO 17)
9299 (compare:CCNO
9300 (xor:SI
9301 (zero_extract:SI
9302 (match_operand 1 "ext_register_operand" "")
9303 (const_int 8)
9304 (const_int 8))
9305 (match_operand:QI 2 "general_operand" ""))
9306 (const_int 0)))
9307 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9308 (const_int 8)
9309 (const_int 8))
9310 (xor:SI
9311 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9312 (match_dup 2)))])]
9313 ""
9314 "")
9315
9316 (define_split
9317 [(set (match_operand 0 "register_operand" "")
9318 (xor (match_operand 1 "register_operand" "")
9319 (match_operand 2 "const_int_operand" "")))
9320 (clobber (reg:CC 17))]
9321 "reload_completed
9322 && QI_REG_P (operands[0])
9323 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9324 && !(INTVAL (operands[2]) & ~(255 << 8))
9325 && GET_MODE (operands[0]) != QImode"
9326 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9327 (xor:SI (zero_extract:SI (match_dup 1)
9328 (const_int 8) (const_int 8))
9329 (match_dup 2)))
9330 (clobber (reg:CC 17))])]
9331 "operands[0] = gen_lowpart (SImode, operands[0]);
9332 operands[1] = gen_lowpart (SImode, operands[1]);
9333 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9334
9335 ;; Since XOR can be encoded with sign extended immediate, this is only
9336 ;; profitable when 7th bit is set.
9337 (define_split
9338 [(set (match_operand 0 "register_operand" "")
9339 (xor (match_operand 1 "general_operand" "")
9340 (match_operand 2 "const_int_operand" "")))
9341 (clobber (reg:CC 17))]
9342 "reload_completed
9343 && ANY_QI_REG_P (operands[0])
9344 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9345 && !(INTVAL (operands[2]) & ~255)
9346 && (INTVAL (operands[2]) & 128)
9347 && GET_MODE (operands[0]) != QImode"
9348 [(parallel [(set (strict_low_part (match_dup 0))
9349 (xor:QI (match_dup 1)
9350 (match_dup 2)))
9351 (clobber (reg:CC 17))])]
9352 "operands[0] = gen_lowpart (QImode, operands[0]);
9353 operands[1] = gen_lowpart (QImode, operands[1]);
9354 operands[2] = gen_lowpart (QImode, operands[2]);")
9355 \f
9356 ;; Negation instructions
9357
9358 (define_expand "negdi2"
9359 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9360 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9361 (clobber (reg:CC 17))])]
9362 ""
9363 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9364
9365 (define_insn "*negdi2_1"
9366 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9367 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9368 (clobber (reg:CC 17))]
9369 "!TARGET_64BIT
9370 && ix86_unary_operator_ok (NEG, DImode, operands)"
9371 "#")
9372
9373 (define_split
9374 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9375 (neg:DI (match_operand:DI 1 "general_operand" "")))
9376 (clobber (reg:CC 17))]
9377 "!TARGET_64BIT && reload_completed"
9378 [(parallel
9379 [(set (reg:CCZ 17)
9380 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9381 (set (match_dup 0) (neg:SI (match_dup 2)))])
9382 (parallel
9383 [(set (match_dup 1)
9384 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9385 (match_dup 3))
9386 (const_int 0)))
9387 (clobber (reg:CC 17))])
9388 (parallel
9389 [(set (match_dup 1)
9390 (neg:SI (match_dup 1)))
9391 (clobber (reg:CC 17))])]
9392 "split_di (operands+1, 1, operands+2, operands+3);
9393 split_di (operands+0, 1, operands+0, operands+1);")
9394
9395 (define_insn "*negdi2_1_rex64"
9396 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9397 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9398 (clobber (reg:CC 17))]
9399 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9400 "neg{q}\t%0"
9401 [(set_attr "type" "negnot")
9402 (set_attr "mode" "DI")])
9403
9404 ;; The problem with neg is that it does not perform (compare x 0),
9405 ;; it really performs (compare 0 x), which leaves us with the zero
9406 ;; flag being the only useful item.
9407
9408 (define_insn "*negdi2_cmpz_rex64"
9409 [(set (reg:CCZ 17)
9410 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9411 (const_int 0)))
9412 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9413 (neg:DI (match_dup 1)))]
9414 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9415 "neg{q}\t%0"
9416 [(set_attr "type" "negnot")
9417 (set_attr "mode" "DI")])
9418
9419
9420 (define_expand "negsi2"
9421 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9422 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9423 (clobber (reg:CC 17))])]
9424 ""
9425 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9426
9427 (define_insn "*negsi2_1"
9428 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9429 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9430 (clobber (reg:CC 17))]
9431 "ix86_unary_operator_ok (NEG, SImode, operands)"
9432 "neg{l}\t%0"
9433 [(set_attr "type" "negnot")
9434 (set_attr "mode" "SI")])
9435
9436 ;; Combine is quite creative about this pattern.
9437 (define_insn "*negsi2_1_zext"
9438 [(set (match_operand:DI 0 "register_operand" "=r")
9439 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9440 (const_int 32)))
9441 (const_int 32)))
9442 (clobber (reg:CC 17))]
9443 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9444 "neg{l}\t%k0"
9445 [(set_attr "type" "negnot")
9446 (set_attr "mode" "SI")])
9447
9448 ;; The problem with neg is that it does not perform (compare x 0),
9449 ;; it really performs (compare 0 x), which leaves us with the zero
9450 ;; flag being the only useful item.
9451
9452 (define_insn "*negsi2_cmpz"
9453 [(set (reg:CCZ 17)
9454 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9455 (const_int 0)))
9456 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9457 (neg:SI (match_dup 1)))]
9458 "ix86_unary_operator_ok (NEG, SImode, operands)"
9459 "neg{l}\t%0"
9460 [(set_attr "type" "negnot")
9461 (set_attr "mode" "SI")])
9462
9463 (define_insn "*negsi2_cmpz_zext"
9464 [(set (reg:CCZ 17)
9465 (compare:CCZ (lshiftrt:DI
9466 (neg:DI (ashift:DI
9467 (match_operand:DI 1 "register_operand" "0")
9468 (const_int 32)))
9469 (const_int 32))
9470 (const_int 0)))
9471 (set (match_operand:DI 0 "register_operand" "=r")
9472 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9473 (const_int 32)))
9474 (const_int 32)))]
9475 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9476 "neg{l}\t%k0"
9477 [(set_attr "type" "negnot")
9478 (set_attr "mode" "SI")])
9479
9480 (define_expand "neghi2"
9481 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9482 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9483 (clobber (reg:CC 17))])]
9484 "TARGET_HIMODE_MATH"
9485 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9486
9487 (define_insn "*neghi2_1"
9488 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9489 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9490 (clobber (reg:CC 17))]
9491 "ix86_unary_operator_ok (NEG, HImode, operands)"
9492 "neg{w}\t%0"
9493 [(set_attr "type" "negnot")
9494 (set_attr "mode" "HI")])
9495
9496 (define_insn "*neghi2_cmpz"
9497 [(set (reg:CCZ 17)
9498 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9499 (const_int 0)))
9500 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9501 (neg:HI (match_dup 1)))]
9502 "ix86_unary_operator_ok (NEG, HImode, operands)"
9503 "neg{w}\t%0"
9504 [(set_attr "type" "negnot")
9505 (set_attr "mode" "HI")])
9506
9507 (define_expand "negqi2"
9508 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9509 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9510 (clobber (reg:CC 17))])]
9511 "TARGET_QIMODE_MATH"
9512 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9513
9514 (define_insn "*negqi2_1"
9515 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9516 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9517 (clobber (reg:CC 17))]
9518 "ix86_unary_operator_ok (NEG, QImode, operands)"
9519 "neg{b}\t%0"
9520 [(set_attr "type" "negnot")
9521 (set_attr "mode" "QI")])
9522
9523 (define_insn "*negqi2_cmpz"
9524 [(set (reg:CCZ 17)
9525 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9526 (const_int 0)))
9527 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9528 (neg:QI (match_dup 1)))]
9529 "ix86_unary_operator_ok (NEG, QImode, operands)"
9530 "neg{b}\t%0"
9531 [(set_attr "type" "negnot")
9532 (set_attr "mode" "QI")])
9533
9534 ;; Changing of sign for FP values is doable using integer unit too.
9535
9536 (define_expand "negsf2"
9537 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9538 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9539 (clobber (reg:CC 17))])]
9540 "TARGET_80387"
9541 "if (TARGET_SSE)
9542 {
9543 /* In case operand is in memory, we will not use SSE. */
9544 if (memory_operand (operands[0], VOIDmode)
9545 && rtx_equal_p (operands[0], operands[1]))
9546 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9547 else
9548 {
9549 /* Using SSE is tricky, since we need bitwise negation of -0
9550 in register. */
9551 rtx reg = gen_reg_rtx (SFmode);
9552 rtx dest = operands[0];
9553 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9554
9555 operands[1] = force_reg (SFmode, operands[1]);
9556 operands[0] = force_reg (SFmode, operands[0]);
9557 reg = force_reg (V4SFmode,
9558 gen_rtx_CONST_VECTOR (V4SFmode,
9559 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9560 CONST0_RTX (SFmode),
9561 CONST0_RTX (SFmode))));
9562 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9563 if (dest != operands[0])
9564 emit_move_insn (dest, operands[0]);
9565 }
9566 DONE;
9567 }
9568 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9569
9570 (define_insn "negsf2_memory"
9571 [(set (match_operand:SF 0 "memory_operand" "=m")
9572 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9573 (clobber (reg:CC 17))]
9574 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9575 "#")
9576
9577 (define_insn "negsf2_ifs"
9578 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9579 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9580 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9581 (clobber (reg:CC 17))]
9582 "TARGET_SSE
9583 && (reload_in_progress || reload_completed
9584 || (register_operand (operands[0], VOIDmode)
9585 && register_operand (operands[1], VOIDmode)))"
9586 "#")
9587
9588 (define_split
9589 [(set (match_operand:SF 0 "memory_operand" "")
9590 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9591 (use (match_operand:SF 2 "" ""))
9592 (clobber (reg:CC 17))]
9593 ""
9594 [(parallel [(set (match_dup 0)
9595 (neg:SF (match_dup 1)))
9596 (clobber (reg:CC 17))])])
9597
9598 (define_split
9599 [(set (match_operand:SF 0 "register_operand" "")
9600 (neg:SF (match_operand:SF 1 "register_operand" "")))
9601 (use (match_operand:V4SF 2 "" ""))
9602 (clobber (reg:CC 17))]
9603 "reload_completed && !SSE_REG_P (operands[0])"
9604 [(parallel [(set (match_dup 0)
9605 (neg:SF (match_dup 1)))
9606 (clobber (reg:CC 17))])])
9607
9608 (define_split
9609 [(set (match_operand:SF 0 "register_operand" "")
9610 (neg:SF (match_operand:SF 1 "register_operand" "")))
9611 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9612 (clobber (reg:CC 17))]
9613 "reload_completed && SSE_REG_P (operands[0])"
9614 [(set (match_dup 0)
9615 (xor:V4SF (match_dup 1)
9616 (match_dup 2)))]
9617 {
9618 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9619 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9620 if (operands_match_p (operands[0], operands[2]))
9621 {
9622 rtx tmp;
9623 tmp = operands[1];
9624 operands[1] = operands[2];
9625 operands[2] = tmp;
9626 }
9627 })
9628
9629
9630 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9631 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9632 ;; to itself.
9633 (define_insn "*negsf2_if"
9634 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9635 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9636 (clobber (reg:CC 17))]
9637 "TARGET_80387 && !TARGET_SSE
9638 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9639 "#")
9640
9641 (define_split
9642 [(set (match_operand:SF 0 "fp_register_operand" "")
9643 (neg:SF (match_operand:SF 1 "register_operand" "")))
9644 (clobber (reg:CC 17))]
9645 "TARGET_80387 && reload_completed"
9646 [(set (match_dup 0)
9647 (neg:SF (match_dup 1)))]
9648 "")
9649
9650 (define_split
9651 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9652 (neg:SF (match_operand:SF 1 "register_operand" "")))
9653 (clobber (reg:CC 17))]
9654 "TARGET_80387 && reload_completed"
9655 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9656 (clobber (reg:CC 17))])]
9657 "operands[1] = gen_int_mode (0x80000000, SImode);
9658 operands[0] = gen_lowpart (SImode, operands[0]);")
9659
9660 (define_split
9661 [(set (match_operand 0 "memory_operand" "")
9662 (neg (match_operand 1 "memory_operand" "")))
9663 (clobber (reg:CC 17))]
9664 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9665 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9666 (clobber (reg:CC 17))])]
9667 {
9668 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9669
9670 if (GET_MODE (operands[1]) == XFmode)
9671 size = 10;
9672 operands[0] = adjust_address (operands[0], QImode, size - 1);
9673 operands[1] = gen_int_mode (0x80, QImode);
9674 })
9675
9676 (define_expand "negdf2"
9677 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9678 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9679 (clobber (reg:CC 17))])]
9680 "TARGET_80387"
9681 "if (TARGET_SSE2)
9682 {
9683 /* In case operand is in memory, we will not use SSE. */
9684 if (memory_operand (operands[0], VOIDmode)
9685 && rtx_equal_p (operands[0], operands[1]))
9686 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9687 else
9688 {
9689 /* Using SSE is tricky, since we need bitwise negation of -0
9690 in register. */
9691 rtx reg;
9692 #if HOST_BITS_PER_WIDE_INT >= 64
9693 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9694 #else
9695 rtx imm = immed_double_const (0, 0x80000000, DImode);
9696 #endif
9697 rtx dest = operands[0];
9698
9699 operands[1] = force_reg (DFmode, operands[1]);
9700 operands[0] = force_reg (DFmode, operands[0]);
9701 imm = gen_lowpart (DFmode, imm);
9702 reg = force_reg (V2DFmode,
9703 gen_rtx_CONST_VECTOR (V2DFmode,
9704 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9705 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9706 if (dest != operands[0])
9707 emit_move_insn (dest, operands[0]);
9708 }
9709 DONE;
9710 }
9711 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9712
9713 (define_insn "negdf2_memory"
9714 [(set (match_operand:DF 0 "memory_operand" "=m")
9715 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9716 (clobber (reg:CC 17))]
9717 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9718 "#")
9719
9720 (define_insn "negdf2_ifs"
9721 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9722 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9723 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9724 (clobber (reg:CC 17))]
9725 "!TARGET_64BIT && TARGET_SSE2
9726 && (reload_in_progress || reload_completed
9727 || (register_operand (operands[0], VOIDmode)
9728 && register_operand (operands[1], VOIDmode)))"
9729 "#")
9730
9731 (define_insn "*negdf2_ifs_rex64"
9732 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9733 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9734 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9735 (clobber (reg:CC 17))]
9736 "TARGET_64BIT && TARGET_SSE2
9737 && (reload_in_progress || reload_completed
9738 || (register_operand (operands[0], VOIDmode)
9739 && register_operand (operands[1], VOIDmode)))"
9740 "#")
9741
9742 (define_split
9743 [(set (match_operand:DF 0 "memory_operand" "")
9744 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9745 (use (match_operand:V2DF 2 "" ""))
9746 (clobber (reg:CC 17))]
9747 ""
9748 [(parallel [(set (match_dup 0)
9749 (neg:DF (match_dup 1)))
9750 (clobber (reg:CC 17))])])
9751
9752 (define_split
9753 [(set (match_operand:DF 0 "register_operand" "")
9754 (neg:DF (match_operand:DF 1 "register_operand" "")))
9755 (use (match_operand:V2DF 2 "" ""))
9756 (clobber (reg:CC 17))]
9757 "reload_completed && !SSE_REG_P (operands[0])
9758 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9759 [(parallel [(set (match_dup 0)
9760 (neg:DF (match_dup 1)))
9761 (clobber (reg:CC 17))])])
9762
9763 (define_split
9764 [(set (match_operand:DF 0 "register_operand" "")
9765 (neg:DF (match_operand:DF 1 "register_operand" "")))
9766 (use (match_operand:V2DF 2 "" ""))
9767 (clobber (reg:CC 17))]
9768 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9769 [(parallel [(set (match_dup 0)
9770 (xor:DI (match_dup 1) (match_dup 2)))
9771 (clobber (reg:CC 17))])]
9772 "operands[0] = gen_lowpart (DImode, operands[0]);
9773 operands[1] = gen_lowpart (DImode, operands[1]);
9774 operands[2] = gen_lowpart (DImode, operands[2]);")
9775
9776 (define_split
9777 [(set (match_operand:DF 0 "register_operand" "")
9778 (neg:DF (match_operand:DF 1 "register_operand" "")))
9779 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9780 (clobber (reg:CC 17))]
9781 "reload_completed && SSE_REG_P (operands[0])"
9782 [(set (match_dup 0)
9783 (xor:V2DF (match_dup 1)
9784 (match_dup 2)))]
9785 {
9786 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9787 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9788 /* Avoid possible reformatting on the operands. */
9789 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9790 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9791 if (operands_match_p (operands[0], operands[2]))
9792 {
9793 rtx tmp;
9794 tmp = operands[1];
9795 operands[1] = operands[2];
9796 operands[2] = tmp;
9797 }
9798 })
9799
9800 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9801 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9802 ;; to itself.
9803 (define_insn "*negdf2_if"
9804 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9805 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9806 (clobber (reg:CC 17))]
9807 "!TARGET_64BIT && TARGET_80387
9808 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9809 "#")
9810
9811 ;; FIXME: We should to allow integer registers here. Problem is that
9812 ;; we need another scratch register to get constant from.
9813 ;; Forcing constant to mem if no register available in peep2 should be
9814 ;; safe even for PIC mode, because of RIP relative addressing.
9815 (define_insn "*negdf2_if_rex64"
9816 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9817 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9818 (clobber (reg:CC 17))]
9819 "TARGET_64BIT && TARGET_80387
9820 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9821 "#")
9822
9823 (define_split
9824 [(set (match_operand:DF 0 "fp_register_operand" "")
9825 (neg:DF (match_operand:DF 1 "register_operand" "")))
9826 (clobber (reg:CC 17))]
9827 "TARGET_80387 && reload_completed"
9828 [(set (match_dup 0)
9829 (neg:DF (match_dup 1)))]
9830 "")
9831
9832 (define_split
9833 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9834 (neg:DF (match_operand:DF 1 "register_operand" "")))
9835 (clobber (reg:CC 17))]
9836 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9837 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9838 (clobber (reg:CC 17))])]
9839 "operands[4] = gen_int_mode (0x80000000, SImode);
9840 split_di (operands+0, 1, operands+2, operands+3);")
9841
9842 (define_expand "negxf2"
9843 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9844 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9845 (clobber (reg:CC 17))])]
9846 "TARGET_80387"
9847 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9848
9849 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9850 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9851 ;; to itself.
9852 (define_insn "*negxf2_if"
9853 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9854 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9855 (clobber (reg:CC 17))]
9856 "TARGET_80387
9857 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9858 "#")
9859
9860 (define_split
9861 [(set (match_operand:XF 0 "fp_register_operand" "")
9862 (neg:XF (match_operand:XF 1 "register_operand" "")))
9863 (clobber (reg:CC 17))]
9864 "TARGET_80387 && reload_completed"
9865 [(set (match_dup 0)
9866 (neg:XF (match_dup 1)))]
9867 "")
9868
9869 (define_split
9870 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9871 (neg:XF (match_operand:XF 1 "register_operand" "")))
9872 (clobber (reg:CC 17))]
9873 "TARGET_80387 && reload_completed"
9874 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9875 (clobber (reg:CC 17))])]
9876 "operands[1] = GEN_INT (0x8000);
9877 operands[0] = gen_rtx_REG (SImode,
9878 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9879
9880 ;; Conditionalize these after reload. If they matches before reload, we
9881 ;; lose the clobber and ability to use integer instructions.
9882
9883 (define_insn "*negsf2_1"
9884 [(set (match_operand:SF 0 "register_operand" "=f")
9885 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9886 "TARGET_80387 && reload_completed"
9887 "fchs"
9888 [(set_attr "type" "fsgn")
9889 (set_attr "mode" "SF")])
9890
9891 (define_insn "*negdf2_1"
9892 [(set (match_operand:DF 0 "register_operand" "=f")
9893 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9894 "TARGET_80387 && reload_completed"
9895 "fchs"
9896 [(set_attr "type" "fsgn")
9897 (set_attr "mode" "DF")])
9898
9899 (define_insn "*negextendsfdf2"
9900 [(set (match_operand:DF 0 "register_operand" "=f")
9901 (neg:DF (float_extend:DF
9902 (match_operand:SF 1 "register_operand" "0"))))]
9903 "TARGET_80387"
9904 "fchs"
9905 [(set_attr "type" "fsgn")
9906 (set_attr "mode" "DF")])
9907
9908 (define_insn "*negxf2_1"
9909 [(set (match_operand:XF 0 "register_operand" "=f")
9910 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9911 "TARGET_80387 && reload_completed"
9912 "fchs"
9913 [(set_attr "type" "fsgn")
9914 (set_attr "mode" "XF")])
9915
9916 (define_insn "*negextenddfxf2"
9917 [(set (match_operand:XF 0 "register_operand" "=f")
9918 (neg:XF (float_extend:XF
9919 (match_operand:DF 1 "register_operand" "0"))))]
9920 "TARGET_80387"
9921 "fchs"
9922 [(set_attr "type" "fsgn")
9923 (set_attr "mode" "XF")])
9924
9925 (define_insn "*negextendsfxf2"
9926 [(set (match_operand:XF 0 "register_operand" "=f")
9927 (neg:XF (float_extend:XF
9928 (match_operand:SF 1 "register_operand" "0"))))]
9929 "TARGET_80387"
9930 "fchs"
9931 [(set_attr "type" "fsgn")
9932 (set_attr "mode" "XF")])
9933 \f
9934 ;; Absolute value instructions
9935
9936 (define_expand "abssf2"
9937 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9938 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9939 (clobber (reg:CC 17))])]
9940 "TARGET_80387"
9941 "if (TARGET_SSE)
9942 {
9943 /* In case operand is in memory, we will not use SSE. */
9944 if (memory_operand (operands[0], VOIDmode)
9945 && rtx_equal_p (operands[0], operands[1]))
9946 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9947 else
9948 {
9949 /* Using SSE is tricky, since we need bitwise negation of -0
9950 in register. */
9951 rtx reg = gen_reg_rtx (V4SFmode);
9952 rtx dest = operands[0];
9953 rtx imm;
9954
9955 operands[1] = force_reg (SFmode, operands[1]);
9956 operands[0] = force_reg (SFmode, operands[0]);
9957 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9958 reg = force_reg (V4SFmode,
9959 gen_rtx_CONST_VECTOR (V4SFmode,
9960 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9961 CONST0_RTX (SFmode),
9962 CONST0_RTX (SFmode))));
9963 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9964 if (dest != operands[0])
9965 emit_move_insn (dest, operands[0]);
9966 }
9967 DONE;
9968 }
9969 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9970
9971 (define_insn "abssf2_memory"
9972 [(set (match_operand:SF 0 "memory_operand" "=m")
9973 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9974 (clobber (reg:CC 17))]
9975 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9976 "#")
9977
9978 (define_insn "abssf2_ifs"
9979 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9980 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9981 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9982 (clobber (reg:CC 17))]
9983 "TARGET_SSE
9984 && (reload_in_progress || reload_completed
9985 || (register_operand (operands[0], VOIDmode)
9986 && register_operand (operands[1], VOIDmode)))"
9987 "#")
9988
9989 (define_split
9990 [(set (match_operand:SF 0 "memory_operand" "")
9991 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9992 (use (match_operand:V4SF 2 "" ""))
9993 (clobber (reg:CC 17))]
9994 ""
9995 [(parallel [(set (match_dup 0)
9996 (abs:SF (match_dup 1)))
9997 (clobber (reg:CC 17))])])
9998
9999 (define_split
10000 [(set (match_operand:SF 0 "register_operand" "")
10001 (abs:SF (match_operand:SF 1 "register_operand" "")))
10002 (use (match_operand:V4SF 2 "" ""))
10003 (clobber (reg:CC 17))]
10004 "reload_completed && !SSE_REG_P (operands[0])"
10005 [(parallel [(set (match_dup 0)
10006 (abs:SF (match_dup 1)))
10007 (clobber (reg:CC 17))])])
10008
10009 (define_split
10010 [(set (match_operand:SF 0 "register_operand" "")
10011 (abs:SF (match_operand:SF 1 "register_operand" "")))
10012 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10013 (clobber (reg:CC 17))]
10014 "reload_completed && SSE_REG_P (operands[0])"
10015 [(set (match_dup 0)
10016 (and:V4SF (match_dup 1)
10017 (match_dup 2)))]
10018 {
10019 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10020 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10021 if (operands_match_p (operands[0], operands[2]))
10022 {
10023 rtx tmp;
10024 tmp = operands[1];
10025 operands[1] = operands[2];
10026 operands[2] = tmp;
10027 }
10028 })
10029
10030 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10031 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10032 ;; to itself.
10033 (define_insn "*abssf2_if"
10034 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10035 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10036 (clobber (reg:CC 17))]
10037 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10038 "#")
10039
10040 (define_split
10041 [(set (match_operand:SF 0 "fp_register_operand" "")
10042 (abs:SF (match_operand:SF 1 "register_operand" "")))
10043 (clobber (reg:CC 17))]
10044 "TARGET_80387 && reload_completed"
10045 [(set (match_dup 0)
10046 (abs:SF (match_dup 1)))]
10047 "")
10048
10049 (define_split
10050 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10051 (abs:SF (match_operand:SF 1 "register_operand" "")))
10052 (clobber (reg:CC 17))]
10053 "TARGET_80387 && reload_completed"
10054 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10055 (clobber (reg:CC 17))])]
10056 "operands[1] = gen_int_mode (~0x80000000, SImode);
10057 operands[0] = gen_lowpart (SImode, operands[0]);")
10058
10059 (define_split
10060 [(set (match_operand 0 "memory_operand" "")
10061 (abs (match_operand 1 "memory_operand" "")))
10062 (clobber (reg:CC 17))]
10063 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10064 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10065 (clobber (reg:CC 17))])]
10066 {
10067 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10068
10069 if (GET_MODE (operands[1]) == XFmode)
10070 size = 10;
10071 operands[0] = adjust_address (operands[0], QImode, size - 1);
10072 operands[1] = gen_int_mode (~0x80, QImode);
10073 })
10074
10075 (define_expand "absdf2"
10076 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10077 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10078 (clobber (reg:CC 17))])]
10079 "TARGET_80387"
10080 "if (TARGET_SSE2)
10081 {
10082 /* In case operand is in memory, we will not use SSE. */
10083 if (memory_operand (operands[0], VOIDmode)
10084 && rtx_equal_p (operands[0], operands[1]))
10085 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10086 else
10087 {
10088 /* Using SSE is tricky, since we need bitwise negation of -0
10089 in register. */
10090 rtx reg = gen_reg_rtx (V2DFmode);
10091 #if HOST_BITS_PER_WIDE_INT >= 64
10092 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10093 #else
10094 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10095 #endif
10096 rtx dest = operands[0];
10097
10098 operands[1] = force_reg (DFmode, operands[1]);
10099 operands[0] = force_reg (DFmode, operands[0]);
10100
10101 /* Produce LONG_DOUBLE with the proper immediate argument. */
10102 imm = gen_lowpart (DFmode, imm);
10103 reg = force_reg (V2DFmode,
10104 gen_rtx_CONST_VECTOR (V2DFmode,
10105 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10106 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10107 if (dest != operands[0])
10108 emit_move_insn (dest, operands[0]);
10109 }
10110 DONE;
10111 }
10112 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10113
10114 (define_insn "absdf2_memory"
10115 [(set (match_operand:DF 0 "memory_operand" "=m")
10116 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10117 (clobber (reg:CC 17))]
10118 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10119 "#")
10120
10121 (define_insn "absdf2_ifs"
10122 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10123 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10124 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10125 (clobber (reg:CC 17))]
10126 "!TARGET_64BIT && TARGET_SSE2
10127 && (reload_in_progress || reload_completed
10128 || (register_operand (operands[0], VOIDmode)
10129 && register_operand (operands[1], VOIDmode)))"
10130 "#")
10131
10132 (define_insn "*absdf2_ifs_rex64"
10133 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10134 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10135 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10136 (clobber (reg:CC 17))]
10137 "TARGET_64BIT && TARGET_SSE2
10138 && (reload_in_progress || reload_completed
10139 || (register_operand (operands[0], VOIDmode)
10140 && register_operand (operands[1], VOIDmode)))"
10141 "#")
10142
10143 (define_split
10144 [(set (match_operand:DF 0 "memory_operand" "")
10145 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10146 (use (match_operand:V2DF 2 "" ""))
10147 (clobber (reg:CC 17))]
10148 ""
10149 [(parallel [(set (match_dup 0)
10150 (abs:DF (match_dup 1)))
10151 (clobber (reg:CC 17))])])
10152
10153 (define_split
10154 [(set (match_operand:DF 0 "register_operand" "")
10155 (abs:DF (match_operand:DF 1 "register_operand" "")))
10156 (use (match_operand:V2DF 2 "" ""))
10157 (clobber (reg:CC 17))]
10158 "reload_completed && !SSE_REG_P (operands[0])"
10159 [(parallel [(set (match_dup 0)
10160 (abs:DF (match_dup 1)))
10161 (clobber (reg:CC 17))])])
10162
10163 (define_split
10164 [(set (match_operand:DF 0 "register_operand" "")
10165 (abs:DF (match_operand:DF 1 "register_operand" "")))
10166 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10167 (clobber (reg:CC 17))]
10168 "reload_completed && SSE_REG_P (operands[0])"
10169 [(set (match_dup 0)
10170 (and:V2DF (match_dup 1)
10171 (match_dup 2)))]
10172 {
10173 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10174 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10175 /* Avoid possible reformatting on the operands. */
10176 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10177 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10178 if (operands_match_p (operands[0], operands[2]))
10179 {
10180 rtx tmp;
10181 tmp = operands[1];
10182 operands[1] = operands[2];
10183 operands[2] = tmp;
10184 }
10185 })
10186
10187
10188 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10189 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10190 ;; to itself.
10191 (define_insn "*absdf2_if"
10192 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10193 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10194 (clobber (reg:CC 17))]
10195 "!TARGET_64BIT && TARGET_80387
10196 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10197 "#")
10198
10199 ;; FIXME: We should to allow integer registers here. Problem is that
10200 ;; we need another scratch register to get constant from.
10201 ;; Forcing constant to mem if no register available in peep2 should be
10202 ;; safe even for PIC mode, because of RIP relative addressing.
10203 (define_insn "*absdf2_if_rex64"
10204 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10205 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10206 (clobber (reg:CC 17))]
10207 "TARGET_64BIT && TARGET_80387
10208 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10209 "#")
10210
10211 (define_split
10212 [(set (match_operand:DF 0 "fp_register_operand" "")
10213 (abs:DF (match_operand:DF 1 "register_operand" "")))
10214 (clobber (reg:CC 17))]
10215 "TARGET_80387 && reload_completed"
10216 [(set (match_dup 0)
10217 (abs:DF (match_dup 1)))]
10218 "")
10219
10220 (define_split
10221 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10222 (abs:DF (match_operand:DF 1 "register_operand" "")))
10223 (clobber (reg:CC 17))]
10224 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10225 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10226 (clobber (reg:CC 17))])]
10227 "operands[4] = gen_int_mode (~0x80000000, SImode);
10228 split_di (operands+0, 1, operands+2, operands+3);")
10229
10230 (define_expand "absxf2"
10231 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10232 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10233 (clobber (reg:CC 17))])]
10234 "TARGET_80387"
10235 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10236
10237 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10238 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10239 ;; to itself.
10240 (define_insn "*absxf2_if"
10241 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10242 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10243 (clobber (reg:CC 17))]
10244 "TARGET_80387
10245 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10246 "#")
10247
10248 (define_split
10249 [(set (match_operand:XF 0 "fp_register_operand" "")
10250 (abs:XF (match_operand:XF 1 "register_operand" "")))
10251 (clobber (reg:CC 17))]
10252 "TARGET_80387 && reload_completed"
10253 [(set (match_dup 0)
10254 (abs:XF (match_dup 1)))]
10255 "")
10256
10257 (define_split
10258 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10259 (abs:XF (match_operand:XF 1 "register_operand" "")))
10260 (clobber (reg:CC 17))]
10261 "TARGET_80387 && reload_completed"
10262 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10263 (clobber (reg:CC 17))])]
10264 "operands[1] = GEN_INT (~0x8000);
10265 operands[0] = gen_rtx_REG (SImode,
10266 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10267
10268 (define_insn "*abssf2_1"
10269 [(set (match_operand:SF 0 "register_operand" "=f")
10270 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10271 "TARGET_80387 && reload_completed"
10272 "fabs"
10273 [(set_attr "type" "fsgn")
10274 (set_attr "mode" "SF")])
10275
10276 (define_insn "*absdf2_1"
10277 [(set (match_operand:DF 0 "register_operand" "=f")
10278 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10279 "TARGET_80387 && reload_completed"
10280 "fabs"
10281 [(set_attr "type" "fsgn")
10282 (set_attr "mode" "DF")])
10283
10284 (define_insn "*absextendsfdf2"
10285 [(set (match_operand:DF 0 "register_operand" "=f")
10286 (abs:DF (float_extend:DF
10287 (match_operand:SF 1 "register_operand" "0"))))]
10288 "TARGET_80387"
10289 "fabs"
10290 [(set_attr "type" "fsgn")
10291 (set_attr "mode" "DF")])
10292
10293 (define_insn "*absxf2_1"
10294 [(set (match_operand:XF 0 "register_operand" "=f")
10295 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10296 "TARGET_80387 && reload_completed"
10297 "fabs"
10298 [(set_attr "type" "fsgn")
10299 (set_attr "mode" "DF")])
10300
10301 (define_insn "*absextenddfxf2"
10302 [(set (match_operand:XF 0 "register_operand" "=f")
10303 (abs:XF (float_extend:XF
10304 (match_operand:DF 1 "register_operand" "0"))))]
10305 "TARGET_80387"
10306 "fabs"
10307 [(set_attr "type" "fsgn")
10308 (set_attr "mode" "XF")])
10309
10310 (define_insn "*absextendsfxf2"
10311 [(set (match_operand:XF 0 "register_operand" "=f")
10312 (abs:XF (float_extend:XF
10313 (match_operand:SF 1 "register_operand" "0"))))]
10314 "TARGET_80387"
10315 "fabs"
10316 [(set_attr "type" "fsgn")
10317 (set_attr "mode" "XF")])
10318 \f
10319 ;; One complement instructions
10320
10321 (define_expand "one_cmpldi2"
10322 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10323 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10324 "TARGET_64BIT"
10325 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10326
10327 (define_insn "*one_cmpldi2_1_rex64"
10328 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10329 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10330 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10331 "not{q}\t%0"
10332 [(set_attr "type" "negnot")
10333 (set_attr "mode" "DI")])
10334
10335 (define_insn "*one_cmpldi2_2_rex64"
10336 [(set (reg 17)
10337 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10338 (const_int 0)))
10339 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10340 (not:DI (match_dup 1)))]
10341 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10342 && ix86_unary_operator_ok (NOT, DImode, operands)"
10343 "#"
10344 [(set_attr "type" "alu1")
10345 (set_attr "mode" "DI")])
10346
10347 (define_split
10348 [(set (reg 17)
10349 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10350 (const_int 0)))
10351 (set (match_operand:DI 0 "nonimmediate_operand" "")
10352 (not:DI (match_dup 1)))]
10353 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10354 [(parallel [(set (reg:CCNO 17)
10355 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10356 (const_int 0)))
10357 (set (match_dup 0)
10358 (xor:DI (match_dup 1) (const_int -1)))])]
10359 "")
10360
10361 (define_expand "one_cmplsi2"
10362 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10363 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10364 ""
10365 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10366
10367 (define_insn "*one_cmplsi2_1"
10368 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10369 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10370 "ix86_unary_operator_ok (NOT, SImode, operands)"
10371 "not{l}\t%0"
10372 [(set_attr "type" "negnot")
10373 (set_attr "mode" "SI")])
10374
10375 ;; ??? Currently never generated - xor is used instead.
10376 (define_insn "*one_cmplsi2_1_zext"
10377 [(set (match_operand:DI 0 "register_operand" "=r")
10378 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10379 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10380 "not{l}\t%k0"
10381 [(set_attr "type" "negnot")
10382 (set_attr "mode" "SI")])
10383
10384 (define_insn "*one_cmplsi2_2"
10385 [(set (reg 17)
10386 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10387 (const_int 0)))
10388 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10389 (not:SI (match_dup 1)))]
10390 "ix86_match_ccmode (insn, CCNOmode)
10391 && ix86_unary_operator_ok (NOT, SImode, operands)"
10392 "#"
10393 [(set_attr "type" "alu1")
10394 (set_attr "mode" "SI")])
10395
10396 (define_split
10397 [(set (reg 17)
10398 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10399 (const_int 0)))
10400 (set (match_operand:SI 0 "nonimmediate_operand" "")
10401 (not:SI (match_dup 1)))]
10402 "ix86_match_ccmode (insn, CCNOmode)"
10403 [(parallel [(set (reg:CCNO 17)
10404 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10405 (const_int 0)))
10406 (set (match_dup 0)
10407 (xor:SI (match_dup 1) (const_int -1)))])]
10408 "")
10409
10410 ;; ??? Currently never generated - xor is used instead.
10411 (define_insn "*one_cmplsi2_2_zext"
10412 [(set (reg 17)
10413 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10414 (const_int 0)))
10415 (set (match_operand:DI 0 "register_operand" "=r")
10416 (zero_extend:DI (not:SI (match_dup 1))))]
10417 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10418 && ix86_unary_operator_ok (NOT, SImode, operands)"
10419 "#"
10420 [(set_attr "type" "alu1")
10421 (set_attr "mode" "SI")])
10422
10423 (define_split
10424 [(set (reg 17)
10425 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10426 (const_int 0)))
10427 (set (match_operand:DI 0 "register_operand" "")
10428 (zero_extend:DI (not:SI (match_dup 1))))]
10429 "ix86_match_ccmode (insn, CCNOmode)"
10430 [(parallel [(set (reg:CCNO 17)
10431 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10432 (const_int 0)))
10433 (set (match_dup 0)
10434 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10435 "")
10436
10437 (define_expand "one_cmplhi2"
10438 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10439 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10440 "TARGET_HIMODE_MATH"
10441 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10442
10443 (define_insn "*one_cmplhi2_1"
10444 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10445 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10446 "ix86_unary_operator_ok (NOT, HImode, operands)"
10447 "not{w}\t%0"
10448 [(set_attr "type" "negnot")
10449 (set_attr "mode" "HI")])
10450
10451 (define_insn "*one_cmplhi2_2"
10452 [(set (reg 17)
10453 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10454 (const_int 0)))
10455 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10456 (not:HI (match_dup 1)))]
10457 "ix86_match_ccmode (insn, CCNOmode)
10458 && ix86_unary_operator_ok (NEG, HImode, operands)"
10459 "#"
10460 [(set_attr "type" "alu1")
10461 (set_attr "mode" "HI")])
10462
10463 (define_split
10464 [(set (reg 17)
10465 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10466 (const_int 0)))
10467 (set (match_operand:HI 0 "nonimmediate_operand" "")
10468 (not:HI (match_dup 1)))]
10469 "ix86_match_ccmode (insn, CCNOmode)"
10470 [(parallel [(set (reg:CCNO 17)
10471 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10472 (const_int 0)))
10473 (set (match_dup 0)
10474 (xor:HI (match_dup 1) (const_int -1)))])]
10475 "")
10476
10477 ;; %%% Potential partial reg stall on alternative 1. What to do?
10478 (define_expand "one_cmplqi2"
10479 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10480 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10481 "TARGET_QIMODE_MATH"
10482 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10483
10484 (define_insn "*one_cmplqi2_1"
10485 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10486 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10487 "ix86_unary_operator_ok (NOT, QImode, operands)"
10488 "@
10489 not{b}\t%0
10490 not{l}\t%k0"
10491 [(set_attr "type" "negnot")
10492 (set_attr "mode" "QI,SI")])
10493
10494 (define_insn "*one_cmplqi2_2"
10495 [(set (reg 17)
10496 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10497 (const_int 0)))
10498 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10499 (not:QI (match_dup 1)))]
10500 "ix86_match_ccmode (insn, CCNOmode)
10501 && ix86_unary_operator_ok (NOT, QImode, operands)"
10502 "#"
10503 [(set_attr "type" "alu1")
10504 (set_attr "mode" "QI")])
10505
10506 (define_split
10507 [(set (reg 17)
10508 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10509 (const_int 0)))
10510 (set (match_operand:QI 0 "nonimmediate_operand" "")
10511 (not:QI (match_dup 1)))]
10512 "ix86_match_ccmode (insn, CCNOmode)"
10513 [(parallel [(set (reg:CCNO 17)
10514 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10515 (const_int 0)))
10516 (set (match_dup 0)
10517 (xor:QI (match_dup 1) (const_int -1)))])]
10518 "")
10519 \f
10520 ;; Arithmetic shift instructions
10521
10522 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10523 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10524 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10525 ;; from the assembler input.
10526 ;;
10527 ;; This instruction shifts the target reg/mem as usual, but instead of
10528 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10529 ;; is a left shift double, bits are taken from the high order bits of
10530 ;; reg, else if the insn is a shift right double, bits are taken from the
10531 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10532 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10533 ;;
10534 ;; Since sh[lr]d does not change the `reg' operand, that is done
10535 ;; separately, making all shifts emit pairs of shift double and normal
10536 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10537 ;; support a 63 bit shift, each shift where the count is in a reg expands
10538 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10539 ;;
10540 ;; If the shift count is a constant, we need never emit more than one
10541 ;; shift pair, instead using moves and sign extension for counts greater
10542 ;; than 31.
10543
10544 (define_expand "ashldi3"
10545 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10546 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10547 (match_operand:QI 2 "nonmemory_operand" "")))
10548 (clobber (reg:CC 17))])]
10549 ""
10550 {
10551 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10552 {
10553 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10554 DONE;
10555 }
10556 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10557 DONE;
10558 })
10559
10560 (define_insn "*ashldi3_1_rex64"
10561 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10562 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10563 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10564 (clobber (reg:CC 17))]
10565 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10566 {
10567 switch (get_attr_type (insn))
10568 {
10569 case TYPE_ALU:
10570 if (operands[2] != const1_rtx)
10571 abort ();
10572 if (!rtx_equal_p (operands[0], operands[1]))
10573 abort ();
10574 return "add{q}\t{%0, %0|%0, %0}";
10575
10576 case TYPE_LEA:
10577 if (GET_CODE (operands[2]) != CONST_INT
10578 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10579 abort ();
10580 operands[1] = gen_rtx_MULT (DImode, operands[1],
10581 GEN_INT (1 << INTVAL (operands[2])));
10582 return "lea{q}\t{%a1, %0|%0, %a1}";
10583
10584 default:
10585 if (REG_P (operands[2]))
10586 return "sal{q}\t{%b2, %0|%0, %b2}";
10587 else if (operands[2] == const1_rtx
10588 && (TARGET_SHIFT1 || optimize_size))
10589 return "sal{q}\t%0";
10590 else
10591 return "sal{q}\t{%2, %0|%0, %2}";
10592 }
10593 }
10594 [(set (attr "type")
10595 (cond [(eq_attr "alternative" "1")
10596 (const_string "lea")
10597 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10598 (const_int 0))
10599 (match_operand 0 "register_operand" ""))
10600 (match_operand 2 "const1_operand" ""))
10601 (const_string "alu")
10602 ]
10603 (const_string "ishift")))
10604 (set_attr "mode" "DI")])
10605
10606 ;; Convert lea to the lea pattern to avoid flags dependency.
10607 (define_split
10608 [(set (match_operand:DI 0 "register_operand" "")
10609 (ashift:DI (match_operand:DI 1 "register_operand" "")
10610 (match_operand:QI 2 "immediate_operand" "")))
10611 (clobber (reg:CC 17))]
10612 "TARGET_64BIT && reload_completed
10613 && true_regnum (operands[0]) != true_regnum (operands[1])"
10614 [(set (match_dup 0)
10615 (mult:DI (match_dup 1)
10616 (match_dup 2)))]
10617 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10618
10619 ;; This pattern can't accept a variable shift count, since shifts by
10620 ;; zero don't affect the flags. We assume that shifts by constant
10621 ;; zero are optimized away.
10622 (define_insn "*ashldi3_cmp_rex64"
10623 [(set (reg 17)
10624 (compare
10625 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10626 (match_operand:QI 2 "immediate_operand" "e"))
10627 (const_int 0)))
10628 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10629 (ashift:DI (match_dup 1) (match_dup 2)))]
10630 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10631 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10632 {
10633 switch (get_attr_type (insn))
10634 {
10635 case TYPE_ALU:
10636 if (operands[2] != const1_rtx)
10637 abort ();
10638 return "add{q}\t{%0, %0|%0, %0}";
10639
10640 default:
10641 if (REG_P (operands[2]))
10642 return "sal{q}\t{%b2, %0|%0, %b2}";
10643 else if (operands[2] == const1_rtx
10644 && (TARGET_SHIFT1 || optimize_size))
10645 return "sal{q}\t%0";
10646 else
10647 return "sal{q}\t{%2, %0|%0, %2}";
10648 }
10649 }
10650 [(set (attr "type")
10651 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10652 (const_int 0))
10653 (match_operand 0 "register_operand" ""))
10654 (match_operand 2 "const1_operand" ""))
10655 (const_string "alu")
10656 ]
10657 (const_string "ishift")))
10658 (set_attr "mode" "DI")])
10659
10660 (define_insn "ashldi3_1"
10661 [(set (match_operand:DI 0 "register_operand" "=r")
10662 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10663 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10664 (clobber (match_scratch:SI 3 "=&r"))
10665 (clobber (reg:CC 17))]
10666 "!TARGET_64BIT && TARGET_CMOVE"
10667 "#"
10668 [(set_attr "type" "multi")])
10669
10670 (define_insn "*ashldi3_2"
10671 [(set (match_operand:DI 0 "register_operand" "=r")
10672 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10673 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10674 (clobber (reg:CC 17))]
10675 "!TARGET_64BIT"
10676 "#"
10677 [(set_attr "type" "multi")])
10678
10679 (define_split
10680 [(set (match_operand:DI 0 "register_operand" "")
10681 (ashift:DI (match_operand:DI 1 "register_operand" "")
10682 (match_operand:QI 2 "nonmemory_operand" "")))
10683 (clobber (match_scratch:SI 3 ""))
10684 (clobber (reg:CC 17))]
10685 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10686 [(const_int 0)]
10687 "ix86_split_ashldi (operands, operands[3]); DONE;")
10688
10689 (define_split
10690 [(set (match_operand:DI 0 "register_operand" "")
10691 (ashift:DI (match_operand:DI 1 "register_operand" "")
10692 (match_operand:QI 2 "nonmemory_operand" "")))
10693 (clobber (reg:CC 17))]
10694 "!TARGET_64BIT && reload_completed"
10695 [(const_int 0)]
10696 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10697
10698 (define_insn "x86_shld_1"
10699 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10700 (ior:SI (ashift:SI (match_dup 0)
10701 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10702 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10703 (minus:QI (const_int 32) (match_dup 2)))))
10704 (clobber (reg:CC 17))]
10705 ""
10706 "@
10707 shld{l}\t{%2, %1, %0|%0, %1, %2}
10708 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10709 [(set_attr "type" "ishift")
10710 (set_attr "prefix_0f" "1")
10711 (set_attr "mode" "SI")
10712 (set_attr "pent_pair" "np")
10713 (set_attr "athlon_decode" "vector")])
10714
10715 (define_expand "x86_shift_adj_1"
10716 [(set (reg:CCZ 17)
10717 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10718 (const_int 32))
10719 (const_int 0)))
10720 (set (match_operand:SI 0 "register_operand" "")
10721 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10722 (match_operand:SI 1 "register_operand" "")
10723 (match_dup 0)))
10724 (set (match_dup 1)
10725 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10726 (match_operand:SI 3 "register_operand" "r")
10727 (match_dup 1)))]
10728 "TARGET_CMOVE"
10729 "")
10730
10731 (define_expand "x86_shift_adj_2"
10732 [(use (match_operand:SI 0 "register_operand" ""))
10733 (use (match_operand:SI 1 "register_operand" ""))
10734 (use (match_operand:QI 2 "register_operand" ""))]
10735 ""
10736 {
10737 rtx label = gen_label_rtx ();
10738 rtx tmp;
10739
10740 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10741
10742 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10743 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10744 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10745 gen_rtx_LABEL_REF (VOIDmode, label),
10746 pc_rtx);
10747 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10748 JUMP_LABEL (tmp) = label;
10749
10750 emit_move_insn (operands[0], operands[1]);
10751 emit_move_insn (operands[1], const0_rtx);
10752
10753 emit_label (label);
10754 LABEL_NUSES (label) = 1;
10755
10756 DONE;
10757 })
10758
10759 (define_expand "ashlsi3"
10760 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10761 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10762 (match_operand:QI 2 "nonmemory_operand" "")))
10763 (clobber (reg:CC 17))]
10764 ""
10765 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10766
10767 (define_insn "*ashlsi3_1"
10768 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10769 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10770 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10771 (clobber (reg:CC 17))]
10772 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10773 {
10774 switch (get_attr_type (insn))
10775 {
10776 case TYPE_ALU:
10777 if (operands[2] != const1_rtx)
10778 abort ();
10779 if (!rtx_equal_p (operands[0], operands[1]))
10780 abort ();
10781 return "add{l}\t{%0, %0|%0, %0}";
10782
10783 case TYPE_LEA:
10784 return "#";
10785
10786 default:
10787 if (REG_P (operands[2]))
10788 return "sal{l}\t{%b2, %0|%0, %b2}";
10789 else if (operands[2] == const1_rtx
10790 && (TARGET_SHIFT1 || optimize_size))
10791 return "sal{l}\t%0";
10792 else
10793 return "sal{l}\t{%2, %0|%0, %2}";
10794 }
10795 }
10796 [(set (attr "type")
10797 (cond [(eq_attr "alternative" "1")
10798 (const_string "lea")
10799 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10800 (const_int 0))
10801 (match_operand 0 "register_operand" ""))
10802 (match_operand 2 "const1_operand" ""))
10803 (const_string "alu")
10804 ]
10805 (const_string "ishift")))
10806 (set_attr "mode" "SI")])
10807
10808 ;; Convert lea to the lea pattern to avoid flags dependency.
10809 (define_split
10810 [(set (match_operand 0 "register_operand" "")
10811 (ashift (match_operand 1 "index_register_operand" "")
10812 (match_operand:QI 2 "const_int_operand" "")))
10813 (clobber (reg:CC 17))]
10814 "reload_completed
10815 && true_regnum (operands[0]) != true_regnum (operands[1])"
10816 [(const_int 0)]
10817 {
10818 rtx pat;
10819 operands[0] = gen_lowpart (SImode, operands[0]);
10820 operands[1] = gen_lowpart (Pmode, operands[1]);
10821 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10822 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10823 if (Pmode != SImode)
10824 pat = gen_rtx_SUBREG (SImode, pat, 0);
10825 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10826 DONE;
10827 })
10828
10829 ;; Rare case of shifting RSP is handled by generating move and shift
10830 (define_split
10831 [(set (match_operand 0 "register_operand" "")
10832 (ashift (match_operand 1 "register_operand" "")
10833 (match_operand:QI 2 "const_int_operand" "")))
10834 (clobber (reg:CC 17))]
10835 "reload_completed
10836 && true_regnum (operands[0]) != true_regnum (operands[1])"
10837 [(const_int 0)]
10838 {
10839 rtx pat, clob;
10840 emit_move_insn (operands[1], operands[0]);
10841 pat = gen_rtx_SET (VOIDmode, operands[0],
10842 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10843 operands[0], operands[2]));
10844 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10845 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10846 DONE;
10847 })
10848
10849 (define_insn "*ashlsi3_1_zext"
10850 [(set (match_operand:DI 0 "register_operand" "=r,r")
10851 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10852 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10853 (clobber (reg:CC 17))]
10854 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10855 {
10856 switch (get_attr_type (insn))
10857 {
10858 case TYPE_ALU:
10859 if (operands[2] != const1_rtx)
10860 abort ();
10861 return "add{l}\t{%k0, %k0|%k0, %k0}";
10862
10863 case TYPE_LEA:
10864 return "#";
10865
10866 default:
10867 if (REG_P (operands[2]))
10868 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10869 else if (operands[2] == const1_rtx
10870 && (TARGET_SHIFT1 || optimize_size))
10871 return "sal{l}\t%k0";
10872 else
10873 return "sal{l}\t{%2, %k0|%k0, %2}";
10874 }
10875 }
10876 [(set (attr "type")
10877 (cond [(eq_attr "alternative" "1")
10878 (const_string "lea")
10879 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10880 (const_int 0))
10881 (match_operand 2 "const1_operand" ""))
10882 (const_string "alu")
10883 ]
10884 (const_string "ishift")))
10885 (set_attr "mode" "SI")])
10886
10887 ;; Convert lea to the lea pattern to avoid flags dependency.
10888 (define_split
10889 [(set (match_operand:DI 0 "register_operand" "")
10890 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10891 (match_operand:QI 2 "const_int_operand" ""))))
10892 (clobber (reg:CC 17))]
10893 "TARGET_64BIT && reload_completed
10894 && true_regnum (operands[0]) != true_regnum (operands[1])"
10895 [(set (match_dup 0) (zero_extend:DI
10896 (subreg:SI (mult:SI (match_dup 1)
10897 (match_dup 2)) 0)))]
10898 {
10899 operands[1] = gen_lowpart (Pmode, operands[1]);
10900 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10901 })
10902
10903 ;; This pattern can't accept a variable shift count, since shifts by
10904 ;; zero don't affect the flags. We assume that shifts by constant
10905 ;; zero are optimized away.
10906 (define_insn "*ashlsi3_cmp"
10907 [(set (reg 17)
10908 (compare
10909 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10910 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10911 (const_int 0)))
10912 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10913 (ashift:SI (match_dup 1) (match_dup 2)))]
10914 "ix86_match_ccmode (insn, CCGOCmode)
10915 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10916 {
10917 switch (get_attr_type (insn))
10918 {
10919 case TYPE_ALU:
10920 if (operands[2] != const1_rtx)
10921 abort ();
10922 return "add{l}\t{%0, %0|%0, %0}";
10923
10924 default:
10925 if (REG_P (operands[2]))
10926 return "sal{l}\t{%b2, %0|%0, %b2}";
10927 else if (operands[2] == const1_rtx
10928 && (TARGET_SHIFT1 || optimize_size))
10929 return "sal{l}\t%0";
10930 else
10931 return "sal{l}\t{%2, %0|%0, %2}";
10932 }
10933 }
10934 [(set (attr "type")
10935 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10936 (const_int 0))
10937 (match_operand 0 "register_operand" ""))
10938 (match_operand 2 "const1_operand" ""))
10939 (const_string "alu")
10940 ]
10941 (const_string "ishift")))
10942 (set_attr "mode" "SI")])
10943
10944 (define_insn "*ashlsi3_cmp_zext"
10945 [(set (reg 17)
10946 (compare
10947 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10948 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10949 (const_int 0)))
10950 (set (match_operand:DI 0 "register_operand" "=r")
10951 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10952 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10953 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10954 {
10955 switch (get_attr_type (insn))
10956 {
10957 case TYPE_ALU:
10958 if (operands[2] != const1_rtx)
10959 abort ();
10960 return "add{l}\t{%k0, %k0|%k0, %k0}";
10961
10962 default:
10963 if (REG_P (operands[2]))
10964 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10965 else if (operands[2] == const1_rtx
10966 && (TARGET_SHIFT1 || optimize_size))
10967 return "sal{l}\t%k0";
10968 else
10969 return "sal{l}\t{%2, %k0|%k0, %2}";
10970 }
10971 }
10972 [(set (attr "type")
10973 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974 (const_int 0))
10975 (match_operand 2 "const1_operand" ""))
10976 (const_string "alu")
10977 ]
10978 (const_string "ishift")))
10979 (set_attr "mode" "SI")])
10980
10981 (define_expand "ashlhi3"
10982 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10983 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10984 (match_operand:QI 2 "nonmemory_operand" "")))
10985 (clobber (reg:CC 17))]
10986 "TARGET_HIMODE_MATH"
10987 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10988
10989 (define_insn "*ashlhi3_1_lea"
10990 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10991 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10992 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10993 (clobber (reg:CC 17))]
10994 "!TARGET_PARTIAL_REG_STALL
10995 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10996 {
10997 switch (get_attr_type (insn))
10998 {
10999 case TYPE_LEA:
11000 return "#";
11001 case TYPE_ALU:
11002 if (operands[2] != const1_rtx)
11003 abort ();
11004 return "add{w}\t{%0, %0|%0, %0}";
11005
11006 default:
11007 if (REG_P (operands[2]))
11008 return "sal{w}\t{%b2, %0|%0, %b2}";
11009 else if (operands[2] == const1_rtx
11010 && (TARGET_SHIFT1 || optimize_size))
11011 return "sal{w}\t%0";
11012 else
11013 return "sal{w}\t{%2, %0|%0, %2}";
11014 }
11015 }
11016 [(set (attr "type")
11017 (cond [(eq_attr "alternative" "1")
11018 (const_string "lea")
11019 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11020 (const_int 0))
11021 (match_operand 0 "register_operand" ""))
11022 (match_operand 2 "const1_operand" ""))
11023 (const_string "alu")
11024 ]
11025 (const_string "ishift")))
11026 (set_attr "mode" "HI,SI")])
11027
11028 (define_insn "*ashlhi3_1"
11029 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11030 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11031 (match_operand:QI 2 "nonmemory_operand" "cI")))
11032 (clobber (reg:CC 17))]
11033 "TARGET_PARTIAL_REG_STALL
11034 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11035 {
11036 switch (get_attr_type (insn))
11037 {
11038 case TYPE_ALU:
11039 if (operands[2] != const1_rtx)
11040 abort ();
11041 return "add{w}\t{%0, %0|%0, %0}";
11042
11043 default:
11044 if (REG_P (operands[2]))
11045 return "sal{w}\t{%b2, %0|%0, %b2}";
11046 else if (operands[2] == const1_rtx
11047 && (TARGET_SHIFT1 || optimize_size))
11048 return "sal{w}\t%0";
11049 else
11050 return "sal{w}\t{%2, %0|%0, %2}";
11051 }
11052 }
11053 [(set (attr "type")
11054 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11055 (const_int 0))
11056 (match_operand 0 "register_operand" ""))
11057 (match_operand 2 "const1_operand" ""))
11058 (const_string "alu")
11059 ]
11060 (const_string "ishift")))
11061 (set_attr "mode" "HI")])
11062
11063 ;; This pattern can't accept a variable shift count, since shifts by
11064 ;; zero don't affect the flags. We assume that shifts by constant
11065 ;; zero are optimized away.
11066 (define_insn "*ashlhi3_cmp"
11067 [(set (reg 17)
11068 (compare
11069 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11070 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11071 (const_int 0)))
11072 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11073 (ashift:HI (match_dup 1) (match_dup 2)))]
11074 "ix86_match_ccmode (insn, CCGOCmode)
11075 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11076 {
11077 switch (get_attr_type (insn))
11078 {
11079 case TYPE_ALU:
11080 if (operands[2] != const1_rtx)
11081 abort ();
11082 return "add{w}\t{%0, %0|%0, %0}";
11083
11084 default:
11085 if (REG_P (operands[2]))
11086 return "sal{w}\t{%b2, %0|%0, %b2}";
11087 else if (operands[2] == const1_rtx
11088 && (TARGET_SHIFT1 || optimize_size))
11089 return "sal{w}\t%0";
11090 else
11091 return "sal{w}\t{%2, %0|%0, %2}";
11092 }
11093 }
11094 [(set (attr "type")
11095 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11096 (const_int 0))
11097 (match_operand 0 "register_operand" ""))
11098 (match_operand 2 "const1_operand" ""))
11099 (const_string "alu")
11100 ]
11101 (const_string "ishift")))
11102 (set_attr "mode" "HI")])
11103
11104 (define_expand "ashlqi3"
11105 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11106 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11107 (match_operand:QI 2 "nonmemory_operand" "")))
11108 (clobber (reg:CC 17))]
11109 "TARGET_QIMODE_MATH"
11110 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11111
11112 ;; %%% Potential partial reg stall on alternative 2. What to do?
11113
11114 (define_insn "*ashlqi3_1_lea"
11115 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11116 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11117 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11118 (clobber (reg:CC 17))]
11119 "!TARGET_PARTIAL_REG_STALL
11120 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11121 {
11122 switch (get_attr_type (insn))
11123 {
11124 case TYPE_LEA:
11125 return "#";
11126 case TYPE_ALU:
11127 if (operands[2] != const1_rtx)
11128 abort ();
11129 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11130 return "add{l}\t{%k0, %k0|%k0, %k0}";
11131 else
11132 return "add{b}\t{%0, %0|%0, %0}";
11133
11134 default:
11135 if (REG_P (operands[2]))
11136 {
11137 if (get_attr_mode (insn) == MODE_SI)
11138 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11139 else
11140 return "sal{b}\t{%b2, %0|%0, %b2}";
11141 }
11142 else if (operands[2] == const1_rtx
11143 && (TARGET_SHIFT1 || optimize_size))
11144 {
11145 if (get_attr_mode (insn) == MODE_SI)
11146 return "sal{l}\t%0";
11147 else
11148 return "sal{b}\t%0";
11149 }
11150 else
11151 {
11152 if (get_attr_mode (insn) == MODE_SI)
11153 return "sal{l}\t{%2, %k0|%k0, %2}";
11154 else
11155 return "sal{b}\t{%2, %0|%0, %2}";
11156 }
11157 }
11158 }
11159 [(set (attr "type")
11160 (cond [(eq_attr "alternative" "2")
11161 (const_string "lea")
11162 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11163 (const_int 0))
11164 (match_operand 0 "register_operand" ""))
11165 (match_operand 2 "const1_operand" ""))
11166 (const_string "alu")
11167 ]
11168 (const_string "ishift")))
11169 (set_attr "mode" "QI,SI,SI")])
11170
11171 (define_insn "*ashlqi3_1"
11172 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11173 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11174 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11175 (clobber (reg:CC 17))]
11176 "TARGET_PARTIAL_REG_STALL
11177 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11178 {
11179 switch (get_attr_type (insn))
11180 {
11181 case TYPE_ALU:
11182 if (operands[2] != const1_rtx)
11183 abort ();
11184 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11185 return "add{l}\t{%k0, %k0|%k0, %k0}";
11186 else
11187 return "add{b}\t{%0, %0|%0, %0}";
11188
11189 default:
11190 if (REG_P (operands[2]))
11191 {
11192 if (get_attr_mode (insn) == MODE_SI)
11193 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11194 else
11195 return "sal{b}\t{%b2, %0|%0, %b2}";
11196 }
11197 else if (operands[2] == const1_rtx
11198 && (TARGET_SHIFT1 || optimize_size))
11199 {
11200 if (get_attr_mode (insn) == MODE_SI)
11201 return "sal{l}\t%0";
11202 else
11203 return "sal{b}\t%0";
11204 }
11205 else
11206 {
11207 if (get_attr_mode (insn) == MODE_SI)
11208 return "sal{l}\t{%2, %k0|%k0, %2}";
11209 else
11210 return "sal{b}\t{%2, %0|%0, %2}";
11211 }
11212 }
11213 }
11214 [(set (attr "type")
11215 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11216 (const_int 0))
11217 (match_operand 0 "register_operand" ""))
11218 (match_operand 2 "const1_operand" ""))
11219 (const_string "alu")
11220 ]
11221 (const_string "ishift")))
11222 (set_attr "mode" "QI,SI")])
11223
11224 ;; This pattern can't accept a variable shift count, since shifts by
11225 ;; zero don't affect the flags. We assume that shifts by constant
11226 ;; zero are optimized away.
11227 (define_insn "*ashlqi3_cmp"
11228 [(set (reg 17)
11229 (compare
11230 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11231 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11232 (const_int 0)))
11233 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11234 (ashift:QI (match_dup 1) (match_dup 2)))]
11235 "ix86_match_ccmode (insn, CCGOCmode)
11236 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11237 {
11238 switch (get_attr_type (insn))
11239 {
11240 case TYPE_ALU:
11241 if (operands[2] != const1_rtx)
11242 abort ();
11243 return "add{b}\t{%0, %0|%0, %0}";
11244
11245 default:
11246 if (REG_P (operands[2]))
11247 return "sal{b}\t{%b2, %0|%0, %b2}";
11248 else if (operands[2] == const1_rtx
11249 && (TARGET_SHIFT1 || optimize_size))
11250 return "sal{b}\t%0";
11251 else
11252 return "sal{b}\t{%2, %0|%0, %2}";
11253 }
11254 }
11255 [(set (attr "type")
11256 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11257 (const_int 0))
11258 (match_operand 0 "register_operand" ""))
11259 (match_operand 2 "const1_operand" ""))
11260 (const_string "alu")
11261 ]
11262 (const_string "ishift")))
11263 (set_attr "mode" "QI")])
11264
11265 ;; See comment above `ashldi3' about how this works.
11266
11267 (define_expand "ashrdi3"
11268 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11269 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11270 (match_operand:QI 2 "nonmemory_operand" "")))
11271 (clobber (reg:CC 17))])]
11272 ""
11273 {
11274 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11275 {
11276 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11277 DONE;
11278 }
11279 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11280 DONE;
11281 })
11282
11283 (define_insn "ashrdi3_63_rex64"
11284 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11285 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11286 (match_operand:DI 2 "const_int_operand" "i,i")))
11287 (clobber (reg:CC 17))]
11288 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11289 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11290 "@
11291 {cqto|cqo}
11292 sar{q}\t{%2, %0|%0, %2}"
11293 [(set_attr "type" "imovx,ishift")
11294 (set_attr "prefix_0f" "0,*")
11295 (set_attr "length_immediate" "0,*")
11296 (set_attr "modrm" "0,1")
11297 (set_attr "mode" "DI")])
11298
11299 (define_insn "*ashrdi3_1_one_bit_rex64"
11300 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11301 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11302 (match_operand:QI 2 "const1_operand" "")))
11303 (clobber (reg:CC 17))]
11304 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11305 && (TARGET_SHIFT1 || optimize_size)"
11306 "sar{q}\t%0"
11307 [(set_attr "type" "ishift")
11308 (set (attr "length")
11309 (if_then_else (match_operand:DI 0 "register_operand" "")
11310 (const_string "2")
11311 (const_string "*")))])
11312
11313 (define_insn "*ashrdi3_1_rex64"
11314 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11315 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11316 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11317 (clobber (reg:CC 17))]
11318 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11319 "@
11320 sar{q}\t{%2, %0|%0, %2}
11321 sar{q}\t{%b2, %0|%0, %b2}"
11322 [(set_attr "type" "ishift")
11323 (set_attr "mode" "DI")])
11324
11325 ;; This pattern can't accept a variable shift count, since shifts by
11326 ;; zero don't affect the flags. We assume that shifts by constant
11327 ;; zero are optimized away.
11328 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11329 [(set (reg 17)
11330 (compare
11331 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11332 (match_operand:QI 2 "const1_operand" ""))
11333 (const_int 0)))
11334 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11335 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11336 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11337 && (TARGET_SHIFT1 || optimize_size)
11338 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11339 "sar{q}\t%0"
11340 [(set_attr "type" "ishift")
11341 (set (attr "length")
11342 (if_then_else (match_operand:DI 0 "register_operand" "")
11343 (const_string "2")
11344 (const_string "*")))])
11345
11346 ;; This pattern can't accept a variable shift count, since shifts by
11347 ;; zero don't affect the flags. We assume that shifts by constant
11348 ;; zero are optimized away.
11349 (define_insn "*ashrdi3_cmp_rex64"
11350 [(set (reg 17)
11351 (compare
11352 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11353 (match_operand:QI 2 "const_int_operand" "n"))
11354 (const_int 0)))
11355 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11356 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11357 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11358 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11359 "sar{q}\t{%2, %0|%0, %2}"
11360 [(set_attr "type" "ishift")
11361 (set_attr "mode" "DI")])
11362
11363
11364 (define_insn "ashrdi3_1"
11365 [(set (match_operand:DI 0 "register_operand" "=r")
11366 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11367 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11368 (clobber (match_scratch:SI 3 "=&r"))
11369 (clobber (reg:CC 17))]
11370 "!TARGET_64BIT && TARGET_CMOVE"
11371 "#"
11372 [(set_attr "type" "multi")])
11373
11374 (define_insn "*ashrdi3_2"
11375 [(set (match_operand:DI 0 "register_operand" "=r")
11376 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11377 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11378 (clobber (reg:CC 17))]
11379 "!TARGET_64BIT"
11380 "#"
11381 [(set_attr "type" "multi")])
11382
11383 (define_split
11384 [(set (match_operand:DI 0 "register_operand" "")
11385 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11386 (match_operand:QI 2 "nonmemory_operand" "")))
11387 (clobber (match_scratch:SI 3 ""))
11388 (clobber (reg:CC 17))]
11389 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11390 [(const_int 0)]
11391 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11392
11393 (define_split
11394 [(set (match_operand:DI 0 "register_operand" "")
11395 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11396 (match_operand:QI 2 "nonmemory_operand" "")))
11397 (clobber (reg:CC 17))]
11398 "!TARGET_64BIT && reload_completed"
11399 [(const_int 0)]
11400 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11401
11402 (define_insn "x86_shrd_1"
11403 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11404 (ior:SI (ashiftrt:SI (match_dup 0)
11405 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11406 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11407 (minus:QI (const_int 32) (match_dup 2)))))
11408 (clobber (reg:CC 17))]
11409 ""
11410 "@
11411 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11412 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11413 [(set_attr "type" "ishift")
11414 (set_attr "prefix_0f" "1")
11415 (set_attr "pent_pair" "np")
11416 (set_attr "mode" "SI")])
11417
11418 (define_expand "x86_shift_adj_3"
11419 [(use (match_operand:SI 0 "register_operand" ""))
11420 (use (match_operand:SI 1 "register_operand" ""))
11421 (use (match_operand:QI 2 "register_operand" ""))]
11422 ""
11423 {
11424 rtx label = gen_label_rtx ();
11425 rtx tmp;
11426
11427 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11428
11429 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11430 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11431 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11432 gen_rtx_LABEL_REF (VOIDmode, label),
11433 pc_rtx);
11434 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11435 JUMP_LABEL (tmp) = label;
11436
11437 emit_move_insn (operands[0], operands[1]);
11438 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11439
11440 emit_label (label);
11441 LABEL_NUSES (label) = 1;
11442
11443 DONE;
11444 })
11445
11446 (define_insn "ashrsi3_31"
11447 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11448 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11449 (match_operand:SI 2 "const_int_operand" "i,i")))
11450 (clobber (reg:CC 17))]
11451 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11452 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11453 "@
11454 {cltd|cdq}
11455 sar{l}\t{%2, %0|%0, %2}"
11456 [(set_attr "type" "imovx,ishift")
11457 (set_attr "prefix_0f" "0,*")
11458 (set_attr "length_immediate" "0,*")
11459 (set_attr "modrm" "0,1")
11460 (set_attr "mode" "SI")])
11461
11462 (define_insn "*ashrsi3_31_zext"
11463 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11464 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11465 (match_operand:SI 2 "const_int_operand" "i,i"))))
11466 (clobber (reg:CC 17))]
11467 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11468 && INTVAL (operands[2]) == 31
11469 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11470 "@
11471 {cltd|cdq}
11472 sar{l}\t{%2, %k0|%k0, %2}"
11473 [(set_attr "type" "imovx,ishift")
11474 (set_attr "prefix_0f" "0,*")
11475 (set_attr "length_immediate" "0,*")
11476 (set_attr "modrm" "0,1")
11477 (set_attr "mode" "SI")])
11478
11479 (define_expand "ashrsi3"
11480 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11481 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11482 (match_operand:QI 2 "nonmemory_operand" "")))
11483 (clobber (reg:CC 17))]
11484 ""
11485 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11486
11487 (define_insn "*ashrsi3_1_one_bit"
11488 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11489 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11490 (match_operand:QI 2 "const1_operand" "")))
11491 (clobber (reg:CC 17))]
11492 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11493 && (TARGET_SHIFT1 || optimize_size)"
11494 "sar{l}\t%0"
11495 [(set_attr "type" "ishift")
11496 (set (attr "length")
11497 (if_then_else (match_operand:SI 0 "register_operand" "")
11498 (const_string "2")
11499 (const_string "*")))])
11500
11501 (define_insn "*ashrsi3_1_one_bit_zext"
11502 [(set (match_operand:DI 0 "register_operand" "=r")
11503 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11504 (match_operand:QI 2 "const1_operand" ""))))
11505 (clobber (reg:CC 17))]
11506 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11507 && (TARGET_SHIFT1 || optimize_size)"
11508 "sar{l}\t%k0"
11509 [(set_attr "type" "ishift")
11510 (set_attr "length" "2")])
11511
11512 (define_insn "*ashrsi3_1"
11513 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11514 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11515 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11516 (clobber (reg:CC 17))]
11517 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11518 "@
11519 sar{l}\t{%2, %0|%0, %2}
11520 sar{l}\t{%b2, %0|%0, %b2}"
11521 [(set_attr "type" "ishift")
11522 (set_attr "mode" "SI")])
11523
11524 (define_insn "*ashrsi3_1_zext"
11525 [(set (match_operand:DI 0 "register_operand" "=r,r")
11526 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11527 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11528 (clobber (reg:CC 17))]
11529 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11530 "@
11531 sar{l}\t{%2, %k0|%k0, %2}
11532 sar{l}\t{%b2, %k0|%k0, %b2}"
11533 [(set_attr "type" "ishift")
11534 (set_attr "mode" "SI")])
11535
11536 ;; This pattern can't accept a variable shift count, since shifts by
11537 ;; zero don't affect the flags. We assume that shifts by constant
11538 ;; zero are optimized away.
11539 (define_insn "*ashrsi3_one_bit_cmp"
11540 [(set (reg 17)
11541 (compare
11542 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11543 (match_operand:QI 2 "const1_operand" ""))
11544 (const_int 0)))
11545 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11546 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11547 "ix86_match_ccmode (insn, CCGOCmode)
11548 && (TARGET_SHIFT1 || optimize_size)
11549 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11550 "sar{l}\t%0"
11551 [(set_attr "type" "ishift")
11552 (set (attr "length")
11553 (if_then_else (match_operand:SI 0 "register_operand" "")
11554 (const_string "2")
11555 (const_string "*")))])
11556
11557 (define_insn "*ashrsi3_one_bit_cmp_zext"
11558 [(set (reg 17)
11559 (compare
11560 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11561 (match_operand:QI 2 "const1_operand" ""))
11562 (const_int 0)))
11563 (set (match_operand:DI 0 "register_operand" "=r")
11564 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11565 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11566 && (TARGET_SHIFT1 || optimize_size)
11567 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11568 "sar{l}\t%k0"
11569 [(set_attr "type" "ishift")
11570 (set_attr "length" "2")])
11571
11572 ;; This pattern can't accept a variable shift count, since shifts by
11573 ;; zero don't affect the flags. We assume that shifts by constant
11574 ;; zero are optimized away.
11575 (define_insn "*ashrsi3_cmp"
11576 [(set (reg 17)
11577 (compare
11578 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11579 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11580 (const_int 0)))
11581 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11582 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11583 "ix86_match_ccmode (insn, CCGOCmode)
11584 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11585 "sar{l}\t{%2, %0|%0, %2}"
11586 [(set_attr "type" "ishift")
11587 (set_attr "mode" "SI")])
11588
11589 (define_insn "*ashrsi3_cmp_zext"
11590 [(set (reg 17)
11591 (compare
11592 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11593 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11594 (const_int 0)))
11595 (set (match_operand:DI 0 "register_operand" "=r")
11596 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11597 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11598 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11599 "sar{l}\t{%2, %k0|%k0, %2}"
11600 [(set_attr "type" "ishift")
11601 (set_attr "mode" "SI")])
11602
11603 (define_expand "ashrhi3"
11604 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11605 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11606 (match_operand:QI 2 "nonmemory_operand" "")))
11607 (clobber (reg:CC 17))]
11608 "TARGET_HIMODE_MATH"
11609 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11610
11611 (define_insn "*ashrhi3_1_one_bit"
11612 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11613 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11614 (match_operand:QI 2 "const1_operand" "")))
11615 (clobber (reg:CC 17))]
11616 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11617 && (TARGET_SHIFT1 || optimize_size)"
11618 "sar{w}\t%0"
11619 [(set_attr "type" "ishift")
11620 (set (attr "length")
11621 (if_then_else (match_operand 0 "register_operand" "")
11622 (const_string "2")
11623 (const_string "*")))])
11624
11625 (define_insn "*ashrhi3_1"
11626 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11627 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11628 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11629 (clobber (reg:CC 17))]
11630 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11631 "@
11632 sar{w}\t{%2, %0|%0, %2}
11633 sar{w}\t{%b2, %0|%0, %b2}"
11634 [(set_attr "type" "ishift")
11635 (set_attr "mode" "HI")])
11636
11637 ;; This pattern can't accept a variable shift count, since shifts by
11638 ;; zero don't affect the flags. We assume that shifts by constant
11639 ;; zero are optimized away.
11640 (define_insn "*ashrhi3_one_bit_cmp"
11641 [(set (reg 17)
11642 (compare
11643 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11644 (match_operand:QI 2 "const1_operand" ""))
11645 (const_int 0)))
11646 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11647 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11648 "ix86_match_ccmode (insn, CCGOCmode)
11649 && (TARGET_SHIFT1 || optimize_size)
11650 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11651 "sar{w}\t%0"
11652 [(set_attr "type" "ishift")
11653 (set (attr "length")
11654 (if_then_else (match_operand 0 "register_operand" "")
11655 (const_string "2")
11656 (const_string "*")))])
11657
11658 ;; This pattern can't accept a variable shift count, since shifts by
11659 ;; zero don't affect the flags. We assume that shifts by constant
11660 ;; zero are optimized away.
11661 (define_insn "*ashrhi3_cmp"
11662 [(set (reg 17)
11663 (compare
11664 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11665 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11666 (const_int 0)))
11667 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11668 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11669 "ix86_match_ccmode (insn, CCGOCmode)
11670 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11671 "sar{w}\t{%2, %0|%0, %2}"
11672 [(set_attr "type" "ishift")
11673 (set_attr "mode" "HI")])
11674
11675 (define_expand "ashrqi3"
11676 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11677 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11678 (match_operand:QI 2 "nonmemory_operand" "")))
11679 (clobber (reg:CC 17))]
11680 "TARGET_QIMODE_MATH"
11681 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11682
11683 (define_insn "*ashrqi3_1_one_bit"
11684 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11685 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11686 (match_operand:QI 2 "const1_operand" "")))
11687 (clobber (reg:CC 17))]
11688 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11689 && (TARGET_SHIFT1 || optimize_size)"
11690 "sar{b}\t%0"
11691 [(set_attr "type" "ishift")
11692 (set (attr "length")
11693 (if_then_else (match_operand 0 "register_operand" "")
11694 (const_string "2")
11695 (const_string "*")))])
11696
11697 (define_insn "*ashrqi3_1_one_bit_slp"
11698 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11699 (ashiftrt:QI (match_dup 0)
11700 (match_operand:QI 1 "const1_operand" "")))
11701 (clobber (reg:CC 17))]
11702 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11703 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11704 && (TARGET_SHIFT1 || optimize_size)"
11705 "sar{b}\t%0"
11706 [(set_attr "type" "ishift1")
11707 (set (attr "length")
11708 (if_then_else (match_operand 0 "register_operand" "")
11709 (const_string "2")
11710 (const_string "*")))])
11711
11712 (define_insn "*ashrqi3_1"
11713 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11714 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11715 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11716 (clobber (reg:CC 17))]
11717 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11718 "@
11719 sar{b}\t{%2, %0|%0, %2}
11720 sar{b}\t{%b2, %0|%0, %b2}"
11721 [(set_attr "type" "ishift")
11722 (set_attr "mode" "QI")])
11723
11724 (define_insn "*ashrqi3_1_slp"
11725 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11726 (ashiftrt:QI (match_dup 0)
11727 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11728 (clobber (reg:CC 17))]
11729 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11730 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11731 "@
11732 sar{b}\t{%1, %0|%0, %1}
11733 sar{b}\t{%b1, %0|%0, %b1}"
11734 [(set_attr "type" "ishift1")
11735 (set_attr "mode" "QI")])
11736
11737 ;; This pattern can't accept a variable shift count, since shifts by
11738 ;; zero don't affect the flags. We assume that shifts by constant
11739 ;; zero are optimized away.
11740 (define_insn "*ashrqi3_one_bit_cmp"
11741 [(set (reg 17)
11742 (compare
11743 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11744 (match_operand:QI 2 "const1_operand" "I"))
11745 (const_int 0)))
11746 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11747 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11748 "ix86_match_ccmode (insn, CCGOCmode)
11749 && (TARGET_SHIFT1 || optimize_size)
11750 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11751 "sar{b}\t%0"
11752 [(set_attr "type" "ishift")
11753 (set (attr "length")
11754 (if_then_else (match_operand 0 "register_operand" "")
11755 (const_string "2")
11756 (const_string "*")))])
11757
11758 ;; This pattern can't accept a variable shift count, since shifts by
11759 ;; zero don't affect the flags. We assume that shifts by constant
11760 ;; zero are optimized away.
11761 (define_insn "*ashrqi3_cmp"
11762 [(set (reg 17)
11763 (compare
11764 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11765 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11766 (const_int 0)))
11767 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11768 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11769 "ix86_match_ccmode (insn, CCGOCmode)
11770 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11771 "sar{b}\t{%2, %0|%0, %2}"
11772 [(set_attr "type" "ishift")
11773 (set_attr "mode" "QI")])
11774 \f
11775 ;; Logical shift instructions
11776
11777 ;; See comment above `ashldi3' about how this works.
11778
11779 (define_expand "lshrdi3"
11780 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11781 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11782 (match_operand:QI 2 "nonmemory_operand" "")))
11783 (clobber (reg:CC 17))])]
11784 ""
11785 {
11786 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11787 {
11788 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11789 DONE;
11790 }
11791 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11792 DONE;
11793 })
11794
11795 (define_insn "*lshrdi3_1_one_bit_rex64"
11796 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11797 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11798 (match_operand:QI 2 "const1_operand" "")))
11799 (clobber (reg:CC 17))]
11800 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11801 && (TARGET_SHIFT1 || optimize_size)"
11802 "shr{q}\t%0"
11803 [(set_attr "type" "ishift")
11804 (set (attr "length")
11805 (if_then_else (match_operand:DI 0 "register_operand" "")
11806 (const_string "2")
11807 (const_string "*")))])
11808
11809 (define_insn "*lshrdi3_1_rex64"
11810 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11811 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11812 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11813 (clobber (reg:CC 17))]
11814 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11815 "@
11816 shr{q}\t{%2, %0|%0, %2}
11817 shr{q}\t{%b2, %0|%0, %b2}"
11818 [(set_attr "type" "ishift")
11819 (set_attr "mode" "DI")])
11820
11821 ;; This pattern can't accept a variable shift count, since shifts by
11822 ;; zero don't affect the flags. We assume that shifts by constant
11823 ;; zero are optimized away.
11824 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11825 [(set (reg 17)
11826 (compare
11827 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11828 (match_operand:QI 2 "const1_operand" ""))
11829 (const_int 0)))
11830 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11831 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11832 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11833 && (TARGET_SHIFT1 || optimize_size)
11834 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11835 "shr{q}\t%0"
11836 [(set_attr "type" "ishift")
11837 (set (attr "length")
11838 (if_then_else (match_operand:DI 0 "register_operand" "")
11839 (const_string "2")
11840 (const_string "*")))])
11841
11842 ;; This pattern can't accept a variable shift count, since shifts by
11843 ;; zero don't affect the flags. We assume that shifts by constant
11844 ;; zero are optimized away.
11845 (define_insn "*lshrdi3_cmp_rex64"
11846 [(set (reg 17)
11847 (compare
11848 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11849 (match_operand:QI 2 "const_int_operand" "e"))
11850 (const_int 0)))
11851 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11852 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11853 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11854 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11855 "shr{q}\t{%2, %0|%0, %2}"
11856 [(set_attr "type" "ishift")
11857 (set_attr "mode" "DI")])
11858
11859 (define_insn "lshrdi3_1"
11860 [(set (match_operand:DI 0 "register_operand" "=r")
11861 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11862 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11863 (clobber (match_scratch:SI 3 "=&r"))
11864 (clobber (reg:CC 17))]
11865 "!TARGET_64BIT && TARGET_CMOVE"
11866 "#"
11867 [(set_attr "type" "multi")])
11868
11869 (define_insn "*lshrdi3_2"
11870 [(set (match_operand:DI 0 "register_operand" "=r")
11871 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11872 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11873 (clobber (reg:CC 17))]
11874 "!TARGET_64BIT"
11875 "#"
11876 [(set_attr "type" "multi")])
11877
11878 (define_split
11879 [(set (match_operand:DI 0 "register_operand" "")
11880 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11881 (match_operand:QI 2 "nonmemory_operand" "")))
11882 (clobber (match_scratch:SI 3 ""))
11883 (clobber (reg:CC 17))]
11884 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11885 [(const_int 0)]
11886 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11887
11888 (define_split
11889 [(set (match_operand:DI 0 "register_operand" "")
11890 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11891 (match_operand:QI 2 "nonmemory_operand" "")))
11892 (clobber (reg:CC 17))]
11893 "!TARGET_64BIT && reload_completed"
11894 [(const_int 0)]
11895 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11896
11897 (define_expand "lshrsi3"
11898 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11899 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11900 (match_operand:QI 2 "nonmemory_operand" "")))
11901 (clobber (reg:CC 17))]
11902 ""
11903 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11904
11905 (define_insn "*lshrsi3_1_one_bit"
11906 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11907 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11908 (match_operand:QI 2 "const1_operand" "")))
11909 (clobber (reg:CC 17))]
11910 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11911 && (TARGET_SHIFT1 || optimize_size)"
11912 "shr{l}\t%0"
11913 [(set_attr "type" "ishift")
11914 (set (attr "length")
11915 (if_then_else (match_operand:SI 0 "register_operand" "")
11916 (const_string "2")
11917 (const_string "*")))])
11918
11919 (define_insn "*lshrsi3_1_one_bit_zext"
11920 [(set (match_operand:DI 0 "register_operand" "=r")
11921 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11922 (match_operand:QI 2 "const1_operand" "")))
11923 (clobber (reg:CC 17))]
11924 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11925 && (TARGET_SHIFT1 || optimize_size)"
11926 "shr{l}\t%k0"
11927 [(set_attr "type" "ishift")
11928 (set_attr "length" "2")])
11929
11930 (define_insn "*lshrsi3_1"
11931 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11932 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11933 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11934 (clobber (reg:CC 17))]
11935 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11936 "@
11937 shr{l}\t{%2, %0|%0, %2}
11938 shr{l}\t{%b2, %0|%0, %b2}"
11939 [(set_attr "type" "ishift")
11940 (set_attr "mode" "SI")])
11941
11942 (define_insn "*lshrsi3_1_zext"
11943 [(set (match_operand:DI 0 "register_operand" "=r,r")
11944 (zero_extend:DI
11945 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11946 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11947 (clobber (reg:CC 17))]
11948 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11949 "@
11950 shr{l}\t{%2, %k0|%k0, %2}
11951 shr{l}\t{%b2, %k0|%k0, %b2}"
11952 [(set_attr "type" "ishift")
11953 (set_attr "mode" "SI")])
11954
11955 ;; This pattern can't accept a variable shift count, since shifts by
11956 ;; zero don't affect the flags. We assume that shifts by constant
11957 ;; zero are optimized away.
11958 (define_insn "*lshrsi3_one_bit_cmp"
11959 [(set (reg 17)
11960 (compare
11961 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11962 (match_operand:QI 2 "const1_operand" ""))
11963 (const_int 0)))
11964 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11965 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11966 "ix86_match_ccmode (insn, CCGOCmode)
11967 && (TARGET_SHIFT1 || optimize_size)
11968 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11969 "shr{l}\t%0"
11970 [(set_attr "type" "ishift")
11971 (set (attr "length")
11972 (if_then_else (match_operand:SI 0 "register_operand" "")
11973 (const_string "2")
11974 (const_string "*")))])
11975
11976 (define_insn "*lshrsi3_cmp_one_bit_zext"
11977 [(set (reg 17)
11978 (compare
11979 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11980 (match_operand:QI 2 "const1_operand" ""))
11981 (const_int 0)))
11982 (set (match_operand:DI 0 "register_operand" "=r")
11983 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11984 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11985 && (TARGET_SHIFT1 || optimize_size)
11986 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11987 "shr{l}\t%k0"
11988 [(set_attr "type" "ishift")
11989 (set_attr "length" "2")])
11990
11991 ;; This pattern can't accept a variable shift count, since shifts by
11992 ;; zero don't affect the flags. We assume that shifts by constant
11993 ;; zero are optimized away.
11994 (define_insn "*lshrsi3_cmp"
11995 [(set (reg 17)
11996 (compare
11997 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11998 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11999 (const_int 0)))
12000 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12001 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12002 "ix86_match_ccmode (insn, CCGOCmode)
12003 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12004 "shr{l}\t{%2, %0|%0, %2}"
12005 [(set_attr "type" "ishift")
12006 (set_attr "mode" "SI")])
12007
12008 (define_insn "*lshrsi3_cmp_zext"
12009 [(set (reg 17)
12010 (compare
12011 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12012 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12013 (const_int 0)))
12014 (set (match_operand:DI 0 "register_operand" "=r")
12015 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12016 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12017 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12018 "shr{l}\t{%2, %k0|%k0, %2}"
12019 [(set_attr "type" "ishift")
12020 (set_attr "mode" "SI")])
12021
12022 (define_expand "lshrhi3"
12023 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12024 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12025 (match_operand:QI 2 "nonmemory_operand" "")))
12026 (clobber (reg:CC 17))]
12027 "TARGET_HIMODE_MATH"
12028 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12029
12030 (define_insn "*lshrhi3_1_one_bit"
12031 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12032 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12033 (match_operand:QI 2 "const1_operand" "")))
12034 (clobber (reg:CC 17))]
12035 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12036 && (TARGET_SHIFT1 || optimize_size)"
12037 "shr{w}\t%0"
12038 [(set_attr "type" "ishift")
12039 (set (attr "length")
12040 (if_then_else (match_operand 0 "register_operand" "")
12041 (const_string "2")
12042 (const_string "*")))])
12043
12044 (define_insn "*lshrhi3_1"
12045 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12046 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12047 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12048 (clobber (reg:CC 17))]
12049 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12050 "@
12051 shr{w}\t{%2, %0|%0, %2}
12052 shr{w}\t{%b2, %0|%0, %b2}"
12053 [(set_attr "type" "ishift")
12054 (set_attr "mode" "HI")])
12055
12056 ;; This pattern can't accept a variable shift count, since shifts by
12057 ;; zero don't affect the flags. We assume that shifts by constant
12058 ;; zero are optimized away.
12059 (define_insn "*lshrhi3_one_bit_cmp"
12060 [(set (reg 17)
12061 (compare
12062 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12063 (match_operand:QI 2 "const1_operand" ""))
12064 (const_int 0)))
12065 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12066 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12067 "ix86_match_ccmode (insn, CCGOCmode)
12068 && (TARGET_SHIFT1 || optimize_size)
12069 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12070 "shr{w}\t%0"
12071 [(set_attr "type" "ishift")
12072 (set (attr "length")
12073 (if_then_else (match_operand:SI 0 "register_operand" "")
12074 (const_string "2")
12075 (const_string "*")))])
12076
12077 ;; This pattern can't accept a variable shift count, since shifts by
12078 ;; zero don't affect the flags. We assume that shifts by constant
12079 ;; zero are optimized away.
12080 (define_insn "*lshrhi3_cmp"
12081 [(set (reg 17)
12082 (compare
12083 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12084 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12085 (const_int 0)))
12086 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12087 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12088 "ix86_match_ccmode (insn, CCGOCmode)
12089 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12090 "shr{w}\t{%2, %0|%0, %2}"
12091 [(set_attr "type" "ishift")
12092 (set_attr "mode" "HI")])
12093
12094 (define_expand "lshrqi3"
12095 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12096 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12097 (match_operand:QI 2 "nonmemory_operand" "")))
12098 (clobber (reg:CC 17))]
12099 "TARGET_QIMODE_MATH"
12100 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12101
12102 (define_insn "*lshrqi3_1_one_bit"
12103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12104 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12105 (match_operand:QI 2 "const1_operand" "")))
12106 (clobber (reg:CC 17))]
12107 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12108 && (TARGET_SHIFT1 || optimize_size)"
12109 "shr{b}\t%0"
12110 [(set_attr "type" "ishift")
12111 (set (attr "length")
12112 (if_then_else (match_operand 0 "register_operand" "")
12113 (const_string "2")
12114 (const_string "*")))])
12115
12116 (define_insn "*lshrqi3_1_one_bit_slp"
12117 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12118 (lshiftrt:QI (match_dup 0)
12119 (match_operand:QI 1 "const1_operand" "")))
12120 (clobber (reg:CC 17))]
12121 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12122 && (TARGET_SHIFT1 || optimize_size)"
12123 "shr{b}\t%0"
12124 [(set_attr "type" "ishift1")
12125 (set (attr "length")
12126 (if_then_else (match_operand 0 "register_operand" "")
12127 (const_string "2")
12128 (const_string "*")))])
12129
12130 (define_insn "*lshrqi3_1"
12131 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12132 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12133 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12134 (clobber (reg:CC 17))]
12135 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12136 "@
12137 shr{b}\t{%2, %0|%0, %2}
12138 shr{b}\t{%b2, %0|%0, %b2}"
12139 [(set_attr "type" "ishift")
12140 (set_attr "mode" "QI")])
12141
12142 (define_insn "*lshrqi3_1_slp"
12143 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12144 (lshiftrt:QI (match_dup 0)
12145 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12146 (clobber (reg:CC 17))]
12147 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12148 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12149 "@
12150 shr{b}\t{%1, %0|%0, %1}
12151 shr{b}\t{%b1, %0|%0, %b1}"
12152 [(set_attr "type" "ishift1")
12153 (set_attr "mode" "QI")])
12154
12155 ;; This pattern can't accept a variable shift count, since shifts by
12156 ;; zero don't affect the flags. We assume that shifts by constant
12157 ;; zero are optimized away.
12158 (define_insn "*lshrqi2_one_bit_cmp"
12159 [(set (reg 17)
12160 (compare
12161 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12162 (match_operand:QI 2 "const1_operand" ""))
12163 (const_int 0)))
12164 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12165 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12166 "ix86_match_ccmode (insn, CCGOCmode)
12167 && (TARGET_SHIFT1 || optimize_size)
12168 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12169 "shr{b}\t%0"
12170 [(set_attr "type" "ishift")
12171 (set (attr "length")
12172 (if_then_else (match_operand:SI 0 "register_operand" "")
12173 (const_string "2")
12174 (const_string "*")))])
12175
12176 ;; This pattern can't accept a variable shift count, since shifts by
12177 ;; zero don't affect the flags. We assume that shifts by constant
12178 ;; zero are optimized away.
12179 (define_insn "*lshrqi2_cmp"
12180 [(set (reg 17)
12181 (compare
12182 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12183 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12184 (const_int 0)))
12185 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12186 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12187 "ix86_match_ccmode (insn, CCGOCmode)
12188 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12189 "shr{b}\t{%2, %0|%0, %2}"
12190 [(set_attr "type" "ishift")
12191 (set_attr "mode" "QI")])
12192 \f
12193 ;; Rotate instructions
12194
12195 (define_expand "rotldi3"
12196 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12197 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12198 (match_operand:QI 2 "nonmemory_operand" "")))
12199 (clobber (reg:CC 17))]
12200 "TARGET_64BIT"
12201 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12202
12203 (define_insn "*rotlsi3_1_one_bit_rex64"
12204 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12205 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12206 (match_operand:QI 2 "const1_operand" "")))
12207 (clobber (reg:CC 17))]
12208 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12209 && (TARGET_SHIFT1 || optimize_size)"
12210 "rol{q}\t%0"
12211 [(set_attr "type" "rotate")
12212 (set (attr "length")
12213 (if_then_else (match_operand:DI 0 "register_operand" "")
12214 (const_string "2")
12215 (const_string "*")))])
12216
12217 (define_insn "*rotldi3_1_rex64"
12218 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12219 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12220 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12221 (clobber (reg:CC 17))]
12222 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12223 "@
12224 rol{q}\t{%2, %0|%0, %2}
12225 rol{q}\t{%b2, %0|%0, %b2}"
12226 [(set_attr "type" "rotate")
12227 (set_attr "mode" "DI")])
12228
12229 (define_expand "rotlsi3"
12230 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12231 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12232 (match_operand:QI 2 "nonmemory_operand" "")))
12233 (clobber (reg:CC 17))]
12234 ""
12235 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12236
12237 (define_insn "*rotlsi3_1_one_bit"
12238 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12239 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const1_operand" "")))
12241 (clobber (reg:CC 17))]
12242 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12243 && (TARGET_SHIFT1 || optimize_size)"
12244 "rol{l}\t%0"
12245 [(set_attr "type" "rotate")
12246 (set (attr "length")
12247 (if_then_else (match_operand:SI 0 "register_operand" "")
12248 (const_string "2")
12249 (const_string "*")))])
12250
12251 (define_insn "*rotlsi3_1_one_bit_zext"
12252 [(set (match_operand:DI 0 "register_operand" "=r")
12253 (zero_extend:DI
12254 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12255 (match_operand:QI 2 "const1_operand" ""))))
12256 (clobber (reg:CC 17))]
12257 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12258 && (TARGET_SHIFT1 || optimize_size)"
12259 "rol{l}\t%k0"
12260 [(set_attr "type" "rotate")
12261 (set_attr "length" "2")])
12262
12263 (define_insn "*rotlsi3_1"
12264 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12265 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12266 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12267 (clobber (reg:CC 17))]
12268 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12269 "@
12270 rol{l}\t{%2, %0|%0, %2}
12271 rol{l}\t{%b2, %0|%0, %b2}"
12272 [(set_attr "type" "rotate")
12273 (set_attr "mode" "SI")])
12274
12275 (define_insn "*rotlsi3_1_zext"
12276 [(set (match_operand:DI 0 "register_operand" "=r,r")
12277 (zero_extend:DI
12278 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12279 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12280 (clobber (reg:CC 17))]
12281 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12282 "@
12283 rol{l}\t{%2, %k0|%k0, %2}
12284 rol{l}\t{%b2, %k0|%k0, %b2}"
12285 [(set_attr "type" "rotate")
12286 (set_attr "mode" "SI")])
12287
12288 (define_expand "rotlhi3"
12289 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12290 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12291 (match_operand:QI 2 "nonmemory_operand" "")))
12292 (clobber (reg:CC 17))]
12293 "TARGET_HIMODE_MATH"
12294 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12295
12296 (define_insn "*rotlhi3_1_one_bit"
12297 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12298 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12299 (match_operand:QI 2 "const1_operand" "")))
12300 (clobber (reg:CC 17))]
12301 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12302 && (TARGET_SHIFT1 || optimize_size)"
12303 "rol{w}\t%0"
12304 [(set_attr "type" "rotate")
12305 (set (attr "length")
12306 (if_then_else (match_operand 0 "register_operand" "")
12307 (const_string "2")
12308 (const_string "*")))])
12309
12310 (define_insn "*rotlhi3_1"
12311 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12312 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12313 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12314 (clobber (reg:CC 17))]
12315 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12316 "@
12317 rol{w}\t{%2, %0|%0, %2}
12318 rol{w}\t{%b2, %0|%0, %b2}"
12319 [(set_attr "type" "rotate")
12320 (set_attr "mode" "HI")])
12321
12322 (define_expand "rotlqi3"
12323 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12324 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12325 (match_operand:QI 2 "nonmemory_operand" "")))
12326 (clobber (reg:CC 17))]
12327 "TARGET_QIMODE_MATH"
12328 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12329
12330 (define_insn "*rotlqi3_1_one_bit_slp"
12331 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12332 (rotate:QI (match_dup 0)
12333 (match_operand:QI 1 "const1_operand" "")))
12334 (clobber (reg:CC 17))]
12335 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12336 && (TARGET_SHIFT1 || optimize_size)"
12337 "rol{b}\t%0"
12338 [(set_attr "type" "rotate1")
12339 (set (attr "length")
12340 (if_then_else (match_operand 0 "register_operand" "")
12341 (const_string "2")
12342 (const_string "*")))])
12343
12344 (define_insn "*rotlqi3_1_one_bit"
12345 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12346 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12347 (match_operand:QI 2 "const1_operand" "")))
12348 (clobber (reg:CC 17))]
12349 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12350 && (TARGET_SHIFT1 || optimize_size)"
12351 "rol{b}\t%0"
12352 [(set_attr "type" "rotate")
12353 (set (attr "length")
12354 (if_then_else (match_operand 0 "register_operand" "")
12355 (const_string "2")
12356 (const_string "*")))])
12357
12358 (define_insn "*rotlqi3_1_slp"
12359 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12360 (rotate:QI (match_dup 0)
12361 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12362 (clobber (reg:CC 17))]
12363 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12364 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12365 "@
12366 rol{b}\t{%1, %0|%0, %1}
12367 rol{b}\t{%b1, %0|%0, %b1}"
12368 [(set_attr "type" "rotate1")
12369 (set_attr "mode" "QI")])
12370
12371 (define_insn "*rotlqi3_1"
12372 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12373 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12374 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12375 (clobber (reg:CC 17))]
12376 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12377 "@
12378 rol{b}\t{%2, %0|%0, %2}
12379 rol{b}\t{%b2, %0|%0, %b2}"
12380 [(set_attr "type" "rotate")
12381 (set_attr "mode" "QI")])
12382
12383 (define_expand "rotrdi3"
12384 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12385 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12386 (match_operand:QI 2 "nonmemory_operand" "")))
12387 (clobber (reg:CC 17))]
12388 "TARGET_64BIT"
12389 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12390
12391 (define_insn "*rotrdi3_1_one_bit_rex64"
12392 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12393 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12394 (match_operand:QI 2 "const1_operand" "")))
12395 (clobber (reg:CC 17))]
12396 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12397 && (TARGET_SHIFT1 || optimize_size)"
12398 "ror{q}\t%0"
12399 [(set_attr "type" "rotate")
12400 (set (attr "length")
12401 (if_then_else (match_operand:DI 0 "register_operand" "")
12402 (const_string "2")
12403 (const_string "*")))])
12404
12405 (define_insn "*rotrdi3_1_rex64"
12406 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12407 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12408 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12409 (clobber (reg:CC 17))]
12410 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12411 "@
12412 ror{q}\t{%2, %0|%0, %2}
12413 ror{q}\t{%b2, %0|%0, %b2}"
12414 [(set_attr "type" "rotate")
12415 (set_attr "mode" "DI")])
12416
12417 (define_expand "rotrsi3"
12418 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12419 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12420 (match_operand:QI 2 "nonmemory_operand" "")))
12421 (clobber (reg:CC 17))]
12422 ""
12423 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12424
12425 (define_insn "*rotrsi3_1_one_bit"
12426 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12427 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12428 (match_operand:QI 2 "const1_operand" "")))
12429 (clobber (reg:CC 17))]
12430 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12431 && (TARGET_SHIFT1 || optimize_size)"
12432 "ror{l}\t%0"
12433 [(set_attr "type" "rotate")
12434 (set (attr "length")
12435 (if_then_else (match_operand:SI 0 "register_operand" "")
12436 (const_string "2")
12437 (const_string "*")))])
12438
12439 (define_insn "*rotrsi3_1_one_bit_zext"
12440 [(set (match_operand:DI 0 "register_operand" "=r")
12441 (zero_extend:DI
12442 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12443 (match_operand:QI 2 "const1_operand" ""))))
12444 (clobber (reg:CC 17))]
12445 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12446 && (TARGET_SHIFT1 || optimize_size)"
12447 "ror{l}\t%k0"
12448 [(set_attr "type" "rotate")
12449 (set (attr "length")
12450 (if_then_else (match_operand:SI 0 "register_operand" "")
12451 (const_string "2")
12452 (const_string "*")))])
12453
12454 (define_insn "*rotrsi3_1"
12455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12456 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12457 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12458 (clobber (reg:CC 17))]
12459 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12460 "@
12461 ror{l}\t{%2, %0|%0, %2}
12462 ror{l}\t{%b2, %0|%0, %b2}"
12463 [(set_attr "type" "rotate")
12464 (set_attr "mode" "SI")])
12465
12466 (define_insn "*rotrsi3_1_zext"
12467 [(set (match_operand:DI 0 "register_operand" "=r,r")
12468 (zero_extend:DI
12469 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12470 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12471 (clobber (reg:CC 17))]
12472 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12473 "@
12474 ror{l}\t{%2, %k0|%k0, %2}
12475 ror{l}\t{%b2, %k0|%k0, %b2}"
12476 [(set_attr "type" "rotate")
12477 (set_attr "mode" "SI")])
12478
12479 (define_expand "rotrhi3"
12480 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12481 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12482 (match_operand:QI 2 "nonmemory_operand" "")))
12483 (clobber (reg:CC 17))]
12484 "TARGET_HIMODE_MATH"
12485 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12486
12487 (define_insn "*rotrhi3_one_bit"
12488 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12489 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12490 (match_operand:QI 2 "const1_operand" "")))
12491 (clobber (reg:CC 17))]
12492 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12493 && (TARGET_SHIFT1 || optimize_size)"
12494 "ror{w}\t%0"
12495 [(set_attr "type" "rotate")
12496 (set (attr "length")
12497 (if_then_else (match_operand 0 "register_operand" "")
12498 (const_string "2")
12499 (const_string "*")))])
12500
12501 (define_insn "*rotrhi3"
12502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12503 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12504 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12505 (clobber (reg:CC 17))]
12506 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12507 "@
12508 ror{w}\t{%2, %0|%0, %2}
12509 ror{w}\t{%b2, %0|%0, %b2}"
12510 [(set_attr "type" "rotate")
12511 (set_attr "mode" "HI")])
12512
12513 (define_expand "rotrqi3"
12514 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12515 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12516 (match_operand:QI 2 "nonmemory_operand" "")))
12517 (clobber (reg:CC 17))]
12518 "TARGET_QIMODE_MATH"
12519 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12520
12521 (define_insn "*rotrqi3_1_one_bit"
12522 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12523 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12524 (match_operand:QI 2 "const1_operand" "")))
12525 (clobber (reg:CC 17))]
12526 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12527 && (TARGET_SHIFT1 || optimize_size)"
12528 "ror{b}\t%0"
12529 [(set_attr "type" "rotate")
12530 (set (attr "length")
12531 (if_then_else (match_operand 0 "register_operand" "")
12532 (const_string "2")
12533 (const_string "*")))])
12534
12535 (define_insn "*rotrqi3_1_one_bit_slp"
12536 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12537 (rotatert:QI (match_dup 0)
12538 (match_operand:QI 1 "const1_operand" "")))
12539 (clobber (reg:CC 17))]
12540 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12541 && (TARGET_SHIFT1 || optimize_size)"
12542 "ror{b}\t%0"
12543 [(set_attr "type" "rotate1")
12544 (set (attr "length")
12545 (if_then_else (match_operand 0 "register_operand" "")
12546 (const_string "2")
12547 (const_string "*")))])
12548
12549 (define_insn "*rotrqi3_1"
12550 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12551 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12552 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12553 (clobber (reg:CC 17))]
12554 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12555 "@
12556 ror{b}\t{%2, %0|%0, %2}
12557 ror{b}\t{%b2, %0|%0, %b2}"
12558 [(set_attr "type" "rotate")
12559 (set_attr "mode" "QI")])
12560
12561 (define_insn "*rotrqi3_1_slp"
12562 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12563 (rotatert:QI (match_dup 0)
12564 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12565 (clobber (reg:CC 17))]
12566 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12567 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12568 "@
12569 ror{b}\t{%1, %0|%0, %1}
12570 ror{b}\t{%b1, %0|%0, %b1}"
12571 [(set_attr "type" "rotate1")
12572 (set_attr "mode" "QI")])
12573 \f
12574 ;; Bit set / bit test instructions
12575
12576 (define_expand "extv"
12577 [(set (match_operand:SI 0 "register_operand" "")
12578 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12579 (match_operand:SI 2 "immediate_operand" "")
12580 (match_operand:SI 3 "immediate_operand" "")))]
12581 ""
12582 {
12583 /* Handle extractions from %ah et al. */
12584 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12585 FAIL;
12586
12587 /* From mips.md: extract_bit_field doesn't verify that our source
12588 matches the predicate, so check it again here. */
12589 if (! register_operand (operands[1], VOIDmode))
12590 FAIL;
12591 })
12592
12593 (define_expand "extzv"
12594 [(set (match_operand:SI 0 "register_operand" "")
12595 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12596 (match_operand:SI 2 "immediate_operand" "")
12597 (match_operand:SI 3 "immediate_operand" "")))]
12598 ""
12599 {
12600 /* Handle extractions from %ah et al. */
12601 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12602 FAIL;
12603
12604 /* From mips.md: extract_bit_field doesn't verify that our source
12605 matches the predicate, so check it again here. */
12606 if (! register_operand (operands[1], VOIDmode))
12607 FAIL;
12608 })
12609
12610 (define_expand "insv"
12611 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12612 (match_operand:SI 1 "immediate_operand" "")
12613 (match_operand:SI 2 "immediate_operand" ""))
12614 (match_operand:SI 3 "register_operand" ""))]
12615 ""
12616 {
12617 /* Handle extractions from %ah et al. */
12618 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12619 FAIL;
12620
12621 /* From mips.md: insert_bit_field doesn't verify that our source
12622 matches the predicate, so check it again here. */
12623 if (! register_operand (operands[0], VOIDmode))
12624 FAIL;
12625 })
12626
12627 ;; %%% bts, btr, btc, bt.
12628 \f
12629 ;; Store-flag instructions.
12630
12631 ;; For all sCOND expanders, also expand the compare or test insn that
12632 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12633
12634 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12635 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12636 ;; way, which can later delete the movzx if only QImode is needed.
12637
12638 (define_expand "seq"
12639 [(set (match_operand:QI 0 "register_operand" "")
12640 (eq:QI (reg:CC 17) (const_int 0)))]
12641 ""
12642 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12643
12644 (define_expand "sne"
12645 [(set (match_operand:QI 0 "register_operand" "")
12646 (ne:QI (reg:CC 17) (const_int 0)))]
12647 ""
12648 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12649
12650 (define_expand "sgt"
12651 [(set (match_operand:QI 0 "register_operand" "")
12652 (gt:QI (reg:CC 17) (const_int 0)))]
12653 ""
12654 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12655
12656 (define_expand "sgtu"
12657 [(set (match_operand:QI 0 "register_operand" "")
12658 (gtu:QI (reg:CC 17) (const_int 0)))]
12659 ""
12660 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12661
12662 (define_expand "slt"
12663 [(set (match_operand:QI 0 "register_operand" "")
12664 (lt:QI (reg:CC 17) (const_int 0)))]
12665 ""
12666 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12667
12668 (define_expand "sltu"
12669 [(set (match_operand:QI 0 "register_operand" "")
12670 (ltu:QI (reg:CC 17) (const_int 0)))]
12671 ""
12672 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12673
12674 (define_expand "sge"
12675 [(set (match_operand:QI 0 "register_operand" "")
12676 (ge:QI (reg:CC 17) (const_int 0)))]
12677 ""
12678 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12679
12680 (define_expand "sgeu"
12681 [(set (match_operand:QI 0 "register_operand" "")
12682 (geu:QI (reg:CC 17) (const_int 0)))]
12683 ""
12684 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12685
12686 (define_expand "sle"
12687 [(set (match_operand:QI 0 "register_operand" "")
12688 (le:QI (reg:CC 17) (const_int 0)))]
12689 ""
12690 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12691
12692 (define_expand "sleu"
12693 [(set (match_operand:QI 0 "register_operand" "")
12694 (leu:QI (reg:CC 17) (const_int 0)))]
12695 ""
12696 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12697
12698 (define_expand "sunordered"
12699 [(set (match_operand:QI 0 "register_operand" "")
12700 (unordered:QI (reg:CC 17) (const_int 0)))]
12701 "TARGET_80387 || TARGET_SSE"
12702 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12703
12704 (define_expand "sordered"
12705 [(set (match_operand:QI 0 "register_operand" "")
12706 (ordered:QI (reg:CC 17) (const_int 0)))]
12707 "TARGET_80387"
12708 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12709
12710 (define_expand "suneq"
12711 [(set (match_operand:QI 0 "register_operand" "")
12712 (uneq:QI (reg:CC 17) (const_int 0)))]
12713 "TARGET_80387 || TARGET_SSE"
12714 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "sunge"
12717 [(set (match_operand:QI 0 "register_operand" "")
12718 (unge:QI (reg:CC 17) (const_int 0)))]
12719 "TARGET_80387 || TARGET_SSE"
12720 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sungt"
12723 [(set (match_operand:QI 0 "register_operand" "")
12724 (ungt:QI (reg:CC 17) (const_int 0)))]
12725 "TARGET_80387 || TARGET_SSE"
12726 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sunle"
12729 [(set (match_operand:QI 0 "register_operand" "")
12730 (unle:QI (reg:CC 17) (const_int 0)))]
12731 "TARGET_80387 || TARGET_SSE"
12732 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "sunlt"
12735 [(set (match_operand:QI 0 "register_operand" "")
12736 (unlt:QI (reg:CC 17) (const_int 0)))]
12737 "TARGET_80387 || TARGET_SSE"
12738 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sltgt"
12741 [(set (match_operand:QI 0 "register_operand" "")
12742 (ltgt:QI (reg:CC 17) (const_int 0)))]
12743 "TARGET_80387 || TARGET_SSE"
12744 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12745
12746 (define_insn "*setcc_1"
12747 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12748 (match_operator:QI 1 "ix86_comparison_operator"
12749 [(reg 17) (const_int 0)]))]
12750 ""
12751 "set%C1\t%0"
12752 [(set_attr "type" "setcc")
12753 (set_attr "mode" "QI")])
12754
12755 (define_insn "setcc_2"
12756 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12757 (match_operator:QI 1 "ix86_comparison_operator"
12758 [(reg 17) (const_int 0)]))]
12759 ""
12760 "set%C1\t%0"
12761 [(set_attr "type" "setcc")
12762 (set_attr "mode" "QI")])
12763
12764 ;; In general it is not safe to assume too much about CCmode registers,
12765 ;; so simplify-rtx stops when it sees a second one. Under certain
12766 ;; conditions this is safe on x86, so help combine not create
12767 ;;
12768 ;; seta %al
12769 ;; testb %al, %al
12770 ;; sete %al
12771
12772 (define_split
12773 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12774 (ne:QI (match_operator 1 "ix86_comparison_operator"
12775 [(reg 17) (const_int 0)])
12776 (const_int 0)))]
12777 ""
12778 [(set (match_dup 0) (match_dup 1))]
12779 {
12780 PUT_MODE (operands[1], QImode);
12781 })
12782
12783 (define_split
12784 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12785 (ne:QI (match_operator 1 "ix86_comparison_operator"
12786 [(reg 17) (const_int 0)])
12787 (const_int 0)))]
12788 ""
12789 [(set (match_dup 0) (match_dup 1))]
12790 {
12791 PUT_MODE (operands[1], QImode);
12792 })
12793
12794 (define_split
12795 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12796 (eq:QI (match_operator 1 "ix86_comparison_operator"
12797 [(reg 17) (const_int 0)])
12798 (const_int 0)))]
12799 ""
12800 [(set (match_dup 0) (match_dup 1))]
12801 {
12802 rtx new_op1 = copy_rtx (operands[1]);
12803 operands[1] = new_op1;
12804 PUT_MODE (new_op1, QImode);
12805 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12806 GET_MODE (XEXP (new_op1, 0))));
12807
12808 /* Make sure that (a) the CCmode we have for the flags is strong
12809 enough for the reversed compare or (b) we have a valid FP compare. */
12810 if (! ix86_comparison_operator (new_op1, VOIDmode))
12811 FAIL;
12812 })
12813
12814 (define_split
12815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12816 (eq:QI (match_operator 1 "ix86_comparison_operator"
12817 [(reg 17) (const_int 0)])
12818 (const_int 0)))]
12819 ""
12820 [(set (match_dup 0) (match_dup 1))]
12821 {
12822 rtx new_op1 = copy_rtx (operands[1]);
12823 operands[1] = new_op1;
12824 PUT_MODE (new_op1, QImode);
12825 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12826 GET_MODE (XEXP (new_op1, 0))));
12827
12828 /* Make sure that (a) the CCmode we have for the flags is strong
12829 enough for the reversed compare or (b) we have a valid FP compare. */
12830 if (! ix86_comparison_operator (new_op1, VOIDmode))
12831 FAIL;
12832 })
12833
12834 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12835 ;; subsequent logical operations are used to imitate conditional moves.
12836 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12837 ;; it directly. Further holding this value in pseudo register might bring
12838 ;; problem in implicit normalization in spill code.
12839 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12840 ;; instructions after reload by splitting the conditional move patterns.
12841
12842 (define_insn "*sse_setccsf"
12843 [(set (match_operand:SF 0 "register_operand" "=x")
12844 (match_operator:SF 1 "sse_comparison_operator"
12845 [(match_operand:SF 2 "register_operand" "0")
12846 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12847 "TARGET_SSE && reload_completed"
12848 "cmp%D1ss\t{%3, %0|%0, %3}"
12849 [(set_attr "type" "ssecmp")
12850 (set_attr "mode" "SF")])
12851
12852 (define_insn "*sse_setccdf"
12853 [(set (match_operand:DF 0 "register_operand" "=Y")
12854 (match_operator:DF 1 "sse_comparison_operator"
12855 [(match_operand:DF 2 "register_operand" "0")
12856 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12857 "TARGET_SSE2 && reload_completed"
12858 "cmp%D1sd\t{%3, %0|%0, %3}"
12859 [(set_attr "type" "ssecmp")
12860 (set_attr "mode" "DF")])
12861 \f
12862 ;; Basic conditional jump instructions.
12863 ;; We ignore the overflow flag for signed branch instructions.
12864
12865 ;; For all bCOND expanders, also expand the compare or test insn that
12866 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12867
12868 (define_expand "beq"
12869 [(set (pc)
12870 (if_then_else (match_dup 1)
12871 (label_ref (match_operand 0 "" ""))
12872 (pc)))]
12873 ""
12874 "ix86_expand_branch (EQ, operands[0]); DONE;")
12875
12876 (define_expand "bne"
12877 [(set (pc)
12878 (if_then_else (match_dup 1)
12879 (label_ref (match_operand 0 "" ""))
12880 (pc)))]
12881 ""
12882 "ix86_expand_branch (NE, operands[0]); DONE;")
12883
12884 (define_expand "bgt"
12885 [(set (pc)
12886 (if_then_else (match_dup 1)
12887 (label_ref (match_operand 0 "" ""))
12888 (pc)))]
12889 ""
12890 "ix86_expand_branch (GT, operands[0]); DONE;")
12891
12892 (define_expand "bgtu"
12893 [(set (pc)
12894 (if_then_else (match_dup 1)
12895 (label_ref (match_operand 0 "" ""))
12896 (pc)))]
12897 ""
12898 "ix86_expand_branch (GTU, operands[0]); DONE;")
12899
12900 (define_expand "blt"
12901 [(set (pc)
12902 (if_then_else (match_dup 1)
12903 (label_ref (match_operand 0 "" ""))
12904 (pc)))]
12905 ""
12906 "ix86_expand_branch (LT, operands[0]); DONE;")
12907
12908 (define_expand "bltu"
12909 [(set (pc)
12910 (if_then_else (match_dup 1)
12911 (label_ref (match_operand 0 "" ""))
12912 (pc)))]
12913 ""
12914 "ix86_expand_branch (LTU, operands[0]); DONE;")
12915
12916 (define_expand "bge"
12917 [(set (pc)
12918 (if_then_else (match_dup 1)
12919 (label_ref (match_operand 0 "" ""))
12920 (pc)))]
12921 ""
12922 "ix86_expand_branch (GE, operands[0]); DONE;")
12923
12924 (define_expand "bgeu"
12925 [(set (pc)
12926 (if_then_else (match_dup 1)
12927 (label_ref (match_operand 0 "" ""))
12928 (pc)))]
12929 ""
12930 "ix86_expand_branch (GEU, operands[0]); DONE;")
12931
12932 (define_expand "ble"
12933 [(set (pc)
12934 (if_then_else (match_dup 1)
12935 (label_ref (match_operand 0 "" ""))
12936 (pc)))]
12937 ""
12938 "ix86_expand_branch (LE, operands[0]); DONE;")
12939
12940 (define_expand "bleu"
12941 [(set (pc)
12942 (if_then_else (match_dup 1)
12943 (label_ref (match_operand 0 "" ""))
12944 (pc)))]
12945 ""
12946 "ix86_expand_branch (LEU, operands[0]); DONE;")
12947
12948 (define_expand "bunordered"
12949 [(set (pc)
12950 (if_then_else (match_dup 1)
12951 (label_ref (match_operand 0 "" ""))
12952 (pc)))]
12953 "TARGET_80387 || TARGET_SSE"
12954 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12955
12956 (define_expand "bordered"
12957 [(set (pc)
12958 (if_then_else (match_dup 1)
12959 (label_ref (match_operand 0 "" ""))
12960 (pc)))]
12961 "TARGET_80387 || TARGET_SSE"
12962 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12963
12964 (define_expand "buneq"
12965 [(set (pc)
12966 (if_then_else (match_dup 1)
12967 (label_ref (match_operand 0 "" ""))
12968 (pc)))]
12969 "TARGET_80387 || TARGET_SSE"
12970 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12971
12972 (define_expand "bunge"
12973 [(set (pc)
12974 (if_then_else (match_dup 1)
12975 (label_ref (match_operand 0 "" ""))
12976 (pc)))]
12977 "TARGET_80387 || TARGET_SSE"
12978 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12979
12980 (define_expand "bungt"
12981 [(set (pc)
12982 (if_then_else (match_dup 1)
12983 (label_ref (match_operand 0 "" ""))
12984 (pc)))]
12985 "TARGET_80387 || TARGET_SSE"
12986 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12987
12988 (define_expand "bunle"
12989 [(set (pc)
12990 (if_then_else (match_dup 1)
12991 (label_ref (match_operand 0 "" ""))
12992 (pc)))]
12993 "TARGET_80387 || TARGET_SSE"
12994 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12995
12996 (define_expand "bunlt"
12997 [(set (pc)
12998 (if_then_else (match_dup 1)
12999 (label_ref (match_operand 0 "" ""))
13000 (pc)))]
13001 "TARGET_80387 || TARGET_SSE"
13002 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13003
13004 (define_expand "bltgt"
13005 [(set (pc)
13006 (if_then_else (match_dup 1)
13007 (label_ref (match_operand 0 "" ""))
13008 (pc)))]
13009 "TARGET_80387 || TARGET_SSE"
13010 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13011
13012 (define_insn "*jcc_1"
13013 [(set (pc)
13014 (if_then_else (match_operator 1 "ix86_comparison_operator"
13015 [(reg 17) (const_int 0)])
13016 (label_ref (match_operand 0 "" ""))
13017 (pc)))]
13018 ""
13019 "%+j%C1\t%l0"
13020 [(set_attr "type" "ibr")
13021 (set_attr "modrm" "0")
13022 (set (attr "length")
13023 (if_then_else (and (ge (minus (match_dup 0) (pc))
13024 (const_int -126))
13025 (lt (minus (match_dup 0) (pc))
13026 (const_int 128)))
13027 (const_int 2)
13028 (const_int 6)))])
13029
13030 (define_insn "*jcc_2"
13031 [(set (pc)
13032 (if_then_else (match_operator 1 "ix86_comparison_operator"
13033 [(reg 17) (const_int 0)])
13034 (pc)
13035 (label_ref (match_operand 0 "" ""))))]
13036 ""
13037 "%+j%c1\t%l0"
13038 [(set_attr "type" "ibr")
13039 (set_attr "modrm" "0")
13040 (set (attr "length")
13041 (if_then_else (and (ge (minus (match_dup 0) (pc))
13042 (const_int -126))
13043 (lt (minus (match_dup 0) (pc))
13044 (const_int 128)))
13045 (const_int 2)
13046 (const_int 6)))])
13047
13048 ;; In general it is not safe to assume too much about CCmode registers,
13049 ;; so simplify-rtx stops when it sees a second one. Under certain
13050 ;; conditions this is safe on x86, so help combine not create
13051 ;;
13052 ;; seta %al
13053 ;; testb %al, %al
13054 ;; je Lfoo
13055
13056 (define_split
13057 [(set (pc)
13058 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13059 [(reg 17) (const_int 0)])
13060 (const_int 0))
13061 (label_ref (match_operand 1 "" ""))
13062 (pc)))]
13063 ""
13064 [(set (pc)
13065 (if_then_else (match_dup 0)
13066 (label_ref (match_dup 1))
13067 (pc)))]
13068 {
13069 PUT_MODE (operands[0], VOIDmode);
13070 })
13071
13072 (define_split
13073 [(set (pc)
13074 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13075 [(reg 17) (const_int 0)])
13076 (const_int 0))
13077 (label_ref (match_operand 1 "" ""))
13078 (pc)))]
13079 ""
13080 [(set (pc)
13081 (if_then_else (match_dup 0)
13082 (label_ref (match_dup 1))
13083 (pc)))]
13084 {
13085 rtx new_op0 = copy_rtx (operands[0]);
13086 operands[0] = new_op0;
13087 PUT_MODE (new_op0, VOIDmode);
13088 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13089 GET_MODE (XEXP (new_op0, 0))));
13090
13091 /* Make sure that (a) the CCmode we have for the flags is strong
13092 enough for the reversed compare or (b) we have a valid FP compare. */
13093 if (! ix86_comparison_operator (new_op0, VOIDmode))
13094 FAIL;
13095 })
13096
13097 ;; Define combination compare-and-branch fp compare instructions to use
13098 ;; during early optimization. Splitting the operation apart early makes
13099 ;; for bad code when we want to reverse the operation.
13100
13101 (define_insn "*fp_jcc_1"
13102 [(set (pc)
13103 (if_then_else (match_operator 0 "comparison_operator"
13104 [(match_operand 1 "register_operand" "f")
13105 (match_operand 2 "register_operand" "f")])
13106 (label_ref (match_operand 3 "" ""))
13107 (pc)))
13108 (clobber (reg:CCFP 18))
13109 (clobber (reg:CCFP 17))]
13110 "TARGET_CMOVE && TARGET_80387
13111 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13112 && FLOAT_MODE_P (GET_MODE (operands[1]))
13113 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13114 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13115 "#")
13116
13117 (define_insn "*fp_jcc_1_sse"
13118 [(set (pc)
13119 (if_then_else (match_operator 0 "comparison_operator"
13120 [(match_operand 1 "register_operand" "f#x,x#f")
13121 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13122 (label_ref (match_operand 3 "" ""))
13123 (pc)))
13124 (clobber (reg:CCFP 18))
13125 (clobber (reg:CCFP 17))]
13126 "TARGET_80387
13127 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13128 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13129 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13130 "#")
13131
13132 (define_insn "*fp_jcc_1_sse_only"
13133 [(set (pc)
13134 (if_then_else (match_operator 0 "comparison_operator"
13135 [(match_operand 1 "register_operand" "x")
13136 (match_operand 2 "nonimmediate_operand" "xm")])
13137 (label_ref (match_operand 3 "" ""))
13138 (pc)))
13139 (clobber (reg:CCFP 18))
13140 (clobber (reg:CCFP 17))]
13141 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13142 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13143 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13144 "#")
13145
13146 (define_insn "*fp_jcc_2"
13147 [(set (pc)
13148 (if_then_else (match_operator 0 "comparison_operator"
13149 [(match_operand 1 "register_operand" "f")
13150 (match_operand 2 "register_operand" "f")])
13151 (pc)
13152 (label_ref (match_operand 3 "" ""))))
13153 (clobber (reg:CCFP 18))
13154 (clobber (reg:CCFP 17))]
13155 "TARGET_CMOVE && TARGET_80387
13156 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13157 && FLOAT_MODE_P (GET_MODE (operands[1]))
13158 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13159 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13160 "#")
13161
13162 (define_insn "*fp_jcc_2_sse"
13163 [(set (pc)
13164 (if_then_else (match_operator 0 "comparison_operator"
13165 [(match_operand 1 "register_operand" "f#x,x#f")
13166 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13167 (pc)
13168 (label_ref (match_operand 3 "" ""))))
13169 (clobber (reg:CCFP 18))
13170 (clobber (reg:CCFP 17))]
13171 "TARGET_80387
13172 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13173 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13174 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13175 "#")
13176
13177 (define_insn "*fp_jcc_2_sse_only"
13178 [(set (pc)
13179 (if_then_else (match_operator 0 "comparison_operator"
13180 [(match_operand 1 "register_operand" "x")
13181 (match_operand 2 "nonimmediate_operand" "xm")])
13182 (pc)
13183 (label_ref (match_operand 3 "" ""))))
13184 (clobber (reg:CCFP 18))
13185 (clobber (reg:CCFP 17))]
13186 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13187 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13188 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13189 "#")
13190
13191 (define_insn "*fp_jcc_3"
13192 [(set (pc)
13193 (if_then_else (match_operator 0 "comparison_operator"
13194 [(match_operand 1 "register_operand" "f")
13195 (match_operand 2 "nonimmediate_operand" "fm")])
13196 (label_ref (match_operand 3 "" ""))
13197 (pc)))
13198 (clobber (reg:CCFP 18))
13199 (clobber (reg:CCFP 17))
13200 (clobber (match_scratch:HI 4 "=a"))]
13201 "TARGET_80387
13202 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13203 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13204 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13205 && SELECT_CC_MODE (GET_CODE (operands[0]),
13206 operands[1], operands[2]) == CCFPmode
13207 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13208 "#")
13209
13210 (define_insn "*fp_jcc_4"
13211 [(set (pc)
13212 (if_then_else (match_operator 0 "comparison_operator"
13213 [(match_operand 1 "register_operand" "f")
13214 (match_operand 2 "nonimmediate_operand" "fm")])
13215 (pc)
13216 (label_ref (match_operand 3 "" ""))))
13217 (clobber (reg:CCFP 18))
13218 (clobber (reg:CCFP 17))
13219 (clobber (match_scratch:HI 4 "=a"))]
13220 "TARGET_80387
13221 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13222 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13223 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13224 && SELECT_CC_MODE (GET_CODE (operands[0]),
13225 operands[1], operands[2]) == CCFPmode
13226 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227 "#")
13228
13229 (define_insn "*fp_jcc_5"
13230 [(set (pc)
13231 (if_then_else (match_operator 0 "comparison_operator"
13232 [(match_operand 1 "register_operand" "f")
13233 (match_operand 2 "register_operand" "f")])
13234 (label_ref (match_operand 3 "" ""))
13235 (pc)))
13236 (clobber (reg:CCFP 18))
13237 (clobber (reg:CCFP 17))
13238 (clobber (match_scratch:HI 4 "=a"))]
13239 "TARGET_80387
13240 && FLOAT_MODE_P (GET_MODE (operands[1]))
13241 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243 "#")
13244
13245 (define_insn "*fp_jcc_6"
13246 [(set (pc)
13247 (if_then_else (match_operator 0 "comparison_operator"
13248 [(match_operand 1 "register_operand" "f")
13249 (match_operand 2 "register_operand" "f")])
13250 (pc)
13251 (label_ref (match_operand 3 "" ""))))
13252 (clobber (reg:CCFP 18))
13253 (clobber (reg:CCFP 17))
13254 (clobber (match_scratch:HI 4 "=a"))]
13255 "TARGET_80387
13256 && FLOAT_MODE_P (GET_MODE (operands[1]))
13257 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13258 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13259 "#")
13260
13261 (define_split
13262 [(set (pc)
13263 (if_then_else (match_operator 0 "comparison_operator"
13264 [(match_operand 1 "register_operand" "")
13265 (match_operand 2 "nonimmediate_operand" "")])
13266 (match_operand 3 "" "")
13267 (match_operand 4 "" "")))
13268 (clobber (reg:CCFP 18))
13269 (clobber (reg:CCFP 17))]
13270 "reload_completed"
13271 [(const_int 0)]
13272 {
13273 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13274 operands[3], operands[4], NULL_RTX);
13275 DONE;
13276 })
13277
13278 (define_split
13279 [(set (pc)
13280 (if_then_else (match_operator 0 "comparison_operator"
13281 [(match_operand 1 "register_operand" "")
13282 (match_operand 2 "nonimmediate_operand" "")])
13283 (match_operand 3 "" "")
13284 (match_operand 4 "" "")))
13285 (clobber (reg:CCFP 18))
13286 (clobber (reg:CCFP 17))
13287 (clobber (match_scratch:HI 5 "=a"))]
13288 "reload_completed"
13289 [(set (pc)
13290 (if_then_else (match_dup 6)
13291 (match_dup 3)
13292 (match_dup 4)))]
13293 {
13294 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13295 operands[3], operands[4], operands[5]);
13296 DONE;
13297 })
13298 \f
13299 ;; Unconditional and other jump instructions
13300
13301 (define_insn "jump"
13302 [(set (pc)
13303 (label_ref (match_operand 0 "" "")))]
13304 ""
13305 "jmp\t%l0"
13306 [(set_attr "type" "ibr")
13307 (set (attr "length")
13308 (if_then_else (and (ge (minus (match_dup 0) (pc))
13309 (const_int -126))
13310 (lt (minus (match_dup 0) (pc))
13311 (const_int 128)))
13312 (const_int 2)
13313 (const_int 5)))
13314 (set_attr "modrm" "0")])
13315
13316 (define_expand "indirect_jump"
13317 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13318 ""
13319 "")
13320
13321 (define_insn "*indirect_jump"
13322 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13323 "!TARGET_64BIT"
13324 "jmp\t%A0"
13325 [(set_attr "type" "ibr")
13326 (set_attr "length_immediate" "0")])
13327
13328 (define_insn "*indirect_jump_rtx64"
13329 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13330 "TARGET_64BIT"
13331 "jmp\t%A0"
13332 [(set_attr "type" "ibr")
13333 (set_attr "length_immediate" "0")])
13334
13335 (define_expand "tablejump"
13336 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13337 (use (label_ref (match_operand 1 "" "")))])]
13338 ""
13339 {
13340 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13341 relative. Convert the relative address to an absolute address. */
13342 if (flag_pic)
13343 {
13344 rtx op0, op1;
13345 enum rtx_code code;
13346
13347 if (TARGET_64BIT)
13348 {
13349 code = PLUS;
13350 op0 = operands[0];
13351 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13352 }
13353 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13354 {
13355 code = PLUS;
13356 op0 = operands[0];
13357 op1 = pic_offset_table_rtx;
13358 }
13359 else
13360 {
13361 code = MINUS;
13362 op0 = pic_offset_table_rtx;
13363 op1 = operands[0];
13364 }
13365
13366 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13367 OPTAB_DIRECT);
13368 }
13369 })
13370
13371 (define_insn "*tablejump_1"
13372 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13373 (use (label_ref (match_operand 1 "" "")))]
13374 "!TARGET_64BIT"
13375 "jmp\t%A0"
13376 [(set_attr "type" "ibr")
13377 (set_attr "length_immediate" "0")])
13378
13379 (define_insn "*tablejump_1_rtx64"
13380 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13381 (use (label_ref (match_operand 1 "" "")))]
13382 "TARGET_64BIT"
13383 "jmp\t%A0"
13384 [(set_attr "type" "ibr")
13385 (set_attr "length_immediate" "0")])
13386 \f
13387 ;; Loop instruction
13388 ;;
13389 ;; This is all complicated by the fact that since this is a jump insn
13390 ;; we must handle our own reloads.
13391
13392 (define_expand "doloop_end"
13393 [(use (match_operand 0 "" "")) ; loop pseudo
13394 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13395 (use (match_operand 2 "" "")) ; max iterations
13396 (use (match_operand 3 "" "")) ; loop level
13397 (use (match_operand 4 "" ""))] ; label
13398 "!TARGET_64BIT && TARGET_USE_LOOP"
13399 "
13400 {
13401 /* Only use cloop on innermost loops. */
13402 if (INTVAL (operands[3]) > 1)
13403 FAIL;
13404 if (GET_MODE (operands[0]) != SImode)
13405 FAIL;
13406 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13407 operands[0]));
13408 DONE;
13409 }")
13410
13411 (define_insn "doloop_end_internal"
13412 [(set (pc)
13413 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13414 (const_int 1))
13415 (label_ref (match_operand 0 "" ""))
13416 (pc)))
13417 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13418 (plus:SI (match_dup 1)
13419 (const_int -1)))
13420 (clobber (match_scratch:SI 3 "=X,X,r"))
13421 (clobber (reg:CC 17))]
13422 "!TARGET_64BIT && TARGET_USE_LOOP
13423 && (reload_in_progress || reload_completed
13424 || register_operand (operands[2], VOIDmode))"
13425 {
13426 if (which_alternative != 0)
13427 return "#";
13428 if (get_attr_length (insn) == 2)
13429 return "%+loop\t%l0";
13430 else
13431 return "dec{l}\t%1\;%+jne\t%l0";
13432 }
13433 [(set (attr "length")
13434 (if_then_else (and (eq_attr "alternative" "0")
13435 (and (ge (minus (match_dup 0) (pc))
13436 (const_int -126))
13437 (lt (minus (match_dup 0) (pc))
13438 (const_int 128))))
13439 (const_int 2)
13440 (const_int 16)))
13441 ;; We don't know the type before shorten branches. Optimistically expect
13442 ;; the loop instruction to match.
13443 (set (attr "type") (const_string "ibr"))])
13444
13445 (define_split
13446 [(set (pc)
13447 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13448 (const_int 1))
13449 (match_operand 0 "" "")
13450 (pc)))
13451 (set (match_dup 1)
13452 (plus:SI (match_dup 1)
13453 (const_int -1)))
13454 (clobber (match_scratch:SI 2 ""))
13455 (clobber (reg:CC 17))]
13456 "!TARGET_64BIT && TARGET_USE_LOOP
13457 && reload_completed
13458 && REGNO (operands[1]) != 2"
13459 [(parallel [(set (reg:CCZ 17)
13460 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13461 (const_int 0)))
13462 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13463 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13464 (match_dup 0)
13465 (pc)))]
13466 "")
13467
13468 (define_split
13469 [(set (pc)
13470 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13471 (const_int 1))
13472 (match_operand 0 "" "")
13473 (pc)))
13474 (set (match_operand:SI 2 "nonimmediate_operand" "")
13475 (plus:SI (match_dup 1)
13476 (const_int -1)))
13477 (clobber (match_scratch:SI 3 ""))
13478 (clobber (reg:CC 17))]
13479 "!TARGET_64BIT && TARGET_USE_LOOP
13480 && reload_completed
13481 && (! REG_P (operands[2])
13482 || ! rtx_equal_p (operands[1], operands[2]))"
13483 [(set (match_dup 3) (match_dup 1))
13484 (parallel [(set (reg:CCZ 17)
13485 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13486 (const_int 0)))
13487 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13488 (set (match_dup 2) (match_dup 3))
13489 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13490 (match_dup 0)
13491 (pc)))]
13492 "")
13493
13494 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13495
13496 (define_peephole2
13497 [(set (reg 17) (match_operand 0 "" ""))
13498 (set (match_operand:QI 1 "register_operand" "")
13499 (match_operator:QI 2 "ix86_comparison_operator"
13500 [(reg 17) (const_int 0)]))
13501 (set (match_operand 3 "q_regs_operand" "")
13502 (zero_extend (match_dup 1)))]
13503 "(peep2_reg_dead_p (3, operands[1])
13504 || operands_match_p (operands[1], operands[3]))
13505 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13506 [(set (match_dup 4) (match_dup 0))
13507 (set (strict_low_part (match_dup 5))
13508 (match_dup 2))]
13509 {
13510 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13511 operands[5] = gen_lowpart (QImode, operands[3]);
13512 ix86_expand_clear (operands[3]);
13513 })
13514
13515 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13516
13517 (define_peephole2
13518 [(set (reg 17) (match_operand 0 "" ""))
13519 (set (match_operand:QI 1 "register_operand" "")
13520 (match_operator:QI 2 "ix86_comparison_operator"
13521 [(reg 17) (const_int 0)]))
13522 (parallel [(set (match_operand 3 "q_regs_operand" "")
13523 (zero_extend (match_dup 1)))
13524 (clobber (reg:CC 17))])]
13525 "(peep2_reg_dead_p (3, operands[1])
13526 || operands_match_p (operands[1], operands[3]))
13527 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13528 [(set (match_dup 4) (match_dup 0))
13529 (set (strict_low_part (match_dup 5))
13530 (match_dup 2))]
13531 {
13532 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13533 operands[5] = gen_lowpart (QImode, operands[3]);
13534 ix86_expand_clear (operands[3]);
13535 })
13536 \f
13537 ;; Call instructions.
13538
13539 ;; The predicates normally associated with named expanders are not properly
13540 ;; checked for calls. This is a bug in the generic code, but it isn't that
13541 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13542
13543 ;; Call subroutine returning no value.
13544
13545 (define_expand "call_pop"
13546 [(parallel [(call (match_operand:QI 0 "" "")
13547 (match_operand:SI 1 "" ""))
13548 (set (reg:SI 7)
13549 (plus:SI (reg:SI 7)
13550 (match_operand:SI 3 "" "")))])]
13551 "!TARGET_64BIT"
13552 {
13553 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13554 DONE;
13555 })
13556
13557 (define_insn "*call_pop_0"
13558 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13559 (match_operand:SI 1 "" ""))
13560 (set (reg:SI 7) (plus:SI (reg:SI 7)
13561 (match_operand:SI 2 "immediate_operand" "")))]
13562 "!TARGET_64BIT"
13563 {
13564 if (SIBLING_CALL_P (insn))
13565 return "jmp\t%P0";
13566 else
13567 return "call\t%P0";
13568 }
13569 [(set_attr "type" "call")])
13570
13571 (define_insn "*call_pop_1"
13572 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13573 (match_operand:SI 1 "" ""))
13574 (set (reg:SI 7) (plus:SI (reg:SI 7)
13575 (match_operand:SI 2 "immediate_operand" "i")))]
13576 "!TARGET_64BIT"
13577 {
13578 if (constant_call_address_operand (operands[0], Pmode))
13579 {
13580 if (SIBLING_CALL_P (insn))
13581 return "jmp\t%P0";
13582 else
13583 return "call\t%P0";
13584 }
13585 if (SIBLING_CALL_P (insn))
13586 return "jmp\t%A0";
13587 else
13588 return "call\t%A0";
13589 }
13590 [(set_attr "type" "call")])
13591
13592 (define_expand "call"
13593 [(call (match_operand:QI 0 "" "")
13594 (match_operand 1 "" ""))
13595 (use (match_operand 2 "" ""))]
13596 ""
13597 {
13598 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13599 DONE;
13600 })
13601
13602 (define_expand "sibcall"
13603 [(call (match_operand:QI 0 "" "")
13604 (match_operand 1 "" ""))
13605 (use (match_operand 2 "" ""))]
13606 ""
13607 {
13608 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13609 DONE;
13610 })
13611
13612 (define_insn "*call_0"
13613 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13614 (match_operand 1 "" ""))]
13615 ""
13616 {
13617 if (SIBLING_CALL_P (insn))
13618 return "jmp\t%P0";
13619 else
13620 return "call\t%P0";
13621 }
13622 [(set_attr "type" "call")])
13623
13624 (define_insn "*call_1"
13625 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13626 (match_operand 1 "" ""))]
13627 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13628 {
13629 if (constant_call_address_operand (operands[0], QImode))
13630 return "call\t%P0";
13631 return "call\t%A0";
13632 }
13633 [(set_attr "type" "call")])
13634
13635 (define_insn "*sibcall_1"
13636 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13637 (match_operand 1 "" ""))]
13638 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13639 {
13640 if (constant_call_address_operand (operands[0], QImode))
13641 return "jmp\t%P0";
13642 return "jmp\t%A0";
13643 }
13644 [(set_attr "type" "call")])
13645
13646 (define_insn "*call_1_rex64"
13647 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13648 (match_operand 1 "" ""))]
13649 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13650 {
13651 if (constant_call_address_operand (operands[0], QImode))
13652 return "call\t%P0";
13653 return "call\t%A0";
13654 }
13655 [(set_attr "type" "call")])
13656
13657 (define_insn "*sibcall_1_rex64"
13658 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13659 (match_operand 1 "" ""))]
13660 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13661 "jmp\t%P0"
13662 [(set_attr "type" "call")])
13663
13664 (define_insn "*sibcall_1_rex64_v"
13665 [(call (mem:QI (reg:DI 40))
13666 (match_operand 0 "" ""))]
13667 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13668 "jmp\t*%%r11"
13669 [(set_attr "type" "call")])
13670
13671
13672 ;; Call subroutine, returning value in operand 0
13673
13674 (define_expand "call_value_pop"
13675 [(parallel [(set (match_operand 0 "" "")
13676 (call (match_operand:QI 1 "" "")
13677 (match_operand:SI 2 "" "")))
13678 (set (reg:SI 7)
13679 (plus:SI (reg:SI 7)
13680 (match_operand:SI 4 "" "")))])]
13681 "!TARGET_64BIT"
13682 {
13683 ix86_expand_call (operands[0], operands[1], operands[2],
13684 operands[3], operands[4], 0);
13685 DONE;
13686 })
13687
13688 (define_expand "call_value"
13689 [(set (match_operand 0 "" "")
13690 (call (match_operand:QI 1 "" "")
13691 (match_operand:SI 2 "" "")))
13692 (use (match_operand:SI 3 "" ""))]
13693 ;; Operand 2 not used on the i386.
13694 ""
13695 {
13696 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13697 DONE;
13698 })
13699
13700 (define_expand "sibcall_value"
13701 [(set (match_operand 0 "" "")
13702 (call (match_operand:QI 1 "" "")
13703 (match_operand:SI 2 "" "")))
13704 (use (match_operand:SI 3 "" ""))]
13705 ;; Operand 2 not used on the i386.
13706 ""
13707 {
13708 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13709 DONE;
13710 })
13711
13712 ;; Call subroutine returning any type.
13713
13714 (define_expand "untyped_call"
13715 [(parallel [(call (match_operand 0 "" "")
13716 (const_int 0))
13717 (match_operand 1 "" "")
13718 (match_operand 2 "" "")])]
13719 ""
13720 {
13721 int i;
13722
13723 /* In order to give reg-stack an easier job in validating two
13724 coprocessor registers as containing a possible return value,
13725 simply pretend the untyped call returns a complex long double
13726 value. */
13727
13728 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13729 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13730 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13731 NULL, 0);
13732
13733 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13734 {
13735 rtx set = XVECEXP (operands[2], 0, i);
13736 emit_move_insn (SET_DEST (set), SET_SRC (set));
13737 }
13738
13739 /* The optimizer does not know that the call sets the function value
13740 registers we stored in the result block. We avoid problems by
13741 claiming that all hard registers are used and clobbered at this
13742 point. */
13743 emit_insn (gen_blockage (const0_rtx));
13744
13745 DONE;
13746 })
13747 \f
13748 ;; Prologue and epilogue instructions
13749
13750 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13751 ;; all of memory. This blocks insns from being moved across this point.
13752
13753 (define_insn "blockage"
13754 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13755 ""
13756 ""
13757 [(set_attr "length" "0")])
13758
13759 ;; Insn emitted into the body of a function to return from a function.
13760 ;; This is only done if the function's epilogue is known to be simple.
13761 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13762
13763 (define_expand "return"
13764 [(return)]
13765 "ix86_can_use_return_insn_p ()"
13766 {
13767 if (current_function_pops_args)
13768 {
13769 rtx popc = GEN_INT (current_function_pops_args);
13770 emit_jump_insn (gen_return_pop_internal (popc));
13771 DONE;
13772 }
13773 })
13774
13775 (define_insn "return_internal"
13776 [(return)]
13777 "reload_completed"
13778 "ret"
13779 [(set_attr "length" "1")
13780 (set_attr "length_immediate" "0")
13781 (set_attr "modrm" "0")])
13782
13783 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13784 ;; instruction Athlon and K8 have.
13785
13786 (define_insn "return_internal_long"
13787 [(return)
13788 (unspec [(const_int 0)] UNSPEC_REP)]
13789 "reload_completed"
13790 "rep {;} ret"
13791 [(set_attr "length" "1")
13792 (set_attr "length_immediate" "0")
13793 (set_attr "prefix_rep" "1")
13794 (set_attr "modrm" "0")])
13795
13796 (define_insn "return_pop_internal"
13797 [(return)
13798 (use (match_operand:SI 0 "const_int_operand" ""))]
13799 "reload_completed"
13800 "ret\t%0"
13801 [(set_attr "length" "3")
13802 (set_attr "length_immediate" "2")
13803 (set_attr "modrm" "0")])
13804
13805 (define_insn "return_indirect_internal"
13806 [(return)
13807 (use (match_operand:SI 0 "register_operand" "r"))]
13808 "reload_completed"
13809 "jmp\t%A0"
13810 [(set_attr "type" "ibr")
13811 (set_attr "length_immediate" "0")])
13812
13813 (define_insn "nop"
13814 [(const_int 0)]
13815 ""
13816 "nop"
13817 [(set_attr "length" "1")
13818 (set_attr "length_immediate" "0")
13819 (set_attr "modrm" "0")])
13820
13821 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13822 ;; branch prediction penalty for the third jump in a 16-byte
13823 ;; block on K8.
13824
13825 (define_insn "align"
13826 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13827 ""
13828 {
13829 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13830 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13831 #else
13832 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13833 The align insn is used to avoid 3 jump instructions in the row to improve
13834 branch prediction and the benefits hardly outweight the cost of extra 8
13835 nops on the average inserted by full alignment pseudo operation. */
13836 #endif
13837 return "";
13838 }
13839 [(set_attr "length" "16")])
13840
13841 (define_expand "prologue"
13842 [(const_int 1)]
13843 ""
13844 "ix86_expand_prologue (); DONE;")
13845
13846 (define_insn "set_got"
13847 [(set (match_operand:SI 0 "register_operand" "=r")
13848 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13849 (clobber (reg:CC 17))]
13850 "!TARGET_64BIT"
13851 { return output_set_got (operands[0]); }
13852 [(set_attr "type" "multi")
13853 (set_attr "length" "12")])
13854
13855 (define_expand "epilogue"
13856 [(const_int 1)]
13857 ""
13858 "ix86_expand_epilogue (1); DONE;")
13859
13860 (define_expand "sibcall_epilogue"
13861 [(const_int 1)]
13862 ""
13863 "ix86_expand_epilogue (0); DONE;")
13864
13865 (define_expand "eh_return"
13866 [(use (match_operand 0 "register_operand" ""))]
13867 ""
13868 {
13869 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13870
13871 /* Tricky bit: we write the address of the handler to which we will
13872 be returning into someone else's stack frame, one word below the
13873 stack address we wish to restore. */
13874 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13875 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13876 tmp = gen_rtx_MEM (Pmode, tmp);
13877 emit_move_insn (tmp, ra);
13878
13879 if (Pmode == SImode)
13880 emit_insn (gen_eh_return_si (sa));
13881 else
13882 emit_insn (gen_eh_return_di (sa));
13883 emit_barrier ();
13884 DONE;
13885 })
13886
13887 (define_insn_and_split "eh_return_si"
13888 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13889 UNSPECV_EH_RETURN)]
13890 "!TARGET_64BIT"
13891 "#"
13892 "reload_completed"
13893 [(const_int 1)]
13894 "ix86_expand_epilogue (2); DONE;")
13895
13896 (define_insn_and_split "eh_return_di"
13897 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13898 UNSPECV_EH_RETURN)]
13899 "TARGET_64BIT"
13900 "#"
13901 "reload_completed"
13902 [(const_int 1)]
13903 "ix86_expand_epilogue (2); DONE;")
13904
13905 (define_insn "leave"
13906 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13907 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13908 (clobber (mem:BLK (scratch)))]
13909 "!TARGET_64BIT"
13910 "leave"
13911 [(set_attr "type" "leave")])
13912
13913 (define_insn "leave_rex64"
13914 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13915 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13916 (clobber (mem:BLK (scratch)))]
13917 "TARGET_64BIT"
13918 "leave"
13919 [(set_attr "type" "leave")])
13920 \f
13921 (define_expand "ffssi2"
13922 [(parallel
13923 [(set (match_operand:SI 0 "register_operand" "")
13924 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13925 (clobber (match_scratch:SI 2 ""))
13926 (clobber (reg:CC 17))])]
13927 ""
13928 "")
13929
13930 (define_insn_and_split "*ffs_cmove"
13931 [(set (match_operand:SI 0 "register_operand" "=r")
13932 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13933 (clobber (match_scratch:SI 2 "=&r"))
13934 (clobber (reg:CC 17))]
13935 "TARGET_CMOVE"
13936 "#"
13937 "&& reload_completed"
13938 [(set (match_dup 2) (const_int -1))
13939 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13940 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13941 (set (match_dup 0) (if_then_else:SI
13942 (eq (reg:CCZ 17) (const_int 0))
13943 (match_dup 2)
13944 (match_dup 0)))
13945 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13946 (clobber (reg:CC 17))])]
13947 "")
13948
13949 (define_insn_and_split "*ffs_no_cmove"
13950 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13951 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13952 (clobber (match_scratch:SI 2 "=&q"))
13953 (clobber (reg:CC 17))]
13954 ""
13955 "#"
13956 "reload_completed"
13957 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13958 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13959 (set (strict_low_part (match_dup 3))
13960 (eq:QI (reg:CCZ 17) (const_int 0)))
13961 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13962 (clobber (reg:CC 17))])
13963 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13964 (clobber (reg:CC 17))])
13965 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13966 (clobber (reg:CC 17))])]
13967 {
13968 operands[3] = gen_lowpart (QImode, operands[2]);
13969 ix86_expand_clear (operands[2]);
13970 })
13971
13972 (define_insn "*ffssi_1"
13973 [(set (reg:CCZ 17)
13974 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13975 (const_int 0)))
13976 (set (match_operand:SI 0 "register_operand" "=r")
13977 (ctz:SI (match_dup 1)))]
13978 ""
13979 "bsf{l}\t{%1, %0|%0, %1}"
13980 [(set_attr "prefix_0f" "1")])
13981
13982 (define_insn "ctzsi2"
13983 [(set (match_operand:SI 0 "register_operand" "=r")
13984 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13985 (clobber (reg:CC 17))]
13986 ""
13987 "bsf{l}\t{%1, %0|%0, %1}"
13988 [(set_attr "prefix_0f" "1")])
13989
13990 (define_expand "clzsi2"
13991 [(parallel
13992 [(set (match_operand:SI 0 "register_operand" "")
13993 (minus:SI (const_int 31)
13994 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13995 (clobber (reg:CC 17))])
13996 (parallel
13997 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13998 (clobber (reg:CC 17))])]
13999 ""
14000 "")
14001
14002 (define_insn "*bsr"
14003 [(set (match_operand:SI 0 "register_operand" "=r")
14004 (minus:SI (const_int 31)
14005 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14006 (clobber (reg:CC 17))]
14007 ""
14008 "bsr{l}\t{%1, %0|%0, %1}"
14009 [(set_attr "prefix_0f" "1")])
14010 \f
14011 ;; Thread-local storage patterns for ELF.
14012 ;;
14013 ;; Note that these code sequences must appear exactly as shown
14014 ;; in order to allow linker relaxation.
14015
14016 (define_insn "*tls_global_dynamic_32_gnu"
14017 [(set (match_operand:SI 0 "register_operand" "=a")
14018 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14019 (match_operand:SI 2 "tls_symbolic_operand" "")
14020 (match_operand:SI 3 "call_insn_operand" "")]
14021 UNSPEC_TLS_GD))
14022 (clobber (match_scratch:SI 4 "=d"))
14023 (clobber (match_scratch:SI 5 "=c"))
14024 (clobber (reg:CC 17))]
14025 "!TARGET_64BIT && TARGET_GNU_TLS"
14026 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14027 [(set_attr "type" "multi")
14028 (set_attr "length" "12")])
14029
14030 (define_insn "*tls_global_dynamic_32_sun"
14031 [(set (match_operand:SI 0 "register_operand" "=a")
14032 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14033 (match_operand:SI 2 "tls_symbolic_operand" "")
14034 (match_operand:SI 3 "call_insn_operand" "")]
14035 UNSPEC_TLS_GD))
14036 (clobber (match_scratch:SI 4 "=d"))
14037 (clobber (match_scratch:SI 5 "=c"))
14038 (clobber (reg:CC 17))]
14039 "!TARGET_64BIT && TARGET_SUN_TLS"
14040 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14041 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14042 [(set_attr "type" "multi")
14043 (set_attr "length" "14")])
14044
14045 (define_expand "tls_global_dynamic_32"
14046 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14047 (unspec:SI
14048 [(match_dup 2)
14049 (match_operand:SI 1 "tls_symbolic_operand" "")
14050 (match_dup 3)]
14051 UNSPEC_TLS_GD))
14052 (clobber (match_scratch:SI 4 ""))
14053 (clobber (match_scratch:SI 5 ""))
14054 (clobber (reg:CC 17))])]
14055 ""
14056 {
14057 if (flag_pic)
14058 operands[2] = pic_offset_table_rtx;
14059 else
14060 {
14061 operands[2] = gen_reg_rtx (Pmode);
14062 emit_insn (gen_set_got (operands[2]));
14063 }
14064 operands[3] = ix86_tls_get_addr ();
14065 })
14066
14067 (define_insn "*tls_global_dynamic_64"
14068 [(set (match_operand:DI 0 "register_operand" "=a")
14069 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14070 (match_operand:DI 3 "" "")))
14071 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14072 UNSPEC_TLS_GD)]
14073 "TARGET_64BIT"
14074 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14075 [(set_attr "type" "multi")
14076 (set_attr "length" "16")])
14077
14078 (define_expand "tls_global_dynamic_64"
14079 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14080 (call (mem:QI (match_dup 2)) (const_int 0)))
14081 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14082 UNSPEC_TLS_GD)])]
14083 ""
14084 {
14085 operands[2] = ix86_tls_get_addr ();
14086 })
14087
14088 (define_insn "*tls_local_dynamic_base_32_gnu"
14089 [(set (match_operand:SI 0 "register_operand" "=a")
14090 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14091 (match_operand:SI 2 "call_insn_operand" "")]
14092 UNSPEC_TLS_LD_BASE))
14093 (clobber (match_scratch:SI 3 "=d"))
14094 (clobber (match_scratch:SI 4 "=c"))
14095 (clobber (reg:CC 17))]
14096 "!TARGET_64BIT && TARGET_GNU_TLS"
14097 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14098 [(set_attr "type" "multi")
14099 (set_attr "length" "11")])
14100
14101 (define_insn "*tls_local_dynamic_base_32_sun"
14102 [(set (match_operand:SI 0 "register_operand" "=a")
14103 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14104 (match_operand:SI 2 "call_insn_operand" "")]
14105 UNSPEC_TLS_LD_BASE))
14106 (clobber (match_scratch:SI 3 "=d"))
14107 (clobber (match_scratch:SI 4 "=c"))
14108 (clobber (reg:CC 17))]
14109 "!TARGET_64BIT && TARGET_SUN_TLS"
14110 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14111 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14112 [(set_attr "type" "multi")
14113 (set_attr "length" "13")])
14114
14115 (define_expand "tls_local_dynamic_base_32"
14116 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14117 (unspec:SI [(match_dup 1) (match_dup 2)]
14118 UNSPEC_TLS_LD_BASE))
14119 (clobber (match_scratch:SI 3 ""))
14120 (clobber (match_scratch:SI 4 ""))
14121 (clobber (reg:CC 17))])]
14122 ""
14123 {
14124 if (flag_pic)
14125 operands[1] = pic_offset_table_rtx;
14126 else
14127 {
14128 operands[1] = gen_reg_rtx (Pmode);
14129 emit_insn (gen_set_got (operands[1]));
14130 }
14131 operands[2] = ix86_tls_get_addr ();
14132 })
14133
14134 (define_insn "*tls_local_dynamic_base_64"
14135 [(set (match_operand:DI 0 "register_operand" "=a")
14136 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14137 (match_operand:DI 2 "" "")))
14138 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14139 "TARGET_64BIT"
14140 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14141 [(set_attr "type" "multi")
14142 (set_attr "length" "12")])
14143
14144 (define_expand "tls_local_dynamic_base_64"
14145 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14146 (call (mem:QI (match_dup 1)) (const_int 0)))
14147 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14148 ""
14149 {
14150 operands[1] = ix86_tls_get_addr ();
14151 })
14152
14153 ;; Local dynamic of a single variable is a lose. Show combine how
14154 ;; to convert that back to global dynamic.
14155
14156 (define_insn_and_split "*tls_local_dynamic_32_once"
14157 [(set (match_operand:SI 0 "register_operand" "=a")
14158 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14159 (match_operand:SI 2 "call_insn_operand" "")]
14160 UNSPEC_TLS_LD_BASE)
14161 (const:SI (unspec:SI
14162 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14163 UNSPEC_DTPOFF))))
14164 (clobber (match_scratch:SI 4 "=d"))
14165 (clobber (match_scratch:SI 5 "=c"))
14166 (clobber (reg:CC 17))]
14167 ""
14168 "#"
14169 ""
14170 [(parallel [(set (match_dup 0)
14171 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14172 UNSPEC_TLS_GD))
14173 (clobber (match_dup 4))
14174 (clobber (match_dup 5))
14175 (clobber (reg:CC 17))])]
14176 "")
14177
14178 ;; Load and add the thread base pointer from %gs:0.
14179
14180 (define_insn "*load_tp_si"
14181 [(set (match_operand:SI 0 "register_operand" "=r")
14182 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14183 "!TARGET_64BIT"
14184 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14185 [(set_attr "type" "imov")
14186 (set_attr "modrm" "0")
14187 (set_attr "length" "7")
14188 (set_attr "memory" "load")
14189 (set_attr "imm_disp" "false")])
14190
14191 (define_insn "*add_tp_si"
14192 [(set (match_operand:SI 0 "register_operand" "=r")
14193 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14194 (match_operand:SI 1 "register_operand" "0")))
14195 (clobber (reg:CC 17))]
14196 "!TARGET_64BIT"
14197 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14198 [(set_attr "type" "alu")
14199 (set_attr "modrm" "0")
14200 (set_attr "length" "7")
14201 (set_attr "memory" "load")
14202 (set_attr "imm_disp" "false")])
14203
14204 (define_insn "*load_tp_di"
14205 [(set (match_operand:DI 0 "register_operand" "=r")
14206 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14207 "TARGET_64BIT"
14208 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14209 [(set_attr "type" "imov")
14210 (set_attr "modrm" "0")
14211 (set_attr "length" "7")
14212 (set_attr "memory" "load")
14213 (set_attr "imm_disp" "false")])
14214
14215 (define_insn "*add_tp_di"
14216 [(set (match_operand:DI 0 "register_operand" "=r")
14217 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14218 (match_operand:DI 1 "register_operand" "0")))
14219 (clobber (reg:CC 17))]
14220 "TARGET_64BIT"
14221 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14222 [(set_attr "type" "alu")
14223 (set_attr "modrm" "0")
14224 (set_attr "length" "7")
14225 (set_attr "memory" "load")
14226 (set_attr "imm_disp" "false")])
14227 \f
14228 ;; These patterns match the binary 387 instructions for addM3, subM3,
14229 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14230 ;; SFmode. The first is the normal insn, the second the same insn but
14231 ;; with one operand a conversion, and the third the same insn but with
14232 ;; the other operand a conversion. The conversion may be SFmode or
14233 ;; SImode if the target mode DFmode, but only SImode if the target mode
14234 ;; is SFmode.
14235
14236 ;; Gcc is slightly more smart about handling normal two address instructions
14237 ;; so use special patterns for add and mull.
14238 (define_insn "*fop_sf_comm_nosse"
14239 [(set (match_operand:SF 0 "register_operand" "=f")
14240 (match_operator:SF 3 "binary_fp_operator"
14241 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14242 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14243 "TARGET_80387 && !TARGET_SSE_MATH
14244 && COMMUTATIVE_ARITH_P (operands[3])
14245 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14246 "* return output_387_binary_op (insn, operands);"
14247 [(set (attr "type")
14248 (if_then_else (match_operand:SF 3 "mult_operator" "")
14249 (const_string "fmul")
14250 (const_string "fop")))
14251 (set_attr "mode" "SF")])
14252
14253 (define_insn "*fop_sf_comm"
14254 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14255 (match_operator:SF 3 "binary_fp_operator"
14256 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14257 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14258 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14259 && COMMUTATIVE_ARITH_P (operands[3])
14260 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14261 "* return output_387_binary_op (insn, operands);"
14262 [(set (attr "type")
14263 (if_then_else (eq_attr "alternative" "1")
14264 (if_then_else (match_operand:SF 3 "mult_operator" "")
14265 (const_string "ssemul")
14266 (const_string "sseadd"))
14267 (if_then_else (match_operand:SF 3 "mult_operator" "")
14268 (const_string "fmul")
14269 (const_string "fop"))))
14270 (set_attr "mode" "SF")])
14271
14272 (define_insn "*fop_sf_comm_sse"
14273 [(set (match_operand:SF 0 "register_operand" "=x")
14274 (match_operator:SF 3 "binary_fp_operator"
14275 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14276 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14277 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14278 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14279 "* return output_387_binary_op (insn, operands);"
14280 [(set (attr "type")
14281 (if_then_else (match_operand:SF 3 "mult_operator" "")
14282 (const_string "ssemul")
14283 (const_string "sseadd")))
14284 (set_attr "mode" "SF")])
14285
14286 (define_insn "*fop_df_comm_nosse"
14287 [(set (match_operand:DF 0 "register_operand" "=f")
14288 (match_operator:DF 3 "binary_fp_operator"
14289 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14290 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14291 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14292 && COMMUTATIVE_ARITH_P (operands[3])
14293 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14294 "* return output_387_binary_op (insn, operands);"
14295 [(set (attr "type")
14296 (if_then_else (match_operand:SF 3 "mult_operator" "")
14297 (const_string "fmul")
14298 (const_string "fop")))
14299 (set_attr "mode" "DF")])
14300
14301 (define_insn "*fop_df_comm"
14302 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14303 (match_operator:DF 3 "binary_fp_operator"
14304 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14305 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14306 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14307 && COMMUTATIVE_ARITH_P (operands[3])
14308 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14309 "* return output_387_binary_op (insn, operands);"
14310 [(set (attr "type")
14311 (if_then_else (eq_attr "alternative" "1")
14312 (if_then_else (match_operand:SF 3 "mult_operator" "")
14313 (const_string "ssemul")
14314 (const_string "sseadd"))
14315 (if_then_else (match_operand:SF 3 "mult_operator" "")
14316 (const_string "fmul")
14317 (const_string "fop"))))
14318 (set_attr "mode" "DF")])
14319
14320 (define_insn "*fop_df_comm_sse"
14321 [(set (match_operand:DF 0 "register_operand" "=Y")
14322 (match_operator:DF 3 "binary_fp_operator"
14323 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14324 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14325 "TARGET_SSE2 && TARGET_SSE_MATH
14326 && COMMUTATIVE_ARITH_P (operands[3])
14327 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14328 "* return output_387_binary_op (insn, operands);"
14329 [(set (attr "type")
14330 (if_then_else (match_operand:SF 3 "mult_operator" "")
14331 (const_string "ssemul")
14332 (const_string "sseadd")))
14333 (set_attr "mode" "DF")])
14334
14335 (define_insn "*fop_xf_comm"
14336 [(set (match_operand:XF 0 "register_operand" "=f")
14337 (match_operator:XF 3 "binary_fp_operator"
14338 [(match_operand:XF 1 "register_operand" "%0")
14339 (match_operand:XF 2 "register_operand" "f")]))]
14340 "TARGET_80387
14341 && COMMUTATIVE_ARITH_P (operands[3])"
14342 "* return output_387_binary_op (insn, operands);"
14343 [(set (attr "type")
14344 (if_then_else (match_operand:XF 3 "mult_operator" "")
14345 (const_string "fmul")
14346 (const_string "fop")))
14347 (set_attr "mode" "XF")])
14348
14349 (define_insn "*fop_sf_1_nosse"
14350 [(set (match_operand:SF 0 "register_operand" "=f,f")
14351 (match_operator:SF 3 "binary_fp_operator"
14352 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14353 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14354 "TARGET_80387 && !TARGET_SSE_MATH
14355 && !COMMUTATIVE_ARITH_P (operands[3])
14356 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14357 "* return output_387_binary_op (insn, operands);"
14358 [(set (attr "type")
14359 (cond [(match_operand:SF 3 "mult_operator" "")
14360 (const_string "fmul")
14361 (match_operand:SF 3 "div_operator" "")
14362 (const_string "fdiv")
14363 ]
14364 (const_string "fop")))
14365 (set_attr "mode" "SF")])
14366
14367 (define_insn "*fop_sf_1"
14368 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14369 (match_operator:SF 3 "binary_fp_operator"
14370 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14371 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14372 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14373 && !COMMUTATIVE_ARITH_P (operands[3])
14374 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14375 "* return output_387_binary_op (insn, operands);"
14376 [(set (attr "type")
14377 (cond [(and (eq_attr "alternative" "2")
14378 (match_operand:SF 3 "mult_operator" ""))
14379 (const_string "ssemul")
14380 (and (eq_attr "alternative" "2")
14381 (match_operand:SF 3 "div_operator" ""))
14382 (const_string "ssediv")
14383 (eq_attr "alternative" "2")
14384 (const_string "sseadd")
14385 (match_operand:SF 3 "mult_operator" "")
14386 (const_string "fmul")
14387 (match_operand:SF 3 "div_operator" "")
14388 (const_string "fdiv")
14389 ]
14390 (const_string "fop")))
14391 (set_attr "mode" "SF")])
14392
14393 (define_insn "*fop_sf_1_sse"
14394 [(set (match_operand:SF 0 "register_operand" "=x")
14395 (match_operator:SF 3 "binary_fp_operator"
14396 [(match_operand:SF 1 "register_operand" "0")
14397 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14398 "TARGET_SSE_MATH
14399 && !COMMUTATIVE_ARITH_P (operands[3])"
14400 "* return output_387_binary_op (insn, operands);"
14401 [(set (attr "type")
14402 (cond [(match_operand:SF 3 "mult_operator" "")
14403 (const_string "ssemul")
14404 (match_operand:SF 3 "div_operator" "")
14405 (const_string "ssediv")
14406 ]
14407 (const_string "sseadd")))
14408 (set_attr "mode" "SF")])
14409
14410 ;; ??? Add SSE splitters for these!
14411 (define_insn "*fop_sf_2"
14412 [(set (match_operand:SF 0 "register_operand" "=f,f")
14413 (match_operator:SF 3 "binary_fp_operator"
14414 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14415 (match_operand:SF 2 "register_operand" "0,0")]))]
14416 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14417 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14418 [(set (attr "type")
14419 (cond [(match_operand:SF 3 "mult_operator" "")
14420 (const_string "fmul")
14421 (match_operand:SF 3 "div_operator" "")
14422 (const_string "fdiv")
14423 ]
14424 (const_string "fop")))
14425 (set_attr "fp_int_src" "true")
14426 (set_attr "mode" "SI")])
14427
14428 (define_insn "*fop_sf_3"
14429 [(set (match_operand:SF 0 "register_operand" "=f,f")
14430 (match_operator:SF 3 "binary_fp_operator"
14431 [(match_operand:SF 1 "register_operand" "0,0")
14432 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14433 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14434 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14435 [(set (attr "type")
14436 (cond [(match_operand:SF 3 "mult_operator" "")
14437 (const_string "fmul")
14438 (match_operand:SF 3 "div_operator" "")
14439 (const_string "fdiv")
14440 ]
14441 (const_string "fop")))
14442 (set_attr "fp_int_src" "true")
14443 (set_attr "mode" "SI")])
14444
14445 (define_insn "*fop_df_1_nosse"
14446 [(set (match_operand:DF 0 "register_operand" "=f,f")
14447 (match_operator:DF 3 "binary_fp_operator"
14448 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14449 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14450 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14451 && !COMMUTATIVE_ARITH_P (operands[3])
14452 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14453 "* return output_387_binary_op (insn, operands);"
14454 [(set (attr "type")
14455 (cond [(match_operand:DF 3 "mult_operator" "")
14456 (const_string "fmul")
14457 (match_operand:DF 3 "div_operator" "")
14458 (const_string "fdiv")
14459 ]
14460 (const_string "fop")))
14461 (set_attr "mode" "DF")])
14462
14463
14464 (define_insn "*fop_df_1"
14465 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14466 (match_operator:DF 3 "binary_fp_operator"
14467 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14468 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14469 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14470 && !COMMUTATIVE_ARITH_P (operands[3])
14471 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14472 "* return output_387_binary_op (insn, operands);"
14473 [(set (attr "type")
14474 (cond [(and (eq_attr "alternative" "2")
14475 (match_operand:SF 3 "mult_operator" ""))
14476 (const_string "ssemul")
14477 (and (eq_attr "alternative" "2")
14478 (match_operand:SF 3 "div_operator" ""))
14479 (const_string "ssediv")
14480 (eq_attr "alternative" "2")
14481 (const_string "sseadd")
14482 (match_operand:DF 3 "mult_operator" "")
14483 (const_string "fmul")
14484 (match_operand:DF 3 "div_operator" "")
14485 (const_string "fdiv")
14486 ]
14487 (const_string "fop")))
14488 (set_attr "mode" "DF")])
14489
14490 (define_insn "*fop_df_1_sse"
14491 [(set (match_operand:DF 0 "register_operand" "=Y")
14492 (match_operator:DF 3 "binary_fp_operator"
14493 [(match_operand:DF 1 "register_operand" "0")
14494 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14495 "TARGET_SSE2 && TARGET_SSE_MATH
14496 && !COMMUTATIVE_ARITH_P (operands[3])"
14497 "* return output_387_binary_op (insn, operands);"
14498 [(set_attr "mode" "DF")
14499 (set (attr "type")
14500 (cond [(match_operand:SF 3 "mult_operator" "")
14501 (const_string "ssemul")
14502 (match_operand:SF 3 "div_operator" "")
14503 (const_string "ssediv")
14504 ]
14505 (const_string "sseadd")))])
14506
14507 ;; ??? Add SSE splitters for these!
14508 (define_insn "*fop_df_2"
14509 [(set (match_operand:DF 0 "register_operand" "=f,f")
14510 (match_operator:DF 3 "binary_fp_operator"
14511 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14512 (match_operand:DF 2 "register_operand" "0,0")]))]
14513 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14514 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14515 [(set (attr "type")
14516 (cond [(match_operand:DF 3 "mult_operator" "")
14517 (const_string "fmul")
14518 (match_operand:DF 3 "div_operator" "")
14519 (const_string "fdiv")
14520 ]
14521 (const_string "fop")))
14522 (set_attr "fp_int_src" "true")
14523 (set_attr "mode" "SI")])
14524
14525 (define_insn "*fop_df_3"
14526 [(set (match_operand:DF 0 "register_operand" "=f,f")
14527 (match_operator:DF 3 "binary_fp_operator"
14528 [(match_operand:DF 1 "register_operand" "0,0")
14529 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14530 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14531 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14532 [(set (attr "type")
14533 (cond [(match_operand:DF 3 "mult_operator" "")
14534 (const_string "fmul")
14535 (match_operand:DF 3 "div_operator" "")
14536 (const_string "fdiv")
14537 ]
14538 (const_string "fop")))
14539 (set_attr "fp_int_src" "true")
14540 (set_attr "mode" "SI")])
14541
14542 (define_insn "*fop_df_4"
14543 [(set (match_operand:DF 0 "register_operand" "=f,f")
14544 (match_operator:DF 3 "binary_fp_operator"
14545 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14546 (match_operand:DF 2 "register_operand" "0,f")]))]
14547 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14548 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14549 "* return output_387_binary_op (insn, operands);"
14550 [(set (attr "type")
14551 (cond [(match_operand:DF 3 "mult_operator" "")
14552 (const_string "fmul")
14553 (match_operand:DF 3 "div_operator" "")
14554 (const_string "fdiv")
14555 ]
14556 (const_string "fop")))
14557 (set_attr "mode" "SF")])
14558
14559 (define_insn "*fop_df_5"
14560 [(set (match_operand:DF 0 "register_operand" "=f,f")
14561 (match_operator:DF 3 "binary_fp_operator"
14562 [(match_operand:DF 1 "register_operand" "0,f")
14563 (float_extend:DF
14564 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14565 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14566 "* return output_387_binary_op (insn, operands);"
14567 [(set (attr "type")
14568 (cond [(match_operand:DF 3 "mult_operator" "")
14569 (const_string "fmul")
14570 (match_operand:DF 3 "div_operator" "")
14571 (const_string "fdiv")
14572 ]
14573 (const_string "fop")))
14574 (set_attr "mode" "SF")])
14575
14576 (define_insn "*fop_df_6"
14577 [(set (match_operand:DF 0 "register_operand" "=f,f")
14578 (match_operator:DF 3 "binary_fp_operator"
14579 [(float_extend:DF
14580 (match_operand:SF 1 "register_operand" "0,f"))
14581 (float_extend:DF
14582 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14583 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14584 "* return output_387_binary_op (insn, operands);"
14585 [(set (attr "type")
14586 (cond [(match_operand:DF 3 "mult_operator" "")
14587 (const_string "fmul")
14588 (match_operand:DF 3 "div_operator" "")
14589 (const_string "fdiv")
14590 ]
14591 (const_string "fop")))
14592 (set_attr "mode" "SF")])
14593
14594 (define_insn "*fop_xf_1"
14595 [(set (match_operand:XF 0 "register_operand" "=f,f")
14596 (match_operator:XF 3 "binary_fp_operator"
14597 [(match_operand:XF 1 "register_operand" "0,f")
14598 (match_operand:XF 2 "register_operand" "f,0")]))]
14599 "TARGET_80387
14600 && !COMMUTATIVE_ARITH_P (operands[3])"
14601 "* return output_387_binary_op (insn, operands);"
14602 [(set (attr "type")
14603 (cond [(match_operand:XF 3 "mult_operator" "")
14604 (const_string "fmul")
14605 (match_operand:XF 3 "div_operator" "")
14606 (const_string "fdiv")
14607 ]
14608 (const_string "fop")))
14609 (set_attr "mode" "XF")])
14610
14611 (define_insn "*fop_xf_2"
14612 [(set (match_operand:XF 0 "register_operand" "=f,f")
14613 (match_operator:XF 3 "binary_fp_operator"
14614 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14615 (match_operand:XF 2 "register_operand" "0,0")]))]
14616 "TARGET_80387 && TARGET_USE_FIOP"
14617 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14618 [(set (attr "type")
14619 (cond [(match_operand:XF 3 "mult_operator" "")
14620 (const_string "fmul")
14621 (match_operand:XF 3 "div_operator" "")
14622 (const_string "fdiv")
14623 ]
14624 (const_string "fop")))
14625 (set_attr "fp_int_src" "true")
14626 (set_attr "mode" "SI")])
14627
14628 (define_insn "*fop_xf_3"
14629 [(set (match_operand:XF 0 "register_operand" "=f,f")
14630 (match_operator:XF 3 "binary_fp_operator"
14631 [(match_operand:XF 1 "register_operand" "0,0")
14632 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14633 "TARGET_80387 && TARGET_USE_FIOP"
14634 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14635 [(set (attr "type")
14636 (cond [(match_operand:XF 3 "mult_operator" "")
14637 (const_string "fmul")
14638 (match_operand:XF 3 "div_operator" "")
14639 (const_string "fdiv")
14640 ]
14641 (const_string "fop")))
14642 (set_attr "fp_int_src" "true")
14643 (set_attr "mode" "SI")])
14644
14645 (define_insn "*fop_xf_4"
14646 [(set (match_operand:XF 0 "register_operand" "=f,f")
14647 (match_operator:XF 3 "binary_fp_operator"
14648 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14649 (match_operand:XF 2 "register_operand" "0,f")]))]
14650 "TARGET_80387"
14651 "* return output_387_binary_op (insn, operands);"
14652 [(set (attr "type")
14653 (cond [(match_operand:XF 3 "mult_operator" "")
14654 (const_string "fmul")
14655 (match_operand:XF 3 "div_operator" "")
14656 (const_string "fdiv")
14657 ]
14658 (const_string "fop")))
14659 (set_attr "mode" "SF")])
14660
14661 (define_insn "*fop_xf_5"
14662 [(set (match_operand:XF 0 "register_operand" "=f,f")
14663 (match_operator:XF 3 "binary_fp_operator"
14664 [(match_operand:XF 1 "register_operand" "0,f")
14665 (float_extend:XF
14666 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14667 "TARGET_80387"
14668 "* return output_387_binary_op (insn, operands);"
14669 [(set (attr "type")
14670 (cond [(match_operand:XF 3 "mult_operator" "")
14671 (const_string "fmul")
14672 (match_operand:XF 3 "div_operator" "")
14673 (const_string "fdiv")
14674 ]
14675 (const_string "fop")))
14676 (set_attr "mode" "SF")])
14677
14678 (define_insn "*fop_xf_6"
14679 [(set (match_operand:XF 0 "register_operand" "=f,f")
14680 (match_operator:XF 3 "binary_fp_operator"
14681 [(float_extend:XF
14682 (match_operand 1 "register_operand" "0,f"))
14683 (float_extend:XF
14684 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14685 "TARGET_80387"
14686 "* return output_387_binary_op (insn, operands);"
14687 [(set (attr "type")
14688 (cond [(match_operand:XF 3 "mult_operator" "")
14689 (const_string "fmul")
14690 (match_operand:XF 3 "div_operator" "")
14691 (const_string "fdiv")
14692 ]
14693 (const_string "fop")))
14694 (set_attr "mode" "SF")])
14695
14696 (define_split
14697 [(set (match_operand 0 "register_operand" "")
14698 (match_operator 3 "binary_fp_operator"
14699 [(float (match_operand:SI 1 "register_operand" ""))
14700 (match_operand 2 "register_operand" "")]))]
14701 "TARGET_80387 && reload_completed
14702 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14703 [(const_int 0)]
14704 {
14705 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14706 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14707 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14708 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14709 GET_MODE (operands[3]),
14710 operands[4],
14711 operands[2])));
14712 ix86_free_from_memory (GET_MODE (operands[1]));
14713 DONE;
14714 })
14715
14716 (define_split
14717 [(set (match_operand 0 "register_operand" "")
14718 (match_operator 3 "binary_fp_operator"
14719 [(match_operand 1 "register_operand" "")
14720 (float (match_operand:SI 2 "register_operand" ""))]))]
14721 "TARGET_80387 && reload_completed
14722 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14723 [(const_int 0)]
14724 {
14725 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14726 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14727 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14728 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14729 GET_MODE (operands[3]),
14730 operands[1],
14731 operands[4])));
14732 ix86_free_from_memory (GET_MODE (operands[2]));
14733 DONE;
14734 })
14735 \f
14736 ;; FPU special functions.
14737
14738 (define_expand "sqrtsf2"
14739 [(set (match_operand:SF 0 "register_operand" "")
14740 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14741 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14742 {
14743 if (!TARGET_SSE_MATH)
14744 operands[1] = force_reg (SFmode, operands[1]);
14745 })
14746
14747 (define_insn "sqrtsf2_1"
14748 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14749 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14750 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14751 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14752 "@
14753 fsqrt
14754 sqrtss\t{%1, %0|%0, %1}"
14755 [(set_attr "type" "fpspc,sse")
14756 (set_attr "mode" "SF,SF")
14757 (set_attr "athlon_decode" "direct,*")])
14758
14759 (define_insn "sqrtsf2_1_sse_only"
14760 [(set (match_operand:SF 0 "register_operand" "=x")
14761 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14762 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14763 "sqrtss\t{%1, %0|%0, %1}"
14764 [(set_attr "type" "sse")
14765 (set_attr "mode" "SF")
14766 (set_attr "athlon_decode" "*")])
14767
14768 (define_insn "sqrtsf2_i387"
14769 [(set (match_operand:SF 0 "register_operand" "=f")
14770 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14771 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14772 && !TARGET_SSE_MATH"
14773 "fsqrt"
14774 [(set_attr "type" "fpspc")
14775 (set_attr "mode" "SF")
14776 (set_attr "athlon_decode" "direct")])
14777
14778 (define_expand "sqrtdf2"
14779 [(set (match_operand:DF 0 "register_operand" "")
14780 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14781 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14782 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14783 {
14784 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14785 operands[1] = force_reg (DFmode, operands[1]);
14786 })
14787
14788 (define_insn "sqrtdf2_1"
14789 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14790 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14791 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14792 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14793 "@
14794 fsqrt
14795 sqrtsd\t{%1, %0|%0, %1}"
14796 [(set_attr "type" "fpspc,sse")
14797 (set_attr "mode" "DF,DF")
14798 (set_attr "athlon_decode" "direct,*")])
14799
14800 (define_insn "sqrtdf2_1_sse_only"
14801 [(set (match_operand:DF 0 "register_operand" "=Y")
14802 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14803 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14804 "sqrtsd\t{%1, %0|%0, %1}"
14805 [(set_attr "type" "sse")
14806 (set_attr "mode" "DF")
14807 (set_attr "athlon_decode" "*")])
14808
14809 (define_insn "sqrtdf2_i387"
14810 [(set (match_operand:DF 0 "register_operand" "=f")
14811 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14812 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14813 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14814 "fsqrt"
14815 [(set_attr "type" "fpspc")
14816 (set_attr "mode" "DF")
14817 (set_attr "athlon_decode" "direct")])
14818
14819 (define_insn "*sqrtextendsfdf2"
14820 [(set (match_operand:DF 0 "register_operand" "=f")
14821 (sqrt:DF (float_extend:DF
14822 (match_operand:SF 1 "register_operand" "0"))))]
14823 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14824 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14825 "fsqrt"
14826 [(set_attr "type" "fpspc")
14827 (set_attr "mode" "DF")
14828 (set_attr "athlon_decode" "direct")])
14829
14830 (define_insn "sqrtxf2"
14831 [(set (match_operand:XF 0 "register_operand" "=f")
14832 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14833 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14834 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14835 "fsqrt"
14836 [(set_attr "type" "fpspc")
14837 (set_attr "mode" "XF")
14838 (set_attr "athlon_decode" "direct")])
14839
14840 (define_insn "*sqrtextenddfxf2"
14841 [(set (match_operand:XF 0 "register_operand" "=f")
14842 (sqrt:XF (float_extend:XF
14843 (match_operand:DF 1 "register_operand" "0"))))]
14844 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14845 "fsqrt"
14846 [(set_attr "type" "fpspc")
14847 (set_attr "mode" "XF")
14848 (set_attr "athlon_decode" "direct")])
14849
14850 (define_insn "*sqrtextendsfxf2"
14851 [(set (match_operand:XF 0 "register_operand" "=f")
14852 (sqrt:XF (float_extend:XF
14853 (match_operand:SF 1 "register_operand" "0"))))]
14854 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14855 "fsqrt"
14856 [(set_attr "type" "fpspc")
14857 (set_attr "mode" "XF")
14858 (set_attr "athlon_decode" "direct")])
14859
14860 (define_insn "*sindf2"
14861 [(set (match_operand:DF 0 "register_operand" "=f")
14862 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14863 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14864 && flag_unsafe_math_optimizations"
14865 "fsin"
14866 [(set_attr "type" "fpspc")
14867 (set_attr "mode" "DF")])
14868
14869 (define_insn "*sinsf2"
14870 [(set (match_operand:SF 0 "register_operand" "=f")
14871 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14872 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14873 && flag_unsafe_math_optimizations"
14874 "fsin"
14875 [(set_attr "type" "fpspc")
14876 (set_attr "mode" "SF")])
14877
14878 (define_insn "*sinextendsfdf2"
14879 [(set (match_operand:DF 0 "register_operand" "=f")
14880 (unspec:DF [(float_extend:DF
14881 (match_operand:SF 1 "register_operand" "0"))]
14882 UNSPEC_SIN))]
14883 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14884 && flag_unsafe_math_optimizations"
14885 "fsin"
14886 [(set_attr "type" "fpspc")
14887 (set_attr "mode" "DF")])
14888
14889 (define_insn "*sinxf2"
14890 [(set (match_operand:XF 0 "register_operand" "=f")
14891 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14892 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14893 && flag_unsafe_math_optimizations"
14894 "fsin"
14895 [(set_attr "type" "fpspc")
14896 (set_attr "mode" "XF")])
14897
14898 (define_insn "*cosdf2"
14899 [(set (match_operand:DF 0 "register_operand" "=f")
14900 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14901 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14902 && flag_unsafe_math_optimizations"
14903 "fcos"
14904 [(set_attr "type" "fpspc")
14905 (set_attr "mode" "DF")])
14906
14907 (define_insn "*cossf2"
14908 [(set (match_operand:SF 0 "register_operand" "=f")
14909 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14910 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14911 && flag_unsafe_math_optimizations"
14912 "fcos"
14913 [(set_attr "type" "fpspc")
14914 (set_attr "mode" "SF")])
14915
14916 (define_insn "*cosextendsfdf2"
14917 [(set (match_operand:DF 0 "register_operand" "=f")
14918 (unspec:DF [(float_extend:DF
14919 (match_operand:SF 1 "register_operand" "0"))]
14920 UNSPEC_COS))]
14921 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14922 && flag_unsafe_math_optimizations"
14923 "fcos"
14924 [(set_attr "type" "fpspc")
14925 (set_attr "mode" "DF")])
14926
14927 (define_insn "*cosxf2"
14928 [(set (match_operand:XF 0 "register_operand" "=f")
14929 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14930 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14931 && flag_unsafe_math_optimizations"
14932 "fcos"
14933 [(set_attr "type" "fpspc")
14934 (set_attr "mode" "XF")])
14935
14936 ;; With sincos pattern defined, sin and cos builtin function will be
14937 ;; expanded to sincos pattern with one of its outputs left unused.
14938 ;; Cse pass will detected, if two sincos patterns can be combined,
14939 ;; otherwise sincos pattern will be splitted back to sin or cos pattern,
14940 ;; depending on the unused output.
14941
14942 (define_insn "sincosdf3"
14943 [(set (match_operand:DF 0 "register_operand" "=f")
14944 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14945 UNSPEC_SINCOS_COS))
14946 (set (match_operand:DF 1 "register_operand" "=u")
14947 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14948 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14949 && flag_unsafe_math_optimizations"
14950 "fsincos"
14951 [(set_attr "type" "fpspc")
14952 (set_attr "mode" "DF")])
14953
14954 (define_split
14955 [(set (match_operand:DF 0 "register_operand" "")
14956 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14957 UNSPEC_SINCOS_COS))
14958 (set (match_operand:DF 1 "register_operand" "")
14959 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14960 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14961 && !reload_completed && !reload_in_progress"
14962 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14963 "")
14964
14965 (define_split
14966 [(set (match_operand:DF 0 "register_operand" "")
14967 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14968 UNSPEC_SINCOS_COS))
14969 (set (match_operand:DF 1 "register_operand" "")
14970 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14971 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14972 && !reload_completed && !reload_in_progress"
14973 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14974 "")
14975
14976 (define_insn "sincossf3"
14977 [(set (match_operand:SF 0 "register_operand" "=f")
14978 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14979 UNSPEC_SINCOS_COS))
14980 (set (match_operand:SF 1 "register_operand" "=u")
14981 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14982 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14983 && flag_unsafe_math_optimizations"
14984 "fsincos"
14985 [(set_attr "type" "fpspc")
14986 (set_attr "mode" "SF")])
14987
14988 (define_split
14989 [(set (match_operand:SF 0 "register_operand" "")
14990 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14991 UNSPEC_SINCOS_COS))
14992 (set (match_operand:SF 1 "register_operand" "")
14993 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14994 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14995 && !reload_completed && !reload_in_progress"
14996 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14997 "")
14998
14999 (define_split
15000 [(set (match_operand:SF 0 "register_operand" "")
15001 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15002 UNSPEC_SINCOS_COS))
15003 (set (match_operand:SF 1 "register_operand" "")
15004 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15005 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15006 && !reload_completed && !reload_in_progress"
15007 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15008 "")
15009
15010 (define_insn "*sincosextendsfdf3"
15011 [(set (match_operand:DF 0 "register_operand" "=f")
15012 (unspec:DF [(float_extend:DF
15013 (match_operand:SF 2 "register_operand" "0"))]
15014 UNSPEC_SINCOS_COS))
15015 (set (match_operand:DF 1 "register_operand" "=u")
15016 (unspec:DF [(float_extend:DF
15017 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15018 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15019 && flag_unsafe_math_optimizations"
15020 "fsincos"
15021 [(set_attr "type" "fpspc")
15022 (set_attr "mode" "DF")])
15023
15024 (define_split
15025 [(set (match_operand:DF 0 "register_operand" "")
15026 (unspec:DF [(float_extend:DF
15027 (match_operand:SF 2 "register_operand" ""))]
15028 UNSPEC_SINCOS_COS))
15029 (set (match_operand:DF 1 "register_operand" "")
15030 (unspec:DF [(float_extend:DF
15031 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15032 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15033 && !reload_completed && !reload_in_progress"
15034 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15035 (match_dup 2))] UNSPEC_SIN))]
15036 "")
15037
15038 (define_split
15039 [(set (match_operand:DF 0 "register_operand" "")
15040 (unspec:DF [(float_extend:DF
15041 (match_operand:SF 2 "register_operand" ""))]
15042 UNSPEC_SINCOS_COS))
15043 (set (match_operand:DF 1 "register_operand" "")
15044 (unspec:DF [(float_extend:DF
15045 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15046 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15047 && !reload_completed && !reload_in_progress"
15048 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15049 (match_dup 2))] UNSPEC_COS))]
15050 "")
15051
15052 (define_insn "sincosxf3"
15053 [(set (match_operand:XF 0 "register_operand" "=f")
15054 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15055 UNSPEC_SINCOS_COS))
15056 (set (match_operand:XF 1 "register_operand" "=u")
15057 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15058 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15059 && flag_unsafe_math_optimizations"
15060 "fsincos"
15061 [(set_attr "type" "fpspc")
15062 (set_attr "mode" "XF")])
15063
15064 (define_split
15065 [(set (match_operand:XF 0 "register_operand" "")
15066 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15067 UNSPEC_SINCOS_COS))
15068 (set (match_operand:XF 1 "register_operand" "")
15069 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15070 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15071 && !reload_completed && !reload_in_progress"
15072 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15073 "")
15074
15075 (define_split
15076 [(set (match_operand:XF 0 "register_operand" "")
15077 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15078 UNSPEC_SINCOS_COS))
15079 (set (match_operand:XF 1 "register_operand" "")
15080 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15081 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15082 && !reload_completed && !reload_in_progress"
15083 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15084 "")
15085
15086 (define_insn "*tandf3_1"
15087 [(set (match_operand:DF 0 "register_operand" "=f")
15088 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15089 UNSPEC_TAN_ONE))
15090 (set (match_operand:DF 1 "register_operand" "=u")
15091 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15092 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15093 && flag_unsafe_math_optimizations"
15094 "fptan"
15095 [(set_attr "type" "fpspc")
15096 (set_attr "mode" "DF")])
15097
15098 ;; optimize sequence: fptan
15099 ;; fstp %st(0)
15100 ;; fld1
15101 ;; into fptan insn.
15102
15103 (define_peephole2
15104 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15105 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15106 UNSPEC_TAN_ONE))
15107 (set (match_operand:DF 1 "register_operand" "")
15108 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15109 (set (match_dup 0)
15110 (match_operand:DF 3 "immediate_operand" ""))]
15111 "standard_80387_constant_p (operands[3]) == 2"
15112 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15113 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15114 "")
15115
15116 (define_expand "tandf2"
15117 [(parallel [(set (match_dup 2)
15118 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15119 UNSPEC_TAN_ONE))
15120 (set (match_operand:DF 0 "register_operand" "")
15121 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15122 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15123 && flag_unsafe_math_optimizations"
15124 {
15125 operands[2] = gen_reg_rtx (DFmode);
15126 })
15127
15128 (define_insn "*tansf3_1"
15129 [(set (match_operand:SF 0 "register_operand" "=f")
15130 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15131 UNSPEC_TAN_ONE))
15132 (set (match_operand:SF 1 "register_operand" "=u")
15133 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15134 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15135 && flag_unsafe_math_optimizations"
15136 "fptan"
15137 [(set_attr "type" "fpspc")
15138 (set_attr "mode" "SF")])
15139
15140 ;; optimize sequence: fptan
15141 ;; fstp %st(0)
15142 ;; fld1
15143 ;; into fptan insn.
15144
15145 (define_peephole2
15146 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15147 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15148 UNSPEC_TAN_ONE))
15149 (set (match_operand:SF 1 "register_operand" "")
15150 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15151 (set (match_dup 0)
15152 (match_operand:SF 3 "immediate_operand" ""))]
15153 "standard_80387_constant_p (operands[3]) == 2"
15154 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15155 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15156 "")
15157
15158 (define_expand "tansf2"
15159 [(parallel [(set (match_dup 2)
15160 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15161 UNSPEC_TAN_ONE))
15162 (set (match_operand:SF 0 "register_operand" "")
15163 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15164 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15165 && flag_unsafe_math_optimizations"
15166 {
15167 operands[2] = gen_reg_rtx (SFmode);
15168 })
15169
15170 (define_insn "*tanxf3_1"
15171 [(set (match_operand:XF 0 "register_operand" "=f")
15172 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15173 UNSPEC_TAN_ONE))
15174 (set (match_operand:XF 1 "register_operand" "=u")
15175 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15176 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15177 && flag_unsafe_math_optimizations"
15178 "fptan"
15179 [(set_attr "type" "fpspc")
15180 (set_attr "mode" "XF")])
15181
15182 ;; optimize sequence: fptan
15183 ;; fstp %st(0)
15184 ;; fld1
15185 ;; into fptan insn.
15186
15187 (define_peephole2
15188 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15189 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15190 UNSPEC_TAN_ONE))
15191 (set (match_operand:XF 1 "register_operand" "")
15192 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15193 (set (match_dup 0)
15194 (match_operand:XF 3 "immediate_operand" ""))]
15195 "standard_80387_constant_p (operands[3]) == 2"
15196 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15197 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15198 "")
15199
15200 (define_expand "tanxf2"
15201 [(parallel [(set (match_dup 2)
15202 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15203 UNSPEC_TAN_ONE))
15204 (set (match_operand:XF 0 "register_operand" "")
15205 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15206 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15207 && flag_unsafe_math_optimizations"
15208 {
15209 operands[2] = gen_reg_rtx (XFmode);
15210 })
15211
15212 (define_insn "atan2df3_1"
15213 [(set (match_operand:DF 0 "register_operand" "=f")
15214 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15215 (match_operand:DF 1 "register_operand" "u")]
15216 UNSPEC_FPATAN))
15217 (clobber (match_scratch:DF 3 "=1"))]
15218 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15219 && flag_unsafe_math_optimizations"
15220 "fpatan"
15221 [(set_attr "type" "fpspc")
15222 (set_attr "mode" "DF")])
15223
15224 (define_expand "atan2df3"
15225 [(use (match_operand:DF 0 "register_operand" "=f"))
15226 (use (match_operand:DF 2 "register_operand" "0"))
15227 (use (match_operand:DF 1 "register_operand" "u"))]
15228 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15229 && flag_unsafe_math_optimizations"
15230 {
15231 rtx copy = gen_reg_rtx (DFmode);
15232 emit_move_insn (copy, operands[1]);
15233 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15234 DONE;
15235 })
15236
15237 (define_insn "atan2sf3_1"
15238 [(set (match_operand:SF 0 "register_operand" "=f")
15239 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15240 (match_operand:SF 1 "register_operand" "u")]
15241 UNSPEC_FPATAN))
15242 (clobber (match_scratch:SF 3 "=1"))]
15243 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15244 && flag_unsafe_math_optimizations"
15245 "fpatan"
15246 [(set_attr "type" "fpspc")
15247 (set_attr "mode" "SF")])
15248
15249 (define_expand "atan2sf3"
15250 [(use (match_operand:SF 0 "register_operand" "=f"))
15251 (use (match_operand:SF 2 "register_operand" "0"))
15252 (use (match_operand:SF 1 "register_operand" "u"))]
15253 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15254 && flag_unsafe_math_optimizations"
15255 {
15256 rtx copy = gen_reg_rtx (SFmode);
15257 emit_move_insn (copy, operands[1]);
15258 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15259 DONE;
15260 })
15261
15262 (define_insn "atan2xf3_1"
15263 [(set (match_operand:XF 0 "register_operand" "=f")
15264 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15265 (match_operand:XF 1 "register_operand" "u")]
15266 UNSPEC_FPATAN))
15267 (clobber (match_scratch:XF 3 "=1"))]
15268 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15269 && flag_unsafe_math_optimizations"
15270 "fpatan"
15271 [(set_attr "type" "fpspc")
15272 (set_attr "mode" "XF")])
15273
15274 (define_expand "atan2xf3"
15275 [(use (match_operand:XF 0 "register_operand" "=f"))
15276 (use (match_operand:XF 2 "register_operand" "0"))
15277 (use (match_operand:XF 1 "register_operand" "u"))]
15278 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15279 && flag_unsafe_math_optimizations"
15280 {
15281 rtx copy = gen_reg_rtx (XFmode);
15282 emit_move_insn (copy, operands[1]);
15283 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15284 DONE;
15285 })
15286
15287 (define_insn "*fyl2x_sfxf3"
15288 [(set (match_operand:SF 0 "register_operand" "=f")
15289 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15290 (match_operand:XF 1 "register_operand" "u")]
15291 UNSPEC_FYL2X))
15292 (clobber (match_scratch:SF 3 "=1"))]
15293 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15294 && flag_unsafe_math_optimizations"
15295 "fyl2x"
15296 [(set_attr "type" "fpspc")
15297 (set_attr "mode" "SF")])
15298
15299 (define_insn "*fyl2x_dfxf3"
15300 [(set (match_operand:DF 0 "register_operand" "=f")
15301 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15302 (match_operand:XF 1 "register_operand" "u")]
15303 UNSPEC_FYL2X))
15304 (clobber (match_scratch:DF 3 "=1"))]
15305 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15306 && flag_unsafe_math_optimizations"
15307 "fyl2x"
15308 [(set_attr "type" "fpspc")
15309 (set_attr "mode" "DF")])
15310
15311 (define_insn "*fyl2x_xf3"
15312 [(set (match_operand:XF 0 "register_operand" "=f")
15313 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15314 (match_operand:XF 1 "register_operand" "u")]
15315 UNSPEC_FYL2X))
15316 (clobber (match_scratch:XF 3 "=1"))]
15317 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15318 && flag_unsafe_math_optimizations"
15319 "fyl2x"
15320 [(set_attr "type" "fpspc")
15321 (set_attr "mode" "XF")])
15322
15323 (define_expand "logsf2"
15324 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15325 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15326 (match_dup 2)] UNSPEC_FYL2X))
15327 (clobber (match_scratch:SF 3 ""))])]
15328 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15329 && flag_unsafe_math_optimizations"
15330 {
15331 rtx temp;
15332
15333 operands[2] = gen_reg_rtx (XFmode);
15334 temp = standard_80387_constant_rtx (4); /* fldln2 */
15335 emit_move_insn (operands[2], temp);
15336 })
15337
15338 (define_expand "logdf2"
15339 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15340 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15341 (match_dup 2)] UNSPEC_FYL2X))
15342 (clobber (match_scratch:DF 3 ""))])]
15343 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15344 && flag_unsafe_math_optimizations"
15345 {
15346 rtx temp;
15347
15348 operands[2] = gen_reg_rtx (XFmode);
15349 temp = standard_80387_constant_rtx (4); /* fldln2 */
15350 emit_move_insn (operands[2], temp);
15351 })
15352
15353 (define_expand "logxf2"
15354 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15355 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15356 (match_dup 2)] UNSPEC_FYL2X))
15357 (clobber (match_scratch:XF 3 ""))])]
15358 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15359 && flag_unsafe_math_optimizations"
15360 {
15361 rtx temp;
15362
15363 operands[2] = gen_reg_rtx (XFmode);
15364 temp = standard_80387_constant_rtx (4); /* fldln2 */
15365 emit_move_insn (operands[2], temp);
15366 })
15367
15368 (define_expand "log10sf2"
15369 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15370 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15371 (match_dup 2)] UNSPEC_FYL2X))
15372 (clobber (match_scratch:SF 3 ""))])]
15373 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15374 && flag_unsafe_math_optimizations"
15375 {
15376 rtx temp;
15377
15378 operands[2] = gen_reg_rtx (XFmode);
15379 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15380 emit_move_insn (operands[2], temp);
15381 })
15382
15383 (define_expand "log10df2"
15384 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15385 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15386 (match_dup 2)] UNSPEC_FYL2X))
15387 (clobber (match_scratch:DF 3 ""))])]
15388 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15389 && flag_unsafe_math_optimizations"
15390 {
15391 rtx temp;
15392
15393 operands[2] = gen_reg_rtx (XFmode);
15394 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15395 emit_move_insn (operands[2], temp);
15396 })
15397
15398 (define_expand "log10xf2"
15399 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15400 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15401 (match_dup 2)] UNSPEC_FYL2X))
15402 (clobber (match_scratch:XF 3 ""))])]
15403 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15404 && flag_unsafe_math_optimizations"
15405 {
15406 rtx temp;
15407
15408 operands[2] = gen_reg_rtx (XFmode);
15409 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15410 emit_move_insn (operands[2], temp);
15411 })
15412
15413 (define_expand "log2sf2"
15414 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15415 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15416 (match_dup 2)] UNSPEC_FYL2X))
15417 (clobber (match_scratch:SF 3 ""))])]
15418 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15419 && flag_unsafe_math_optimizations"
15420 {
15421 operands[2] = gen_reg_rtx (XFmode);
15422 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15423
15424 })
15425
15426 (define_expand "log2df2"
15427 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15428 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15429 (match_dup 2)] UNSPEC_FYL2X))
15430 (clobber (match_scratch:DF 3 ""))])]
15431 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15432 && flag_unsafe_math_optimizations"
15433 {
15434 operands[2] = gen_reg_rtx (XFmode);
15435 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15436 })
15437
15438 (define_expand "log2xf2"
15439 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15440 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15441 (match_dup 2)] UNSPEC_FYL2X))
15442 (clobber (match_scratch:XF 3 ""))])]
15443 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15444 && flag_unsafe_math_optimizations"
15445 {
15446 operands[2] = gen_reg_rtx (XFmode);
15447 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15448 })
15449
15450 (define_insn "*fxtractdf3"
15451 [(set (match_operand:DF 0 "register_operand" "=f")
15452 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15453 UNSPEC_XTRACT_FRACT))
15454 (set (match_operand:DF 1 "register_operand" "=u")
15455 (unspec:DF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15456 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15457 && flag_unsafe_math_optimizations"
15458 "fxtract"
15459 [(set_attr "type" "fpspc")
15460 (set_attr "mode" "DF")])
15461
15462 (define_expand "logbdf2"
15463 [(parallel [(set (match_dup 2)
15464 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15465 UNSPEC_XTRACT_FRACT))
15466 (set (match_operand:DF 0 "register_operand" "")
15467 (unspec:DF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15468 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15469 && flag_unsafe_math_optimizations"
15470 {
15471 operands[2] = gen_reg_rtx (DFmode);
15472 })
15473
15474 (define_insn "*fxtractsf3"
15475 [(set (match_operand:SF 0 "register_operand" "=f")
15476 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15477 UNSPEC_XTRACT_FRACT))
15478 (set (match_operand:SF 1 "register_operand" "=u")
15479 (unspec:SF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15480 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15481 && flag_unsafe_math_optimizations"
15482 "fxtract"
15483 [(set_attr "type" "fpspc")
15484 (set_attr "mode" "SF")])
15485
15486 (define_expand "logbsf2"
15487 [(parallel [(set (match_dup 2)
15488 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15489 UNSPEC_XTRACT_FRACT))
15490 (set (match_operand:SF 0 "register_operand" "")
15491 (unspec:SF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15492 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15493 && flag_unsafe_math_optimizations"
15494 {
15495 operands[2] = gen_reg_rtx (SFmode);
15496 })
15497
15498 (define_insn "*fxtractxf3"
15499 [(set (match_operand:XF 0 "register_operand" "=f")
15500 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15501 UNSPEC_XTRACT_FRACT))
15502 (set (match_operand:XF 1 "register_operand" "=u")
15503 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15504 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15505 && flag_unsafe_math_optimizations"
15506 "fxtract"
15507 [(set_attr "type" "fpspc")
15508 (set_attr "mode" "XF")])
15509
15510 (define_expand "logbxf2"
15511 [(parallel [(set (match_dup 2)
15512 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15513 UNSPEC_XTRACT_FRACT))
15514 (set (match_operand:XF 0 "register_operand" "")
15515 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15516 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15517 && flag_unsafe_math_optimizations"
15518 {
15519 operands[2] = gen_reg_rtx (XFmode);
15520 })
15521
15522 (define_expand "ilogbsi2"
15523 [(parallel [(set (match_dup 2)
15524 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15525 UNSPEC_XTRACT_FRACT))
15526 (set (match_operand:XF 3 "register_operand" "")
15527 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15528 (parallel [(set (match_operand:SI 0 "register_operand" "")
15529 (fix:SI (match_dup 3)))
15530 (clobber (reg:CC 17))])]
15531 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15532 && flag_unsafe_math_optimizations"
15533 {
15534 operands[2] = gen_reg_rtx (XFmode);
15535 operands[3] = gen_reg_rtx (XFmode);
15536 })
15537
15538 (define_insn "*fscale_sfxf3"
15539 [(set (match_operand:SF 0 "register_operand" "=f")
15540 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15541 (match_operand:XF 1 "register_operand" "u")]
15542 UNSPEC_FSCALE))
15543 (clobber (match_scratch:SF 3 "=1"))]
15544 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15545 && flag_unsafe_math_optimizations"
15546 "fscale\;fstp\t%y1"
15547 [(set_attr "type" "fpspc")
15548 (set_attr "mode" "SF")])
15549
15550 (define_insn "*fscale_dfxf3"
15551 [(set (match_operand:DF 0 "register_operand" "=f")
15552 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15553 (match_operand:XF 1 "register_operand" "u")]
15554 UNSPEC_FSCALE))
15555 (clobber (match_scratch:DF 3 "=1"))]
15556 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15557 && flag_unsafe_math_optimizations"
15558 "fscale\;fstp\t%y1"
15559 [(set_attr "type" "fpspc")
15560 (set_attr "mode" "DF")])
15561
15562 (define_insn "*fscale_xf3"
15563 [(set (match_operand:XF 0 "register_operand" "=f")
15564 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15565 (match_operand:XF 1 "register_operand" "u")]
15566 UNSPEC_FSCALE))
15567 (clobber (match_scratch:XF 3 "=1"))]
15568 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15569 && flag_unsafe_math_optimizations"
15570 "fscale\;fstp\t%y1"
15571 [(set_attr "type" "fpspc")
15572 (set_attr "mode" "XF")])
15573
15574 (define_insn "*frndintxf2"
15575 [(set (match_operand:XF 0 "register_operand" "=f")
15576 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15577 UNSPEC_FRNDINT))]
15578 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15579 && flag_unsafe_math_optimizations"
15580 "frndint"
15581 [(set_attr "type" "fpspc")
15582 (set_attr "mode" "XF")])
15583
15584 (define_insn "*f2xm1xf2"
15585 [(set (match_operand:XF 0 "register_operand" "=f")
15586 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15587 UNSPEC_F2XM1))]
15588 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15589 && flag_unsafe_math_optimizations"
15590 "f2xm1"
15591 [(set_attr "type" "fpspc")
15592 (set_attr "mode" "XF")])
15593
15594 (define_expand "expsf2"
15595 [(set (match_dup 2)
15596 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15597 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15598 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15599 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15600 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15601 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15602 (parallel [(set (match_operand:SF 0 "register_operand" "")
15603 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15604 (clobber (match_scratch:SF 5 ""))])]
15605 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15606 && flag_unsafe_math_optimizations"
15607 {
15608 rtx temp;
15609 int i;
15610
15611 for (i=2; i<10; i++)
15612 operands[i] = gen_reg_rtx (XFmode);
15613 temp = standard_80387_constant_rtx (5); /* fldl2e */
15614 emit_move_insn (operands[3], temp);
15615 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15616 })
15617
15618 (define_expand "expdf2"
15619 [(set (match_dup 2)
15620 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15621 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15622 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15623 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15624
15625 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15626 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15627 (parallel [(set (match_operand:DF 0 "register_operand" "")
15628 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15629 (clobber (match_scratch:DF 5 ""))])]
15630 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15631 && flag_unsafe_math_optimizations"
15632 {
15633 rtx temp;
15634 int i;
15635
15636 for (i=2; i<10; i++)
15637 operands[i] = gen_reg_rtx (XFmode);
15638 temp = standard_80387_constant_rtx (5); /* fldl2e */
15639 emit_move_insn (operands[3], temp);
15640 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15641 })
15642
15643 (define_expand "expxf2"
15644 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15645 (match_dup 2)))
15646 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15647 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15648 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15649 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15650 (parallel [(set (match_operand:XF 0 "register_operand" "")
15651 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15652 (clobber (match_scratch:XF 5 ""))])]
15653 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15654 && flag_unsafe_math_optimizations"
15655 {
15656 rtx temp;
15657 int i;
15658
15659 for (i=2; i<9; i++)
15660 operands[i] = gen_reg_rtx (XFmode);
15661 temp = standard_80387_constant_rtx (5); /* fldl2e */
15662 emit_move_insn (operands[2], temp);
15663 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15664 })
15665
15666 (define_expand "exp10sf2"
15667 [(set (match_dup 2)
15668 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15669 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15670 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15671 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15672 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15673 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15674 (parallel [(set (match_operand:SF 0 "register_operand" "")
15675 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15676 (clobber (match_scratch:SF 5 ""))])]
15677 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15678 && flag_unsafe_math_optimizations"
15679 {
15680 rtx temp;
15681 int i;
15682
15683 for (i=2; i<10; i++)
15684 operands[i] = gen_reg_rtx (XFmode);
15685 temp = standard_80387_constant_rtx (6); /* fldl2t */
15686 emit_move_insn (operands[3], temp);
15687 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15688 })
15689
15690 (define_expand "exp10df2"
15691 [(set (match_dup 2)
15692 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15693 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15694 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15695 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15696 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15697 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15698 (parallel [(set (match_operand:DF 0 "register_operand" "")
15699 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15700 (clobber (match_scratch:DF 5 ""))])]
15701 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15702 && flag_unsafe_math_optimizations"
15703 {
15704 rtx temp;
15705 int i;
15706
15707 for (i=2; i<10; i++)
15708 operands[i] = gen_reg_rtx (XFmode);
15709 temp = standard_80387_constant_rtx (6); /* fldl2t */
15710 emit_move_insn (operands[3], temp);
15711 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15712 })
15713
15714 (define_expand "exp10xf2"
15715 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15716 (match_dup 2)))
15717 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15718 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15719 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15720 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15721 (parallel [(set (match_operand:XF 0 "register_operand" "")
15722 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15723 (clobber (match_scratch:XF 5 ""))])]
15724 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15725 && flag_unsafe_math_optimizations"
15726 {
15727 rtx temp;
15728 int i;
15729
15730 for (i=2; i<9; i++)
15731 operands[i] = gen_reg_rtx (XFmode);
15732 temp = standard_80387_constant_rtx (6); /* fldl2t */
15733 emit_move_insn (operands[2], temp);
15734 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15735 })
15736
15737 (define_expand "exp2sf2"
15738 [(set (match_dup 2)
15739 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15740 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15741 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15742 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15743 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15744 (parallel [(set (match_operand:SF 0 "register_operand" "")
15745 (unspec:SF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15746 (clobber (match_scratch:SF 3 ""))])]
15747 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15748 && flag_unsafe_math_optimizations"
15749 {
15750 int i;
15751
15752 for (i=2; i<8; i++)
15753 operands[i] = gen_reg_rtx (XFmode);
15754 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15755 })
15756
15757 (define_expand "exp2df2"
15758 [(set (match_dup 2)
15759 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15760 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15761 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15762 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15763 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15764 (parallel [(set (match_operand:DF 0 "register_operand" "")
15765 (unspec:DF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15766 (clobber (match_scratch:DF 3 ""))])]
15767 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15768 && flag_unsafe_math_optimizations"
15769 {
15770 int i;
15771
15772 for (i=2; i<8; i++)
15773 operands[i] = gen_reg_rtx (XFmode);
15774 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15775 })
15776
15777 (define_expand "exp2xf2"
15778 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15779 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15780 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15781 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15782 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15783 (parallel [(set (match_operand:XF 0 "register_operand" "")
15784 (unspec:XF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15785 (clobber (match_scratch:XF 3 ""))])]
15786 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15787 && flag_unsafe_math_optimizations"
15788 {
15789 int i;
15790
15791 for (i=2; i<8; i++)
15792 operands[i] = gen_reg_rtx (XFmode);
15793 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15794 })
15795
15796 (define_expand "atansf2"
15797 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15798 (unspec:SF [(match_dup 2)
15799 (match_operand:SF 1 "register_operand" "")]
15800 UNSPEC_FPATAN))
15801 (clobber (match_scratch:SF 3 ""))])]
15802 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15803 && flag_unsafe_math_optimizations"
15804 {
15805 operands[2] = gen_reg_rtx (SFmode);
15806 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15807 })
15808
15809 (define_expand "atandf2"
15810 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15811 (unspec:DF [(match_dup 2)
15812 (match_operand:DF 1 "register_operand" "")]
15813 UNSPEC_FPATAN))
15814 (clobber (match_scratch:DF 3 ""))])]
15815 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15816 && flag_unsafe_math_optimizations"
15817 {
15818 operands[2] = gen_reg_rtx (DFmode);
15819 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15820 })
15821
15822 (define_expand "atanxf2"
15823 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15824 (unspec:XF [(match_dup 2)
15825 (match_operand:XF 1 "register_operand" "")]
15826 UNSPEC_FPATAN))
15827 (clobber (match_scratch:XF 3 ""))])]
15828 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15829 && flag_unsafe_math_optimizations"
15830 {
15831 operands[2] = gen_reg_rtx (XFmode);
15832 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15833 })
15834 \f
15835 ;; Block operation instructions
15836
15837 (define_insn "cld"
15838 [(set (reg:SI 19) (const_int 0))]
15839 ""
15840 "cld"
15841 [(set_attr "type" "cld")])
15842
15843 (define_expand "movstrsi"
15844 [(use (match_operand:BLK 0 "memory_operand" ""))
15845 (use (match_operand:BLK 1 "memory_operand" ""))
15846 (use (match_operand:SI 2 "nonmemory_operand" ""))
15847 (use (match_operand:SI 3 "const_int_operand" ""))]
15848 "! optimize_size"
15849 {
15850 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15851 DONE;
15852 else
15853 FAIL;
15854 })
15855
15856 (define_expand "movstrdi"
15857 [(use (match_operand:BLK 0 "memory_operand" ""))
15858 (use (match_operand:BLK 1 "memory_operand" ""))
15859 (use (match_operand:DI 2 "nonmemory_operand" ""))
15860 (use (match_operand:DI 3 "const_int_operand" ""))]
15861 "TARGET_64BIT"
15862 {
15863 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15864 DONE;
15865 else
15866 FAIL;
15867 })
15868
15869 ;; Most CPUs don't like single string operations
15870 ;; Handle this case here to simplify previous expander.
15871
15872 (define_expand "strmov"
15873 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15874 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15875 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15876 (clobber (reg:CC 17))])
15877 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15878 (clobber (reg:CC 17))])]
15879 ""
15880 {
15881 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15882
15883 /* If .md ever supports :P for Pmode, these can be directly
15884 in the pattern above. */
15885 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15886 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15887
15888 if (TARGET_SINGLE_STRINGOP || optimize_size)
15889 {
15890 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15891 operands[2], operands[3],
15892 operands[5], operands[6]));
15893 DONE;
15894 }
15895
15896 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15897 })
15898
15899 (define_expand "strmov_singleop"
15900 [(parallel [(set (match_operand 1 "memory_operand" "")
15901 (match_operand 3 "memory_operand" ""))
15902 (set (match_operand 0 "register_operand" "")
15903 (match_operand 4 "" ""))
15904 (set (match_operand 2 "register_operand" "")
15905 (match_operand 5 "" ""))
15906 (use (reg:SI 19))])]
15907 "TARGET_SINGLE_STRINGOP || optimize_size"
15908 "")
15909
15910 (define_insn "*strmovdi_rex_1"
15911 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15912 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15913 (set (match_operand:DI 0 "register_operand" "=D")
15914 (plus:DI (match_dup 2)
15915 (const_int 8)))
15916 (set (match_operand:DI 1 "register_operand" "=S")
15917 (plus:DI (match_dup 3)
15918 (const_int 8)))
15919 (use (reg:SI 19))]
15920 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15921 "movsq"
15922 [(set_attr "type" "str")
15923 (set_attr "mode" "DI")
15924 (set_attr "memory" "both")])
15925
15926 (define_insn "*strmovsi_1"
15927 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15928 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15929 (set (match_operand:SI 0 "register_operand" "=D")
15930 (plus:SI (match_dup 2)
15931 (const_int 4)))
15932 (set (match_operand:SI 1 "register_operand" "=S")
15933 (plus:SI (match_dup 3)
15934 (const_int 4)))
15935 (use (reg:SI 19))]
15936 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15937 "{movsl|movsd}"
15938 [(set_attr "type" "str")
15939 (set_attr "mode" "SI")
15940 (set_attr "memory" "both")])
15941
15942 (define_insn "*strmovsi_rex_1"
15943 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15944 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15945 (set (match_operand:DI 0 "register_operand" "=D")
15946 (plus:DI (match_dup 2)
15947 (const_int 4)))
15948 (set (match_operand:DI 1 "register_operand" "=S")
15949 (plus:DI (match_dup 3)
15950 (const_int 4)))
15951 (use (reg:SI 19))]
15952 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15953 "{movsl|movsd}"
15954 [(set_attr "type" "str")
15955 (set_attr "mode" "SI")
15956 (set_attr "memory" "both")])
15957
15958 (define_insn "*strmovhi_1"
15959 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15960 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15961 (set (match_operand:SI 0 "register_operand" "=D")
15962 (plus:SI (match_dup 2)
15963 (const_int 2)))
15964 (set (match_operand:SI 1 "register_operand" "=S")
15965 (plus:SI (match_dup 3)
15966 (const_int 2)))
15967 (use (reg:SI 19))]
15968 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15969 "movsw"
15970 [(set_attr "type" "str")
15971 (set_attr "memory" "both")
15972 (set_attr "mode" "HI")])
15973
15974 (define_insn "*strmovhi_rex_1"
15975 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15976 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15977 (set (match_operand:DI 0 "register_operand" "=D")
15978 (plus:DI (match_dup 2)
15979 (const_int 2)))
15980 (set (match_operand:DI 1 "register_operand" "=S")
15981 (plus:DI (match_dup 3)
15982 (const_int 2)))
15983 (use (reg:SI 19))]
15984 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15985 "movsw"
15986 [(set_attr "type" "str")
15987 (set_attr "memory" "both")
15988 (set_attr "mode" "HI")])
15989
15990 (define_insn "*strmovqi_1"
15991 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15992 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15993 (set (match_operand:SI 0 "register_operand" "=D")
15994 (plus:SI (match_dup 2)
15995 (const_int 1)))
15996 (set (match_operand:SI 1 "register_operand" "=S")
15997 (plus:SI (match_dup 3)
15998 (const_int 1)))
15999 (use (reg:SI 19))]
16000 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16001 "movsb"
16002 [(set_attr "type" "str")
16003 (set_attr "memory" "both")
16004 (set_attr "mode" "QI")])
16005
16006 (define_insn "*strmovqi_rex_1"
16007 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16008 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16009 (set (match_operand:DI 0 "register_operand" "=D")
16010 (plus:DI (match_dup 2)
16011 (const_int 1)))
16012 (set (match_operand:DI 1 "register_operand" "=S")
16013 (plus:DI (match_dup 3)
16014 (const_int 1)))
16015 (use (reg:SI 19))]
16016 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16017 "movsb"
16018 [(set_attr "type" "str")
16019 (set_attr "memory" "both")
16020 (set_attr "mode" "QI")])
16021
16022 (define_expand "rep_mov"
16023 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16024 (set (match_operand 0 "register_operand" "")
16025 (match_operand 5 "" ""))
16026 (set (match_operand 2 "register_operand" "")
16027 (match_operand 6 "" ""))
16028 (set (match_operand 1 "memory_operand" "")
16029 (match_operand 3 "memory_operand" ""))
16030 (use (match_dup 4))
16031 (use (reg:SI 19))])]
16032 ""
16033 "")
16034
16035 (define_insn "*rep_movdi_rex64"
16036 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16037 (set (match_operand:DI 0 "register_operand" "=D")
16038 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16039 (const_int 3))
16040 (match_operand:DI 3 "register_operand" "0")))
16041 (set (match_operand:DI 1 "register_operand" "=S")
16042 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16043 (match_operand:DI 4 "register_operand" "1")))
16044 (set (mem:BLK (match_dup 3))
16045 (mem:BLK (match_dup 4)))
16046 (use (match_dup 5))
16047 (use (reg:SI 19))]
16048 "TARGET_64BIT"
16049 "{rep\;movsq|rep movsq}"
16050 [(set_attr "type" "str")
16051 (set_attr "prefix_rep" "1")
16052 (set_attr "memory" "both")
16053 (set_attr "mode" "DI")])
16054
16055 (define_insn "*rep_movsi"
16056 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16057 (set (match_operand:SI 0 "register_operand" "=D")
16058 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16059 (const_int 2))
16060 (match_operand:SI 3 "register_operand" "0")))
16061 (set (match_operand:SI 1 "register_operand" "=S")
16062 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16063 (match_operand:SI 4 "register_operand" "1")))
16064 (set (mem:BLK (match_dup 3))
16065 (mem:BLK (match_dup 4)))
16066 (use (match_dup 5))
16067 (use (reg:SI 19))]
16068 "!TARGET_64BIT"
16069 "{rep\;movsl|rep movsd}"
16070 [(set_attr "type" "str")
16071 (set_attr "prefix_rep" "1")
16072 (set_attr "memory" "both")
16073 (set_attr "mode" "SI")])
16074
16075 (define_insn "*rep_movsi_rex64"
16076 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16077 (set (match_operand:DI 0 "register_operand" "=D")
16078 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16079 (const_int 2))
16080 (match_operand:DI 3 "register_operand" "0")))
16081 (set (match_operand:DI 1 "register_operand" "=S")
16082 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16083 (match_operand:DI 4 "register_operand" "1")))
16084 (set (mem:BLK (match_dup 3))
16085 (mem:BLK (match_dup 4)))
16086 (use (match_dup 5))
16087 (use (reg:SI 19))]
16088 "TARGET_64BIT"
16089 "{rep\;movsl|rep movsd}"
16090 [(set_attr "type" "str")
16091 (set_attr "prefix_rep" "1")
16092 (set_attr "memory" "both")
16093 (set_attr "mode" "SI")])
16094
16095 (define_insn "*rep_movqi"
16096 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16097 (set (match_operand:SI 0 "register_operand" "=D")
16098 (plus:SI (match_operand:SI 3 "register_operand" "0")
16099 (match_operand:SI 5 "register_operand" "2")))
16100 (set (match_operand:SI 1 "register_operand" "=S")
16101 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16102 (set (mem:BLK (match_dup 3))
16103 (mem:BLK (match_dup 4)))
16104 (use (match_dup 5))
16105 (use (reg:SI 19))]
16106 "!TARGET_64BIT"
16107 "{rep\;movsb|rep movsb}"
16108 [(set_attr "type" "str")
16109 (set_attr "prefix_rep" "1")
16110 (set_attr "memory" "both")
16111 (set_attr "mode" "SI")])
16112
16113 (define_insn "*rep_movqi_rex64"
16114 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16115 (set (match_operand:DI 0 "register_operand" "=D")
16116 (plus:DI (match_operand:DI 3 "register_operand" "0")
16117 (match_operand:DI 5 "register_operand" "2")))
16118 (set (match_operand:DI 1 "register_operand" "=S")
16119 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16120 (set (mem:BLK (match_dup 3))
16121 (mem:BLK (match_dup 4)))
16122 (use (match_dup 5))
16123 (use (reg:SI 19))]
16124 "TARGET_64BIT"
16125 "{rep\;movsb|rep movsb}"
16126 [(set_attr "type" "str")
16127 (set_attr "prefix_rep" "1")
16128 (set_attr "memory" "both")
16129 (set_attr "mode" "SI")])
16130
16131 (define_expand "clrstrsi"
16132 [(use (match_operand:BLK 0 "memory_operand" ""))
16133 (use (match_operand:SI 1 "nonmemory_operand" ""))
16134 (use (match_operand 2 "const_int_operand" ""))]
16135 ""
16136 {
16137 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16138 DONE;
16139 else
16140 FAIL;
16141 })
16142
16143 (define_expand "clrstrdi"
16144 [(use (match_operand:BLK 0 "memory_operand" ""))
16145 (use (match_operand:DI 1 "nonmemory_operand" ""))
16146 (use (match_operand 2 "const_int_operand" ""))]
16147 "TARGET_64BIT"
16148 {
16149 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16150 DONE;
16151 else
16152 FAIL;
16153 })
16154
16155 ;; Most CPUs don't like single string operations
16156 ;; Handle this case here to simplify previous expander.
16157
16158 (define_expand "strset"
16159 [(set (match_operand 1 "memory_operand" "")
16160 (match_operand 2 "register_operand" ""))
16161 (parallel [(set (match_operand 0 "register_operand" "")
16162 (match_dup 3))
16163 (clobber (reg:CC 17))])]
16164 ""
16165 {
16166 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16167 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16168
16169 /* If .md ever supports :P for Pmode, this can be directly
16170 in the pattern above. */
16171 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16172 GEN_INT (GET_MODE_SIZE (GET_MODE
16173 (operands[2]))));
16174 if (TARGET_SINGLE_STRINGOP || optimize_size)
16175 {
16176 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16177 operands[3]));
16178 DONE;
16179 }
16180 })
16181
16182 (define_expand "strset_singleop"
16183 [(parallel [(set (match_operand 1 "memory_operand" "")
16184 (match_operand 2 "register_operand" ""))
16185 (set (match_operand 0 "register_operand" "")
16186 (match_operand 3 "" ""))
16187 (use (reg:SI 19))])]
16188 "TARGET_SINGLE_STRINGOP || optimize_size"
16189 "")
16190
16191 (define_insn "*strsetdi_rex_1"
16192 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16193 (match_operand:SI 2 "register_operand" "a"))
16194 (set (match_operand:DI 0 "register_operand" "=D")
16195 (plus:DI (match_dup 1)
16196 (const_int 8)))
16197 (use (reg:SI 19))]
16198 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16199 "stosq"
16200 [(set_attr "type" "str")
16201 (set_attr "memory" "store")
16202 (set_attr "mode" "DI")])
16203
16204 (define_insn "*strsetsi_1"
16205 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16206 (match_operand:SI 2 "register_operand" "a"))
16207 (set (match_operand:SI 0 "register_operand" "=D")
16208 (plus:SI (match_dup 1)
16209 (const_int 4)))
16210 (use (reg:SI 19))]
16211 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16212 "{stosl|stosd}"
16213 [(set_attr "type" "str")
16214 (set_attr "memory" "store")
16215 (set_attr "mode" "SI")])
16216
16217 (define_insn "*strsetsi_rex_1"
16218 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16219 (match_operand:SI 2 "register_operand" "a"))
16220 (set (match_operand:DI 0 "register_operand" "=D")
16221 (plus:DI (match_dup 1)
16222 (const_int 4)))
16223 (use (reg:SI 19))]
16224 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16225 "{stosl|stosd}"
16226 [(set_attr "type" "str")
16227 (set_attr "memory" "store")
16228 (set_attr "mode" "SI")])
16229
16230 (define_insn "*strsethi_1"
16231 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16232 (match_operand:HI 2 "register_operand" "a"))
16233 (set (match_operand:SI 0 "register_operand" "=D")
16234 (plus:SI (match_dup 1)
16235 (const_int 2)))
16236 (use (reg:SI 19))]
16237 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16238 "stosw"
16239 [(set_attr "type" "str")
16240 (set_attr "memory" "store")
16241 (set_attr "mode" "HI")])
16242
16243 (define_insn "*strsethi_rex_1"
16244 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16245 (match_operand:HI 2 "register_operand" "a"))
16246 (set (match_operand:DI 0 "register_operand" "=D")
16247 (plus:DI (match_dup 1)
16248 (const_int 2)))
16249 (use (reg:SI 19))]
16250 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16251 "stosw"
16252 [(set_attr "type" "str")
16253 (set_attr "memory" "store")
16254 (set_attr "mode" "HI")])
16255
16256 (define_insn "*strsetqi_1"
16257 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16258 (match_operand:QI 2 "register_operand" "a"))
16259 (set (match_operand:SI 0 "register_operand" "=D")
16260 (plus:SI (match_dup 1)
16261 (const_int 1)))
16262 (use (reg:SI 19))]
16263 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16264 "stosb"
16265 [(set_attr "type" "str")
16266 (set_attr "memory" "store")
16267 (set_attr "mode" "QI")])
16268
16269 (define_insn "*strsetqi_rex_1"
16270 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16271 (match_operand:QI 2 "register_operand" "a"))
16272 (set (match_operand:DI 0 "register_operand" "=D")
16273 (plus:DI (match_dup 1)
16274 (const_int 1)))
16275 (use (reg:SI 19))]
16276 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16277 "stosb"
16278 [(set_attr "type" "str")
16279 (set_attr "memory" "store")
16280 (set_attr "mode" "QI")])
16281
16282 (define_expand "rep_stos"
16283 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16284 (set (match_operand 0 "register_operand" "")
16285 (match_operand 4 "" ""))
16286 (set (match_operand 2 "memory_operand" "") (const_int 0))
16287 (use (match_operand 3 "register_operand" ""))
16288 (use (match_dup 1))
16289 (use (reg:SI 19))])]
16290 ""
16291 "")
16292
16293 (define_insn "*rep_stosdi_rex64"
16294 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16295 (set (match_operand:DI 0 "register_operand" "=D")
16296 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16297 (const_int 3))
16298 (match_operand:DI 3 "register_operand" "0")))
16299 (set (mem:BLK (match_dup 3))
16300 (const_int 0))
16301 (use (match_operand:DI 2 "register_operand" "a"))
16302 (use (match_dup 4))
16303 (use (reg:SI 19))]
16304 "TARGET_64BIT"
16305 "{rep\;stosq|rep stosq}"
16306 [(set_attr "type" "str")
16307 (set_attr "prefix_rep" "1")
16308 (set_attr "memory" "store")
16309 (set_attr "mode" "DI")])
16310
16311 (define_insn "*rep_stossi"
16312 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16313 (set (match_operand:SI 0 "register_operand" "=D")
16314 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16315 (const_int 2))
16316 (match_operand:SI 3 "register_operand" "0")))
16317 (set (mem:BLK (match_dup 3))
16318 (const_int 0))
16319 (use (match_operand:SI 2 "register_operand" "a"))
16320 (use (match_dup 4))
16321 (use (reg:SI 19))]
16322 "!TARGET_64BIT"
16323 "{rep\;stosl|rep stosd}"
16324 [(set_attr "type" "str")
16325 (set_attr "prefix_rep" "1")
16326 (set_attr "memory" "store")
16327 (set_attr "mode" "SI")])
16328
16329 (define_insn "*rep_stossi_rex64"
16330 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16331 (set (match_operand:DI 0 "register_operand" "=D")
16332 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16333 (const_int 2))
16334 (match_operand:DI 3 "register_operand" "0")))
16335 (set (mem:BLK (match_dup 3))
16336 (const_int 0))
16337 (use (match_operand:SI 2 "register_operand" "a"))
16338 (use (match_dup 4))
16339 (use (reg:SI 19))]
16340 "TARGET_64BIT"
16341 "{rep\;stosl|rep stosd}"
16342 [(set_attr "type" "str")
16343 (set_attr "prefix_rep" "1")
16344 (set_attr "memory" "store")
16345 (set_attr "mode" "SI")])
16346
16347 (define_insn "*rep_stosqi"
16348 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16349 (set (match_operand:SI 0 "register_operand" "=D")
16350 (plus:SI (match_operand:SI 3 "register_operand" "0")
16351 (match_operand:SI 4 "register_operand" "1")))
16352 (set (mem:BLK (match_dup 3))
16353 (const_int 0))
16354 (use (match_operand:QI 2 "register_operand" "a"))
16355 (use (match_dup 4))
16356 (use (reg:SI 19))]
16357 "!TARGET_64BIT"
16358 "{rep\;stosb|rep stosb}"
16359 [(set_attr "type" "str")
16360 (set_attr "prefix_rep" "1")
16361 (set_attr "memory" "store")
16362 (set_attr "mode" "QI")])
16363
16364 (define_insn "*rep_stosqi_rex64"
16365 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16366 (set (match_operand:DI 0 "register_operand" "=D")
16367 (plus:DI (match_operand:DI 3 "register_operand" "0")
16368 (match_operand:DI 4 "register_operand" "1")))
16369 (set (mem:BLK (match_dup 3))
16370 (const_int 0))
16371 (use (match_operand:QI 2 "register_operand" "a"))
16372 (use (match_dup 4))
16373 (use (reg:SI 19))]
16374 "TARGET_64BIT"
16375 "{rep\;stosb|rep stosb}"
16376 [(set_attr "type" "str")
16377 (set_attr "prefix_rep" "1")
16378 (set_attr "memory" "store")
16379 (set_attr "mode" "QI")])
16380
16381 (define_expand "cmpstrsi"
16382 [(set (match_operand:SI 0 "register_operand" "")
16383 (compare:SI (match_operand:BLK 1 "general_operand" "")
16384 (match_operand:BLK 2 "general_operand" "")))
16385 (use (match_operand 3 "general_operand" ""))
16386 (use (match_operand 4 "immediate_operand" ""))]
16387 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16388 {
16389 rtx addr1, addr2, out, outlow, count, countreg, align;
16390
16391 /* Can't use this if the user has appropriated esi or edi. */
16392 if (global_regs[4] || global_regs[5])
16393 FAIL;
16394
16395 out = operands[0];
16396 if (GET_CODE (out) != REG)
16397 out = gen_reg_rtx (SImode);
16398
16399 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16400 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16401 if (addr1 != XEXP (operands[1], 0))
16402 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16403 if (addr2 != XEXP (operands[2], 0))
16404 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16405
16406 count = operands[3];
16407 countreg = ix86_zero_extend_to_Pmode (count);
16408
16409 /* %%% Iff we are testing strict equality, we can use known alignment
16410 to good advantage. This may be possible with combine, particularly
16411 once cc0 is dead. */
16412 align = operands[4];
16413
16414 emit_insn (gen_cld ());
16415 if (GET_CODE (count) == CONST_INT)
16416 {
16417 if (INTVAL (count) == 0)
16418 {
16419 emit_move_insn (operands[0], const0_rtx);
16420 DONE;
16421 }
16422 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16423 operands[1], operands[2]));
16424 }
16425 else
16426 {
16427 if (TARGET_64BIT)
16428 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16429 else
16430 emit_insn (gen_cmpsi_1 (countreg, countreg));
16431 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16432 operands[1], operands[2]));
16433 }
16434
16435 outlow = gen_lowpart (QImode, out);
16436 emit_insn (gen_cmpintqi (outlow));
16437 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16438
16439 if (operands[0] != out)
16440 emit_move_insn (operands[0], out);
16441
16442 DONE;
16443 })
16444
16445 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16446
16447 (define_expand "cmpintqi"
16448 [(set (match_dup 1)
16449 (gtu:QI (reg:CC 17) (const_int 0)))
16450 (set (match_dup 2)
16451 (ltu:QI (reg:CC 17) (const_int 0)))
16452 (parallel [(set (match_operand:QI 0 "register_operand" "")
16453 (minus:QI (match_dup 1)
16454 (match_dup 2)))
16455 (clobber (reg:CC 17))])]
16456 ""
16457 "operands[1] = gen_reg_rtx (QImode);
16458 operands[2] = gen_reg_rtx (QImode);")
16459
16460 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16461 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16462
16463 (define_expand "cmpstrqi_nz_1"
16464 [(parallel [(set (reg:CC 17)
16465 (compare:CC (match_operand 4 "memory_operand" "")
16466 (match_operand 5 "memory_operand" "")))
16467 (use (match_operand 2 "register_operand" ""))
16468 (use (match_operand:SI 3 "immediate_operand" ""))
16469 (use (reg:SI 19))
16470 (clobber (match_operand 0 "register_operand" ""))
16471 (clobber (match_operand 1 "register_operand" ""))
16472 (clobber (match_dup 2))])]
16473 ""
16474 "")
16475
16476 (define_insn "*cmpstrqi_nz_1"
16477 [(set (reg:CC 17)
16478 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16479 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16480 (use (match_operand:SI 6 "register_operand" "2"))
16481 (use (match_operand:SI 3 "immediate_operand" "i"))
16482 (use (reg:SI 19))
16483 (clobber (match_operand:SI 0 "register_operand" "=S"))
16484 (clobber (match_operand:SI 1 "register_operand" "=D"))
16485 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16486 "!TARGET_64BIT"
16487 "repz{\;| }cmpsb"
16488 [(set_attr "type" "str")
16489 (set_attr "mode" "QI")
16490 (set_attr "prefix_rep" "1")])
16491
16492 (define_insn "*cmpstrqi_nz_rex_1"
16493 [(set (reg:CC 17)
16494 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16495 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16496 (use (match_operand:DI 6 "register_operand" "2"))
16497 (use (match_operand:SI 3 "immediate_operand" "i"))
16498 (use (reg:SI 19))
16499 (clobber (match_operand:DI 0 "register_operand" "=S"))
16500 (clobber (match_operand:DI 1 "register_operand" "=D"))
16501 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16502 "TARGET_64BIT"
16503 "repz{\;| }cmpsb"
16504 [(set_attr "type" "str")
16505 (set_attr "mode" "QI")
16506 (set_attr "prefix_rep" "1")])
16507
16508 ;; The same, but the count is not known to not be zero.
16509
16510 (define_expand "cmpstrqi_1"
16511 [(parallel [(set (reg:CC 17)
16512 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16513 (const_int 0))
16514 (compare:CC (match_operand 4 "memory_operand" "")
16515 (match_operand 5 "memory_operand" ""))
16516 (const_int 0)))
16517 (use (match_operand:SI 3 "immediate_operand" ""))
16518 (use (reg:CC 17))
16519 (use (reg:SI 19))
16520 (clobber (match_operand 0 "register_operand" ""))
16521 (clobber (match_operand 1 "register_operand" ""))
16522 (clobber (match_dup 2))])]
16523 ""
16524 "")
16525
16526 (define_insn "*cmpstrqi_1"
16527 [(set (reg:CC 17)
16528 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16529 (const_int 0))
16530 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16531 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16532 (const_int 0)))
16533 (use (match_operand:SI 3 "immediate_operand" "i"))
16534 (use (reg:CC 17))
16535 (use (reg:SI 19))
16536 (clobber (match_operand:SI 0 "register_operand" "=S"))
16537 (clobber (match_operand:SI 1 "register_operand" "=D"))
16538 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16539 "!TARGET_64BIT"
16540 "repz{\;| }cmpsb"
16541 [(set_attr "type" "str")
16542 (set_attr "mode" "QI")
16543 (set_attr "prefix_rep" "1")])
16544
16545 (define_insn "*cmpstrqi_rex_1"
16546 [(set (reg:CC 17)
16547 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16548 (const_int 0))
16549 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16550 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16551 (const_int 0)))
16552 (use (match_operand:SI 3 "immediate_operand" "i"))
16553 (use (reg:CC 17))
16554 (use (reg:SI 19))
16555 (clobber (match_operand:DI 0 "register_operand" "=S"))
16556 (clobber (match_operand:DI 1 "register_operand" "=D"))
16557 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16558 "TARGET_64BIT"
16559 "repz{\;| }cmpsb"
16560 [(set_attr "type" "str")
16561 (set_attr "mode" "QI")
16562 (set_attr "prefix_rep" "1")])
16563
16564 (define_expand "strlensi"
16565 [(set (match_operand:SI 0 "register_operand" "")
16566 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16567 (match_operand:QI 2 "immediate_operand" "")
16568 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16569 ""
16570 {
16571 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16572 DONE;
16573 else
16574 FAIL;
16575 })
16576
16577 (define_expand "strlendi"
16578 [(set (match_operand:DI 0 "register_operand" "")
16579 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16580 (match_operand:QI 2 "immediate_operand" "")
16581 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16582 ""
16583 {
16584 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16585 DONE;
16586 else
16587 FAIL;
16588 })
16589
16590 (define_expand "strlenqi_1"
16591 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16592 (use (reg:SI 19))
16593 (clobber (match_operand 1 "register_operand" ""))
16594 (clobber (reg:CC 17))])]
16595 ""
16596 "")
16597
16598 (define_insn "*strlenqi_1"
16599 [(set (match_operand:SI 0 "register_operand" "=&c")
16600 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16601 (match_operand:QI 2 "register_operand" "a")
16602 (match_operand:SI 3 "immediate_operand" "i")
16603 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16604 (use (reg:SI 19))
16605 (clobber (match_operand:SI 1 "register_operand" "=D"))
16606 (clobber (reg:CC 17))]
16607 "!TARGET_64BIT"
16608 "repnz{\;| }scasb"
16609 [(set_attr "type" "str")
16610 (set_attr "mode" "QI")
16611 (set_attr "prefix_rep" "1")])
16612
16613 (define_insn "*strlenqi_rex_1"
16614 [(set (match_operand:DI 0 "register_operand" "=&c")
16615 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16616 (match_operand:QI 2 "register_operand" "a")
16617 (match_operand:DI 3 "immediate_operand" "i")
16618 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16619 (use (reg:SI 19))
16620 (clobber (match_operand:DI 1 "register_operand" "=D"))
16621 (clobber (reg:CC 17))]
16622 "TARGET_64BIT"
16623 "repnz{\;| }scasb"
16624 [(set_attr "type" "str")
16625 (set_attr "mode" "QI")
16626 (set_attr "prefix_rep" "1")])
16627
16628 ;; Peephole optimizations to clean up after cmpstr*. This should be
16629 ;; handled in combine, but it is not currently up to the task.
16630 ;; When used for their truth value, the cmpstr* expanders generate
16631 ;; code like this:
16632 ;;
16633 ;; repz cmpsb
16634 ;; seta %al
16635 ;; setb %dl
16636 ;; cmpb %al, %dl
16637 ;; jcc label
16638 ;;
16639 ;; The intermediate three instructions are unnecessary.
16640
16641 ;; This one handles cmpstr*_nz_1...
16642 (define_peephole2
16643 [(parallel[
16644 (set (reg:CC 17)
16645 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16646 (mem:BLK (match_operand 5 "register_operand" ""))))
16647 (use (match_operand 6 "register_operand" ""))
16648 (use (match_operand:SI 3 "immediate_operand" ""))
16649 (use (reg:SI 19))
16650 (clobber (match_operand 0 "register_operand" ""))
16651 (clobber (match_operand 1 "register_operand" ""))
16652 (clobber (match_operand 2 "register_operand" ""))])
16653 (set (match_operand:QI 7 "register_operand" "")
16654 (gtu:QI (reg:CC 17) (const_int 0)))
16655 (set (match_operand:QI 8 "register_operand" "")
16656 (ltu:QI (reg:CC 17) (const_int 0)))
16657 (set (reg 17)
16658 (compare (match_dup 7) (match_dup 8)))
16659 ]
16660 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16661 [(parallel[
16662 (set (reg:CC 17)
16663 (compare:CC (mem:BLK (match_dup 4))
16664 (mem:BLK (match_dup 5))))
16665 (use (match_dup 6))
16666 (use (match_dup 3))
16667 (use (reg:SI 19))
16668 (clobber (match_dup 0))
16669 (clobber (match_dup 1))
16670 (clobber (match_dup 2))])]
16671 "")
16672
16673 ;; ...and this one handles cmpstr*_1.
16674 (define_peephole2
16675 [(parallel[
16676 (set (reg:CC 17)
16677 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16678 (const_int 0))
16679 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16680 (mem:BLK (match_operand 5 "register_operand" "")))
16681 (const_int 0)))
16682 (use (match_operand:SI 3 "immediate_operand" ""))
16683 (use (reg:CC 17))
16684 (use (reg:SI 19))
16685 (clobber (match_operand 0 "register_operand" ""))
16686 (clobber (match_operand 1 "register_operand" ""))
16687 (clobber (match_operand 2 "register_operand" ""))])
16688 (set (match_operand:QI 7 "register_operand" "")
16689 (gtu:QI (reg:CC 17) (const_int 0)))
16690 (set (match_operand:QI 8 "register_operand" "")
16691 (ltu:QI (reg:CC 17) (const_int 0)))
16692 (set (reg 17)
16693 (compare (match_dup 7) (match_dup 8)))
16694 ]
16695 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16696 [(parallel[
16697 (set (reg:CC 17)
16698 (if_then_else:CC (ne (match_dup 6)
16699 (const_int 0))
16700 (compare:CC (mem:BLK (match_dup 4))
16701 (mem:BLK (match_dup 5)))
16702 (const_int 0)))
16703 (use (match_dup 3))
16704 (use (reg:CC 17))
16705 (use (reg:SI 19))
16706 (clobber (match_dup 0))
16707 (clobber (match_dup 1))
16708 (clobber (match_dup 2))])]
16709 "")
16710
16711
16712 \f
16713 ;; Conditional move instructions.
16714
16715 (define_expand "movdicc"
16716 [(set (match_operand:DI 0 "register_operand" "")
16717 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16718 (match_operand:DI 2 "general_operand" "")
16719 (match_operand:DI 3 "general_operand" "")))]
16720 "TARGET_64BIT"
16721 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16722
16723 (define_insn "x86_movdicc_0_m1_rex64"
16724 [(set (match_operand:DI 0 "register_operand" "=r")
16725 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16726 (const_int -1)
16727 (const_int 0)))
16728 (clobber (reg:CC 17))]
16729 "TARGET_64BIT"
16730 "sbb{q}\t%0, %0"
16731 ; Since we don't have the proper number of operands for an alu insn,
16732 ; fill in all the blanks.
16733 [(set_attr "type" "alu")
16734 (set_attr "pent_pair" "pu")
16735 (set_attr "memory" "none")
16736 (set_attr "imm_disp" "false")
16737 (set_attr "mode" "DI")
16738 (set_attr "length_immediate" "0")])
16739
16740 (define_insn "movdicc_c_rex64"
16741 [(set (match_operand:DI 0 "register_operand" "=r,r")
16742 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16743 [(reg 17) (const_int 0)])
16744 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16745 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16746 "TARGET_64BIT && TARGET_CMOVE
16747 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16748 "@
16749 cmov%O2%C1\t{%2, %0|%0, %2}
16750 cmov%O2%c1\t{%3, %0|%0, %3}"
16751 [(set_attr "type" "icmov")
16752 (set_attr "mode" "DI")])
16753
16754 (define_expand "movsicc"
16755 [(set (match_operand:SI 0 "register_operand" "")
16756 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16757 (match_operand:SI 2 "general_operand" "")
16758 (match_operand:SI 3 "general_operand" "")))]
16759 ""
16760 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16761
16762 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16763 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16764 ;; So just document what we're doing explicitly.
16765
16766 (define_insn "x86_movsicc_0_m1"
16767 [(set (match_operand:SI 0 "register_operand" "=r")
16768 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16769 (const_int -1)
16770 (const_int 0)))
16771 (clobber (reg:CC 17))]
16772 ""
16773 "sbb{l}\t%0, %0"
16774 ; Since we don't have the proper number of operands for an alu insn,
16775 ; fill in all the blanks.
16776 [(set_attr "type" "alu")
16777 (set_attr "pent_pair" "pu")
16778 (set_attr "memory" "none")
16779 (set_attr "imm_disp" "false")
16780 (set_attr "mode" "SI")
16781 (set_attr "length_immediate" "0")])
16782
16783 (define_insn "*movsicc_noc"
16784 [(set (match_operand:SI 0 "register_operand" "=r,r")
16785 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16786 [(reg 17) (const_int 0)])
16787 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16788 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16789 "TARGET_CMOVE
16790 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16791 "@
16792 cmov%O2%C1\t{%2, %0|%0, %2}
16793 cmov%O2%c1\t{%3, %0|%0, %3}"
16794 [(set_attr "type" "icmov")
16795 (set_attr "mode" "SI")])
16796
16797 (define_expand "movhicc"
16798 [(set (match_operand:HI 0 "register_operand" "")
16799 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16800 (match_operand:HI 2 "general_operand" "")
16801 (match_operand:HI 3 "general_operand" "")))]
16802 "TARGET_HIMODE_MATH"
16803 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16804
16805 (define_insn "*movhicc_noc"
16806 [(set (match_operand:HI 0 "register_operand" "=r,r")
16807 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16808 [(reg 17) (const_int 0)])
16809 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16810 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16811 "TARGET_CMOVE
16812 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16813 "@
16814 cmov%O2%C1\t{%2, %0|%0, %2}
16815 cmov%O2%c1\t{%3, %0|%0, %3}"
16816 [(set_attr "type" "icmov")
16817 (set_attr "mode" "HI")])
16818
16819 (define_expand "movqicc"
16820 [(set (match_operand:QI 0 "register_operand" "")
16821 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16822 (match_operand:QI 2 "general_operand" "")
16823 (match_operand:QI 3 "general_operand" "")))]
16824 "TARGET_QIMODE_MATH"
16825 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16826
16827 (define_insn_and_split "*movqicc_noc"
16828 [(set (match_operand:QI 0 "register_operand" "=r,r")
16829 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16830 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16831 (match_operand:QI 2 "register_operand" "r,0")
16832 (match_operand:QI 3 "register_operand" "0,r")))]
16833 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16834 "#"
16835 "&& reload_completed"
16836 [(set (match_dup 0)
16837 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16838 (match_dup 2)
16839 (match_dup 3)))]
16840 "operands[0] = gen_lowpart (SImode, operands[0]);
16841 operands[2] = gen_lowpart (SImode, operands[2]);
16842 operands[3] = gen_lowpart (SImode, operands[3]);"
16843 [(set_attr "type" "icmov")
16844 (set_attr "mode" "SI")])
16845
16846 (define_expand "movsfcc"
16847 [(set (match_operand:SF 0 "register_operand" "")
16848 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16849 (match_operand:SF 2 "register_operand" "")
16850 (match_operand:SF 3 "register_operand" "")))]
16851 "TARGET_CMOVE"
16852 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16853
16854 (define_insn "*movsfcc_1"
16855 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16856 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16857 [(reg 17) (const_int 0)])
16858 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16859 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16860 "TARGET_CMOVE
16861 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16862 "@
16863 fcmov%F1\t{%2, %0|%0, %2}
16864 fcmov%f1\t{%3, %0|%0, %3}
16865 cmov%O2%C1\t{%2, %0|%0, %2}
16866 cmov%O2%c1\t{%3, %0|%0, %3}"
16867 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16868 (set_attr "mode" "SF,SF,SI,SI")])
16869
16870 (define_expand "movdfcc"
16871 [(set (match_operand:DF 0 "register_operand" "")
16872 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16873 (match_operand:DF 2 "register_operand" "")
16874 (match_operand:DF 3 "register_operand" "")))]
16875 "TARGET_CMOVE"
16876 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16877
16878 (define_insn "*movdfcc_1"
16879 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16880 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16881 [(reg 17) (const_int 0)])
16882 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16883 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16884 "!TARGET_64BIT && TARGET_CMOVE
16885 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16886 "@
16887 fcmov%F1\t{%2, %0|%0, %2}
16888 fcmov%f1\t{%3, %0|%0, %3}
16889 #
16890 #"
16891 [(set_attr "type" "fcmov,fcmov,multi,multi")
16892 (set_attr "mode" "DF")])
16893
16894 (define_insn "*movdfcc_1_rex64"
16895 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16896 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16897 [(reg 17) (const_int 0)])
16898 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16899 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16900 "TARGET_64BIT && TARGET_CMOVE
16901 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16902 "@
16903 fcmov%F1\t{%2, %0|%0, %2}
16904 fcmov%f1\t{%3, %0|%0, %3}
16905 cmov%O2%C1\t{%2, %0|%0, %2}
16906 cmov%O2%c1\t{%3, %0|%0, %3}"
16907 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16908 (set_attr "mode" "DF")])
16909
16910 (define_split
16911 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16912 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16913 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16914 (match_operand:DF 2 "nonimmediate_operand" "")
16915 (match_operand:DF 3 "nonimmediate_operand" "")))]
16916 "!TARGET_64BIT && reload_completed"
16917 [(set (match_dup 2)
16918 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16919 (match_dup 5)
16920 (match_dup 7)))
16921 (set (match_dup 3)
16922 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16923 (match_dup 6)
16924 (match_dup 8)))]
16925 "split_di (operands+2, 1, operands+5, operands+6);
16926 split_di (operands+3, 1, operands+7, operands+8);
16927 split_di (operands, 1, operands+2, operands+3);")
16928
16929 (define_expand "movxfcc"
16930 [(set (match_operand:XF 0 "register_operand" "")
16931 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16932 (match_operand:XF 2 "register_operand" "")
16933 (match_operand:XF 3 "register_operand" "")))]
16934 "TARGET_CMOVE"
16935 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16936
16937 (define_insn "*movxfcc_1"
16938 [(set (match_operand:XF 0 "register_operand" "=f,f")
16939 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16940 [(reg 17) (const_int 0)])
16941 (match_operand:XF 2 "register_operand" "f,0")
16942 (match_operand:XF 3 "register_operand" "0,f")))]
16943 "TARGET_CMOVE"
16944 "@
16945 fcmov%F1\t{%2, %0|%0, %2}
16946 fcmov%f1\t{%3, %0|%0, %3}"
16947 [(set_attr "type" "fcmov")
16948 (set_attr "mode" "XF")])
16949
16950 (define_expand "minsf3"
16951 [(parallel [
16952 (set (match_operand:SF 0 "register_operand" "")
16953 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16954 (match_operand:SF 2 "nonimmediate_operand" ""))
16955 (match_dup 1)
16956 (match_dup 2)))
16957 (clobber (reg:CC 17))])]
16958 "TARGET_SSE"
16959 "")
16960
16961 (define_insn "*minsf"
16962 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16963 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16964 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16965 (match_dup 1)
16966 (match_dup 2)))
16967 (clobber (reg:CC 17))]
16968 "TARGET_SSE && TARGET_IEEE_FP"
16969 "#")
16970
16971 (define_insn "*minsf_nonieee"
16972 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16973 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16974 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16975 (match_dup 1)
16976 (match_dup 2)))
16977 (clobber (reg:CC 17))]
16978 "TARGET_SSE && !TARGET_IEEE_FP
16979 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16980 "#")
16981
16982 (define_split
16983 [(set (match_operand:SF 0 "register_operand" "")
16984 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16985 (match_operand:SF 2 "nonimmediate_operand" ""))
16986 (match_operand:SF 3 "register_operand" "")
16987 (match_operand:SF 4 "nonimmediate_operand" "")))
16988 (clobber (reg:CC 17))]
16989 "SSE_REG_P (operands[0]) && reload_completed
16990 && ((operands_match_p (operands[1], operands[3])
16991 && operands_match_p (operands[2], operands[4]))
16992 || (operands_match_p (operands[1], operands[4])
16993 && operands_match_p (operands[2], operands[3])))"
16994 [(set (match_dup 0)
16995 (if_then_else:SF (lt (match_dup 1)
16996 (match_dup 2))
16997 (match_dup 1)
16998 (match_dup 2)))])
16999
17000 ;; Conditional addition patterns
17001 (define_expand "addqicc"
17002 [(match_operand:QI 0 "register_operand" "")
17003 (match_operand 1 "comparison_operator" "")
17004 (match_operand:QI 2 "register_operand" "")
17005 (match_operand:QI 3 "const_int_operand" "")]
17006 ""
17007 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17008
17009 (define_expand "addhicc"
17010 [(match_operand:HI 0 "register_operand" "")
17011 (match_operand 1 "comparison_operator" "")
17012 (match_operand:HI 2 "register_operand" "")
17013 (match_operand:HI 3 "const_int_operand" "")]
17014 ""
17015 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17016
17017 (define_expand "addsicc"
17018 [(match_operand:SI 0 "register_operand" "")
17019 (match_operand 1 "comparison_operator" "")
17020 (match_operand:SI 2 "register_operand" "")
17021 (match_operand:SI 3 "const_int_operand" "")]
17022 ""
17023 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17024
17025 (define_expand "adddicc"
17026 [(match_operand:DI 0 "register_operand" "")
17027 (match_operand 1 "comparison_operator" "")
17028 (match_operand:DI 2 "register_operand" "")
17029 (match_operand:DI 3 "const_int_operand" "")]
17030 "TARGET_64BIT"
17031 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17032
17033 ;; We can't represent the LT test directly. Do this by swapping the operands.
17034
17035 (define_split
17036 [(set (match_operand:SF 0 "fp_register_operand" "")
17037 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17038 (match_operand:SF 2 "register_operand" ""))
17039 (match_operand:SF 3 "register_operand" "")
17040 (match_operand:SF 4 "register_operand" "")))
17041 (clobber (reg:CC 17))]
17042 "reload_completed
17043 && ((operands_match_p (operands[1], operands[3])
17044 && operands_match_p (operands[2], operands[4]))
17045 || (operands_match_p (operands[1], operands[4])
17046 && operands_match_p (operands[2], operands[3])))"
17047 [(set (reg:CCFP 17)
17048 (compare:CCFP (match_dup 2)
17049 (match_dup 1)))
17050 (set (match_dup 0)
17051 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17052 (match_dup 1)
17053 (match_dup 2)))])
17054
17055 (define_insn "*minsf_sse"
17056 [(set (match_operand:SF 0 "register_operand" "=x")
17057 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17058 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17059 (match_dup 1)
17060 (match_dup 2)))]
17061 "TARGET_SSE && reload_completed"
17062 "minss\t{%2, %0|%0, %2}"
17063 [(set_attr "type" "sse")
17064 (set_attr "mode" "SF")])
17065
17066 (define_expand "mindf3"
17067 [(parallel [
17068 (set (match_operand:DF 0 "register_operand" "")
17069 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17070 (match_operand:DF 2 "nonimmediate_operand" ""))
17071 (match_dup 1)
17072 (match_dup 2)))
17073 (clobber (reg:CC 17))])]
17074 "TARGET_SSE2 && TARGET_SSE_MATH"
17075 "#")
17076
17077 (define_insn "*mindf"
17078 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17079 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17080 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17081 (match_dup 1)
17082 (match_dup 2)))
17083 (clobber (reg:CC 17))]
17084 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17085 "#")
17086
17087 (define_insn "*mindf_nonieee"
17088 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17089 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17090 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17091 (match_dup 1)
17092 (match_dup 2)))
17093 (clobber (reg:CC 17))]
17094 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17095 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17096 "#")
17097
17098 (define_split
17099 [(set (match_operand:DF 0 "register_operand" "")
17100 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17101 (match_operand:DF 2 "nonimmediate_operand" ""))
17102 (match_operand:DF 3 "register_operand" "")
17103 (match_operand:DF 4 "nonimmediate_operand" "")))
17104 (clobber (reg:CC 17))]
17105 "SSE_REG_P (operands[0]) && reload_completed
17106 && ((operands_match_p (operands[1], operands[3])
17107 && operands_match_p (operands[2], operands[4]))
17108 || (operands_match_p (operands[1], operands[4])
17109 && operands_match_p (operands[2], operands[3])))"
17110 [(set (match_dup 0)
17111 (if_then_else:DF (lt (match_dup 1)
17112 (match_dup 2))
17113 (match_dup 1)
17114 (match_dup 2)))])
17115
17116 ;; We can't represent the LT test directly. Do this by swapping the operands.
17117 (define_split
17118 [(set (match_operand:DF 0 "fp_register_operand" "")
17119 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17120 (match_operand:DF 2 "register_operand" ""))
17121 (match_operand:DF 3 "register_operand" "")
17122 (match_operand:DF 4 "register_operand" "")))
17123 (clobber (reg:CC 17))]
17124 "reload_completed
17125 && ((operands_match_p (operands[1], operands[3])
17126 && operands_match_p (operands[2], operands[4]))
17127 || (operands_match_p (operands[1], operands[4])
17128 && operands_match_p (operands[2], operands[3])))"
17129 [(set (reg:CCFP 17)
17130 (compare:CCFP (match_dup 2)
17131 (match_dup 1)))
17132 (set (match_dup 0)
17133 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17134 (match_dup 1)
17135 (match_dup 2)))])
17136
17137 (define_insn "*mindf_sse"
17138 [(set (match_operand:DF 0 "register_operand" "=Y")
17139 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17140 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17141 (match_dup 1)
17142 (match_dup 2)))]
17143 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17144 "minsd\t{%2, %0|%0, %2}"
17145 [(set_attr "type" "sse")
17146 (set_attr "mode" "DF")])
17147
17148 (define_expand "maxsf3"
17149 [(parallel [
17150 (set (match_operand:SF 0 "register_operand" "")
17151 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17152 (match_operand:SF 2 "nonimmediate_operand" ""))
17153 (match_dup 1)
17154 (match_dup 2)))
17155 (clobber (reg:CC 17))])]
17156 "TARGET_SSE"
17157 "#")
17158
17159 (define_insn "*maxsf"
17160 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17161 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17162 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17163 (match_dup 1)
17164 (match_dup 2)))
17165 (clobber (reg:CC 17))]
17166 "TARGET_SSE && TARGET_IEEE_FP"
17167 "#")
17168
17169 (define_insn "*maxsf_nonieee"
17170 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17171 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17172 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17173 (match_dup 1)
17174 (match_dup 2)))
17175 (clobber (reg:CC 17))]
17176 "TARGET_SSE && !TARGET_IEEE_FP
17177 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17178 "#")
17179
17180 (define_split
17181 [(set (match_operand:SF 0 "register_operand" "")
17182 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17183 (match_operand:SF 2 "nonimmediate_operand" ""))
17184 (match_operand:SF 3 "register_operand" "")
17185 (match_operand:SF 4 "nonimmediate_operand" "")))
17186 (clobber (reg:CC 17))]
17187 "SSE_REG_P (operands[0]) && reload_completed
17188 && ((operands_match_p (operands[1], operands[3])
17189 && operands_match_p (operands[2], operands[4]))
17190 || (operands_match_p (operands[1], operands[4])
17191 && operands_match_p (operands[2], operands[3])))"
17192 [(set (match_dup 0)
17193 (if_then_else:SF (gt (match_dup 1)
17194 (match_dup 2))
17195 (match_dup 1)
17196 (match_dup 2)))])
17197
17198 (define_split
17199 [(set (match_operand:SF 0 "fp_register_operand" "")
17200 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17201 (match_operand:SF 2 "register_operand" ""))
17202 (match_operand:SF 3 "register_operand" "")
17203 (match_operand:SF 4 "register_operand" "")))
17204 (clobber (reg:CC 17))]
17205 "reload_completed
17206 && ((operands_match_p (operands[1], operands[3])
17207 && operands_match_p (operands[2], operands[4]))
17208 || (operands_match_p (operands[1], operands[4])
17209 && operands_match_p (operands[2], operands[3])))"
17210 [(set (reg:CCFP 17)
17211 (compare:CCFP (match_dup 1)
17212 (match_dup 2)))
17213 (set (match_dup 0)
17214 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17215 (match_dup 1)
17216 (match_dup 2)))])
17217
17218 (define_insn "*maxsf_sse"
17219 [(set (match_operand:SF 0 "register_operand" "=x")
17220 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17221 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17222 (match_dup 1)
17223 (match_dup 2)))]
17224 "TARGET_SSE && reload_completed"
17225 "maxss\t{%2, %0|%0, %2}"
17226 [(set_attr "type" "sse")
17227 (set_attr "mode" "SF")])
17228
17229 (define_expand "maxdf3"
17230 [(parallel [
17231 (set (match_operand:DF 0 "register_operand" "")
17232 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17233 (match_operand:DF 2 "nonimmediate_operand" ""))
17234 (match_dup 1)
17235 (match_dup 2)))
17236 (clobber (reg:CC 17))])]
17237 "TARGET_SSE2 && TARGET_SSE_MATH"
17238 "#")
17239
17240 (define_insn "*maxdf"
17241 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17242 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17243 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17244 (match_dup 1)
17245 (match_dup 2)))
17246 (clobber (reg:CC 17))]
17247 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17248 "#")
17249
17250 (define_insn "*maxdf_nonieee"
17251 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17252 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17253 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17254 (match_dup 1)
17255 (match_dup 2)))
17256 (clobber (reg:CC 17))]
17257 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17258 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17259 "#")
17260
17261 (define_split
17262 [(set (match_operand:DF 0 "register_operand" "")
17263 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17264 (match_operand:DF 2 "nonimmediate_operand" ""))
17265 (match_operand:DF 3 "register_operand" "")
17266 (match_operand:DF 4 "nonimmediate_operand" "")))
17267 (clobber (reg:CC 17))]
17268 "SSE_REG_P (operands[0]) && reload_completed
17269 && ((operands_match_p (operands[1], operands[3])
17270 && operands_match_p (operands[2], operands[4]))
17271 || (operands_match_p (operands[1], operands[4])
17272 && operands_match_p (operands[2], operands[3])))"
17273 [(set (match_dup 0)
17274 (if_then_else:DF (gt (match_dup 1)
17275 (match_dup 2))
17276 (match_dup 1)
17277 (match_dup 2)))])
17278
17279 (define_split
17280 [(set (match_operand:DF 0 "fp_register_operand" "")
17281 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17282 (match_operand:DF 2 "register_operand" ""))
17283 (match_operand:DF 3 "register_operand" "")
17284 (match_operand:DF 4 "register_operand" "")))
17285 (clobber (reg:CC 17))]
17286 "reload_completed
17287 && ((operands_match_p (operands[1], operands[3])
17288 && operands_match_p (operands[2], operands[4]))
17289 || (operands_match_p (operands[1], operands[4])
17290 && operands_match_p (operands[2], operands[3])))"
17291 [(set (reg:CCFP 17)
17292 (compare:CCFP (match_dup 1)
17293 (match_dup 2)))
17294 (set (match_dup 0)
17295 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17296 (match_dup 1)
17297 (match_dup 2)))])
17298
17299 (define_insn "*maxdf_sse"
17300 [(set (match_operand:DF 0 "register_operand" "=Y")
17301 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17302 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17303 (match_dup 1)
17304 (match_dup 2)))]
17305 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17306 "maxsd\t{%2, %0|%0, %2}"
17307 [(set_attr "type" "sse")
17308 (set_attr "mode" "DF")])
17309 \f
17310 ;; Misc patterns (?)
17311
17312 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17313 ;; Otherwise there will be nothing to keep
17314 ;;
17315 ;; [(set (reg ebp) (reg esp))]
17316 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17317 ;; (clobber (eflags)]
17318 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17319 ;;
17320 ;; in proper program order.
17321 (define_insn "pro_epilogue_adjust_stack_1"
17322 [(set (match_operand:SI 0 "register_operand" "=r,r")
17323 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17324 (match_operand:SI 2 "immediate_operand" "i,i")))
17325 (clobber (reg:CC 17))
17326 (clobber (mem:BLK (scratch)))]
17327 "!TARGET_64BIT"
17328 {
17329 switch (get_attr_type (insn))
17330 {
17331 case TYPE_IMOV:
17332 return "mov{l}\t{%1, %0|%0, %1}";
17333
17334 case TYPE_ALU:
17335 if (GET_CODE (operands[2]) == CONST_INT
17336 && (INTVAL (operands[2]) == 128
17337 || (INTVAL (operands[2]) < 0
17338 && INTVAL (operands[2]) != -128)))
17339 {
17340 operands[2] = GEN_INT (-INTVAL (operands[2]));
17341 return "sub{l}\t{%2, %0|%0, %2}";
17342 }
17343 return "add{l}\t{%2, %0|%0, %2}";
17344
17345 case TYPE_LEA:
17346 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17347 return "lea{l}\t{%a2, %0|%0, %a2}";
17348
17349 default:
17350 abort ();
17351 }
17352 }
17353 [(set (attr "type")
17354 (cond [(eq_attr "alternative" "0")
17355 (const_string "alu")
17356 (match_operand:SI 2 "const0_operand" "")
17357 (const_string "imov")
17358 ]
17359 (const_string "lea")))
17360 (set_attr "mode" "SI")])
17361
17362 (define_insn "pro_epilogue_adjust_stack_rex64"
17363 [(set (match_operand:DI 0 "register_operand" "=r,r")
17364 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17365 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17366 (clobber (reg:CC 17))
17367 (clobber (mem:BLK (scratch)))]
17368 "TARGET_64BIT"
17369 {
17370 switch (get_attr_type (insn))
17371 {
17372 case TYPE_IMOV:
17373 return "mov{q}\t{%1, %0|%0, %1}";
17374
17375 case TYPE_ALU:
17376 if (GET_CODE (operands[2]) == CONST_INT
17377 /* Avoid overflows. */
17378 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17379 && (INTVAL (operands[2]) == 128
17380 || (INTVAL (operands[2]) < 0
17381 && INTVAL (operands[2]) != -128)))
17382 {
17383 operands[2] = GEN_INT (-INTVAL (operands[2]));
17384 return "sub{q}\t{%2, %0|%0, %2}";
17385 }
17386 return "add{q}\t{%2, %0|%0, %2}";
17387
17388 case TYPE_LEA:
17389 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17390 return "lea{q}\t{%a2, %0|%0, %a2}";
17391
17392 default:
17393 abort ();
17394 }
17395 }
17396 [(set (attr "type")
17397 (cond [(eq_attr "alternative" "0")
17398 (const_string "alu")
17399 (match_operand:DI 2 "const0_operand" "")
17400 (const_string "imov")
17401 ]
17402 (const_string "lea")))
17403 (set_attr "mode" "DI")])
17404
17405 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17406 [(set (match_operand:DI 0 "register_operand" "=r,r")
17407 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17408 (match_operand:DI 3 "immediate_operand" "i,i")))
17409 (use (match_operand:DI 2 "register_operand" "r,r"))
17410 (clobber (reg:CC 17))
17411 (clobber (mem:BLK (scratch)))]
17412 "TARGET_64BIT"
17413 {
17414 switch (get_attr_type (insn))
17415 {
17416 case TYPE_ALU:
17417 return "add{q}\t{%2, %0|%0, %2}";
17418
17419 case TYPE_LEA:
17420 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17421 return "lea{q}\t{%a2, %0|%0, %a2}";
17422
17423 default:
17424 abort ();
17425 }
17426 }
17427 [(set_attr "type" "alu,lea")
17428 (set_attr "mode" "DI")])
17429
17430 ;; Placeholder for the conditional moves. This one is split either to SSE
17431 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17432 ;; fact is that compares supported by the cmp??ss instructions are exactly
17433 ;; swapped of those supported by cmove sequence.
17434 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17435 ;; supported by i387 comparisons and we do need to emit two conditional moves
17436 ;; in tandem.
17437
17438 (define_insn "sse_movsfcc"
17439 [(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")
17440 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17441 [(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")
17442 (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")])
17443 (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")
17444 (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")))
17445 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17446 (clobber (reg:CC 17))]
17447 "TARGET_SSE
17448 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17449 /* Avoid combine from being smart and converting min/max
17450 instruction patterns into conditional moves. */
17451 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17452 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17453 || !rtx_equal_p (operands[4], operands[2])
17454 || !rtx_equal_p (operands[5], operands[3]))
17455 && (!TARGET_IEEE_FP
17456 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17457 "#")
17458
17459 (define_insn "sse_movsfcc_eq"
17460 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17461 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17462 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17463 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17464 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17465 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17466 (clobber (reg:CC 17))]
17467 "TARGET_SSE
17468 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17469 "#")
17470
17471 (define_insn "sse_movdfcc"
17472 [(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")
17473 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17474 [(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")
17475 (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")])
17476 (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")
17477 (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")))
17478 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17479 (clobber (reg:CC 17))]
17480 "TARGET_SSE2
17481 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17482 /* Avoid combine from being smart and converting min/max
17483 instruction patterns into conditional moves. */
17484 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17485 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17486 || !rtx_equal_p (operands[4], operands[2])
17487 || !rtx_equal_p (operands[5], operands[3]))
17488 && (!TARGET_IEEE_FP
17489 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17490 "#")
17491
17492 (define_insn "sse_movdfcc_eq"
17493 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17494 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17495 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17496 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17497 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17498 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17499 (clobber (reg:CC 17))]
17500 "TARGET_SSE
17501 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17502 "#")
17503
17504 ;; For non-sse moves just expand the usual cmove sequence.
17505 (define_split
17506 [(set (match_operand 0 "register_operand" "")
17507 (if_then_else (match_operator 1 "comparison_operator"
17508 [(match_operand 4 "nonimmediate_operand" "")
17509 (match_operand 5 "register_operand" "")])
17510 (match_operand 2 "nonimmediate_operand" "")
17511 (match_operand 3 "nonimmediate_operand" "")))
17512 (clobber (match_operand 6 "" ""))
17513 (clobber (reg:CC 17))]
17514 "!SSE_REG_P (operands[0]) && reload_completed
17515 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17516 [(const_int 0)]
17517 {
17518 ix86_compare_op0 = operands[5];
17519 ix86_compare_op1 = operands[4];
17520 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17521 VOIDmode, operands[5], operands[4]);
17522 ix86_expand_fp_movcc (operands);
17523 DONE;
17524 })
17525
17526 ;; Split SSE based conditional move into sequence:
17527 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17528 ;; and op2, op0 - zero op2 if comparison was false
17529 ;; nand op0, op3 - load op3 to op0 if comparison was false
17530 ;; or op2, op0 - get the nonzero one into the result.
17531 (define_split
17532 [(set (match_operand:SF 0 "register_operand" "")
17533 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
17534 [(match_operand:SF 4 "register_operand" "")
17535 (match_operand:SF 5 "nonimmediate_operand" "")])
17536 (match_operand:SF 2 "register_operand" "")
17537 (match_operand:SF 3 "register_operand" "")))
17538 (clobber (match_operand 6 "" ""))
17539 (clobber (reg:CC 17))]
17540 "SSE_REG_P (operands[0]) && reload_completed"
17541 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17542 (set (match_dup 2) (and:V4SF (match_dup 2)
17543 (match_dup 8)))
17544 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17545 (match_dup 3)))
17546 (set (match_dup 0) (ior:V4SF (match_dup 6)
17547 (match_dup 7)))]
17548 {
17549 /* If op2 == op3, op3 would be clobbered before it is used. */
17550 if (operands_match_p (operands[2], operands[3]))
17551 {
17552 emit_move_insn (operands[0], operands[2]);
17553 DONE;
17554 }
17555
17556 PUT_MODE (operands[1], GET_MODE (operands[0]));
17557 if (operands_match_p (operands[0], operands[4]))
17558 operands[6] = operands[4], operands[7] = operands[2];
17559 else
17560 operands[6] = operands[2], operands[7] = operands[4];
17561 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17562 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17563 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17564 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17565 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17566 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17567 })
17568
17569 (define_split
17570 [(set (match_operand:DF 0 "register_operand" "")
17571 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
17572 [(match_operand:DF 4 "register_operand" "")
17573 (match_operand:DF 5 "nonimmediate_operand" "")])
17574 (match_operand:DF 2 "register_operand" "")
17575 (match_operand:DF 3 "register_operand" "")))
17576 (clobber (match_operand 6 "" ""))
17577 (clobber (reg:CC 17))]
17578 "SSE_REG_P (operands[0]) && reload_completed"
17579 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17580 (set (match_dup 2) (and:V2DF (match_dup 2)
17581 (match_dup 8)))
17582 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17583 (match_dup 3)))
17584 (set (match_dup 0) (ior:V2DF (match_dup 6)
17585 (match_dup 7)))]
17586 {
17587 if (GET_MODE (operands[2]) == DFmode
17588 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17589 {
17590 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17591 emit_insn (gen_sse2_unpcklpd (op, op, op));
17592 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17593 emit_insn (gen_sse2_unpcklpd (op, op, op));
17594 }
17595
17596 /* If op2 == op3, op3 would be clobbered before it is used. */
17597 if (operands_match_p (operands[2], operands[3]))
17598 {
17599 emit_move_insn (operands[0], operands[2]);
17600 DONE;
17601 }
17602
17603 PUT_MODE (operands[1], GET_MODE (operands[0]));
17604 if (operands_match_p (operands[0], operands[4]))
17605 operands[6] = operands[4], operands[7] = operands[2];
17606 else
17607 operands[6] = operands[2], operands[7] = operands[4];
17608 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17609 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17610 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17611 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17612 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17613 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17614 })
17615
17616 ;; Special case of conditional move we can handle effectively.
17617 ;; Do not brother with the integer/floating point case, since these are
17618 ;; bot considerably slower, unlike in the generic case.
17619 (define_insn "*sse_movsfcc_const0_1"
17620 [(set (match_operand:SF 0 "register_operand" "=&x")
17621 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17622 [(match_operand:SF 4 "register_operand" "0")
17623 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17624 (match_operand:SF 2 "register_operand" "x")
17625 (match_operand:SF 3 "const0_operand" "X")))]
17626 "TARGET_SSE"
17627 "#")
17628
17629 (define_insn "*sse_movsfcc_const0_2"
17630 [(set (match_operand:SF 0 "register_operand" "=&x")
17631 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17632 [(match_operand:SF 4 "register_operand" "0")
17633 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17634 (match_operand:SF 2 "const0_operand" "X")
17635 (match_operand:SF 3 "register_operand" "x")))]
17636 "TARGET_SSE"
17637 "#")
17638
17639 (define_insn "*sse_movsfcc_const0_3"
17640 [(set (match_operand:SF 0 "register_operand" "=&x")
17641 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17642 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17643 (match_operand:SF 5 "register_operand" "0")])
17644 (match_operand:SF 2 "register_operand" "x")
17645 (match_operand:SF 3 "const0_operand" "X")))]
17646 "TARGET_SSE"
17647 "#")
17648
17649 (define_insn "*sse_movsfcc_const0_4"
17650 [(set (match_operand:SF 0 "register_operand" "=&x")
17651 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17652 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17653 (match_operand:SF 5 "register_operand" "0")])
17654 (match_operand:SF 2 "const0_operand" "X")
17655 (match_operand:SF 3 "register_operand" "x")))]
17656 "TARGET_SSE"
17657 "#")
17658
17659 (define_insn "*sse_movdfcc_const0_1"
17660 [(set (match_operand:DF 0 "register_operand" "=&Y")
17661 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17662 [(match_operand:DF 4 "register_operand" "0")
17663 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17664 (match_operand:DF 2 "register_operand" "Y")
17665 (match_operand:DF 3 "const0_operand" "X")))]
17666 "TARGET_SSE2"
17667 "#")
17668
17669 (define_insn "*sse_movdfcc_const0_2"
17670 [(set (match_operand:DF 0 "register_operand" "=&Y")
17671 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17672 [(match_operand:DF 4 "register_operand" "0")
17673 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17674 (match_operand:DF 2 "const0_operand" "X")
17675 (match_operand:DF 3 "register_operand" "Y")))]
17676 "TARGET_SSE2"
17677 "#")
17678
17679 (define_insn "*sse_movdfcc_const0_3"
17680 [(set (match_operand:DF 0 "register_operand" "=&Y")
17681 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17682 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17683 (match_operand:DF 5 "register_operand" "0")])
17684 (match_operand:DF 2 "register_operand" "Y")
17685 (match_operand:DF 3 "const0_operand" "X")))]
17686 "TARGET_SSE2"
17687 "#")
17688
17689 (define_insn "*sse_movdfcc_const0_4"
17690 [(set (match_operand:DF 0 "register_operand" "=&Y")
17691 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17692 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17693 (match_operand:DF 5 "register_operand" "0")])
17694 (match_operand:DF 2 "const0_operand" "X")
17695 (match_operand:DF 3 "register_operand" "Y")))]
17696 "TARGET_SSE2"
17697 "#")
17698
17699 (define_split
17700 [(set (match_operand:SF 0 "register_operand" "")
17701 (if_then_else (match_operator:SF 1 "comparison_operator"
17702 [(match_operand:SF 4 "nonimmediate_operand" "")
17703 (match_operand:SF 5 "nonimmediate_operand" "")])
17704 (match_operand:SF 2 "nonmemory_operand" "")
17705 (match_operand:SF 3 "nonmemory_operand" "")))]
17706 "SSE_REG_P (operands[0]) && reload_completed
17707 && (const0_operand (operands[2], GET_MODE (operands[0]))
17708 || const0_operand (operands[3], GET_MODE (operands[0])))"
17709 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17710 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17711 {
17712 PUT_MODE (operands[1], GET_MODE (operands[0]));
17713 if (!sse_comparison_operator (operands[1], VOIDmode)
17714 || !rtx_equal_p (operands[0], operands[4]))
17715 {
17716 rtx tmp = operands[5];
17717 operands[5] = operands[4];
17718 operands[4] = tmp;
17719 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17720 }
17721 if (!rtx_equal_p (operands[0], operands[4]))
17722 abort ();
17723 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17724 if (const0_operand (operands[2], GET_MODE (operands[2])))
17725 {
17726 operands[7] = operands[3];
17727 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17728 }
17729 else
17730 {
17731 operands[7] = operands[2];
17732 operands[6] = operands[0];
17733 }
17734 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17735 })
17736
17737 (define_split
17738 [(set (match_operand:DF 0 "register_operand" "")
17739 (if_then_else (match_operator:DF 1 "comparison_operator"
17740 [(match_operand:DF 4 "nonimmediate_operand" "")
17741 (match_operand:DF 5 "nonimmediate_operand" "")])
17742 (match_operand:DF 2 "nonmemory_operand" "")
17743 (match_operand:DF 3 "nonmemory_operand" "")))]
17744 "SSE_REG_P (operands[0]) && reload_completed
17745 && (const0_operand (operands[2], GET_MODE (operands[0]))
17746 || const0_operand (operands[3], GET_MODE (operands[0])))"
17747 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17748 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17749 {
17750 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17751 && GET_MODE (operands[2]) == DFmode)
17752 {
17753 if (REG_P (operands[2]))
17754 {
17755 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17756 emit_insn (gen_sse2_unpcklpd (op, op, op));
17757 }
17758 if (REG_P (operands[3]))
17759 {
17760 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17761 emit_insn (gen_sse2_unpcklpd (op, op, op));
17762 }
17763 }
17764 PUT_MODE (operands[1], GET_MODE (operands[0]));
17765 if (!sse_comparison_operator (operands[1], VOIDmode)
17766 || !rtx_equal_p (operands[0], operands[4]))
17767 {
17768 rtx tmp = operands[5];
17769 operands[5] = operands[4];
17770 operands[4] = tmp;
17771 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17772 }
17773 if (!rtx_equal_p (operands[0], operands[4]))
17774 abort ();
17775 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17776 if (const0_operand (operands[2], GET_MODE (operands[2])))
17777 {
17778 operands[7] = operands[3];
17779 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
17780 }
17781 else
17782 {
17783 operands[7] = operands[2];
17784 operands[6] = operands[8];
17785 }
17786 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17787 })
17788
17789 (define_expand "allocate_stack_worker"
17790 [(match_operand:SI 0 "register_operand" "")]
17791 "TARGET_STACK_PROBE"
17792 {
17793 if (reload_completed)
17794 {
17795 if (TARGET_64BIT)
17796 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17797 else
17798 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17799 }
17800 else
17801 {
17802 if (TARGET_64BIT)
17803 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17804 else
17805 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17806 }
17807 DONE;
17808 })
17809
17810 (define_insn "allocate_stack_worker_1"
17811 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17812 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17813 (clobber (match_scratch:SI 1 "=0"))
17814 (clobber (reg:CC 17))]
17815 "!TARGET_64BIT && TARGET_STACK_PROBE"
17816 "call\t__alloca"
17817 [(set_attr "type" "multi")
17818 (set_attr "length" "5")])
17819
17820 (define_expand "allocate_stack_worker_postreload"
17821 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17822 UNSPEC_STACK_PROBE)
17823 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17824 (clobber (match_dup 0))
17825 (clobber (reg:CC 17))])]
17826 ""
17827 "")
17828
17829 (define_insn "allocate_stack_worker_rex64"
17830 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17831 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17832 (clobber (match_scratch:DI 1 "=0"))
17833 (clobber (reg:CC 17))]
17834 "TARGET_64BIT && TARGET_STACK_PROBE"
17835 "call\t__alloca"
17836 [(set_attr "type" "multi")
17837 (set_attr "length" "5")])
17838
17839 (define_expand "allocate_stack_worker_rex64_postreload"
17840 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17841 UNSPEC_STACK_PROBE)
17842 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17843 (clobber (match_dup 0))
17844 (clobber (reg:CC 17))])]
17845 ""
17846 "")
17847
17848 (define_expand "allocate_stack"
17849 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17850 (minus:SI (reg:SI 7)
17851 (match_operand:SI 1 "general_operand" "")))
17852 (clobber (reg:CC 17))])
17853 (parallel [(set (reg:SI 7)
17854 (minus:SI (reg:SI 7) (match_dup 1)))
17855 (clobber (reg:CC 17))])]
17856 "TARGET_STACK_PROBE"
17857 {
17858 #ifdef CHECK_STACK_LIMIT
17859 if (GET_CODE (operands[1]) == CONST_INT
17860 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17861 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17862 operands[1]));
17863 else
17864 #endif
17865 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17866 operands[1])));
17867
17868 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17869 DONE;
17870 })
17871
17872 (define_expand "builtin_setjmp_receiver"
17873 [(label_ref (match_operand 0 "" ""))]
17874 "!TARGET_64BIT && flag_pic"
17875 {
17876 emit_insn (gen_set_got (pic_offset_table_rtx));
17877 DONE;
17878 })
17879 \f
17880 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17881
17882 (define_split
17883 [(set (match_operand 0 "register_operand" "")
17884 (match_operator 3 "promotable_binary_operator"
17885 [(match_operand 1 "register_operand" "")
17886 (match_operand 2 "aligned_operand" "")]))
17887 (clobber (reg:CC 17))]
17888 "! TARGET_PARTIAL_REG_STALL && reload_completed
17889 && ((GET_MODE (operands[0]) == HImode
17890 && ((!optimize_size && !TARGET_FAST_PREFIX)
17891 || GET_CODE (operands[2]) != CONST_INT
17892 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17893 || (GET_MODE (operands[0]) == QImode
17894 && (TARGET_PROMOTE_QImode || optimize_size)))"
17895 [(parallel [(set (match_dup 0)
17896 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17897 (clobber (reg:CC 17))])]
17898 "operands[0] = gen_lowpart (SImode, operands[0]);
17899 operands[1] = gen_lowpart (SImode, operands[1]);
17900 if (GET_CODE (operands[3]) != ASHIFT)
17901 operands[2] = gen_lowpart (SImode, operands[2]);
17902 PUT_MODE (operands[3], SImode);")
17903
17904 ; Promote the QImode tests, as i386 has encoding of the AND
17905 ; instruction with 32-bit sign-extended immediate and thus the
17906 ; instruction size is unchanged, except in the %eax case for
17907 ; which it is increased by one byte, hence the ! optimize_size.
17908 (define_split
17909 [(set (reg 17)
17910 (compare (and (match_operand 1 "aligned_operand" "")
17911 (match_operand 2 "const_int_operand" ""))
17912 (const_int 0)))
17913 (set (match_operand 0 "register_operand" "")
17914 (and (match_dup 1) (match_dup 2)))]
17915 "! TARGET_PARTIAL_REG_STALL && reload_completed
17916 /* Ensure that the operand will remain sign-extended immediate. */
17917 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17918 && ! optimize_size
17919 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17920 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17921 [(parallel [(set (reg:CCNO 17)
17922 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17923 (const_int 0)))
17924 (set (match_dup 0)
17925 (and:SI (match_dup 1) (match_dup 2)))])]
17926 "operands[2]
17927 = gen_int_mode (INTVAL (operands[2])
17928 & GET_MODE_MASK (GET_MODE (operands[0])),
17929 SImode);
17930 operands[0] = gen_lowpart (SImode, operands[0]);
17931 operands[1] = gen_lowpart (SImode, operands[1]);")
17932
17933 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17934 ; the TEST instruction with 32-bit sign-extended immediate and thus
17935 ; the instruction size would at least double, which is not what we
17936 ; want even with ! optimize_size.
17937 (define_split
17938 [(set (reg 17)
17939 (compare (and (match_operand:HI 0 "aligned_operand" "")
17940 (match_operand:HI 1 "const_int_operand" ""))
17941 (const_int 0)))]
17942 "! TARGET_PARTIAL_REG_STALL && reload_completed
17943 /* Ensure that the operand will remain sign-extended immediate. */
17944 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17945 && ! TARGET_FAST_PREFIX
17946 && ! optimize_size"
17947 [(set (reg:CCNO 17)
17948 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17949 (const_int 0)))]
17950 "operands[1]
17951 = gen_int_mode (INTVAL (operands[1])
17952 & GET_MODE_MASK (GET_MODE (operands[0])),
17953 SImode);
17954 operands[0] = gen_lowpart (SImode, operands[0]);")
17955
17956 (define_split
17957 [(set (match_operand 0 "register_operand" "")
17958 (neg (match_operand 1 "register_operand" "")))
17959 (clobber (reg:CC 17))]
17960 "! TARGET_PARTIAL_REG_STALL && reload_completed
17961 && (GET_MODE (operands[0]) == HImode
17962 || (GET_MODE (operands[0]) == QImode
17963 && (TARGET_PROMOTE_QImode || optimize_size)))"
17964 [(parallel [(set (match_dup 0)
17965 (neg:SI (match_dup 1)))
17966 (clobber (reg:CC 17))])]
17967 "operands[0] = gen_lowpart (SImode, operands[0]);
17968 operands[1] = gen_lowpart (SImode, operands[1]);")
17969
17970 (define_split
17971 [(set (match_operand 0 "register_operand" "")
17972 (not (match_operand 1 "register_operand" "")))]
17973 "! TARGET_PARTIAL_REG_STALL && reload_completed
17974 && (GET_MODE (operands[0]) == HImode
17975 || (GET_MODE (operands[0]) == QImode
17976 && (TARGET_PROMOTE_QImode || optimize_size)))"
17977 [(set (match_dup 0)
17978 (not:SI (match_dup 1)))]
17979 "operands[0] = gen_lowpart (SImode, operands[0]);
17980 operands[1] = gen_lowpart (SImode, operands[1]);")
17981
17982 (define_split
17983 [(set (match_operand 0 "register_operand" "")
17984 (if_then_else (match_operator 1 "comparison_operator"
17985 [(reg 17) (const_int 0)])
17986 (match_operand 2 "register_operand" "")
17987 (match_operand 3 "register_operand" "")))]
17988 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17989 && (GET_MODE (operands[0]) == HImode
17990 || (GET_MODE (operands[0]) == QImode
17991 && (TARGET_PROMOTE_QImode || optimize_size)))"
17992 [(set (match_dup 0)
17993 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17994 "operands[0] = gen_lowpart (SImode, operands[0]);
17995 operands[2] = gen_lowpart (SImode, operands[2]);
17996 operands[3] = gen_lowpart (SImode, operands[3]);")
17997
17998 \f
17999 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18000 ;; transform a complex memory operation into two memory to register operations.
18001
18002 ;; Don't push memory operands
18003 (define_peephole2
18004 [(set (match_operand:SI 0 "push_operand" "")
18005 (match_operand:SI 1 "memory_operand" ""))
18006 (match_scratch:SI 2 "r")]
18007 "! optimize_size && ! TARGET_PUSH_MEMORY"
18008 [(set (match_dup 2) (match_dup 1))
18009 (set (match_dup 0) (match_dup 2))]
18010 "")
18011
18012 (define_peephole2
18013 [(set (match_operand:DI 0 "push_operand" "")
18014 (match_operand:DI 1 "memory_operand" ""))
18015 (match_scratch:DI 2 "r")]
18016 "! optimize_size && ! TARGET_PUSH_MEMORY"
18017 [(set (match_dup 2) (match_dup 1))
18018 (set (match_dup 0) (match_dup 2))]
18019 "")
18020
18021 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18022 ;; SImode pushes.
18023 (define_peephole2
18024 [(set (match_operand:SF 0 "push_operand" "")
18025 (match_operand:SF 1 "memory_operand" ""))
18026 (match_scratch:SF 2 "r")]
18027 "! optimize_size && ! TARGET_PUSH_MEMORY"
18028 [(set (match_dup 2) (match_dup 1))
18029 (set (match_dup 0) (match_dup 2))]
18030 "")
18031
18032 (define_peephole2
18033 [(set (match_operand:HI 0 "push_operand" "")
18034 (match_operand:HI 1 "memory_operand" ""))
18035 (match_scratch:HI 2 "r")]
18036 "! optimize_size && ! TARGET_PUSH_MEMORY"
18037 [(set (match_dup 2) (match_dup 1))
18038 (set (match_dup 0) (match_dup 2))]
18039 "")
18040
18041 (define_peephole2
18042 [(set (match_operand:QI 0 "push_operand" "")
18043 (match_operand:QI 1 "memory_operand" ""))
18044 (match_scratch:QI 2 "q")]
18045 "! optimize_size && ! TARGET_PUSH_MEMORY"
18046 [(set (match_dup 2) (match_dup 1))
18047 (set (match_dup 0) (match_dup 2))]
18048 "")
18049
18050 ;; Don't move an immediate directly to memory when the instruction
18051 ;; gets too big.
18052 (define_peephole2
18053 [(match_scratch:SI 1 "r")
18054 (set (match_operand:SI 0 "memory_operand" "")
18055 (const_int 0))]
18056 "! optimize_size
18057 && ! TARGET_USE_MOV0
18058 && TARGET_SPLIT_LONG_MOVES
18059 && get_attr_length (insn) >= ix86_cost->large_insn
18060 && peep2_regno_dead_p (0, FLAGS_REG)"
18061 [(parallel [(set (match_dup 1) (const_int 0))
18062 (clobber (reg:CC 17))])
18063 (set (match_dup 0) (match_dup 1))]
18064 "")
18065
18066 (define_peephole2
18067 [(match_scratch:HI 1 "r")
18068 (set (match_operand:HI 0 "memory_operand" "")
18069 (const_int 0))]
18070 "! optimize_size
18071 && ! TARGET_USE_MOV0
18072 && TARGET_SPLIT_LONG_MOVES
18073 && get_attr_length (insn) >= ix86_cost->large_insn
18074 && peep2_regno_dead_p (0, FLAGS_REG)"
18075 [(parallel [(set (match_dup 2) (const_int 0))
18076 (clobber (reg:CC 17))])
18077 (set (match_dup 0) (match_dup 1))]
18078 "operands[2] = gen_lowpart (SImode, operands[1]);")
18079
18080 (define_peephole2
18081 [(match_scratch:QI 1 "q")
18082 (set (match_operand:QI 0 "memory_operand" "")
18083 (const_int 0))]
18084 "! optimize_size
18085 && ! TARGET_USE_MOV0
18086 && TARGET_SPLIT_LONG_MOVES
18087 && get_attr_length (insn) >= ix86_cost->large_insn
18088 && peep2_regno_dead_p (0, FLAGS_REG)"
18089 [(parallel [(set (match_dup 2) (const_int 0))
18090 (clobber (reg:CC 17))])
18091 (set (match_dup 0) (match_dup 1))]
18092 "operands[2] = gen_lowpart (SImode, operands[1]);")
18093
18094 (define_peephole2
18095 [(match_scratch:SI 2 "r")
18096 (set (match_operand:SI 0 "memory_operand" "")
18097 (match_operand:SI 1 "immediate_operand" ""))]
18098 "! optimize_size
18099 && get_attr_length (insn) >= ix86_cost->large_insn
18100 && TARGET_SPLIT_LONG_MOVES"
18101 [(set (match_dup 2) (match_dup 1))
18102 (set (match_dup 0) (match_dup 2))]
18103 "")
18104
18105 (define_peephole2
18106 [(match_scratch:HI 2 "r")
18107 (set (match_operand:HI 0 "memory_operand" "")
18108 (match_operand:HI 1 "immediate_operand" ""))]
18109 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18110 && TARGET_SPLIT_LONG_MOVES"
18111 [(set (match_dup 2) (match_dup 1))
18112 (set (match_dup 0) (match_dup 2))]
18113 "")
18114
18115 (define_peephole2
18116 [(match_scratch:QI 2 "q")
18117 (set (match_operand:QI 0 "memory_operand" "")
18118 (match_operand:QI 1 "immediate_operand" ""))]
18119 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18120 && TARGET_SPLIT_LONG_MOVES"
18121 [(set (match_dup 2) (match_dup 1))
18122 (set (match_dup 0) (match_dup 2))]
18123 "")
18124
18125 ;; Don't compare memory with zero, load and use a test instead.
18126 (define_peephole2
18127 [(set (reg 17)
18128 (compare (match_operand:SI 0 "memory_operand" "")
18129 (const_int 0)))
18130 (match_scratch:SI 3 "r")]
18131 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18132 [(set (match_dup 3) (match_dup 0))
18133 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18134 "")
18135
18136 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18137 ;; Don't split NOTs with a displacement operand, because resulting XOR
18138 ;; will not be pairable anyway.
18139 ;;
18140 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18141 ;; represented using a modRM byte. The XOR replacement is long decoded,
18142 ;; so this split helps here as well.
18143 ;;
18144 ;; Note: Can't do this as a regular split because we can't get proper
18145 ;; lifetime information then.
18146
18147 (define_peephole2
18148 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18149 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18150 "!optimize_size
18151 && peep2_regno_dead_p (0, FLAGS_REG)
18152 && ((TARGET_PENTIUM
18153 && (GET_CODE (operands[0]) != MEM
18154 || !memory_displacement_operand (operands[0], SImode)))
18155 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18156 [(parallel [(set (match_dup 0)
18157 (xor:SI (match_dup 1) (const_int -1)))
18158 (clobber (reg:CC 17))])]
18159 "")
18160
18161 (define_peephole2
18162 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18163 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18164 "!optimize_size
18165 && peep2_regno_dead_p (0, FLAGS_REG)
18166 && ((TARGET_PENTIUM
18167 && (GET_CODE (operands[0]) != MEM
18168 || !memory_displacement_operand (operands[0], HImode)))
18169 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18170 [(parallel [(set (match_dup 0)
18171 (xor:HI (match_dup 1) (const_int -1)))
18172 (clobber (reg:CC 17))])]
18173 "")
18174
18175 (define_peephole2
18176 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18177 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18178 "!optimize_size
18179 && peep2_regno_dead_p (0, FLAGS_REG)
18180 && ((TARGET_PENTIUM
18181 && (GET_CODE (operands[0]) != MEM
18182 || !memory_displacement_operand (operands[0], QImode)))
18183 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18184 [(parallel [(set (match_dup 0)
18185 (xor:QI (match_dup 1) (const_int -1)))
18186 (clobber (reg:CC 17))])]
18187 "")
18188
18189 ;; Non pairable "test imm, reg" instructions can be translated to
18190 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18191 ;; byte opcode instead of two, have a short form for byte operands),
18192 ;; so do it for other CPUs as well. Given that the value was dead,
18193 ;; this should not create any new dependencies. Pass on the sub-word
18194 ;; versions if we're concerned about partial register stalls.
18195
18196 (define_peephole2
18197 [(set (reg 17)
18198 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18199 (match_operand:SI 1 "immediate_operand" ""))
18200 (const_int 0)))]
18201 "ix86_match_ccmode (insn, CCNOmode)
18202 && (true_regnum (operands[0]) != 0
18203 || (GET_CODE (operands[1]) == CONST_INT
18204 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18205 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18206 [(parallel
18207 [(set (reg:CCNO 17)
18208 (compare:CCNO (and:SI (match_dup 0)
18209 (match_dup 1))
18210 (const_int 0)))
18211 (set (match_dup 0)
18212 (and:SI (match_dup 0) (match_dup 1)))])]
18213 "")
18214
18215 ;; We don't need to handle HImode case, because it will be promoted to SImode
18216 ;; on ! TARGET_PARTIAL_REG_STALL
18217
18218 (define_peephole2
18219 [(set (reg 17)
18220 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18221 (match_operand:QI 1 "immediate_operand" ""))
18222 (const_int 0)))]
18223 "! TARGET_PARTIAL_REG_STALL
18224 && ix86_match_ccmode (insn, CCNOmode)
18225 && true_regnum (operands[0]) != 0
18226 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18227 [(parallel
18228 [(set (reg:CCNO 17)
18229 (compare:CCNO (and:QI (match_dup 0)
18230 (match_dup 1))
18231 (const_int 0)))
18232 (set (match_dup 0)
18233 (and:QI (match_dup 0) (match_dup 1)))])]
18234 "")
18235
18236 (define_peephole2
18237 [(set (reg 17)
18238 (compare
18239 (and:SI
18240 (zero_extract:SI
18241 (match_operand 0 "ext_register_operand" "")
18242 (const_int 8)
18243 (const_int 8))
18244 (match_operand 1 "const_int_operand" ""))
18245 (const_int 0)))]
18246 "! TARGET_PARTIAL_REG_STALL
18247 && ix86_match_ccmode (insn, CCNOmode)
18248 && true_regnum (operands[0]) != 0
18249 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18250 [(parallel [(set (reg:CCNO 17)
18251 (compare:CCNO
18252 (and:SI
18253 (zero_extract:SI
18254 (match_dup 0)
18255 (const_int 8)
18256 (const_int 8))
18257 (match_dup 1))
18258 (const_int 0)))
18259 (set (zero_extract:SI (match_dup 0)
18260 (const_int 8)
18261 (const_int 8))
18262 (and:SI
18263 (zero_extract:SI
18264 (match_dup 0)
18265 (const_int 8)
18266 (const_int 8))
18267 (match_dup 1)))])]
18268 "")
18269
18270 ;; Don't do logical operations with memory inputs.
18271 (define_peephole2
18272 [(match_scratch:SI 2 "r")
18273 (parallel [(set (match_operand:SI 0 "register_operand" "")
18274 (match_operator:SI 3 "arith_or_logical_operator"
18275 [(match_dup 0)
18276 (match_operand:SI 1 "memory_operand" "")]))
18277 (clobber (reg:CC 17))])]
18278 "! optimize_size && ! TARGET_READ_MODIFY"
18279 [(set (match_dup 2) (match_dup 1))
18280 (parallel [(set (match_dup 0)
18281 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18282 (clobber (reg:CC 17))])]
18283 "")
18284
18285 (define_peephole2
18286 [(match_scratch:SI 2 "r")
18287 (parallel [(set (match_operand:SI 0 "register_operand" "")
18288 (match_operator:SI 3 "arith_or_logical_operator"
18289 [(match_operand:SI 1 "memory_operand" "")
18290 (match_dup 0)]))
18291 (clobber (reg:CC 17))])]
18292 "! optimize_size && ! TARGET_READ_MODIFY"
18293 [(set (match_dup 2) (match_dup 1))
18294 (parallel [(set (match_dup 0)
18295 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18296 (clobber (reg:CC 17))])]
18297 "")
18298
18299 ; Don't do logical operations with memory outputs
18300 ;
18301 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18302 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18303 ; the same decoder scheduling characteristics as the original.
18304
18305 (define_peephole2
18306 [(match_scratch:SI 2 "r")
18307 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18308 (match_operator:SI 3 "arith_or_logical_operator"
18309 [(match_dup 0)
18310 (match_operand:SI 1 "nonmemory_operand" "")]))
18311 (clobber (reg:CC 17))])]
18312 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18313 [(set (match_dup 2) (match_dup 0))
18314 (parallel [(set (match_dup 2)
18315 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18316 (clobber (reg:CC 17))])
18317 (set (match_dup 0) (match_dup 2))]
18318 "")
18319
18320 (define_peephole2
18321 [(match_scratch:SI 2 "r")
18322 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18323 (match_operator:SI 3 "arith_or_logical_operator"
18324 [(match_operand:SI 1 "nonmemory_operand" "")
18325 (match_dup 0)]))
18326 (clobber (reg:CC 17))])]
18327 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18328 [(set (match_dup 2) (match_dup 0))
18329 (parallel [(set (match_dup 2)
18330 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18331 (clobber (reg:CC 17))])
18332 (set (match_dup 0) (match_dup 2))]
18333 "")
18334
18335 ;; Attempt to always use XOR for zeroing registers.
18336 (define_peephole2
18337 [(set (match_operand 0 "register_operand" "")
18338 (const_int 0))]
18339 "(GET_MODE (operands[0]) == QImode
18340 || GET_MODE (operands[0]) == HImode
18341 || GET_MODE (operands[0]) == SImode
18342 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18343 && (! TARGET_USE_MOV0 || optimize_size)
18344 && peep2_regno_dead_p (0, FLAGS_REG)"
18345 [(parallel [(set (match_dup 0) (const_int 0))
18346 (clobber (reg:CC 17))])]
18347 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18348 operands[0]);")
18349
18350 (define_peephole2
18351 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18352 (const_int 0))]
18353 "(GET_MODE (operands[0]) == QImode
18354 || GET_MODE (operands[0]) == HImode)
18355 && (! TARGET_USE_MOV0 || optimize_size)
18356 && peep2_regno_dead_p (0, FLAGS_REG)"
18357 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18358 (clobber (reg:CC 17))])])
18359
18360 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18361 (define_peephole2
18362 [(set (match_operand 0 "register_operand" "")
18363 (const_int -1))]
18364 "(GET_MODE (operands[0]) == HImode
18365 || GET_MODE (operands[0]) == SImode
18366 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18367 && (optimize_size || TARGET_PENTIUM)
18368 && peep2_regno_dead_p (0, FLAGS_REG)"
18369 [(parallel [(set (match_dup 0) (const_int -1))
18370 (clobber (reg:CC 17))])]
18371 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18372 operands[0]);")
18373
18374 ;; Attempt to convert simple leas to adds. These can be created by
18375 ;; move expanders.
18376 (define_peephole2
18377 [(set (match_operand:SI 0 "register_operand" "")
18378 (plus:SI (match_dup 0)
18379 (match_operand:SI 1 "nonmemory_operand" "")))]
18380 "peep2_regno_dead_p (0, FLAGS_REG)"
18381 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18382 (clobber (reg:CC 17))])]
18383 "")
18384
18385 (define_peephole2
18386 [(set (match_operand:SI 0 "register_operand" "")
18387 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18388 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18389 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18390 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18391 (clobber (reg:CC 17))])]
18392 "operands[2] = gen_lowpart (SImode, operands[2]);")
18393
18394 (define_peephole2
18395 [(set (match_operand:DI 0 "register_operand" "")
18396 (plus:DI (match_dup 0)
18397 (match_operand:DI 1 "x86_64_general_operand" "")))]
18398 "peep2_regno_dead_p (0, FLAGS_REG)"
18399 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18400 (clobber (reg:CC 17))])]
18401 "")
18402
18403 (define_peephole2
18404 [(set (match_operand:SI 0 "register_operand" "")
18405 (mult:SI (match_dup 0)
18406 (match_operand:SI 1 "const_int_operand" "")))]
18407 "exact_log2 (INTVAL (operands[1])) >= 0
18408 && peep2_regno_dead_p (0, FLAGS_REG)"
18409 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18410 (clobber (reg:CC 17))])]
18411 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18412
18413 (define_peephole2
18414 [(set (match_operand:DI 0 "register_operand" "")
18415 (mult:DI (match_dup 0)
18416 (match_operand:DI 1 "const_int_operand" "")))]
18417 "exact_log2 (INTVAL (operands[1])) >= 0
18418 && peep2_regno_dead_p (0, FLAGS_REG)"
18419 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18420 (clobber (reg:CC 17))])]
18421 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18422
18423 (define_peephole2
18424 [(set (match_operand:SI 0 "register_operand" "")
18425 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18426 (match_operand:DI 2 "const_int_operand" "")) 0))]
18427 "exact_log2 (INTVAL (operands[2])) >= 0
18428 && REGNO (operands[0]) == REGNO (operands[1])
18429 && peep2_regno_dead_p (0, FLAGS_REG)"
18430 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18431 (clobber (reg:CC 17))])]
18432 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18433
18434 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18435 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18436 ;; many CPUs it is also faster, since special hardware to avoid esp
18437 ;; dependencies is present.
18438
18439 ;; While some of these conversions may be done using splitters, we use peepholes
18440 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18441
18442 ;; Convert prologue esp subtractions to push.
18443 ;; We need register to push. In order to keep verify_flow_info happy we have
18444 ;; two choices
18445 ;; - use scratch and clobber it in order to avoid dependencies
18446 ;; - use already live register
18447 ;; We can't use the second way right now, since there is no reliable way how to
18448 ;; verify that given register is live. First choice will also most likely in
18449 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18450 ;; call clobbered registers are dead. We may want to use base pointer as an
18451 ;; alternative when no register is available later.
18452
18453 (define_peephole2
18454 [(match_scratch:SI 0 "r")
18455 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18456 (clobber (reg:CC 17))
18457 (clobber (mem:BLK (scratch)))])]
18458 "optimize_size || !TARGET_SUB_ESP_4"
18459 [(clobber (match_dup 0))
18460 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18461 (clobber (mem:BLK (scratch)))])])
18462
18463 (define_peephole2
18464 [(match_scratch:SI 0 "r")
18465 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18466 (clobber (reg:CC 17))
18467 (clobber (mem:BLK (scratch)))])]
18468 "optimize_size || !TARGET_SUB_ESP_8"
18469 [(clobber (match_dup 0))
18470 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18471 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18472 (clobber (mem:BLK (scratch)))])])
18473
18474 ;; Convert esp subtractions to push.
18475 (define_peephole2
18476 [(match_scratch:SI 0 "r")
18477 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18478 (clobber (reg:CC 17))])]
18479 "optimize_size || !TARGET_SUB_ESP_4"
18480 [(clobber (match_dup 0))
18481 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18482
18483 (define_peephole2
18484 [(match_scratch:SI 0 "r")
18485 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18486 (clobber (reg:CC 17))])]
18487 "optimize_size || !TARGET_SUB_ESP_8"
18488 [(clobber (match_dup 0))
18489 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18490 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18491
18492 ;; Convert epilogue deallocator to pop.
18493 (define_peephole2
18494 [(match_scratch:SI 0 "r")
18495 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18496 (clobber (reg:CC 17))
18497 (clobber (mem:BLK (scratch)))])]
18498 "optimize_size || !TARGET_ADD_ESP_4"
18499 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18500 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18501 (clobber (mem:BLK (scratch)))])]
18502 "")
18503
18504 ;; Two pops case is tricky, since pop causes dependency on destination register.
18505 ;; We use two registers if available.
18506 (define_peephole2
18507 [(match_scratch:SI 0 "r")
18508 (match_scratch:SI 1 "r")
18509 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18510 (clobber (reg:CC 17))
18511 (clobber (mem:BLK (scratch)))])]
18512 "optimize_size || !TARGET_ADD_ESP_8"
18513 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18514 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18515 (clobber (mem:BLK (scratch)))])
18516 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18517 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18518 "")
18519
18520 (define_peephole2
18521 [(match_scratch:SI 0 "r")
18522 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18523 (clobber (reg:CC 17))
18524 (clobber (mem:BLK (scratch)))])]
18525 "optimize_size"
18526 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18527 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18528 (clobber (mem:BLK (scratch)))])
18529 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18530 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18531 "")
18532
18533 ;; Convert esp additions to pop.
18534 (define_peephole2
18535 [(match_scratch:SI 0 "r")
18536 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18537 (clobber (reg:CC 17))])]
18538 ""
18539 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18540 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18541 "")
18542
18543 ;; Two pops case is tricky, since pop causes dependency on destination register.
18544 ;; We use two registers if available.
18545 (define_peephole2
18546 [(match_scratch:SI 0 "r")
18547 (match_scratch:SI 1 "r")
18548 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18549 (clobber (reg:CC 17))])]
18550 ""
18551 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18552 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18553 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18554 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18555 "")
18556
18557 (define_peephole2
18558 [(match_scratch:SI 0 "r")
18559 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18560 (clobber (reg:CC 17))])]
18561 "optimize_size"
18562 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18563 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18564 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18565 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18566 "")
18567 \f
18568 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18569 ;; required and register dies.
18570 (define_peephole2
18571 [(set (reg 17)
18572 (compare (match_operand:SI 0 "register_operand" "")
18573 (match_operand:SI 1 "incdec_operand" "")))]
18574 "ix86_match_ccmode (insn, CCGCmode)
18575 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18576 [(parallel [(set (reg:CCGC 17)
18577 (compare:CCGC (match_dup 0)
18578 (match_dup 1)))
18579 (clobber (match_dup 0))])]
18580 "")
18581
18582 (define_peephole2
18583 [(set (reg 17)
18584 (compare (match_operand:HI 0 "register_operand" "")
18585 (match_operand:HI 1 "incdec_operand" "")))]
18586 "ix86_match_ccmode (insn, CCGCmode)
18587 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18588 [(parallel [(set (reg:CCGC 17)
18589 (compare:CCGC (match_dup 0)
18590 (match_dup 1)))
18591 (clobber (match_dup 0))])]
18592 "")
18593
18594 (define_peephole2
18595 [(set (reg 17)
18596 (compare (match_operand:QI 0 "register_operand" "")
18597 (match_operand:QI 1 "incdec_operand" "")))]
18598 "ix86_match_ccmode (insn, CCGCmode)
18599 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18600 [(parallel [(set (reg:CCGC 17)
18601 (compare:CCGC (match_dup 0)
18602 (match_dup 1)))
18603 (clobber (match_dup 0))])]
18604 "")
18605
18606 ;; Convert compares with 128 to shorter add -128
18607 (define_peephole2
18608 [(set (reg 17)
18609 (compare (match_operand:SI 0 "register_operand" "")
18610 (const_int 128)))]
18611 "ix86_match_ccmode (insn, CCGCmode)
18612 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18613 [(parallel [(set (reg:CCGC 17)
18614 (compare:CCGC (match_dup 0)
18615 (const_int 128)))
18616 (clobber (match_dup 0))])]
18617 "")
18618
18619 (define_peephole2
18620 [(set (reg 17)
18621 (compare (match_operand:HI 0 "register_operand" "")
18622 (const_int 128)))]
18623 "ix86_match_ccmode (insn, CCGCmode)
18624 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18625 [(parallel [(set (reg:CCGC 17)
18626 (compare:CCGC (match_dup 0)
18627 (const_int 128)))
18628 (clobber (match_dup 0))])]
18629 "")
18630 \f
18631 (define_peephole2
18632 [(match_scratch:DI 0 "r")
18633 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18634 (clobber (reg:CC 17))
18635 (clobber (mem:BLK (scratch)))])]
18636 "optimize_size || !TARGET_SUB_ESP_4"
18637 [(clobber (match_dup 0))
18638 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18639 (clobber (mem:BLK (scratch)))])])
18640
18641 (define_peephole2
18642 [(match_scratch:DI 0 "r")
18643 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18644 (clobber (reg:CC 17))
18645 (clobber (mem:BLK (scratch)))])]
18646 "optimize_size || !TARGET_SUB_ESP_8"
18647 [(clobber (match_dup 0))
18648 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18649 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18650 (clobber (mem:BLK (scratch)))])])
18651
18652 ;; Convert esp subtractions to push.
18653 (define_peephole2
18654 [(match_scratch:DI 0 "r")
18655 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18656 (clobber (reg:CC 17))])]
18657 "optimize_size || !TARGET_SUB_ESP_4"
18658 [(clobber (match_dup 0))
18659 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18660
18661 (define_peephole2
18662 [(match_scratch:DI 0 "r")
18663 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18664 (clobber (reg:CC 17))])]
18665 "optimize_size || !TARGET_SUB_ESP_8"
18666 [(clobber (match_dup 0))
18667 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18668 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18669
18670 ;; Convert epilogue deallocator to pop.
18671 (define_peephole2
18672 [(match_scratch:DI 0 "r")
18673 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18674 (clobber (reg:CC 17))
18675 (clobber (mem:BLK (scratch)))])]
18676 "optimize_size || !TARGET_ADD_ESP_4"
18677 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18678 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18679 (clobber (mem:BLK (scratch)))])]
18680 "")
18681
18682 ;; Two pops case is tricky, since pop causes dependency on destination register.
18683 ;; We use two registers if available.
18684 (define_peephole2
18685 [(match_scratch:DI 0 "r")
18686 (match_scratch:DI 1 "r")
18687 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18688 (clobber (reg:CC 17))
18689 (clobber (mem:BLK (scratch)))])]
18690 "optimize_size || !TARGET_ADD_ESP_8"
18691 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18692 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18693 (clobber (mem:BLK (scratch)))])
18694 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18695 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18696 "")
18697
18698 (define_peephole2
18699 [(match_scratch:DI 0 "r")
18700 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18701 (clobber (reg:CC 17))
18702 (clobber (mem:BLK (scratch)))])]
18703 "optimize_size"
18704 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18705 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18706 (clobber (mem:BLK (scratch)))])
18707 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18708 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18709 "")
18710
18711 ;; Convert esp additions to pop.
18712 (define_peephole2
18713 [(match_scratch:DI 0 "r")
18714 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18715 (clobber (reg:CC 17))])]
18716 ""
18717 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18718 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18719 "")
18720
18721 ;; Two pops case is tricky, since pop causes dependency on destination register.
18722 ;; We use two registers if available.
18723 (define_peephole2
18724 [(match_scratch:DI 0 "r")
18725 (match_scratch:DI 1 "r")
18726 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18727 (clobber (reg:CC 17))])]
18728 ""
18729 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18730 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18731 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18732 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18733 "")
18734
18735 (define_peephole2
18736 [(match_scratch:DI 0 "r")
18737 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18738 (clobber (reg:CC 17))])]
18739 "optimize_size"
18740 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18741 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18742 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18743 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18744 "")
18745 \f
18746 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18747 ;; imul $32bit_imm, reg, reg is direct decoded.
18748 (define_peephole2
18749 [(match_scratch:DI 3 "r")
18750 (parallel [(set (match_operand:DI 0 "register_operand" "")
18751 (mult:DI (match_operand:DI 1 "memory_operand" "")
18752 (match_operand:DI 2 "immediate_operand" "")))
18753 (clobber (reg:CC 17))])]
18754 "TARGET_K8 && !optimize_size
18755 && (GET_CODE (operands[2]) != CONST_INT
18756 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18757 [(set (match_dup 3) (match_dup 1))
18758 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18759 (clobber (reg:CC 17))])]
18760 "")
18761
18762 (define_peephole2
18763 [(match_scratch:SI 3 "r")
18764 (parallel [(set (match_operand:SI 0 "register_operand" "")
18765 (mult:SI (match_operand:SI 1 "memory_operand" "")
18766 (match_operand:SI 2 "immediate_operand" "")))
18767 (clobber (reg:CC 17))])]
18768 "TARGET_K8 && !optimize_size
18769 && (GET_CODE (operands[2]) != CONST_INT
18770 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18771 [(set (match_dup 3) (match_dup 1))
18772 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18773 (clobber (reg:CC 17))])]
18774 "")
18775
18776 (define_peephole2
18777 [(match_scratch:SI 3 "r")
18778 (parallel [(set (match_operand:DI 0 "register_operand" "")
18779 (zero_extend:DI
18780 (mult:SI (match_operand:SI 1 "memory_operand" "")
18781 (match_operand:SI 2 "immediate_operand" ""))))
18782 (clobber (reg:CC 17))])]
18783 "TARGET_K8 && !optimize_size
18784 && (GET_CODE (operands[2]) != CONST_INT
18785 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18786 [(set (match_dup 3) (match_dup 1))
18787 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18788 (clobber (reg:CC 17))])]
18789 "")
18790
18791 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18792 ;; Convert it into imul reg, reg
18793 ;; It would be better to force assembler to encode instruction using long
18794 ;; immediate, but there is apparently no way to do so.
18795 (define_peephole2
18796 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18797 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18798 (match_operand:DI 2 "const_int_operand" "")))
18799 (clobber (reg:CC 17))])
18800 (match_scratch:DI 3 "r")]
18801 "TARGET_K8 && !optimize_size
18802 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18803 [(set (match_dup 3) (match_dup 2))
18804 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18805 (clobber (reg:CC 17))])]
18806 {
18807 if (!rtx_equal_p (operands[0], operands[1]))
18808 emit_move_insn (operands[0], operands[1]);
18809 })
18810
18811 (define_peephole2
18812 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18813 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18814 (match_operand:SI 2 "const_int_operand" "")))
18815 (clobber (reg:CC 17))])
18816 (match_scratch:SI 3 "r")]
18817 "TARGET_K8 && !optimize_size
18818 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18819 [(set (match_dup 3) (match_dup 2))
18820 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18821 (clobber (reg:CC 17))])]
18822 {
18823 if (!rtx_equal_p (operands[0], operands[1]))
18824 emit_move_insn (operands[0], operands[1]);
18825 })
18826
18827 (define_peephole2
18828 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18829 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18830 (match_operand:HI 2 "immediate_operand" "")))
18831 (clobber (reg:CC 17))])
18832 (match_scratch:HI 3 "r")]
18833 "TARGET_K8 && !optimize_size"
18834 [(set (match_dup 3) (match_dup 2))
18835 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18836 (clobber (reg:CC 17))])]
18837 {
18838 if (!rtx_equal_p (operands[0], operands[1]))
18839 emit_move_insn (operands[0], operands[1]);
18840 })
18841 \f
18842 ;; Call-value patterns last so that the wildcard operand does not
18843 ;; disrupt insn-recog's switch tables.
18844
18845 (define_insn "*call_value_pop_0"
18846 [(set (match_operand 0 "" "")
18847 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18848 (match_operand:SI 2 "" "")))
18849 (set (reg:SI 7) (plus:SI (reg:SI 7)
18850 (match_operand:SI 3 "immediate_operand" "")))]
18851 "!TARGET_64BIT"
18852 {
18853 if (SIBLING_CALL_P (insn))
18854 return "jmp\t%P1";
18855 else
18856 return "call\t%P1";
18857 }
18858 [(set_attr "type" "callv")])
18859
18860 (define_insn "*call_value_pop_1"
18861 [(set (match_operand 0 "" "")
18862 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18863 (match_operand:SI 2 "" "")))
18864 (set (reg:SI 7) (plus:SI (reg:SI 7)
18865 (match_operand:SI 3 "immediate_operand" "i")))]
18866 "!TARGET_64BIT"
18867 {
18868 if (constant_call_address_operand (operands[1], QImode))
18869 {
18870 if (SIBLING_CALL_P (insn))
18871 return "jmp\t%P1";
18872 else
18873 return "call\t%P1";
18874 }
18875 if (SIBLING_CALL_P (insn))
18876 return "jmp\t%A1";
18877 else
18878 return "call\t%A1";
18879 }
18880 [(set_attr "type" "callv")])
18881
18882 (define_insn "*call_value_0"
18883 [(set (match_operand 0 "" "")
18884 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18885 (match_operand:SI 2 "" "")))]
18886 "!TARGET_64BIT"
18887 {
18888 if (SIBLING_CALL_P (insn))
18889 return "jmp\t%P1";
18890 else
18891 return "call\t%P1";
18892 }
18893 [(set_attr "type" "callv")])
18894
18895 (define_insn "*call_value_0_rex64"
18896 [(set (match_operand 0 "" "")
18897 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18898 (match_operand:DI 2 "const_int_operand" "")))]
18899 "TARGET_64BIT"
18900 {
18901 if (SIBLING_CALL_P (insn))
18902 return "jmp\t%P1";
18903 else
18904 return "call\t%P1";
18905 }
18906 [(set_attr "type" "callv")])
18907
18908 (define_insn "*call_value_1"
18909 [(set (match_operand 0 "" "")
18910 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18911 (match_operand:SI 2 "" "")))]
18912 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18913 {
18914 if (constant_call_address_operand (operands[1], QImode))
18915 return "call\t%P1";
18916 return "call\t%*%1";
18917 }
18918 [(set_attr "type" "callv")])
18919
18920 (define_insn "*sibcall_value_1"
18921 [(set (match_operand 0 "" "")
18922 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18923 (match_operand:SI 2 "" "")))]
18924 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18925 {
18926 if (constant_call_address_operand (operands[1], QImode))
18927 return "jmp\t%P1";
18928 return "jmp\t%*%1";
18929 }
18930 [(set_attr "type" "callv")])
18931
18932 (define_insn "*call_value_1_rex64"
18933 [(set (match_operand 0 "" "")
18934 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18935 (match_operand:DI 2 "" "")))]
18936 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18937 {
18938 if (constant_call_address_operand (operands[1], QImode))
18939 return "call\t%P1";
18940 return "call\t%A1";
18941 }
18942 [(set_attr "type" "callv")])
18943
18944 (define_insn "*sibcall_value_1_rex64"
18945 [(set (match_operand 0 "" "")
18946 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18947 (match_operand:DI 2 "" "")))]
18948 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18949 "jmp\t%P1"
18950 [(set_attr "type" "callv")])
18951
18952 (define_insn "*sibcall_value_1_rex64_v"
18953 [(set (match_operand 0 "" "")
18954 (call (mem:QI (reg:DI 40))
18955 (match_operand:DI 1 "" "")))]
18956 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18957 "jmp\t*%%r11"
18958 [(set_attr "type" "callv")])
18959 \f
18960 (define_insn "trap"
18961 [(trap_if (const_int 1) (const_int 5))]
18962 ""
18963 "int\t$5")
18964
18965 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18966 ;;; for the sake of bounds checking. By emitting bounds checks as
18967 ;;; conditional traps rather than as conditional jumps around
18968 ;;; unconditional traps we avoid introducing spurious basic-block
18969 ;;; boundaries and facilitate elimination of redundant checks. In
18970 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18971 ;;; interrupt 5.
18972 ;;;
18973 ;;; FIXME: Static branch prediction rules for ix86 are such that
18974 ;;; forward conditional branches predict as untaken. As implemented
18975 ;;; below, pseudo conditional traps violate that rule. We should use
18976 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18977 ;;; section loaded at the end of the text segment and branch forward
18978 ;;; there on bounds-failure, and then jump back immediately (in case
18979 ;;; the system chooses to ignore bounds violations, or to report
18980 ;;; violations and continue execution).
18981
18982 (define_expand "conditional_trap"
18983 [(trap_if (match_operator 0 "comparison_operator"
18984 [(match_dup 2) (const_int 0)])
18985 (match_operand 1 "const_int_operand" ""))]
18986 ""
18987 {
18988 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18989 ix86_expand_compare (GET_CODE (operands[0]),
18990 NULL, NULL),
18991 operands[1]));
18992 DONE;
18993 })
18994
18995 (define_insn "*conditional_trap_1"
18996 [(trap_if (match_operator 0 "comparison_operator"
18997 [(reg 17) (const_int 0)])
18998 (match_operand 1 "const_int_operand" ""))]
18999 ""
19000 {
19001 operands[2] = gen_label_rtx ();
19002 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19003 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19004 CODE_LABEL_NUMBER (operands[2]));
19005 RET;
19006 })
19007
19008 ;; Pentium III SIMD instructions.
19009
19010 ;; Moves for SSE/MMX regs.
19011
19012 (define_insn "movv4sf_internal"
19013 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19014 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19015 "TARGET_SSE"
19016 "@
19017 xorps\t%0, %0
19018 movaps\t{%1, %0|%0, %1}
19019 movaps\t{%1, %0|%0, %1}"
19020 [(set_attr "type" "ssemov")
19021 (set_attr "mode" "V4SF")])
19022
19023 (define_split
19024 [(set (match_operand:V4SF 0 "register_operand" "")
19025 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19026 "TARGET_SSE"
19027 [(set (match_dup 0)
19028 (vec_merge:V4SF
19029 (vec_duplicate:V4SF (match_dup 1))
19030 (match_dup 2)
19031 (const_int 1)))]
19032 {
19033 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19034 operands[2] = CONST0_RTX (V4SFmode);
19035 })
19036
19037 (define_insn "movv4si_internal"
19038 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19039 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19040 "TARGET_SSE"
19041 {
19042 switch (which_alternative)
19043 {
19044 case 0:
19045 if (get_attr_mode (insn) == MODE_V4SF)
19046 return "xorps\t%0, %0";
19047 else
19048 return "pxor\t%0, %0";
19049 case 1:
19050 case 2:
19051 if (get_attr_mode (insn) == MODE_V4SF)
19052 return "movaps\t{%1, %0|%0, %1}";
19053 else
19054 return "movdqa\t{%1, %0|%0, %1}";
19055 default:
19056 abort ();
19057 }
19058 }
19059 [(set_attr "type" "ssemov")
19060 (set (attr "mode")
19061 (cond [(eq_attr "alternative" "0,1")
19062 (if_then_else
19063 (ne (symbol_ref "optimize_size")
19064 (const_int 0))
19065 (const_string "V4SF")
19066 (const_string "TI"))
19067 (eq_attr "alternative" "2")
19068 (if_then_else
19069 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19070 (const_int 0))
19071 (ne (symbol_ref "optimize_size")
19072 (const_int 0)))
19073 (const_string "V4SF")
19074 (const_string "TI"))]
19075 (const_string "TI")))])
19076
19077 (define_insn "movv2di_internal"
19078 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19079 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19080 "TARGET_SSE"
19081 {
19082 switch (which_alternative)
19083 {
19084 case 0:
19085 if (get_attr_mode (insn) == MODE_V4SF)
19086 return "xorps\t%0, %0";
19087 else
19088 return "pxor\t%0, %0";
19089 case 1:
19090 case 2:
19091 if (get_attr_mode (insn) == MODE_V4SF)
19092 return "movaps\t{%1, %0|%0, %1}";
19093 else
19094 return "movdqa\t{%1, %0|%0, %1}";
19095 default:
19096 abort ();
19097 }
19098 }
19099 [(set_attr "type" "ssemov")
19100 (set (attr "mode")
19101 (cond [(eq_attr "alternative" "0,1")
19102 (if_then_else
19103 (ne (symbol_ref "optimize_size")
19104 (const_int 0))
19105 (const_string "V4SF")
19106 (const_string "TI"))
19107 (eq_attr "alternative" "2")
19108 (if_then_else
19109 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19110 (const_int 0))
19111 (ne (symbol_ref "optimize_size")
19112 (const_int 0)))
19113 (const_string "V4SF")
19114 (const_string "TI"))]
19115 (const_string "TI")))])
19116
19117 (define_split
19118 [(set (match_operand:V2DF 0 "register_operand" "")
19119 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19120 "TARGET_SSE2"
19121 [(set (match_dup 0)
19122 (vec_merge:V2DF
19123 (vec_duplicate:V2DF (match_dup 1))
19124 (match_dup 2)
19125 (const_int 1)))]
19126 {
19127 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19128 operands[2] = CONST0_RTX (V2DFmode);
19129 })
19130
19131 (define_insn "movv8qi_internal"
19132 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19133 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19134 "TARGET_MMX
19135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19136 "@
19137 pxor\t%0, %0
19138 movq\t{%1, %0|%0, %1}
19139 movq\t{%1, %0|%0, %1}"
19140 [(set_attr "type" "mmxmov")
19141 (set_attr "mode" "DI")])
19142
19143 (define_insn "movv4hi_internal"
19144 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19145 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19146 "TARGET_MMX
19147 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19148 "@
19149 pxor\t%0, %0
19150 movq\t{%1, %0|%0, %1}
19151 movq\t{%1, %0|%0, %1}"
19152 [(set_attr "type" "mmxmov")
19153 (set_attr "mode" "DI")])
19154
19155 (define_insn "movv2si_internal"
19156 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19157 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19158 "TARGET_MMX
19159 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19160 "@
19161 pxor\t%0, %0
19162 movq\t{%1, %0|%0, %1}
19163 movq\t{%1, %0|%0, %1}"
19164 [(set_attr "type" "mmxcvt")
19165 (set_attr "mode" "DI")])
19166
19167 (define_insn "movv2sf_internal"
19168 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19169 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19170 "TARGET_3DNOW
19171 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19172 "@
19173 pxor\t%0, %0
19174 movq\t{%1, %0|%0, %1}
19175 movq\t{%1, %0|%0, %1}"
19176 [(set_attr "type" "mmxcvt")
19177 (set_attr "mode" "DI")])
19178
19179 (define_expand "movti"
19180 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19181 (match_operand:TI 1 "nonimmediate_operand" ""))]
19182 "TARGET_SSE || TARGET_64BIT"
19183 {
19184 if (TARGET_64BIT)
19185 ix86_expand_move (TImode, operands);
19186 else
19187 ix86_expand_vector_move (TImode, operands);
19188 DONE;
19189 })
19190
19191 (define_expand "movtf"
19192 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19193 (match_operand:TF 1 "nonimmediate_operand" ""))]
19194 "TARGET_64BIT"
19195 {
19196 if (TARGET_64BIT)
19197 ix86_expand_move (TFmode, operands);
19198 else
19199 ix86_expand_vector_move (TFmode, operands);
19200 DONE;
19201 })
19202
19203 (define_insn "movv2df_internal"
19204 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19205 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19206 "TARGET_SSE2
19207 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19208 {
19209 switch (which_alternative)
19210 {
19211 case 0:
19212 if (get_attr_mode (insn) == MODE_V4SF)
19213 return "xorps\t%0, %0";
19214 else
19215 return "xorpd\t%0, %0";
19216 case 1:
19217 case 2:
19218 if (get_attr_mode (insn) == MODE_V4SF)
19219 return "movaps\t{%1, %0|%0, %1}";
19220 else
19221 return "movapd\t{%1, %0|%0, %1}";
19222 default:
19223 abort ();
19224 }
19225 }
19226 [(set_attr "type" "ssemov")
19227 (set (attr "mode")
19228 (cond [(eq_attr "alternative" "0,1")
19229 (if_then_else
19230 (ne (symbol_ref "optimize_size")
19231 (const_int 0))
19232 (const_string "V4SF")
19233 (const_string "V2DF"))
19234 (eq_attr "alternative" "2")
19235 (if_then_else
19236 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19237 (const_int 0))
19238 (ne (symbol_ref "optimize_size")
19239 (const_int 0)))
19240 (const_string "V4SF")
19241 (const_string "V2DF"))]
19242 (const_string "V2DF")))])
19243
19244 (define_insn "movv8hi_internal"
19245 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19246 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19247 "TARGET_SSE2
19248 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19249 {
19250 switch (which_alternative)
19251 {
19252 case 0:
19253 if (get_attr_mode (insn) == MODE_V4SF)
19254 return "xorps\t%0, %0";
19255 else
19256 return "pxor\t%0, %0";
19257 case 1:
19258 case 2:
19259 if (get_attr_mode (insn) == MODE_V4SF)
19260 return "movaps\t{%1, %0|%0, %1}";
19261 else
19262 return "movdqa\t{%1, %0|%0, %1}";
19263 default:
19264 abort ();
19265 }
19266 }
19267 [(set_attr "type" "ssemov")
19268 (set (attr "mode")
19269 (cond [(eq_attr "alternative" "0,1")
19270 (if_then_else
19271 (ne (symbol_ref "optimize_size")
19272 (const_int 0))
19273 (const_string "V4SF")
19274 (const_string "TI"))
19275 (eq_attr "alternative" "2")
19276 (if_then_else
19277 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19278 (const_int 0))
19279 (ne (symbol_ref "optimize_size")
19280 (const_int 0)))
19281 (const_string "V4SF")
19282 (const_string "TI"))]
19283 (const_string "TI")))])
19284
19285 (define_insn "movv16qi_internal"
19286 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19287 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19288 "TARGET_SSE2
19289 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19290 {
19291 switch (which_alternative)
19292 {
19293 case 0:
19294 if (get_attr_mode (insn) == MODE_V4SF)
19295 return "xorps\t%0, %0";
19296 else
19297 return "pxor\t%0, %0";
19298 case 1:
19299 case 2:
19300 if (get_attr_mode (insn) == MODE_V4SF)
19301 return "movaps\t{%1, %0|%0, %1}";
19302 else
19303 return "movdqa\t{%1, %0|%0, %1}";
19304 default:
19305 abort ();
19306 }
19307 }
19308 [(set_attr "type" "ssemov")
19309 (set (attr "mode")
19310 (cond [(eq_attr "alternative" "0,1")
19311 (if_then_else
19312 (ne (symbol_ref "optimize_size")
19313 (const_int 0))
19314 (const_string "V4SF")
19315 (const_string "TI"))
19316 (eq_attr "alternative" "2")
19317 (if_then_else
19318 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19319 (const_int 0))
19320 (ne (symbol_ref "optimize_size")
19321 (const_int 0)))
19322 (const_string "V4SF")
19323 (const_string "TI"))]
19324 (const_string "TI")))])
19325
19326 (define_expand "movv2df"
19327 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19328 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19329 "TARGET_SSE2"
19330 {
19331 ix86_expand_vector_move (V2DFmode, operands);
19332 DONE;
19333 })
19334
19335 (define_expand "movv8hi"
19336 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19337 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19338 "TARGET_SSE2"
19339 {
19340 ix86_expand_vector_move (V8HImode, operands);
19341 DONE;
19342 })
19343
19344 (define_expand "movv16qi"
19345 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19346 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19347 "TARGET_SSE2"
19348 {
19349 ix86_expand_vector_move (V16QImode, operands);
19350 DONE;
19351 })
19352
19353 (define_expand "movv4sf"
19354 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19355 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19356 "TARGET_SSE"
19357 {
19358 ix86_expand_vector_move (V4SFmode, operands);
19359 DONE;
19360 })
19361
19362 (define_expand "movv4si"
19363 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19364 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19365 "TARGET_SSE"
19366 {
19367 ix86_expand_vector_move (V4SImode, operands);
19368 DONE;
19369 })
19370
19371 (define_expand "movv2di"
19372 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19373 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19374 "TARGET_SSE"
19375 {
19376 ix86_expand_vector_move (V2DImode, operands);
19377 DONE;
19378 })
19379
19380 (define_expand "movv2si"
19381 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19382 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19383 "TARGET_MMX"
19384 {
19385 ix86_expand_vector_move (V2SImode, operands);
19386 DONE;
19387 })
19388
19389 (define_expand "movv4hi"
19390 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19391 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19392 "TARGET_MMX"
19393 {
19394 ix86_expand_vector_move (V4HImode, operands);
19395 DONE;
19396 })
19397
19398 (define_expand "movv8qi"
19399 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19400 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19401 "TARGET_MMX"
19402 {
19403 ix86_expand_vector_move (V8QImode, operands);
19404 DONE;
19405 })
19406
19407 (define_expand "movv2sf"
19408 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19409 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19410 "TARGET_3DNOW"
19411 {
19412 ix86_expand_vector_move (V2SFmode, operands);
19413 DONE;
19414 })
19415
19416 (define_insn "*pushti"
19417 [(set (match_operand:TI 0 "push_operand" "=<")
19418 (match_operand:TI 1 "register_operand" "x"))]
19419 "TARGET_SSE"
19420 "#")
19421
19422 (define_insn "*pushv2df"
19423 [(set (match_operand:V2DF 0 "push_operand" "=<")
19424 (match_operand:V2DF 1 "register_operand" "x"))]
19425 "TARGET_SSE"
19426 "#")
19427
19428 (define_insn "*pushv2di"
19429 [(set (match_operand:V2DI 0 "push_operand" "=<")
19430 (match_operand:V2DI 1 "register_operand" "x"))]
19431 "TARGET_SSE2"
19432 "#")
19433
19434 (define_insn "*pushv8hi"
19435 [(set (match_operand:V8HI 0 "push_operand" "=<")
19436 (match_operand:V8HI 1 "register_operand" "x"))]
19437 "TARGET_SSE2"
19438 "#")
19439
19440 (define_insn "*pushv16qi"
19441 [(set (match_operand:V16QI 0 "push_operand" "=<")
19442 (match_operand:V16QI 1 "register_operand" "x"))]
19443 "TARGET_SSE2"
19444 "#")
19445
19446 (define_insn "*pushv4sf"
19447 [(set (match_operand:V4SF 0 "push_operand" "=<")
19448 (match_operand:V4SF 1 "register_operand" "x"))]
19449 "TARGET_SSE"
19450 "#")
19451
19452 (define_insn "*pushv4si"
19453 [(set (match_operand:V4SI 0 "push_operand" "=<")
19454 (match_operand:V4SI 1 "register_operand" "x"))]
19455 "TARGET_SSE2"
19456 "#")
19457
19458 (define_insn "*pushv2si"
19459 [(set (match_operand:V2SI 0 "push_operand" "=<")
19460 (match_operand:V2SI 1 "register_operand" "y"))]
19461 "TARGET_MMX"
19462 "#")
19463
19464 (define_insn "*pushv4hi"
19465 [(set (match_operand:V4HI 0 "push_operand" "=<")
19466 (match_operand:V4HI 1 "register_operand" "y"))]
19467 "TARGET_MMX"
19468 "#")
19469
19470 (define_insn "*pushv8qi"
19471 [(set (match_operand:V8QI 0 "push_operand" "=<")
19472 (match_operand:V8QI 1 "register_operand" "y"))]
19473 "TARGET_MMX"
19474 "#")
19475
19476 (define_insn "*pushv2sf"
19477 [(set (match_operand:V2SF 0 "push_operand" "=<")
19478 (match_operand:V2SF 1 "register_operand" "y"))]
19479 "TARGET_3DNOW"
19480 "#")
19481
19482 (define_split
19483 [(set (match_operand 0 "push_operand" "")
19484 (match_operand 1 "register_operand" ""))]
19485 "!TARGET_64BIT && reload_completed
19486 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19487 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19488 (set (match_dup 2) (match_dup 1))]
19489 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19490 stack_pointer_rtx);
19491 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19492
19493 (define_split
19494 [(set (match_operand 0 "push_operand" "")
19495 (match_operand 1 "register_operand" ""))]
19496 "TARGET_64BIT && reload_completed
19497 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19498 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19499 (set (match_dup 2) (match_dup 1))]
19500 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19501 stack_pointer_rtx);
19502 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19503
19504
19505 (define_insn "movti_internal"
19506 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19507 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19508 "TARGET_SSE && !TARGET_64BIT
19509 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19510 {
19511 switch (which_alternative)
19512 {
19513 case 0:
19514 if (get_attr_mode (insn) == MODE_V4SF)
19515 return "xorps\t%0, %0";
19516 else
19517 return "pxor\t%0, %0";
19518 case 1:
19519 case 2:
19520 if (get_attr_mode (insn) == MODE_V4SF)
19521 return "movaps\t{%1, %0|%0, %1}";
19522 else
19523 return "movdqa\t{%1, %0|%0, %1}";
19524 default:
19525 abort ();
19526 }
19527 }
19528 [(set_attr "type" "ssemov,ssemov,ssemov")
19529 (set (attr "mode")
19530 (cond [(eq_attr "alternative" "0,1")
19531 (if_then_else
19532 (ne (symbol_ref "optimize_size")
19533 (const_int 0))
19534 (const_string "V4SF")
19535 (const_string "TI"))
19536 (eq_attr "alternative" "2")
19537 (if_then_else
19538 (ne (symbol_ref "optimize_size")
19539 (const_int 0))
19540 (const_string "V4SF")
19541 (const_string "TI"))]
19542 (const_string "TI")))])
19543
19544 (define_insn "*movti_rex64"
19545 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19546 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19547 "TARGET_64BIT
19548 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19549 {
19550 switch (which_alternative)
19551 {
19552 case 0:
19553 case 1:
19554 return "#";
19555 case 2:
19556 if (get_attr_mode (insn) == MODE_V4SF)
19557 return "xorps\t%0, %0";
19558 else
19559 return "pxor\t%0, %0";
19560 case 3:
19561 case 4:
19562 if (get_attr_mode (insn) == MODE_V4SF)
19563 return "movaps\t{%1, %0|%0, %1}";
19564 else
19565 return "movdqa\t{%1, %0|%0, %1}";
19566 default:
19567 abort ();
19568 }
19569 }
19570 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19571 (set (attr "mode")
19572 (cond [(eq_attr "alternative" "2,3")
19573 (if_then_else
19574 (ne (symbol_ref "optimize_size")
19575 (const_int 0))
19576 (const_string "V4SF")
19577 (const_string "TI"))
19578 (eq_attr "alternative" "4")
19579 (if_then_else
19580 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19581 (const_int 0))
19582 (ne (symbol_ref "optimize_size")
19583 (const_int 0)))
19584 (const_string "V4SF")
19585 (const_string "TI"))]
19586 (const_string "DI")))])
19587
19588 (define_insn "*movtf_rex64"
19589 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19590 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19591 "TARGET_64BIT
19592 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19593 {
19594 switch (which_alternative)
19595 {
19596 case 0:
19597 case 1:
19598 return "#";
19599 case 2:
19600 if (get_attr_mode (insn) == MODE_V4SF)
19601 return "xorps\t%0, %0";
19602 else
19603 return "pxor\t%0, %0";
19604 case 3:
19605 case 4:
19606 if (get_attr_mode (insn) == MODE_V4SF)
19607 return "movaps\t{%1, %0|%0, %1}";
19608 else
19609 return "movdqa\t{%1, %0|%0, %1}";
19610 default:
19611 abort ();
19612 }
19613 }
19614 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19615 (set (attr "mode")
19616 (cond [(eq_attr "alternative" "2,3")
19617 (if_then_else
19618 (ne (symbol_ref "optimize_size")
19619 (const_int 0))
19620 (const_string "V4SF")
19621 (const_string "TI"))
19622 (eq_attr "alternative" "4")
19623 (if_then_else
19624 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19625 (const_int 0))
19626 (ne (symbol_ref "optimize_size")
19627 (const_int 0)))
19628 (const_string "V4SF")
19629 (const_string "TI"))]
19630 (const_string "DI")))])
19631
19632 (define_split
19633 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19634 (match_operand:TI 1 "general_operand" ""))]
19635 "reload_completed && !SSE_REG_P (operands[0])
19636 && !SSE_REG_P (operands[1])"
19637 [(const_int 0)]
19638 "ix86_split_long_move (operands); DONE;")
19639
19640 (define_split
19641 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19642 (match_operand:TF 1 "general_operand" ""))]
19643 "reload_completed && !SSE_REG_P (operands[0])
19644 && !SSE_REG_P (operands[1])"
19645 [(const_int 0)]
19646 "ix86_split_long_move (operands); DONE;")
19647
19648 ;; These two patterns are useful for specifying exactly whether to use
19649 ;; movaps or movups
19650 (define_expand "sse_movaps"
19651 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19652 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19653 UNSPEC_MOVA))]
19654 "TARGET_SSE"
19655 {
19656 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19657 {
19658 rtx tmp = gen_reg_rtx (V4SFmode);
19659 emit_insn (gen_sse_movaps (tmp, operands[1]));
19660 emit_move_insn (operands[0], tmp);
19661 DONE;
19662 }
19663 })
19664
19665 (define_insn "*sse_movaps_1"
19666 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19667 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19668 UNSPEC_MOVA))]
19669 "TARGET_SSE
19670 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19671 "movaps\t{%1, %0|%0, %1}"
19672 [(set_attr "type" "ssemov,ssemov")
19673 (set_attr "mode" "V4SF")])
19674
19675 (define_expand "sse_movups"
19676 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19677 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19678 UNSPEC_MOVU))]
19679 "TARGET_SSE"
19680 {
19681 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19682 {
19683 rtx tmp = gen_reg_rtx (V4SFmode);
19684 emit_insn (gen_sse_movups (tmp, operands[1]));
19685 emit_move_insn (operands[0], tmp);
19686 DONE;
19687 }
19688 })
19689
19690 (define_insn "*sse_movups_1"
19691 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19692 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19693 UNSPEC_MOVU))]
19694 "TARGET_SSE
19695 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19696 "movups\t{%1, %0|%0, %1}"
19697 [(set_attr "type" "ssecvt,ssecvt")
19698 (set_attr "mode" "V4SF")])
19699
19700 ;; SSE Strange Moves.
19701
19702 (define_insn "sse_movmskps"
19703 [(set (match_operand:SI 0 "register_operand" "=r")
19704 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19705 UNSPEC_MOVMSK))]
19706 "TARGET_SSE"
19707 "movmskps\t{%1, %0|%0, %1}"
19708 [(set_attr "type" "ssecvt")
19709 (set_attr "mode" "V4SF")])
19710
19711 (define_insn "mmx_pmovmskb"
19712 [(set (match_operand:SI 0 "register_operand" "=r")
19713 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19714 UNSPEC_MOVMSK))]
19715 "TARGET_SSE || TARGET_3DNOW_A"
19716 "pmovmskb\t{%1, %0|%0, %1}"
19717 [(set_attr "type" "ssecvt")
19718 (set_attr "mode" "V4SF")])
19719
19720
19721 (define_insn "mmx_maskmovq"
19722 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19723 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19724 (match_operand:V8QI 2 "register_operand" "y")]
19725 UNSPEC_MASKMOV))]
19726 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19727 ;; @@@ check ordering of operands in intel/nonintel syntax
19728 "maskmovq\t{%2, %1|%1, %2}"
19729 [(set_attr "type" "mmxcvt")
19730 (set_attr "mode" "DI")])
19731
19732 (define_insn "mmx_maskmovq_rex"
19733 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19734 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19735 (match_operand:V8QI 2 "register_operand" "y")]
19736 UNSPEC_MASKMOV))]
19737 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19738 ;; @@@ check ordering of operands in intel/nonintel syntax
19739 "maskmovq\t{%2, %1|%1, %2}"
19740 [(set_attr "type" "mmxcvt")
19741 (set_attr "mode" "DI")])
19742
19743 (define_insn "sse_movntv4sf"
19744 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19745 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19746 UNSPEC_MOVNT))]
19747 "TARGET_SSE"
19748 "movntps\t{%1, %0|%0, %1}"
19749 [(set_attr "type" "ssemov")
19750 (set_attr "mode" "V4SF")])
19751
19752 (define_insn "sse_movntdi"
19753 [(set (match_operand:DI 0 "memory_operand" "=m")
19754 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19755 UNSPEC_MOVNT))]
19756 "TARGET_SSE || TARGET_3DNOW_A"
19757 "movntq\t{%1, %0|%0, %1}"
19758 [(set_attr "type" "mmxmov")
19759 (set_attr "mode" "DI")])
19760
19761 (define_insn "sse_movhlps"
19762 [(set (match_operand:V4SF 0 "register_operand" "=x")
19763 (vec_merge:V4SF
19764 (match_operand:V4SF 1 "register_operand" "0")
19765 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19766 (parallel [(const_int 2)
19767 (const_int 3)
19768 (const_int 0)
19769 (const_int 1)]))
19770 (const_int 3)))]
19771 "TARGET_SSE"
19772 "movhlps\t{%2, %0|%0, %2}"
19773 [(set_attr "type" "ssecvt")
19774 (set_attr "mode" "V4SF")])
19775
19776 (define_insn "sse_movlhps"
19777 [(set (match_operand:V4SF 0 "register_operand" "=x")
19778 (vec_merge:V4SF
19779 (match_operand:V4SF 1 "register_operand" "0")
19780 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19781 (parallel [(const_int 2)
19782 (const_int 3)
19783 (const_int 0)
19784 (const_int 1)]))
19785 (const_int 12)))]
19786 "TARGET_SSE"
19787 "movlhps\t{%2, %0|%0, %2}"
19788 [(set_attr "type" "ssecvt")
19789 (set_attr "mode" "V4SF")])
19790
19791 (define_insn "sse_movhps"
19792 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19793 (vec_merge:V4SF
19794 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19795 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19796 (const_int 12)))]
19797 "TARGET_SSE
19798 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19799 "movhps\t{%2, %0|%0, %2}"
19800 [(set_attr "type" "ssecvt")
19801 (set_attr "mode" "V4SF")])
19802
19803 (define_insn "sse_movlps"
19804 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19805 (vec_merge:V4SF
19806 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19807 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19808 (const_int 3)))]
19809 "TARGET_SSE
19810 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19811 "movlps\t{%2, %0|%0, %2}"
19812 [(set_attr "type" "ssecvt")
19813 (set_attr "mode" "V4SF")])
19814
19815 (define_expand "sse_loadss"
19816 [(match_operand:V4SF 0 "register_operand" "")
19817 (match_operand:SF 1 "memory_operand" "")]
19818 "TARGET_SSE"
19819 {
19820 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19821 CONST0_RTX (V4SFmode)));
19822 DONE;
19823 })
19824
19825 (define_insn "sse_loadss_1"
19826 [(set (match_operand:V4SF 0 "register_operand" "=x")
19827 (vec_merge:V4SF
19828 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19829 (match_operand:V4SF 2 "const0_operand" "X")
19830 (const_int 1)))]
19831 "TARGET_SSE"
19832 "movss\t{%1, %0|%0, %1}"
19833 [(set_attr "type" "ssemov")
19834 (set_attr "mode" "SF")])
19835
19836 (define_insn "sse_movss"
19837 [(set (match_operand:V4SF 0 "register_operand" "=x")
19838 (vec_merge:V4SF
19839 (match_operand:V4SF 1 "register_operand" "0")
19840 (match_operand:V4SF 2 "register_operand" "x")
19841 (const_int 1)))]
19842 "TARGET_SSE"
19843 "movss\t{%2, %0|%0, %2}"
19844 [(set_attr "type" "ssemov")
19845 (set_attr "mode" "SF")])
19846
19847 (define_insn "sse_storess"
19848 [(set (match_operand:SF 0 "memory_operand" "=m")
19849 (vec_select:SF
19850 (match_operand:V4SF 1 "register_operand" "x")
19851 (parallel [(const_int 0)])))]
19852 "TARGET_SSE"
19853 "movss\t{%1, %0|%0, %1}"
19854 [(set_attr "type" "ssemov")
19855 (set_attr "mode" "SF")])
19856
19857 (define_insn "sse_shufps"
19858 [(set (match_operand:V4SF 0 "register_operand" "=x")
19859 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19860 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19861 (match_operand:SI 3 "immediate_operand" "i")]
19862 UNSPEC_SHUFFLE))]
19863 "TARGET_SSE"
19864 ;; @@@ check operand order for intel/nonintel syntax
19865 "shufps\t{%3, %2, %0|%0, %2, %3}"
19866 [(set_attr "type" "ssecvt")
19867 (set_attr "mode" "V4SF")])
19868
19869
19870 ;; SSE arithmetic
19871
19872 (define_insn "addv4sf3"
19873 [(set (match_operand:V4SF 0 "register_operand" "=x")
19874 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19875 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19876 "TARGET_SSE"
19877 "addps\t{%2, %0|%0, %2}"
19878 [(set_attr "type" "sseadd")
19879 (set_attr "mode" "V4SF")])
19880
19881 (define_insn "vmaddv4sf3"
19882 [(set (match_operand:V4SF 0 "register_operand" "=x")
19883 (vec_merge:V4SF
19884 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19885 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19886 (match_dup 1)
19887 (const_int 1)))]
19888 "TARGET_SSE"
19889 "addss\t{%2, %0|%0, %2}"
19890 [(set_attr "type" "sseadd")
19891 (set_attr "mode" "SF")])
19892
19893 (define_insn "subv4sf3"
19894 [(set (match_operand:V4SF 0 "register_operand" "=x")
19895 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19896 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19897 "TARGET_SSE"
19898 "subps\t{%2, %0|%0, %2}"
19899 [(set_attr "type" "sseadd")
19900 (set_attr "mode" "V4SF")])
19901
19902 (define_insn "vmsubv4sf3"
19903 [(set (match_operand:V4SF 0 "register_operand" "=x")
19904 (vec_merge:V4SF
19905 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19906 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19907 (match_dup 1)
19908 (const_int 1)))]
19909 "TARGET_SSE"
19910 "subss\t{%2, %0|%0, %2}"
19911 [(set_attr "type" "sseadd")
19912 (set_attr "mode" "SF")])
19913
19914 (define_insn "mulv4sf3"
19915 [(set (match_operand:V4SF 0 "register_operand" "=x")
19916 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19917 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19918 "TARGET_SSE"
19919 "mulps\t{%2, %0|%0, %2}"
19920 [(set_attr "type" "ssemul")
19921 (set_attr "mode" "V4SF")])
19922
19923 (define_insn "vmmulv4sf3"
19924 [(set (match_operand:V4SF 0 "register_operand" "=x")
19925 (vec_merge:V4SF
19926 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19927 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19928 (match_dup 1)
19929 (const_int 1)))]
19930 "TARGET_SSE"
19931 "mulss\t{%2, %0|%0, %2}"
19932 [(set_attr "type" "ssemul")
19933 (set_attr "mode" "SF")])
19934
19935 (define_insn "divv4sf3"
19936 [(set (match_operand:V4SF 0 "register_operand" "=x")
19937 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19938 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19939 "TARGET_SSE"
19940 "divps\t{%2, %0|%0, %2}"
19941 [(set_attr "type" "ssediv")
19942 (set_attr "mode" "V4SF")])
19943
19944 (define_insn "vmdivv4sf3"
19945 [(set (match_operand:V4SF 0 "register_operand" "=x")
19946 (vec_merge:V4SF
19947 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19948 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19949 (match_dup 1)
19950 (const_int 1)))]
19951 "TARGET_SSE"
19952 "divss\t{%2, %0|%0, %2}"
19953 [(set_attr "type" "ssediv")
19954 (set_attr "mode" "SF")])
19955
19956
19957 ;; SSE square root/reciprocal
19958
19959 (define_insn "rcpv4sf2"
19960 [(set (match_operand:V4SF 0 "register_operand" "=x")
19961 (unspec:V4SF
19962 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19963 "TARGET_SSE"
19964 "rcpps\t{%1, %0|%0, %1}"
19965 [(set_attr "type" "sse")
19966 (set_attr "mode" "V4SF")])
19967
19968 (define_insn "vmrcpv4sf2"
19969 [(set (match_operand:V4SF 0 "register_operand" "=x")
19970 (vec_merge:V4SF
19971 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19972 UNSPEC_RCP)
19973 (match_operand:V4SF 2 "register_operand" "0")
19974 (const_int 1)))]
19975 "TARGET_SSE"
19976 "rcpss\t{%1, %0|%0, %1}"
19977 [(set_attr "type" "sse")
19978 (set_attr "mode" "SF")])
19979
19980 (define_insn "rsqrtv4sf2"
19981 [(set (match_operand:V4SF 0 "register_operand" "=x")
19982 (unspec:V4SF
19983 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19984 "TARGET_SSE"
19985 "rsqrtps\t{%1, %0|%0, %1}"
19986 [(set_attr "type" "sse")
19987 (set_attr "mode" "V4SF")])
19988
19989 (define_insn "vmrsqrtv4sf2"
19990 [(set (match_operand:V4SF 0 "register_operand" "=x")
19991 (vec_merge:V4SF
19992 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19993 UNSPEC_RSQRT)
19994 (match_operand:V4SF 2 "register_operand" "0")
19995 (const_int 1)))]
19996 "TARGET_SSE"
19997 "rsqrtss\t{%1, %0|%0, %1}"
19998 [(set_attr "type" "sse")
19999 (set_attr "mode" "SF")])
20000
20001 (define_insn "sqrtv4sf2"
20002 [(set (match_operand:V4SF 0 "register_operand" "=x")
20003 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20004 "TARGET_SSE"
20005 "sqrtps\t{%1, %0|%0, %1}"
20006 [(set_attr "type" "sse")
20007 (set_attr "mode" "V4SF")])
20008
20009 (define_insn "vmsqrtv4sf2"
20010 [(set (match_operand:V4SF 0 "register_operand" "=x")
20011 (vec_merge:V4SF
20012 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20013 (match_operand:V4SF 2 "register_operand" "0")
20014 (const_int 1)))]
20015 "TARGET_SSE"
20016 "sqrtss\t{%1, %0|%0, %1}"
20017 [(set_attr "type" "sse")
20018 (set_attr "mode" "SF")])
20019
20020 ;; SSE logical operations.
20021
20022 ;; SSE defines logical operations on floating point values. This brings
20023 ;; interesting challenge to RTL representation where logicals are only valid
20024 ;; on integral types. We deal with this by representing the floating point
20025 ;; logical as logical on arguments casted to TImode as this is what hardware
20026 ;; really does. Unfortunately hardware requires the type information to be
20027 ;; present and thus we must avoid subregs from being simplified and eliminated
20028 ;; in later compilation phases.
20029 ;;
20030 ;; We have following variants from each instruction:
20031 ;; sse_andsf3 - the operation taking V4SF vector operands
20032 ;; and doing TImode cast on them
20033 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20034 ;; TImode, since backend insist on eliminating casts
20035 ;; on memory operands
20036 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20037 ;; We can not accept memory operand here as instruction reads
20038 ;; whole scalar. This is generated only post reload by GCC
20039 ;; scalar float operations that expands to logicals (fabs)
20040 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20041 ;; memory operand. Eventually combine can be able
20042 ;; to synthesize these using splitter.
20043 ;; sse2_anddf3, *sse2_anddf3_memory
20044 ;;
20045 ;;
20046 ;; These are not called andti3 etc. because we really really don't want
20047 ;; the compiler to widen DImode ands to TImode ands and then try to move
20048 ;; into DImode subregs of SSE registers, and them together, and move out
20049 ;; of DImode subregs again!
20050 ;; SSE1 single precision floating point logical operation
20051 (define_expand "sse_andv4sf3"
20052 [(set (match_operand:V4SF 0 "register_operand" "")
20053 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
20054 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20055 "TARGET_SSE"
20056 "")
20057
20058 (define_insn "*sse_andv4sf3"
20059 [(set (match_operand:V4SF 0 "register_operand" "=x")
20060 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20061 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20062 "TARGET_SSE
20063 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20064 "andps\t{%2, %0|%0, %2}"
20065 [(set_attr "type" "sselog")
20066 (set_attr "mode" "V4SF")])
20067
20068 (define_expand "sse_nandv4sf3"
20069 [(set (match_operand:V4SF 0 "register_operand" "")
20070 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
20071 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20072 "TARGET_SSE"
20073 "")
20074
20075 (define_insn "*sse_nandv4sf3"
20076 [(set (match_operand:V4SF 0 "register_operand" "=x")
20077 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
20078 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20079 "TARGET_SSE"
20080 "andnps\t{%2, %0|%0, %2}"
20081 [(set_attr "type" "sselog")
20082 (set_attr "mode" "V4SF")])
20083
20084 (define_expand "sse_iorv4sf3"
20085 [(set (match_operand:V4SF 0 "register_operand" "")
20086 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
20087 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20088 "TARGET_SSE"
20089 "")
20090
20091 (define_insn "*sse_iorv4sf3"
20092 [(set (match_operand:V4SF 0 "register_operand" "=x")
20093 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20094 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20095 "TARGET_SSE
20096 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20097 "orps\t{%2, %0|%0, %2}"
20098 [(set_attr "type" "sselog")
20099 (set_attr "mode" "V4SF")])
20100
20101 (define_expand "sse_xorv4sf3"
20102 [(set (match_operand:V4SF 0 "register_operand" "")
20103 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
20104 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
20105 "TARGET_SSE"
20106 "")
20107
20108 (define_insn "*sse_xorv4sf3"
20109 [(set (match_operand:V4SF 0 "register_operand" "=x")
20110 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
20111 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20112 "TARGET_SSE
20113 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20114 "xorps\t{%2, %0|%0, %2}"
20115 [(set_attr "type" "sselog")
20116 (set_attr "mode" "V4SF")])
20117
20118 ;; SSE2 double precision floating point logical operation
20119
20120 (define_expand "sse2_andv2df3"
20121 [(set (match_operand:V2DF 0 "register_operand" "")
20122 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
20123 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20124 "TARGET_SSE2"
20125 "")
20126
20127 (define_insn "*sse2_andv2df3"
20128 [(set (match_operand:V2DF 0 "register_operand" "=x")
20129 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20130 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20131 "TARGET_SSE2
20132 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20133 "andpd\t{%2, %0|%0, %2}"
20134 [(set_attr "type" "sselog")
20135 (set_attr "mode" "V2DF")])
20136
20137 (define_expand "sse2_nandv2df3"
20138 [(set (match_operand:V2DF 0 "register_operand" "")
20139 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
20140 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20141 "TARGET_SSE2"
20142 "")
20143
20144 (define_insn "*sse2_nandv2df3"
20145 [(set (match_operand:V2DF 0 "register_operand" "=x")
20146 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
20147 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20148 "TARGET_SSE2"
20149 "andnpd\t{%2, %0|%0, %2}"
20150 [(set_attr "type" "sselog")
20151 (set_attr "mode" "V2DF")])
20152
20153 (define_expand "sse2_iorv2df3"
20154 [(set (match_operand:V2DF 0 "register_operand" "")
20155 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
20156 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20157 "TARGET_SSE2"
20158 "")
20159
20160 (define_insn "*sse2_iorv2df3"
20161 [(set (match_operand:V2DF 0 "register_operand" "=x")
20162 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20163 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20164 "TARGET_SSE2
20165 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20166 "orpd\t{%2, %0|%0, %2}"
20167 [(set_attr "type" "sselog")
20168 (set_attr "mode" "V2DF")])
20169
20170 (define_expand "sse2_xorv2df3"
20171 [(set (match_operand:V2DF 0 "register_operand" "")
20172 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
20173 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
20174 "TARGET_SSE2"
20175 "")
20176
20177 (define_insn "*sse2_xorv2df3"
20178 [(set (match_operand:V2DF 0 "register_operand" "=x")
20179 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
20180 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
20181 "TARGET_SSE2
20182 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20183 "xorpd\t{%2, %0|%0, %2}"
20184 [(set_attr "type" "sselog")
20185 (set_attr "mode" "V2DF")])
20186
20187 ;; SSE2 integral logicals. These patterns must always come after floating
20188 ;; point ones since we don't want compiler to use integer opcodes on floating
20189 ;; point SSE values to avoid matching of subregs in the match_operand.
20190 (define_insn "*sse2_andti3"
20191 [(set (match_operand:TI 0 "register_operand" "=x")
20192 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20193 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20194 "TARGET_SSE2
20195 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20196 "pand\t{%2, %0|%0, %2}"
20197 [(set_attr "type" "sselog")
20198 (set_attr "mode" "TI")])
20199
20200 (define_insn "sse2_andv2di3"
20201 [(set (match_operand:V2DI 0 "register_operand" "=x")
20202 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20203 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20204 "TARGET_SSE2
20205 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20206 "pand\t{%2, %0|%0, %2}"
20207 [(set_attr "type" "sselog")
20208 (set_attr "mode" "TI")])
20209
20210 (define_insn "*sse2_nandti3"
20211 [(set (match_operand:TI 0 "register_operand" "=x")
20212 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20213 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20214 "TARGET_SSE2"
20215 "pandn\t{%2, %0|%0, %2}"
20216 [(set_attr "type" "sselog")
20217 (set_attr "mode" "TI")])
20218
20219 (define_insn "sse2_nandv2di3"
20220 [(set (match_operand:V2DI 0 "register_operand" "=x")
20221 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20222 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20223 "TARGET_SSE2
20224 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20225 "pandn\t{%2, %0|%0, %2}"
20226 [(set_attr "type" "sselog")
20227 (set_attr "mode" "TI")])
20228
20229 (define_insn "*sse2_iorti3"
20230 [(set (match_operand:TI 0 "register_operand" "=x")
20231 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20232 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20233 "TARGET_SSE2
20234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20235 "por\t{%2, %0|%0, %2}"
20236 [(set_attr "type" "sselog")
20237 (set_attr "mode" "TI")])
20238
20239 (define_insn "sse2_iorv2di3"
20240 [(set (match_operand:V2DI 0 "register_operand" "=x")
20241 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20242 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20243 "TARGET_SSE2
20244 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20245 "por\t{%2, %0|%0, %2}"
20246 [(set_attr "type" "sselog")
20247 (set_attr "mode" "TI")])
20248
20249 (define_insn "*sse2_xorti3"
20250 [(set (match_operand:TI 0 "register_operand" "=x")
20251 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20252 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20253 "TARGET_SSE2
20254 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20255 "pxor\t{%2, %0|%0, %2}"
20256 [(set_attr "type" "sselog")
20257 (set_attr "mode" "TI")])
20258
20259 (define_insn "sse2_xorv2di3"
20260 [(set (match_operand:V2DI 0 "register_operand" "=x")
20261 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20262 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20263 "TARGET_SSE2
20264 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20265 "pxor\t{%2, %0|%0, %2}"
20266 [(set_attr "type" "sselog")
20267 (set_attr "mode" "TI")])
20268
20269 ;; Use xor, but don't show input operands so they aren't live before
20270 ;; this insn.
20271 (define_insn "sse_clrv4sf"
20272 [(set (match_operand:V4SF 0 "register_operand" "=x")
20273 (match_operand:V4SF 1 "const0_operand" "X"))]
20274 "TARGET_SSE"
20275 {
20276 if (get_attr_mode (insn) == MODE_TI)
20277 return "pxor\t{%0, %0|%0, %0}";
20278 else
20279 return "xorps\t{%0, %0|%0, %0}";
20280 }
20281 [(set_attr "type" "sselog")
20282 (set_attr "memory" "none")
20283 (set (attr "mode")
20284 (if_then_else
20285 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20286 (const_int 0))
20287 (ne (symbol_ref "TARGET_SSE2")
20288 (const_int 0)))
20289 (eq (symbol_ref "optimize_size")
20290 (const_int 0)))
20291 (const_string "TI")
20292 (const_string "V4SF")))])
20293
20294 ;; Use xor, but don't show input operands so they aren't live before
20295 ;; this insn.
20296 (define_insn "sse_clrv2df"
20297 [(set (match_operand:V2DF 0 "register_operand" "=x")
20298 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20299 "TARGET_SSE2"
20300 "xorpd\t{%0, %0|%0, %0}"
20301 [(set_attr "type" "sselog")
20302 (set_attr "memory" "none")
20303 (set_attr "mode" "V4SF")])
20304
20305 ;; SSE mask-generating compares
20306
20307 (define_insn "maskcmpv4sf3"
20308 [(set (match_operand:V4SI 0 "register_operand" "=x")
20309 (match_operator:V4SI 3 "sse_comparison_operator"
20310 [(match_operand:V4SF 1 "register_operand" "0")
20311 (match_operand:V4SF 2 "register_operand" "x")]))]
20312 "TARGET_SSE"
20313 "cmp%D3ps\t{%2, %0|%0, %2}"
20314 [(set_attr "type" "ssecmp")
20315 (set_attr "mode" "V4SF")])
20316
20317 (define_insn "maskncmpv4sf3"
20318 [(set (match_operand:V4SI 0 "register_operand" "=x")
20319 (not:V4SI
20320 (match_operator:V4SI 3 "sse_comparison_operator"
20321 [(match_operand:V4SF 1 "register_operand" "0")
20322 (match_operand:V4SF 2 "register_operand" "x")])))]
20323 "TARGET_SSE"
20324 {
20325 if (GET_CODE (operands[3]) == UNORDERED)
20326 return "cmpordps\t{%2, %0|%0, %2}";
20327 else
20328 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20329 }
20330 [(set_attr "type" "ssecmp")
20331 (set_attr "mode" "V4SF")])
20332
20333 (define_insn "vmmaskcmpv4sf3"
20334 [(set (match_operand:V4SI 0 "register_operand" "=x")
20335 (vec_merge:V4SI
20336 (match_operator:V4SI 3 "sse_comparison_operator"
20337 [(match_operand:V4SF 1 "register_operand" "0")
20338 (match_operand:V4SF 2 "register_operand" "x")])
20339 (subreg:V4SI (match_dup 1) 0)
20340 (const_int 1)))]
20341 "TARGET_SSE"
20342 "cmp%D3ss\t{%2, %0|%0, %2}"
20343 [(set_attr "type" "ssecmp")
20344 (set_attr "mode" "SF")])
20345
20346 (define_insn "vmmaskncmpv4sf3"
20347 [(set (match_operand:V4SI 0 "register_operand" "=x")
20348 (vec_merge:V4SI
20349 (not:V4SI
20350 (match_operator:V4SI 3 "sse_comparison_operator"
20351 [(match_operand:V4SF 1 "register_operand" "0")
20352 (match_operand:V4SF 2 "register_operand" "x")]))
20353 (subreg:V4SI (match_dup 1) 0)
20354 (const_int 1)))]
20355 "TARGET_SSE"
20356 {
20357 if (GET_CODE (operands[3]) == UNORDERED)
20358 return "cmpordss\t{%2, %0|%0, %2}";
20359 else
20360 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20361 }
20362 [(set_attr "type" "ssecmp")
20363 (set_attr "mode" "SF")])
20364
20365 (define_insn "sse_comi"
20366 [(set (reg:CCFP 17)
20367 (compare:CCFP (vec_select:SF
20368 (match_operand:V4SF 0 "register_operand" "x")
20369 (parallel [(const_int 0)]))
20370 (vec_select:SF
20371 (match_operand:V4SF 1 "register_operand" "x")
20372 (parallel [(const_int 0)]))))]
20373 "TARGET_SSE"
20374 "comiss\t{%1, %0|%0, %1}"
20375 [(set_attr "type" "ssecomi")
20376 (set_attr "mode" "SF")])
20377
20378 (define_insn "sse_ucomi"
20379 [(set (reg:CCFPU 17)
20380 (compare:CCFPU (vec_select:SF
20381 (match_operand:V4SF 0 "register_operand" "x")
20382 (parallel [(const_int 0)]))
20383 (vec_select:SF
20384 (match_operand:V4SF 1 "register_operand" "x")
20385 (parallel [(const_int 0)]))))]
20386 "TARGET_SSE"
20387 "ucomiss\t{%1, %0|%0, %1}"
20388 [(set_attr "type" "ssecomi")
20389 (set_attr "mode" "SF")])
20390
20391
20392 ;; SSE unpack
20393
20394 (define_insn "sse_unpckhps"
20395 [(set (match_operand:V4SF 0 "register_operand" "=x")
20396 (vec_merge:V4SF
20397 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20398 (parallel [(const_int 2)
20399 (const_int 0)
20400 (const_int 3)
20401 (const_int 1)]))
20402 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20403 (parallel [(const_int 0)
20404 (const_int 2)
20405 (const_int 1)
20406 (const_int 3)]))
20407 (const_int 5)))]
20408 "TARGET_SSE"
20409 "unpckhps\t{%2, %0|%0, %2}"
20410 [(set_attr "type" "ssecvt")
20411 (set_attr "mode" "V4SF")])
20412
20413 (define_insn "sse_unpcklps"
20414 [(set (match_operand:V4SF 0 "register_operand" "=x")
20415 (vec_merge:V4SF
20416 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20417 (parallel [(const_int 0)
20418 (const_int 2)
20419 (const_int 1)
20420 (const_int 3)]))
20421 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20422 (parallel [(const_int 2)
20423 (const_int 0)
20424 (const_int 3)
20425 (const_int 1)]))
20426 (const_int 5)))]
20427 "TARGET_SSE"
20428 "unpcklps\t{%2, %0|%0, %2}"
20429 [(set_attr "type" "ssecvt")
20430 (set_attr "mode" "V4SF")])
20431
20432
20433 ;; SSE min/max
20434
20435 (define_insn "smaxv4sf3"
20436 [(set (match_operand:V4SF 0 "register_operand" "=x")
20437 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20438 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20439 "TARGET_SSE"
20440 "maxps\t{%2, %0|%0, %2}"
20441 [(set_attr "type" "sse")
20442 (set_attr "mode" "V4SF")])
20443
20444 (define_insn "vmsmaxv4sf3"
20445 [(set (match_operand:V4SF 0 "register_operand" "=x")
20446 (vec_merge:V4SF
20447 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20448 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20449 (match_dup 1)
20450 (const_int 1)))]
20451 "TARGET_SSE"
20452 "maxss\t{%2, %0|%0, %2}"
20453 [(set_attr "type" "sse")
20454 (set_attr "mode" "SF")])
20455
20456 (define_insn "sminv4sf3"
20457 [(set (match_operand:V4SF 0 "register_operand" "=x")
20458 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20459 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20460 "TARGET_SSE"
20461 "minps\t{%2, %0|%0, %2}"
20462 [(set_attr "type" "sse")
20463 (set_attr "mode" "V4SF")])
20464
20465 (define_insn "vmsminv4sf3"
20466 [(set (match_operand:V4SF 0 "register_operand" "=x")
20467 (vec_merge:V4SF
20468 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20469 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20470 (match_dup 1)
20471 (const_int 1)))]
20472 "TARGET_SSE"
20473 "minss\t{%2, %0|%0, %2}"
20474 [(set_attr "type" "sse")
20475 (set_attr "mode" "SF")])
20476
20477 ;; SSE <-> integer/MMX conversions
20478
20479 (define_insn "cvtpi2ps"
20480 [(set (match_operand:V4SF 0 "register_operand" "=x")
20481 (vec_merge:V4SF
20482 (match_operand:V4SF 1 "register_operand" "0")
20483 (vec_duplicate:V4SF
20484 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20485 (const_int 12)))]
20486 "TARGET_SSE"
20487 "cvtpi2ps\t{%2, %0|%0, %2}"
20488 [(set_attr "type" "ssecvt")
20489 (set_attr "mode" "V4SF")])
20490
20491 (define_insn "cvtps2pi"
20492 [(set (match_operand:V2SI 0 "register_operand" "=y")
20493 (vec_select:V2SI
20494 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20495 (parallel [(const_int 0) (const_int 1)])))]
20496 "TARGET_SSE"
20497 "cvtps2pi\t{%1, %0|%0, %1}"
20498 [(set_attr "type" "ssecvt")
20499 (set_attr "mode" "V4SF")])
20500
20501 (define_insn "cvttps2pi"
20502 [(set (match_operand:V2SI 0 "register_operand" "=y")
20503 (vec_select:V2SI
20504 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20505 UNSPEC_FIX)
20506 (parallel [(const_int 0) (const_int 1)])))]
20507 "TARGET_SSE"
20508 "cvttps2pi\t{%1, %0|%0, %1}"
20509 [(set_attr "type" "ssecvt")
20510 (set_attr "mode" "SF")])
20511
20512 (define_insn "cvtsi2ss"
20513 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20514 (vec_merge:V4SF
20515 (match_operand:V4SF 1 "register_operand" "0,0")
20516 (vec_duplicate:V4SF
20517 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20518 (const_int 14)))]
20519 "TARGET_SSE"
20520 "cvtsi2ss\t{%2, %0|%0, %2}"
20521 [(set_attr "type" "sseicvt")
20522 (set_attr "athlon_decode" "vector,double")
20523 (set_attr "mode" "SF")])
20524
20525 (define_insn "cvtsi2ssq"
20526 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20527 (vec_merge:V4SF
20528 (match_operand:V4SF 1 "register_operand" "0,0")
20529 (vec_duplicate:V4SF
20530 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20531 (const_int 14)))]
20532 "TARGET_SSE && TARGET_64BIT"
20533 "cvtsi2ssq\t{%2, %0|%0, %2}"
20534 [(set_attr "type" "sseicvt")
20535 (set_attr "athlon_decode" "vector,double")
20536 (set_attr "mode" "SF")])
20537
20538 (define_insn "cvtss2si"
20539 [(set (match_operand:SI 0 "register_operand" "=r,r")
20540 (vec_select:SI
20541 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20542 (parallel [(const_int 0)])))]
20543 "TARGET_SSE"
20544 "cvtss2si\t{%1, %0|%0, %1}"
20545 [(set_attr "type" "sseicvt")
20546 (set_attr "athlon_decode" "double,vector")
20547 (set_attr "mode" "SI")])
20548
20549 (define_insn "cvtss2siq"
20550 [(set (match_operand:DI 0 "register_operand" "=r,r")
20551 (vec_select:DI
20552 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20553 (parallel [(const_int 0)])))]
20554 "TARGET_SSE"
20555 "cvtss2siq\t{%1, %0|%0, %1}"
20556 [(set_attr "type" "sseicvt")
20557 (set_attr "athlon_decode" "double,vector")
20558 (set_attr "mode" "DI")])
20559
20560 (define_insn "cvttss2si"
20561 [(set (match_operand:SI 0 "register_operand" "=r,r")
20562 (vec_select:SI
20563 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20564 UNSPEC_FIX)
20565 (parallel [(const_int 0)])))]
20566 "TARGET_SSE"
20567 "cvttss2si\t{%1, %0|%0, %1}"
20568 [(set_attr "type" "sseicvt")
20569 (set_attr "mode" "SF")
20570 (set_attr "athlon_decode" "double,vector")])
20571
20572 (define_insn "cvttss2siq"
20573 [(set (match_operand:DI 0 "register_operand" "=r,r")
20574 (vec_select:DI
20575 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20576 UNSPEC_FIX)
20577 (parallel [(const_int 0)])))]
20578 "TARGET_SSE && TARGET_64BIT"
20579 "cvttss2siq\t{%1, %0|%0, %1}"
20580 [(set_attr "type" "sseicvt")
20581 (set_attr "mode" "SF")
20582 (set_attr "athlon_decode" "double,vector")])
20583
20584
20585 ;; MMX insns
20586
20587 ;; MMX arithmetic
20588
20589 (define_insn "addv8qi3"
20590 [(set (match_operand:V8QI 0 "register_operand" "=y")
20591 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20592 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20593 "TARGET_MMX"
20594 "paddb\t{%2, %0|%0, %2}"
20595 [(set_attr "type" "mmxadd")
20596 (set_attr "mode" "DI")])
20597
20598 (define_insn "addv4hi3"
20599 [(set (match_operand:V4HI 0 "register_operand" "=y")
20600 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20601 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20602 "TARGET_MMX"
20603 "paddw\t{%2, %0|%0, %2}"
20604 [(set_attr "type" "mmxadd")
20605 (set_attr "mode" "DI")])
20606
20607 (define_insn "addv2si3"
20608 [(set (match_operand:V2SI 0 "register_operand" "=y")
20609 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20610 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20611 "TARGET_MMX"
20612 "paddd\t{%2, %0|%0, %2}"
20613 [(set_attr "type" "mmxadd")
20614 (set_attr "mode" "DI")])
20615
20616 (define_insn "mmx_adddi3"
20617 [(set (match_operand:DI 0 "register_operand" "=y")
20618 (unspec:DI
20619 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20620 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20621 UNSPEC_NOP))]
20622 "TARGET_MMX"
20623 "paddq\t{%2, %0|%0, %2}"
20624 [(set_attr "type" "mmxadd")
20625 (set_attr "mode" "DI")])
20626
20627 (define_insn "ssaddv8qi3"
20628 [(set (match_operand:V8QI 0 "register_operand" "=y")
20629 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20630 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20631 "TARGET_MMX"
20632 "paddsb\t{%2, %0|%0, %2}"
20633 [(set_attr "type" "mmxadd")
20634 (set_attr "mode" "DI")])
20635
20636 (define_insn "ssaddv4hi3"
20637 [(set (match_operand:V4HI 0 "register_operand" "=y")
20638 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20639 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20640 "TARGET_MMX"
20641 "paddsw\t{%2, %0|%0, %2}"
20642 [(set_attr "type" "mmxadd")
20643 (set_attr "mode" "DI")])
20644
20645 (define_insn "usaddv8qi3"
20646 [(set (match_operand:V8QI 0 "register_operand" "=y")
20647 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20648 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20649 "TARGET_MMX"
20650 "paddusb\t{%2, %0|%0, %2}"
20651 [(set_attr "type" "mmxadd")
20652 (set_attr "mode" "DI")])
20653
20654 (define_insn "usaddv4hi3"
20655 [(set (match_operand:V4HI 0 "register_operand" "=y")
20656 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20657 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20658 "TARGET_MMX"
20659 "paddusw\t{%2, %0|%0, %2}"
20660 [(set_attr "type" "mmxadd")
20661 (set_attr "mode" "DI")])
20662
20663 (define_insn "subv8qi3"
20664 [(set (match_operand:V8QI 0 "register_operand" "=y")
20665 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20666 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20667 "TARGET_MMX"
20668 "psubb\t{%2, %0|%0, %2}"
20669 [(set_attr "type" "mmxadd")
20670 (set_attr "mode" "DI")])
20671
20672 (define_insn "subv4hi3"
20673 [(set (match_operand:V4HI 0 "register_operand" "=y")
20674 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20675 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20676 "TARGET_MMX"
20677 "psubw\t{%2, %0|%0, %2}"
20678 [(set_attr "type" "mmxadd")
20679 (set_attr "mode" "DI")])
20680
20681 (define_insn "subv2si3"
20682 [(set (match_operand:V2SI 0 "register_operand" "=y")
20683 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20684 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20685 "TARGET_MMX"
20686 "psubd\t{%2, %0|%0, %2}"
20687 [(set_attr "type" "mmxadd")
20688 (set_attr "mode" "DI")])
20689
20690 (define_insn "mmx_subdi3"
20691 [(set (match_operand:DI 0 "register_operand" "=y")
20692 (unspec:DI
20693 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20694 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20695 UNSPEC_NOP))]
20696 "TARGET_MMX"
20697 "psubq\t{%2, %0|%0, %2}"
20698 [(set_attr "type" "mmxadd")
20699 (set_attr "mode" "DI")])
20700
20701 (define_insn "sssubv8qi3"
20702 [(set (match_operand:V8QI 0 "register_operand" "=y")
20703 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20704 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20705 "TARGET_MMX"
20706 "psubsb\t{%2, %0|%0, %2}"
20707 [(set_attr "type" "mmxadd")
20708 (set_attr "mode" "DI")])
20709
20710 (define_insn "sssubv4hi3"
20711 [(set (match_operand:V4HI 0 "register_operand" "=y")
20712 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20713 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20714 "TARGET_MMX"
20715 "psubsw\t{%2, %0|%0, %2}"
20716 [(set_attr "type" "mmxadd")
20717 (set_attr "mode" "DI")])
20718
20719 (define_insn "ussubv8qi3"
20720 [(set (match_operand:V8QI 0 "register_operand" "=y")
20721 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20722 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20723 "TARGET_MMX"
20724 "psubusb\t{%2, %0|%0, %2}"
20725 [(set_attr "type" "mmxadd")
20726 (set_attr "mode" "DI")])
20727
20728 (define_insn "ussubv4hi3"
20729 [(set (match_operand:V4HI 0 "register_operand" "=y")
20730 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20731 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20732 "TARGET_MMX"
20733 "psubusw\t{%2, %0|%0, %2}"
20734 [(set_attr "type" "mmxadd")
20735 (set_attr "mode" "DI")])
20736
20737 (define_insn "mulv4hi3"
20738 [(set (match_operand:V4HI 0 "register_operand" "=y")
20739 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20740 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20741 "TARGET_MMX"
20742 "pmullw\t{%2, %0|%0, %2}"
20743 [(set_attr "type" "mmxmul")
20744 (set_attr "mode" "DI")])
20745
20746 (define_insn "smulv4hi3_highpart"
20747 [(set (match_operand:V4HI 0 "register_operand" "=y")
20748 (truncate:V4HI
20749 (lshiftrt:V4SI
20750 (mult:V4SI (sign_extend:V4SI
20751 (match_operand:V4HI 1 "register_operand" "0"))
20752 (sign_extend:V4SI
20753 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20754 (const_int 16))))]
20755 "TARGET_MMX"
20756 "pmulhw\t{%2, %0|%0, %2}"
20757 [(set_attr "type" "mmxmul")
20758 (set_attr "mode" "DI")])
20759
20760 (define_insn "umulv4hi3_highpart"
20761 [(set (match_operand:V4HI 0 "register_operand" "=y")
20762 (truncate:V4HI
20763 (lshiftrt:V4SI
20764 (mult:V4SI (zero_extend:V4SI
20765 (match_operand:V4HI 1 "register_operand" "0"))
20766 (zero_extend:V4SI
20767 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20768 (const_int 16))))]
20769 "TARGET_SSE || TARGET_3DNOW_A"
20770 "pmulhuw\t{%2, %0|%0, %2}"
20771 [(set_attr "type" "mmxmul")
20772 (set_attr "mode" "DI")])
20773
20774 (define_insn "mmx_pmaddwd"
20775 [(set (match_operand:V2SI 0 "register_operand" "=y")
20776 (plus:V2SI
20777 (mult:V2SI
20778 (sign_extend:V2SI
20779 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20780 (parallel [(const_int 0) (const_int 2)])))
20781 (sign_extend:V2SI
20782 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20783 (parallel [(const_int 0) (const_int 2)]))))
20784 (mult:V2SI
20785 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20786 (parallel [(const_int 1)
20787 (const_int 3)])))
20788 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20789 (parallel [(const_int 1)
20790 (const_int 3)]))))))]
20791 "TARGET_MMX"
20792 "pmaddwd\t{%2, %0|%0, %2}"
20793 [(set_attr "type" "mmxmul")
20794 (set_attr "mode" "DI")])
20795
20796
20797 ;; MMX logical operations
20798 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20799 ;; normal code that also wants to use the FPU from getting broken.
20800 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20801 (define_insn "mmx_iordi3"
20802 [(set (match_operand:DI 0 "register_operand" "=y")
20803 (unspec:DI
20804 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20805 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20806 UNSPEC_NOP))]
20807 "TARGET_MMX"
20808 "por\t{%2, %0|%0, %2}"
20809 [(set_attr "type" "mmxadd")
20810 (set_attr "mode" "DI")])
20811
20812 (define_insn "mmx_xordi3"
20813 [(set (match_operand:DI 0 "register_operand" "=y")
20814 (unspec:DI
20815 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20816 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20817 UNSPEC_NOP))]
20818 "TARGET_MMX"
20819 "pxor\t{%2, %0|%0, %2}"
20820 [(set_attr "type" "mmxadd")
20821 (set_attr "mode" "DI")
20822 (set_attr "memory" "none")])
20823
20824 ;; Same as pxor, but don't show input operands so that we don't think
20825 ;; they are live.
20826 (define_insn "mmx_clrdi"
20827 [(set (match_operand:DI 0 "register_operand" "=y")
20828 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20829 "TARGET_MMX"
20830 "pxor\t{%0, %0|%0, %0}"
20831 [(set_attr "type" "mmxadd")
20832 (set_attr "mode" "DI")
20833 (set_attr "memory" "none")])
20834
20835 (define_insn "mmx_anddi3"
20836 [(set (match_operand:DI 0 "register_operand" "=y")
20837 (unspec:DI
20838 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20839 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20840 UNSPEC_NOP))]
20841 "TARGET_MMX"
20842 "pand\t{%2, %0|%0, %2}"
20843 [(set_attr "type" "mmxadd")
20844 (set_attr "mode" "DI")])
20845
20846 (define_insn "mmx_nanddi3"
20847 [(set (match_operand:DI 0 "register_operand" "=y")
20848 (unspec:DI
20849 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20850 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20851 UNSPEC_NOP))]
20852 "TARGET_MMX"
20853 "pandn\t{%2, %0|%0, %2}"
20854 [(set_attr "type" "mmxadd")
20855 (set_attr "mode" "DI")])
20856
20857
20858 ;; MMX unsigned averages/sum of absolute differences
20859
20860 (define_insn "mmx_uavgv8qi3"
20861 [(set (match_operand:V8QI 0 "register_operand" "=y")
20862 (ashiftrt:V8QI
20863 (plus:V8QI (plus:V8QI
20864 (match_operand:V8QI 1 "register_operand" "0")
20865 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20866 (const_vector:V8QI [(const_int 1)
20867 (const_int 1)
20868 (const_int 1)
20869 (const_int 1)
20870 (const_int 1)
20871 (const_int 1)
20872 (const_int 1)
20873 (const_int 1)]))
20874 (const_int 1)))]
20875 "TARGET_SSE || TARGET_3DNOW_A"
20876 "pavgb\t{%2, %0|%0, %2}"
20877 [(set_attr "type" "mmxshft")
20878 (set_attr "mode" "DI")])
20879
20880 (define_insn "mmx_uavgv4hi3"
20881 [(set (match_operand:V4HI 0 "register_operand" "=y")
20882 (ashiftrt:V4HI
20883 (plus:V4HI (plus:V4HI
20884 (match_operand:V4HI 1 "register_operand" "0")
20885 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20886 (const_vector:V4HI [(const_int 1)
20887 (const_int 1)
20888 (const_int 1)
20889 (const_int 1)]))
20890 (const_int 1)))]
20891 "TARGET_SSE || TARGET_3DNOW_A"
20892 "pavgw\t{%2, %0|%0, %2}"
20893 [(set_attr "type" "mmxshft")
20894 (set_attr "mode" "DI")])
20895
20896 (define_insn "mmx_psadbw"
20897 [(set (match_operand:DI 0 "register_operand" "=y")
20898 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20899 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20900 UNSPEC_PSADBW))]
20901 "TARGET_SSE || TARGET_3DNOW_A"
20902 "psadbw\t{%2, %0|%0, %2}"
20903 [(set_attr "type" "mmxshft")
20904 (set_attr "mode" "DI")])
20905
20906
20907 ;; MMX insert/extract/shuffle
20908
20909 (define_insn "mmx_pinsrw"
20910 [(set (match_operand:V4HI 0 "register_operand" "=y")
20911 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20912 (vec_duplicate:V4HI
20913 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20914 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20915 "TARGET_SSE || TARGET_3DNOW_A"
20916 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20917 [(set_attr "type" "mmxcvt")
20918 (set_attr "mode" "DI")])
20919
20920 (define_insn "mmx_pextrw"
20921 [(set (match_operand:SI 0 "register_operand" "=r")
20922 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20923 (parallel
20924 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20925 "TARGET_SSE || TARGET_3DNOW_A"
20926 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20927 [(set_attr "type" "mmxcvt")
20928 (set_attr "mode" "DI")])
20929
20930 (define_insn "mmx_pshufw"
20931 [(set (match_operand:V4HI 0 "register_operand" "=y")
20932 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
20933 (match_operand:SI 2 "immediate_operand" "i")]
20934 UNSPEC_SHUFFLE))]
20935 "TARGET_SSE || TARGET_3DNOW_A"
20936 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20937 [(set_attr "type" "mmxcvt")
20938 (set_attr "mode" "DI")])
20939
20940
20941 ;; MMX mask-generating comparisons
20942
20943 (define_insn "eqv8qi3"
20944 [(set (match_operand:V8QI 0 "register_operand" "=y")
20945 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20946 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20947 "TARGET_MMX"
20948 "pcmpeqb\t{%2, %0|%0, %2}"
20949 [(set_attr "type" "mmxcmp")
20950 (set_attr "mode" "DI")])
20951
20952 (define_insn "eqv4hi3"
20953 [(set (match_operand:V4HI 0 "register_operand" "=y")
20954 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20955 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20956 "TARGET_MMX"
20957 "pcmpeqw\t{%2, %0|%0, %2}"
20958 [(set_attr "type" "mmxcmp")
20959 (set_attr "mode" "DI")])
20960
20961 (define_insn "eqv2si3"
20962 [(set (match_operand:V2SI 0 "register_operand" "=y")
20963 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20964 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20965 "TARGET_MMX"
20966 "pcmpeqd\t{%2, %0|%0, %2}"
20967 [(set_attr "type" "mmxcmp")
20968 (set_attr "mode" "DI")])
20969
20970 (define_insn "gtv8qi3"
20971 [(set (match_operand:V8QI 0 "register_operand" "=y")
20972 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20973 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20974 "TARGET_MMX"
20975 "pcmpgtb\t{%2, %0|%0, %2}"
20976 [(set_attr "type" "mmxcmp")
20977 (set_attr "mode" "DI")])
20978
20979 (define_insn "gtv4hi3"
20980 [(set (match_operand:V4HI 0 "register_operand" "=y")
20981 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20982 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20983 "TARGET_MMX"
20984 "pcmpgtw\t{%2, %0|%0, %2}"
20985 [(set_attr "type" "mmxcmp")
20986 (set_attr "mode" "DI")])
20987
20988 (define_insn "gtv2si3"
20989 [(set (match_operand:V2SI 0 "register_operand" "=y")
20990 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20991 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20992 "TARGET_MMX"
20993 "pcmpgtd\t{%2, %0|%0, %2}"
20994 [(set_attr "type" "mmxcmp")
20995 (set_attr "mode" "DI")])
20996
20997
20998 ;; MMX max/min insns
20999
21000 (define_insn "umaxv8qi3"
21001 [(set (match_operand:V8QI 0 "register_operand" "=y")
21002 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21003 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21004 "TARGET_SSE || TARGET_3DNOW_A"
21005 "pmaxub\t{%2, %0|%0, %2}"
21006 [(set_attr "type" "mmxadd")
21007 (set_attr "mode" "DI")])
21008
21009 (define_insn "smaxv4hi3"
21010 [(set (match_operand:V4HI 0 "register_operand" "=y")
21011 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21012 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21013 "TARGET_SSE || TARGET_3DNOW_A"
21014 "pmaxsw\t{%2, %0|%0, %2}"
21015 [(set_attr "type" "mmxadd")
21016 (set_attr "mode" "DI")])
21017
21018 (define_insn "uminv8qi3"
21019 [(set (match_operand:V8QI 0 "register_operand" "=y")
21020 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21021 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21022 "TARGET_SSE || TARGET_3DNOW_A"
21023 "pminub\t{%2, %0|%0, %2}"
21024 [(set_attr "type" "mmxadd")
21025 (set_attr "mode" "DI")])
21026
21027 (define_insn "sminv4hi3"
21028 [(set (match_operand:V4HI 0 "register_operand" "=y")
21029 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21030 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21031 "TARGET_SSE || TARGET_3DNOW_A"
21032 "pminsw\t{%2, %0|%0, %2}"
21033 [(set_attr "type" "mmxadd")
21034 (set_attr "mode" "DI")])
21035
21036
21037 ;; MMX shifts
21038
21039 (define_insn "ashrv4hi3"
21040 [(set (match_operand:V4HI 0 "register_operand" "=y")
21041 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21042 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21043 "TARGET_MMX"
21044 "psraw\t{%2, %0|%0, %2}"
21045 [(set_attr "type" "mmxshft")
21046 (set_attr "mode" "DI")])
21047
21048 (define_insn "ashrv2si3"
21049 [(set (match_operand:V2SI 0 "register_operand" "=y")
21050 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21051 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21052 "TARGET_MMX"
21053 "psrad\t{%2, %0|%0, %2}"
21054 [(set_attr "type" "mmxshft")
21055 (set_attr "mode" "DI")])
21056
21057 (define_insn "lshrv4hi3"
21058 [(set (match_operand:V4HI 0 "register_operand" "=y")
21059 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21060 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21061 "TARGET_MMX"
21062 "psrlw\t{%2, %0|%0, %2}"
21063 [(set_attr "type" "mmxshft")
21064 (set_attr "mode" "DI")])
21065
21066 (define_insn "lshrv2si3"
21067 [(set (match_operand:V2SI 0 "register_operand" "=y")
21068 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21069 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21070 "TARGET_MMX"
21071 "psrld\t{%2, %0|%0, %2}"
21072 [(set_attr "type" "mmxshft")
21073 (set_attr "mode" "DI")])
21074
21075 ;; See logical MMX insns.
21076 (define_insn "mmx_lshrdi3"
21077 [(set (match_operand:DI 0 "register_operand" "=y")
21078 (unspec:DI
21079 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21080 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21081 UNSPEC_NOP))]
21082 "TARGET_MMX"
21083 "psrlq\t{%2, %0|%0, %2}"
21084 [(set_attr "type" "mmxshft")
21085 (set_attr "mode" "DI")])
21086
21087 (define_insn "ashlv4hi3"
21088 [(set (match_operand:V4HI 0 "register_operand" "=y")
21089 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21090 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21091 "TARGET_MMX"
21092 "psllw\t{%2, %0|%0, %2}"
21093 [(set_attr "type" "mmxshft")
21094 (set_attr "mode" "DI")])
21095
21096 (define_insn "ashlv2si3"
21097 [(set (match_operand:V2SI 0 "register_operand" "=y")
21098 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21099 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21100 "TARGET_MMX"
21101 "pslld\t{%2, %0|%0, %2}"
21102 [(set_attr "type" "mmxshft")
21103 (set_attr "mode" "DI")])
21104
21105 ;; See logical MMX insns.
21106 (define_insn "mmx_ashldi3"
21107 [(set (match_operand:DI 0 "register_operand" "=y")
21108 (unspec:DI
21109 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21110 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21111 UNSPEC_NOP))]
21112 "TARGET_MMX"
21113 "psllq\t{%2, %0|%0, %2}"
21114 [(set_attr "type" "mmxshft")
21115 (set_attr "mode" "DI")])
21116
21117
21118 ;; MMX pack/unpack insns.
21119
21120 (define_insn "mmx_packsswb"
21121 [(set (match_operand:V8QI 0 "register_operand" "=y")
21122 (vec_concat:V8QI
21123 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21124 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21125 "TARGET_MMX"
21126 "packsswb\t{%2, %0|%0, %2}"
21127 [(set_attr "type" "mmxshft")
21128 (set_attr "mode" "DI")])
21129
21130 (define_insn "mmx_packssdw"
21131 [(set (match_operand:V4HI 0 "register_operand" "=y")
21132 (vec_concat:V4HI
21133 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21134 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21135 "TARGET_MMX"
21136 "packssdw\t{%2, %0|%0, %2}"
21137 [(set_attr "type" "mmxshft")
21138 (set_attr "mode" "DI")])
21139
21140 (define_insn "mmx_packuswb"
21141 [(set (match_operand:V8QI 0 "register_operand" "=y")
21142 (vec_concat:V8QI
21143 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21144 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21145 "TARGET_MMX"
21146 "packuswb\t{%2, %0|%0, %2}"
21147 [(set_attr "type" "mmxshft")
21148 (set_attr "mode" "DI")])
21149
21150 (define_insn "mmx_punpckhbw"
21151 [(set (match_operand:V8QI 0 "register_operand" "=y")
21152 (vec_merge:V8QI
21153 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21154 (parallel [(const_int 4)
21155 (const_int 0)
21156 (const_int 5)
21157 (const_int 1)
21158 (const_int 6)
21159 (const_int 2)
21160 (const_int 7)
21161 (const_int 3)]))
21162 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21163 (parallel [(const_int 0)
21164 (const_int 4)
21165 (const_int 1)
21166 (const_int 5)
21167 (const_int 2)
21168 (const_int 6)
21169 (const_int 3)
21170 (const_int 7)]))
21171 (const_int 85)))]
21172 "TARGET_MMX"
21173 "punpckhbw\t{%2, %0|%0, %2}"
21174 [(set_attr "type" "mmxcvt")
21175 (set_attr "mode" "DI")])
21176
21177 (define_insn "mmx_punpckhwd"
21178 [(set (match_operand:V4HI 0 "register_operand" "=y")
21179 (vec_merge:V4HI
21180 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21181 (parallel [(const_int 0)
21182 (const_int 2)
21183 (const_int 1)
21184 (const_int 3)]))
21185 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21186 (parallel [(const_int 2)
21187 (const_int 0)
21188 (const_int 3)
21189 (const_int 1)]))
21190 (const_int 5)))]
21191 "TARGET_MMX"
21192 "punpckhwd\t{%2, %0|%0, %2}"
21193 [(set_attr "type" "mmxcvt")
21194 (set_attr "mode" "DI")])
21195
21196 (define_insn "mmx_punpckhdq"
21197 [(set (match_operand:V2SI 0 "register_operand" "=y")
21198 (vec_merge:V2SI
21199 (match_operand:V2SI 1 "register_operand" "0")
21200 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21201 (parallel [(const_int 1)
21202 (const_int 0)]))
21203 (const_int 1)))]
21204 "TARGET_MMX"
21205 "punpckhdq\t{%2, %0|%0, %2}"
21206 [(set_attr "type" "mmxcvt")
21207 (set_attr "mode" "DI")])
21208
21209 (define_insn "mmx_punpcklbw"
21210 [(set (match_operand:V8QI 0 "register_operand" "=y")
21211 (vec_merge:V8QI
21212 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21213 (parallel [(const_int 0)
21214 (const_int 4)
21215 (const_int 1)
21216 (const_int 5)
21217 (const_int 2)
21218 (const_int 6)
21219 (const_int 3)
21220 (const_int 7)]))
21221 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21222 (parallel [(const_int 4)
21223 (const_int 0)
21224 (const_int 5)
21225 (const_int 1)
21226 (const_int 6)
21227 (const_int 2)
21228 (const_int 7)
21229 (const_int 3)]))
21230 (const_int 85)))]
21231 "TARGET_MMX"
21232 "punpcklbw\t{%2, %0|%0, %2}"
21233 [(set_attr "type" "mmxcvt")
21234 (set_attr "mode" "DI")])
21235
21236 (define_insn "mmx_punpcklwd"
21237 [(set (match_operand:V4HI 0 "register_operand" "=y")
21238 (vec_merge:V4HI
21239 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21240 (parallel [(const_int 2)
21241 (const_int 0)
21242 (const_int 3)
21243 (const_int 1)]))
21244 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21245 (parallel [(const_int 0)
21246 (const_int 2)
21247 (const_int 1)
21248 (const_int 3)]))
21249 (const_int 5)))]
21250 "TARGET_MMX"
21251 "punpcklwd\t{%2, %0|%0, %2}"
21252 [(set_attr "type" "mmxcvt")
21253 (set_attr "mode" "DI")])
21254
21255 (define_insn "mmx_punpckldq"
21256 [(set (match_operand:V2SI 0 "register_operand" "=y")
21257 (vec_merge:V2SI
21258 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21259 (parallel [(const_int 1)
21260 (const_int 0)]))
21261 (match_operand:V2SI 2 "register_operand" "y")
21262 (const_int 1)))]
21263 "TARGET_MMX"
21264 "punpckldq\t{%2, %0|%0, %2}"
21265 [(set_attr "type" "mmxcvt")
21266 (set_attr "mode" "DI")])
21267
21268
21269 ;; Miscellaneous stuff
21270
21271 (define_insn "emms"
21272 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21273 (clobber (reg:XF 8))
21274 (clobber (reg:XF 9))
21275 (clobber (reg:XF 10))
21276 (clobber (reg:XF 11))
21277 (clobber (reg:XF 12))
21278 (clobber (reg:XF 13))
21279 (clobber (reg:XF 14))
21280 (clobber (reg:XF 15))
21281 (clobber (reg:DI 29))
21282 (clobber (reg:DI 30))
21283 (clobber (reg:DI 31))
21284 (clobber (reg:DI 32))
21285 (clobber (reg:DI 33))
21286 (clobber (reg:DI 34))
21287 (clobber (reg:DI 35))
21288 (clobber (reg:DI 36))]
21289 "TARGET_MMX"
21290 "emms"
21291 [(set_attr "type" "mmx")
21292 (set_attr "memory" "unknown")])
21293
21294 (define_insn "ldmxcsr"
21295 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21296 UNSPECV_LDMXCSR)]
21297 "TARGET_SSE"
21298 "ldmxcsr\t%0"
21299 [(set_attr "type" "sse")
21300 (set_attr "memory" "load")])
21301
21302 (define_insn "stmxcsr"
21303 [(set (match_operand:SI 0 "memory_operand" "=m")
21304 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21305 "TARGET_SSE"
21306 "stmxcsr\t%0"
21307 [(set_attr "type" "sse")
21308 (set_attr "memory" "store")])
21309
21310 (define_expand "sfence"
21311 [(set (match_dup 0)
21312 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21313 "TARGET_SSE || TARGET_3DNOW_A"
21314 {
21315 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21316 MEM_VOLATILE_P (operands[0]) = 1;
21317 })
21318
21319 (define_insn "*sfence_insn"
21320 [(set (match_operand:BLK 0 "" "")
21321 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21322 "TARGET_SSE || TARGET_3DNOW_A"
21323 "sfence"
21324 [(set_attr "type" "sse")
21325 (set_attr "memory" "unknown")])
21326
21327 (define_expand "sse_prologue_save"
21328 [(parallel [(set (match_operand:BLK 0 "" "")
21329 (unspec:BLK [(reg:DI 21)
21330 (reg:DI 22)
21331 (reg:DI 23)
21332 (reg:DI 24)
21333 (reg:DI 25)
21334 (reg:DI 26)
21335 (reg:DI 27)
21336 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21337 (use (match_operand:DI 1 "register_operand" ""))
21338 (use (match_operand:DI 2 "immediate_operand" ""))
21339 (use (label_ref:DI (match_operand 3 "" "")))])]
21340 "TARGET_64BIT"
21341 "")
21342
21343 (define_insn "*sse_prologue_save_insn"
21344 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21345 (match_operand:DI 4 "const_int_operand" "n")))
21346 (unspec:BLK [(reg:DI 21)
21347 (reg:DI 22)
21348 (reg:DI 23)
21349 (reg:DI 24)
21350 (reg:DI 25)
21351 (reg:DI 26)
21352 (reg:DI 27)
21353 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21354 (use (match_operand:DI 1 "register_operand" "r"))
21355 (use (match_operand:DI 2 "const_int_operand" "i"))
21356 (use (label_ref:DI (match_operand 3 "" "X")))]
21357 "TARGET_64BIT
21358 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21359 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21360 "*
21361 {
21362 int i;
21363 operands[0] = gen_rtx_MEM (Pmode,
21364 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21365 output_asm_insn (\"jmp\\t%A1\", operands);
21366 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21367 {
21368 operands[4] = adjust_address (operands[0], DImode, i*16);
21369 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21370 PUT_MODE (operands[4], TImode);
21371 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21372 output_asm_insn (\"rex\", operands);
21373 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21374 }
21375 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21376 CODE_LABEL_NUMBER (operands[3]));
21377 RET;
21378 }
21379 "
21380 [(set_attr "type" "other")
21381 (set_attr "length_immediate" "0")
21382 (set_attr "length_address" "0")
21383 (set_attr "length" "135")
21384 (set_attr "memory" "store")
21385 (set_attr "modrm" "0")
21386 (set_attr "mode" "DI")])
21387
21388 ;; 3Dnow! instructions
21389
21390 (define_insn "addv2sf3"
21391 [(set (match_operand:V2SF 0 "register_operand" "=y")
21392 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21393 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21394 "TARGET_3DNOW"
21395 "pfadd\\t{%2, %0|%0, %2}"
21396 [(set_attr "type" "mmxadd")
21397 (set_attr "mode" "V2SF")])
21398
21399 (define_insn "subv2sf3"
21400 [(set (match_operand:V2SF 0 "register_operand" "=y")
21401 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21402 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21403 "TARGET_3DNOW"
21404 "pfsub\\t{%2, %0|%0, %2}"
21405 [(set_attr "type" "mmxadd")
21406 (set_attr "mode" "V2SF")])
21407
21408 (define_insn "subrv2sf3"
21409 [(set (match_operand:V2SF 0 "register_operand" "=y")
21410 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21411 (match_operand:V2SF 1 "register_operand" "0")))]
21412 "TARGET_3DNOW"
21413 "pfsubr\\t{%2, %0|%0, %2}"
21414 [(set_attr "type" "mmxadd")
21415 (set_attr "mode" "V2SF")])
21416
21417 (define_insn "gtv2sf3"
21418 [(set (match_operand:V2SI 0 "register_operand" "=y")
21419 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21420 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21421 "TARGET_3DNOW"
21422 "pfcmpgt\\t{%2, %0|%0, %2}"
21423 [(set_attr "type" "mmxcmp")
21424 (set_attr "mode" "V2SF")])
21425
21426 (define_insn "gev2sf3"
21427 [(set (match_operand:V2SI 0 "register_operand" "=y")
21428 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21429 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21430 "TARGET_3DNOW"
21431 "pfcmpge\\t{%2, %0|%0, %2}"
21432 [(set_attr "type" "mmxcmp")
21433 (set_attr "mode" "V2SF")])
21434
21435 (define_insn "eqv2sf3"
21436 [(set (match_operand:V2SI 0 "register_operand" "=y")
21437 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21438 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21439 "TARGET_3DNOW"
21440 "pfcmpeq\\t{%2, %0|%0, %2}"
21441 [(set_attr "type" "mmxcmp")
21442 (set_attr "mode" "V2SF")])
21443
21444 (define_insn "pfmaxv2sf3"
21445 [(set (match_operand:V2SF 0 "register_operand" "=y")
21446 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21447 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21448 "TARGET_3DNOW"
21449 "pfmax\\t{%2, %0|%0, %2}"
21450 [(set_attr "type" "mmxadd")
21451 (set_attr "mode" "V2SF")])
21452
21453 (define_insn "pfminv2sf3"
21454 [(set (match_operand:V2SF 0 "register_operand" "=y")
21455 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21456 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21457 "TARGET_3DNOW"
21458 "pfmin\\t{%2, %0|%0, %2}"
21459 [(set_attr "type" "mmxadd")
21460 (set_attr "mode" "V2SF")])
21461
21462 (define_insn "mulv2sf3"
21463 [(set (match_operand:V2SF 0 "register_operand" "=y")
21464 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21465 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21466 "TARGET_3DNOW"
21467 "pfmul\\t{%2, %0|%0, %2}"
21468 [(set_attr "type" "mmxmul")
21469 (set_attr "mode" "V2SF")])
21470
21471 (define_insn "femms"
21472 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21473 (clobber (reg:XF 8))
21474 (clobber (reg:XF 9))
21475 (clobber (reg:XF 10))
21476 (clobber (reg:XF 11))
21477 (clobber (reg:XF 12))
21478 (clobber (reg:XF 13))
21479 (clobber (reg:XF 14))
21480 (clobber (reg:XF 15))
21481 (clobber (reg:DI 29))
21482 (clobber (reg:DI 30))
21483 (clobber (reg:DI 31))
21484 (clobber (reg:DI 32))
21485 (clobber (reg:DI 33))
21486 (clobber (reg:DI 34))
21487 (clobber (reg:DI 35))
21488 (clobber (reg:DI 36))]
21489 "TARGET_3DNOW"
21490 "femms"
21491 [(set_attr "type" "mmx")
21492 (set_attr "memory" "none")])
21493
21494 (define_insn "pf2id"
21495 [(set (match_operand:V2SI 0 "register_operand" "=y")
21496 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21497 "TARGET_3DNOW"
21498 "pf2id\\t{%1, %0|%0, %1}"
21499 [(set_attr "type" "mmxcvt")
21500 (set_attr "mode" "V2SF")])
21501
21502 (define_insn "pf2iw"
21503 [(set (match_operand:V2SI 0 "register_operand" "=y")
21504 (sign_extend:V2SI
21505 (ss_truncate:V2HI
21506 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21507 "TARGET_3DNOW_A"
21508 "pf2iw\\t{%1, %0|%0, %1}"
21509 [(set_attr "type" "mmxcvt")
21510 (set_attr "mode" "V2SF")])
21511
21512 (define_insn "pfacc"
21513 [(set (match_operand:V2SF 0 "register_operand" "=y")
21514 (vec_concat:V2SF
21515 (plus:SF
21516 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21517 (parallel [(const_int 0)]))
21518 (vec_select:SF (match_dup 1)
21519 (parallel [(const_int 1)])))
21520 (plus:SF
21521 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21522 (parallel [(const_int 0)]))
21523 (vec_select:SF (match_dup 2)
21524 (parallel [(const_int 1)])))))]
21525 "TARGET_3DNOW"
21526 "pfacc\\t{%2, %0|%0, %2}"
21527 [(set_attr "type" "mmxadd")
21528 (set_attr "mode" "V2SF")])
21529
21530 (define_insn "pfnacc"
21531 [(set (match_operand:V2SF 0 "register_operand" "=y")
21532 (vec_concat:V2SF
21533 (minus:SF
21534 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21535 (parallel [(const_int 0)]))
21536 (vec_select:SF (match_dup 1)
21537 (parallel [(const_int 1)])))
21538 (minus:SF
21539 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21540 (parallel [(const_int 0)]))
21541 (vec_select:SF (match_dup 2)
21542 (parallel [(const_int 1)])))))]
21543 "TARGET_3DNOW_A"
21544 "pfnacc\\t{%2, %0|%0, %2}"
21545 [(set_attr "type" "mmxadd")
21546 (set_attr "mode" "V2SF")])
21547
21548 (define_insn "pfpnacc"
21549 [(set (match_operand:V2SF 0 "register_operand" "=y")
21550 (vec_concat:V2SF
21551 (minus:SF
21552 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21553 (parallel [(const_int 0)]))
21554 (vec_select:SF (match_dup 1)
21555 (parallel [(const_int 1)])))
21556 (plus:SF
21557 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21558 (parallel [(const_int 0)]))
21559 (vec_select:SF (match_dup 2)
21560 (parallel [(const_int 1)])))))]
21561 "TARGET_3DNOW_A"
21562 "pfpnacc\\t{%2, %0|%0, %2}"
21563 [(set_attr "type" "mmxadd")
21564 (set_attr "mode" "V2SF")])
21565
21566 (define_insn "pi2fw"
21567 [(set (match_operand:V2SF 0 "register_operand" "=y")
21568 (float:V2SF
21569 (vec_concat:V2SI
21570 (sign_extend:SI
21571 (truncate:HI
21572 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21573 (parallel [(const_int 0)]))))
21574 (sign_extend:SI
21575 (truncate:HI
21576 (vec_select:SI (match_dup 1)
21577 (parallel [(const_int 1)])))))))]
21578 "TARGET_3DNOW_A"
21579 "pi2fw\\t{%1, %0|%0, %1}"
21580 [(set_attr "type" "mmxcvt")
21581 (set_attr "mode" "V2SF")])
21582
21583 (define_insn "floatv2si2"
21584 [(set (match_operand:V2SF 0 "register_operand" "=y")
21585 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21586 "TARGET_3DNOW"
21587 "pi2fd\\t{%1, %0|%0, %1}"
21588 [(set_attr "type" "mmxcvt")
21589 (set_attr "mode" "V2SF")])
21590
21591 ;; This insn is identical to pavgb in operation, but the opcode is
21592 ;; different. To avoid accidentally matching pavgb, use an unspec.
21593
21594 (define_insn "pavgusb"
21595 [(set (match_operand:V8QI 0 "register_operand" "=y")
21596 (unspec:V8QI
21597 [(match_operand:V8QI 1 "register_operand" "0")
21598 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21599 UNSPEC_PAVGUSB))]
21600 "TARGET_3DNOW"
21601 "pavgusb\\t{%2, %0|%0, %2}"
21602 [(set_attr "type" "mmxshft")
21603 (set_attr "mode" "TI")])
21604
21605 ;; 3DNow reciprocal and sqrt
21606
21607 (define_insn "pfrcpv2sf2"
21608 [(set (match_operand:V2SF 0 "register_operand" "=y")
21609 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21610 UNSPEC_PFRCP))]
21611 "TARGET_3DNOW"
21612 "pfrcp\\t{%1, %0|%0, %1}"
21613 [(set_attr "type" "mmx")
21614 (set_attr "mode" "TI")])
21615
21616 (define_insn "pfrcpit1v2sf3"
21617 [(set (match_operand:V2SF 0 "register_operand" "=y")
21618 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21619 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21620 UNSPEC_PFRCPIT1))]
21621 "TARGET_3DNOW"
21622 "pfrcpit1\\t{%2, %0|%0, %2}"
21623 [(set_attr "type" "mmx")
21624 (set_attr "mode" "TI")])
21625
21626 (define_insn "pfrcpit2v2sf3"
21627 [(set (match_operand:V2SF 0 "register_operand" "=y")
21628 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21629 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21630 UNSPEC_PFRCPIT2))]
21631 "TARGET_3DNOW"
21632 "pfrcpit2\\t{%2, %0|%0, %2}"
21633 [(set_attr "type" "mmx")
21634 (set_attr "mode" "TI")])
21635
21636 (define_insn "pfrsqrtv2sf2"
21637 [(set (match_operand:V2SF 0 "register_operand" "=y")
21638 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21639 UNSPEC_PFRSQRT))]
21640 "TARGET_3DNOW"
21641 "pfrsqrt\\t{%1, %0|%0, %1}"
21642 [(set_attr "type" "mmx")
21643 (set_attr "mode" "TI")])
21644
21645 (define_insn "pfrsqit1v2sf3"
21646 [(set (match_operand:V2SF 0 "register_operand" "=y")
21647 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21648 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21649 UNSPEC_PFRSQIT1))]
21650 "TARGET_3DNOW"
21651 "pfrsqit1\\t{%2, %0|%0, %2}"
21652 [(set_attr "type" "mmx")
21653 (set_attr "mode" "TI")])
21654
21655 (define_insn "pmulhrwv4hi3"
21656 [(set (match_operand:V4HI 0 "register_operand" "=y")
21657 (truncate:V4HI
21658 (lshiftrt:V4SI
21659 (plus:V4SI
21660 (mult:V4SI
21661 (sign_extend:V4SI
21662 (match_operand:V4HI 1 "register_operand" "0"))
21663 (sign_extend:V4SI
21664 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21665 (const_vector:V4SI [(const_int 32768)
21666 (const_int 32768)
21667 (const_int 32768)
21668 (const_int 32768)]))
21669 (const_int 16))))]
21670 "TARGET_3DNOW"
21671 "pmulhrw\\t{%2, %0|%0, %2}"
21672 [(set_attr "type" "mmxmul")
21673 (set_attr "mode" "TI")])
21674
21675 (define_insn "pswapdv2si2"
21676 [(set (match_operand:V2SI 0 "register_operand" "=y")
21677 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21678 (parallel [(const_int 1) (const_int 0)])))]
21679 "TARGET_3DNOW_A"
21680 "pswapd\\t{%1, %0|%0, %1}"
21681 [(set_attr "type" "mmxcvt")
21682 (set_attr "mode" "TI")])
21683
21684 (define_insn "pswapdv2sf2"
21685 [(set (match_operand:V2SF 0 "register_operand" "=y")
21686 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21687 (parallel [(const_int 1) (const_int 0)])))]
21688 "TARGET_3DNOW_A"
21689 "pswapd\\t{%1, %0|%0, %1}"
21690 [(set_attr "type" "mmxcvt")
21691 (set_attr "mode" "TI")])
21692
21693 (define_expand "prefetch"
21694 [(prefetch (match_operand 0 "address_operand" "")
21695 (match_operand:SI 1 "const_int_operand" "")
21696 (match_operand:SI 2 "const_int_operand" ""))]
21697 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21698 {
21699 int rw = INTVAL (operands[1]);
21700 int locality = INTVAL (operands[2]);
21701
21702 if (rw != 0 && rw != 1)
21703 abort ();
21704 if (locality < 0 || locality > 3)
21705 abort ();
21706 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21707 abort ();
21708
21709 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21710 suported by SSE counterpart or the SSE prefetch is not available
21711 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21712 of locality. */
21713 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21714 operands[2] = GEN_INT (3);
21715 else
21716 operands[1] = const0_rtx;
21717 })
21718
21719 (define_insn "*prefetch_sse"
21720 [(prefetch (match_operand:SI 0 "address_operand" "p")
21721 (const_int 0)
21722 (match_operand:SI 1 "const_int_operand" ""))]
21723 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21724 {
21725 static const char * const patterns[4] = {
21726 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21727 };
21728
21729 int locality = INTVAL (operands[1]);
21730 if (locality < 0 || locality > 3)
21731 abort ();
21732
21733 return patterns[locality];
21734 }
21735 [(set_attr "type" "sse")
21736 (set_attr "memory" "none")])
21737
21738 (define_insn "*prefetch_sse_rex"
21739 [(prefetch (match_operand:DI 0 "address_operand" "p")
21740 (const_int 0)
21741 (match_operand:SI 1 "const_int_operand" ""))]
21742 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21743 {
21744 static const char * const patterns[4] = {
21745 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21746 };
21747
21748 int locality = INTVAL (operands[1]);
21749 if (locality < 0 || locality > 3)
21750 abort ();
21751
21752 return patterns[locality];
21753 }
21754 [(set_attr "type" "sse")
21755 (set_attr "memory" "none")])
21756
21757 (define_insn "*prefetch_3dnow"
21758 [(prefetch (match_operand:SI 0 "address_operand" "p")
21759 (match_operand:SI 1 "const_int_operand" "n")
21760 (const_int 3))]
21761 "TARGET_3DNOW && !TARGET_64BIT"
21762 {
21763 if (INTVAL (operands[1]) == 0)
21764 return "prefetch\t%a0";
21765 else
21766 return "prefetchw\t%a0";
21767 }
21768 [(set_attr "type" "mmx")
21769 (set_attr "memory" "none")])
21770
21771 (define_insn "*prefetch_3dnow_rex"
21772 [(prefetch (match_operand:DI 0 "address_operand" "p")
21773 (match_operand:SI 1 "const_int_operand" "n")
21774 (const_int 3))]
21775 "TARGET_3DNOW && TARGET_64BIT"
21776 {
21777 if (INTVAL (operands[1]) == 0)
21778 return "prefetch\t%a0";
21779 else
21780 return "prefetchw\t%a0";
21781 }
21782 [(set_attr "type" "mmx")
21783 (set_attr "memory" "none")])
21784
21785 ;; SSE2 support
21786
21787 (define_insn "addv2df3"
21788 [(set (match_operand:V2DF 0 "register_operand" "=x")
21789 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21790 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21791 "TARGET_SSE2"
21792 "addpd\t{%2, %0|%0, %2}"
21793 [(set_attr "type" "sseadd")
21794 (set_attr "mode" "V2DF")])
21795
21796 (define_insn "vmaddv2df3"
21797 [(set (match_operand:V2DF 0 "register_operand" "=x")
21798 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21799 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21800 (match_dup 1)
21801 (const_int 1)))]
21802 "TARGET_SSE2"
21803 "addsd\t{%2, %0|%0, %2}"
21804 [(set_attr "type" "sseadd")
21805 (set_attr "mode" "DF")])
21806
21807 (define_insn "subv2df3"
21808 [(set (match_operand:V2DF 0 "register_operand" "=x")
21809 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21810 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21811 "TARGET_SSE2"
21812 "subpd\t{%2, %0|%0, %2}"
21813 [(set_attr "type" "sseadd")
21814 (set_attr "mode" "V2DF")])
21815
21816 (define_insn "vmsubv2df3"
21817 [(set (match_operand:V2DF 0 "register_operand" "=x")
21818 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21819 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21820 (match_dup 1)
21821 (const_int 1)))]
21822 "TARGET_SSE2"
21823 "subsd\t{%2, %0|%0, %2}"
21824 [(set_attr "type" "sseadd")
21825 (set_attr "mode" "DF")])
21826
21827 (define_insn "mulv2df3"
21828 [(set (match_operand:V2DF 0 "register_operand" "=x")
21829 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21830 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21831 "TARGET_SSE2"
21832 "mulpd\t{%2, %0|%0, %2}"
21833 [(set_attr "type" "ssemul")
21834 (set_attr "mode" "V2DF")])
21835
21836 (define_insn "vmmulv2df3"
21837 [(set (match_operand:V2DF 0 "register_operand" "=x")
21838 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21839 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21840 (match_dup 1)
21841 (const_int 1)))]
21842 "TARGET_SSE2"
21843 "mulsd\t{%2, %0|%0, %2}"
21844 [(set_attr "type" "ssemul")
21845 (set_attr "mode" "DF")])
21846
21847 (define_insn "divv2df3"
21848 [(set (match_operand:V2DF 0 "register_operand" "=x")
21849 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21850 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21851 "TARGET_SSE2"
21852 "divpd\t{%2, %0|%0, %2}"
21853 [(set_attr "type" "ssediv")
21854 (set_attr "mode" "V2DF")])
21855
21856 (define_insn "vmdivv2df3"
21857 [(set (match_operand:V2DF 0 "register_operand" "=x")
21858 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21859 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21860 (match_dup 1)
21861 (const_int 1)))]
21862 "TARGET_SSE2"
21863 "divsd\t{%2, %0|%0, %2}"
21864 [(set_attr "type" "ssediv")
21865 (set_attr "mode" "DF")])
21866
21867 ;; SSE min/max
21868
21869 (define_insn "smaxv2df3"
21870 [(set (match_operand:V2DF 0 "register_operand" "=x")
21871 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21872 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21873 "TARGET_SSE2"
21874 "maxpd\t{%2, %0|%0, %2}"
21875 [(set_attr "type" "sseadd")
21876 (set_attr "mode" "V2DF")])
21877
21878 (define_insn "vmsmaxv2df3"
21879 [(set (match_operand:V2DF 0 "register_operand" "=x")
21880 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21881 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21882 (match_dup 1)
21883 (const_int 1)))]
21884 "TARGET_SSE2"
21885 "maxsd\t{%2, %0|%0, %2}"
21886 [(set_attr "type" "sseadd")
21887 (set_attr "mode" "DF")])
21888
21889 (define_insn "sminv2df3"
21890 [(set (match_operand:V2DF 0 "register_operand" "=x")
21891 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21892 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21893 "TARGET_SSE2"
21894 "minpd\t{%2, %0|%0, %2}"
21895 [(set_attr "type" "sseadd")
21896 (set_attr "mode" "V2DF")])
21897
21898 (define_insn "vmsminv2df3"
21899 [(set (match_operand:V2DF 0 "register_operand" "=x")
21900 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21901 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21902 (match_dup 1)
21903 (const_int 1)))]
21904 "TARGET_SSE2"
21905 "minsd\t{%2, %0|%0, %2}"
21906 [(set_attr "type" "sseadd")
21907 (set_attr "mode" "DF")])
21908 ;; SSE2 square root. There doesn't appear to be an extension for the
21909 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21910
21911 (define_insn "sqrtv2df2"
21912 [(set (match_operand:V2DF 0 "register_operand" "=x")
21913 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21914 "TARGET_SSE2"
21915 "sqrtpd\t{%1, %0|%0, %1}"
21916 [(set_attr "type" "sse")
21917 (set_attr "mode" "V2DF")])
21918
21919 (define_insn "vmsqrtv2df2"
21920 [(set (match_operand:V2DF 0 "register_operand" "=x")
21921 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21922 (match_operand:V2DF 2 "register_operand" "0")
21923 (const_int 1)))]
21924 "TARGET_SSE2"
21925 "sqrtsd\t{%1, %0|%0, %1}"
21926 [(set_attr "type" "sse")
21927 (set_attr "mode" "SF")])
21928
21929 ;; SSE mask-generating compares
21930
21931 (define_insn "maskcmpv2df3"
21932 [(set (match_operand:V2DI 0 "register_operand" "=x")
21933 (match_operator:V2DI 3 "sse_comparison_operator"
21934 [(match_operand:V2DF 1 "register_operand" "0")
21935 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21936 "TARGET_SSE2"
21937 "cmp%D3pd\t{%2, %0|%0, %2}"
21938 [(set_attr "type" "ssecmp")
21939 (set_attr "mode" "V2DF")])
21940
21941 (define_insn "maskncmpv2df3"
21942 [(set (match_operand:V2DI 0 "register_operand" "=x")
21943 (not:V2DI
21944 (match_operator:V2DI 3 "sse_comparison_operator"
21945 [(match_operand:V2DF 1 "register_operand" "0")
21946 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21947 "TARGET_SSE2"
21948 {
21949 if (GET_CODE (operands[3]) == UNORDERED)
21950 return "cmpordps\t{%2, %0|%0, %2}";
21951 else
21952 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21953 }
21954 [(set_attr "type" "ssecmp")
21955 (set_attr "mode" "V2DF")])
21956
21957 (define_insn "vmmaskcmpv2df3"
21958 [(set (match_operand:V2DI 0 "register_operand" "=x")
21959 (vec_merge:V2DI
21960 (match_operator:V2DI 3 "sse_comparison_operator"
21961 [(match_operand:V2DF 1 "register_operand" "0")
21962 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21963 (subreg:V2DI (match_dup 1) 0)
21964 (const_int 1)))]
21965 "TARGET_SSE2"
21966 "cmp%D3sd\t{%2, %0|%0, %2}"
21967 [(set_attr "type" "ssecmp")
21968 (set_attr "mode" "DF")])
21969
21970 (define_insn "vmmaskncmpv2df3"
21971 [(set (match_operand:V2DI 0 "register_operand" "=x")
21972 (vec_merge:V2DI
21973 (not:V2DI
21974 (match_operator:V2DI 3 "sse_comparison_operator"
21975 [(match_operand:V2DF 1 "register_operand" "0")
21976 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21977 (subreg:V2DI (match_dup 1) 0)
21978 (const_int 1)))]
21979 "TARGET_SSE2"
21980 {
21981 if (GET_CODE (operands[3]) == UNORDERED)
21982 return "cmpordsd\t{%2, %0|%0, %2}";
21983 else
21984 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21985 }
21986 [(set_attr "type" "ssecmp")
21987 (set_attr "mode" "DF")])
21988
21989 (define_insn "sse2_comi"
21990 [(set (reg:CCFP 17)
21991 (compare:CCFP (vec_select:DF
21992 (match_operand:V2DF 0 "register_operand" "x")
21993 (parallel [(const_int 0)]))
21994 (vec_select:DF
21995 (match_operand:V2DF 1 "register_operand" "x")
21996 (parallel [(const_int 0)]))))]
21997 "TARGET_SSE2"
21998 "comisd\t{%1, %0|%0, %1}"
21999 [(set_attr "type" "ssecomi")
22000 (set_attr "mode" "DF")])
22001
22002 (define_insn "sse2_ucomi"
22003 [(set (reg:CCFPU 17)
22004 (compare:CCFPU (vec_select:DF
22005 (match_operand:V2DF 0 "register_operand" "x")
22006 (parallel [(const_int 0)]))
22007 (vec_select:DF
22008 (match_operand:V2DF 1 "register_operand" "x")
22009 (parallel [(const_int 0)]))))]
22010 "TARGET_SSE2"
22011 "ucomisd\t{%1, %0|%0, %1}"
22012 [(set_attr "type" "ssecomi")
22013 (set_attr "mode" "DF")])
22014
22015 ;; SSE Strange Moves.
22016
22017 (define_insn "sse2_movmskpd"
22018 [(set (match_operand:SI 0 "register_operand" "=r")
22019 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22020 UNSPEC_MOVMSK))]
22021 "TARGET_SSE2"
22022 "movmskpd\t{%1, %0|%0, %1}"
22023 [(set_attr "type" "ssecvt")
22024 (set_attr "mode" "V2DF")])
22025
22026 (define_insn "sse2_pmovmskb"
22027 [(set (match_operand:SI 0 "register_operand" "=r")
22028 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22029 UNSPEC_MOVMSK))]
22030 "TARGET_SSE2"
22031 "pmovmskb\t{%1, %0|%0, %1}"
22032 [(set_attr "type" "ssecvt")
22033 (set_attr "mode" "V2DF")])
22034
22035 (define_insn "sse2_maskmovdqu"
22036 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22037 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22038 (match_operand:V16QI 2 "register_operand" "x")]
22039 UNSPEC_MASKMOV))]
22040 "TARGET_SSE2"
22041 ;; @@@ check ordering of operands in intel/nonintel syntax
22042 "maskmovdqu\t{%2, %1|%1, %2}"
22043 [(set_attr "type" "ssecvt")
22044 (set_attr "mode" "TI")])
22045
22046 (define_insn "sse2_maskmovdqu_rex64"
22047 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22048 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22049 (match_operand:V16QI 2 "register_operand" "x")]
22050 UNSPEC_MASKMOV))]
22051 "TARGET_SSE2"
22052 ;; @@@ check ordering of operands in intel/nonintel syntax
22053 "maskmovdqu\t{%2, %1|%1, %2}"
22054 [(set_attr "type" "ssecvt")
22055 (set_attr "mode" "TI")])
22056
22057 (define_insn "sse2_movntv2df"
22058 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22059 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22060 UNSPEC_MOVNT))]
22061 "TARGET_SSE2"
22062 "movntpd\t{%1, %0|%0, %1}"
22063 [(set_attr "type" "ssecvt")
22064 (set_attr "mode" "V2DF")])
22065
22066 (define_insn "sse2_movntv2di"
22067 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22068 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22069 UNSPEC_MOVNT))]
22070 "TARGET_SSE2"
22071 "movntdq\t{%1, %0|%0, %1}"
22072 [(set_attr "type" "ssecvt")
22073 (set_attr "mode" "TI")])
22074
22075 (define_insn "sse2_movntsi"
22076 [(set (match_operand:SI 0 "memory_operand" "=m")
22077 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22078 UNSPEC_MOVNT))]
22079 "TARGET_SSE2"
22080 "movnti\t{%1, %0|%0, %1}"
22081 [(set_attr "type" "ssecvt")
22082 (set_attr "mode" "V2DF")])
22083
22084 ;; SSE <-> integer/MMX conversions
22085
22086 ;; Conversions between SI and SF
22087
22088 (define_insn "cvtdq2ps"
22089 [(set (match_operand:V4SF 0 "register_operand" "=x")
22090 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22091 "TARGET_SSE2"
22092 "cvtdq2ps\t{%1, %0|%0, %1}"
22093 [(set_attr "type" "ssecvt")
22094 (set_attr "mode" "V2DF")])
22095
22096 (define_insn "cvtps2dq"
22097 [(set (match_operand:V4SI 0 "register_operand" "=x")
22098 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22099 "TARGET_SSE2"
22100 "cvtps2dq\t{%1, %0|%0, %1}"
22101 [(set_attr "type" "ssecvt")
22102 (set_attr "mode" "TI")])
22103
22104 (define_insn "cvttps2dq"
22105 [(set (match_operand:V4SI 0 "register_operand" "=x")
22106 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22107 UNSPEC_FIX))]
22108 "TARGET_SSE2"
22109 "cvttps2dq\t{%1, %0|%0, %1}"
22110 [(set_attr "type" "ssecvt")
22111 (set_attr "mode" "TI")])
22112
22113 ;; Conversions between SI and DF
22114
22115 (define_insn "cvtdq2pd"
22116 [(set (match_operand:V2DF 0 "register_operand" "=x")
22117 (float:V2DF (vec_select:V2SI
22118 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22119 (parallel
22120 [(const_int 0)
22121 (const_int 1)]))))]
22122 "TARGET_SSE2"
22123 "cvtdq2pd\t{%1, %0|%0, %1}"
22124 [(set_attr "type" "ssecvt")
22125 (set_attr "mode" "V2DF")])
22126
22127 (define_insn "cvtpd2dq"
22128 [(set (match_operand:V4SI 0 "register_operand" "=x")
22129 (vec_concat:V4SI
22130 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22131 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22132 "TARGET_SSE2"
22133 "cvtpd2dq\t{%1, %0|%0, %1}"
22134 [(set_attr "type" "ssecvt")
22135 (set_attr "mode" "TI")])
22136
22137 (define_insn "cvttpd2dq"
22138 [(set (match_operand:V4SI 0 "register_operand" "=x")
22139 (vec_concat:V4SI
22140 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22141 UNSPEC_FIX)
22142 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22143 "TARGET_SSE2"
22144 "cvttpd2dq\t{%1, %0|%0, %1}"
22145 [(set_attr "type" "ssecvt")
22146 (set_attr "mode" "TI")])
22147
22148 (define_insn "cvtpd2pi"
22149 [(set (match_operand:V2SI 0 "register_operand" "=y")
22150 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22151 "TARGET_SSE2"
22152 "cvtpd2pi\t{%1, %0|%0, %1}"
22153 [(set_attr "type" "ssecvt")
22154 (set_attr "mode" "TI")])
22155
22156 (define_insn "cvttpd2pi"
22157 [(set (match_operand:V2SI 0 "register_operand" "=y")
22158 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22159 UNSPEC_FIX))]
22160 "TARGET_SSE2"
22161 "cvttpd2pi\t{%1, %0|%0, %1}"
22162 [(set_attr "type" "ssecvt")
22163 (set_attr "mode" "TI")])
22164
22165 (define_insn "cvtpi2pd"
22166 [(set (match_operand:V2DF 0 "register_operand" "=x")
22167 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22168 "TARGET_SSE2"
22169 "cvtpi2pd\t{%1, %0|%0, %1}"
22170 [(set_attr "type" "ssecvt")
22171 (set_attr "mode" "TI")])
22172
22173 ;; Conversions between SI and DF
22174
22175 (define_insn "cvtsd2si"
22176 [(set (match_operand:SI 0 "register_operand" "=r,r")
22177 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22178 (parallel [(const_int 0)]))))]
22179 "TARGET_SSE2"
22180 "cvtsd2si\t{%1, %0|%0, %1}"
22181 [(set_attr "type" "sseicvt")
22182 (set_attr "athlon_decode" "double,vector")
22183 (set_attr "mode" "SI")])
22184
22185 (define_insn "cvtsd2siq"
22186 [(set (match_operand:DI 0 "register_operand" "=r,r")
22187 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22188 (parallel [(const_int 0)]))))]
22189 "TARGET_SSE2 && TARGET_64BIT"
22190 "cvtsd2siq\t{%1, %0|%0, %1}"
22191 [(set_attr "type" "sseicvt")
22192 (set_attr "athlon_decode" "double,vector")
22193 (set_attr "mode" "DI")])
22194
22195 (define_insn "cvttsd2si"
22196 [(set (match_operand:SI 0 "register_operand" "=r,r")
22197 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22198 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22199 "TARGET_SSE2"
22200 "cvttsd2si\t{%1, %0|%0, %1}"
22201 [(set_attr "type" "sseicvt")
22202 (set_attr "mode" "SI")
22203 (set_attr "athlon_decode" "double,vector")])
22204
22205 (define_insn "cvttsd2siq"
22206 [(set (match_operand:DI 0 "register_operand" "=r,r")
22207 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22208 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22209 "TARGET_SSE2 && TARGET_64BIT"
22210 "cvttsd2siq\t{%1, %0|%0, %1}"
22211 [(set_attr "type" "sseicvt")
22212 (set_attr "mode" "DI")
22213 (set_attr "athlon_decode" "double,vector")])
22214
22215 (define_insn "cvtsi2sd"
22216 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22217 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22218 (vec_duplicate:V2DF
22219 (float:DF
22220 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22221 (const_int 2)))]
22222 "TARGET_SSE2"
22223 "cvtsi2sd\t{%2, %0|%0, %2}"
22224 [(set_attr "type" "sseicvt")
22225 (set_attr "mode" "DF")
22226 (set_attr "athlon_decode" "double,direct")])
22227
22228 (define_insn "cvtsi2sdq"
22229 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22230 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22231 (vec_duplicate:V2DF
22232 (float:DF
22233 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22234 (const_int 2)))]
22235 "TARGET_SSE2 && TARGET_64BIT"
22236 "cvtsi2sdq\t{%2, %0|%0, %2}"
22237 [(set_attr "type" "sseicvt")
22238 (set_attr "mode" "DF")
22239 (set_attr "athlon_decode" "double,direct")])
22240
22241 ;; Conversions between SF and DF
22242
22243 (define_insn "cvtsd2ss"
22244 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22245 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22246 (vec_duplicate:V4SF
22247 (float_truncate:V2SF
22248 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22249 (const_int 14)))]
22250 "TARGET_SSE2"
22251 "cvtsd2ss\t{%2, %0|%0, %2}"
22252 [(set_attr "type" "ssecvt")
22253 (set_attr "athlon_decode" "vector,double")
22254 (set_attr "mode" "SF")])
22255
22256 (define_insn "cvtss2sd"
22257 [(set (match_operand:V2DF 0 "register_operand" "=x")
22258 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22259 (float_extend:V2DF
22260 (vec_select:V2SF
22261 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22262 (parallel [(const_int 0)
22263 (const_int 1)])))
22264 (const_int 2)))]
22265 "TARGET_SSE2"
22266 "cvtss2sd\t{%2, %0|%0, %2}"
22267 [(set_attr "type" "ssecvt")
22268 (set_attr "mode" "DF")])
22269
22270 (define_insn "cvtpd2ps"
22271 [(set (match_operand:V4SF 0 "register_operand" "=x")
22272 (subreg:V4SF
22273 (vec_concat:V4SI
22274 (subreg:V2SI (float_truncate:V2SF
22275 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22276 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22277 "TARGET_SSE2"
22278 "cvtpd2ps\t{%1, %0|%0, %1}"
22279 [(set_attr "type" "ssecvt")
22280 (set_attr "mode" "V4SF")])
22281
22282 (define_insn "cvtps2pd"
22283 [(set (match_operand:V2DF 0 "register_operand" "=x")
22284 (float_extend:V2DF
22285 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22286 (parallel [(const_int 0)
22287 (const_int 1)]))))]
22288 "TARGET_SSE2"
22289 "cvtps2pd\t{%1, %0|%0, %1}"
22290 [(set_attr "type" "ssecvt")
22291 (set_attr "mode" "V2DF")])
22292
22293 ;; SSE2 variants of MMX insns
22294
22295 ;; MMX arithmetic
22296
22297 (define_insn "addv16qi3"
22298 [(set (match_operand:V16QI 0 "register_operand" "=x")
22299 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22300 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22301 "TARGET_SSE2"
22302 "paddb\t{%2, %0|%0, %2}"
22303 [(set_attr "type" "sseiadd")
22304 (set_attr "mode" "TI")])
22305
22306 (define_insn "addv8hi3"
22307 [(set (match_operand:V8HI 0 "register_operand" "=x")
22308 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22309 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22310 "TARGET_SSE2"
22311 "paddw\t{%2, %0|%0, %2}"
22312 [(set_attr "type" "sseiadd")
22313 (set_attr "mode" "TI")])
22314
22315 (define_insn "addv4si3"
22316 [(set (match_operand:V4SI 0 "register_operand" "=x")
22317 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22318 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22319 "TARGET_SSE2"
22320 "paddd\t{%2, %0|%0, %2}"
22321 [(set_attr "type" "sseiadd")
22322 (set_attr "mode" "TI")])
22323
22324 (define_insn "addv2di3"
22325 [(set (match_operand:V2DI 0 "register_operand" "=x")
22326 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22327 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22328 "TARGET_SSE2"
22329 "paddq\t{%2, %0|%0, %2}"
22330 [(set_attr "type" "sseiadd")
22331 (set_attr "mode" "TI")])
22332
22333 (define_insn "ssaddv16qi3"
22334 [(set (match_operand:V16QI 0 "register_operand" "=x")
22335 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22336 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22337 "TARGET_SSE2"
22338 "paddsb\t{%2, %0|%0, %2}"
22339 [(set_attr "type" "sseiadd")
22340 (set_attr "mode" "TI")])
22341
22342 (define_insn "ssaddv8hi3"
22343 [(set (match_operand:V8HI 0 "register_operand" "=x")
22344 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22345 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22346 "TARGET_SSE2"
22347 "paddsw\t{%2, %0|%0, %2}"
22348 [(set_attr "type" "sseiadd")
22349 (set_attr "mode" "TI")])
22350
22351 (define_insn "usaddv16qi3"
22352 [(set (match_operand:V16QI 0 "register_operand" "=x")
22353 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22354 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22355 "TARGET_SSE2"
22356 "paddusb\t{%2, %0|%0, %2}"
22357 [(set_attr "type" "sseiadd")
22358 (set_attr "mode" "TI")])
22359
22360 (define_insn "usaddv8hi3"
22361 [(set (match_operand:V8HI 0 "register_operand" "=x")
22362 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22363 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22364 "TARGET_SSE2"
22365 "paddusw\t{%2, %0|%0, %2}"
22366 [(set_attr "type" "sseiadd")
22367 (set_attr "mode" "TI")])
22368
22369 (define_insn "subv16qi3"
22370 [(set (match_operand:V16QI 0 "register_operand" "=x")
22371 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22372 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22373 "TARGET_SSE2"
22374 "psubb\t{%2, %0|%0, %2}"
22375 [(set_attr "type" "sseiadd")
22376 (set_attr "mode" "TI")])
22377
22378 (define_insn "subv8hi3"
22379 [(set (match_operand:V8HI 0 "register_operand" "=x")
22380 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22381 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22382 "TARGET_SSE2"
22383 "psubw\t{%2, %0|%0, %2}"
22384 [(set_attr "type" "sseiadd")
22385 (set_attr "mode" "TI")])
22386
22387 (define_insn "subv4si3"
22388 [(set (match_operand:V4SI 0 "register_operand" "=x")
22389 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22390 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22391 "TARGET_SSE2"
22392 "psubd\t{%2, %0|%0, %2}"
22393 [(set_attr "type" "sseiadd")
22394 (set_attr "mode" "TI")])
22395
22396 (define_insn "subv2di3"
22397 [(set (match_operand:V2DI 0 "register_operand" "=x")
22398 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22399 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22400 "TARGET_SSE2"
22401 "psubq\t{%2, %0|%0, %2}"
22402 [(set_attr "type" "sseiadd")
22403 (set_attr "mode" "TI")])
22404
22405 (define_insn "sssubv16qi3"
22406 [(set (match_operand:V16QI 0 "register_operand" "=x")
22407 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22408 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22409 "TARGET_SSE2"
22410 "psubsb\t{%2, %0|%0, %2}"
22411 [(set_attr "type" "sseiadd")
22412 (set_attr "mode" "TI")])
22413
22414 (define_insn "sssubv8hi3"
22415 [(set (match_operand:V8HI 0 "register_operand" "=x")
22416 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22417 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22418 "TARGET_SSE2"
22419 "psubsw\t{%2, %0|%0, %2}"
22420 [(set_attr "type" "sseiadd")
22421 (set_attr "mode" "TI")])
22422
22423 (define_insn "ussubv16qi3"
22424 [(set (match_operand:V16QI 0 "register_operand" "=x")
22425 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22426 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22427 "TARGET_SSE2"
22428 "psubusb\t{%2, %0|%0, %2}"
22429 [(set_attr "type" "sseiadd")
22430 (set_attr "mode" "TI")])
22431
22432 (define_insn "ussubv8hi3"
22433 [(set (match_operand:V8HI 0 "register_operand" "=x")
22434 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22435 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22436 "TARGET_SSE2"
22437 "psubusw\t{%2, %0|%0, %2}"
22438 [(set_attr "type" "sseiadd")
22439 (set_attr "mode" "TI")])
22440
22441 (define_insn "mulv8hi3"
22442 [(set (match_operand:V8HI 0 "register_operand" "=x")
22443 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22444 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22445 "TARGET_SSE2"
22446 "pmullw\t{%2, %0|%0, %2}"
22447 [(set_attr "type" "sseimul")
22448 (set_attr "mode" "TI")])
22449
22450 (define_insn "smulv8hi3_highpart"
22451 [(set (match_operand:V8HI 0 "register_operand" "=x")
22452 (truncate:V8HI
22453 (lshiftrt:V8SI
22454 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22455 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22456 (const_int 16))))]
22457 "TARGET_SSE2"
22458 "pmulhw\t{%2, %0|%0, %2}"
22459 [(set_attr "type" "sseimul")
22460 (set_attr "mode" "TI")])
22461
22462 (define_insn "umulv8hi3_highpart"
22463 [(set (match_operand:V8HI 0 "register_operand" "=x")
22464 (truncate:V8HI
22465 (lshiftrt:V8SI
22466 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22467 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22468 (const_int 16))))]
22469 "TARGET_SSE2"
22470 "pmulhuw\t{%2, %0|%0, %2}"
22471 [(set_attr "type" "sseimul")
22472 (set_attr "mode" "TI")])
22473
22474 (define_insn "sse2_umulsidi3"
22475 [(set (match_operand:DI 0 "register_operand" "=y")
22476 (mult:DI (zero_extend:DI (vec_select:SI
22477 (match_operand:V2SI 1 "register_operand" "0")
22478 (parallel [(const_int 0)])))
22479 (zero_extend:DI (vec_select:SI
22480 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22481 (parallel [(const_int 0)])))))]
22482 "TARGET_SSE2"
22483 "pmuludq\t{%2, %0|%0, %2}"
22484 [(set_attr "type" "sseimul")
22485 (set_attr "mode" "TI")])
22486
22487 (define_insn "sse2_umulv2siv2di3"
22488 [(set (match_operand:V2DI 0 "register_operand" "=x")
22489 (mult:V2DI (zero_extend:V2DI
22490 (vec_select:V2SI
22491 (match_operand:V4SI 1 "register_operand" "0")
22492 (parallel [(const_int 0) (const_int 2)])))
22493 (zero_extend:V2DI
22494 (vec_select:V2SI
22495 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22496 (parallel [(const_int 0) (const_int 2)])))))]
22497 "TARGET_SSE2"
22498 "pmuludq\t{%2, %0|%0, %2}"
22499 [(set_attr "type" "sseimul")
22500 (set_attr "mode" "TI")])
22501
22502 (define_insn "sse2_pmaddwd"
22503 [(set (match_operand:V4SI 0 "register_operand" "=x")
22504 (plus:V4SI
22505 (mult:V4SI
22506 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22507 (parallel [(const_int 0)
22508 (const_int 2)
22509 (const_int 4)
22510 (const_int 6)])))
22511 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22512 (parallel [(const_int 0)
22513 (const_int 2)
22514 (const_int 4)
22515 (const_int 6)]))))
22516 (mult:V4SI
22517 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22518 (parallel [(const_int 1)
22519 (const_int 3)
22520 (const_int 5)
22521 (const_int 7)])))
22522 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22523 (parallel [(const_int 1)
22524 (const_int 3)
22525 (const_int 5)
22526 (const_int 7)]))))))]
22527 "TARGET_SSE2"
22528 "pmaddwd\t{%2, %0|%0, %2}"
22529 [(set_attr "type" "sseiadd")
22530 (set_attr "mode" "TI")])
22531
22532 ;; Same as pxor, but don't show input operands so that we don't think
22533 ;; they are live.
22534 (define_insn "sse2_clrti"
22535 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22536 "TARGET_SSE2"
22537 {
22538 if (get_attr_mode (insn) == MODE_TI)
22539 return "pxor\t%0, %0";
22540 else
22541 return "xorps\t%0, %0";
22542 }
22543 [(set_attr "type" "ssemov")
22544 (set_attr "memory" "none")
22545 (set (attr "mode")
22546 (if_then_else
22547 (ne (symbol_ref "optimize_size")
22548 (const_int 0))
22549 (const_string "V4SF")
22550 (const_string "TI")))])
22551
22552 ;; MMX unsigned averages/sum of absolute differences
22553
22554 (define_insn "sse2_uavgv16qi3"
22555 [(set (match_operand:V16QI 0 "register_operand" "=x")
22556 (ashiftrt:V16QI
22557 (plus:V16QI (plus:V16QI
22558 (match_operand:V16QI 1 "register_operand" "0")
22559 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22560 (const_vector:V16QI [(const_int 1) (const_int 1)
22561 (const_int 1) (const_int 1)
22562 (const_int 1) (const_int 1)
22563 (const_int 1) (const_int 1)
22564 (const_int 1) (const_int 1)
22565 (const_int 1) (const_int 1)
22566 (const_int 1) (const_int 1)
22567 (const_int 1) (const_int 1)]))
22568 (const_int 1)))]
22569 "TARGET_SSE2"
22570 "pavgb\t{%2, %0|%0, %2}"
22571 [(set_attr "type" "sseiadd")
22572 (set_attr "mode" "TI")])
22573
22574 (define_insn "sse2_uavgv8hi3"
22575 [(set (match_operand:V8HI 0 "register_operand" "=x")
22576 (ashiftrt:V8HI
22577 (plus:V8HI (plus:V8HI
22578 (match_operand:V8HI 1 "register_operand" "0")
22579 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22580 (const_vector:V8HI [(const_int 1) (const_int 1)
22581 (const_int 1) (const_int 1)
22582 (const_int 1) (const_int 1)
22583 (const_int 1) (const_int 1)]))
22584 (const_int 1)))]
22585 "TARGET_SSE2"
22586 "pavgw\t{%2, %0|%0, %2}"
22587 [(set_attr "type" "sseiadd")
22588 (set_attr "mode" "TI")])
22589
22590 ;; @@@ this isn't the right representation.
22591 (define_insn "sse2_psadbw"
22592 [(set (match_operand:V2DI 0 "register_operand" "=x")
22593 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22594 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22595 UNSPEC_PSADBW))]
22596 "TARGET_SSE2"
22597 "psadbw\t{%2, %0|%0, %2}"
22598 [(set_attr "type" "sseiadd")
22599 (set_attr "mode" "TI")])
22600
22601
22602 ;; MMX insert/extract/shuffle
22603
22604 (define_insn "sse2_pinsrw"
22605 [(set (match_operand:V8HI 0 "register_operand" "=x")
22606 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22607 (vec_duplicate:V8HI
22608 (truncate:HI
22609 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22610 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22611 "TARGET_SSE2"
22612 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22613 [(set_attr "type" "ssecvt")
22614 (set_attr "mode" "TI")])
22615
22616 (define_insn "sse2_pextrw"
22617 [(set (match_operand:SI 0 "register_operand" "=r")
22618 (zero_extend:SI
22619 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22620 (parallel
22621 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22622 "TARGET_SSE2"
22623 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22624 [(set_attr "type" "ssecvt")
22625 (set_attr "mode" "TI")])
22626
22627 (define_insn "sse2_pshufd"
22628 [(set (match_operand:V4SI 0 "register_operand" "=x")
22629 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
22630 (match_operand:SI 2 "immediate_operand" "i")]
22631 UNSPEC_SHUFFLE))]
22632 "TARGET_SSE2"
22633 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22634 [(set_attr "type" "ssecvt")
22635 (set_attr "mode" "TI")])
22636
22637 (define_insn "sse2_pshuflw"
22638 [(set (match_operand:V8HI 0 "register_operand" "=x")
22639 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
22640 (match_operand:SI 2 "immediate_operand" "i")]
22641 UNSPEC_PSHUFLW))]
22642 "TARGET_SSE2"
22643 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22644 [(set_attr "type" "ssecvt")
22645 (set_attr "mode" "TI")])
22646
22647 (define_insn "sse2_pshufhw"
22648 [(set (match_operand:V8HI 0 "register_operand" "=x")
22649 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
22650 (match_operand:SI 2 "immediate_operand" "i")]
22651 UNSPEC_PSHUFHW))]
22652 "TARGET_SSE2"
22653 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22654 [(set_attr "type" "ssecvt")
22655 (set_attr "mode" "TI")])
22656
22657 ;; MMX mask-generating comparisons
22658
22659 (define_insn "eqv16qi3"
22660 [(set (match_operand:V16QI 0 "register_operand" "=x")
22661 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22662 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22663 "TARGET_SSE2"
22664 "pcmpeqb\t{%2, %0|%0, %2}"
22665 [(set_attr "type" "ssecmp")
22666 (set_attr "mode" "TI")])
22667
22668 (define_insn "eqv8hi3"
22669 [(set (match_operand:V8HI 0 "register_operand" "=x")
22670 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22671 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22672 "TARGET_SSE2"
22673 "pcmpeqw\t{%2, %0|%0, %2}"
22674 [(set_attr "type" "ssecmp")
22675 (set_attr "mode" "TI")])
22676
22677 (define_insn "eqv4si3"
22678 [(set (match_operand:V4SI 0 "register_operand" "=x")
22679 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22680 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22681 "TARGET_SSE2"
22682 "pcmpeqd\t{%2, %0|%0, %2}"
22683 [(set_attr "type" "ssecmp")
22684 (set_attr "mode" "TI")])
22685
22686 (define_insn "gtv16qi3"
22687 [(set (match_operand:V16QI 0 "register_operand" "=x")
22688 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22689 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22690 "TARGET_SSE2"
22691 "pcmpgtb\t{%2, %0|%0, %2}"
22692 [(set_attr "type" "ssecmp")
22693 (set_attr "mode" "TI")])
22694
22695 (define_insn "gtv8hi3"
22696 [(set (match_operand:V8HI 0 "register_operand" "=x")
22697 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22698 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22699 "TARGET_SSE2"
22700 "pcmpgtw\t{%2, %0|%0, %2}"
22701 [(set_attr "type" "ssecmp")
22702 (set_attr "mode" "TI")])
22703
22704 (define_insn "gtv4si3"
22705 [(set (match_operand:V4SI 0 "register_operand" "=x")
22706 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22707 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22708 "TARGET_SSE2"
22709 "pcmpgtd\t{%2, %0|%0, %2}"
22710 [(set_attr "type" "ssecmp")
22711 (set_attr "mode" "TI")])
22712
22713
22714 ;; MMX max/min insns
22715
22716 (define_insn "umaxv16qi3"
22717 [(set (match_operand:V16QI 0 "register_operand" "=x")
22718 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22719 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22720 "TARGET_SSE2"
22721 "pmaxub\t{%2, %0|%0, %2}"
22722 [(set_attr "type" "sseiadd")
22723 (set_attr "mode" "TI")])
22724
22725 (define_insn "smaxv8hi3"
22726 [(set (match_operand:V8HI 0 "register_operand" "=x")
22727 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22728 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22729 "TARGET_SSE2"
22730 "pmaxsw\t{%2, %0|%0, %2}"
22731 [(set_attr "type" "sseiadd")
22732 (set_attr "mode" "TI")])
22733
22734 (define_insn "uminv16qi3"
22735 [(set (match_operand:V16QI 0 "register_operand" "=x")
22736 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22737 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22738 "TARGET_SSE2"
22739 "pminub\t{%2, %0|%0, %2}"
22740 [(set_attr "type" "sseiadd")
22741 (set_attr "mode" "TI")])
22742
22743 (define_insn "sminv8hi3"
22744 [(set (match_operand:V8HI 0 "register_operand" "=x")
22745 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22746 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22747 "TARGET_SSE2"
22748 "pminsw\t{%2, %0|%0, %2}"
22749 [(set_attr "type" "sseiadd")
22750 (set_attr "mode" "TI")])
22751
22752
22753 ;; MMX shifts
22754
22755 (define_insn "ashrv8hi3"
22756 [(set (match_operand:V8HI 0 "register_operand" "=x")
22757 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22758 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22759 "TARGET_SSE2"
22760 "psraw\t{%2, %0|%0, %2}"
22761 [(set_attr "type" "sseishft")
22762 (set_attr "mode" "TI")])
22763
22764 (define_insn "ashrv4si3"
22765 [(set (match_operand:V4SI 0 "register_operand" "=x")
22766 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22767 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22768 "TARGET_SSE2"
22769 "psrad\t{%2, %0|%0, %2}"
22770 [(set_attr "type" "sseishft")
22771 (set_attr "mode" "TI")])
22772
22773 (define_insn "lshrv8hi3"
22774 [(set (match_operand:V8HI 0 "register_operand" "=x")
22775 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22776 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22777 "TARGET_SSE2"
22778 "psrlw\t{%2, %0|%0, %2}"
22779 [(set_attr "type" "sseishft")
22780 (set_attr "mode" "TI")])
22781
22782 (define_insn "lshrv4si3"
22783 [(set (match_operand:V4SI 0 "register_operand" "=x")
22784 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22785 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22786 "TARGET_SSE2"
22787 "psrld\t{%2, %0|%0, %2}"
22788 [(set_attr "type" "sseishft")
22789 (set_attr "mode" "TI")])
22790
22791 (define_insn "lshrv2di3"
22792 [(set (match_operand:V2DI 0 "register_operand" "=x")
22793 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22794 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22795 "TARGET_SSE2"
22796 "psrlq\t{%2, %0|%0, %2}"
22797 [(set_attr "type" "sseishft")
22798 (set_attr "mode" "TI")])
22799
22800 (define_insn "ashlv8hi3"
22801 [(set (match_operand:V8HI 0 "register_operand" "=x")
22802 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22803 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22804 "TARGET_SSE2"
22805 "psllw\t{%2, %0|%0, %2}"
22806 [(set_attr "type" "sseishft")
22807 (set_attr "mode" "TI")])
22808
22809 (define_insn "ashlv4si3"
22810 [(set (match_operand:V4SI 0 "register_operand" "=x")
22811 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22812 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22813 "TARGET_SSE2"
22814 "pslld\t{%2, %0|%0, %2}"
22815 [(set_attr "type" "sseishft")
22816 (set_attr "mode" "TI")])
22817
22818 (define_insn "ashlv2di3"
22819 [(set (match_operand:V2DI 0 "register_operand" "=x")
22820 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22821 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22822 "TARGET_SSE2"
22823 "psllq\t{%2, %0|%0, %2}"
22824 [(set_attr "type" "sseishft")
22825 (set_attr "mode" "TI")])
22826
22827 (define_insn "ashrv8hi3_ti"
22828 [(set (match_operand:V8HI 0 "register_operand" "=x")
22829 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22830 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22831 "TARGET_SSE2"
22832 "psraw\t{%2, %0|%0, %2}"
22833 [(set_attr "type" "sseishft")
22834 (set_attr "mode" "TI")])
22835
22836 (define_insn "ashrv4si3_ti"
22837 [(set (match_operand:V4SI 0 "register_operand" "=x")
22838 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22839 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22840 "TARGET_SSE2"
22841 "psrad\t{%2, %0|%0, %2}"
22842 [(set_attr "type" "sseishft")
22843 (set_attr "mode" "TI")])
22844
22845 (define_insn "lshrv8hi3_ti"
22846 [(set (match_operand:V8HI 0 "register_operand" "=x")
22847 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22848 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22849 "TARGET_SSE2"
22850 "psrlw\t{%2, %0|%0, %2}"
22851 [(set_attr "type" "sseishft")
22852 (set_attr "mode" "TI")])
22853
22854 (define_insn "lshrv4si3_ti"
22855 [(set (match_operand:V4SI 0 "register_operand" "=x")
22856 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22857 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22858 "TARGET_SSE2"
22859 "psrld\t{%2, %0|%0, %2}"
22860 [(set_attr "type" "sseishft")
22861 (set_attr "mode" "TI")])
22862
22863 (define_insn "lshrv2di3_ti"
22864 [(set (match_operand:V2DI 0 "register_operand" "=x")
22865 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22866 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22867 "TARGET_SSE2"
22868 "psrlq\t{%2, %0|%0, %2}"
22869 [(set_attr "type" "sseishft")
22870 (set_attr "mode" "TI")])
22871
22872 (define_insn "ashlv8hi3_ti"
22873 [(set (match_operand:V8HI 0 "register_operand" "=x")
22874 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22875 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22876 "TARGET_SSE2"
22877 "psllw\t{%2, %0|%0, %2}"
22878 [(set_attr "type" "sseishft")
22879 (set_attr "mode" "TI")])
22880
22881 (define_insn "ashlv4si3_ti"
22882 [(set (match_operand:V4SI 0 "register_operand" "=x")
22883 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22884 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22885 "TARGET_SSE2"
22886 "pslld\t{%2, %0|%0, %2}"
22887 [(set_attr "type" "sseishft")
22888 (set_attr "mode" "TI")])
22889
22890 (define_insn "ashlv2di3_ti"
22891 [(set (match_operand:V2DI 0 "register_operand" "=x")
22892 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22893 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22894 "TARGET_SSE2"
22895 "psllq\t{%2, %0|%0, %2}"
22896 [(set_attr "type" "sseishft")
22897 (set_attr "mode" "TI")])
22898
22899 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22900 ;; we wouldn't need here it since we never generate TImode arithmetic.
22901
22902 ;; There has to be some kind of prize for the weirdest new instruction...
22903 (define_insn "sse2_ashlti3"
22904 [(set (match_operand:TI 0 "register_operand" "=x")
22905 (unspec:TI
22906 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22907 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22908 (const_int 8)))] UNSPEC_NOP))]
22909 "TARGET_SSE2"
22910 "pslldq\t{%2, %0|%0, %2}"
22911 [(set_attr "type" "sseishft")
22912 (set_attr "mode" "TI")])
22913
22914 (define_insn "sse2_lshrti3"
22915 [(set (match_operand:TI 0 "register_operand" "=x")
22916 (unspec:TI
22917 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22918 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22919 (const_int 8)))] UNSPEC_NOP))]
22920 "TARGET_SSE2"
22921 "psrldq\t{%2, %0|%0, %2}"
22922 [(set_attr "type" "sseishft")
22923 (set_attr "mode" "TI")])
22924
22925 ;; SSE unpack
22926
22927 (define_insn "sse2_unpckhpd"
22928 [(set (match_operand:V2DF 0 "register_operand" "=x")
22929 (vec_concat:V2DF
22930 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22931 (parallel [(const_int 1)]))
22932 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22933 (parallel [(const_int 1)]))))]
22934 "TARGET_SSE2"
22935 "unpckhpd\t{%2, %0|%0, %2}"
22936 [(set_attr "type" "ssecvt")
22937 (set_attr "mode" "V2DF")])
22938
22939 (define_insn "sse2_unpcklpd"
22940 [(set (match_operand:V2DF 0 "register_operand" "=x")
22941 (vec_concat:V2DF
22942 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22943 (parallel [(const_int 0)]))
22944 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22945 (parallel [(const_int 0)]))))]
22946 "TARGET_SSE2"
22947 "unpcklpd\t{%2, %0|%0, %2}"
22948 [(set_attr "type" "ssecvt")
22949 (set_attr "mode" "V2DF")])
22950
22951 ;; MMX pack/unpack insns.
22952
22953 (define_insn "sse2_packsswb"
22954 [(set (match_operand:V16QI 0 "register_operand" "=x")
22955 (vec_concat:V16QI
22956 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22957 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22958 "TARGET_SSE2"
22959 "packsswb\t{%2, %0|%0, %2}"
22960 [(set_attr "type" "ssecvt")
22961 (set_attr "mode" "TI")])
22962
22963 (define_insn "sse2_packssdw"
22964 [(set (match_operand:V8HI 0 "register_operand" "=x")
22965 (vec_concat:V8HI
22966 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22967 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22968 "TARGET_SSE2"
22969 "packssdw\t{%2, %0|%0, %2}"
22970 [(set_attr "type" "ssecvt")
22971 (set_attr "mode" "TI")])
22972
22973 (define_insn "sse2_packuswb"
22974 [(set (match_operand:V16QI 0 "register_operand" "=x")
22975 (vec_concat:V16QI
22976 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22977 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22978 "TARGET_SSE2"
22979 "packuswb\t{%2, %0|%0, %2}"
22980 [(set_attr "type" "ssecvt")
22981 (set_attr "mode" "TI")])
22982
22983 (define_insn "sse2_punpckhbw"
22984 [(set (match_operand:V16QI 0 "register_operand" "=x")
22985 (vec_merge:V16QI
22986 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22987 (parallel [(const_int 8) (const_int 0)
22988 (const_int 9) (const_int 1)
22989 (const_int 10) (const_int 2)
22990 (const_int 11) (const_int 3)
22991 (const_int 12) (const_int 4)
22992 (const_int 13) (const_int 5)
22993 (const_int 14) (const_int 6)
22994 (const_int 15) (const_int 7)]))
22995 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22996 (parallel [(const_int 0) (const_int 8)
22997 (const_int 1) (const_int 9)
22998 (const_int 2) (const_int 10)
22999 (const_int 3) (const_int 11)
23000 (const_int 4) (const_int 12)
23001 (const_int 5) (const_int 13)
23002 (const_int 6) (const_int 14)
23003 (const_int 7) (const_int 15)]))
23004 (const_int 21845)))]
23005 "TARGET_SSE2"
23006 "punpckhbw\t{%2, %0|%0, %2}"
23007 [(set_attr "type" "ssecvt")
23008 (set_attr "mode" "TI")])
23009
23010 (define_insn "sse2_punpckhwd"
23011 [(set (match_operand:V8HI 0 "register_operand" "=x")
23012 (vec_merge:V8HI
23013 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23014 (parallel [(const_int 4) (const_int 0)
23015 (const_int 5) (const_int 1)
23016 (const_int 6) (const_int 2)
23017 (const_int 7) (const_int 3)]))
23018 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23019 (parallel [(const_int 0) (const_int 4)
23020 (const_int 1) (const_int 5)
23021 (const_int 2) (const_int 6)
23022 (const_int 3) (const_int 7)]))
23023 (const_int 85)))]
23024 "TARGET_SSE2"
23025 "punpckhwd\t{%2, %0|%0, %2}"
23026 [(set_attr "type" "ssecvt")
23027 (set_attr "mode" "TI")])
23028
23029 (define_insn "sse2_punpckhdq"
23030 [(set (match_operand:V4SI 0 "register_operand" "=x")
23031 (vec_merge:V4SI
23032 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23033 (parallel [(const_int 2) (const_int 0)
23034 (const_int 3) (const_int 1)]))
23035 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23036 (parallel [(const_int 0) (const_int 2)
23037 (const_int 1) (const_int 3)]))
23038 (const_int 5)))]
23039 "TARGET_SSE2"
23040 "punpckhdq\t{%2, %0|%0, %2}"
23041 [(set_attr "type" "ssecvt")
23042 (set_attr "mode" "TI")])
23043
23044 (define_insn "sse2_punpcklbw"
23045 [(set (match_operand:V16QI 0 "register_operand" "=x")
23046 (vec_merge:V16QI
23047 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23048 (parallel [(const_int 0) (const_int 8)
23049 (const_int 1) (const_int 9)
23050 (const_int 2) (const_int 10)
23051 (const_int 3) (const_int 11)
23052 (const_int 4) (const_int 12)
23053 (const_int 5) (const_int 13)
23054 (const_int 6) (const_int 14)
23055 (const_int 7) (const_int 15)]))
23056 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23057 (parallel [(const_int 8) (const_int 0)
23058 (const_int 9) (const_int 1)
23059 (const_int 10) (const_int 2)
23060 (const_int 11) (const_int 3)
23061 (const_int 12) (const_int 4)
23062 (const_int 13) (const_int 5)
23063 (const_int 14) (const_int 6)
23064 (const_int 15) (const_int 7)]))
23065 (const_int 21845)))]
23066 "TARGET_SSE2"
23067 "punpcklbw\t{%2, %0|%0, %2}"
23068 [(set_attr "type" "ssecvt")
23069 (set_attr "mode" "TI")])
23070
23071 (define_insn "sse2_punpcklwd"
23072 [(set (match_operand:V8HI 0 "register_operand" "=x")
23073 (vec_merge:V8HI
23074 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23075 (parallel [(const_int 0) (const_int 4)
23076 (const_int 1) (const_int 5)
23077 (const_int 2) (const_int 6)
23078 (const_int 3) (const_int 7)]))
23079 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23080 (parallel [(const_int 4) (const_int 0)
23081 (const_int 5) (const_int 1)
23082 (const_int 6) (const_int 2)
23083 (const_int 7) (const_int 3)]))
23084 (const_int 85)))]
23085 "TARGET_SSE2"
23086 "punpcklwd\t{%2, %0|%0, %2}"
23087 [(set_attr "type" "ssecvt")
23088 (set_attr "mode" "TI")])
23089
23090 (define_insn "sse2_punpckldq"
23091 [(set (match_operand:V4SI 0 "register_operand" "=x")
23092 (vec_merge:V4SI
23093 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23094 (parallel [(const_int 0) (const_int 2)
23095 (const_int 1) (const_int 3)]))
23096 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23097 (parallel [(const_int 2) (const_int 0)
23098 (const_int 3) (const_int 1)]))
23099 (const_int 5)))]
23100 "TARGET_SSE2"
23101 "punpckldq\t{%2, %0|%0, %2}"
23102 [(set_attr "type" "ssecvt")
23103 (set_attr "mode" "TI")])
23104
23105 (define_insn "sse2_punpcklqdq"
23106 [(set (match_operand:V2DI 0 "register_operand" "=x")
23107 (vec_merge:V2DI
23108 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23109 (parallel [(const_int 1)
23110 (const_int 0)]))
23111 (match_operand:V2DI 1 "register_operand" "0")
23112 (const_int 1)))]
23113 "TARGET_SSE2"
23114 "punpcklqdq\t{%2, %0|%0, %2}"
23115 [(set_attr "type" "ssecvt")
23116 (set_attr "mode" "TI")])
23117
23118 (define_insn "sse2_punpckhqdq"
23119 [(set (match_operand:V2DI 0 "register_operand" "=x")
23120 (vec_merge:V2DI
23121 (match_operand:V2DI 1 "register_operand" "0")
23122 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23123 (parallel [(const_int 1)
23124 (const_int 0)]))
23125 (const_int 1)))]
23126 "TARGET_SSE2"
23127 "punpckhqdq\t{%2, %0|%0, %2}"
23128 [(set_attr "type" "ssecvt")
23129 (set_attr "mode" "TI")])
23130
23131 ;; SSE2 moves
23132
23133 (define_insn "sse2_movapd"
23134 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23135 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23136 UNSPEC_MOVA))]
23137 "TARGET_SSE2
23138 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23139 "movapd\t{%1, %0|%0, %1}"
23140 [(set_attr "type" "ssemov")
23141 (set_attr "mode" "V2DF")])
23142
23143 (define_insn "sse2_movupd"
23144 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23145 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23146 UNSPEC_MOVU))]
23147 "TARGET_SSE2
23148 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23149 "movupd\t{%1, %0|%0, %1}"
23150 [(set_attr "type" "ssecvt")
23151 (set_attr "mode" "V2DF")])
23152
23153 (define_insn "sse2_movdqa"
23154 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23155 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23156 UNSPEC_MOVA))]
23157 "TARGET_SSE2
23158 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23159 "movdqa\t{%1, %0|%0, %1}"
23160 [(set_attr "type" "ssemov")
23161 (set_attr "mode" "TI")])
23162
23163 (define_insn "sse2_movdqu"
23164 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23165 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23166 UNSPEC_MOVU))]
23167 "TARGET_SSE2
23168 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23169 "movdqu\t{%1, %0|%0, %1}"
23170 [(set_attr "type" "ssecvt")
23171 (set_attr "mode" "TI")])
23172
23173 (define_insn "sse2_movdq2q"
23174 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23175 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23176 (parallel [(const_int 0)])))]
23177 "TARGET_SSE2 && !TARGET_64BIT"
23178 "@
23179 movq\t{%1, %0|%0, %1}
23180 movdq2q\t{%1, %0|%0, %1}"
23181 [(set_attr "type" "ssecvt")
23182 (set_attr "mode" "TI")])
23183
23184 (define_insn "sse2_movdq2q_rex64"
23185 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23186 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23187 (parallel [(const_int 0)])))]
23188 "TARGET_SSE2 && TARGET_64BIT"
23189 "@
23190 movq\t{%1, %0|%0, %1}
23191 movdq2q\t{%1, %0|%0, %1}
23192 movd\t{%1, %0|%0, %1}"
23193 [(set_attr "type" "ssecvt")
23194 (set_attr "mode" "TI")])
23195
23196 (define_insn "sse2_movq2dq"
23197 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23198 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23199 (const_int 0)))]
23200 "TARGET_SSE2 && !TARGET_64BIT"
23201 "@
23202 movq\t{%1, %0|%0, %1}
23203 movq2dq\t{%1, %0|%0, %1}"
23204 [(set_attr "type" "ssecvt,ssemov")
23205 (set_attr "mode" "TI")])
23206
23207 (define_insn "sse2_movq2dq_rex64"
23208 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23209 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23210 (const_int 0)))]
23211 "TARGET_SSE2 && TARGET_64BIT"
23212 "@
23213 movq\t{%1, %0|%0, %1}
23214 movq2dq\t{%1, %0|%0, %1}
23215 movd\t{%1, %0|%0, %1}"
23216 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23217 (set_attr "mode" "TI")])
23218
23219 (define_insn "sse2_movq"
23220 [(set (match_operand:V2DI 0 "register_operand" "=x")
23221 (vec_concat:V2DI (vec_select:DI
23222 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23223 (parallel [(const_int 0)]))
23224 (const_int 0)))]
23225 "TARGET_SSE2"
23226 "movq\t{%1, %0|%0, %1}"
23227 [(set_attr "type" "ssemov")
23228 (set_attr "mode" "TI")])
23229
23230 (define_insn "sse2_loadd"
23231 [(set (match_operand:V4SI 0 "register_operand" "=x")
23232 (vec_merge:V4SI
23233 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23234 (const_vector:V4SI [(const_int 0)
23235 (const_int 0)
23236 (const_int 0)
23237 (const_int 0)])
23238 (const_int 1)))]
23239 "TARGET_SSE2"
23240 "movd\t{%1, %0|%0, %1}"
23241 [(set_attr "type" "ssemov")
23242 (set_attr "mode" "TI")])
23243
23244 (define_insn "sse2_stored"
23245 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23246 (vec_select:SI
23247 (match_operand:V4SI 1 "register_operand" "x")
23248 (parallel [(const_int 0)])))]
23249 "TARGET_SSE2"
23250 "movd\t{%1, %0|%0, %1}"
23251 [(set_attr "type" "ssemov")
23252 (set_attr "mode" "TI")])
23253
23254 (define_insn "sse2_movhpd"
23255 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23256 (vec_merge:V2DF
23257 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23258 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23259 (const_int 2)))]
23260 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23261 "movhpd\t{%2, %0|%0, %2}"
23262 [(set_attr "type" "ssecvt")
23263 (set_attr "mode" "V2DF")])
23264
23265 (define_expand "sse2_loadsd"
23266 [(match_operand:V2DF 0 "register_operand" "")
23267 (match_operand:DF 1 "memory_operand" "")]
23268 "TARGET_SSE2"
23269 {
23270 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23271 CONST0_RTX (V2DFmode)));
23272 DONE;
23273 })
23274
23275 (define_insn "sse2_loadsd_1"
23276 [(set (match_operand:V2DF 0 "register_operand" "=x")
23277 (vec_merge:V2DF
23278 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23279 (match_operand:V2DF 2 "const0_operand" "X")
23280 (const_int 1)))]
23281 "TARGET_SSE2"
23282 "movsd\t{%1, %0|%0, %1}"
23283 [(set_attr "type" "ssecvt")
23284 (set_attr "mode" "DF")])
23285
23286 (define_insn "sse2_movsd"
23287 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
23288 (vec_merge:V2DF
23289 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
23290 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
23291 (const_int 1)))]
23292 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
23293 "@movsd\t{%2, %0|%0, %2}
23294 movlpd\t{%2, %0|%0, %2}
23295 movlpd\t{%2, %0|%0, %2}"
23296 [(set_attr "type" "ssecvt")
23297 (set_attr "mode" "DF,V2DF,V2DF")])
23298
23299 (define_insn "sse2_storesd"
23300 [(set (match_operand:DF 0 "memory_operand" "=m")
23301 (vec_select:DF
23302 (match_operand:V2DF 1 "register_operand" "x")
23303 (parallel [(const_int 0)])))]
23304 "TARGET_SSE2"
23305 "movsd\t{%1, %0|%0, %1}"
23306 [(set_attr "type" "ssecvt")
23307 (set_attr "mode" "DF")])
23308
23309 (define_insn "sse2_shufpd"
23310 [(set (match_operand:V2DF 0 "register_operand" "=x")
23311 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23312 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23313 (match_operand:SI 3 "immediate_operand" "i")]
23314 UNSPEC_SHUFFLE))]
23315 "TARGET_SSE2"
23316 ;; @@@ check operand order for intel/nonintel syntax
23317 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23318 [(set_attr "type" "ssecvt")
23319 (set_attr "mode" "V2DF")])
23320
23321 (define_insn "sse2_clflush"
23322 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23323 UNSPECV_CLFLUSH)]
23324 "TARGET_SSE2"
23325 "clflush %0"
23326 [(set_attr "type" "sse")
23327 (set_attr "memory" "unknown")])
23328
23329 (define_expand "sse2_mfence"
23330 [(set (match_dup 0)
23331 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23332 "TARGET_SSE2"
23333 {
23334 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23335 MEM_VOLATILE_P (operands[0]) = 1;
23336 })
23337
23338 (define_insn "*mfence_insn"
23339 [(set (match_operand:BLK 0 "" "")
23340 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23341 "TARGET_SSE2"
23342 "mfence"
23343 [(set_attr "type" "sse")
23344 (set_attr "memory" "unknown")])
23345
23346 (define_expand "sse2_lfence"
23347 [(set (match_dup 0)
23348 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23349 "TARGET_SSE2"
23350 {
23351 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23352 MEM_VOLATILE_P (operands[0]) = 1;
23353 })
23354
23355 (define_insn "*lfence_insn"
23356 [(set (match_operand:BLK 0 "" "")
23357 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23358 "TARGET_SSE2"
23359 "lfence"
23360 [(set_attr "type" "sse")
23361 (set_attr "memory" "unknown")])
23362
23363 ;; SSE3
23364
23365 (define_insn "mwait"
23366 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23367 (match_operand:SI 1 "register_operand" "c")]
23368 UNSPECV_MWAIT)]
23369 "TARGET_SSE3"
23370 "mwait\t%0, %1"
23371 [(set_attr "length" "3")])
23372
23373 (define_insn "monitor"
23374 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23375 (match_operand:SI 1 "register_operand" "c")
23376 (match_operand:SI 2 "register_operand" "d")]
23377 UNSPECV_MONITOR)]
23378 "TARGET_SSE3"
23379 "monitor\t%0, %1, %2"
23380 [(set_attr "length" "3")])
23381
23382 ;; SSE3 arithmetic
23383
23384 (define_insn "addsubv4sf3"
23385 [(set (match_operand:V4SF 0 "register_operand" "=x")
23386 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23387 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23388 UNSPEC_ADDSUB))]
23389 "TARGET_SSE3"
23390 "addsubps\t{%2, %0|%0, %2}"
23391 [(set_attr "type" "sseadd")
23392 (set_attr "mode" "V4SF")])
23393
23394 (define_insn "addsubv2df3"
23395 [(set (match_operand:V2DF 0 "register_operand" "=x")
23396 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23397 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23398 UNSPEC_ADDSUB))]
23399 "TARGET_SSE3"
23400 "addsubpd\t{%2, %0|%0, %2}"
23401 [(set_attr "type" "sseadd")
23402 (set_attr "mode" "V2DF")])
23403
23404 (define_insn "haddv4sf3"
23405 [(set (match_operand:V4SF 0 "register_operand" "=x")
23406 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23407 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23408 UNSPEC_HADD))]
23409 "TARGET_SSE3"
23410 "haddps\t{%2, %0|%0, %2}"
23411 [(set_attr "type" "sseadd")
23412 (set_attr "mode" "V4SF")])
23413
23414 (define_insn "haddv2df3"
23415 [(set (match_operand:V2DF 0 "register_operand" "=x")
23416 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23417 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23418 UNSPEC_HADD))]
23419 "TARGET_SSE3"
23420 "haddpd\t{%2, %0|%0, %2}"
23421 [(set_attr "type" "sseadd")
23422 (set_attr "mode" "V2DF")])
23423
23424 (define_insn "hsubv4sf3"
23425 [(set (match_operand:V4SF 0 "register_operand" "=x")
23426 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23427 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23428 UNSPEC_HSUB))]
23429 "TARGET_SSE3"
23430 "hsubps\t{%2, %0|%0, %2}"
23431 [(set_attr "type" "sseadd")
23432 (set_attr "mode" "V4SF")])
23433
23434 (define_insn "hsubv2df3"
23435 [(set (match_operand:V2DF 0 "register_operand" "=x")
23436 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23437 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23438 UNSPEC_HSUB))]
23439 "TARGET_SSE3"
23440 "hsubpd\t{%2, %0|%0, %2}"
23441 [(set_attr "type" "sseadd")
23442 (set_attr "mode" "V2DF")])
23443
23444 (define_insn "movshdup"
23445 [(set (match_operand:V4SF 0 "register_operand" "=x")
23446 (unspec:V4SF
23447 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23448 "TARGET_SSE3"
23449 "movshdup\t{%1, %0|%0, %1}"
23450 [(set_attr "type" "sse")
23451 (set_attr "mode" "V4SF")])
23452
23453 (define_insn "movsldup"
23454 [(set (match_operand:V4SF 0 "register_operand" "=x")
23455 (unspec:V4SF
23456 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23457 "TARGET_SSE3"
23458 "movsldup\t{%1, %0|%0, %1}"
23459 [(set_attr "type" "sse")
23460 (set_attr "mode" "V4SF")])
23461
23462 (define_insn "lddqu"
23463 [(set (match_operand:V16QI 0 "register_operand" "=x")
23464 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23465 UNSPEC_LDQQU))]
23466 "TARGET_SSE3"
23467 "lddqu\t{%1, %0|%0, %1}"
23468 [(set_attr "type" "ssecvt")
23469 (set_attr "mode" "TI")])
23470
23471 (define_insn "loadddup"
23472 [(set (match_operand:V2DF 0 "register_operand" "=x")
23473 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23474 "TARGET_SSE3"
23475 "movddup\t{%1, %0|%0, %1}"
23476 [(set_attr "type" "ssecvt")
23477 (set_attr "mode" "DF")])
23478
23479 (define_insn "movddup"
23480 [(set (match_operand:V2DF 0 "register_operand" "=x")
23481 (vec_duplicate:V2DF
23482 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23483 (parallel [(const_int 0)]))))]
23484 "TARGET_SSE3"
23485 "movddup\t{%1, %0|%0, %1}"
23486 [(set_attr "type" "ssecvt")
23487 (set_attr "mode" "DF")])