re PR target/14702 (wrong definitions of instructions mmx_pshufw, sse2_pshufd, sse2_p...
[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 ; REP instruction
125 (UNSPEC_REP 75)
126 ])
127
128 (define_constants
129 [(UNSPECV_BLOCKAGE 0)
130 (UNSPECV_EH_RETURN 13)
131 (UNSPECV_EMMS 31)
132 (UNSPECV_LDMXCSR 37)
133 (UNSPECV_STMXCSR 40)
134 (UNSPECV_FEMMS 46)
135 (UNSPECV_CLFLUSH 57)
136 (UNSPECV_ALIGN 68)
137 (UNSPECV_MONITOR 69)
138 (UNSPECV_MWAIT 70)
139 ])
140
141 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
142 ;; from i386.c.
143
144 ;; In C guard expressions, put expressions which may be compile-time
145 ;; constants first. This allows for better optimization. For
146 ;; example, write "TARGET_64BIT && reload_completed", not
147 ;; "reload_completed && TARGET_64BIT".
148
149 \f
150 ;; Processor type. This attribute must exactly match the processor_type
151 ;; enumeration in i386.h.
152 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153 (const (symbol_ref "ix86_tune")))
154
155 ;; A basic instruction type. Refinements due to arguments to be
156 ;; provided in other attributes.
157 (define_attr "type"
158 "other,multi,
159 alu,alu1,negnot,imov,imovx,lea,
160 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161 icmp,test,ibr,setcc,icmov,
162 push,pop,call,callv,leave,
163 str,cld,
164 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165 sselog,sseiadd,sseishft,sseimul,
166 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
168 (const_string "other"))
169
170 ;; Main data type used by the insn
171 (define_attr "mode"
172 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
173 (const_string "unknown"))
174
175 ;; The CPU unit operations uses.
176 (define_attr "unit" "integer,i387,sse,mmx,unknown"
177 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178 (const_string "i387")
179 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181 (const_string "sse")
182 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183 (const_string "mmx")
184 (eq_attr "type" "other")
185 (const_string "unknown")]
186 (const_string "integer")))
187
188 ;; The (bounding maximum) length of an instruction immediate.
189 (define_attr "length_immediate" ""
190 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
191 (const_int 0)
192 (eq_attr "unit" "i387,sse,mmx")
193 (const_int 0)
194 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195 imul,icmp,push,pop")
196 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
197 (eq_attr "type" "imov,test")
198 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
199 (eq_attr "type" "call")
200 (if_then_else (match_operand 0 "constant_call_address_operand" "")
201 (const_int 4)
202 (const_int 0))
203 (eq_attr "type" "callv")
204 (if_then_else (match_operand 1 "constant_call_address_operand" "")
205 (const_int 4)
206 (const_int 0))
207 ;; We don't know the size before shorten_branches. Expect
208 ;; the instruction to fit for better scheduling.
209 (eq_attr "type" "ibr")
210 (const_int 1)
211 ]
212 (symbol_ref "/* Update immediate_length and other attributes! */
213 abort(),1")))
214
215 ;; The (bounding maximum) length of an instruction address.
216 (define_attr "length_address" ""
217 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
218 (const_int 0)
219 (and (eq_attr "type" "call")
220 (match_operand 0 "constant_call_address_operand" ""))
221 (const_int 0)
222 (and (eq_attr "type" "callv")
223 (match_operand 1 "constant_call_address_operand" ""))
224 (const_int 0)
225 ]
226 (symbol_ref "ix86_attr_length_address_default (insn)")))
227
228 ;; Set when length prefix is used.
229 (define_attr "prefix_data16" ""
230 (if_then_else (ior (eq_attr "mode" "HI")
231 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
232 (const_int 1)
233 (const_int 0)))
234
235 ;; Set when string REP prefix is used.
236 (define_attr "prefix_rep" ""
237 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238 (const_int 1)
239 (const_int 0)))
240
241 ;; Set when 0f opcode prefix is used.
242 (define_attr "prefix_0f" ""
243 (if_then_else
244 (ior (eq_attr "type" "imovx,setcc,icmov")
245 (eq_attr "unit" "sse,mmx"))
246 (const_int 1)
247 (const_int 0)))
248
249 ;; Set when REX opcode prefix is used.
250 (define_attr "prefix_rex" ""
251 (cond [(and (eq_attr "mode" "DI")
252 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253 (const_int 1)
254 (and (eq_attr "mode" "QI")
255 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256 (const_int 0)))
257 (const_int 1)
258 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259 (const_int 0))
260 (const_int 1)
261 ]
262 (const_int 0)))
263
264 ;; Set when modrm byte is used.
265 (define_attr "modrm" ""
266 (cond [(eq_attr "type" "str,cld,leave")
267 (const_int 0)
268 (eq_attr "unit" "i387")
269 (const_int 0)
270 (and (eq_attr "type" "incdec")
271 (ior (match_operand:SI 1 "register_operand" "")
272 (match_operand:HI 1 "register_operand" "")))
273 (const_int 0)
274 (and (eq_attr "type" "push")
275 (not (match_operand 1 "memory_operand" "")))
276 (const_int 0)
277 (and (eq_attr "type" "pop")
278 (not (match_operand 0 "memory_operand" "")))
279 (const_int 0)
280 (and (eq_attr "type" "imov")
281 (and (match_operand 0 "register_operand" "")
282 (match_operand 1 "immediate_operand" "")))
283 (const_int 0)
284 (and (eq_attr "type" "call")
285 (match_operand 0 "constant_call_address_operand" ""))
286 (const_int 0)
287 (and (eq_attr "type" "callv")
288 (match_operand 1 "constant_call_address_operand" ""))
289 (const_int 0)
290 ]
291 (const_int 1)))
292
293 ;; The (bounding maximum) length of an instruction in bytes.
294 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
295 ;; to split it and compute proper length as for other insns.
296 (define_attr "length" ""
297 (cond [(eq_attr "type" "other,multi,fistp")
298 (const_int 16)
299 (eq_attr "type" "fcmp")
300 (const_int 4)
301 (eq_attr "unit" "i387")
302 (plus (const_int 2)
303 (plus (attr "prefix_data16")
304 (attr "length_address")))]
305 (plus (plus (attr "modrm")
306 (plus (attr "prefix_0f")
307 (plus (attr "prefix_rex")
308 (const_int 1))))
309 (plus (attr "prefix_rep")
310 (plus (attr "prefix_data16")
311 (plus (attr "length_immediate")
312 (attr "length_address")))))))
313
314 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
315 ;; `store' if there is a simple memory reference therein, or `unknown'
316 ;; if the instruction is complex.
317
318 (define_attr "memory" "none,load,store,both,unknown"
319 (cond [(eq_attr "type" "other,multi,str")
320 (const_string "unknown")
321 (eq_attr "type" "lea,fcmov,fpspc,cld")
322 (const_string "none")
323 (eq_attr "type" "fistp,leave")
324 (const_string "both")
325 (eq_attr "type" "push")
326 (if_then_else (match_operand 1 "memory_operand" "")
327 (const_string "both")
328 (const_string "store"))
329 (eq_attr "type" "pop")
330 (if_then_else (match_operand 0 "memory_operand" "")
331 (const_string "both")
332 (const_string "load"))
333 (eq_attr "type" "setcc")
334 (if_then_else (match_operand 0 "memory_operand" "")
335 (const_string "store")
336 (const_string "none"))
337 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
338 (if_then_else (ior (match_operand 0 "memory_operand" "")
339 (match_operand 1 "memory_operand" ""))
340 (const_string "load")
341 (const_string "none"))
342 (eq_attr "type" "ibr")
343 (if_then_else (match_operand 0 "memory_operand" "")
344 (const_string "load")
345 (const_string "none"))
346 (eq_attr "type" "call")
347 (if_then_else (match_operand 0 "constant_call_address_operand" "")
348 (const_string "none")
349 (const_string "load"))
350 (eq_attr "type" "callv")
351 (if_then_else (match_operand 1 "constant_call_address_operand" "")
352 (const_string "none")
353 (const_string "load"))
354 (and (eq_attr "type" "alu1,negnot,ishift1")
355 (match_operand 1 "memory_operand" ""))
356 (const_string "both")
357 (and (match_operand 0 "memory_operand" "")
358 (match_operand 1 "memory_operand" ""))
359 (const_string "both")
360 (match_operand 0 "memory_operand" "")
361 (const_string "store")
362 (match_operand 1 "memory_operand" "")
363 (const_string "load")
364 (and (eq_attr "type"
365 "!alu1,negnot,ishift1,
366 imov,imovx,icmp,test,
367 fmov,fcmp,fsgn,
368 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369 mmx,mmxmov,mmxcmp,mmxcvt")
370 (match_operand 2 "memory_operand" ""))
371 (const_string "load")
372 (and (eq_attr "type" "icmov")
373 (match_operand 3 "memory_operand" ""))
374 (const_string "load")
375 ]
376 (const_string "none")))
377
378 ;; Indicates if an instruction has both an immediate and a displacement.
379
380 (define_attr "imm_disp" "false,true,unknown"
381 (cond [(eq_attr "type" "other,multi")
382 (const_string "unknown")
383 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
384 (and (match_operand 0 "memory_displacement_operand" "")
385 (match_operand 1 "immediate_operand" "")))
386 (const_string "true")
387 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
388 (and (match_operand 0 "memory_displacement_operand" "")
389 (match_operand 2 "immediate_operand" "")))
390 (const_string "true")
391 ]
392 (const_string "false")))
393
394 ;; Indicates if an FP operation has an integer source.
395
396 (define_attr "fp_int_src" "false,true"
397 (const_string "false"))
398
399 ;; Describe a user's asm statement.
400 (define_asm_attributes
401 [(set_attr "length" "128")
402 (set_attr "type" "multi")])
403 \f
404 (include "pentium.md")
405 (include "ppro.md")
406 (include "k6.md")
407 (include "athlon.md")
408 \f
409 ;; Compare instructions.
410
411 ;; All compare insns have expanders that save the operands away without
412 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
413 ;; after the cmp) will actually emit the cmpM.
414
415 (define_expand "cmpdi"
416 [(set (reg:CC 17)
417 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
418 (match_operand:DI 1 "x86_64_general_operand" "")))]
419 ""
420 {
421 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
422 operands[0] = force_reg (DImode, operands[0]);
423 ix86_compare_op0 = operands[0];
424 ix86_compare_op1 = operands[1];
425 DONE;
426 })
427
428 (define_expand "cmpsi"
429 [(set (reg:CC 17)
430 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
431 (match_operand:SI 1 "general_operand" "")))]
432 ""
433 {
434 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
435 operands[0] = force_reg (SImode, operands[0]);
436 ix86_compare_op0 = operands[0];
437 ix86_compare_op1 = operands[1];
438 DONE;
439 })
440
441 (define_expand "cmphi"
442 [(set (reg:CC 17)
443 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
444 (match_operand:HI 1 "general_operand" "")))]
445 ""
446 {
447 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
448 operands[0] = force_reg (HImode, operands[0]);
449 ix86_compare_op0 = operands[0];
450 ix86_compare_op1 = operands[1];
451 DONE;
452 })
453
454 (define_expand "cmpqi"
455 [(set (reg:CC 17)
456 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
457 (match_operand:QI 1 "general_operand" "")))]
458 "TARGET_QIMODE_MATH"
459 {
460 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
461 operands[0] = force_reg (QImode, operands[0]);
462 ix86_compare_op0 = operands[0];
463 ix86_compare_op1 = operands[1];
464 DONE;
465 })
466
467 (define_insn "cmpdi_ccno_1_rex64"
468 [(set (reg 17)
469 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
470 (match_operand:DI 1 "const0_operand" "n,n")))]
471 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
472 "@
473 test{q}\t{%0, %0|%0, %0}
474 cmp{q}\t{%1, %0|%0, %1}"
475 [(set_attr "type" "test,icmp")
476 (set_attr "length_immediate" "0,1")
477 (set_attr "mode" "DI")])
478
479 (define_insn "*cmpdi_minus_1_rex64"
480 [(set (reg 17)
481 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
482 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
483 (const_int 0)))]
484 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
485 "cmp{q}\t{%1, %0|%0, %1}"
486 [(set_attr "type" "icmp")
487 (set_attr "mode" "DI")])
488
489 (define_expand "cmpdi_1_rex64"
490 [(set (reg:CC 17)
491 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
492 (match_operand:DI 1 "general_operand" "")))]
493 "TARGET_64BIT"
494 "")
495
496 (define_insn "cmpdi_1_insn_rex64"
497 [(set (reg 17)
498 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
499 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
500 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
501 "cmp{q}\t{%1, %0|%0, %1}"
502 [(set_attr "type" "icmp")
503 (set_attr "mode" "DI")])
504
505
506 (define_insn "*cmpsi_ccno_1"
507 [(set (reg 17)
508 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
509 (match_operand:SI 1 "const0_operand" "n,n")))]
510 "ix86_match_ccmode (insn, CCNOmode)"
511 "@
512 test{l}\t{%0, %0|%0, %0}
513 cmp{l}\t{%1, %0|%0, %1}"
514 [(set_attr "type" "test,icmp")
515 (set_attr "length_immediate" "0,1")
516 (set_attr "mode" "SI")])
517
518 (define_insn "*cmpsi_minus_1"
519 [(set (reg 17)
520 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
521 (match_operand:SI 1 "general_operand" "ri,mr"))
522 (const_int 0)))]
523 "ix86_match_ccmode (insn, CCGOCmode)"
524 "cmp{l}\t{%1, %0|%0, %1}"
525 [(set_attr "type" "icmp")
526 (set_attr "mode" "SI")])
527
528 (define_expand "cmpsi_1"
529 [(set (reg:CC 17)
530 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
531 (match_operand:SI 1 "general_operand" "ri,mr")))]
532 ""
533 "")
534
535 (define_insn "*cmpsi_1_insn"
536 [(set (reg 17)
537 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
538 (match_operand:SI 1 "general_operand" "ri,mr")))]
539 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
540 && ix86_match_ccmode (insn, CCmode)"
541 "cmp{l}\t{%1, %0|%0, %1}"
542 [(set_attr "type" "icmp")
543 (set_attr "mode" "SI")])
544
545 (define_insn "*cmphi_ccno_1"
546 [(set (reg 17)
547 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
548 (match_operand:HI 1 "const0_operand" "n,n")))]
549 "ix86_match_ccmode (insn, CCNOmode)"
550 "@
551 test{w}\t{%0, %0|%0, %0}
552 cmp{w}\t{%1, %0|%0, %1}"
553 [(set_attr "type" "test,icmp")
554 (set_attr "length_immediate" "0,1")
555 (set_attr "mode" "HI")])
556
557 (define_insn "*cmphi_minus_1"
558 [(set (reg 17)
559 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
560 (match_operand:HI 1 "general_operand" "ri,mr"))
561 (const_int 0)))]
562 "ix86_match_ccmode (insn, CCGOCmode)"
563 "cmp{w}\t{%1, %0|%0, %1}"
564 [(set_attr "type" "icmp")
565 (set_attr "mode" "HI")])
566
567 (define_insn "*cmphi_1"
568 [(set (reg 17)
569 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:HI 1 "general_operand" "ri,mr")))]
571 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572 && ix86_match_ccmode (insn, CCmode)"
573 "cmp{w}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "HI")])
576
577 (define_insn "*cmpqi_ccno_1"
578 [(set (reg 17)
579 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
580 (match_operand:QI 1 "const0_operand" "n,n")))]
581 "ix86_match_ccmode (insn, CCNOmode)"
582 "@
583 test{b}\t{%0, %0|%0, %0}
584 cmp{b}\t{$0, %0|%0, 0}"
585 [(set_attr "type" "test,icmp")
586 (set_attr "length_immediate" "0,1")
587 (set_attr "mode" "QI")])
588
589 (define_insn "*cmpqi_1"
590 [(set (reg 17)
591 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
592 (match_operand:QI 1 "general_operand" "qi,mq")))]
593 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
594 && ix86_match_ccmode (insn, CCmode)"
595 "cmp{b}\t{%1, %0|%0, %1}"
596 [(set_attr "type" "icmp")
597 (set_attr "mode" "QI")])
598
599 (define_insn "*cmpqi_minus_1"
600 [(set (reg 17)
601 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
602 (match_operand:QI 1 "general_operand" "qi,mq"))
603 (const_int 0)))]
604 "ix86_match_ccmode (insn, CCGOCmode)"
605 "cmp{b}\t{%1, %0|%0, %1}"
606 [(set_attr "type" "icmp")
607 (set_attr "mode" "QI")])
608
609 (define_insn "*cmpqi_ext_1"
610 [(set (reg 17)
611 (compare
612 (match_operand:QI 0 "general_operand" "Qm")
613 (subreg:QI
614 (zero_extract:SI
615 (match_operand 1 "ext_register_operand" "Q")
616 (const_int 8)
617 (const_int 8)) 0)))]
618 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
619 "cmp{b}\t{%h1, %0|%0, %h1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "QI")])
622
623 (define_insn "*cmpqi_ext_1_rex64"
624 [(set (reg 17)
625 (compare
626 (match_operand:QI 0 "register_operand" "Q")
627 (subreg:QI
628 (zero_extract:SI
629 (match_operand 1 "ext_register_operand" "Q")
630 (const_int 8)
631 (const_int 8)) 0)))]
632 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633 "cmp{b}\t{%h1, %0|%0, %h1}"
634 [(set_attr "type" "icmp")
635 (set_attr "mode" "QI")])
636
637 (define_insn "*cmpqi_ext_2"
638 [(set (reg 17)
639 (compare
640 (subreg:QI
641 (zero_extract:SI
642 (match_operand 0 "ext_register_operand" "Q")
643 (const_int 8)
644 (const_int 8)) 0)
645 (match_operand:QI 1 "const0_operand" "n")))]
646 "ix86_match_ccmode (insn, CCNOmode)"
647 "test{b}\t%h0, %h0"
648 [(set_attr "type" "test")
649 (set_attr "length_immediate" "0")
650 (set_attr "mode" "QI")])
651
652 (define_expand "cmpqi_ext_3"
653 [(set (reg:CC 17)
654 (compare:CC
655 (subreg:QI
656 (zero_extract:SI
657 (match_operand 0 "ext_register_operand" "")
658 (const_int 8)
659 (const_int 8)) 0)
660 (match_operand:QI 1 "general_operand" "")))]
661 ""
662 "")
663
664 (define_insn "cmpqi_ext_3_insn"
665 [(set (reg 17)
666 (compare
667 (subreg:QI
668 (zero_extract:SI
669 (match_operand 0 "ext_register_operand" "Q")
670 (const_int 8)
671 (const_int 8)) 0)
672 (match_operand:QI 1 "general_operand" "Qmn")))]
673 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
674 "cmp{b}\t{%1, %h0|%h0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "QI")])
677
678 (define_insn "cmpqi_ext_3_insn_rex64"
679 [(set (reg 17)
680 (compare
681 (subreg:QI
682 (zero_extract:SI
683 (match_operand 0 "ext_register_operand" "Q")
684 (const_int 8)
685 (const_int 8)) 0)
686 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{b}\t{%1, %h0|%h0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_ext_4"
693 [(set (reg 17)
694 (compare
695 (subreg:QI
696 (zero_extract:SI
697 (match_operand 0 "ext_register_operand" "Q")
698 (const_int 8)
699 (const_int 8)) 0)
700 (subreg:QI
701 (zero_extract:SI
702 (match_operand 1 "ext_register_operand" "Q")
703 (const_int 8)
704 (const_int 8)) 0)))]
705 "ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%h1, %h0|%h0, %h1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
709
710 ;; These implement float point compares.
711 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
712 ;; which would allow mix and match FP modes on the compares. Which is what
713 ;; the old patterns did, but with many more of them.
714
715 (define_expand "cmpxf"
716 [(set (reg:CC 17)
717 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
718 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
719 "TARGET_80387"
720 {
721 ix86_compare_op0 = operands[0];
722 ix86_compare_op1 = operands[1];
723 DONE;
724 })
725
726 (define_expand "cmpdf"
727 [(set (reg:CC 17)
728 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
729 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
730 "TARGET_80387 || TARGET_SSE2"
731 {
732 ix86_compare_op0 = operands[0];
733 ix86_compare_op1 = operands[1];
734 DONE;
735 })
736
737 (define_expand "cmpsf"
738 [(set (reg:CC 17)
739 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
740 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
741 "TARGET_80387 || TARGET_SSE"
742 {
743 ix86_compare_op0 = operands[0];
744 ix86_compare_op1 = operands[1];
745 DONE;
746 })
747
748 ;; FP compares, step 1:
749 ;; Set the FP condition codes.
750 ;;
751 ;; CCFPmode compare with exceptions
752 ;; CCFPUmode compare with no exceptions
753
754 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
755 ;; and that fp moves clobber the condition codes, and that there is
756 ;; currently no way to describe this fact to reg-stack. So there are
757 ;; no splitters yet for this.
758
759 ;; %%% YIKES! This scheme does not retain a strong connection between
760 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
761 ;; work! Only allow tos/mem with tos in op 0.
762 ;;
763 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
764 ;; things aren't as bad as they sound...
765
766 (define_insn "*cmpfp_0"
767 [(set (match_operand:HI 0 "register_operand" "=a")
768 (unspec:HI
769 [(compare:CCFP (match_operand 1 "register_operand" "f")
770 (match_operand 2 "const0_operand" "X"))]
771 UNSPEC_FNSTSW))]
772 "TARGET_80387
773 && FLOAT_MODE_P (GET_MODE (operands[1]))
774 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
775 {
776 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
777 return "ftst\;fnstsw\t%0\;fstp\t%y0";
778 else
779 return "ftst\;fnstsw\t%0";
780 }
781 [(set_attr "type" "multi")
782 (set (attr "mode")
783 (cond [(match_operand:SF 1 "" "")
784 (const_string "SF")
785 (match_operand:DF 1 "" "")
786 (const_string "DF")
787 ]
788 (const_string "XF")))])
789
790 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
791 ;; used to manage the reg stack popping would not be preserved.
792
793 (define_insn "*cmpfp_2_sf"
794 [(set (reg:CCFP 18)
795 (compare:CCFP
796 (match_operand:SF 0 "register_operand" "f")
797 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
798 "TARGET_80387"
799 "* return output_fp_compare (insn, operands, 0, 0);"
800 [(set_attr "type" "fcmp")
801 (set_attr "mode" "SF")])
802
803 (define_insn "*cmpfp_2_sf_1"
804 [(set (match_operand:HI 0 "register_operand" "=a")
805 (unspec:HI
806 [(compare:CCFP
807 (match_operand:SF 1 "register_operand" "f")
808 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
809 UNSPEC_FNSTSW))]
810 "TARGET_80387"
811 "* return output_fp_compare (insn, operands, 2, 0);"
812 [(set_attr "type" "fcmp")
813 (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_2_df"
816 [(set (reg:CCFP 18)
817 (compare:CCFP
818 (match_operand:DF 0 "register_operand" "f")
819 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
820 "TARGET_80387"
821 "* return output_fp_compare (insn, operands, 0, 0);"
822 [(set_attr "type" "fcmp")
823 (set_attr "mode" "DF")])
824
825 (define_insn "*cmpfp_2_df_1"
826 [(set (match_operand:HI 0 "register_operand" "=a")
827 (unspec:HI
828 [(compare:CCFP
829 (match_operand:DF 1 "register_operand" "f")
830 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
831 UNSPEC_FNSTSW))]
832 "TARGET_80387"
833 "* return output_fp_compare (insn, operands, 2, 0);"
834 [(set_attr "type" "multi")
835 (set_attr "mode" "DF")])
836
837 (define_insn "*cmpfp_2_xf"
838 [(set (reg:CCFP 18)
839 (compare:CCFP
840 (match_operand:XF 0 "register_operand" "f")
841 (match_operand:XF 1 "register_operand" "f")))]
842 "TARGET_80387"
843 "* return output_fp_compare (insn, operands, 0, 0);"
844 [(set_attr "type" "fcmp")
845 (set_attr "mode" "XF")])
846
847 (define_insn "*cmpfp_2_xf_1"
848 [(set (match_operand:HI 0 "register_operand" "=a")
849 (unspec:HI
850 [(compare:CCFP
851 (match_operand:XF 1 "register_operand" "f")
852 (match_operand:XF 2 "register_operand" "f"))]
853 UNSPEC_FNSTSW))]
854 "TARGET_80387"
855 "* return output_fp_compare (insn, operands, 2, 0);"
856 [(set_attr "type" "multi")
857 (set_attr "mode" "XF")])
858
859 (define_insn "*cmpfp_2u"
860 [(set (reg:CCFPU 18)
861 (compare:CCFPU
862 (match_operand 0 "register_operand" "f")
863 (match_operand 1 "register_operand" "f")))]
864 "TARGET_80387
865 && FLOAT_MODE_P (GET_MODE (operands[0]))
866 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
867 "* return output_fp_compare (insn, operands, 0, 1);"
868 [(set_attr "type" "fcmp")
869 (set (attr "mode")
870 (cond [(match_operand:SF 1 "" "")
871 (const_string "SF")
872 (match_operand:DF 1 "" "")
873 (const_string "DF")
874 ]
875 (const_string "XF")))])
876
877 (define_insn "*cmpfp_2u_1"
878 [(set (match_operand:HI 0 "register_operand" "=a")
879 (unspec:HI
880 [(compare:CCFPU
881 (match_operand 1 "register_operand" "f")
882 (match_operand 2 "register_operand" "f"))]
883 UNSPEC_FNSTSW))]
884 "TARGET_80387
885 && FLOAT_MODE_P (GET_MODE (operands[1]))
886 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887 "* return output_fp_compare (insn, operands, 2, 1);"
888 [(set_attr "type" "multi")
889 (set (attr "mode")
890 (cond [(match_operand:SF 1 "" "")
891 (const_string "SF")
892 (match_operand:DF 1 "" "")
893 (const_string "DF")
894 ]
895 (const_string "XF")))])
896
897 ;; Patterns to match the SImode-in-memory ficom instructions.
898 ;;
899 ;; %%% Play games with accepting gp registers, as otherwise we have to
900 ;; force them to memory during rtl generation, which is no good. We
901 ;; can get rid of this once we teach reload to do memory input reloads
902 ;; via pushes.
903
904 (define_insn "*ficom_1"
905 [(set (reg:CCFP 18)
906 (compare:CCFP
907 (match_operand 0 "register_operand" "f,f")
908 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
909 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
910 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
911 "#")
912
913 ;; Split the not-really-implemented gp register case into a
914 ;; push-op-pop sequence.
915 ;;
916 ;; %%% This is most efficient, but am I gonna get in trouble
917 ;; for separating cc0_setter and cc0_user?
918
919 (define_split
920 [(set (reg:CCFP 18)
921 (compare:CCFP
922 (match_operand:SF 0 "register_operand" "")
923 (float (match_operand:SI 1 "register_operand" ""))))]
924 "0 && TARGET_80387 && reload_completed"
925 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
926 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
927 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
928 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
929 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
930 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
931
932 ;; FP compares, step 2
933 ;; Move the fpsw to ax.
934
935 (define_insn "*x86_fnstsw_1"
936 [(set (match_operand:HI 0 "register_operand" "=a")
937 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
938 "TARGET_80387"
939 "fnstsw\t%0"
940 [(set_attr "length" "2")
941 (set_attr "mode" "SI")
942 (set_attr "unit" "i387")])
943
944 ;; FP compares, step 3
945 ;; Get ax into flags, general case.
946
947 (define_insn "x86_sahf_1"
948 [(set (reg:CC 17)
949 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
950 "!TARGET_64BIT"
951 "sahf"
952 [(set_attr "length" "1")
953 (set_attr "athlon_decode" "vector")
954 (set_attr "mode" "SI")])
955
956 ;; Pentium Pro can do steps 1 through 3 in one go.
957
958 (define_insn "*cmpfp_i"
959 [(set (reg:CCFP 17)
960 (compare:CCFP (match_operand 0 "register_operand" "f")
961 (match_operand 1 "register_operand" "f")))]
962 "TARGET_80387 && TARGET_CMOVE
963 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
964 && FLOAT_MODE_P (GET_MODE (operands[0]))
965 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
966 "* return output_fp_compare (insn, operands, 1, 0);"
967 [(set_attr "type" "fcmp")
968 (set (attr "mode")
969 (cond [(match_operand:SF 1 "" "")
970 (const_string "SF")
971 (match_operand:DF 1 "" "")
972 (const_string "DF")
973 ]
974 (const_string "XF")))
975 (set_attr "athlon_decode" "vector")])
976
977 (define_insn "*cmpfp_i_sse"
978 [(set (reg:CCFP 17)
979 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
980 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
981 "TARGET_80387
982 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
984 "* return output_fp_compare (insn, operands, 1, 0);"
985 [(set_attr "type" "fcmp,ssecomi")
986 (set (attr "mode")
987 (if_then_else (match_operand:SF 1 "" "")
988 (const_string "SF")
989 (const_string "DF")))
990 (set_attr "athlon_decode" "vector")])
991
992 (define_insn "*cmpfp_i_sse_only"
993 [(set (reg:CCFP 17)
994 (compare:CCFP (match_operand 0 "register_operand" "x")
995 (match_operand 1 "nonimmediate_operand" "xm")))]
996 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
997 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
998 "* return output_fp_compare (insn, operands, 1, 0);"
999 [(set_attr "type" "ssecomi")
1000 (set (attr "mode")
1001 (if_then_else (match_operand:SF 1 "" "")
1002 (const_string "SF")
1003 (const_string "DF")))
1004 (set_attr "athlon_decode" "vector")])
1005
1006 (define_insn "*cmpfp_iu"
1007 [(set (reg:CCFPU 17)
1008 (compare:CCFPU (match_operand 0 "register_operand" "f")
1009 (match_operand 1 "register_operand" "f")))]
1010 "TARGET_80387 && TARGET_CMOVE
1011 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1012 && FLOAT_MODE_P (GET_MODE (operands[0]))
1013 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1014 "* return output_fp_compare (insn, operands, 1, 1);"
1015 [(set_attr "type" "fcmp")
1016 (set (attr "mode")
1017 (cond [(match_operand:SF 1 "" "")
1018 (const_string "SF")
1019 (match_operand:DF 1 "" "")
1020 (const_string "DF")
1021 ]
1022 (const_string "XF")))
1023 (set_attr "athlon_decode" "vector")])
1024
1025 (define_insn "*cmpfp_iu_sse"
1026 [(set (reg:CCFPU 17)
1027 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1028 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1029 "TARGET_80387
1030 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1031 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1032 "* return output_fp_compare (insn, operands, 1, 1);"
1033 [(set_attr "type" "fcmp,ssecomi")
1034 (set (attr "mode")
1035 (if_then_else (match_operand:SF 1 "" "")
1036 (const_string "SF")
1037 (const_string "DF")))
1038 (set_attr "athlon_decode" "vector")])
1039
1040 (define_insn "*cmpfp_iu_sse_only"
1041 [(set (reg:CCFPU 17)
1042 (compare:CCFPU (match_operand 0 "register_operand" "x")
1043 (match_operand 1 "nonimmediate_operand" "xm")))]
1044 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1045 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1046 "* return output_fp_compare (insn, operands, 1, 1);"
1047 [(set_attr "type" "ssecomi")
1048 (set (attr "mode")
1049 (if_then_else (match_operand:SF 1 "" "")
1050 (const_string "SF")
1051 (const_string "DF")))
1052 (set_attr "athlon_decode" "vector")])
1053 \f
1054 ;; Move instructions.
1055
1056 ;; General case of fullword move.
1057
1058 (define_expand "movsi"
1059 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1060 (match_operand:SI 1 "general_operand" ""))]
1061 ""
1062 "ix86_expand_move (SImode, operands); DONE;")
1063
1064 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1065 ;; general_operand.
1066 ;;
1067 ;; %%% We don't use a post-inc memory reference because x86 is not a
1068 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1069 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1070 ;; targets without our curiosities, and it is just as easy to represent
1071 ;; this differently.
1072
1073 (define_insn "*pushsi2"
1074 [(set (match_operand:SI 0 "push_operand" "=<")
1075 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1076 "!TARGET_64BIT"
1077 "push{l}\t%1"
1078 [(set_attr "type" "push")
1079 (set_attr "mode" "SI")])
1080
1081 ;; For 64BIT abi we always round up to 8 bytes.
1082 (define_insn "*pushsi2_rex64"
1083 [(set (match_operand:SI 0 "push_operand" "=X")
1084 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1085 "TARGET_64BIT"
1086 "push{q}\t%q1"
1087 [(set_attr "type" "push")
1088 (set_attr "mode" "SI")])
1089
1090 (define_insn "*pushsi2_prologue"
1091 [(set (match_operand:SI 0 "push_operand" "=<")
1092 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1093 (clobber (mem:BLK (scratch)))]
1094 "!TARGET_64BIT"
1095 "push{l}\t%1"
1096 [(set_attr "type" "push")
1097 (set_attr "mode" "SI")])
1098
1099 (define_insn "*popsi1_epilogue"
1100 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1101 (mem:SI (reg:SI 7)))
1102 (set (reg:SI 7)
1103 (plus:SI (reg:SI 7) (const_int 4)))
1104 (clobber (mem:BLK (scratch)))]
1105 "!TARGET_64BIT"
1106 "pop{l}\t%0"
1107 [(set_attr "type" "pop")
1108 (set_attr "mode" "SI")])
1109
1110 (define_insn "popsi1"
1111 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1112 (mem:SI (reg:SI 7)))
1113 (set (reg:SI 7)
1114 (plus:SI (reg:SI 7) (const_int 4)))]
1115 "!TARGET_64BIT"
1116 "pop{l}\t%0"
1117 [(set_attr "type" "pop")
1118 (set_attr "mode" "SI")])
1119
1120 (define_insn "*movsi_xor"
1121 [(set (match_operand:SI 0 "register_operand" "=r")
1122 (match_operand:SI 1 "const0_operand" "i"))
1123 (clobber (reg:CC 17))]
1124 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1125 "xor{l}\t{%0, %0|%0, %0}"
1126 [(set_attr "type" "alu1")
1127 (set_attr "mode" "SI")
1128 (set_attr "length_immediate" "0")])
1129
1130 (define_insn "*movsi_or"
1131 [(set (match_operand:SI 0 "register_operand" "=r")
1132 (match_operand:SI 1 "immediate_operand" "i"))
1133 (clobber (reg:CC 17))]
1134 "reload_completed
1135 && operands[1] == constm1_rtx
1136 && (TARGET_PENTIUM || optimize_size)"
1137 {
1138 operands[1] = constm1_rtx;
1139 return "or{l}\t{%1, %0|%0, %1}";
1140 }
1141 [(set_attr "type" "alu1")
1142 (set_attr "mode" "SI")
1143 (set_attr "length_immediate" "1")])
1144
1145 (define_insn "*movsi_1"
1146 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1147 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1148 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1149 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1150 {
1151 switch (get_attr_type (insn))
1152 {
1153 case TYPE_SSEMOV:
1154 if (get_attr_mode (insn) == MODE_TI)
1155 return "movdqa\t{%1, %0|%0, %1}";
1156 return "movd\t{%1, %0|%0, %1}";
1157
1158 case TYPE_MMXMOV:
1159 if (get_attr_mode (insn) == MODE_DI)
1160 return "movq\t{%1, %0|%0, %1}";
1161 return "movd\t{%1, %0|%0, %1}";
1162
1163 case TYPE_LEA:
1164 return "lea{l}\t{%1, %0|%0, %1}";
1165
1166 default:
1167 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1168 abort();
1169 return "mov{l}\t{%1, %0|%0, %1}";
1170 }
1171 }
1172 [(set (attr "type")
1173 (cond [(eq_attr "alternative" "2,3,4")
1174 (const_string "mmxmov")
1175 (eq_attr "alternative" "5,6,7")
1176 (const_string "ssemov")
1177 (and (ne (symbol_ref "flag_pic") (const_int 0))
1178 (match_operand:SI 1 "symbolic_operand" ""))
1179 (const_string "lea")
1180 ]
1181 (const_string "imov")))
1182 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1183
1184 (define_insn "*movsi_1_nointernunit"
1185 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1186 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1187 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1188 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1189 {
1190 switch (get_attr_type (insn))
1191 {
1192 case TYPE_SSEMOV:
1193 if (get_attr_mode (insn) == MODE_TI)
1194 return "movdqa\t{%1, %0|%0, %1}";
1195 return "movd\t{%1, %0|%0, %1}";
1196
1197 case TYPE_MMXMOV:
1198 if (get_attr_mode (insn) == MODE_DI)
1199 return "movq\t{%1, %0|%0, %1}";
1200 return "movd\t{%1, %0|%0, %1}";
1201
1202 case TYPE_LEA:
1203 return "lea{l}\t{%1, %0|%0, %1}";
1204
1205 default:
1206 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1207 abort();
1208 return "mov{l}\t{%1, %0|%0, %1}";
1209 }
1210 }
1211 [(set (attr "type")
1212 (cond [(eq_attr "alternative" "2,3,4")
1213 (const_string "mmxmov")
1214 (eq_attr "alternative" "5,6,7")
1215 (const_string "ssemov")
1216 (and (ne (symbol_ref "flag_pic") (const_int 0))
1217 (match_operand:SI 1 "symbolic_operand" ""))
1218 (const_string "lea")
1219 ]
1220 (const_string "imov")))
1221 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1222
1223 ;; Stores and loads of ax to arbitrary constant address.
1224 ;; We fake an second form of instruction to force reload to load address
1225 ;; into register when rax is not available
1226 (define_insn "*movabssi_1_rex64"
1227 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1228 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1229 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1230 "@
1231 movabs{l}\t{%1, %P0|%P0, %1}
1232 mov{l}\t{%1, %a0|%a0, %1}"
1233 [(set_attr "type" "imov")
1234 (set_attr "modrm" "0,*")
1235 (set_attr "length_address" "8,0")
1236 (set_attr "length_immediate" "0,*")
1237 (set_attr "memory" "store")
1238 (set_attr "mode" "SI")])
1239
1240 (define_insn "*movabssi_2_rex64"
1241 [(set (match_operand:SI 0 "register_operand" "=a,r")
1242 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1243 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1244 "@
1245 movabs{l}\t{%P1, %0|%0, %P1}
1246 mov{l}\t{%a1, %0|%0, %a1}"
1247 [(set_attr "type" "imov")
1248 (set_attr "modrm" "0,*")
1249 (set_attr "length_address" "8,0")
1250 (set_attr "length_immediate" "0")
1251 (set_attr "memory" "load")
1252 (set_attr "mode" "SI")])
1253
1254 (define_insn "*swapsi"
1255 [(set (match_operand:SI 0 "register_operand" "+r")
1256 (match_operand:SI 1 "register_operand" "+r"))
1257 (set (match_dup 1)
1258 (match_dup 0))]
1259 ""
1260 "xchg{l}\t%1, %0"
1261 [(set_attr "type" "imov")
1262 (set_attr "pent_pair" "np")
1263 (set_attr "athlon_decode" "vector")
1264 (set_attr "mode" "SI")
1265 (set_attr "modrm" "0")])
1266
1267 (define_expand "movhi"
1268 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1269 (match_operand:HI 1 "general_operand" ""))]
1270 ""
1271 "ix86_expand_move (HImode, operands); DONE;")
1272
1273 (define_insn "*pushhi2"
1274 [(set (match_operand:HI 0 "push_operand" "=<,<")
1275 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1276 "!TARGET_64BIT"
1277 "@
1278 push{w}\t{|WORD PTR }%1
1279 push{w}\t%1"
1280 [(set_attr "type" "push")
1281 (set_attr "mode" "HI")])
1282
1283 ;; For 64BIT abi we always round up to 8 bytes.
1284 (define_insn "*pushhi2_rex64"
1285 [(set (match_operand:HI 0 "push_operand" "=X")
1286 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1287 "TARGET_64BIT"
1288 "push{q}\t%q1"
1289 [(set_attr "type" "push")
1290 (set_attr "mode" "QI")])
1291
1292 (define_insn "*movhi_1"
1293 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1294 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1295 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1296 {
1297 switch (get_attr_type (insn))
1298 {
1299 case TYPE_IMOVX:
1300 /* movzwl is faster than movw on p2 due to partial word stalls,
1301 though not as fast as an aligned movl. */
1302 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1303 default:
1304 if (get_attr_mode (insn) == MODE_SI)
1305 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1306 else
1307 return "mov{w}\t{%1, %0|%0, %1}";
1308 }
1309 }
1310 [(set (attr "type")
1311 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1312 (const_string "imov")
1313 (and (eq_attr "alternative" "0")
1314 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1315 (const_int 0))
1316 (eq (symbol_ref "TARGET_HIMODE_MATH")
1317 (const_int 0))))
1318 (const_string "imov")
1319 (and (eq_attr "alternative" "1,2")
1320 (match_operand:HI 1 "aligned_operand" ""))
1321 (const_string "imov")
1322 (and (ne (symbol_ref "TARGET_MOVX")
1323 (const_int 0))
1324 (eq_attr "alternative" "0,2"))
1325 (const_string "imovx")
1326 ]
1327 (const_string "imov")))
1328 (set (attr "mode")
1329 (cond [(eq_attr "type" "imovx")
1330 (const_string "SI")
1331 (and (eq_attr "alternative" "1,2")
1332 (match_operand:HI 1 "aligned_operand" ""))
1333 (const_string "SI")
1334 (and (eq_attr "alternative" "0")
1335 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1336 (const_int 0))
1337 (eq (symbol_ref "TARGET_HIMODE_MATH")
1338 (const_int 0))))
1339 (const_string "SI")
1340 ]
1341 (const_string "HI")))])
1342
1343 ;; Stores and loads of ax to arbitrary constant address.
1344 ;; We fake an second form of instruction to force reload to load address
1345 ;; into register when rax is not available
1346 (define_insn "*movabshi_1_rex64"
1347 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1348 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1349 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1350 "@
1351 movabs{w}\t{%1, %P0|%P0, %1}
1352 mov{w}\t{%1, %a0|%a0, %1}"
1353 [(set_attr "type" "imov")
1354 (set_attr "modrm" "0,*")
1355 (set_attr "length_address" "8,0")
1356 (set_attr "length_immediate" "0,*")
1357 (set_attr "memory" "store")
1358 (set_attr "mode" "HI")])
1359
1360 (define_insn "*movabshi_2_rex64"
1361 [(set (match_operand:HI 0 "register_operand" "=a,r")
1362 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1363 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1364 "@
1365 movabs{w}\t{%P1, %0|%0, %P1}
1366 mov{w}\t{%a1, %0|%0, %a1}"
1367 [(set_attr "type" "imov")
1368 (set_attr "modrm" "0,*")
1369 (set_attr "length_address" "8,0")
1370 (set_attr "length_immediate" "0")
1371 (set_attr "memory" "load")
1372 (set_attr "mode" "HI")])
1373
1374 (define_insn "*swaphi_1"
1375 [(set (match_operand:HI 0 "register_operand" "+r")
1376 (match_operand:HI 1 "register_operand" "+r"))
1377 (set (match_dup 1)
1378 (match_dup 0))]
1379 "TARGET_PARTIAL_REG_STALL"
1380 "xchg{w}\t%1, %0"
1381 [(set_attr "type" "imov")
1382 (set_attr "pent_pair" "np")
1383 (set_attr "mode" "HI")
1384 (set_attr "modrm" "0")])
1385
1386 (define_insn "*swaphi_2"
1387 [(set (match_operand:HI 0 "register_operand" "+r")
1388 (match_operand:HI 1 "register_operand" "+r"))
1389 (set (match_dup 1)
1390 (match_dup 0))]
1391 "! TARGET_PARTIAL_REG_STALL"
1392 "xchg{l}\t%k1, %k0"
1393 [(set_attr "type" "imov")
1394 (set_attr "pent_pair" "np")
1395 (set_attr "mode" "SI")
1396 (set_attr "modrm" "0")])
1397
1398 (define_expand "movstricthi"
1399 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1400 (match_operand:HI 1 "general_operand" ""))]
1401 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1402 {
1403 /* Don't generate memory->memory moves, go through a register */
1404 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1405 operands[1] = force_reg (HImode, operands[1]);
1406 })
1407
1408 (define_insn "*movstricthi_1"
1409 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1410 (match_operand:HI 1 "general_operand" "rn,m"))]
1411 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1412 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1413 "mov{w}\t{%1, %0|%0, %1}"
1414 [(set_attr "type" "imov")
1415 (set_attr "mode" "HI")])
1416
1417 (define_insn "*movstricthi_xor"
1418 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1419 (match_operand:HI 1 "const0_operand" "i"))
1420 (clobber (reg:CC 17))]
1421 "reload_completed
1422 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1423 "xor{w}\t{%0, %0|%0, %0}"
1424 [(set_attr "type" "alu1")
1425 (set_attr "mode" "HI")
1426 (set_attr "length_immediate" "0")])
1427
1428 (define_expand "movqi"
1429 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1430 (match_operand:QI 1 "general_operand" ""))]
1431 ""
1432 "ix86_expand_move (QImode, operands); DONE;")
1433
1434 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1435 ;; "push a byte". But actually we use pushw, which has the effect
1436 ;; of rounding the amount pushed up to a halfword.
1437
1438 (define_insn "*pushqi2"
1439 [(set (match_operand:QI 0 "push_operand" "=X,X")
1440 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1441 "!TARGET_64BIT"
1442 "@
1443 push{w}\t{|word ptr }%1
1444 push{w}\t%w1"
1445 [(set_attr "type" "push")
1446 (set_attr "mode" "HI")])
1447
1448 ;; For 64BIT abi we always round up to 8 bytes.
1449 (define_insn "*pushqi2_rex64"
1450 [(set (match_operand:QI 0 "push_operand" "=X")
1451 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1452 "TARGET_64BIT"
1453 "push{q}\t%q1"
1454 [(set_attr "type" "push")
1455 (set_attr "mode" "QI")])
1456
1457 ;; Situation is quite tricky about when to choose full sized (SImode) move
1458 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1459 ;; partial register dependency machines (such as AMD Athlon), where QImode
1460 ;; moves issue extra dependency and for partial register stalls machines
1461 ;; that don't use QImode patterns (and QImode move cause stall on the next
1462 ;; instruction).
1463 ;;
1464 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1465 ;; register stall machines with, where we use QImode instructions, since
1466 ;; partial register stall can be caused there. Then we use movzx.
1467 (define_insn "*movqi_1"
1468 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1469 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1470 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1471 {
1472 switch (get_attr_type (insn))
1473 {
1474 case TYPE_IMOVX:
1475 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1476 abort ();
1477 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1478 default:
1479 if (get_attr_mode (insn) == MODE_SI)
1480 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1481 else
1482 return "mov{b}\t{%1, %0|%0, %1}";
1483 }
1484 }
1485 [(set (attr "type")
1486 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1487 (const_string "imov")
1488 (and (eq_attr "alternative" "3")
1489 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1490 (const_int 0))
1491 (eq (symbol_ref "TARGET_QIMODE_MATH")
1492 (const_int 0))))
1493 (const_string "imov")
1494 (eq_attr "alternative" "3,5")
1495 (const_string "imovx")
1496 (and (ne (symbol_ref "TARGET_MOVX")
1497 (const_int 0))
1498 (eq_attr "alternative" "2"))
1499 (const_string "imovx")
1500 ]
1501 (const_string "imov")))
1502 (set (attr "mode")
1503 (cond [(eq_attr "alternative" "3,4,5")
1504 (const_string "SI")
1505 (eq_attr "alternative" "6")
1506 (const_string "QI")
1507 (eq_attr "type" "imovx")
1508 (const_string "SI")
1509 (and (eq_attr "type" "imov")
1510 (and (eq_attr "alternative" "0,1,2")
1511 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1512 (const_int 0))))
1513 (const_string "SI")
1514 ;; Avoid partial register stalls when not using QImode arithmetic
1515 (and (eq_attr "type" "imov")
1516 (and (eq_attr "alternative" "0,1,2")
1517 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518 (const_int 0))
1519 (eq (symbol_ref "TARGET_QIMODE_MATH")
1520 (const_int 0)))))
1521 (const_string "SI")
1522 ]
1523 (const_string "QI")))])
1524
1525 (define_expand "reload_outqi"
1526 [(parallel [(match_operand:QI 0 "" "=m")
1527 (match_operand:QI 1 "register_operand" "r")
1528 (match_operand:QI 2 "register_operand" "=&q")])]
1529 ""
1530 {
1531 rtx op0, op1, op2;
1532 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1533
1534 if (reg_overlap_mentioned_p (op2, op0))
1535 abort ();
1536 if (! q_regs_operand (op1, QImode))
1537 {
1538 emit_insn (gen_movqi (op2, op1));
1539 op1 = op2;
1540 }
1541 emit_insn (gen_movqi (op0, op1));
1542 DONE;
1543 })
1544
1545 (define_insn "*swapqi"
1546 [(set (match_operand:QI 0 "register_operand" "+r")
1547 (match_operand:QI 1 "register_operand" "+r"))
1548 (set (match_dup 1)
1549 (match_dup 0))]
1550 ""
1551 "xchg{b}\t%1, %0"
1552 [(set_attr "type" "imov")
1553 (set_attr "pent_pair" "np")
1554 (set_attr "mode" "QI")
1555 (set_attr "modrm" "0")])
1556
1557 (define_expand "movstrictqi"
1558 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1559 (match_operand:QI 1 "general_operand" ""))]
1560 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1561 {
1562 /* Don't generate memory->memory moves, go through a register. */
1563 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1564 operands[1] = force_reg (QImode, operands[1]);
1565 })
1566
1567 (define_insn "*movstrictqi_1"
1568 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1569 (match_operand:QI 1 "general_operand" "*qn,m"))]
1570 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1571 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1572 "mov{b}\t{%1, %0|%0, %1}"
1573 [(set_attr "type" "imov")
1574 (set_attr "mode" "QI")])
1575
1576 (define_insn "*movstrictqi_xor"
1577 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1578 (match_operand:QI 1 "const0_operand" "i"))
1579 (clobber (reg:CC 17))]
1580 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1581 "xor{b}\t{%0, %0|%0, %0}"
1582 [(set_attr "type" "alu1")
1583 (set_attr "mode" "QI")
1584 (set_attr "length_immediate" "0")])
1585
1586 (define_insn "*movsi_extv_1"
1587 [(set (match_operand:SI 0 "register_operand" "=R")
1588 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1589 (const_int 8)
1590 (const_int 8)))]
1591 ""
1592 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1593 [(set_attr "type" "imovx")
1594 (set_attr "mode" "SI")])
1595
1596 (define_insn "*movhi_extv_1"
1597 [(set (match_operand:HI 0 "register_operand" "=R")
1598 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1599 (const_int 8)
1600 (const_int 8)))]
1601 ""
1602 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1603 [(set_attr "type" "imovx")
1604 (set_attr "mode" "SI")])
1605
1606 (define_insn "*movqi_extv_1"
1607 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1608 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1609 (const_int 8)
1610 (const_int 8)))]
1611 "!TARGET_64BIT"
1612 {
1613 switch (get_attr_type (insn))
1614 {
1615 case TYPE_IMOVX:
1616 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1617 default:
1618 return "mov{b}\t{%h1, %0|%0, %h1}";
1619 }
1620 }
1621 [(set (attr "type")
1622 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1623 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1624 (ne (symbol_ref "TARGET_MOVX")
1625 (const_int 0))))
1626 (const_string "imovx")
1627 (const_string "imov")))
1628 (set (attr "mode")
1629 (if_then_else (eq_attr "type" "imovx")
1630 (const_string "SI")
1631 (const_string "QI")))])
1632
1633 (define_insn "*movqi_extv_1_rex64"
1634 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1635 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1636 (const_int 8)
1637 (const_int 8)))]
1638 "TARGET_64BIT"
1639 {
1640 switch (get_attr_type (insn))
1641 {
1642 case TYPE_IMOVX:
1643 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1644 default:
1645 return "mov{b}\t{%h1, %0|%0, %h1}";
1646 }
1647 }
1648 [(set (attr "type")
1649 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1650 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1651 (ne (symbol_ref "TARGET_MOVX")
1652 (const_int 0))))
1653 (const_string "imovx")
1654 (const_string "imov")))
1655 (set (attr "mode")
1656 (if_then_else (eq_attr "type" "imovx")
1657 (const_string "SI")
1658 (const_string "QI")))])
1659
1660 ;; Stores and loads of ax to arbitrary constant address.
1661 ;; We fake an second form of instruction to force reload to load address
1662 ;; into register when rax is not available
1663 (define_insn "*movabsqi_1_rex64"
1664 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1665 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1666 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1667 "@
1668 movabs{b}\t{%1, %P0|%P0, %1}
1669 mov{b}\t{%1, %a0|%a0, %1}"
1670 [(set_attr "type" "imov")
1671 (set_attr "modrm" "0,*")
1672 (set_attr "length_address" "8,0")
1673 (set_attr "length_immediate" "0,*")
1674 (set_attr "memory" "store")
1675 (set_attr "mode" "QI")])
1676
1677 (define_insn "*movabsqi_2_rex64"
1678 [(set (match_operand:QI 0 "register_operand" "=a,r")
1679 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1680 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1681 "@
1682 movabs{b}\t{%P1, %0|%0, %P1}
1683 mov{b}\t{%a1, %0|%0, %a1}"
1684 [(set_attr "type" "imov")
1685 (set_attr "modrm" "0,*")
1686 (set_attr "length_address" "8,0")
1687 (set_attr "length_immediate" "0")
1688 (set_attr "memory" "load")
1689 (set_attr "mode" "QI")])
1690
1691 (define_insn "*movsi_extzv_1"
1692 [(set (match_operand:SI 0 "register_operand" "=R")
1693 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1694 (const_int 8)
1695 (const_int 8)))]
1696 ""
1697 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1698 [(set_attr "type" "imovx")
1699 (set_attr "mode" "SI")])
1700
1701 (define_insn "*movqi_extzv_2"
1702 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1703 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1704 (const_int 8)
1705 (const_int 8)) 0))]
1706 "!TARGET_64BIT"
1707 {
1708 switch (get_attr_type (insn))
1709 {
1710 case TYPE_IMOVX:
1711 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1712 default:
1713 return "mov{b}\t{%h1, %0|%0, %h1}";
1714 }
1715 }
1716 [(set (attr "type")
1717 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1718 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1719 (ne (symbol_ref "TARGET_MOVX")
1720 (const_int 0))))
1721 (const_string "imovx")
1722 (const_string "imov")))
1723 (set (attr "mode")
1724 (if_then_else (eq_attr "type" "imovx")
1725 (const_string "SI")
1726 (const_string "QI")))])
1727
1728 (define_insn "*movqi_extzv_2_rex64"
1729 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1730 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1731 (const_int 8)
1732 (const_int 8)) 0))]
1733 "TARGET_64BIT"
1734 {
1735 switch (get_attr_type (insn))
1736 {
1737 case TYPE_IMOVX:
1738 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1739 default:
1740 return "mov{b}\t{%h1, %0|%0, %h1}";
1741 }
1742 }
1743 [(set (attr "type")
1744 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1745 (ne (symbol_ref "TARGET_MOVX")
1746 (const_int 0)))
1747 (const_string "imovx")
1748 (const_string "imov")))
1749 (set (attr "mode")
1750 (if_then_else (eq_attr "type" "imovx")
1751 (const_string "SI")
1752 (const_string "QI")))])
1753
1754 (define_insn "movsi_insv_1"
1755 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1756 (const_int 8)
1757 (const_int 8))
1758 (match_operand:SI 1 "general_operand" "Qmn"))]
1759 "!TARGET_64BIT"
1760 "mov{b}\t{%b1, %h0|%h0, %b1}"
1761 [(set_attr "type" "imov")
1762 (set_attr "mode" "QI")])
1763
1764 (define_insn "*movsi_insv_1_rex64"
1765 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1766 (const_int 8)
1767 (const_int 8))
1768 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1769 "TARGET_64BIT"
1770 "mov{b}\t{%b1, %h0|%h0, %b1}"
1771 [(set_attr "type" "imov")
1772 (set_attr "mode" "QI")])
1773
1774 (define_insn "*movqi_insv_2"
1775 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1776 (const_int 8)
1777 (const_int 8))
1778 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1779 (const_int 8)))]
1780 ""
1781 "mov{b}\t{%h1, %h0|%h0, %h1}"
1782 [(set_attr "type" "imov")
1783 (set_attr "mode" "QI")])
1784
1785 (define_expand "movdi"
1786 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1787 (match_operand:DI 1 "general_operand" ""))]
1788 ""
1789 "ix86_expand_move (DImode, operands); DONE;")
1790
1791 (define_insn "*pushdi"
1792 [(set (match_operand:DI 0 "push_operand" "=<")
1793 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1794 "!TARGET_64BIT"
1795 "#")
1796
1797 (define_insn "pushdi2_rex64"
1798 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1799 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1800 "TARGET_64BIT"
1801 "@
1802 push{q}\t%1
1803 #"
1804 [(set_attr "type" "push,multi")
1805 (set_attr "mode" "DI")])
1806
1807 ;; Convert impossible pushes of immediate to existing instructions.
1808 ;; First try to get scratch register and go through it. In case this
1809 ;; fails, push sign extended lower part first and then overwrite
1810 ;; upper part by 32bit move.
1811 (define_peephole2
1812 [(match_scratch:DI 2 "r")
1813 (set (match_operand:DI 0 "push_operand" "")
1814 (match_operand:DI 1 "immediate_operand" ""))]
1815 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1816 && !x86_64_immediate_operand (operands[1], DImode)"
1817 [(set (match_dup 2) (match_dup 1))
1818 (set (match_dup 0) (match_dup 2))]
1819 "")
1820
1821 ;; We need to define this as both peepholer and splitter for case
1822 ;; peephole2 pass is not run.
1823 (define_peephole2
1824 [(set (match_operand:DI 0 "push_operand" "")
1825 (match_operand:DI 1 "immediate_operand" ""))]
1826 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1827 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1828 [(set (match_dup 0) (match_dup 1))
1829 (set (match_dup 2) (match_dup 3))]
1830 "split_di (operands + 1, 1, operands + 2, operands + 3);
1831 operands[1] = gen_lowpart (DImode, operands[2]);
1832 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1833 GEN_INT (4)));
1834 ")
1835
1836 (define_split
1837 [(set (match_operand:DI 0 "push_operand" "")
1838 (match_operand:DI 1 "immediate_operand" ""))]
1839 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1840 && !symbolic_operand (operands[1], DImode)
1841 && !x86_64_immediate_operand (operands[1], DImode)"
1842 [(set (match_dup 0) (match_dup 1))
1843 (set (match_dup 2) (match_dup 3))]
1844 "split_di (operands + 1, 1, operands + 2, operands + 3);
1845 operands[1] = gen_lowpart (DImode, operands[2]);
1846 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1847 GEN_INT (4)));
1848 ")
1849
1850 (define_insn "*pushdi2_prologue_rex64"
1851 [(set (match_operand:DI 0 "push_operand" "=<")
1852 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1853 (clobber (mem:BLK (scratch)))]
1854 "TARGET_64BIT"
1855 "push{q}\t%1"
1856 [(set_attr "type" "push")
1857 (set_attr "mode" "DI")])
1858
1859 (define_insn "*popdi1_epilogue_rex64"
1860 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1861 (mem:DI (reg:DI 7)))
1862 (set (reg:DI 7)
1863 (plus:DI (reg:DI 7) (const_int 8)))
1864 (clobber (mem:BLK (scratch)))]
1865 "TARGET_64BIT"
1866 "pop{q}\t%0"
1867 [(set_attr "type" "pop")
1868 (set_attr "mode" "DI")])
1869
1870 (define_insn "popdi1"
1871 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1872 (mem:DI (reg:DI 7)))
1873 (set (reg:DI 7)
1874 (plus:DI (reg:DI 7) (const_int 8)))]
1875 "TARGET_64BIT"
1876 "pop{q}\t%0"
1877 [(set_attr "type" "pop")
1878 (set_attr "mode" "DI")])
1879
1880 (define_insn "*movdi_xor_rex64"
1881 [(set (match_operand:DI 0 "register_operand" "=r")
1882 (match_operand:DI 1 "const0_operand" "i"))
1883 (clobber (reg:CC 17))]
1884 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1885 && reload_completed"
1886 "xor{l}\t{%k0, %k0|%k0, %k0}"
1887 [(set_attr "type" "alu1")
1888 (set_attr "mode" "SI")
1889 (set_attr "length_immediate" "0")])
1890
1891 (define_insn "*movdi_or_rex64"
1892 [(set (match_operand:DI 0 "register_operand" "=r")
1893 (match_operand:DI 1 "const_int_operand" "i"))
1894 (clobber (reg:CC 17))]
1895 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1896 && reload_completed
1897 && operands[1] == constm1_rtx"
1898 {
1899 operands[1] = constm1_rtx;
1900 return "or{q}\t{%1, %0|%0, %1}";
1901 }
1902 [(set_attr "type" "alu1")
1903 (set_attr "mode" "DI")
1904 (set_attr "length_immediate" "1")])
1905
1906 (define_insn "*movdi_2"
1907 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1908 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1909 "!TARGET_64BIT
1910 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1911 "@
1912 #
1913 #
1914 movq\t{%1, %0|%0, %1}
1915 movq\t{%1, %0|%0, %1}
1916 movq\t{%1, %0|%0, %1}
1917 movdqa\t{%1, %0|%0, %1}
1918 movq\t{%1, %0|%0, %1}"
1919 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1920 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1921
1922 (define_split
1923 [(set (match_operand:DI 0 "push_operand" "")
1924 (match_operand:DI 1 "general_operand" ""))]
1925 "!TARGET_64BIT && reload_completed
1926 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1927 [(const_int 0)]
1928 "ix86_split_long_move (operands); DONE;")
1929
1930 ;; %%% This multiword shite has got to go.
1931 (define_split
1932 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1933 (match_operand:DI 1 "general_operand" ""))]
1934 "!TARGET_64BIT && reload_completed
1935 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1936 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1937 [(const_int 0)]
1938 "ix86_split_long_move (operands); DONE;")
1939
1940 (define_insn "*movdi_1_rex64"
1941 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1942 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1943 "TARGET_64BIT
1944 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1945 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1946 {
1947 switch (get_attr_type (insn))
1948 {
1949 case TYPE_SSEMOV:
1950 if (get_attr_mode (insn) == MODE_TI)
1951 return "movdqa\t{%1, %0|%0, %1}";
1952 /* FALLTHRU */
1953 case TYPE_MMXMOV:
1954 /* Moves from and into integer register is done using movd opcode with
1955 REX prefix. */
1956 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1957 return "movd\t{%1, %0|%0, %1}";
1958 return "movq\t{%1, %0|%0, %1}";
1959 case TYPE_MULTI:
1960 return "#";
1961 case TYPE_LEA:
1962 return "lea{q}\t{%a1, %0|%0, %a1}";
1963 default:
1964 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1965 abort ();
1966 if (get_attr_mode (insn) == MODE_SI)
1967 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1968 else if (which_alternative == 2)
1969 return "movabs{q}\t{%1, %0|%0, %1}";
1970 else
1971 return "mov{q}\t{%1, %0|%0, %1}";
1972 }
1973 }
1974 [(set (attr "type")
1975 (cond [(eq_attr "alternative" "5,6,7")
1976 (const_string "mmxmov")
1977 (eq_attr "alternative" "8,9,10")
1978 (const_string "ssemov")
1979 (eq_attr "alternative" "4")
1980 (const_string "multi")
1981 (and (ne (symbol_ref "flag_pic") (const_int 0))
1982 (match_operand:DI 1 "symbolic_operand" ""))
1983 (const_string "lea")
1984 ]
1985 (const_string "imov")))
1986 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1987 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1988 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1989
1990 (define_insn "*movdi_1_rex64_nointerunit"
1991 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1992 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1993 "TARGET_64BIT
1994 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1995 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1996 {
1997 switch (get_attr_type (insn))
1998 {
1999 case TYPE_SSEMOV:
2000 if (get_attr_mode (insn) == MODE_TI)
2001 return "movdqa\t{%1, %0|%0, %1}";
2002 /* FALLTHRU */
2003 case TYPE_MMXMOV:
2004 return "movq\t{%1, %0|%0, %1}";
2005 case TYPE_MULTI:
2006 return "#";
2007 case TYPE_LEA:
2008 return "lea{q}\t{%a1, %0|%0, %a1}";
2009 default:
2010 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2011 abort ();
2012 if (get_attr_mode (insn) == MODE_SI)
2013 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2014 else if (which_alternative == 2)
2015 return "movabs{q}\t{%1, %0|%0, %1}";
2016 else
2017 return "mov{q}\t{%1, %0|%0, %1}";
2018 }
2019 }
2020 [(set (attr "type")
2021 (cond [(eq_attr "alternative" "5,6,7")
2022 (const_string "mmxmov")
2023 (eq_attr "alternative" "8,9,10")
2024 (const_string "ssemov")
2025 (eq_attr "alternative" "4")
2026 (const_string "multi")
2027 (and (ne (symbol_ref "flag_pic") (const_int 0))
2028 (match_operand:DI 1 "symbolic_operand" ""))
2029 (const_string "lea")
2030 ]
2031 (const_string "imov")))
2032 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2033 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2034 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2035
2036 ;; Stores and loads of ax to arbitrary constant address.
2037 ;; We fake an second form of instruction to force reload to load address
2038 ;; into register when rax is not available
2039 (define_insn "*movabsdi_1_rex64"
2040 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2041 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2042 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2043 "@
2044 movabs{q}\t{%1, %P0|%P0, %1}
2045 mov{q}\t{%1, %a0|%a0, %1}"
2046 [(set_attr "type" "imov")
2047 (set_attr "modrm" "0,*")
2048 (set_attr "length_address" "8,0")
2049 (set_attr "length_immediate" "0,*")
2050 (set_attr "memory" "store")
2051 (set_attr "mode" "DI")])
2052
2053 (define_insn "*movabsdi_2_rex64"
2054 [(set (match_operand:DI 0 "register_operand" "=a,r")
2055 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2056 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2057 "@
2058 movabs{q}\t{%P1, %0|%0, %P1}
2059 mov{q}\t{%a1, %0|%0, %a1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "modrm" "0,*")
2062 (set_attr "length_address" "8,0")
2063 (set_attr "length_immediate" "0")
2064 (set_attr "memory" "load")
2065 (set_attr "mode" "DI")])
2066
2067 ;; Convert impossible stores of immediate to existing instructions.
2068 ;; First try to get scratch register and go through it. In case this
2069 ;; fails, move by 32bit parts.
2070 (define_peephole2
2071 [(match_scratch:DI 2 "r")
2072 (set (match_operand:DI 0 "memory_operand" "")
2073 (match_operand:DI 1 "immediate_operand" ""))]
2074 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2075 && !x86_64_immediate_operand (operands[1], DImode)"
2076 [(set (match_dup 2) (match_dup 1))
2077 (set (match_dup 0) (match_dup 2))]
2078 "")
2079
2080 ;; We need to define this as both peepholer and splitter for case
2081 ;; peephole2 pass is not run.
2082 (define_peephole2
2083 [(set (match_operand:DI 0 "memory_operand" "")
2084 (match_operand:DI 1 "immediate_operand" ""))]
2085 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2086 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2087 [(set (match_dup 2) (match_dup 3))
2088 (set (match_dup 4) (match_dup 5))]
2089 "split_di (operands, 2, operands + 2, operands + 4);")
2090
2091 (define_split
2092 [(set (match_operand:DI 0 "memory_operand" "")
2093 (match_operand:DI 1 "immediate_operand" ""))]
2094 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2095 && !symbolic_operand (operands[1], DImode)
2096 && !x86_64_immediate_operand (operands[1], DImode)"
2097 [(set (match_dup 2) (match_dup 3))
2098 (set (match_dup 4) (match_dup 5))]
2099 "split_di (operands, 2, operands + 2, operands + 4);")
2100
2101 (define_insn "*swapdi_rex64"
2102 [(set (match_operand:DI 0 "register_operand" "+r")
2103 (match_operand:DI 1 "register_operand" "+r"))
2104 (set (match_dup 1)
2105 (match_dup 0))]
2106 "TARGET_64BIT"
2107 "xchg{q}\t%1, %0"
2108 [(set_attr "type" "imov")
2109 (set_attr "pent_pair" "np")
2110 (set_attr "athlon_decode" "vector")
2111 (set_attr "mode" "DI")
2112 (set_attr "modrm" "0")])
2113
2114
2115 (define_expand "movsf"
2116 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2117 (match_operand:SF 1 "general_operand" ""))]
2118 ""
2119 "ix86_expand_move (SFmode, operands); DONE;")
2120
2121 (define_insn "*pushsf"
2122 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2123 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2124 "!TARGET_64BIT"
2125 {
2126 switch (which_alternative)
2127 {
2128 case 1:
2129 return "push{l}\t%1";
2130
2131 default:
2132 /* This insn should be already split before reg-stack. */
2133 abort ();
2134 }
2135 }
2136 [(set_attr "type" "multi,push,multi")
2137 (set_attr "mode" "SF,SI,SF")])
2138
2139 (define_insn "*pushsf_rex64"
2140 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2141 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2142 "TARGET_64BIT"
2143 {
2144 switch (which_alternative)
2145 {
2146 case 1:
2147 return "push{q}\t%q1";
2148
2149 default:
2150 /* This insn should be already split before reg-stack. */
2151 abort ();
2152 }
2153 }
2154 [(set_attr "type" "multi,push,multi")
2155 (set_attr "mode" "SF,DI,SF")])
2156
2157 (define_split
2158 [(set (match_operand:SF 0 "push_operand" "")
2159 (match_operand:SF 1 "memory_operand" ""))]
2160 "reload_completed
2161 && GET_CODE (operands[1]) == MEM
2162 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2163 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2164 [(set (match_dup 0)
2165 (match_dup 1))]
2166 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2167
2168
2169 ;; %%% Kill this when call knows how to work this out.
2170 (define_split
2171 [(set (match_operand:SF 0 "push_operand" "")
2172 (match_operand:SF 1 "any_fp_register_operand" ""))]
2173 "!TARGET_64BIT"
2174 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2175 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2176
2177 (define_split
2178 [(set (match_operand:SF 0 "push_operand" "")
2179 (match_operand:SF 1 "any_fp_register_operand" ""))]
2180 "TARGET_64BIT"
2181 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2182 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2183
2184 (define_insn "*movsf_1"
2185 [(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")
2186 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2187 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2188 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2189 && (reload_in_progress || reload_completed
2190 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2191 || GET_CODE (operands[1]) != CONST_DOUBLE
2192 || memory_operand (operands[0], SFmode))"
2193 {
2194 switch (which_alternative)
2195 {
2196 case 0:
2197 if (REG_P (operands[1])
2198 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2199 return "fstp\t%y0";
2200 else if (STACK_TOP_P (operands[0]))
2201 return "fld%z1\t%y1";
2202 else
2203 return "fst\t%y0";
2204
2205 case 1:
2206 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2207 return "fstp%z0\t%y0";
2208 else
2209 return "fst%z0\t%y0";
2210
2211 case 2:
2212 return standard_80387_constant_opcode (operands[1]);
2213
2214 case 3:
2215 case 4:
2216 return "mov{l}\t{%1, %0|%0, %1}";
2217 case 5:
2218 if (get_attr_mode (insn) == MODE_TI)
2219 return "pxor\t%0, %0";
2220 else
2221 return "xorps\t%0, %0";
2222 case 6:
2223 if (get_attr_mode (insn) == MODE_V4SF)
2224 return "movaps\t{%1, %0|%0, %1}";
2225 else
2226 return "movss\t{%1, %0|%0, %1}";
2227 case 7:
2228 case 8:
2229 return "movss\t{%1, %0|%0, %1}";
2230
2231 case 9:
2232 case 10:
2233 return "movd\t{%1, %0|%0, %1}";
2234
2235 case 11:
2236 return "movq\t{%1, %0|%0, %1}";
2237
2238 default:
2239 abort();
2240 }
2241 }
2242 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2243 (set (attr "mode")
2244 (cond [(eq_attr "alternative" "3,4,9,10")
2245 (const_string "SI")
2246 (eq_attr "alternative" "5")
2247 (if_then_else
2248 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2249 (const_int 0))
2250 (ne (symbol_ref "TARGET_SSE2")
2251 (const_int 0)))
2252 (eq (symbol_ref "optimize_size")
2253 (const_int 0)))
2254 (const_string "TI")
2255 (const_string "V4SF"))
2256 /* For architectures resolving dependencies on
2257 whole SSE registers use APS move to break dependency
2258 chains, otherwise use short move to avoid extra work.
2259
2260 Do the same for architectures resolving dependencies on
2261 the parts. While in DF mode it is better to always handle
2262 just register parts, the SF mode is different due to lack
2263 of instructions to load just part of the register. It is
2264 better to maintain the whole registers in single format
2265 to avoid problems on using packed logical operations. */
2266 (eq_attr "alternative" "6")
2267 (if_then_else
2268 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2269 (const_int 0))
2270 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2271 (const_int 0)))
2272 (const_string "V4SF")
2273 (const_string "SF"))
2274 (eq_attr "alternative" "11")
2275 (const_string "DI")]
2276 (const_string "SF")))])
2277
2278 (define_insn "*movsf_1_nointerunit"
2279 [(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")
2280 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2281 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2282 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2283 && (reload_in_progress || reload_completed
2284 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2285 || GET_CODE (operands[1]) != CONST_DOUBLE
2286 || memory_operand (operands[0], SFmode))"
2287 {
2288 switch (which_alternative)
2289 {
2290 case 0:
2291 if (REG_P (operands[1])
2292 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293 {
2294 if (REGNO (operands[0]) == FIRST_STACK_REG
2295 && TARGET_USE_FFREEP)
2296 return "ffreep\t%y0";
2297 return "fstp\t%y0";
2298 }
2299 else if (STACK_TOP_P (operands[0]))
2300 return "fld%z1\t%y1";
2301 else
2302 return "fst\t%y0";
2303
2304 case 1:
2305 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2306 return "fstp%z0\t%y0";
2307 else
2308 return "fst%z0\t%y0";
2309
2310 case 2:
2311 return standard_80387_constant_opcode (operands[1]);
2312
2313 case 3:
2314 case 4:
2315 return "mov{l}\t{%1, %0|%0, %1}";
2316 case 5:
2317 if (get_attr_mode (insn) == MODE_TI)
2318 return "pxor\t%0, %0";
2319 else
2320 return "xorps\t%0, %0";
2321 case 6:
2322 if (get_attr_mode (insn) == MODE_V4SF)
2323 return "movaps\t{%1, %0|%0, %1}";
2324 else
2325 return "movss\t{%1, %0|%0, %1}";
2326 case 7:
2327 case 8:
2328 return "movss\t{%1, %0|%0, %1}";
2329
2330 case 9:
2331 case 10:
2332 return "movd\t{%1, %0|%0, %1}";
2333
2334 case 11:
2335 return "movq\t{%1, %0|%0, %1}";
2336
2337 default:
2338 abort();
2339 }
2340 }
2341 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2342 (set (attr "mode")
2343 (cond [(eq_attr "alternative" "3,4,9,10")
2344 (const_string "SI")
2345 (eq_attr "alternative" "5")
2346 (if_then_else
2347 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2348 (const_int 0))
2349 (ne (symbol_ref "TARGET_SSE2")
2350 (const_int 0)))
2351 (eq (symbol_ref "optimize_size")
2352 (const_int 0)))
2353 (const_string "TI")
2354 (const_string "V4SF"))
2355 /* For architectures resolving dependencies on
2356 whole SSE registers use APS move to break dependency
2357 chains, otherwise use short move to avoid extra work.
2358
2359 Do the same for architectures resolving dependencies on
2360 the parts. While in DF mode it is better to always handle
2361 just register parts, the SF mode is different due to lack
2362 of instructions to load just part of the register. It is
2363 better to maintain the whole registers in single format
2364 to avoid problems on using packed logical operations. */
2365 (eq_attr "alternative" "6")
2366 (if_then_else
2367 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2368 (const_int 0))
2369 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2370 (const_int 0)))
2371 (const_string "V4SF")
2372 (const_string "SF"))
2373 (eq_attr "alternative" "11")
2374 (const_string "DI")]
2375 (const_string "SF")))])
2376
2377 (define_insn "*swapsf"
2378 [(set (match_operand:SF 0 "register_operand" "+f")
2379 (match_operand:SF 1 "register_operand" "+f"))
2380 (set (match_dup 1)
2381 (match_dup 0))]
2382 "reload_completed || !TARGET_SSE"
2383 {
2384 if (STACK_TOP_P (operands[0]))
2385 return "fxch\t%1";
2386 else
2387 return "fxch\t%0";
2388 }
2389 [(set_attr "type" "fxch")
2390 (set_attr "mode" "SF")])
2391
2392 (define_expand "movdf"
2393 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2394 (match_operand:DF 1 "general_operand" ""))]
2395 ""
2396 "ix86_expand_move (DFmode, operands); DONE;")
2397
2398 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2399 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2400 ;; On the average, pushdf using integers can be still shorter. Allow this
2401 ;; pattern for optimize_size too.
2402
2403 (define_insn "*pushdf_nointeger"
2404 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2405 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2406 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2407 {
2408 /* This insn should be already split before reg-stack. */
2409 abort ();
2410 }
2411 [(set_attr "type" "multi")
2412 (set_attr "mode" "DF,SI,SI,DF")])
2413
2414 (define_insn "*pushdf_integer"
2415 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2416 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2417 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2418 {
2419 /* This insn should be already split before reg-stack. */
2420 abort ();
2421 }
2422 [(set_attr "type" "multi")
2423 (set_attr "mode" "DF,SI,DF")])
2424
2425 ;; %%% Kill this when call knows how to work this out.
2426 (define_split
2427 [(set (match_operand:DF 0 "push_operand" "")
2428 (match_operand:DF 1 "any_fp_register_operand" ""))]
2429 "!TARGET_64BIT && reload_completed"
2430 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2431 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2432 "")
2433
2434 (define_split
2435 [(set (match_operand:DF 0 "push_operand" "")
2436 (match_operand:DF 1 "any_fp_register_operand" ""))]
2437 "TARGET_64BIT && reload_completed"
2438 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2439 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2440 "")
2441
2442 (define_split
2443 [(set (match_operand:DF 0 "push_operand" "")
2444 (match_operand:DF 1 "general_operand" ""))]
2445 "reload_completed"
2446 [(const_int 0)]
2447 "ix86_split_long_move (operands); DONE;")
2448
2449 ;; Moving is usually shorter when only FP registers are used. This separate
2450 ;; movdf pattern avoids the use of integer registers for FP operations
2451 ;; when optimizing for size.
2452
2453 (define_insn "*movdf_nointeger"
2454 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2455 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2456 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2457 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2458 && (reload_in_progress || reload_completed
2459 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2460 || GET_CODE (operands[1]) != CONST_DOUBLE
2461 || memory_operand (operands[0], DFmode))"
2462 {
2463 switch (which_alternative)
2464 {
2465 case 0:
2466 if (REG_P (operands[1])
2467 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2468 {
2469 if (REGNO (operands[0]) == FIRST_STACK_REG
2470 && TARGET_USE_FFREEP)
2471 return "ffreep\t%y0";
2472 return "fstp\t%y0";
2473 }
2474 else if (STACK_TOP_P (operands[0]))
2475 return "fld%z1\t%y1";
2476 else
2477 return "fst\t%y0";
2478
2479 case 1:
2480 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2481 return "fstp%z0\t%y0";
2482 else
2483 return "fst%z0\t%y0";
2484
2485 case 2:
2486 return standard_80387_constant_opcode (operands[1]);
2487
2488 case 3:
2489 case 4:
2490 return "#";
2491 case 5:
2492 switch (get_attr_mode (insn))
2493 {
2494 case MODE_V4SF:
2495 return "xorps\t%0, %0";
2496 case MODE_V2DF:
2497 return "xorpd\t%0, %0";
2498 case MODE_TI:
2499 return "pxor\t%0, %0";
2500 default:
2501 abort ();
2502 }
2503 case 6:
2504 switch (get_attr_mode (insn))
2505 {
2506 case MODE_V4SF:
2507 return "movaps\t{%1, %0|%0, %1}";
2508 case MODE_V2DF:
2509 return "movapd\t{%1, %0|%0, %1}";
2510 case MODE_DF:
2511 return "movsd\t{%1, %0|%0, %1}";
2512 default:
2513 abort ();
2514 }
2515 case 7:
2516 if (get_attr_mode (insn) == MODE_V2DF)
2517 return "movlpd\t{%1, %0|%0, %1}";
2518 else
2519 return "movsd\t{%1, %0|%0, %1}";
2520 case 8:
2521 return "movsd\t{%1, %0|%0, %1}";
2522
2523 default:
2524 abort();
2525 }
2526 }
2527 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2528 (set (attr "mode")
2529 (cond [(eq_attr "alternative" "3,4")
2530 (const_string "SI")
2531 /* xorps is one byte shorter. */
2532 (eq_attr "alternative" "5")
2533 (cond [(ne (symbol_ref "optimize_size")
2534 (const_int 0))
2535 (const_string "V4SF")
2536 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2537 (const_int 0))
2538 (const_string "TI")]
2539 (const_string "V2DF"))
2540 /* For architectures resolving dependencies on
2541 whole SSE registers use APD move to break dependency
2542 chains, otherwise use short move to avoid extra work.
2543
2544 movaps encodes one byte shorter. */
2545 (eq_attr "alternative" "6")
2546 (cond
2547 [(ne (symbol_ref "optimize_size")
2548 (const_int 0))
2549 (const_string "V4SF")
2550 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2551 (const_int 0))
2552 (const_string "V2DF")]
2553 (const_string "DF"))
2554 /* For architectures resolving dependencies on register
2555 parts we may avoid extra work to zero out upper part
2556 of register. */
2557 (eq_attr "alternative" "7")
2558 (if_then_else
2559 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2560 (const_int 0))
2561 (const_string "V2DF")
2562 (const_string "DF"))]
2563 (const_string "DF")))])
2564
2565 (define_insn "*movdf_integer"
2566 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2567 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2568 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2569 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2570 && (reload_in_progress || reload_completed
2571 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2572 || GET_CODE (operands[1]) != CONST_DOUBLE
2573 || memory_operand (operands[0], DFmode))"
2574 {
2575 switch (which_alternative)
2576 {
2577 case 0:
2578 if (REG_P (operands[1])
2579 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580 {
2581 if (REGNO (operands[0]) == FIRST_STACK_REG
2582 && TARGET_USE_FFREEP)
2583 return "ffreep\t%y0";
2584 return "fstp\t%y0";
2585 }
2586 else if (STACK_TOP_P (operands[0]))
2587 return "fld%z1\t%y1";
2588 else
2589 return "fst\t%y0";
2590
2591 case 1:
2592 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2593 return "fstp%z0\t%y0";
2594 else
2595 return "fst%z0\t%y0";
2596
2597 case 2:
2598 return standard_80387_constant_opcode (operands[1]);
2599
2600 case 3:
2601 case 4:
2602 return "#";
2603
2604 case 5:
2605 switch (get_attr_mode (insn))
2606 {
2607 case MODE_V4SF:
2608 return "xorps\t%0, %0";
2609 case MODE_V2DF:
2610 return "xorpd\t%0, %0";
2611 case MODE_TI:
2612 return "pxor\t%0, %0";
2613 default:
2614 abort ();
2615 }
2616 case 6:
2617 switch (get_attr_mode (insn))
2618 {
2619 case MODE_V4SF:
2620 return "movaps\t{%1, %0|%0, %1}";
2621 case MODE_V2DF:
2622 return "movapd\t{%1, %0|%0, %1}";
2623 case MODE_DF:
2624 return "movsd\t{%1, %0|%0, %1}";
2625 default:
2626 abort ();
2627 }
2628 case 7:
2629 if (get_attr_mode (insn) == MODE_V2DF)
2630 return "movlpd\t{%1, %0|%0, %1}";
2631 else
2632 return "movsd\t{%1, %0|%0, %1}";
2633 case 8:
2634 return "movsd\t{%1, %0|%0, %1}";
2635
2636 default:
2637 abort();
2638 }
2639 }
2640 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2641 (set (attr "mode")
2642 (cond [(eq_attr "alternative" "3,4")
2643 (const_string "SI")
2644 /* xorps is one byte shorter. */
2645 (eq_attr "alternative" "5")
2646 (cond [(ne (symbol_ref "optimize_size")
2647 (const_int 0))
2648 (const_string "V4SF")
2649 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2650 (const_int 0))
2651 (const_string "TI")]
2652 (const_string "V2DF"))
2653 /* For architectures resolving dependencies on
2654 whole SSE registers use APD move to break dependency
2655 chains, otherwise use short move to avoid extra work.
2656
2657 movaps encodes one byte shorter. */
2658 (eq_attr "alternative" "6")
2659 (cond
2660 [(ne (symbol_ref "optimize_size")
2661 (const_int 0))
2662 (const_string "V4SF")
2663 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2664 (const_int 0))
2665 (const_string "V2DF")]
2666 (const_string "DF"))
2667 /* For architectures resolving dependencies on register
2668 parts we may avoid extra work to zero out upper part
2669 of register. */
2670 (eq_attr "alternative" "7")
2671 (if_then_else
2672 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2673 (const_int 0))
2674 (const_string "V2DF")
2675 (const_string "DF"))]
2676 (const_string "DF")))])
2677
2678 (define_split
2679 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2680 (match_operand:DF 1 "general_operand" ""))]
2681 "reload_completed
2682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2683 && ! (ANY_FP_REG_P (operands[0]) ||
2684 (GET_CODE (operands[0]) == SUBREG
2685 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2686 && ! (ANY_FP_REG_P (operands[1]) ||
2687 (GET_CODE (operands[1]) == SUBREG
2688 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2689 [(const_int 0)]
2690 "ix86_split_long_move (operands); DONE;")
2691
2692 (define_insn "*swapdf"
2693 [(set (match_operand:DF 0 "register_operand" "+f")
2694 (match_operand:DF 1 "register_operand" "+f"))
2695 (set (match_dup 1)
2696 (match_dup 0))]
2697 "reload_completed || !TARGET_SSE2"
2698 {
2699 if (STACK_TOP_P (operands[0]))
2700 return "fxch\t%1";
2701 else
2702 return "fxch\t%0";
2703 }
2704 [(set_attr "type" "fxch")
2705 (set_attr "mode" "DF")])
2706
2707 (define_expand "movxf"
2708 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2709 (match_operand:XF 1 "general_operand" ""))]
2710 ""
2711 "ix86_expand_move (XFmode, operands); DONE;")
2712
2713 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2714 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2715 ;; Pushing using integer instructions is longer except for constants
2716 ;; and direct memory references.
2717 ;; (assuming that any given constant is pushed only once, but this ought to be
2718 ;; handled elsewhere).
2719
2720 (define_insn "*pushxf_nointeger"
2721 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2722 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2723 "optimize_size"
2724 {
2725 /* This insn should be already split before reg-stack. */
2726 abort ();
2727 }
2728 [(set_attr "type" "multi")
2729 (set_attr "mode" "XF,SI,SI")])
2730
2731 (define_insn "*pushxf_integer"
2732 [(set (match_operand:XF 0 "push_operand" "=<,<")
2733 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2734 "!optimize_size"
2735 {
2736 /* This insn should be already split before reg-stack. */
2737 abort ();
2738 }
2739 [(set_attr "type" "multi")
2740 (set_attr "mode" "XF,SI")])
2741
2742 (define_split
2743 [(set (match_operand 0 "push_operand" "")
2744 (match_operand 1 "general_operand" ""))]
2745 "reload_completed
2746 && (GET_MODE (operands[0]) == XFmode
2747 || GET_MODE (operands[0]) == DFmode)
2748 && !ANY_FP_REG_P (operands[1])"
2749 [(const_int 0)]
2750 "ix86_split_long_move (operands); DONE;")
2751
2752 (define_split
2753 [(set (match_operand:XF 0 "push_operand" "")
2754 (match_operand:XF 1 "any_fp_register_operand" ""))]
2755 "!TARGET_64BIT"
2756 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2757 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2758 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2759
2760 (define_split
2761 [(set (match_operand:XF 0 "push_operand" "")
2762 (match_operand:XF 1 "any_fp_register_operand" ""))]
2763 "TARGET_64BIT"
2764 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2765 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2766 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767
2768 ;; Do not use integer registers when optimizing for size
2769 (define_insn "*movxf_nointeger"
2770 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2771 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2772 "optimize_size
2773 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2774 && (reload_in_progress || reload_completed
2775 || GET_CODE (operands[1]) != CONST_DOUBLE
2776 || memory_operand (operands[0], XFmode))"
2777 {
2778 switch (which_alternative)
2779 {
2780 case 0:
2781 if (REG_P (operands[1])
2782 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2783 {
2784 if (REGNO (operands[0]) == FIRST_STACK_REG
2785 && TARGET_USE_FFREEP)
2786 return "ffreep\t%y0";
2787 return "fstp\t%y0";
2788 }
2789 else if (STACK_TOP_P (operands[0]))
2790 return "fld%z1\t%y1";
2791 else
2792 return "fst\t%y0";
2793
2794 case 1:
2795 /* There is no non-popping store to memory for XFmode. So if
2796 we need one, follow the store with a load. */
2797 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2798 return "fstp%z0\t%y0\;fld%z0\t%y0";
2799 else
2800 return "fstp%z0\t%y0";
2801
2802 case 2:
2803 return standard_80387_constant_opcode (operands[1]);
2804
2805 case 3: case 4:
2806 return "#";
2807 }
2808 abort();
2809 }
2810 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2811 (set_attr "mode" "XF,XF,XF,SI,SI")])
2812
2813 (define_insn "*movxf_integer"
2814 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2815 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2816 "!optimize_size
2817 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2818 && (reload_in_progress || reload_completed
2819 || GET_CODE (operands[1]) != CONST_DOUBLE
2820 || memory_operand (operands[0], XFmode))"
2821 {
2822 switch (which_alternative)
2823 {
2824 case 0:
2825 if (REG_P (operands[1])
2826 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827 {
2828 if (REGNO (operands[0]) == FIRST_STACK_REG
2829 && TARGET_USE_FFREEP)
2830 return "ffreep\t%y0";
2831 return "fstp\t%y0";
2832 }
2833 else if (STACK_TOP_P (operands[0]))
2834 return "fld%z1\t%y1";
2835 else
2836 return "fst\t%y0";
2837
2838 case 1:
2839 /* There is no non-popping store to memory for XFmode. So if
2840 we need one, follow the store with a load. */
2841 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2842 return "fstp%z0\t%y0\;fld%z0\t%y0";
2843 else
2844 return "fstp%z0\t%y0";
2845
2846 case 2:
2847 return standard_80387_constant_opcode (operands[1]);
2848
2849 case 3: case 4:
2850 return "#";
2851 }
2852 abort();
2853 }
2854 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2855 (set_attr "mode" "XF,XF,XF,SI,SI")])
2856
2857 (define_split
2858 [(set (match_operand 0 "nonimmediate_operand" "")
2859 (match_operand 1 "general_operand" ""))]
2860 "reload_completed
2861 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2862 && GET_MODE (operands[0]) == XFmode
2863 && ! (ANY_FP_REG_P (operands[0]) ||
2864 (GET_CODE (operands[0]) == SUBREG
2865 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2866 && ! (ANY_FP_REG_P (operands[1]) ||
2867 (GET_CODE (operands[1]) == SUBREG
2868 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2869 [(const_int 0)]
2870 "ix86_split_long_move (operands); DONE;")
2871
2872 (define_split
2873 [(set (match_operand 0 "register_operand" "")
2874 (match_operand 1 "memory_operand" ""))]
2875 "reload_completed
2876 && GET_CODE (operands[1]) == MEM
2877 && (GET_MODE (operands[0]) == XFmode
2878 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2879 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2880 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2881 [(set (match_dup 0) (match_dup 1))]
2882 {
2883 rtx c = get_pool_constant (XEXP (operands[1], 0));
2884 rtx r = operands[0];
2885
2886 if (GET_CODE (r) == SUBREG)
2887 r = SUBREG_REG (r);
2888
2889 if (SSE_REG_P (r))
2890 {
2891 if (!standard_sse_constant_p (c))
2892 FAIL;
2893 }
2894 else if (FP_REG_P (r))
2895 {
2896 if (!standard_80387_constant_p (c))
2897 FAIL;
2898 }
2899 else if (MMX_REG_P (r))
2900 FAIL;
2901
2902 operands[1] = c;
2903 })
2904
2905 (define_insn "swapxf"
2906 [(set (match_operand:XF 0 "register_operand" "+f")
2907 (match_operand:XF 1 "register_operand" "+f"))
2908 (set (match_dup 1)
2909 (match_dup 0))]
2910 ""
2911 {
2912 if (STACK_TOP_P (operands[0]))
2913 return "fxch\t%1";
2914 else
2915 return "fxch\t%0";
2916 }
2917 [(set_attr "type" "fxch")
2918 (set_attr "mode" "XF")])
2919 \f
2920 ;; Zero extension instructions
2921
2922 (define_expand "zero_extendhisi2"
2923 [(set (match_operand:SI 0 "register_operand" "")
2924 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2925 ""
2926 {
2927 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2928 {
2929 operands[1] = force_reg (HImode, operands[1]);
2930 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2931 DONE;
2932 }
2933 })
2934
2935 (define_insn "zero_extendhisi2_and"
2936 [(set (match_operand:SI 0 "register_operand" "=r")
2937 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2938 (clobber (reg:CC 17))]
2939 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2940 "#"
2941 [(set_attr "type" "alu1")
2942 (set_attr "mode" "SI")])
2943
2944 (define_split
2945 [(set (match_operand:SI 0 "register_operand" "")
2946 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2947 (clobber (reg:CC 17))]
2948 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2949 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2950 (clobber (reg:CC 17))])]
2951 "")
2952
2953 (define_insn "*zero_extendhisi2_movzwl"
2954 [(set (match_operand:SI 0 "register_operand" "=r")
2955 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2956 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2957 "movz{wl|x}\t{%1, %0|%0, %1}"
2958 [(set_attr "type" "imovx")
2959 (set_attr "mode" "SI")])
2960
2961 (define_expand "zero_extendqihi2"
2962 [(parallel
2963 [(set (match_operand:HI 0 "register_operand" "")
2964 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2965 (clobber (reg:CC 17))])]
2966 ""
2967 "")
2968
2969 (define_insn "*zero_extendqihi2_and"
2970 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2971 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2972 (clobber (reg:CC 17))]
2973 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2974 "#"
2975 [(set_attr "type" "alu1")
2976 (set_attr "mode" "HI")])
2977
2978 (define_insn "*zero_extendqihi2_movzbw_and"
2979 [(set (match_operand:HI 0 "register_operand" "=r,r")
2980 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2981 (clobber (reg:CC 17))]
2982 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2983 "#"
2984 [(set_attr "type" "imovx,alu1")
2985 (set_attr "mode" "HI")])
2986
2987 (define_insn "*zero_extendqihi2_movzbw"
2988 [(set (match_operand:HI 0 "register_operand" "=r")
2989 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2990 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2991 "movz{bw|x}\t{%1, %0|%0, %1}"
2992 [(set_attr "type" "imovx")
2993 (set_attr "mode" "HI")])
2994
2995 ;; For the movzbw case strip only the clobber
2996 (define_split
2997 [(set (match_operand:HI 0 "register_operand" "")
2998 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2999 (clobber (reg:CC 17))]
3000 "reload_completed
3001 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3002 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3003 [(set (match_operand:HI 0 "register_operand" "")
3004 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3005
3006 ;; When source and destination does not overlap, clear destination
3007 ;; first and then do the movb
3008 (define_split
3009 [(set (match_operand:HI 0 "register_operand" "")
3010 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3011 (clobber (reg:CC 17))]
3012 "reload_completed
3013 && ANY_QI_REG_P (operands[0])
3014 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3015 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3016 [(set (match_dup 0) (const_int 0))
3017 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3018 "operands[2] = gen_lowpart (QImode, operands[0]);")
3019
3020 ;; Rest is handled by single and.
3021 (define_split
3022 [(set (match_operand:HI 0 "register_operand" "")
3023 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3024 (clobber (reg:CC 17))]
3025 "reload_completed
3026 && true_regnum (operands[0]) == true_regnum (operands[1])"
3027 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3028 (clobber (reg:CC 17))])]
3029 "")
3030
3031 (define_expand "zero_extendqisi2"
3032 [(parallel
3033 [(set (match_operand:SI 0 "register_operand" "")
3034 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3035 (clobber (reg:CC 17))])]
3036 ""
3037 "")
3038
3039 (define_insn "*zero_extendqisi2_and"
3040 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3041 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3042 (clobber (reg:CC 17))]
3043 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3044 "#"
3045 [(set_attr "type" "alu1")
3046 (set_attr "mode" "SI")])
3047
3048 (define_insn "*zero_extendqisi2_movzbw_and"
3049 [(set (match_operand:SI 0 "register_operand" "=r,r")
3050 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3051 (clobber (reg:CC 17))]
3052 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3053 "#"
3054 [(set_attr "type" "imovx,alu1")
3055 (set_attr "mode" "SI")])
3056
3057 (define_insn "*zero_extendqisi2_movzbw"
3058 [(set (match_operand:SI 0 "register_operand" "=r")
3059 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3060 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3061 "movz{bl|x}\t{%1, %0|%0, %1}"
3062 [(set_attr "type" "imovx")
3063 (set_attr "mode" "SI")])
3064
3065 ;; For the movzbl case strip only the clobber
3066 (define_split
3067 [(set (match_operand:SI 0 "register_operand" "")
3068 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3069 (clobber (reg:CC 17))]
3070 "reload_completed
3071 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3072 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3073 [(set (match_dup 0)
3074 (zero_extend:SI (match_dup 1)))])
3075
3076 ;; When source and destination does not overlap, clear destination
3077 ;; first and then do the movb
3078 (define_split
3079 [(set (match_operand:SI 0 "register_operand" "")
3080 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3081 (clobber (reg:CC 17))]
3082 "reload_completed
3083 && ANY_QI_REG_P (operands[0])
3084 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3085 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3086 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3087 [(set (match_dup 0) (const_int 0))
3088 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3089 "operands[2] = gen_lowpart (QImode, operands[0]);")
3090
3091 ;; Rest is handled by single and.
3092 (define_split
3093 [(set (match_operand:SI 0 "register_operand" "")
3094 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3095 (clobber (reg:CC 17))]
3096 "reload_completed
3097 && true_regnum (operands[0]) == true_regnum (operands[1])"
3098 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3099 (clobber (reg:CC 17))])]
3100 "")
3101
3102 ;; %%% Kill me once multi-word ops are sane.
3103 (define_expand "zero_extendsidi2"
3104 [(set (match_operand:DI 0 "register_operand" "=r")
3105 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3106 ""
3107 "if (!TARGET_64BIT)
3108 {
3109 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3110 DONE;
3111 }
3112 ")
3113
3114 (define_insn "zero_extendsidi2_32"
3115 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3116 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3117 (clobber (reg:CC 17))]
3118 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3119 "@
3120 #
3121 #
3122 #
3123 movd\t{%1, %0|%0, %1}
3124 movd\t{%1, %0|%0, %1}"
3125 [(set_attr "mode" "SI,SI,SI,DI,TI")
3126 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3127
3128 (define_insn "*zero_extendsidi2_32_1"
3129 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3130 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3131 (clobber (reg:CC 17))]
3132 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3133 "@
3134 #
3135 #
3136 #
3137 movd\t{%1, %0|%0, %1}
3138 movd\t{%1, %0|%0, %1}"
3139 [(set_attr "mode" "SI,SI,SI,DI,TI")
3140 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3141
3142 (define_insn "zero_extendsidi2_rex64"
3143 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3144 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3145 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3146 "@
3147 mov\t{%k1, %k0|%k0, %k1}
3148 #
3149 movd\t{%1, %0|%0, %1}
3150 movd\t{%1, %0|%0, %1}"
3151 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3152 (set_attr "mode" "SI,DI,DI,TI")])
3153
3154 (define_insn "*zero_extendsidi2_rex64_1"
3155 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3156 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3157 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3158 "@
3159 mov\t{%k1, %k0|%k0, %k1}
3160 #
3161 movd\t{%1, %0|%0, %1}
3162 movd\t{%1, %0|%0, %1}"
3163 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3164 (set_attr "mode" "SI,DI,SI,SI")])
3165
3166 (define_split
3167 [(set (match_operand:DI 0 "memory_operand" "")
3168 (zero_extend:DI (match_dup 0)))]
3169 "TARGET_64BIT"
3170 [(set (match_dup 4) (const_int 0))]
3171 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3172
3173 (define_split
3174 [(set (match_operand:DI 0 "register_operand" "")
3175 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3176 (clobber (reg:CC 17))]
3177 "!TARGET_64BIT && reload_completed
3178 && true_regnum (operands[0]) == true_regnum (operands[1])"
3179 [(set (match_dup 4) (const_int 0))]
3180 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3181
3182 (define_split
3183 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3184 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3185 (clobber (reg:CC 17))]
3186 "!TARGET_64BIT && reload_completed
3187 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3188 [(set (match_dup 3) (match_dup 1))
3189 (set (match_dup 4) (const_int 0))]
3190 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3191
3192 (define_insn "zero_extendhidi2"
3193 [(set (match_operand:DI 0 "register_operand" "=r,r")
3194 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3195 "TARGET_64BIT"
3196 "@
3197 movz{wl|x}\t{%1, %k0|%k0, %1}
3198 movz{wq|x}\t{%1, %0|%0, %1}"
3199 [(set_attr "type" "imovx")
3200 (set_attr "mode" "SI,DI")])
3201
3202 (define_insn "zero_extendqidi2"
3203 [(set (match_operand:DI 0 "register_operand" "=r,r")
3204 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3205 "TARGET_64BIT"
3206 "@
3207 movz{bl|x}\t{%1, %k0|%k0, %1}
3208 movz{bq|x}\t{%1, %0|%0, %1}"
3209 [(set_attr "type" "imovx")
3210 (set_attr "mode" "SI,DI")])
3211 \f
3212 ;; Sign extension instructions
3213
3214 (define_expand "extendsidi2"
3215 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3216 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3217 (clobber (reg:CC 17))
3218 (clobber (match_scratch:SI 2 ""))])]
3219 ""
3220 {
3221 if (TARGET_64BIT)
3222 {
3223 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3224 DONE;
3225 }
3226 })
3227
3228 (define_insn "*extendsidi2_1"
3229 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3230 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3231 (clobber (reg:CC 17))
3232 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3233 "!TARGET_64BIT"
3234 "#")
3235
3236 (define_insn "extendsidi2_rex64"
3237 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3238 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3239 "TARGET_64BIT"
3240 "@
3241 {cltq|cdqe}
3242 movs{lq|x}\t{%1,%0|%0, %1}"
3243 [(set_attr "type" "imovx")
3244 (set_attr "mode" "DI")
3245 (set_attr "prefix_0f" "0")
3246 (set_attr "modrm" "0,1")])
3247
3248 (define_insn "extendhidi2"
3249 [(set (match_operand:DI 0 "register_operand" "=r")
3250 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3251 "TARGET_64BIT"
3252 "movs{wq|x}\t{%1,%0|%0, %1}"
3253 [(set_attr "type" "imovx")
3254 (set_attr "mode" "DI")])
3255
3256 (define_insn "extendqidi2"
3257 [(set (match_operand:DI 0 "register_operand" "=r")
3258 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3259 "TARGET_64BIT"
3260 "movs{bq|x}\t{%1,%0|%0, %1}"
3261 [(set_attr "type" "imovx")
3262 (set_attr "mode" "DI")])
3263
3264 ;; Extend to memory case when source register does die.
3265 (define_split
3266 [(set (match_operand:DI 0 "memory_operand" "")
3267 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3268 (clobber (reg:CC 17))
3269 (clobber (match_operand:SI 2 "register_operand" ""))]
3270 "(reload_completed
3271 && dead_or_set_p (insn, operands[1])
3272 && !reg_mentioned_p (operands[1], operands[0]))"
3273 [(set (match_dup 3) (match_dup 1))
3274 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3275 (clobber (reg:CC 17))])
3276 (set (match_dup 4) (match_dup 1))]
3277 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3278
3279 ;; Extend to memory case when source register does not die.
3280 (define_split
3281 [(set (match_operand:DI 0 "memory_operand" "")
3282 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3283 (clobber (reg:CC 17))
3284 (clobber (match_operand:SI 2 "register_operand" ""))]
3285 "reload_completed"
3286 [(const_int 0)]
3287 {
3288 split_di (&operands[0], 1, &operands[3], &operands[4]);
3289
3290 emit_move_insn (operands[3], operands[1]);
3291
3292 /* Generate a cltd if possible and doing so it profitable. */
3293 if (true_regnum (operands[1]) == 0
3294 && true_regnum (operands[2]) == 1
3295 && (optimize_size || TARGET_USE_CLTD))
3296 {
3297 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3298 }
3299 else
3300 {
3301 emit_move_insn (operands[2], operands[1]);
3302 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3303 }
3304 emit_move_insn (operands[4], operands[2]);
3305 DONE;
3306 })
3307
3308 ;; Extend to register case. Optimize case where source and destination
3309 ;; registers match and cases where we can use cltd.
3310 (define_split
3311 [(set (match_operand:DI 0 "register_operand" "")
3312 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3313 (clobber (reg:CC 17))
3314 (clobber (match_scratch:SI 2 ""))]
3315 "reload_completed"
3316 [(const_int 0)]
3317 {
3318 split_di (&operands[0], 1, &operands[3], &operands[4]);
3319
3320 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3321 emit_move_insn (operands[3], operands[1]);
3322
3323 /* Generate a cltd if possible and doing so it profitable. */
3324 if (true_regnum (operands[3]) == 0
3325 && (optimize_size || TARGET_USE_CLTD))
3326 {
3327 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3328 DONE;
3329 }
3330
3331 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3332 emit_move_insn (operands[4], operands[1]);
3333
3334 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3335 DONE;
3336 })
3337
3338 (define_insn "extendhisi2"
3339 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3340 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3341 ""
3342 {
3343 switch (get_attr_prefix_0f (insn))
3344 {
3345 case 0:
3346 return "{cwtl|cwde}";
3347 default:
3348 return "movs{wl|x}\t{%1,%0|%0, %1}";
3349 }
3350 }
3351 [(set_attr "type" "imovx")
3352 (set_attr "mode" "SI")
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 "*extendhisi2_zext"
3365 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3366 (zero_extend:DI
3367 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3368 "TARGET_64BIT"
3369 {
3370 switch (get_attr_prefix_0f (insn))
3371 {
3372 case 0:
3373 return "{cwtl|cwde}";
3374 default:
3375 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3376 }
3377 }
3378 [(set_attr "type" "imovx")
3379 (set_attr "mode" "SI")
3380 (set (attr "prefix_0f")
3381 ;; movsx is short decodable while cwtl is vector decoded.
3382 (if_then_else (and (eq_attr "cpu" "!k6")
3383 (eq_attr "alternative" "0"))
3384 (const_string "0")
3385 (const_string "1")))
3386 (set (attr "modrm")
3387 (if_then_else (eq_attr "prefix_0f" "0")
3388 (const_string "0")
3389 (const_string "1")))])
3390
3391 (define_insn "extendqihi2"
3392 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3393 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3394 ""
3395 {
3396 switch (get_attr_prefix_0f (insn))
3397 {
3398 case 0:
3399 return "{cbtw|cbw}";
3400 default:
3401 return "movs{bw|x}\t{%1,%0|%0, %1}";
3402 }
3403 }
3404 [(set_attr "type" "imovx")
3405 (set_attr "mode" "HI")
3406 (set (attr "prefix_0f")
3407 ;; movsx is short decodable while cwtl is vector decoded.
3408 (if_then_else (and (eq_attr "cpu" "!k6")
3409 (eq_attr "alternative" "0"))
3410 (const_string "0")
3411 (const_string "1")))
3412 (set (attr "modrm")
3413 (if_then_else (eq_attr "prefix_0f" "0")
3414 (const_string "0")
3415 (const_string "1")))])
3416
3417 (define_insn "extendqisi2"
3418 [(set (match_operand:SI 0 "register_operand" "=r")
3419 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3420 ""
3421 "movs{bl|x}\t{%1,%0|%0, %1}"
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "SI")])
3424
3425 (define_insn "*extendqisi2_zext"
3426 [(set (match_operand:DI 0 "register_operand" "=r")
3427 (zero_extend:DI
3428 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3429 "TARGET_64BIT"
3430 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3431 [(set_attr "type" "imovx")
3432 (set_attr "mode" "SI")])
3433 \f
3434 ;; Conversions between float and double.
3435
3436 ;; These are all no-ops in the model used for the 80387. So just
3437 ;; emit moves.
3438
3439 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3440 (define_insn "*dummy_extendsfdf2"
3441 [(set (match_operand:DF 0 "push_operand" "=<")
3442 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3443 "0"
3444 "#")
3445
3446 (define_split
3447 [(set (match_operand:DF 0 "push_operand" "")
3448 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3449 "!TARGET_64BIT"
3450 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3451 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3452
3453 (define_split
3454 [(set (match_operand:DF 0 "push_operand" "")
3455 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3456 "TARGET_64BIT"
3457 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3458 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3459
3460 (define_insn "*dummy_extendsfxf2"
3461 [(set (match_operand:XF 0 "push_operand" "=<")
3462 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3463 "0"
3464 "#")
3465
3466 (define_split
3467 [(set (match_operand:XF 0 "push_operand" "")
3468 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3469 ""
3470 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3471 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3472 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473
3474 (define_split
3475 [(set (match_operand:XF 0 "push_operand" "")
3476 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3477 "TARGET_64BIT"
3478 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3479 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3480 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_split
3483 [(set (match_operand:XF 0 "push_operand" "")
3484 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3485 ""
3486 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3487 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3488 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489
3490 (define_split
3491 [(set (match_operand:XF 0 "push_operand" "")
3492 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3493 "TARGET_64BIT"
3494 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3495 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3496 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497
3498 (define_expand "extendsfdf2"
3499 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3500 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3501 "TARGET_80387 || TARGET_SSE2"
3502 {
3503 /* ??? Needed for compress_float_constant since all fp constants
3504 are LEGITIMATE_CONSTANT_P. */
3505 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3506 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3507 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3508 operands[1] = force_reg (SFmode, operands[1]);
3509 })
3510
3511 (define_insn "*extendsfdf2_1"
3512 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3513 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3514 "(TARGET_80387 || TARGET_SSE2)
3515 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3516 {
3517 switch (which_alternative)
3518 {
3519 case 0:
3520 if (REG_P (operands[1])
3521 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3522 return "fstp\t%y0";
3523 else if (STACK_TOP_P (operands[0]))
3524 return "fld%z1\t%y1";
3525 else
3526 return "fst\t%y0";
3527
3528 case 1:
3529 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3530 return "fstp%z0\t%y0";
3531
3532 else
3533 return "fst%z0\t%y0";
3534 case 2:
3535 return "cvtss2sd\t{%1, %0|%0, %1}";
3536
3537 default:
3538 abort ();
3539 }
3540 }
3541 [(set_attr "type" "fmov,fmov,ssecvt")
3542 (set_attr "mode" "SF,XF,DF")])
3543
3544 (define_insn "*extendsfdf2_1_sse_only"
3545 [(set (match_operand:DF 0 "register_operand" "=Y")
3546 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3547 "!TARGET_80387 && TARGET_SSE2
3548 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3549 "cvtss2sd\t{%1, %0|%0, %1}"
3550 [(set_attr "type" "ssecvt")
3551 (set_attr "mode" "DF")])
3552
3553 (define_expand "extendsfxf2"
3554 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3555 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3556 "TARGET_80387"
3557 {
3558 /* ??? Needed for compress_float_constant since all fp constants
3559 are LEGITIMATE_CONSTANT_P. */
3560 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3561 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3562 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3563 operands[1] = force_reg (SFmode, operands[1]);
3564 })
3565
3566 (define_insn "*extendsfxf2_1"
3567 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3568 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3569 "TARGET_80387
3570 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3571 {
3572 switch (which_alternative)
3573 {
3574 case 0:
3575 if (REG_P (operands[1])
3576 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3577 return "fstp\t%y0";
3578 else if (STACK_TOP_P (operands[0]))
3579 return "fld%z1\t%y1";
3580 else
3581 return "fst\t%y0";
3582
3583 case 1:
3584 /* There is no non-popping store to memory for XFmode. So if
3585 we need one, follow the store with a load. */
3586 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3587 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3588 else
3589 return "fstp%z0\t%y0";
3590
3591 default:
3592 abort ();
3593 }
3594 }
3595 [(set_attr "type" "fmov")
3596 (set_attr "mode" "SF,XF")])
3597
3598 (define_expand "extenddfxf2"
3599 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3600 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3601 "TARGET_80387"
3602 {
3603 /* ??? Needed for compress_float_constant since all fp constants
3604 are LEGITIMATE_CONSTANT_P. */
3605 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3606 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3607 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3608 operands[1] = force_reg (DFmode, operands[1]);
3609 })
3610
3611 (define_insn "*extenddfxf2_1"
3612 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3613 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3614 "TARGET_80387
3615 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3616 {
3617 switch (which_alternative)
3618 {
3619 case 0:
3620 if (REG_P (operands[1])
3621 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3622 return "fstp\t%y0";
3623 else if (STACK_TOP_P (operands[0]))
3624 return "fld%z1\t%y1";
3625 else
3626 return "fst\t%y0";
3627
3628 case 1:
3629 /* There is no non-popping store to memory for XFmode. So if
3630 we need one, follow the store with a load. */
3631 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3632 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3633 else
3634 return "fstp%z0\t%y0";
3635
3636 default:
3637 abort ();
3638 }
3639 }
3640 [(set_attr "type" "fmov")
3641 (set_attr "mode" "DF,XF")])
3642
3643 ;; %%% This seems bad bad news.
3644 ;; This cannot output into an f-reg because there is no way to be sure
3645 ;; of truncating in that case. Otherwise this is just like a simple move
3646 ;; insn. So we pretend we can output to a reg in order to get better
3647 ;; register preferencing, but we really use a stack slot.
3648
3649 (define_expand "truncdfsf2"
3650 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3651 (float_truncate:SF
3652 (match_operand:DF 1 "register_operand" "")))
3653 (clobber (match_dup 2))])]
3654 "TARGET_80387 || TARGET_SSE2"
3655 "
3656 if (!TARGET_80387)
3657 {
3658 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3659 DONE;
3660 }
3661 else if (flag_unsafe_math_optimizations)
3662 {
3663 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3664 emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3665 if (reg != operands[0])
3666 emit_move_insn (operands[0], reg);
3667 DONE;
3668 }
3669 else
3670 operands[2] = assign_386_stack_local (SFmode, 0);
3671 ")
3672
3673 (define_insn "truncdfsf2_noop"
3674 [(set (match_operand:SF 0 "register_operand" "=f")
3675 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3676 "TARGET_80387 && flag_unsafe_math_optimizations"
3677 "#")
3678
3679 (define_insn "*truncdfsf2_1"
3680 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3681 (float_truncate:SF
3682 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3683 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3684 "TARGET_80387 && !TARGET_SSE2"
3685 {
3686 switch (which_alternative)
3687 {
3688 case 0:
3689 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3690 return "fstp%z0\t%y0";
3691 else
3692 return "fst%z0\t%y0";
3693 default:
3694 abort ();
3695 }
3696 }
3697 [(set_attr "type" "fmov,multi,multi,multi")
3698 (set_attr "mode" "SF,SF,SF,SF")])
3699
3700 (define_insn "*truncdfsf2_1_sse"
3701 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3702 (float_truncate:SF
3703 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3704 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3705 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3706 {
3707 switch (which_alternative)
3708 {
3709 case 0:
3710 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3711 return "fstp%z0\t%y0";
3712 else
3713 return "fst%z0\t%y0";
3714 case 4:
3715 return "#";
3716 default:
3717 abort ();
3718 }
3719 }
3720 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3721 (set_attr "mode" "SF,SF,SF,SF,DF")])
3722
3723 (define_insn "*truncdfsf2_1_sse_nooverlap"
3724 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3725 (float_truncate:SF
3726 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3727 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3728 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3729 {
3730 switch (which_alternative)
3731 {
3732 case 0:
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 case 4:
3738 return "#";
3739 default:
3740 abort ();
3741 }
3742 }
3743 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3744 (set_attr "mode" "SF,SF,SF,SF,DF")])
3745
3746 (define_insn "*truncdfsf2_2"
3747 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3748 (float_truncate:SF
3749 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3750 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3751 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3752 {
3753 switch (which_alternative)
3754 {
3755 case 0:
3756 case 1:
3757 return "cvtsd2ss\t{%1, %0|%0, %1}";
3758 case 2:
3759 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3760 return "fstp%z0\t%y0";
3761 else
3762 return "fst%z0\t%y0";
3763 default:
3764 abort ();
3765 }
3766 }
3767 [(set_attr "type" "ssecvt,ssecvt,fmov")
3768 (set_attr "athlon_decode" "vector,double,*")
3769 (set_attr "mode" "SF,SF,SF")])
3770
3771 (define_insn "*truncdfsf2_2_nooverlap"
3772 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3773 (float_truncate:SF
3774 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3775 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3776 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3777 {
3778 switch (which_alternative)
3779 {
3780 case 0:
3781 return "#";
3782 case 1:
3783 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3784 return "fstp%z0\t%y0";
3785 else
3786 return "fst%z0\t%y0";
3787 default:
3788 abort ();
3789 }
3790 }
3791 [(set_attr "type" "ssecvt,fmov")
3792 (set_attr "mode" "DF,SF")])
3793
3794 (define_insn "*truncdfsf2_3"
3795 [(set (match_operand:SF 0 "memory_operand" "=m")
3796 (float_truncate:SF
3797 (match_operand:DF 1 "register_operand" "f")))]
3798 "TARGET_80387"
3799 {
3800 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3801 return "fstp%z0\t%y0";
3802 else
3803 return "fst%z0\t%y0";
3804 }
3805 [(set_attr "type" "fmov")
3806 (set_attr "mode" "SF")])
3807
3808 (define_insn "truncdfsf2_sse_only"
3809 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3810 (float_truncate:SF
3811 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3812 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3813 "cvtsd2ss\t{%1, %0|%0, %1}"
3814 [(set_attr "type" "ssecvt")
3815 (set_attr "athlon_decode" "vector,double")
3816 (set_attr "mode" "SF")])
3817
3818 (define_insn "*truncdfsf2_sse_only_nooverlap"
3819 [(set (match_operand:SF 0 "register_operand" "=&Y")
3820 (float_truncate:SF
3821 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3822 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3823 "#"
3824 [(set_attr "type" "ssecvt")
3825 (set_attr "mode" "DF")])
3826
3827 (define_split
3828 [(set (match_operand:SF 0 "memory_operand" "")
3829 (float_truncate:SF
3830 (match_operand:DF 1 "register_operand" "")))
3831 (clobber (match_operand:SF 2 "memory_operand" ""))]
3832 "TARGET_80387"
3833 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3834 "")
3835
3836 ; Avoid possible reformatting penalty on the destination by first
3837 ; zeroing it out
3838 (define_split
3839 [(set (match_operand:SF 0 "register_operand" "")
3840 (float_truncate:SF
3841 (match_operand:DF 1 "nonimmediate_operand" "")))
3842 (clobber (match_operand 2 "" ""))]
3843 "TARGET_80387 && reload_completed
3844 && SSE_REG_P (operands[0])
3845 && !STACK_REG_P (operands[1])"
3846 [(const_int 0)]
3847 {
3848 rtx src, dest;
3849 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3850 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3851 else
3852 {
3853 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3854 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3855 /* simplify_gen_subreg refuses to widen memory references. */
3856 if (GET_CODE (src) == SUBREG)
3857 alter_subreg (&src);
3858 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3859 abort ();
3860 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3861 emit_insn (gen_cvtsd2ss (dest, dest, src));
3862 }
3863 DONE;
3864 })
3865
3866 (define_split
3867 [(set (match_operand:SF 0 "register_operand" "")
3868 (float_truncate:SF
3869 (match_operand:DF 1 "nonimmediate_operand" "")))]
3870 "TARGET_80387 && reload_completed
3871 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3872 [(const_int 0)]
3873 {
3874 rtx src, dest;
3875 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3876 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3877 /* simplify_gen_subreg refuses to widen memory references. */
3878 if (GET_CODE (src) == SUBREG)
3879 alter_subreg (&src);
3880 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3881 abort ();
3882 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3883 emit_insn (gen_cvtsd2ss (dest, dest, src));
3884 DONE;
3885 })
3886
3887 (define_split
3888 [(set (match_operand:SF 0 "register_operand" "")
3889 (float_truncate:SF
3890 (match_operand:DF 1 "fp_register_operand" "")))
3891 (clobber (match_operand:SF 2 "memory_operand" ""))]
3892 "TARGET_80387 && reload_completed"
3893 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3894 (set (match_dup 0) (match_dup 2))]
3895 "")
3896
3897 (define_expand "truncxfsf2"
3898 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3899 (float_truncate:SF
3900 (match_operand:XF 1 "register_operand" "")))
3901 (clobber (match_dup 2))])]
3902 "TARGET_80387"
3903 "
3904 if (flag_unsafe_math_optimizations)
3905 {
3906 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3907 emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3908 if (reg != operands[0])
3909 emit_move_insn (operands[0], reg);
3910 DONE;
3911 }
3912 else
3913 operands[2] = assign_386_stack_local (SFmode, 0);
3914 ")
3915
3916 (define_insn "truncxfsf2_noop"
3917 [(set (match_operand:SF 0 "register_operand" "=f")
3918 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3919 "TARGET_80387 && flag_unsafe_math_optimizations"
3920 "#")
3921
3922 (define_insn "*truncxfsf2_1"
3923 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3924 (float_truncate:SF
3925 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3926 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3927 "TARGET_80387"
3928 {
3929 switch (which_alternative)
3930 {
3931 case 0:
3932 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933 return "fstp%z0\t%y0";
3934 else
3935 return "fst%z0\t%y0";
3936 default:
3937 abort();
3938 }
3939 }
3940 [(set_attr "type" "fmov,multi,multi,multi")
3941 (set_attr "mode" "SF")])
3942
3943 (define_insn "*truncxfsf2_2"
3944 [(set (match_operand:SF 0 "memory_operand" "=m")
3945 (float_truncate:SF
3946 (match_operand:XF 1 "register_operand" "f")))]
3947 "TARGET_80387"
3948 {
3949 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3950 return "fstp%z0\t%y0";
3951 else
3952 return "fst%z0\t%y0";
3953 }
3954 [(set_attr "type" "fmov")
3955 (set_attr "mode" "SF")])
3956
3957 (define_split
3958 [(set (match_operand:SF 0 "memory_operand" "")
3959 (float_truncate:SF
3960 (match_operand:XF 1 "register_operand" "")))
3961 (clobber (match_operand:SF 2 "memory_operand" ""))]
3962 "TARGET_80387"
3963 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3964 "")
3965
3966 (define_split
3967 [(set (match_operand:SF 0 "register_operand" "")
3968 (float_truncate:SF
3969 (match_operand:XF 1 "register_operand" "")))
3970 (clobber (match_operand:SF 2 "memory_operand" ""))]
3971 "TARGET_80387 && reload_completed"
3972 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3973 (set (match_dup 0) (match_dup 2))]
3974 "")
3975
3976 (define_expand "truncxfdf2"
3977 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3978 (float_truncate:DF
3979 (match_operand:XF 1 "register_operand" "")))
3980 (clobber (match_dup 2))])]
3981 "TARGET_80387"
3982 "
3983 if (flag_unsafe_math_optimizations)
3984 {
3985 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3986 emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3987 if (reg != operands[0])
3988 emit_move_insn (operands[0], reg);
3989 DONE;
3990 }
3991 else
3992 operands[2] = assign_386_stack_local (DFmode, 0);
3993 ")
3994
3995 (define_insn "truncxfdf2_noop"
3996 [(set (match_operand:DF 0 "register_operand" "=f")
3997 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3998 "TARGET_80387 && flag_unsafe_math_optimizations"
3999 "#")
4000
4001 (define_insn "*truncxfdf2_1"
4002 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4003 (float_truncate:DF
4004 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4005 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4006 "TARGET_80387"
4007 {
4008 switch (which_alternative)
4009 {
4010 case 0:
4011 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4012 return "fstp%z0\t%y0";
4013 else
4014 return "fst%z0\t%y0";
4015 default:
4016 abort();
4017 }
4018 abort ();
4019 }
4020 [(set_attr "type" "fmov,multi,multi,multi")
4021 (set_attr "mode" "DF")])
4022
4023 (define_insn "*truncxfdf2_2"
4024 [(set (match_operand:DF 0 "memory_operand" "=m")
4025 (float_truncate:DF
4026 (match_operand:XF 1 "register_operand" "f")))]
4027 "TARGET_80387"
4028 {
4029 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4030 return "fstp%z0\t%y0";
4031 else
4032 return "fst%z0\t%y0";
4033 }
4034 [(set_attr "type" "fmov")
4035 (set_attr "mode" "DF")])
4036
4037 (define_split
4038 [(set (match_operand:DF 0 "memory_operand" "")
4039 (float_truncate:DF
4040 (match_operand:XF 1 "register_operand" "")))
4041 (clobber (match_operand:DF 2 "memory_operand" ""))]
4042 "TARGET_80387"
4043 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4044 "")
4045
4046 (define_split
4047 [(set (match_operand:DF 0 "register_operand" "")
4048 (float_truncate:DF
4049 (match_operand:XF 1 "register_operand" "")))
4050 (clobber (match_operand:DF 2 "memory_operand" ""))]
4051 "TARGET_80387 && reload_completed"
4052 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4053 (set (match_dup 0) (match_dup 2))]
4054 "")
4055
4056 \f
4057 ;; %%% Break up all these bad boys.
4058
4059 ;; Signed conversion to DImode.
4060
4061 (define_expand "fix_truncxfdi2"
4062 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4063 (fix:DI (match_operand:XF 1 "register_operand" "")))
4064 (clobber (reg:CC 17))])]
4065 "TARGET_80387"
4066 "")
4067
4068 (define_expand "fix_truncdfdi2"
4069 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4070 (fix:DI (match_operand:DF 1 "register_operand" "")))
4071 (clobber (reg:CC 17))])]
4072 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4073 {
4074 if (TARGET_64BIT && TARGET_SSE2)
4075 {
4076 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4077 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4078 if (out != operands[0])
4079 emit_move_insn (operands[0], out);
4080 DONE;
4081 }
4082 })
4083
4084 (define_expand "fix_truncsfdi2"
4085 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4086 (fix:DI (match_operand:SF 1 "register_operand" "")))
4087 (clobber (reg:CC 17))])]
4088 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4089 {
4090 if (TARGET_SSE && TARGET_64BIT)
4091 {
4092 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4093 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4094 if (out != operands[0])
4095 emit_move_insn (operands[0], out);
4096 DONE;
4097 }
4098 })
4099
4100 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4101 ;; of the machinery.
4102 (define_insn_and_split "*fix_truncdi_1"
4103 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4104 (fix:DI (match_operand 1 "register_operand" "f,f")))
4105 (clobber (reg:CC 17))]
4106 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4107 && !reload_completed && !reload_in_progress
4108 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4109 "#"
4110 "&& 1"
4111 [(const_int 0)]
4112 {
4113 ix86_optimize_mode_switching = 1;
4114 operands[2] = assign_386_stack_local (HImode, 1);
4115 operands[3] = assign_386_stack_local (HImode, 2);
4116 if (memory_operand (operands[0], VOIDmode))
4117 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4118 operands[2], operands[3]));
4119 else
4120 {
4121 operands[4] = assign_386_stack_local (DImode, 0);
4122 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4123 operands[2], operands[3],
4124 operands[4]));
4125 }
4126 DONE;
4127 }
4128 [(set_attr "type" "fistp")
4129 (set_attr "mode" "DI")])
4130
4131 (define_insn "fix_truncdi_nomemory"
4132 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4133 (fix:DI (match_operand 1 "register_operand" "f,f")))
4134 (use (match_operand:HI 2 "memory_operand" "m,m"))
4135 (use (match_operand:HI 3 "memory_operand" "m,m"))
4136 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4137 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4138 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4139 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4140 "#"
4141 [(set_attr "type" "fistp")
4142 (set_attr "mode" "DI")])
4143
4144 (define_insn "fix_truncdi_memory"
4145 [(set (match_operand:DI 0 "memory_operand" "=m")
4146 (fix:DI (match_operand 1 "register_operand" "f")))
4147 (use (match_operand:HI 2 "memory_operand" "m"))
4148 (use (match_operand:HI 3 "memory_operand" "m"))
4149 (clobber (match_scratch:DF 4 "=&1f"))]
4150 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4151 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4152 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4153 [(set_attr "type" "fistp")
4154 (set_attr "mode" "DI")])
4155
4156 (define_split
4157 [(set (match_operand:DI 0 "register_operand" "")
4158 (fix:DI (match_operand 1 "register_operand" "")))
4159 (use (match_operand:HI 2 "memory_operand" ""))
4160 (use (match_operand:HI 3 "memory_operand" ""))
4161 (clobber (match_operand:DI 4 "memory_operand" ""))
4162 (clobber (match_scratch 5 ""))]
4163 "reload_completed"
4164 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4165 (use (match_dup 2))
4166 (use (match_dup 3))
4167 (clobber (match_dup 5))])
4168 (set (match_dup 0) (match_dup 4))]
4169 "")
4170
4171 (define_split
4172 [(set (match_operand:DI 0 "memory_operand" "")
4173 (fix:DI (match_operand 1 "register_operand" "")))
4174 (use (match_operand:HI 2 "memory_operand" ""))
4175 (use (match_operand:HI 3 "memory_operand" ""))
4176 (clobber (match_operand:DI 4 "memory_operand" ""))
4177 (clobber (match_scratch 5 ""))]
4178 "reload_completed"
4179 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4180 (use (match_dup 2))
4181 (use (match_dup 3))
4182 (clobber (match_dup 5))])]
4183 "")
4184
4185 ;; When SSE available, it is always faster to use it!
4186 (define_insn "fix_truncsfdi_sse"
4187 [(set (match_operand:DI 0 "register_operand" "=r,r")
4188 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4189 "TARGET_64BIT && TARGET_SSE"
4190 "cvttss2si{q}\t{%1, %0|%0, %1}"
4191 [(set_attr "type" "sseicvt")
4192 (set_attr "mode" "SF")
4193 (set_attr "athlon_decode" "double,vector")])
4194
4195 ;; Avoid vector decoded form of the instruction.
4196 (define_peephole2
4197 [(match_scratch:SF 2 "x")
4198 (set (match_operand:DI 0 "register_operand" "")
4199 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4200 "TARGET_K8 && !optimize_size"
4201 [(set (match_dup 2) (match_dup 1))
4202 (set (match_dup 0) (fix:DI (match_dup 2)))]
4203 "")
4204
4205 (define_insn "fix_truncdfdi_sse"
4206 [(set (match_operand:DI 0 "register_operand" "=r,r")
4207 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4208 "TARGET_64BIT && TARGET_SSE2"
4209 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4210 [(set_attr "type" "sseicvt,sseicvt")
4211 (set_attr "mode" "DF")
4212 (set_attr "athlon_decode" "double,vector")])
4213
4214 ;; Avoid vector decoded form of the instruction.
4215 (define_peephole2
4216 [(match_scratch:DF 2 "Y")
4217 (set (match_operand:DI 0 "register_operand" "")
4218 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4219 "TARGET_K8 && !optimize_size"
4220 [(set (match_dup 2) (match_dup 1))
4221 (set (match_dup 0) (fix:DI (match_dup 2)))]
4222 "")
4223
4224 ;; Signed conversion to SImode.
4225
4226 (define_expand "fix_truncxfsi2"
4227 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4228 (fix:SI (match_operand:XF 1 "register_operand" "")))
4229 (clobber (reg:CC 17))])]
4230 "TARGET_80387"
4231 "")
4232
4233 (define_expand "fix_truncdfsi2"
4234 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4235 (fix:SI (match_operand:DF 1 "register_operand" "")))
4236 (clobber (reg:CC 17))])]
4237 "TARGET_80387 || TARGET_SSE2"
4238 {
4239 if (TARGET_SSE2)
4240 {
4241 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4242 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4243 if (out != operands[0])
4244 emit_move_insn (operands[0], out);
4245 DONE;
4246 }
4247 })
4248
4249 (define_expand "fix_truncsfsi2"
4250 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4251 (fix:SI (match_operand:SF 1 "register_operand" "")))
4252 (clobber (reg:CC 17))])]
4253 "TARGET_80387 || TARGET_SSE"
4254 {
4255 if (TARGET_SSE)
4256 {
4257 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4258 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4259 if (out != operands[0])
4260 emit_move_insn (operands[0], out);
4261 DONE;
4262 }
4263 })
4264
4265 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4266 ;; of the machinery.
4267 (define_insn_and_split "*fix_truncsi_1"
4268 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4269 (fix:SI (match_operand 1 "register_operand" "f,f")))
4270 (clobber (reg:CC 17))]
4271 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4272 && !reload_completed && !reload_in_progress
4273 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4274 "#"
4275 "&& 1"
4276 [(const_int 0)]
4277 {
4278 ix86_optimize_mode_switching = 1;
4279 operands[2] = assign_386_stack_local (HImode, 1);
4280 operands[3] = assign_386_stack_local (HImode, 2);
4281 if (memory_operand (operands[0], VOIDmode))
4282 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4283 operands[2], operands[3]));
4284 else
4285 {
4286 operands[4] = assign_386_stack_local (SImode, 0);
4287 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4288 operands[2], operands[3],
4289 operands[4]));
4290 }
4291 DONE;
4292 }
4293 [(set_attr "type" "fistp")
4294 (set_attr "mode" "SI")])
4295
4296 (define_insn "fix_truncsi_nomemory"
4297 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4298 (fix:SI (match_operand 1 "register_operand" "f,f")))
4299 (use (match_operand:HI 2 "memory_operand" "m,m"))
4300 (use (match_operand:HI 3 "memory_operand" "m,m"))
4301 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4302 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4303 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4304 "#"
4305 [(set_attr "type" "fistp")
4306 (set_attr "mode" "SI")])
4307
4308 (define_insn "fix_truncsi_memory"
4309 [(set (match_operand:SI 0 "memory_operand" "=m")
4310 (fix:SI (match_operand 1 "register_operand" "f")))
4311 (use (match_operand:HI 2 "memory_operand" "m"))
4312 (use (match_operand:HI 3 "memory_operand" "m"))]
4313 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4314 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4315 "* return output_fix_trunc (insn, operands);"
4316 [(set_attr "type" "fistp")
4317 (set_attr "mode" "SI")])
4318
4319 ;; When SSE available, it is always faster to use it!
4320 (define_insn "fix_truncsfsi_sse"
4321 [(set (match_operand:SI 0 "register_operand" "=r,r")
4322 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4323 "TARGET_SSE"
4324 "cvttss2si\t{%1, %0|%0, %1}"
4325 [(set_attr "type" "sseicvt")
4326 (set_attr "mode" "DF")
4327 (set_attr "athlon_decode" "double,vector")])
4328
4329 ;; Avoid vector decoded form of the instruction.
4330 (define_peephole2
4331 [(match_scratch:SF 2 "x")
4332 (set (match_operand:SI 0 "register_operand" "")
4333 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4334 "TARGET_K8 && !optimize_size"
4335 [(set (match_dup 2) (match_dup 1))
4336 (set (match_dup 0) (fix:SI (match_dup 2)))]
4337 "")
4338
4339 (define_insn "fix_truncdfsi_sse"
4340 [(set (match_operand:SI 0 "register_operand" "=r,r")
4341 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4342 "TARGET_SSE2"
4343 "cvttsd2si\t{%1, %0|%0, %1}"
4344 [(set_attr "type" "sseicvt")
4345 (set_attr "mode" "DF")
4346 (set_attr "athlon_decode" "double,vector")])
4347
4348 ;; Avoid vector decoded form of the instruction.
4349 (define_peephole2
4350 [(match_scratch:DF 2 "Y")
4351 (set (match_operand:SI 0 "register_operand" "")
4352 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4353 "TARGET_K8 && !optimize_size"
4354 [(set (match_dup 2) (match_dup 1))
4355 (set (match_dup 0) (fix:SI (match_dup 2)))]
4356 "")
4357
4358 (define_split
4359 [(set (match_operand:SI 0 "register_operand" "")
4360 (fix:SI (match_operand 1 "register_operand" "")))
4361 (use (match_operand:HI 2 "memory_operand" ""))
4362 (use (match_operand:HI 3 "memory_operand" ""))
4363 (clobber (match_operand:SI 4 "memory_operand" ""))]
4364 "reload_completed"
4365 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4366 (use (match_dup 2))
4367 (use (match_dup 3))])
4368 (set (match_dup 0) (match_dup 4))]
4369 "")
4370
4371 (define_split
4372 [(set (match_operand:SI 0 "memory_operand" "")
4373 (fix:SI (match_operand 1 "register_operand" "")))
4374 (use (match_operand:HI 2 "memory_operand" ""))
4375 (use (match_operand:HI 3 "memory_operand" ""))
4376 (clobber (match_operand:SI 4 "memory_operand" ""))]
4377 "reload_completed"
4378 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4379 (use (match_dup 2))
4380 (use (match_dup 3))])]
4381 "")
4382
4383 ;; Signed conversion to HImode.
4384
4385 (define_expand "fix_truncxfhi2"
4386 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4387 (fix:HI (match_operand:XF 1 "register_operand" "")))
4388 (clobber (reg:CC 17))])]
4389 "TARGET_80387"
4390 "")
4391
4392 (define_expand "fix_truncdfhi2"
4393 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4394 (fix:HI (match_operand:DF 1 "register_operand" "")))
4395 (clobber (reg:CC 17))])]
4396 "TARGET_80387 && !TARGET_SSE2"
4397 "")
4398
4399 (define_expand "fix_truncsfhi2"
4400 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4401 (fix:HI (match_operand:SF 1 "register_operand" "")))
4402 (clobber (reg:CC 17))])]
4403 "TARGET_80387 && !TARGET_SSE"
4404 "")
4405
4406 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4407 ;; of the machinery.
4408 (define_insn_and_split "*fix_trunchi_1"
4409 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4410 (fix:HI (match_operand 1 "register_operand" "f,f")))
4411 (clobber (reg:CC 17))]
4412 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4413 && !reload_completed && !reload_in_progress
4414 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4415 "#"
4416 ""
4417 [(const_int 0)]
4418 {
4419 ix86_optimize_mode_switching = 1;
4420 operands[2] = assign_386_stack_local (HImode, 1);
4421 operands[3] = assign_386_stack_local (HImode, 2);
4422 if (memory_operand (operands[0], VOIDmode))
4423 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4424 operands[2], operands[3]));
4425 else
4426 {
4427 operands[4] = assign_386_stack_local (HImode, 0);
4428 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4429 operands[2], operands[3],
4430 operands[4]));
4431 }
4432 DONE;
4433 }
4434 [(set_attr "type" "fistp")
4435 (set_attr "mode" "HI")])
4436
4437 (define_insn "fix_trunchi_nomemory"
4438 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4439 (fix:HI (match_operand 1 "register_operand" "f,f")))
4440 (use (match_operand:HI 2 "memory_operand" "m,m"))
4441 (use (match_operand:HI 3 "memory_operand" "m,m"))
4442 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4443 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4445 "#"
4446 [(set_attr "type" "fistp")
4447 (set_attr "mode" "HI")])
4448
4449 (define_insn "fix_trunchi_memory"
4450 [(set (match_operand:HI 0 "memory_operand" "=m")
4451 (fix:HI (match_operand 1 "register_operand" "f")))
4452 (use (match_operand:HI 2 "memory_operand" "m"))
4453 (use (match_operand:HI 3 "memory_operand" "m"))]
4454 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4455 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4456 "* return output_fix_trunc (insn, operands);"
4457 [(set_attr "type" "fistp")
4458 (set_attr "mode" "HI")])
4459
4460 (define_split
4461 [(set (match_operand:HI 0 "memory_operand" "")
4462 (fix:HI (match_operand 1 "register_operand" "")))
4463 (use (match_operand:HI 2 "memory_operand" ""))
4464 (use (match_operand:HI 3 "memory_operand" ""))
4465 (clobber (match_operand:HI 4 "memory_operand" ""))]
4466 "reload_completed"
4467 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4468 (use (match_dup 2))
4469 (use (match_dup 3))])]
4470 "")
4471
4472 (define_split
4473 [(set (match_operand:HI 0 "register_operand" "")
4474 (fix:HI (match_operand 1 "register_operand" "")))
4475 (use (match_operand:HI 2 "memory_operand" ""))
4476 (use (match_operand:HI 3 "memory_operand" ""))
4477 (clobber (match_operand:HI 4 "memory_operand" ""))]
4478 "reload_completed"
4479 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4480 (use (match_dup 2))
4481 (use (match_dup 3))
4482 (clobber (match_dup 4))])
4483 (set (match_dup 0) (match_dup 4))]
4484 "")
4485
4486 ;; %% Not used yet.
4487 (define_insn "x86_fnstcw_1"
4488 [(set (match_operand:HI 0 "memory_operand" "=m")
4489 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4490 "TARGET_80387"
4491 "fnstcw\t%0"
4492 [(set_attr "length" "2")
4493 (set_attr "mode" "HI")
4494 (set_attr "unit" "i387")])
4495
4496 (define_insn "x86_fldcw_1"
4497 [(set (reg:HI 18)
4498 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4499 "TARGET_80387"
4500 "fldcw\t%0"
4501 [(set_attr "length" "2")
4502 (set_attr "mode" "HI")
4503 (set_attr "unit" "i387")
4504 (set_attr "athlon_decode" "vector")])
4505 \f
4506 ;; Conversion between fixed point and floating point.
4507
4508 ;; Even though we only accept memory inputs, the backend _really_
4509 ;; wants to be able to do this between registers.
4510
4511 (define_expand "floathisf2"
4512 [(set (match_operand:SF 0 "register_operand" "")
4513 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4514 "TARGET_SSE || TARGET_80387"
4515 {
4516 if (TARGET_SSE && TARGET_SSE_MATH)
4517 {
4518 emit_insn (gen_floatsisf2 (operands[0],
4519 convert_to_mode (SImode, operands[1], 0)));
4520 DONE;
4521 }
4522 })
4523
4524 (define_insn "*floathisf2_1"
4525 [(set (match_operand:SF 0 "register_operand" "=f,f")
4526 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4527 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4528 "@
4529 fild%z1\t%1
4530 #"
4531 [(set_attr "type" "fmov,multi")
4532 (set_attr "mode" "SF")
4533 (set_attr "fp_int_src" "true")])
4534
4535 (define_expand "floatsisf2"
4536 [(set (match_operand:SF 0 "register_operand" "")
4537 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4538 "TARGET_SSE || TARGET_80387"
4539 "")
4540
4541 (define_insn "*floatsisf2_i387"
4542 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4543 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4544 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4545 "@
4546 fild%z1\t%1
4547 #
4548 cvtsi2ss\t{%1, %0|%0, %1}
4549 cvtsi2ss\t{%1, %0|%0, %1}"
4550 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4551 (set_attr "mode" "SF")
4552 (set_attr "athlon_decode" "*,*,vector,double")
4553 (set_attr "fp_int_src" "true")])
4554
4555 (define_insn "*floatsisf2_sse"
4556 [(set (match_operand:SF 0 "register_operand" "=x,x")
4557 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4558 "TARGET_SSE"
4559 "cvtsi2ss\t{%1, %0|%0, %1}"
4560 [(set_attr "type" "sseicvt")
4561 (set_attr "mode" "SF")
4562 (set_attr "athlon_decode" "vector,double")
4563 (set_attr "fp_int_src" "true")])
4564
4565 ; Avoid possible reformatting penalty on the destination by first
4566 ; zeroing it out
4567 (define_split
4568 [(set (match_operand:SF 0 "register_operand" "")
4569 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4570 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4571 && SSE_REG_P (operands[0])"
4572 [(const_int 0)]
4573 {
4574 rtx dest;
4575 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4576 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4577 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4578 DONE;
4579 })
4580
4581 (define_expand "floatdisf2"
4582 [(set (match_operand:SF 0 "register_operand" "")
4583 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4584 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4585 "")
4586
4587 (define_insn "*floatdisf2_i387_only"
4588 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4589 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4590 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4591 "@
4592 fild%z1\t%1
4593 #"
4594 [(set_attr "type" "fmov,multi")
4595 (set_attr "mode" "SF")
4596 (set_attr "fp_int_src" "true")])
4597
4598 (define_insn "*floatdisf2_i387"
4599 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4600 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4601 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4602 "@
4603 fild%z1\t%1
4604 #
4605 cvtsi2ss{q}\t{%1, %0|%0, %1}
4606 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4607 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4608 (set_attr "mode" "SF")
4609 (set_attr "athlon_decode" "*,*,vector,double")
4610 (set_attr "fp_int_src" "true")])
4611
4612 (define_insn "*floatdisf2_sse"
4613 [(set (match_operand:SF 0 "register_operand" "=x,x")
4614 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4615 "TARGET_64BIT && TARGET_SSE"
4616 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4617 [(set_attr "type" "sseicvt")
4618 (set_attr "mode" "SF")
4619 (set_attr "athlon_decode" "vector,double")
4620 (set_attr "fp_int_src" "true")])
4621
4622 ; Avoid possible reformatting penalty on the destination by first
4623 ; zeroing it out
4624 (define_split
4625 [(set (match_operand:SF 0 "register_operand" "")
4626 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4627 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4628 && SSE_REG_P (operands[0])"
4629 [(const_int 0)]
4630 {
4631 rtx dest;
4632 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4633 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4634 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4635 DONE;
4636 })
4637
4638 (define_expand "floathidf2"
4639 [(set (match_operand:DF 0 "register_operand" "")
4640 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4641 "TARGET_SSE2 || TARGET_80387"
4642 {
4643 if (TARGET_SSE && TARGET_SSE_MATH)
4644 {
4645 emit_insn (gen_floatsidf2 (operands[0],
4646 convert_to_mode (SImode, operands[1], 0)));
4647 DONE;
4648 }
4649 })
4650
4651 (define_insn "*floathidf2_1"
4652 [(set (match_operand:DF 0 "register_operand" "=f,f")
4653 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4654 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4655 "@
4656 fild%z1\t%1
4657 #"
4658 [(set_attr "type" "fmov,multi")
4659 (set_attr "mode" "DF")
4660 (set_attr "fp_int_src" "true")])
4661
4662 (define_expand "floatsidf2"
4663 [(set (match_operand:DF 0 "register_operand" "")
4664 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4665 "TARGET_80387 || TARGET_SSE2"
4666 "")
4667
4668 (define_insn "*floatsidf2_i387"
4669 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4670 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4671 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4672 "@
4673 fild%z1\t%1
4674 #
4675 cvtsi2sd\t{%1, %0|%0, %1}
4676 cvtsi2sd\t{%1, %0|%0, %1}"
4677 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4678 (set_attr "mode" "DF")
4679 (set_attr "athlon_decode" "*,*,double,direct")
4680 (set_attr "fp_int_src" "true")])
4681
4682 (define_insn "*floatsidf2_sse"
4683 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4684 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4685 "TARGET_SSE2"
4686 "cvtsi2sd\t{%1, %0|%0, %1}"
4687 [(set_attr "type" "sseicvt")
4688 (set_attr "mode" "DF")
4689 (set_attr "athlon_decode" "double,direct")
4690 (set_attr "fp_int_src" "true")])
4691
4692 (define_expand "floatdidf2"
4693 [(set (match_operand:DF 0 "register_operand" "")
4694 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4695 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4696 "")
4697
4698 (define_insn "*floatdidf2_i387_only"
4699 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4700 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4701 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4702 "@
4703 fild%z1\t%1
4704 #"
4705 [(set_attr "type" "fmov,multi")
4706 (set_attr "mode" "DF")
4707 (set_attr "fp_int_src" "true")])
4708
4709 (define_insn "*floatdidf2_i387"
4710 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4711 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4712 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4713 "@
4714 fild%z1\t%1
4715 #
4716 cvtsi2sd{q}\t{%1, %0|%0, %1}
4717 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4718 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4719 (set_attr "mode" "DF")
4720 (set_attr "athlon_decode" "*,*,double,direct")
4721 (set_attr "fp_int_src" "true")])
4722
4723 (define_insn "*floatdidf2_sse"
4724 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4725 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4726 "TARGET_SSE2"
4727 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4728 [(set_attr "type" "sseicvt")
4729 (set_attr "mode" "DF")
4730 (set_attr "athlon_decode" "double,direct")
4731 (set_attr "fp_int_src" "true")])
4732
4733 (define_insn "floathixf2"
4734 [(set (match_operand:XF 0 "register_operand" "=f,f")
4735 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4736 "TARGET_80387"
4737 "@
4738 fild%z1\t%1
4739 #"
4740 [(set_attr "type" "fmov,multi")
4741 (set_attr "mode" "XF")
4742 (set_attr "fp_int_src" "true")])
4743
4744 (define_insn "floatsixf2"
4745 [(set (match_operand:XF 0 "register_operand" "=f,f")
4746 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4747 "TARGET_80387"
4748 "@
4749 fild%z1\t%1
4750 #"
4751 [(set_attr "type" "fmov,multi")
4752 (set_attr "mode" "XF")
4753 (set_attr "fp_int_src" "true")])
4754
4755 (define_insn "floatdixf2"
4756 [(set (match_operand:XF 0 "register_operand" "=f,f")
4757 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4758 "TARGET_80387"
4759 "@
4760 fild%z1\t%1
4761 #"
4762 [(set_attr "type" "fmov,multi")
4763 (set_attr "mode" "XF")
4764 (set_attr "fp_int_src" "true")])
4765
4766 ;; %%% Kill these when reload knows how to do it.
4767 (define_split
4768 [(set (match_operand 0 "fp_register_operand" "")
4769 (float (match_operand 1 "register_operand" "")))]
4770 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4771 [(const_int 0)]
4772 {
4773 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4774 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4775 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4776 ix86_free_from_memory (GET_MODE (operands[1]));
4777 DONE;
4778 })
4779
4780 (define_expand "floatunssisf2"
4781 [(use (match_operand:SF 0 "register_operand" ""))
4782 (use (match_operand:SI 1 "register_operand" ""))]
4783 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4784 "x86_emit_floatuns (operands); DONE;")
4785
4786 (define_expand "floatunsdisf2"
4787 [(use (match_operand:SF 0 "register_operand" ""))
4788 (use (match_operand:DI 1 "register_operand" ""))]
4789 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4790 "x86_emit_floatuns (operands); DONE;")
4791
4792 (define_expand "floatunsdidf2"
4793 [(use (match_operand:DF 0 "register_operand" ""))
4794 (use (match_operand:DI 1 "register_operand" ""))]
4795 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4796 "x86_emit_floatuns (operands); DONE;")
4797 \f
4798 ;; SSE extract/set expanders
4799
4800 (define_expand "vec_setv2df"
4801 [(match_operand:V2DF 0 "register_operand" "")
4802 (match_operand:DF 1 "register_operand" "")
4803 (match_operand 2 "const_int_operand" "")]
4804 "TARGET_SSE2"
4805 {
4806 switch (INTVAL (operands[2]))
4807 {
4808 case 0:
4809 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4810 simplify_gen_subreg (V2DFmode, operands[1],
4811 DFmode, 0)));
4812 break;
4813 case 1:
4814 {
4815 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4816
4817 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4818 }
4819 break;
4820 default:
4821 abort ();
4822 }
4823 DONE;
4824 })
4825
4826 (define_expand "vec_extractv2df"
4827 [(match_operand:DF 0 "register_operand" "")
4828 (match_operand:V2DF 1 "register_operand" "")
4829 (match_operand 2 "const_int_operand" "")]
4830 "TARGET_SSE2"
4831 {
4832 switch (INTVAL (operands[2]))
4833 {
4834 case 0:
4835 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4836 break;
4837 case 1:
4838 {
4839 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4840
4841 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4842 }
4843 break;
4844 default:
4845 abort ();
4846 }
4847 DONE;
4848 })
4849
4850 (define_expand "vec_initv2df"
4851 [(match_operand:V2DF 0 "register_operand" "")
4852 (match_operand 1 "" "")]
4853 "TARGET_SSE2"
4854 {
4855 ix86_expand_vector_init (operands[0], operands[1]);
4856 DONE;
4857 })
4858
4859 (define_expand "vec_setv4sf"
4860 [(match_operand:V4SF 0 "register_operand" "")
4861 (match_operand:SF 1 "register_operand" "")
4862 (match_operand 2 "const_int_operand" "")]
4863 "TARGET_SSE"
4864 {
4865 switch (INTVAL (operands[2]))
4866 {
4867 case 0:
4868 emit_insn (gen_sse_movss (operands[0], operands[0],
4869 simplify_gen_subreg (V4SFmode, operands[1],
4870 SFmode, 0)));
4871 break;
4872 case 1:
4873 {
4874 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4875 rtx tmp = gen_reg_rtx (V4SFmode);
4876
4877 emit_move_insn (tmp, operands[0]);
4878 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4879 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4880 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4881 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4882 }
4883 case 2:
4884 {
4885 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4886 rtx tmp = gen_reg_rtx (V4SFmode);
4887
4888 emit_move_insn (tmp, operands[0]);
4889 emit_insn (gen_sse_movss (tmp, tmp, op1));
4890 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4891 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4892 }
4893 break;
4894 case 3:
4895 {
4896 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4897 rtx tmp = gen_reg_rtx (V4SFmode);
4898
4899 emit_move_insn (tmp, operands[0]);
4900 emit_insn (gen_sse_movss (tmp, tmp, op1));
4901 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4902 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4903 }
4904 break;
4905 default:
4906 abort ();
4907 }
4908 DONE;
4909 })
4910
4911 (define_expand "vec_extractv4sf"
4912 [(match_operand:SF 0 "register_operand" "")
4913 (match_operand:V4SF 1 "register_operand" "")
4914 (match_operand 2 "const_int_operand" "")]
4915 "TARGET_SSE"
4916 {
4917 switch (INTVAL (operands[2]))
4918 {
4919 case 0:
4920 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4921 break;
4922 case 1:
4923 {
4924 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4925 rtx tmp = gen_reg_rtx (V4SFmode);
4926
4927 emit_move_insn (tmp, operands[1]);
4928 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4929 const1_rtx));
4930 }
4931 case 2:
4932 {
4933 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4934 rtx tmp = gen_reg_rtx (V4SFmode);
4935
4936 emit_move_insn (tmp, operands[1]);
4937 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4938 }
4939 case 3:
4940 {
4941 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4942 rtx tmp = gen_reg_rtx (V4SFmode);
4943
4944 emit_move_insn (tmp, operands[1]);
4945 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4946 GEN_INT (3)));
4947 }
4948 default:
4949 abort ();
4950 }
4951 DONE;
4952 })
4953
4954 (define_expand "vec_initv4sf"
4955 [(match_operand:V4SF 0 "register_operand" "")
4956 (match_operand 1 "" "")]
4957 "TARGET_SSE"
4958 {
4959 ix86_expand_vector_init (operands[0], operands[1]);
4960 DONE;
4961 })
4962 \f
4963 ;; Add instructions
4964
4965 ;; %%% splits for addsidi3
4966 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4967 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4968 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4969
4970 (define_expand "adddi3"
4971 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4972 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4973 (match_operand:DI 2 "x86_64_general_operand" "")))
4974 (clobber (reg:CC 17))]
4975 ""
4976 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4977
4978 (define_insn "*adddi3_1"
4979 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4980 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4981 (match_operand:DI 2 "general_operand" "roiF,riF")))
4982 (clobber (reg:CC 17))]
4983 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4984 "#")
4985
4986 (define_split
4987 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4988 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4989 (match_operand:DI 2 "general_operand" "")))
4990 (clobber (reg:CC 17))]
4991 "!TARGET_64BIT && reload_completed"
4992 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4993 UNSPEC_ADD_CARRY))
4994 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4995 (parallel [(set (match_dup 3)
4996 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4997 (match_dup 4))
4998 (match_dup 5)))
4999 (clobber (reg:CC 17))])]
5000 "split_di (operands+0, 1, operands+0, operands+3);
5001 split_di (operands+1, 1, operands+1, operands+4);
5002 split_di (operands+2, 1, operands+2, operands+5);")
5003
5004 (define_insn "adddi3_carry_rex64"
5005 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5006 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5007 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5008 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5009 (clobber (reg:CC 17))]
5010 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5011 "adc{q}\t{%2, %0|%0, %2}"
5012 [(set_attr "type" "alu")
5013 (set_attr "pent_pair" "pu")
5014 (set_attr "mode" "DI")])
5015
5016 (define_insn "*adddi3_cc_rex64"
5017 [(set (reg:CC 17)
5018 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5019 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5020 UNSPEC_ADD_CARRY))
5021 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5022 (plus:DI (match_dup 1) (match_dup 2)))]
5023 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5024 "add{q}\t{%2, %0|%0, %2}"
5025 [(set_attr "type" "alu")
5026 (set_attr "mode" "DI")])
5027
5028 (define_insn "addqi3_carry"
5029 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5030 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5031 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5032 (match_operand:QI 2 "general_operand" "qi,qm")))
5033 (clobber (reg:CC 17))]
5034 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5035 "adc{b}\t{%2, %0|%0, %2}"
5036 [(set_attr "type" "alu")
5037 (set_attr "pent_pair" "pu")
5038 (set_attr "mode" "QI")])
5039
5040 (define_insn "addhi3_carry"
5041 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5042 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5043 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5044 (match_operand:HI 2 "general_operand" "ri,rm")))
5045 (clobber (reg:CC 17))]
5046 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5047 "adc{w}\t{%2, %0|%0, %2}"
5048 [(set_attr "type" "alu")
5049 (set_attr "pent_pair" "pu")
5050 (set_attr "mode" "HI")])
5051
5052 (define_insn "addsi3_carry"
5053 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5054 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5055 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5056 (match_operand:SI 2 "general_operand" "ri,rm")))
5057 (clobber (reg:CC 17))]
5058 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5059 "adc{l}\t{%2, %0|%0, %2}"
5060 [(set_attr "type" "alu")
5061 (set_attr "pent_pair" "pu")
5062 (set_attr "mode" "SI")])
5063
5064 (define_insn "*addsi3_carry_zext"
5065 [(set (match_operand:DI 0 "register_operand" "=r")
5066 (zero_extend:DI
5067 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5068 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5069 (match_operand:SI 2 "general_operand" "rim"))))
5070 (clobber (reg:CC 17))]
5071 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5072 "adc{l}\t{%2, %k0|%k0, %2}"
5073 [(set_attr "type" "alu")
5074 (set_attr "pent_pair" "pu")
5075 (set_attr "mode" "SI")])
5076
5077 (define_insn "*addsi3_cc"
5078 [(set (reg:CC 17)
5079 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5080 (match_operand:SI 2 "general_operand" "ri,rm")]
5081 UNSPEC_ADD_CARRY))
5082 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5083 (plus:SI (match_dup 1) (match_dup 2)))]
5084 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5085 "add{l}\t{%2, %0|%0, %2}"
5086 [(set_attr "type" "alu")
5087 (set_attr "mode" "SI")])
5088
5089 (define_insn "addqi3_cc"
5090 [(set (reg:CC 17)
5091 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5092 (match_operand:QI 2 "general_operand" "qi,qm")]
5093 UNSPEC_ADD_CARRY))
5094 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5095 (plus:QI (match_dup 1) (match_dup 2)))]
5096 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5097 "add{b}\t{%2, %0|%0, %2}"
5098 [(set_attr "type" "alu")
5099 (set_attr "mode" "QI")])
5100
5101 (define_expand "addsi3"
5102 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5103 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5104 (match_operand:SI 2 "general_operand" "")))
5105 (clobber (reg:CC 17))])]
5106 ""
5107 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5108
5109 (define_insn "*lea_1"
5110 [(set (match_operand:SI 0 "register_operand" "=r")
5111 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5112 "!TARGET_64BIT"
5113 "lea{l}\t{%a1, %0|%0, %a1}"
5114 [(set_attr "type" "lea")
5115 (set_attr "mode" "SI")])
5116
5117 (define_insn "*lea_1_rex64"
5118 [(set (match_operand:SI 0 "register_operand" "=r")
5119 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5120 "TARGET_64BIT"
5121 "lea{l}\t{%a1, %0|%0, %a1}"
5122 [(set_attr "type" "lea")
5123 (set_attr "mode" "SI")])
5124
5125 (define_insn "*lea_1_zext"
5126 [(set (match_operand:DI 0 "register_operand" "=r")
5127 (zero_extend:DI
5128 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5129 "TARGET_64BIT"
5130 "lea{l}\t{%a1, %k0|%k0, %a1}"
5131 [(set_attr "type" "lea")
5132 (set_attr "mode" "SI")])
5133
5134 (define_insn "*lea_2_rex64"
5135 [(set (match_operand:DI 0 "register_operand" "=r")
5136 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5137 "TARGET_64BIT"
5138 "lea{q}\t{%a1, %0|%0, %a1}"
5139 [(set_attr "type" "lea")
5140 (set_attr "mode" "DI")])
5141
5142 ;; The lea patterns for non-Pmodes needs to be matched by several
5143 ;; insns converted to real lea by splitters.
5144
5145 (define_insn_and_split "*lea_general_1"
5146 [(set (match_operand 0 "register_operand" "=r")
5147 (plus (plus (match_operand 1 "index_register_operand" "r")
5148 (match_operand 2 "register_operand" "r"))
5149 (match_operand 3 "immediate_operand" "i")))]
5150 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5151 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5152 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5153 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5154 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5155 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5156 || GET_MODE (operands[3]) == VOIDmode)"
5157 "#"
5158 "&& reload_completed"
5159 [(const_int 0)]
5160 {
5161 rtx pat;
5162 operands[0] = gen_lowpart (SImode, operands[0]);
5163 operands[1] = gen_lowpart (Pmode, operands[1]);
5164 operands[2] = gen_lowpart (Pmode, operands[2]);
5165 operands[3] = gen_lowpart (Pmode, operands[3]);
5166 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5167 operands[3]);
5168 if (Pmode != SImode)
5169 pat = gen_rtx_SUBREG (SImode, pat, 0);
5170 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5171 DONE;
5172 }
5173 [(set_attr "type" "lea")
5174 (set_attr "mode" "SI")])
5175
5176 (define_insn_and_split "*lea_general_1_zext"
5177 [(set (match_operand:DI 0 "register_operand" "=r")
5178 (zero_extend:DI
5179 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5180 (match_operand:SI 2 "register_operand" "r"))
5181 (match_operand:SI 3 "immediate_operand" "i"))))]
5182 "TARGET_64BIT"
5183 "#"
5184 "&& reload_completed"
5185 [(set (match_dup 0)
5186 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5187 (match_dup 2))
5188 (match_dup 3)) 0)))]
5189 {
5190 operands[1] = gen_lowpart (Pmode, operands[1]);
5191 operands[2] = gen_lowpart (Pmode, operands[2]);
5192 operands[3] = gen_lowpart (Pmode, operands[3]);
5193 }
5194 [(set_attr "type" "lea")
5195 (set_attr "mode" "SI")])
5196
5197 (define_insn_and_split "*lea_general_2"
5198 [(set (match_operand 0 "register_operand" "=r")
5199 (plus (mult (match_operand 1 "index_register_operand" "r")
5200 (match_operand 2 "const248_operand" "i"))
5201 (match_operand 3 "nonmemory_operand" "ri")))]
5202 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5203 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5204 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5205 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5206 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5207 || GET_MODE (operands[3]) == VOIDmode)"
5208 "#"
5209 "&& reload_completed"
5210 [(const_int 0)]
5211 {
5212 rtx pat;
5213 operands[0] = gen_lowpart (SImode, operands[0]);
5214 operands[1] = gen_lowpart (Pmode, operands[1]);
5215 operands[3] = gen_lowpart (Pmode, operands[3]);
5216 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5217 operands[3]);
5218 if (Pmode != SImode)
5219 pat = gen_rtx_SUBREG (SImode, pat, 0);
5220 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5221 DONE;
5222 }
5223 [(set_attr "type" "lea")
5224 (set_attr "mode" "SI")])
5225
5226 (define_insn_and_split "*lea_general_2_zext"
5227 [(set (match_operand:DI 0 "register_operand" "=r")
5228 (zero_extend:DI
5229 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5230 (match_operand:SI 2 "const248_operand" "n"))
5231 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5232 "TARGET_64BIT"
5233 "#"
5234 "&& reload_completed"
5235 [(set (match_dup 0)
5236 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5237 (match_dup 2))
5238 (match_dup 3)) 0)))]
5239 {
5240 operands[1] = gen_lowpart (Pmode, operands[1]);
5241 operands[3] = gen_lowpart (Pmode, operands[3]);
5242 }
5243 [(set_attr "type" "lea")
5244 (set_attr "mode" "SI")])
5245
5246 (define_insn_and_split "*lea_general_3"
5247 [(set (match_operand 0 "register_operand" "=r")
5248 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5249 (match_operand 2 "const248_operand" "i"))
5250 (match_operand 3 "register_operand" "r"))
5251 (match_operand 4 "immediate_operand" "i")))]
5252 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5253 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5254 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5255 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5256 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5257 "#"
5258 "&& reload_completed"
5259 [(const_int 0)]
5260 {
5261 rtx pat;
5262 operands[0] = gen_lowpart (SImode, operands[0]);
5263 operands[1] = gen_lowpart (Pmode, operands[1]);
5264 operands[3] = gen_lowpart (Pmode, operands[3]);
5265 operands[4] = gen_lowpart (Pmode, operands[4]);
5266 pat = gen_rtx_PLUS (Pmode,
5267 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5268 operands[2]),
5269 operands[3]),
5270 operands[4]);
5271 if (Pmode != SImode)
5272 pat = gen_rtx_SUBREG (SImode, pat, 0);
5273 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5274 DONE;
5275 }
5276 [(set_attr "type" "lea")
5277 (set_attr "mode" "SI")])
5278
5279 (define_insn_and_split "*lea_general_3_zext"
5280 [(set (match_operand:DI 0 "register_operand" "=r")
5281 (zero_extend:DI
5282 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5283 (match_operand:SI 2 "const248_operand" "n"))
5284 (match_operand:SI 3 "register_operand" "r"))
5285 (match_operand:SI 4 "immediate_operand" "i"))))]
5286 "TARGET_64BIT"
5287 "#"
5288 "&& reload_completed"
5289 [(set (match_dup 0)
5290 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5291 (match_dup 2))
5292 (match_dup 3))
5293 (match_dup 4)) 0)))]
5294 {
5295 operands[1] = gen_lowpart (Pmode, operands[1]);
5296 operands[3] = gen_lowpart (Pmode, operands[3]);
5297 operands[4] = gen_lowpart (Pmode, operands[4]);
5298 }
5299 [(set_attr "type" "lea")
5300 (set_attr "mode" "SI")])
5301
5302 (define_insn "*adddi_1_rex64"
5303 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5304 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5305 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5306 (clobber (reg:CC 17))]
5307 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5308 {
5309 switch (get_attr_type (insn))
5310 {
5311 case TYPE_LEA:
5312 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5313 return "lea{q}\t{%a2, %0|%0, %a2}";
5314
5315 case TYPE_INCDEC:
5316 if (! rtx_equal_p (operands[0], operands[1]))
5317 abort ();
5318 if (operands[2] == const1_rtx)
5319 return "inc{q}\t%0";
5320 else if (operands[2] == constm1_rtx)
5321 return "dec{q}\t%0";
5322 else
5323 abort ();
5324
5325 default:
5326 if (! rtx_equal_p (operands[0], operands[1]))
5327 abort ();
5328
5329 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5330 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5331 if (GET_CODE (operands[2]) == CONST_INT
5332 /* Avoid overflows. */
5333 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5334 && (INTVAL (operands[2]) == 128
5335 || (INTVAL (operands[2]) < 0
5336 && INTVAL (operands[2]) != -128)))
5337 {
5338 operands[2] = GEN_INT (-INTVAL (operands[2]));
5339 return "sub{q}\t{%2, %0|%0, %2}";
5340 }
5341 return "add{q}\t{%2, %0|%0, %2}";
5342 }
5343 }
5344 [(set (attr "type")
5345 (cond [(eq_attr "alternative" "2")
5346 (const_string "lea")
5347 ; Current assemblers are broken and do not allow @GOTOFF in
5348 ; ought but a memory context.
5349 (match_operand:DI 2 "pic_symbolic_operand" "")
5350 (const_string "lea")
5351 (match_operand:DI 2 "incdec_operand" "")
5352 (const_string "incdec")
5353 ]
5354 (const_string "alu")))
5355 (set_attr "mode" "DI")])
5356
5357 ;; Convert lea to the lea pattern to avoid flags dependency.
5358 (define_split
5359 [(set (match_operand:DI 0 "register_operand" "")
5360 (plus:DI (match_operand:DI 1 "register_operand" "")
5361 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5362 (clobber (reg:CC 17))]
5363 "TARGET_64BIT && reload_completed
5364 && true_regnum (operands[0]) != true_regnum (operands[1])"
5365 [(set (match_dup 0)
5366 (plus:DI (match_dup 1)
5367 (match_dup 2)))]
5368 "")
5369
5370 (define_insn "*adddi_2_rex64"
5371 [(set (reg 17)
5372 (compare
5373 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5374 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5375 (const_int 0)))
5376 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5377 (plus:DI (match_dup 1) (match_dup 2)))]
5378 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5379 && ix86_binary_operator_ok (PLUS, DImode, operands)
5380 /* Current assemblers are broken and do not allow @GOTOFF in
5381 ought but a memory context. */
5382 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5383 {
5384 switch (get_attr_type (insn))
5385 {
5386 case TYPE_INCDEC:
5387 if (! rtx_equal_p (operands[0], operands[1]))
5388 abort ();
5389 if (operands[2] == const1_rtx)
5390 return "inc{q}\t%0";
5391 else if (operands[2] == constm1_rtx)
5392 return "dec{q}\t%0";
5393 else
5394 abort ();
5395
5396 default:
5397 if (! rtx_equal_p (operands[0], operands[1]))
5398 abort ();
5399 /* ???? We ought to handle there the 32bit case too
5400 - do we need new constraint? */
5401 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5402 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5403 if (GET_CODE (operands[2]) == CONST_INT
5404 /* Avoid overflows. */
5405 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5406 && (INTVAL (operands[2]) == 128
5407 || (INTVAL (operands[2]) < 0
5408 && INTVAL (operands[2]) != -128)))
5409 {
5410 operands[2] = GEN_INT (-INTVAL (operands[2]));
5411 return "sub{q}\t{%2, %0|%0, %2}";
5412 }
5413 return "add{q}\t{%2, %0|%0, %2}";
5414 }
5415 }
5416 [(set (attr "type")
5417 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5418 (const_string "incdec")
5419 (const_string "alu")))
5420 (set_attr "mode" "DI")])
5421
5422 (define_insn "*adddi_3_rex64"
5423 [(set (reg 17)
5424 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5425 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5426 (clobber (match_scratch:DI 0 "=r"))]
5427 "TARGET_64BIT
5428 && ix86_match_ccmode (insn, CCZmode)
5429 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5430 /* Current assemblers are broken and do not allow @GOTOFF in
5431 ought but a memory context. */
5432 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5433 {
5434 switch (get_attr_type (insn))
5435 {
5436 case TYPE_INCDEC:
5437 if (! rtx_equal_p (operands[0], operands[1]))
5438 abort ();
5439 if (operands[2] == const1_rtx)
5440 return "inc{q}\t%0";
5441 else if (operands[2] == constm1_rtx)
5442 return "dec{q}\t%0";
5443 else
5444 abort ();
5445
5446 default:
5447 if (! rtx_equal_p (operands[0], operands[1]))
5448 abort ();
5449 /* ???? We ought to handle there the 32bit case too
5450 - do we need new constraint? */
5451 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5453 if (GET_CODE (operands[2]) == CONST_INT
5454 /* Avoid overflows. */
5455 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5456 && (INTVAL (operands[2]) == 128
5457 || (INTVAL (operands[2]) < 0
5458 && INTVAL (operands[2]) != -128)))
5459 {
5460 operands[2] = GEN_INT (-INTVAL (operands[2]));
5461 return "sub{q}\t{%2, %0|%0, %2}";
5462 }
5463 return "add{q}\t{%2, %0|%0, %2}";
5464 }
5465 }
5466 [(set (attr "type")
5467 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5468 (const_string "incdec")
5469 (const_string "alu")))
5470 (set_attr "mode" "DI")])
5471
5472 ; For comparisons against 1, -1 and 128, we may generate better code
5473 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5474 ; is matched then. We can't accept general immediate, because for
5475 ; case of overflows, the result is messed up.
5476 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5477 ; when negated.
5478 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5479 ; only for comparisons not depending on it.
5480 (define_insn "*adddi_4_rex64"
5481 [(set (reg 17)
5482 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5483 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5484 (clobber (match_scratch:DI 0 "=rm"))]
5485 "TARGET_64BIT
5486 && ix86_match_ccmode (insn, CCGCmode)"
5487 {
5488 switch (get_attr_type (insn))
5489 {
5490 case TYPE_INCDEC:
5491 if (operands[2] == constm1_rtx)
5492 return "inc{q}\t%0";
5493 else if (operands[2] == const1_rtx)
5494 return "dec{q}\t%0";
5495 else
5496 abort();
5497
5498 default:
5499 if (! rtx_equal_p (operands[0], operands[1]))
5500 abort ();
5501 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5502 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5503 if ((INTVAL (operands[2]) == -128
5504 || (INTVAL (operands[2]) > 0
5505 && INTVAL (operands[2]) != 128))
5506 /* Avoid overflows. */
5507 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5508 return "sub{q}\t{%2, %0|%0, %2}";
5509 operands[2] = GEN_INT (-INTVAL (operands[2]));
5510 return "add{q}\t{%2, %0|%0, %2}";
5511 }
5512 }
5513 [(set (attr "type")
5514 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5515 (const_string "incdec")
5516 (const_string "alu")))
5517 (set_attr "mode" "DI")])
5518
5519 (define_insn "*adddi_5_rex64"
5520 [(set (reg 17)
5521 (compare
5522 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5523 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5524 (const_int 0)))
5525 (clobber (match_scratch:DI 0 "=r"))]
5526 "TARGET_64BIT
5527 && ix86_match_ccmode (insn, CCGOCmode)
5528 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5529 /* Current assemblers are broken and do not allow @GOTOFF in
5530 ought but a memory context. */
5531 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5532 {
5533 switch (get_attr_type (insn))
5534 {
5535 case TYPE_INCDEC:
5536 if (! rtx_equal_p (operands[0], operands[1]))
5537 abort ();
5538 if (operands[2] == const1_rtx)
5539 return "inc{q}\t%0";
5540 else if (operands[2] == constm1_rtx)
5541 return "dec{q}\t%0";
5542 else
5543 abort();
5544
5545 default:
5546 if (! rtx_equal_p (operands[0], operands[1]))
5547 abort ();
5548 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5549 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5550 if (GET_CODE (operands[2]) == CONST_INT
5551 /* Avoid overflows. */
5552 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5553 && (INTVAL (operands[2]) == 128
5554 || (INTVAL (operands[2]) < 0
5555 && INTVAL (operands[2]) != -128)))
5556 {
5557 operands[2] = GEN_INT (-INTVAL (operands[2]));
5558 return "sub{q}\t{%2, %0|%0, %2}";
5559 }
5560 return "add{q}\t{%2, %0|%0, %2}";
5561 }
5562 }
5563 [(set (attr "type")
5564 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5565 (const_string "incdec")
5566 (const_string "alu")))
5567 (set_attr "mode" "DI")])
5568
5569
5570 (define_insn "*addsi_1"
5571 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5572 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5573 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5574 (clobber (reg:CC 17))]
5575 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5576 {
5577 switch (get_attr_type (insn))
5578 {
5579 case TYPE_LEA:
5580 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5581 return "lea{l}\t{%a2, %0|%0, %a2}";
5582
5583 case TYPE_INCDEC:
5584 if (! rtx_equal_p (operands[0], operands[1]))
5585 abort ();
5586 if (operands[2] == const1_rtx)
5587 return "inc{l}\t%0";
5588 else if (operands[2] == constm1_rtx)
5589 return "dec{l}\t%0";
5590 else
5591 abort();
5592
5593 default:
5594 if (! rtx_equal_p (operands[0], operands[1]))
5595 abort ();
5596
5597 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5598 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5599 if (GET_CODE (operands[2]) == CONST_INT
5600 && (INTVAL (operands[2]) == 128
5601 || (INTVAL (operands[2]) < 0
5602 && INTVAL (operands[2]) != -128)))
5603 {
5604 operands[2] = GEN_INT (-INTVAL (operands[2]));
5605 return "sub{l}\t{%2, %0|%0, %2}";
5606 }
5607 return "add{l}\t{%2, %0|%0, %2}";
5608 }
5609 }
5610 [(set (attr "type")
5611 (cond [(eq_attr "alternative" "2")
5612 (const_string "lea")
5613 ; Current assemblers are broken and do not allow @GOTOFF in
5614 ; ought but a memory context.
5615 (match_operand:SI 2 "pic_symbolic_operand" "")
5616 (const_string "lea")
5617 (match_operand:SI 2 "incdec_operand" "")
5618 (const_string "incdec")
5619 ]
5620 (const_string "alu")))
5621 (set_attr "mode" "SI")])
5622
5623 ;; Convert lea to the lea pattern to avoid flags dependency.
5624 (define_split
5625 [(set (match_operand 0 "register_operand" "")
5626 (plus (match_operand 1 "register_operand" "")
5627 (match_operand 2 "nonmemory_operand" "")))
5628 (clobber (reg:CC 17))]
5629 "reload_completed
5630 && true_regnum (operands[0]) != true_regnum (operands[1])"
5631 [(const_int 0)]
5632 {
5633 rtx pat;
5634 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5635 may confuse gen_lowpart. */
5636 if (GET_MODE (operands[0]) != Pmode)
5637 {
5638 operands[1] = gen_lowpart (Pmode, operands[1]);
5639 operands[2] = gen_lowpart (Pmode, operands[2]);
5640 }
5641 operands[0] = gen_lowpart (SImode, operands[0]);
5642 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5643 if (Pmode != SImode)
5644 pat = gen_rtx_SUBREG (SImode, pat, 0);
5645 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5646 DONE;
5647 })
5648
5649 ;; It may seem that nonimmediate operand is proper one for operand 1.
5650 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5651 ;; we take care in ix86_binary_operator_ok to not allow two memory
5652 ;; operands so proper swapping will be done in reload. This allow
5653 ;; patterns constructed from addsi_1 to match.
5654 (define_insn "addsi_1_zext"
5655 [(set (match_operand:DI 0 "register_operand" "=r,r")
5656 (zero_extend:DI
5657 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5658 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5659 (clobber (reg:CC 17))]
5660 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5661 {
5662 switch (get_attr_type (insn))
5663 {
5664 case TYPE_LEA:
5665 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5666 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5667
5668 case TYPE_INCDEC:
5669 if (operands[2] == const1_rtx)
5670 return "inc{l}\t%k0";
5671 else if (operands[2] == constm1_rtx)
5672 return "dec{l}\t%k0";
5673 else
5674 abort();
5675
5676 default:
5677 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5678 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5679 if (GET_CODE (operands[2]) == CONST_INT
5680 && (INTVAL (operands[2]) == 128
5681 || (INTVAL (operands[2]) < 0
5682 && INTVAL (operands[2]) != -128)))
5683 {
5684 operands[2] = GEN_INT (-INTVAL (operands[2]));
5685 return "sub{l}\t{%2, %k0|%k0, %2}";
5686 }
5687 return "add{l}\t{%2, %k0|%k0, %2}";
5688 }
5689 }
5690 [(set (attr "type")
5691 (cond [(eq_attr "alternative" "1")
5692 (const_string "lea")
5693 ; Current assemblers are broken and do not allow @GOTOFF in
5694 ; ought but a memory context.
5695 (match_operand:SI 2 "pic_symbolic_operand" "")
5696 (const_string "lea")
5697 (match_operand:SI 2 "incdec_operand" "")
5698 (const_string "incdec")
5699 ]
5700 (const_string "alu")))
5701 (set_attr "mode" "SI")])
5702
5703 ;; Convert lea to the lea pattern to avoid flags dependency.
5704 (define_split
5705 [(set (match_operand:DI 0 "register_operand" "")
5706 (zero_extend:DI
5707 (plus:SI (match_operand:SI 1 "register_operand" "")
5708 (match_operand:SI 2 "nonmemory_operand" ""))))
5709 (clobber (reg:CC 17))]
5710 "TARGET_64BIT && reload_completed
5711 && true_regnum (operands[0]) != true_regnum (operands[1])"
5712 [(set (match_dup 0)
5713 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5714 {
5715 operands[1] = gen_lowpart (Pmode, operands[1]);
5716 operands[2] = gen_lowpart (Pmode, operands[2]);
5717 })
5718
5719 (define_insn "*addsi_2"
5720 [(set (reg 17)
5721 (compare
5722 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5723 (match_operand:SI 2 "general_operand" "rmni,rni"))
5724 (const_int 0)))
5725 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5726 (plus:SI (match_dup 1) (match_dup 2)))]
5727 "ix86_match_ccmode (insn, CCGOCmode)
5728 && ix86_binary_operator_ok (PLUS, SImode, operands)
5729 /* Current assemblers are broken and do not allow @GOTOFF in
5730 ought but a memory context. */
5731 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5732 {
5733 switch (get_attr_type (insn))
5734 {
5735 case TYPE_INCDEC:
5736 if (! rtx_equal_p (operands[0], operands[1]))
5737 abort ();
5738 if (operands[2] == const1_rtx)
5739 return "inc{l}\t%0";
5740 else if (operands[2] == constm1_rtx)
5741 return "dec{l}\t%0";
5742 else
5743 abort();
5744
5745 default:
5746 if (! rtx_equal_p (operands[0], operands[1]))
5747 abort ();
5748 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5749 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5750 if (GET_CODE (operands[2]) == CONST_INT
5751 && (INTVAL (operands[2]) == 128
5752 || (INTVAL (operands[2]) < 0
5753 && INTVAL (operands[2]) != -128)))
5754 {
5755 operands[2] = GEN_INT (-INTVAL (operands[2]));
5756 return "sub{l}\t{%2, %0|%0, %2}";
5757 }
5758 return "add{l}\t{%2, %0|%0, %2}";
5759 }
5760 }
5761 [(set (attr "type")
5762 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5763 (const_string "incdec")
5764 (const_string "alu")))
5765 (set_attr "mode" "SI")])
5766
5767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5768 (define_insn "*addsi_2_zext"
5769 [(set (reg 17)
5770 (compare
5771 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5772 (match_operand:SI 2 "general_operand" "rmni"))
5773 (const_int 0)))
5774 (set (match_operand:DI 0 "register_operand" "=r")
5775 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5776 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5777 && ix86_binary_operator_ok (PLUS, SImode, operands)
5778 /* Current assemblers are broken and do not allow @GOTOFF in
5779 ought but a memory context. */
5780 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5781 {
5782 switch (get_attr_type (insn))
5783 {
5784 case TYPE_INCDEC:
5785 if (operands[2] == const1_rtx)
5786 return "inc{l}\t%k0";
5787 else if (operands[2] == constm1_rtx)
5788 return "dec{l}\t%k0";
5789 else
5790 abort();
5791
5792 default:
5793 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5794 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5795 if (GET_CODE (operands[2]) == CONST_INT
5796 && (INTVAL (operands[2]) == 128
5797 || (INTVAL (operands[2]) < 0
5798 && INTVAL (operands[2]) != -128)))
5799 {
5800 operands[2] = GEN_INT (-INTVAL (operands[2]));
5801 return "sub{l}\t{%2, %k0|%k0, %2}";
5802 }
5803 return "add{l}\t{%2, %k0|%k0, %2}";
5804 }
5805 }
5806 [(set (attr "type")
5807 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5808 (const_string "incdec")
5809 (const_string "alu")))
5810 (set_attr "mode" "SI")])
5811
5812 (define_insn "*addsi_3"
5813 [(set (reg 17)
5814 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5815 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5816 (clobber (match_scratch:SI 0 "=r"))]
5817 "ix86_match_ccmode (insn, CCZmode)
5818 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5819 /* Current assemblers are broken and do not allow @GOTOFF in
5820 ought but a memory context. */
5821 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5822 {
5823 switch (get_attr_type (insn))
5824 {
5825 case TYPE_INCDEC:
5826 if (! rtx_equal_p (operands[0], operands[1]))
5827 abort ();
5828 if (operands[2] == const1_rtx)
5829 return "inc{l}\t%0";
5830 else if (operands[2] == constm1_rtx)
5831 return "dec{l}\t%0";
5832 else
5833 abort();
5834
5835 default:
5836 if (! rtx_equal_p (operands[0], operands[1]))
5837 abort ();
5838 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5839 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5840 if (GET_CODE (operands[2]) == CONST_INT
5841 && (INTVAL (operands[2]) == 128
5842 || (INTVAL (operands[2]) < 0
5843 && INTVAL (operands[2]) != -128)))
5844 {
5845 operands[2] = GEN_INT (-INTVAL (operands[2]));
5846 return "sub{l}\t{%2, %0|%0, %2}";
5847 }
5848 return "add{l}\t{%2, %0|%0, %2}";
5849 }
5850 }
5851 [(set (attr "type")
5852 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5853 (const_string "incdec")
5854 (const_string "alu")))
5855 (set_attr "mode" "SI")])
5856
5857 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5858 (define_insn "*addsi_3_zext"
5859 [(set (reg 17)
5860 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5861 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5862 (set (match_operand:DI 0 "register_operand" "=r")
5863 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5864 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5865 && ix86_binary_operator_ok (PLUS, SImode, operands)
5866 /* Current assemblers are broken and do not allow @GOTOFF in
5867 ought but a memory context. */
5868 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5869 {
5870 switch (get_attr_type (insn))
5871 {
5872 case TYPE_INCDEC:
5873 if (operands[2] == const1_rtx)
5874 return "inc{l}\t%k0";
5875 else if (operands[2] == constm1_rtx)
5876 return "dec{l}\t%k0";
5877 else
5878 abort();
5879
5880 default:
5881 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5882 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5883 if (GET_CODE (operands[2]) == CONST_INT
5884 && (INTVAL (operands[2]) == 128
5885 || (INTVAL (operands[2]) < 0
5886 && INTVAL (operands[2]) != -128)))
5887 {
5888 operands[2] = GEN_INT (-INTVAL (operands[2]));
5889 return "sub{l}\t{%2, %k0|%k0, %2}";
5890 }
5891 return "add{l}\t{%2, %k0|%k0, %2}";
5892 }
5893 }
5894 [(set (attr "type")
5895 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5896 (const_string "incdec")
5897 (const_string "alu")))
5898 (set_attr "mode" "SI")])
5899
5900 ; For comparisons against 1, -1 and 128, we may generate better code
5901 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5902 ; is matched then. We can't accept general immediate, because for
5903 ; case of overflows, the result is messed up.
5904 ; This pattern also don't hold of 0x80000000, since the value overflows
5905 ; when negated.
5906 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5907 ; only for comparisons not depending on it.
5908 (define_insn "*addsi_4"
5909 [(set (reg 17)
5910 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5911 (match_operand:SI 2 "const_int_operand" "n")))
5912 (clobber (match_scratch:SI 0 "=rm"))]
5913 "ix86_match_ccmode (insn, CCGCmode)
5914 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5915 {
5916 switch (get_attr_type (insn))
5917 {
5918 case TYPE_INCDEC:
5919 if (operands[2] == constm1_rtx)
5920 return "inc{l}\t%0";
5921 else if (operands[2] == const1_rtx)
5922 return "dec{l}\t%0";
5923 else
5924 abort();
5925
5926 default:
5927 if (! rtx_equal_p (operands[0], operands[1]))
5928 abort ();
5929 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5930 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5931 if ((INTVAL (operands[2]) == -128
5932 || (INTVAL (operands[2]) > 0
5933 && INTVAL (operands[2]) != 128)))
5934 return "sub{l}\t{%2, %0|%0, %2}";
5935 operands[2] = GEN_INT (-INTVAL (operands[2]));
5936 return "add{l}\t{%2, %0|%0, %2}";
5937 }
5938 }
5939 [(set (attr "type")
5940 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5941 (const_string "incdec")
5942 (const_string "alu")))
5943 (set_attr "mode" "SI")])
5944
5945 (define_insn "*addsi_5"
5946 [(set (reg 17)
5947 (compare
5948 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5949 (match_operand:SI 2 "general_operand" "rmni"))
5950 (const_int 0)))
5951 (clobber (match_scratch:SI 0 "=r"))]
5952 "ix86_match_ccmode (insn, CCGOCmode)
5953 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5954 /* Current assemblers are broken and do not allow @GOTOFF in
5955 ought but a memory context. */
5956 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5957 {
5958 switch (get_attr_type (insn))
5959 {
5960 case TYPE_INCDEC:
5961 if (! rtx_equal_p (operands[0], operands[1]))
5962 abort ();
5963 if (operands[2] == const1_rtx)
5964 return "inc{l}\t%0";
5965 else if (operands[2] == constm1_rtx)
5966 return "dec{l}\t%0";
5967 else
5968 abort();
5969
5970 default:
5971 if (! rtx_equal_p (operands[0], operands[1]))
5972 abort ();
5973 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5974 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5975 if (GET_CODE (operands[2]) == CONST_INT
5976 && (INTVAL (operands[2]) == 128
5977 || (INTVAL (operands[2]) < 0
5978 && INTVAL (operands[2]) != -128)))
5979 {
5980 operands[2] = GEN_INT (-INTVAL (operands[2]));
5981 return "sub{l}\t{%2, %0|%0, %2}";
5982 }
5983 return "add{l}\t{%2, %0|%0, %2}";
5984 }
5985 }
5986 [(set (attr "type")
5987 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5988 (const_string "incdec")
5989 (const_string "alu")))
5990 (set_attr "mode" "SI")])
5991
5992 (define_expand "addhi3"
5993 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5994 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5995 (match_operand:HI 2 "general_operand" "")))
5996 (clobber (reg:CC 17))])]
5997 "TARGET_HIMODE_MATH"
5998 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5999
6000 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6001 ;; type optimizations enabled by define-splits. This is not important
6002 ;; for PII, and in fact harmful because of partial register stalls.
6003
6004 (define_insn "*addhi_1_lea"
6005 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6006 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6007 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6008 (clobber (reg:CC 17))]
6009 "!TARGET_PARTIAL_REG_STALL
6010 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6011 {
6012 switch (get_attr_type (insn))
6013 {
6014 case TYPE_LEA:
6015 return "#";
6016 case TYPE_INCDEC:
6017 if (operands[2] == const1_rtx)
6018 return "inc{w}\t%0";
6019 else if (operands[2] == constm1_rtx)
6020 return "dec{w}\t%0";
6021 abort();
6022
6023 default:
6024 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6025 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6026 if (GET_CODE (operands[2]) == CONST_INT
6027 && (INTVAL (operands[2]) == 128
6028 || (INTVAL (operands[2]) < 0
6029 && INTVAL (operands[2]) != -128)))
6030 {
6031 operands[2] = GEN_INT (-INTVAL (operands[2]));
6032 return "sub{w}\t{%2, %0|%0, %2}";
6033 }
6034 return "add{w}\t{%2, %0|%0, %2}";
6035 }
6036 }
6037 [(set (attr "type")
6038 (if_then_else (eq_attr "alternative" "2")
6039 (const_string "lea")
6040 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6041 (const_string "incdec")
6042 (const_string "alu"))))
6043 (set_attr "mode" "HI,HI,SI")])
6044
6045 (define_insn "*addhi_1"
6046 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6047 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6048 (match_operand:HI 2 "general_operand" "ri,rm")))
6049 (clobber (reg:CC 17))]
6050 "TARGET_PARTIAL_REG_STALL
6051 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6052 {
6053 switch (get_attr_type (insn))
6054 {
6055 case TYPE_INCDEC:
6056 if (operands[2] == const1_rtx)
6057 return "inc{w}\t%0";
6058 else if (operands[2] == constm1_rtx)
6059 return "dec{w}\t%0";
6060 abort();
6061
6062 default:
6063 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6064 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6065 if (GET_CODE (operands[2]) == CONST_INT
6066 && (INTVAL (operands[2]) == 128
6067 || (INTVAL (operands[2]) < 0
6068 && INTVAL (operands[2]) != -128)))
6069 {
6070 operands[2] = GEN_INT (-INTVAL (operands[2]));
6071 return "sub{w}\t{%2, %0|%0, %2}";
6072 }
6073 return "add{w}\t{%2, %0|%0, %2}";
6074 }
6075 }
6076 [(set (attr "type")
6077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078 (const_string "incdec")
6079 (const_string "alu")))
6080 (set_attr "mode" "HI")])
6081
6082 (define_insn "*addhi_2"
6083 [(set (reg 17)
6084 (compare
6085 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6086 (match_operand:HI 2 "general_operand" "rmni,rni"))
6087 (const_int 0)))
6088 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6089 (plus:HI (match_dup 1) (match_dup 2)))]
6090 "ix86_match_ccmode (insn, CCGOCmode)
6091 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6092 {
6093 switch (get_attr_type (insn))
6094 {
6095 case TYPE_INCDEC:
6096 if (operands[2] == const1_rtx)
6097 return "inc{w}\t%0";
6098 else if (operands[2] == constm1_rtx)
6099 return "dec{w}\t%0";
6100 abort();
6101
6102 default:
6103 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6104 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6105 if (GET_CODE (operands[2]) == CONST_INT
6106 && (INTVAL (operands[2]) == 128
6107 || (INTVAL (operands[2]) < 0
6108 && INTVAL (operands[2]) != -128)))
6109 {
6110 operands[2] = GEN_INT (-INTVAL (operands[2]));
6111 return "sub{w}\t{%2, %0|%0, %2}";
6112 }
6113 return "add{w}\t{%2, %0|%0, %2}";
6114 }
6115 }
6116 [(set (attr "type")
6117 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6118 (const_string "incdec")
6119 (const_string "alu")))
6120 (set_attr "mode" "HI")])
6121
6122 (define_insn "*addhi_3"
6123 [(set (reg 17)
6124 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6125 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6126 (clobber (match_scratch:HI 0 "=r"))]
6127 "ix86_match_ccmode (insn, CCZmode)
6128 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6129 {
6130 switch (get_attr_type (insn))
6131 {
6132 case TYPE_INCDEC:
6133 if (operands[2] == const1_rtx)
6134 return "inc{w}\t%0";
6135 else if (operands[2] == constm1_rtx)
6136 return "dec{w}\t%0";
6137 abort();
6138
6139 default:
6140 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6142 if (GET_CODE (operands[2]) == CONST_INT
6143 && (INTVAL (operands[2]) == 128
6144 || (INTVAL (operands[2]) < 0
6145 && INTVAL (operands[2]) != -128)))
6146 {
6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 return "sub{w}\t{%2, %0|%0, %2}";
6149 }
6150 return "add{w}\t{%2, %0|%0, %2}";
6151 }
6152 }
6153 [(set (attr "type")
6154 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6155 (const_string "incdec")
6156 (const_string "alu")))
6157 (set_attr "mode" "HI")])
6158
6159 ; See comments above addsi_3_imm for details.
6160 (define_insn "*addhi_4"
6161 [(set (reg 17)
6162 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6163 (match_operand:HI 2 "const_int_operand" "n")))
6164 (clobber (match_scratch:HI 0 "=rm"))]
6165 "ix86_match_ccmode (insn, CCGCmode)
6166 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6167 {
6168 switch (get_attr_type (insn))
6169 {
6170 case TYPE_INCDEC:
6171 if (operands[2] == constm1_rtx)
6172 return "inc{w}\t%0";
6173 else if (operands[2] == const1_rtx)
6174 return "dec{w}\t%0";
6175 else
6176 abort();
6177
6178 default:
6179 if (! rtx_equal_p (operands[0], operands[1]))
6180 abort ();
6181 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6182 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6183 if ((INTVAL (operands[2]) == -128
6184 || (INTVAL (operands[2]) > 0
6185 && INTVAL (operands[2]) != 128)))
6186 return "sub{w}\t{%2, %0|%0, %2}";
6187 operands[2] = GEN_INT (-INTVAL (operands[2]));
6188 return "add{w}\t{%2, %0|%0, %2}";
6189 }
6190 }
6191 [(set (attr "type")
6192 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6193 (const_string "incdec")
6194 (const_string "alu")))
6195 (set_attr "mode" "SI")])
6196
6197
6198 (define_insn "*addhi_5"
6199 [(set (reg 17)
6200 (compare
6201 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6202 (match_operand:HI 2 "general_operand" "rmni"))
6203 (const_int 0)))
6204 (clobber (match_scratch:HI 0 "=r"))]
6205 "ix86_match_ccmode (insn, CCGOCmode)
6206 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6207 {
6208 switch (get_attr_type (insn))
6209 {
6210 case TYPE_INCDEC:
6211 if (operands[2] == const1_rtx)
6212 return "inc{w}\t%0";
6213 else if (operands[2] == constm1_rtx)
6214 return "dec{w}\t%0";
6215 abort();
6216
6217 default:
6218 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6219 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6220 if (GET_CODE (operands[2]) == CONST_INT
6221 && (INTVAL (operands[2]) == 128
6222 || (INTVAL (operands[2]) < 0
6223 && INTVAL (operands[2]) != -128)))
6224 {
6225 operands[2] = GEN_INT (-INTVAL (operands[2]));
6226 return "sub{w}\t{%2, %0|%0, %2}";
6227 }
6228 return "add{w}\t{%2, %0|%0, %2}";
6229 }
6230 }
6231 [(set (attr "type")
6232 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6233 (const_string "incdec")
6234 (const_string "alu")))
6235 (set_attr "mode" "HI")])
6236
6237 (define_expand "addqi3"
6238 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6239 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6240 (match_operand:QI 2 "general_operand" "")))
6241 (clobber (reg:CC 17))])]
6242 "TARGET_QIMODE_MATH"
6243 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6244
6245 ;; %%% Potential partial reg stall on alternative 2. What to do?
6246 (define_insn "*addqi_1_lea"
6247 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6248 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6249 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6250 (clobber (reg:CC 17))]
6251 "!TARGET_PARTIAL_REG_STALL
6252 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6253 {
6254 int widen = (which_alternative == 2);
6255 switch (get_attr_type (insn))
6256 {
6257 case TYPE_LEA:
6258 return "#";
6259 case TYPE_INCDEC:
6260 if (operands[2] == const1_rtx)
6261 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6262 else if (operands[2] == constm1_rtx)
6263 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6264 abort();
6265
6266 default:
6267 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6268 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6269 if (GET_CODE (operands[2]) == CONST_INT
6270 && (INTVAL (operands[2]) == 128
6271 || (INTVAL (operands[2]) < 0
6272 && INTVAL (operands[2]) != -128)))
6273 {
6274 operands[2] = GEN_INT (-INTVAL (operands[2]));
6275 if (widen)
6276 return "sub{l}\t{%2, %k0|%k0, %2}";
6277 else
6278 return "sub{b}\t{%2, %0|%0, %2}";
6279 }
6280 if (widen)
6281 return "add{l}\t{%k2, %k0|%k0, %k2}";
6282 else
6283 return "add{b}\t{%2, %0|%0, %2}";
6284 }
6285 }
6286 [(set (attr "type")
6287 (if_then_else (eq_attr "alternative" "3")
6288 (const_string "lea")
6289 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6290 (const_string "incdec")
6291 (const_string "alu"))))
6292 (set_attr "mode" "QI,QI,SI,SI")])
6293
6294 (define_insn "*addqi_1"
6295 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6296 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6297 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6298 (clobber (reg:CC 17))]
6299 "TARGET_PARTIAL_REG_STALL
6300 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6301 {
6302 int widen = (which_alternative == 2);
6303 switch (get_attr_type (insn))
6304 {
6305 case TYPE_INCDEC:
6306 if (operands[2] == const1_rtx)
6307 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6308 else if (operands[2] == constm1_rtx)
6309 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6310 abort();
6311
6312 default:
6313 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6314 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6315 if (GET_CODE (operands[2]) == CONST_INT
6316 && (INTVAL (operands[2]) == 128
6317 || (INTVAL (operands[2]) < 0
6318 && INTVAL (operands[2]) != -128)))
6319 {
6320 operands[2] = GEN_INT (-INTVAL (operands[2]));
6321 if (widen)
6322 return "sub{l}\t{%2, %k0|%k0, %2}";
6323 else
6324 return "sub{b}\t{%2, %0|%0, %2}";
6325 }
6326 if (widen)
6327 return "add{l}\t{%k2, %k0|%k0, %k2}";
6328 else
6329 return "add{b}\t{%2, %0|%0, %2}";
6330 }
6331 }
6332 [(set (attr "type")
6333 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6334 (const_string "incdec")
6335 (const_string "alu")))
6336 (set_attr "mode" "QI,QI,SI")])
6337
6338 (define_insn "*addqi_1_slp"
6339 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6340 (plus:QI (match_dup 0)
6341 (match_operand:QI 1 "general_operand" "qn,qnm")))
6342 (clobber (reg:CC 17))]
6343 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6344 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6345 {
6346 switch (get_attr_type (insn))
6347 {
6348 case TYPE_INCDEC:
6349 if (operands[1] == const1_rtx)
6350 return "inc{b}\t%0";
6351 else if (operands[1] == constm1_rtx)
6352 return "dec{b}\t%0";
6353 abort();
6354
6355 default:
6356 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6357 if (GET_CODE (operands[1]) == CONST_INT
6358 && INTVAL (operands[1]) < 0)
6359 {
6360 operands[1] = GEN_INT (-INTVAL (operands[1]));
6361 return "sub{b}\t{%1, %0|%0, %1}";
6362 }
6363 return "add{b}\t{%1, %0|%0, %1}";
6364 }
6365 }
6366 [(set (attr "type")
6367 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6368 (const_string "incdec")
6369 (const_string "alu1")))
6370 (set_attr "mode" "QI")])
6371
6372 (define_insn "*addqi_2"
6373 [(set (reg 17)
6374 (compare
6375 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6376 (match_operand:QI 2 "general_operand" "qmni,qni"))
6377 (const_int 0)))
6378 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6379 (plus:QI (match_dup 1) (match_dup 2)))]
6380 "ix86_match_ccmode (insn, CCGOCmode)
6381 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6382 {
6383 switch (get_attr_type (insn))
6384 {
6385 case TYPE_INCDEC:
6386 if (operands[2] == const1_rtx)
6387 return "inc{b}\t%0";
6388 else if (operands[2] == constm1_rtx
6389 || (GET_CODE (operands[2]) == CONST_INT
6390 && INTVAL (operands[2]) == 255))
6391 return "dec{b}\t%0";
6392 abort();
6393
6394 default:
6395 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6396 if (GET_CODE (operands[2]) == CONST_INT
6397 && INTVAL (operands[2]) < 0)
6398 {
6399 operands[2] = GEN_INT (-INTVAL (operands[2]));
6400 return "sub{b}\t{%2, %0|%0, %2}";
6401 }
6402 return "add{b}\t{%2, %0|%0, %2}";
6403 }
6404 }
6405 [(set (attr "type")
6406 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407 (const_string "incdec")
6408 (const_string "alu")))
6409 (set_attr "mode" "QI")])
6410
6411 (define_insn "*addqi_3"
6412 [(set (reg 17)
6413 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6414 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6415 (clobber (match_scratch:QI 0 "=q"))]
6416 "ix86_match_ccmode (insn, CCZmode)
6417 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6418 {
6419 switch (get_attr_type (insn))
6420 {
6421 case TYPE_INCDEC:
6422 if (operands[2] == const1_rtx)
6423 return "inc{b}\t%0";
6424 else if (operands[2] == constm1_rtx
6425 || (GET_CODE (operands[2]) == CONST_INT
6426 && INTVAL (operands[2]) == 255))
6427 return "dec{b}\t%0";
6428 abort();
6429
6430 default:
6431 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6432 if (GET_CODE (operands[2]) == CONST_INT
6433 && INTVAL (operands[2]) < 0)
6434 {
6435 operands[2] = GEN_INT (-INTVAL (operands[2]));
6436 return "sub{b}\t{%2, %0|%0, %2}";
6437 }
6438 return "add{b}\t{%2, %0|%0, %2}";
6439 }
6440 }
6441 [(set (attr "type")
6442 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6443 (const_string "incdec")
6444 (const_string "alu")))
6445 (set_attr "mode" "QI")])
6446
6447 ; See comments above addsi_3_imm for details.
6448 (define_insn "*addqi_4"
6449 [(set (reg 17)
6450 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6451 (match_operand:QI 2 "const_int_operand" "n")))
6452 (clobber (match_scratch:QI 0 "=qm"))]
6453 "ix86_match_ccmode (insn, CCGCmode)
6454 && (INTVAL (operands[2]) & 0xff) != 0x80"
6455 {
6456 switch (get_attr_type (insn))
6457 {
6458 case TYPE_INCDEC:
6459 if (operands[2] == constm1_rtx
6460 || (GET_CODE (operands[2]) == CONST_INT
6461 && INTVAL (operands[2]) == 255))
6462 return "inc{b}\t%0";
6463 else if (operands[2] == const1_rtx)
6464 return "dec{b}\t%0";
6465 else
6466 abort();
6467
6468 default:
6469 if (! rtx_equal_p (operands[0], operands[1]))
6470 abort ();
6471 if (INTVAL (operands[2]) < 0)
6472 {
6473 operands[2] = GEN_INT (-INTVAL (operands[2]));
6474 return "add{b}\t{%2, %0|%0, %2}";
6475 }
6476 return "sub{b}\t{%2, %0|%0, %2}";
6477 }
6478 }
6479 [(set (attr "type")
6480 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6481 (const_string "incdec")
6482 (const_string "alu")))
6483 (set_attr "mode" "QI")])
6484
6485
6486 (define_insn "*addqi_5"
6487 [(set (reg 17)
6488 (compare
6489 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6490 (match_operand:QI 2 "general_operand" "qmni"))
6491 (const_int 0)))
6492 (clobber (match_scratch:QI 0 "=q"))]
6493 "ix86_match_ccmode (insn, CCGOCmode)
6494 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6495 {
6496 switch (get_attr_type (insn))
6497 {
6498 case TYPE_INCDEC:
6499 if (operands[2] == const1_rtx)
6500 return "inc{b}\t%0";
6501 else if (operands[2] == constm1_rtx
6502 || (GET_CODE (operands[2]) == CONST_INT
6503 && INTVAL (operands[2]) == 255))
6504 return "dec{b}\t%0";
6505 abort();
6506
6507 default:
6508 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6509 if (GET_CODE (operands[2]) == CONST_INT
6510 && INTVAL (operands[2]) < 0)
6511 {
6512 operands[2] = GEN_INT (-INTVAL (operands[2]));
6513 return "sub{b}\t{%2, %0|%0, %2}";
6514 }
6515 return "add{b}\t{%2, %0|%0, %2}";
6516 }
6517 }
6518 [(set (attr "type")
6519 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6520 (const_string "incdec")
6521 (const_string "alu")))
6522 (set_attr "mode" "QI")])
6523
6524
6525 (define_insn "addqi_ext_1"
6526 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6527 (const_int 8)
6528 (const_int 8))
6529 (plus:SI
6530 (zero_extract:SI
6531 (match_operand 1 "ext_register_operand" "0")
6532 (const_int 8)
6533 (const_int 8))
6534 (match_operand:QI 2 "general_operand" "Qmn")))
6535 (clobber (reg:CC 17))]
6536 "!TARGET_64BIT"
6537 {
6538 switch (get_attr_type (insn))
6539 {
6540 case TYPE_INCDEC:
6541 if (operands[2] == const1_rtx)
6542 return "inc{b}\t%h0";
6543 else if (operands[2] == constm1_rtx
6544 || (GET_CODE (operands[2]) == CONST_INT
6545 && INTVAL (operands[2]) == 255))
6546 return "dec{b}\t%h0";
6547 abort();
6548
6549 default:
6550 return "add{b}\t{%2, %h0|%h0, %2}";
6551 }
6552 }
6553 [(set (attr "type")
6554 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6555 (const_string "incdec")
6556 (const_string "alu")))
6557 (set_attr "mode" "QI")])
6558
6559 (define_insn "*addqi_ext_1_rex64"
6560 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6561 (const_int 8)
6562 (const_int 8))
6563 (plus:SI
6564 (zero_extract:SI
6565 (match_operand 1 "ext_register_operand" "0")
6566 (const_int 8)
6567 (const_int 8))
6568 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6569 (clobber (reg:CC 17))]
6570 "TARGET_64BIT"
6571 {
6572 switch (get_attr_type (insn))
6573 {
6574 case TYPE_INCDEC:
6575 if (operands[2] == const1_rtx)
6576 return "inc{b}\t%h0";
6577 else if (operands[2] == constm1_rtx
6578 || (GET_CODE (operands[2]) == CONST_INT
6579 && INTVAL (operands[2]) == 255))
6580 return "dec{b}\t%h0";
6581 abort();
6582
6583 default:
6584 return "add{b}\t{%2, %h0|%h0, %2}";
6585 }
6586 }
6587 [(set (attr "type")
6588 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6589 (const_string "incdec")
6590 (const_string "alu")))
6591 (set_attr "mode" "QI")])
6592
6593 (define_insn "*addqi_ext_2"
6594 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6595 (const_int 8)
6596 (const_int 8))
6597 (plus:SI
6598 (zero_extract:SI
6599 (match_operand 1 "ext_register_operand" "%0")
6600 (const_int 8)
6601 (const_int 8))
6602 (zero_extract:SI
6603 (match_operand 2 "ext_register_operand" "Q")
6604 (const_int 8)
6605 (const_int 8))))
6606 (clobber (reg:CC 17))]
6607 ""
6608 "add{b}\t{%h2, %h0|%h0, %h2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "mode" "QI")])
6611
6612 ;; The patterns that match these are at the end of this file.
6613
6614 (define_expand "addxf3"
6615 [(set (match_operand:XF 0 "register_operand" "")
6616 (plus:XF (match_operand:XF 1 "register_operand" "")
6617 (match_operand:XF 2 "register_operand" "")))]
6618 "TARGET_80387"
6619 "")
6620
6621 (define_expand "adddf3"
6622 [(set (match_operand:DF 0 "register_operand" "")
6623 (plus:DF (match_operand:DF 1 "register_operand" "")
6624 (match_operand:DF 2 "nonimmediate_operand" "")))]
6625 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6626 "")
6627
6628 (define_expand "addsf3"
6629 [(set (match_operand:SF 0 "register_operand" "")
6630 (plus:SF (match_operand:SF 1 "register_operand" "")
6631 (match_operand:SF 2 "nonimmediate_operand" "")))]
6632 "TARGET_80387 || TARGET_SSE_MATH"
6633 "")
6634 \f
6635 ;; Subtract instructions
6636
6637 ;; %%% splits for subsidi3
6638
6639 (define_expand "subdi3"
6640 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6641 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6642 (match_operand:DI 2 "x86_64_general_operand" "")))
6643 (clobber (reg:CC 17))])]
6644 ""
6645 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6646
6647 (define_insn "*subdi3_1"
6648 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6649 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6650 (match_operand:DI 2 "general_operand" "roiF,riF")))
6651 (clobber (reg:CC 17))]
6652 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6653 "#")
6654
6655 (define_split
6656 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6657 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6658 (match_operand:DI 2 "general_operand" "")))
6659 (clobber (reg:CC 17))]
6660 "!TARGET_64BIT && reload_completed"
6661 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6662 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6663 (parallel [(set (match_dup 3)
6664 (minus:SI (match_dup 4)
6665 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6666 (match_dup 5))))
6667 (clobber (reg:CC 17))])]
6668 "split_di (operands+0, 1, operands+0, operands+3);
6669 split_di (operands+1, 1, operands+1, operands+4);
6670 split_di (operands+2, 1, operands+2, operands+5);")
6671
6672 (define_insn "subdi3_carry_rex64"
6673 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6674 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6675 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6676 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6677 (clobber (reg:CC 17))]
6678 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6679 "sbb{q}\t{%2, %0|%0, %2}"
6680 [(set_attr "type" "alu")
6681 (set_attr "pent_pair" "pu")
6682 (set_attr "mode" "DI")])
6683
6684 (define_insn "*subdi_1_rex64"
6685 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6686 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6687 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6688 (clobber (reg:CC 17))]
6689 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6690 "sub{q}\t{%2, %0|%0, %2}"
6691 [(set_attr "type" "alu")
6692 (set_attr "mode" "DI")])
6693
6694 (define_insn "*subdi_2_rex64"
6695 [(set (reg 17)
6696 (compare
6697 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6698 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6699 (const_int 0)))
6700 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6701 (minus:DI (match_dup 1) (match_dup 2)))]
6702 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6703 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6704 "sub{q}\t{%2, %0|%0, %2}"
6705 [(set_attr "type" "alu")
6706 (set_attr "mode" "DI")])
6707
6708 (define_insn "*subdi_3_rex63"
6709 [(set (reg 17)
6710 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6711 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6712 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6713 (minus:DI (match_dup 1) (match_dup 2)))]
6714 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6715 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6716 "sub{q}\t{%2, %0|%0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "DI")])
6719
6720 (define_insn "subqi3_carry"
6721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6722 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6723 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6724 (match_operand:QI 2 "general_operand" "qi,qm"))))
6725 (clobber (reg:CC 17))]
6726 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6727 "sbb{b}\t{%2, %0|%0, %2}"
6728 [(set_attr "type" "alu")
6729 (set_attr "pent_pair" "pu")
6730 (set_attr "mode" "QI")])
6731
6732 (define_insn "subhi3_carry"
6733 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6734 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6735 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6736 (match_operand:HI 2 "general_operand" "ri,rm"))))
6737 (clobber (reg:CC 17))]
6738 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6739 "sbb{w}\t{%2, %0|%0, %2}"
6740 [(set_attr "type" "alu")
6741 (set_attr "pent_pair" "pu")
6742 (set_attr "mode" "HI")])
6743
6744 (define_insn "subsi3_carry"
6745 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6746 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6747 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6748 (match_operand:SI 2 "general_operand" "ri,rm"))))
6749 (clobber (reg:CC 17))]
6750 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6751 "sbb{l}\t{%2, %0|%0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "pent_pair" "pu")
6754 (set_attr "mode" "SI")])
6755
6756 (define_insn "subsi3_carry_zext"
6757 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6758 (zero_extend:DI
6759 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6760 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6761 (match_operand:SI 2 "general_operand" "ri,rm")))))
6762 (clobber (reg:CC 17))]
6763 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6764 "sbb{l}\t{%2, %k0|%k0, %2}"
6765 [(set_attr "type" "alu")
6766 (set_attr "pent_pair" "pu")
6767 (set_attr "mode" "SI")])
6768
6769 (define_expand "subsi3"
6770 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6771 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6772 (match_operand:SI 2 "general_operand" "")))
6773 (clobber (reg:CC 17))])]
6774 ""
6775 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6776
6777 (define_insn "*subsi_1"
6778 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6779 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6780 (match_operand:SI 2 "general_operand" "ri,rm")))
6781 (clobber (reg:CC 17))]
6782 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6783 "sub{l}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "SI")])
6786
6787 (define_insn "*subsi_1_zext"
6788 [(set (match_operand:DI 0 "register_operand" "=r")
6789 (zero_extend:DI
6790 (minus:SI (match_operand:SI 1 "register_operand" "0")
6791 (match_operand:SI 2 "general_operand" "rim"))))
6792 (clobber (reg:CC 17))]
6793 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6794 "sub{l}\t{%2, %k0|%k0, %2}"
6795 [(set_attr "type" "alu")
6796 (set_attr "mode" "SI")])
6797
6798 (define_insn "*subsi_2"
6799 [(set (reg 17)
6800 (compare
6801 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:SI 2 "general_operand" "ri,rm"))
6803 (const_int 0)))
6804 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6805 (minus:SI (match_dup 1) (match_dup 2)))]
6806 "ix86_match_ccmode (insn, CCGOCmode)
6807 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6808 "sub{l}\t{%2, %0|%0, %2}"
6809 [(set_attr "type" "alu")
6810 (set_attr "mode" "SI")])
6811
6812 (define_insn "*subsi_2_zext"
6813 [(set (reg 17)
6814 (compare
6815 (minus:SI (match_operand:SI 1 "register_operand" "0")
6816 (match_operand:SI 2 "general_operand" "rim"))
6817 (const_int 0)))
6818 (set (match_operand:DI 0 "register_operand" "=r")
6819 (zero_extend:DI
6820 (minus:SI (match_dup 1)
6821 (match_dup 2))))]
6822 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6823 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6824 "sub{l}\t{%2, %k0|%k0, %2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "SI")])
6827
6828 (define_insn "*subsi_3"
6829 [(set (reg 17)
6830 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6831 (match_operand:SI 2 "general_operand" "ri,rm")))
6832 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6833 (minus:SI (match_dup 1) (match_dup 2)))]
6834 "ix86_match_ccmode (insn, CCmode)
6835 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6836 "sub{l}\t{%2, %0|%0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "mode" "SI")])
6839
6840 (define_insn "*subsi_3_zext"
6841 [(set (reg 17)
6842 (compare (match_operand:SI 1 "register_operand" "0")
6843 (match_operand:SI 2 "general_operand" "rim")))
6844 (set (match_operand:DI 0 "register_operand" "=r")
6845 (zero_extend:DI
6846 (minus:SI (match_dup 1)
6847 (match_dup 2))))]
6848 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6849 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6850 "sub{q}\t{%2, %0|%0, %2}"
6851 [(set_attr "type" "alu")
6852 (set_attr "mode" "DI")])
6853
6854 (define_expand "subhi3"
6855 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6856 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6857 (match_operand:HI 2 "general_operand" "")))
6858 (clobber (reg:CC 17))])]
6859 "TARGET_HIMODE_MATH"
6860 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6861
6862 (define_insn "*subhi_1"
6863 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6864 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6865 (match_operand:HI 2 "general_operand" "ri,rm")))
6866 (clobber (reg:CC 17))]
6867 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6868 "sub{w}\t{%2, %0|%0, %2}"
6869 [(set_attr "type" "alu")
6870 (set_attr "mode" "HI")])
6871
6872 (define_insn "*subhi_2"
6873 [(set (reg 17)
6874 (compare
6875 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6876 (match_operand:HI 2 "general_operand" "ri,rm"))
6877 (const_int 0)))
6878 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6879 (minus:HI (match_dup 1) (match_dup 2)))]
6880 "ix86_match_ccmode (insn, CCGOCmode)
6881 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6882 "sub{w}\t{%2, %0|%0, %2}"
6883 [(set_attr "type" "alu")
6884 (set_attr "mode" "HI")])
6885
6886 (define_insn "*subhi_3"
6887 [(set (reg 17)
6888 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6889 (match_operand:HI 2 "general_operand" "ri,rm")))
6890 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6891 (minus:HI (match_dup 1) (match_dup 2)))]
6892 "ix86_match_ccmode (insn, CCmode)
6893 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6894 "sub{w}\t{%2, %0|%0, %2}"
6895 [(set_attr "type" "alu")
6896 (set_attr "mode" "HI")])
6897
6898 (define_expand "subqi3"
6899 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6900 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6901 (match_operand:QI 2 "general_operand" "")))
6902 (clobber (reg:CC 17))])]
6903 "TARGET_QIMODE_MATH"
6904 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6905
6906 (define_insn "*subqi_1"
6907 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6908 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6909 (match_operand:QI 2 "general_operand" "qn,qmn")))
6910 (clobber (reg:CC 17))]
6911 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6912 "sub{b}\t{%2, %0|%0, %2}"
6913 [(set_attr "type" "alu")
6914 (set_attr "mode" "QI")])
6915
6916 (define_insn "*subqi_1_slp"
6917 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6918 (minus:QI (match_dup 0)
6919 (match_operand:QI 1 "general_operand" "qn,qmn")))
6920 (clobber (reg:CC 17))]
6921 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6922 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6923 "sub{b}\t{%1, %0|%0, %1}"
6924 [(set_attr "type" "alu1")
6925 (set_attr "mode" "QI")])
6926
6927 (define_insn "*subqi_2"
6928 [(set (reg 17)
6929 (compare
6930 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6931 (match_operand:QI 2 "general_operand" "qi,qm"))
6932 (const_int 0)))
6933 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6934 (minus:HI (match_dup 1) (match_dup 2)))]
6935 "ix86_match_ccmode (insn, CCGOCmode)
6936 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6937 "sub{b}\t{%2, %0|%0, %2}"
6938 [(set_attr "type" "alu")
6939 (set_attr "mode" "QI")])
6940
6941 (define_insn "*subqi_3"
6942 [(set (reg 17)
6943 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6944 (match_operand:QI 2 "general_operand" "qi,qm")))
6945 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6946 (minus:HI (match_dup 1) (match_dup 2)))]
6947 "ix86_match_ccmode (insn, CCmode)
6948 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6949 "sub{b}\t{%2, %0|%0, %2}"
6950 [(set_attr "type" "alu")
6951 (set_attr "mode" "QI")])
6952
6953 ;; The patterns that match these are at the end of this file.
6954
6955 (define_expand "subxf3"
6956 [(set (match_operand:XF 0 "register_operand" "")
6957 (minus:XF (match_operand:XF 1 "register_operand" "")
6958 (match_operand:XF 2 "register_operand" "")))]
6959 "TARGET_80387"
6960 "")
6961
6962 (define_expand "subdf3"
6963 [(set (match_operand:DF 0 "register_operand" "")
6964 (minus:DF (match_operand:DF 1 "register_operand" "")
6965 (match_operand:DF 2 "nonimmediate_operand" "")))]
6966 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6967 "")
6968
6969 (define_expand "subsf3"
6970 [(set (match_operand:SF 0 "register_operand" "")
6971 (minus:SF (match_operand:SF 1 "register_operand" "")
6972 (match_operand:SF 2 "nonimmediate_operand" "")))]
6973 "TARGET_80387 || TARGET_SSE_MATH"
6974 "")
6975 \f
6976 ;; Multiply instructions
6977
6978 (define_expand "muldi3"
6979 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6980 (mult:DI (match_operand:DI 1 "register_operand" "")
6981 (match_operand:DI 2 "x86_64_general_operand" "")))
6982 (clobber (reg:CC 17))])]
6983 "TARGET_64BIT"
6984 "")
6985
6986 (define_insn "*muldi3_1_rex64"
6987 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6988 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6989 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6990 (clobber (reg:CC 17))]
6991 "TARGET_64BIT
6992 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6993 "@
6994 imul{q}\t{%2, %1, %0|%0, %1, %2}
6995 imul{q}\t{%2, %1, %0|%0, %1, %2}
6996 imul{q}\t{%2, %0|%0, %2}"
6997 [(set_attr "type" "imul")
6998 (set_attr "prefix_0f" "0,0,1")
6999 (set (attr "athlon_decode")
7000 (cond [(eq_attr "cpu" "athlon")
7001 (const_string "vector")
7002 (eq_attr "alternative" "1")
7003 (const_string "vector")
7004 (and (eq_attr "alternative" "2")
7005 (match_operand 1 "memory_operand" ""))
7006 (const_string "vector")]
7007 (const_string "direct")))
7008 (set_attr "mode" "DI")])
7009
7010 (define_expand "mulsi3"
7011 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7012 (mult:SI (match_operand:SI 1 "register_operand" "")
7013 (match_operand:SI 2 "general_operand" "")))
7014 (clobber (reg:CC 17))])]
7015 ""
7016 "")
7017
7018 (define_insn "*mulsi3_1"
7019 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7020 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7021 (match_operand:SI 2 "general_operand" "K,i,mr")))
7022 (clobber (reg:CC 17))]
7023 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7024 "@
7025 imul{l}\t{%2, %1, %0|%0, %1, %2}
7026 imul{l}\t{%2, %1, %0|%0, %1, %2}
7027 imul{l}\t{%2, %0|%0, %2}"
7028 [(set_attr "type" "imul")
7029 (set_attr "prefix_0f" "0,0,1")
7030 (set (attr "athlon_decode")
7031 (cond [(eq_attr "cpu" "athlon")
7032 (const_string "vector")
7033 (eq_attr "alternative" "1")
7034 (const_string "vector")
7035 (and (eq_attr "alternative" "2")
7036 (match_operand 1 "memory_operand" ""))
7037 (const_string "vector")]
7038 (const_string "direct")))
7039 (set_attr "mode" "SI")])
7040
7041 (define_insn "*mulsi3_1_zext"
7042 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7043 (zero_extend:DI
7044 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7045 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7046 (clobber (reg:CC 17))]
7047 "TARGET_64BIT
7048 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7049 "@
7050 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7051 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7052 imul{l}\t{%2, %k0|%k0, %2}"
7053 [(set_attr "type" "imul")
7054 (set_attr "prefix_0f" "0,0,1")
7055 (set (attr "athlon_decode")
7056 (cond [(eq_attr "cpu" "athlon")
7057 (const_string "vector")
7058 (eq_attr "alternative" "1")
7059 (const_string "vector")
7060 (and (eq_attr "alternative" "2")
7061 (match_operand 1 "memory_operand" ""))
7062 (const_string "vector")]
7063 (const_string "direct")))
7064 (set_attr "mode" "SI")])
7065
7066 (define_expand "mulhi3"
7067 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7068 (mult:HI (match_operand:HI 1 "register_operand" "")
7069 (match_operand:HI 2 "general_operand" "")))
7070 (clobber (reg:CC 17))])]
7071 "TARGET_HIMODE_MATH"
7072 "")
7073
7074 (define_insn "*mulhi3_1"
7075 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7076 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7077 (match_operand:HI 2 "general_operand" "K,i,mr")))
7078 (clobber (reg:CC 17))]
7079 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7080 "@
7081 imul{w}\t{%2, %1, %0|%0, %1, %2}
7082 imul{w}\t{%2, %1, %0|%0, %1, %2}
7083 imul{w}\t{%2, %0|%0, %2}"
7084 [(set_attr "type" "imul")
7085 (set_attr "prefix_0f" "0,0,1")
7086 (set (attr "athlon_decode")
7087 (cond [(eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (eq_attr "alternative" "1,2")
7090 (const_string "vector")]
7091 (const_string "direct")))
7092 (set_attr "mode" "HI")])
7093
7094 (define_expand "mulqi3"
7095 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7096 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7097 (match_operand:QI 2 "register_operand" "")))
7098 (clobber (reg:CC 17))])]
7099 "TARGET_QIMODE_MATH"
7100 "")
7101
7102 (define_insn "*mulqi3_1"
7103 [(set (match_operand:QI 0 "register_operand" "=a")
7104 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7105 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7106 (clobber (reg:CC 17))]
7107 "TARGET_QIMODE_MATH
7108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7109 "mul{b}\t%2"
7110 [(set_attr "type" "imul")
7111 (set_attr "length_immediate" "0")
7112 (set (attr "athlon_decode")
7113 (if_then_else (eq_attr "cpu" "athlon")
7114 (const_string "vector")
7115 (const_string "direct")))
7116 (set_attr "mode" "QI")])
7117
7118 (define_expand "umulqihi3"
7119 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7120 (mult:HI (zero_extend:HI
7121 (match_operand:QI 1 "nonimmediate_operand" ""))
7122 (zero_extend:HI
7123 (match_operand:QI 2 "register_operand" ""))))
7124 (clobber (reg:CC 17))])]
7125 "TARGET_QIMODE_MATH"
7126 "")
7127
7128 (define_insn "*umulqihi3_1"
7129 [(set (match_operand:HI 0 "register_operand" "=a")
7130 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7131 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7132 (clobber (reg:CC 17))]
7133 "TARGET_QIMODE_MATH
7134 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7135 "mul{b}\t%2"
7136 [(set_attr "type" "imul")
7137 (set_attr "length_immediate" "0")
7138 (set (attr "athlon_decode")
7139 (if_then_else (eq_attr "cpu" "athlon")
7140 (const_string "vector")
7141 (const_string "direct")))
7142 (set_attr "mode" "QI")])
7143
7144 (define_expand "mulqihi3"
7145 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7146 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7147 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7148 (clobber (reg:CC 17))])]
7149 "TARGET_QIMODE_MATH"
7150 "")
7151
7152 (define_insn "*mulqihi3_insn"
7153 [(set (match_operand:HI 0 "register_operand" "=a")
7154 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7155 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7156 (clobber (reg:CC 17))]
7157 "TARGET_QIMODE_MATH
7158 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7159 "imul{b}\t%2"
7160 [(set_attr "type" "imul")
7161 (set_attr "length_immediate" "0")
7162 (set (attr "athlon_decode")
7163 (if_then_else (eq_attr "cpu" "athlon")
7164 (const_string "vector")
7165 (const_string "direct")))
7166 (set_attr "mode" "QI")])
7167
7168 (define_expand "umulditi3"
7169 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7170 (mult:TI (zero_extend:TI
7171 (match_operand:DI 1 "nonimmediate_operand" ""))
7172 (zero_extend:TI
7173 (match_operand:DI 2 "register_operand" ""))))
7174 (clobber (reg:CC 17))])]
7175 "TARGET_64BIT"
7176 "")
7177
7178 (define_insn "*umulditi3_insn"
7179 [(set (match_operand:TI 0 "register_operand" "=A")
7180 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7181 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7182 (clobber (reg:CC 17))]
7183 "TARGET_64BIT
7184 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7185 "mul{q}\t%2"
7186 [(set_attr "type" "imul")
7187 (set_attr "length_immediate" "0")
7188 (set (attr "athlon_decode")
7189 (if_then_else (eq_attr "cpu" "athlon")
7190 (const_string "vector")
7191 (const_string "double")))
7192 (set_attr "mode" "DI")])
7193
7194 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7195 (define_expand "umulsidi3"
7196 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7197 (mult:DI (zero_extend:DI
7198 (match_operand:SI 1 "nonimmediate_operand" ""))
7199 (zero_extend:DI
7200 (match_operand:SI 2 "register_operand" ""))))
7201 (clobber (reg:CC 17))])]
7202 "!TARGET_64BIT"
7203 "")
7204
7205 (define_insn "*umulsidi3_insn"
7206 [(set (match_operand:DI 0 "register_operand" "=A")
7207 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7208 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7209 (clobber (reg:CC 17))]
7210 "!TARGET_64BIT
7211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7212 "mul{l}\t%2"
7213 [(set_attr "type" "imul")
7214 (set_attr "length_immediate" "0")
7215 (set (attr "athlon_decode")
7216 (if_then_else (eq_attr "cpu" "athlon")
7217 (const_string "vector")
7218 (const_string "double")))
7219 (set_attr "mode" "SI")])
7220
7221 (define_expand "mulditi3"
7222 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7223 (mult:TI (sign_extend:TI
7224 (match_operand:DI 1 "nonimmediate_operand" ""))
7225 (sign_extend:TI
7226 (match_operand:DI 2 "register_operand" ""))))
7227 (clobber (reg:CC 17))])]
7228 "TARGET_64BIT"
7229 "")
7230
7231 (define_insn "*mulditi3_insn"
7232 [(set (match_operand:TI 0 "register_operand" "=A")
7233 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7234 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7235 (clobber (reg:CC 17))]
7236 "TARGET_64BIT
7237 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7238 "imul{q}\t%2"
7239 [(set_attr "type" "imul")
7240 (set_attr "length_immediate" "0")
7241 (set (attr "athlon_decode")
7242 (if_then_else (eq_attr "cpu" "athlon")
7243 (const_string "vector")
7244 (const_string "double")))
7245 (set_attr "mode" "DI")])
7246
7247 (define_expand "mulsidi3"
7248 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7249 (mult:DI (sign_extend:DI
7250 (match_operand:SI 1 "nonimmediate_operand" ""))
7251 (sign_extend:DI
7252 (match_operand:SI 2 "register_operand" ""))))
7253 (clobber (reg:CC 17))])]
7254 "!TARGET_64BIT"
7255 "")
7256
7257 (define_insn "*mulsidi3_insn"
7258 [(set (match_operand:DI 0 "register_operand" "=A")
7259 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7260 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7261 (clobber (reg:CC 17))]
7262 "!TARGET_64BIT
7263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264 "imul{l}\t%2"
7265 [(set_attr "type" "imul")
7266 (set_attr "length_immediate" "0")
7267 (set (attr "athlon_decode")
7268 (if_then_else (eq_attr "cpu" "athlon")
7269 (const_string "vector")
7270 (const_string "double")))
7271 (set_attr "mode" "SI")])
7272
7273 (define_expand "umuldi3_highpart"
7274 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7275 (truncate:DI
7276 (lshiftrt:TI
7277 (mult:TI (zero_extend:TI
7278 (match_operand:DI 1 "nonimmediate_operand" ""))
7279 (zero_extend:TI
7280 (match_operand:DI 2 "register_operand" "")))
7281 (const_int 64))))
7282 (clobber (match_scratch:DI 3 ""))
7283 (clobber (reg:CC 17))])]
7284 "TARGET_64BIT"
7285 "")
7286
7287 (define_insn "*umuldi3_highpart_rex64"
7288 [(set (match_operand:DI 0 "register_operand" "=d")
7289 (truncate:DI
7290 (lshiftrt:TI
7291 (mult:TI (zero_extend:TI
7292 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7293 (zero_extend:TI
7294 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7295 (const_int 64))))
7296 (clobber (match_scratch:DI 3 "=1"))
7297 (clobber (reg:CC 17))]
7298 "TARGET_64BIT
7299 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7300 "mul{q}\t%2"
7301 [(set_attr "type" "imul")
7302 (set_attr "length_immediate" "0")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "double")))
7307 (set_attr "mode" "DI")])
7308
7309 (define_expand "umulsi3_highpart"
7310 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7311 (truncate:SI
7312 (lshiftrt:DI
7313 (mult:DI (zero_extend:DI
7314 (match_operand:SI 1 "nonimmediate_operand" ""))
7315 (zero_extend:DI
7316 (match_operand:SI 2 "register_operand" "")))
7317 (const_int 32))))
7318 (clobber (match_scratch:SI 3 ""))
7319 (clobber (reg:CC 17))])]
7320 ""
7321 "")
7322
7323 (define_insn "*umulsi3_highpart_insn"
7324 [(set (match_operand:SI 0 "register_operand" "=d")
7325 (truncate:SI
7326 (lshiftrt:DI
7327 (mult:DI (zero_extend:DI
7328 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7329 (zero_extend:DI
7330 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7331 (const_int 32))))
7332 (clobber (match_scratch:SI 3 "=1"))
7333 (clobber (reg:CC 17))]
7334 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7335 "mul{l}\t%2"
7336 [(set_attr "type" "imul")
7337 (set_attr "length_immediate" "0")
7338 (set (attr "athlon_decode")
7339 (if_then_else (eq_attr "cpu" "athlon")
7340 (const_string "vector")
7341 (const_string "double")))
7342 (set_attr "mode" "SI")])
7343
7344 (define_insn "*umulsi3_highpart_zext"
7345 [(set (match_operand:DI 0 "register_operand" "=d")
7346 (zero_extend:DI (truncate:SI
7347 (lshiftrt:DI
7348 (mult:DI (zero_extend:DI
7349 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7350 (zero_extend:DI
7351 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7352 (const_int 32)))))
7353 (clobber (match_scratch:SI 3 "=1"))
7354 (clobber (reg:CC 17))]
7355 "TARGET_64BIT
7356 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7357 "mul{l}\t%2"
7358 [(set_attr "type" "imul")
7359 (set_attr "length_immediate" "0")
7360 (set (attr "athlon_decode")
7361 (if_then_else (eq_attr "cpu" "athlon")
7362 (const_string "vector")
7363 (const_string "double")))
7364 (set_attr "mode" "SI")])
7365
7366 (define_expand "smuldi3_highpart"
7367 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7368 (truncate:DI
7369 (lshiftrt:TI
7370 (mult:TI (sign_extend:TI
7371 (match_operand:DI 1 "nonimmediate_operand" ""))
7372 (sign_extend:TI
7373 (match_operand:DI 2 "register_operand" "")))
7374 (const_int 64))))
7375 (clobber (match_scratch:DI 3 ""))
7376 (clobber (reg:CC 17))])]
7377 "TARGET_64BIT"
7378 "")
7379
7380 (define_insn "*smuldi3_highpart_rex64"
7381 [(set (match_operand:DI 0 "register_operand" "=d")
7382 (truncate:DI
7383 (lshiftrt:TI
7384 (mult:TI (sign_extend:TI
7385 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7386 (sign_extend:TI
7387 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7388 (const_int 64))))
7389 (clobber (match_scratch:DI 3 "=1"))
7390 (clobber (reg:CC 17))]
7391 "TARGET_64BIT
7392 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7393 "imul{q}\t%2"
7394 [(set_attr "type" "imul")
7395 (set (attr "athlon_decode")
7396 (if_then_else (eq_attr "cpu" "athlon")
7397 (const_string "vector")
7398 (const_string "double")))
7399 (set_attr "mode" "DI")])
7400
7401 (define_expand "smulsi3_highpart"
7402 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7403 (truncate:SI
7404 (lshiftrt:DI
7405 (mult:DI (sign_extend:DI
7406 (match_operand:SI 1 "nonimmediate_operand" ""))
7407 (sign_extend:DI
7408 (match_operand:SI 2 "register_operand" "")))
7409 (const_int 32))))
7410 (clobber (match_scratch:SI 3 ""))
7411 (clobber (reg:CC 17))])]
7412 ""
7413 "")
7414
7415 (define_insn "*smulsi3_highpart_insn"
7416 [(set (match_operand:SI 0 "register_operand" "=d")
7417 (truncate:SI
7418 (lshiftrt:DI
7419 (mult:DI (sign_extend:DI
7420 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7421 (sign_extend:DI
7422 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7423 (const_int 32))))
7424 (clobber (match_scratch:SI 3 "=1"))
7425 (clobber (reg:CC 17))]
7426 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7427 "imul{l}\t%2"
7428 [(set_attr "type" "imul")
7429 (set (attr "athlon_decode")
7430 (if_then_else (eq_attr "cpu" "athlon")
7431 (const_string "vector")
7432 (const_string "double")))
7433 (set_attr "mode" "SI")])
7434
7435 (define_insn "*smulsi3_highpart_zext"
7436 [(set (match_operand:DI 0 "register_operand" "=d")
7437 (zero_extend:DI (truncate:SI
7438 (lshiftrt:DI
7439 (mult:DI (sign_extend:DI
7440 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7441 (sign_extend:DI
7442 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7443 (const_int 32)))))
7444 (clobber (match_scratch:SI 3 "=1"))
7445 (clobber (reg:CC 17))]
7446 "TARGET_64BIT
7447 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7448 "imul{l}\t%2"
7449 [(set_attr "type" "imul")
7450 (set (attr "athlon_decode")
7451 (if_then_else (eq_attr "cpu" "athlon")
7452 (const_string "vector")
7453 (const_string "double")))
7454 (set_attr "mode" "SI")])
7455
7456 ;; The patterns that match these are at the end of this file.
7457
7458 (define_expand "mulxf3"
7459 [(set (match_operand:XF 0 "register_operand" "")
7460 (mult:XF (match_operand:XF 1 "register_operand" "")
7461 (match_operand:XF 2 "register_operand" "")))]
7462 "TARGET_80387"
7463 "")
7464
7465 (define_expand "muldf3"
7466 [(set (match_operand:DF 0 "register_operand" "")
7467 (mult:DF (match_operand:DF 1 "register_operand" "")
7468 (match_operand:DF 2 "nonimmediate_operand" "")))]
7469 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7470 "")
7471
7472 (define_expand "mulsf3"
7473 [(set (match_operand:SF 0 "register_operand" "")
7474 (mult:SF (match_operand:SF 1 "register_operand" "")
7475 (match_operand:SF 2 "nonimmediate_operand" "")))]
7476 "TARGET_80387 || TARGET_SSE_MATH"
7477 "")
7478 \f
7479 ;; Divide instructions
7480
7481 (define_insn "divqi3"
7482 [(set (match_operand:QI 0 "register_operand" "=a")
7483 (div:QI (match_operand:HI 1 "register_operand" "0")
7484 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7485 (clobber (reg:CC 17))]
7486 "TARGET_QIMODE_MATH"
7487 "idiv{b}\t%2"
7488 [(set_attr "type" "idiv")
7489 (set_attr "mode" "QI")])
7490
7491 (define_insn "udivqi3"
7492 [(set (match_operand:QI 0 "register_operand" "=a")
7493 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7494 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7495 (clobber (reg:CC 17))]
7496 "TARGET_QIMODE_MATH"
7497 "div{b}\t%2"
7498 [(set_attr "type" "idiv")
7499 (set_attr "mode" "QI")])
7500
7501 ;; The patterns that match these are at the end of this file.
7502
7503 (define_expand "divxf3"
7504 [(set (match_operand:XF 0 "register_operand" "")
7505 (div:XF (match_operand:XF 1 "register_operand" "")
7506 (match_operand:XF 2 "register_operand" "")))]
7507 "TARGET_80387"
7508 "")
7509
7510 (define_expand "divdf3"
7511 [(set (match_operand:DF 0 "register_operand" "")
7512 (div:DF (match_operand:DF 1 "register_operand" "")
7513 (match_operand:DF 2 "nonimmediate_operand" "")))]
7514 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7515 "")
7516
7517 (define_expand "divsf3"
7518 [(set (match_operand:SF 0 "register_operand" "")
7519 (div:SF (match_operand:SF 1 "register_operand" "")
7520 (match_operand:SF 2 "nonimmediate_operand" "")))]
7521 "TARGET_80387 || TARGET_SSE_MATH"
7522 "")
7523 \f
7524 ;; Remainder instructions.
7525
7526 (define_expand "divmoddi4"
7527 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7528 (div:DI (match_operand:DI 1 "register_operand" "")
7529 (match_operand:DI 2 "nonimmediate_operand" "")))
7530 (set (match_operand:DI 3 "register_operand" "")
7531 (mod:DI (match_dup 1) (match_dup 2)))
7532 (clobber (reg:CC 17))])]
7533 "TARGET_64BIT"
7534 "")
7535
7536 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7537 ;; Penalize eax case slightly because it results in worse scheduling
7538 ;; of code.
7539 (define_insn "*divmoddi4_nocltd_rex64"
7540 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7541 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7542 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7543 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7544 (mod:DI (match_dup 2) (match_dup 3)))
7545 (clobber (reg:CC 17))]
7546 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7547 "#"
7548 [(set_attr "type" "multi")])
7549
7550 (define_insn "*divmoddi4_cltd_rex64"
7551 [(set (match_operand:DI 0 "register_operand" "=a")
7552 (div:DI (match_operand:DI 2 "register_operand" "a")
7553 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7554 (set (match_operand:DI 1 "register_operand" "=&d")
7555 (mod:DI (match_dup 2) (match_dup 3)))
7556 (clobber (reg:CC 17))]
7557 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7558 "#"
7559 [(set_attr "type" "multi")])
7560
7561 (define_insn "*divmoddi_noext_rex64"
7562 [(set (match_operand:DI 0 "register_operand" "=a")
7563 (div:DI (match_operand:DI 1 "register_operand" "0")
7564 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7565 (set (match_operand:DI 3 "register_operand" "=d")
7566 (mod:DI (match_dup 1) (match_dup 2)))
7567 (use (match_operand:DI 4 "register_operand" "3"))
7568 (clobber (reg:CC 17))]
7569 "TARGET_64BIT"
7570 "idiv{q}\t%2"
7571 [(set_attr "type" "idiv")
7572 (set_attr "mode" "DI")])
7573
7574 (define_split
7575 [(set (match_operand:DI 0 "register_operand" "")
7576 (div:DI (match_operand:DI 1 "register_operand" "")
7577 (match_operand:DI 2 "nonimmediate_operand" "")))
7578 (set (match_operand:DI 3 "register_operand" "")
7579 (mod:DI (match_dup 1) (match_dup 2)))
7580 (clobber (reg:CC 17))]
7581 "TARGET_64BIT && reload_completed"
7582 [(parallel [(set (match_dup 3)
7583 (ashiftrt:DI (match_dup 4) (const_int 63)))
7584 (clobber (reg:CC 17))])
7585 (parallel [(set (match_dup 0)
7586 (div:DI (reg:DI 0) (match_dup 2)))
7587 (set (match_dup 3)
7588 (mod:DI (reg:DI 0) (match_dup 2)))
7589 (use (match_dup 3))
7590 (clobber (reg:CC 17))])]
7591 {
7592 /* Avoid use of cltd in favor of a mov+shift. */
7593 if (!TARGET_USE_CLTD && !optimize_size)
7594 {
7595 if (true_regnum (operands[1]))
7596 emit_move_insn (operands[0], operands[1]);
7597 else
7598 emit_move_insn (operands[3], operands[1]);
7599 operands[4] = operands[3];
7600 }
7601 else
7602 {
7603 if (true_regnum (operands[1]))
7604 abort();
7605 operands[4] = operands[1];
7606 }
7607 })
7608
7609
7610 (define_expand "divmodsi4"
7611 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7612 (div:SI (match_operand:SI 1 "register_operand" "")
7613 (match_operand:SI 2 "nonimmediate_operand" "")))
7614 (set (match_operand:SI 3 "register_operand" "")
7615 (mod:SI (match_dup 1) (match_dup 2)))
7616 (clobber (reg:CC 17))])]
7617 ""
7618 "")
7619
7620 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7621 ;; Penalize eax case slightly because it results in worse scheduling
7622 ;; of code.
7623 (define_insn "*divmodsi4_nocltd"
7624 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7625 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7626 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7627 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7628 (mod:SI (match_dup 2) (match_dup 3)))
7629 (clobber (reg:CC 17))]
7630 "!optimize_size && !TARGET_USE_CLTD"
7631 "#"
7632 [(set_attr "type" "multi")])
7633
7634 (define_insn "*divmodsi4_cltd"
7635 [(set (match_operand:SI 0 "register_operand" "=a")
7636 (div:SI (match_operand:SI 2 "register_operand" "a")
7637 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7638 (set (match_operand:SI 1 "register_operand" "=&d")
7639 (mod:SI (match_dup 2) (match_dup 3)))
7640 (clobber (reg:CC 17))]
7641 "optimize_size || TARGET_USE_CLTD"
7642 "#"
7643 [(set_attr "type" "multi")])
7644
7645 (define_insn "*divmodsi_noext"
7646 [(set (match_operand:SI 0 "register_operand" "=a")
7647 (div:SI (match_operand:SI 1 "register_operand" "0")
7648 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7649 (set (match_operand:SI 3 "register_operand" "=d")
7650 (mod:SI (match_dup 1) (match_dup 2)))
7651 (use (match_operand:SI 4 "register_operand" "3"))
7652 (clobber (reg:CC 17))]
7653 ""
7654 "idiv{l}\t%2"
7655 [(set_attr "type" "idiv")
7656 (set_attr "mode" "SI")])
7657
7658 (define_split
7659 [(set (match_operand:SI 0 "register_operand" "")
7660 (div:SI (match_operand:SI 1 "register_operand" "")
7661 (match_operand:SI 2 "nonimmediate_operand" "")))
7662 (set (match_operand:SI 3 "register_operand" "")
7663 (mod:SI (match_dup 1) (match_dup 2)))
7664 (clobber (reg:CC 17))]
7665 "reload_completed"
7666 [(parallel [(set (match_dup 3)
7667 (ashiftrt:SI (match_dup 4) (const_int 31)))
7668 (clobber (reg:CC 17))])
7669 (parallel [(set (match_dup 0)
7670 (div:SI (reg:SI 0) (match_dup 2)))
7671 (set (match_dup 3)
7672 (mod:SI (reg:SI 0) (match_dup 2)))
7673 (use (match_dup 3))
7674 (clobber (reg:CC 17))])]
7675 {
7676 /* Avoid use of cltd in favor of a mov+shift. */
7677 if (!TARGET_USE_CLTD && !optimize_size)
7678 {
7679 if (true_regnum (operands[1]))
7680 emit_move_insn (operands[0], operands[1]);
7681 else
7682 emit_move_insn (operands[3], operands[1]);
7683 operands[4] = operands[3];
7684 }
7685 else
7686 {
7687 if (true_regnum (operands[1]))
7688 abort();
7689 operands[4] = operands[1];
7690 }
7691 })
7692 ;; %%% Split me.
7693 (define_insn "divmodhi4"
7694 [(set (match_operand:HI 0 "register_operand" "=a")
7695 (div:HI (match_operand:HI 1 "register_operand" "0")
7696 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7697 (set (match_operand:HI 3 "register_operand" "=&d")
7698 (mod:HI (match_dup 1) (match_dup 2)))
7699 (clobber (reg:CC 17))]
7700 "TARGET_HIMODE_MATH"
7701 "cwtd\;idiv{w}\t%2"
7702 [(set_attr "type" "multi")
7703 (set_attr "length_immediate" "0")
7704 (set_attr "mode" "SI")])
7705
7706 (define_insn "udivmoddi4"
7707 [(set (match_operand:DI 0 "register_operand" "=a")
7708 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7709 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7710 (set (match_operand:DI 3 "register_operand" "=&d")
7711 (umod:DI (match_dup 1) (match_dup 2)))
7712 (clobber (reg:CC 17))]
7713 "TARGET_64BIT"
7714 "xor{q}\t%3, %3\;div{q}\t%2"
7715 [(set_attr "type" "multi")
7716 (set_attr "length_immediate" "0")
7717 (set_attr "mode" "DI")])
7718
7719 (define_insn "*udivmoddi4_noext"
7720 [(set (match_operand:DI 0 "register_operand" "=a")
7721 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7722 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7723 (set (match_operand:DI 3 "register_operand" "=d")
7724 (umod:DI (match_dup 1) (match_dup 2)))
7725 (use (match_dup 3))
7726 (clobber (reg:CC 17))]
7727 "TARGET_64BIT"
7728 "div{q}\t%2"
7729 [(set_attr "type" "idiv")
7730 (set_attr "mode" "DI")])
7731
7732 (define_split
7733 [(set (match_operand:DI 0 "register_operand" "")
7734 (udiv:DI (match_operand:DI 1 "register_operand" "")
7735 (match_operand:DI 2 "nonimmediate_operand" "")))
7736 (set (match_operand:DI 3 "register_operand" "")
7737 (umod:DI (match_dup 1) (match_dup 2)))
7738 (clobber (reg:CC 17))]
7739 "TARGET_64BIT && reload_completed"
7740 [(set (match_dup 3) (const_int 0))
7741 (parallel [(set (match_dup 0)
7742 (udiv:DI (match_dup 1) (match_dup 2)))
7743 (set (match_dup 3)
7744 (umod:DI (match_dup 1) (match_dup 2)))
7745 (use (match_dup 3))
7746 (clobber (reg:CC 17))])]
7747 "")
7748
7749 (define_insn "udivmodsi4"
7750 [(set (match_operand:SI 0 "register_operand" "=a")
7751 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7752 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7753 (set (match_operand:SI 3 "register_operand" "=&d")
7754 (umod:SI (match_dup 1) (match_dup 2)))
7755 (clobber (reg:CC 17))]
7756 ""
7757 "xor{l}\t%3, %3\;div{l}\t%2"
7758 [(set_attr "type" "multi")
7759 (set_attr "length_immediate" "0")
7760 (set_attr "mode" "SI")])
7761
7762 (define_insn "*udivmodsi4_noext"
7763 [(set (match_operand:SI 0 "register_operand" "=a")
7764 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7765 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7766 (set (match_operand:SI 3 "register_operand" "=d")
7767 (umod:SI (match_dup 1) (match_dup 2)))
7768 (use (match_dup 3))
7769 (clobber (reg:CC 17))]
7770 ""
7771 "div{l}\t%2"
7772 [(set_attr "type" "idiv")
7773 (set_attr "mode" "SI")])
7774
7775 (define_split
7776 [(set (match_operand:SI 0 "register_operand" "")
7777 (udiv:SI (match_operand:SI 1 "register_operand" "")
7778 (match_operand:SI 2 "nonimmediate_operand" "")))
7779 (set (match_operand:SI 3 "register_operand" "")
7780 (umod:SI (match_dup 1) (match_dup 2)))
7781 (clobber (reg:CC 17))]
7782 "reload_completed"
7783 [(set (match_dup 3) (const_int 0))
7784 (parallel [(set (match_dup 0)
7785 (udiv:SI (match_dup 1) (match_dup 2)))
7786 (set (match_dup 3)
7787 (umod:SI (match_dup 1) (match_dup 2)))
7788 (use (match_dup 3))
7789 (clobber (reg:CC 17))])]
7790 "")
7791
7792 (define_expand "udivmodhi4"
7793 [(set (match_dup 4) (const_int 0))
7794 (parallel [(set (match_operand:HI 0 "register_operand" "")
7795 (udiv:HI (match_operand:HI 1 "register_operand" "")
7796 (match_operand:HI 2 "nonimmediate_operand" "")))
7797 (set (match_operand:HI 3 "register_operand" "")
7798 (umod:HI (match_dup 1) (match_dup 2)))
7799 (use (match_dup 4))
7800 (clobber (reg:CC 17))])]
7801 "TARGET_HIMODE_MATH"
7802 "operands[4] = gen_reg_rtx (HImode);")
7803
7804 (define_insn "*udivmodhi_noext"
7805 [(set (match_operand:HI 0 "register_operand" "=a")
7806 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7807 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7808 (set (match_operand:HI 3 "register_operand" "=d")
7809 (umod:HI (match_dup 1) (match_dup 2)))
7810 (use (match_operand:HI 4 "register_operand" "3"))
7811 (clobber (reg:CC 17))]
7812 ""
7813 "div{w}\t%2"
7814 [(set_attr "type" "idiv")
7815 (set_attr "mode" "HI")])
7816
7817 ;; We can not use div/idiv for double division, because it causes
7818 ;; "division by zero" on the overflow and that's not what we expect
7819 ;; from truncate. Because true (non truncating) double division is
7820 ;; never generated, we can't create this insn anyway.
7821 ;
7822 ;(define_insn ""
7823 ; [(set (match_operand:SI 0 "register_operand" "=a")
7824 ; (truncate:SI
7825 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7826 ; (zero_extend:DI
7827 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7828 ; (set (match_operand:SI 3 "register_operand" "=d")
7829 ; (truncate:SI
7830 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7831 ; (clobber (reg:CC 17))]
7832 ; ""
7833 ; "div{l}\t{%2, %0|%0, %2}"
7834 ; [(set_attr "type" "idiv")])
7835 \f
7836 ;;- Logical AND instructions
7837
7838 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7839 ;; Note that this excludes ah.
7840
7841 (define_insn "*testdi_1_rex64"
7842 [(set (reg 17)
7843 (compare
7844 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7845 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7846 (const_int 0)))]
7847 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7849 "@
7850 test{l}\t{%k1, %k0|%k0, %k1}
7851 test{l}\t{%k1, %k0|%k0, %k1}
7852 test{q}\t{%1, %0|%0, %1}
7853 test{q}\t{%1, %0|%0, %1}
7854 test{q}\t{%1, %0|%0, %1}"
7855 [(set_attr "type" "test")
7856 (set_attr "modrm" "0,1,0,1,1")
7857 (set_attr "mode" "SI,SI,DI,DI,DI")
7858 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7859
7860 (define_insn "testsi_1"
7861 [(set (reg 17)
7862 (compare
7863 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7864 (match_operand:SI 1 "general_operand" "in,in,rin"))
7865 (const_int 0)))]
7866 "ix86_match_ccmode (insn, CCNOmode)
7867 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7868 "test{l}\t{%1, %0|%0, %1}"
7869 [(set_attr "type" "test")
7870 (set_attr "modrm" "0,1,1")
7871 (set_attr "mode" "SI")
7872 (set_attr "pent_pair" "uv,np,uv")])
7873
7874 (define_expand "testsi_ccno_1"
7875 [(set (reg:CCNO 17)
7876 (compare:CCNO
7877 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7878 (match_operand:SI 1 "nonmemory_operand" ""))
7879 (const_int 0)))]
7880 ""
7881 "")
7882
7883 (define_insn "*testhi_1"
7884 [(set (reg 17)
7885 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7886 (match_operand:HI 1 "general_operand" "n,n,rn"))
7887 (const_int 0)))]
7888 "ix86_match_ccmode (insn, CCNOmode)
7889 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7890 "test{w}\t{%1, %0|%0, %1}"
7891 [(set_attr "type" "test")
7892 (set_attr "modrm" "0,1,1")
7893 (set_attr "mode" "HI")
7894 (set_attr "pent_pair" "uv,np,uv")])
7895
7896 (define_expand "testqi_ccz_1"
7897 [(set (reg:CCZ 17)
7898 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7899 (match_operand:QI 1 "nonmemory_operand" ""))
7900 (const_int 0)))]
7901 ""
7902 "")
7903
7904 (define_insn "*testqi_1"
7905 [(set (reg 17)
7906 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7907 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7908 (const_int 0)))]
7909 "ix86_match_ccmode (insn, CCNOmode)
7910 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7911 {
7912 if (which_alternative == 3)
7913 {
7914 if (GET_CODE (operands[1]) == CONST_INT
7915 && (INTVAL (operands[1]) & 0xffffff00))
7916 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7917 return "test{l}\t{%1, %k0|%k0, %1}";
7918 }
7919 return "test{b}\t{%1, %0|%0, %1}";
7920 }
7921 [(set_attr "type" "test")
7922 (set_attr "modrm" "0,1,1,1")
7923 (set_attr "mode" "QI,QI,QI,SI")
7924 (set_attr "pent_pair" "uv,np,uv,np")])
7925
7926 (define_expand "testqi_ext_ccno_0"
7927 [(set (reg:CCNO 17)
7928 (compare:CCNO
7929 (and:SI
7930 (zero_extract:SI
7931 (match_operand 0 "ext_register_operand" "")
7932 (const_int 8)
7933 (const_int 8))
7934 (match_operand 1 "const_int_operand" ""))
7935 (const_int 0)))]
7936 ""
7937 "")
7938
7939 (define_insn "*testqi_ext_0"
7940 [(set (reg 17)
7941 (compare
7942 (and:SI
7943 (zero_extract:SI
7944 (match_operand 0 "ext_register_operand" "Q")
7945 (const_int 8)
7946 (const_int 8))
7947 (match_operand 1 "const_int_operand" "n"))
7948 (const_int 0)))]
7949 "ix86_match_ccmode (insn, CCNOmode)"
7950 "test{b}\t{%1, %h0|%h0, %1}"
7951 [(set_attr "type" "test")
7952 (set_attr "mode" "QI")
7953 (set_attr "length_immediate" "1")
7954 (set_attr "pent_pair" "np")])
7955
7956 (define_insn "*testqi_ext_1"
7957 [(set (reg 17)
7958 (compare
7959 (and:SI
7960 (zero_extract:SI
7961 (match_operand 0 "ext_register_operand" "Q")
7962 (const_int 8)
7963 (const_int 8))
7964 (zero_extend:SI
7965 (match_operand:QI 1 "general_operand" "Qm")))
7966 (const_int 0)))]
7967 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7968 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7969 "test{b}\t{%1, %h0|%h0, %1}"
7970 [(set_attr "type" "test")
7971 (set_attr "mode" "QI")])
7972
7973 (define_insn "*testqi_ext_1_rex64"
7974 [(set (reg 17)
7975 (compare
7976 (and:SI
7977 (zero_extract:SI
7978 (match_operand 0 "ext_register_operand" "Q")
7979 (const_int 8)
7980 (const_int 8))
7981 (zero_extend:SI
7982 (match_operand:QI 1 "register_operand" "Q")))
7983 (const_int 0)))]
7984 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7985 "test{b}\t{%1, %h0|%h0, %1}"
7986 [(set_attr "type" "test")
7987 (set_attr "mode" "QI")])
7988
7989 (define_insn "*testqi_ext_2"
7990 [(set (reg 17)
7991 (compare
7992 (and:SI
7993 (zero_extract:SI
7994 (match_operand 0 "ext_register_operand" "Q")
7995 (const_int 8)
7996 (const_int 8))
7997 (zero_extract:SI
7998 (match_operand 1 "ext_register_operand" "Q")
7999 (const_int 8)
8000 (const_int 8)))
8001 (const_int 0)))]
8002 "ix86_match_ccmode (insn, CCNOmode)"
8003 "test{b}\t{%h1, %h0|%h0, %h1}"
8004 [(set_attr "type" "test")
8005 (set_attr "mode" "QI")])
8006
8007 ;; Combine likes to form bit extractions for some tests. Humor it.
8008 (define_insn "*testqi_ext_3"
8009 [(set (reg 17)
8010 (compare (zero_extract:SI
8011 (match_operand 0 "nonimmediate_operand" "rm")
8012 (match_operand:SI 1 "const_int_operand" "")
8013 (match_operand:SI 2 "const_int_operand" ""))
8014 (const_int 0)))]
8015 "ix86_match_ccmode (insn, CCNOmode)
8016 && (GET_MODE (operands[0]) == SImode
8017 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8018 || GET_MODE (operands[0]) == HImode
8019 || GET_MODE (operands[0]) == QImode)"
8020 "#")
8021
8022 (define_insn "*testqi_ext_3_rex64"
8023 [(set (reg 17)
8024 (compare (zero_extract:DI
8025 (match_operand 0 "nonimmediate_operand" "rm")
8026 (match_operand:DI 1 "const_int_operand" "")
8027 (match_operand:DI 2 "const_int_operand" ""))
8028 (const_int 0)))]
8029 "TARGET_64BIT
8030 && ix86_match_ccmode (insn, CCNOmode)
8031 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8032 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8033 /* Ensure that resulting mask is zero or sign extended operand. */
8034 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8035 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8036 && INTVAL (operands[1]) > 32))
8037 && (GET_MODE (operands[0]) == SImode
8038 || GET_MODE (operands[0]) == DImode
8039 || GET_MODE (operands[0]) == HImode
8040 || GET_MODE (operands[0]) == QImode)"
8041 "#")
8042
8043 (define_split
8044 [(set (reg 17)
8045 (compare (zero_extract
8046 (match_operand 0 "nonimmediate_operand" "")
8047 (match_operand 1 "const_int_operand" "")
8048 (match_operand 2 "const_int_operand" ""))
8049 (const_int 0)))]
8050 "ix86_match_ccmode (insn, CCNOmode)"
8051 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8052 {
8053 HOST_WIDE_INT len = INTVAL (operands[1]);
8054 HOST_WIDE_INT pos = INTVAL (operands[2]);
8055 HOST_WIDE_INT mask;
8056 enum machine_mode mode, submode;
8057
8058 mode = GET_MODE (operands[0]);
8059 if (GET_CODE (operands[0]) == MEM)
8060 {
8061 /* ??? Combine likes to put non-volatile mem extractions in QImode
8062 no matter the size of the test. So find a mode that works. */
8063 if (! MEM_VOLATILE_P (operands[0]))
8064 {
8065 mode = smallest_mode_for_size (pos + len, MODE_INT);
8066 operands[0] = adjust_address (operands[0], mode, 0);
8067 }
8068 }
8069 else if (GET_CODE (operands[0]) == SUBREG
8070 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8071 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8072 && pos + len <= GET_MODE_BITSIZE (submode))
8073 {
8074 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8075 mode = submode;
8076 operands[0] = SUBREG_REG (operands[0]);
8077 }
8078 else if (mode == HImode && pos + len <= 8)
8079 {
8080 /* Small HImode tests can be converted to QImode. */
8081 mode = QImode;
8082 operands[0] = gen_lowpart (QImode, operands[0]);
8083 }
8084
8085 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8086 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8087
8088 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8089 })
8090
8091 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8092 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8093 ;; this is relatively important trick.
8094 ;; Do the conversion only post-reload to avoid limiting of the register class
8095 ;; to QI regs.
8096 (define_split
8097 [(set (reg 17)
8098 (compare
8099 (and (match_operand 0 "register_operand" "")
8100 (match_operand 1 "const_int_operand" ""))
8101 (const_int 0)))]
8102 "reload_completed
8103 && QI_REG_P (operands[0])
8104 && ((ix86_match_ccmode (insn, CCZmode)
8105 && !(INTVAL (operands[1]) & ~(255 << 8)))
8106 || (ix86_match_ccmode (insn, CCNOmode)
8107 && !(INTVAL (operands[1]) & ~(127 << 8))))
8108 && GET_MODE (operands[0]) != QImode"
8109 [(set (reg:CCNO 17)
8110 (compare:CCNO
8111 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8112 (match_dup 1))
8113 (const_int 0)))]
8114 "operands[0] = gen_lowpart (SImode, operands[0]);
8115 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8116
8117 (define_split
8118 [(set (reg 17)
8119 (compare
8120 (and (match_operand 0 "nonimmediate_operand" "")
8121 (match_operand 1 "const_int_operand" ""))
8122 (const_int 0)))]
8123 "reload_completed
8124 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8125 && ((ix86_match_ccmode (insn, CCZmode)
8126 && !(INTVAL (operands[1]) & ~255))
8127 || (ix86_match_ccmode (insn, CCNOmode)
8128 && !(INTVAL (operands[1]) & ~127)))
8129 && GET_MODE (operands[0]) != QImode"
8130 [(set (reg:CCNO 17)
8131 (compare:CCNO
8132 (and:QI (match_dup 0)
8133 (match_dup 1))
8134 (const_int 0)))]
8135 "operands[0] = gen_lowpart (QImode, operands[0]);
8136 operands[1] = gen_lowpart (QImode, operands[1]);")
8137
8138
8139 ;; %%% This used to optimize known byte-wide and operations to memory,
8140 ;; and sometimes to QImode registers. If this is considered useful,
8141 ;; it should be done with splitters.
8142
8143 (define_expand "anddi3"
8144 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8145 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8146 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8147 (clobber (reg:CC 17))]
8148 "TARGET_64BIT"
8149 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8150
8151 (define_insn "*anddi_1_rex64"
8152 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8153 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8154 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8155 (clobber (reg:CC 17))]
8156 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8157 {
8158 switch (get_attr_type (insn))
8159 {
8160 case TYPE_IMOVX:
8161 {
8162 enum machine_mode mode;
8163
8164 if (GET_CODE (operands[2]) != CONST_INT)
8165 abort ();
8166 if (INTVAL (operands[2]) == 0xff)
8167 mode = QImode;
8168 else if (INTVAL (operands[2]) == 0xffff)
8169 mode = HImode;
8170 else
8171 abort ();
8172
8173 operands[1] = gen_lowpart (mode, operands[1]);
8174 if (mode == QImode)
8175 return "movz{bq|x}\t{%1,%0|%0, %1}";
8176 else
8177 return "movz{wq|x}\t{%1,%0|%0, %1}";
8178 }
8179
8180 default:
8181 if (! rtx_equal_p (operands[0], operands[1]))
8182 abort ();
8183 if (get_attr_mode (insn) == MODE_SI)
8184 return "and{l}\t{%k2, %k0|%k0, %k2}";
8185 else
8186 return "and{q}\t{%2, %0|%0, %2}";
8187 }
8188 }
8189 [(set_attr "type" "alu,alu,alu,imovx")
8190 (set_attr "length_immediate" "*,*,*,0")
8191 (set_attr "mode" "SI,DI,DI,DI")])
8192
8193 (define_insn "*anddi_2"
8194 [(set (reg 17)
8195 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8196 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8197 (const_int 0)))
8198 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8199 (and:DI (match_dup 1) (match_dup 2)))]
8200 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8201 && ix86_binary_operator_ok (AND, DImode, operands)"
8202 "@
8203 and{l}\t{%k2, %k0|%k0, %k2}
8204 and{q}\t{%2, %0|%0, %2}
8205 and{q}\t{%2, %0|%0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "SI,DI,DI")])
8208
8209 (define_expand "andsi3"
8210 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8211 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8212 (match_operand:SI 2 "general_operand" "")))
8213 (clobber (reg:CC 17))]
8214 ""
8215 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8216
8217 (define_insn "*andsi_1"
8218 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8219 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8220 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8221 (clobber (reg:CC 17))]
8222 "ix86_binary_operator_ok (AND, SImode, operands)"
8223 {
8224 switch (get_attr_type (insn))
8225 {
8226 case TYPE_IMOVX:
8227 {
8228 enum machine_mode mode;
8229
8230 if (GET_CODE (operands[2]) != CONST_INT)
8231 abort ();
8232 if (INTVAL (operands[2]) == 0xff)
8233 mode = QImode;
8234 else if (INTVAL (operands[2]) == 0xffff)
8235 mode = HImode;
8236 else
8237 abort ();
8238
8239 operands[1] = gen_lowpart (mode, operands[1]);
8240 if (mode == QImode)
8241 return "movz{bl|x}\t{%1,%0|%0, %1}";
8242 else
8243 return "movz{wl|x}\t{%1,%0|%0, %1}";
8244 }
8245
8246 default:
8247 if (! rtx_equal_p (operands[0], operands[1]))
8248 abort ();
8249 return "and{l}\t{%2, %0|%0, %2}";
8250 }
8251 }
8252 [(set_attr "type" "alu,alu,imovx")
8253 (set_attr "length_immediate" "*,*,0")
8254 (set_attr "mode" "SI")])
8255
8256 (define_split
8257 [(set (match_operand 0 "register_operand" "")
8258 (and (match_dup 0)
8259 (const_int -65536)))
8260 (clobber (reg:CC 17))]
8261 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8262 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8263 "operands[1] = gen_lowpart (HImode, operands[0]);")
8264
8265 (define_split
8266 [(set (match_operand 0 "ext_register_operand" "")
8267 (and (match_dup 0)
8268 (const_int -256)))
8269 (clobber (reg:CC 17))]
8270 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8271 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8272 "operands[1] = gen_lowpart (QImode, operands[0]);")
8273
8274 (define_split
8275 [(set (match_operand 0 "ext_register_operand" "")
8276 (and (match_dup 0)
8277 (const_int -65281)))
8278 (clobber (reg:CC 17))]
8279 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8280 [(parallel [(set (zero_extract:SI (match_dup 0)
8281 (const_int 8)
8282 (const_int 8))
8283 (xor:SI
8284 (zero_extract:SI (match_dup 0)
8285 (const_int 8)
8286 (const_int 8))
8287 (zero_extract:SI (match_dup 0)
8288 (const_int 8)
8289 (const_int 8))))
8290 (clobber (reg:CC 17))])]
8291 "operands[0] = gen_lowpart (SImode, operands[0]);")
8292
8293 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8294 (define_insn "*andsi_1_zext"
8295 [(set (match_operand:DI 0 "register_operand" "=r")
8296 (zero_extend:DI
8297 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8298 (match_operand:SI 2 "general_operand" "rim"))))
8299 (clobber (reg:CC 17))]
8300 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8301 "and{l}\t{%2, %k0|%k0, %2}"
8302 [(set_attr "type" "alu")
8303 (set_attr "mode" "SI")])
8304
8305 (define_insn "*andsi_2"
8306 [(set (reg 17)
8307 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8308 (match_operand:SI 2 "general_operand" "rim,ri"))
8309 (const_int 0)))
8310 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8311 (and:SI (match_dup 1) (match_dup 2)))]
8312 "ix86_match_ccmode (insn, CCNOmode)
8313 && ix86_binary_operator_ok (AND, SImode, operands)"
8314 "and{l}\t{%2, %0|%0, %2}"
8315 [(set_attr "type" "alu")
8316 (set_attr "mode" "SI")])
8317
8318 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8319 (define_insn "*andsi_2_zext"
8320 [(set (reg 17)
8321 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8322 (match_operand:SI 2 "general_operand" "rim"))
8323 (const_int 0)))
8324 (set (match_operand:DI 0 "register_operand" "=r")
8325 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8326 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8327 && ix86_binary_operator_ok (AND, SImode, operands)"
8328 "and{l}\t{%2, %k0|%k0, %2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "mode" "SI")])
8331
8332 (define_expand "andhi3"
8333 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8334 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8335 (match_operand:HI 2 "general_operand" "")))
8336 (clobber (reg:CC 17))]
8337 "TARGET_HIMODE_MATH"
8338 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8339
8340 (define_insn "*andhi_1"
8341 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8342 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8343 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8344 (clobber (reg:CC 17))]
8345 "ix86_binary_operator_ok (AND, HImode, operands)"
8346 {
8347 switch (get_attr_type (insn))
8348 {
8349 case TYPE_IMOVX:
8350 if (GET_CODE (operands[2]) != CONST_INT)
8351 abort ();
8352 if (INTVAL (operands[2]) == 0xff)
8353 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8354 abort ();
8355
8356 default:
8357 if (! rtx_equal_p (operands[0], operands[1]))
8358 abort ();
8359
8360 return "and{w}\t{%2, %0|%0, %2}";
8361 }
8362 }
8363 [(set_attr "type" "alu,alu,imovx")
8364 (set_attr "length_immediate" "*,*,0")
8365 (set_attr "mode" "HI,HI,SI")])
8366
8367 (define_insn "*andhi_2"
8368 [(set (reg 17)
8369 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8370 (match_operand:HI 2 "general_operand" "rim,ri"))
8371 (const_int 0)))
8372 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8373 (and:HI (match_dup 1) (match_dup 2)))]
8374 "ix86_match_ccmode (insn, CCNOmode)
8375 && ix86_binary_operator_ok (AND, HImode, operands)"
8376 "and{w}\t{%2, %0|%0, %2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "HI")])
8379
8380 (define_expand "andqi3"
8381 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8382 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8383 (match_operand:QI 2 "general_operand" "")))
8384 (clobber (reg:CC 17))]
8385 "TARGET_QIMODE_MATH"
8386 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8387
8388 ;; %%% Potential partial reg stall on alternative 2. What to do?
8389 (define_insn "*andqi_1"
8390 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8391 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8392 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8393 (clobber (reg:CC 17))]
8394 "ix86_binary_operator_ok (AND, QImode, operands)"
8395 "@
8396 and{b}\t{%2, %0|%0, %2}
8397 and{b}\t{%2, %0|%0, %2}
8398 and{l}\t{%k2, %k0|%k0, %k2}"
8399 [(set_attr "type" "alu")
8400 (set_attr "mode" "QI,QI,SI")])
8401
8402 (define_insn "*andqi_1_slp"
8403 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8404 (and:QI (match_dup 0)
8405 (match_operand:QI 1 "general_operand" "qi,qmi")))
8406 (clobber (reg:CC 17))]
8407 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8408 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8409 "and{b}\t{%1, %0|%0, %1}"
8410 [(set_attr "type" "alu1")
8411 (set_attr "mode" "QI")])
8412
8413 (define_insn "*andqi_2"
8414 [(set (reg 17)
8415 (compare (and:QI
8416 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8417 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8418 (const_int 0)))
8419 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8420 (and:QI (match_dup 1) (match_dup 2)))]
8421 "ix86_match_ccmode (insn, CCNOmode)
8422 && ix86_binary_operator_ok (AND, QImode, operands)"
8423 {
8424 if (which_alternative == 2)
8425 {
8426 if (GET_CODE (operands[2]) == CONST_INT
8427 && (INTVAL (operands[2]) & 0xffffff00))
8428 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8429 return "and{l}\t{%2, %k0|%k0, %2}";
8430 }
8431 return "and{b}\t{%2, %0|%0, %2}";
8432 }
8433 [(set_attr "type" "alu")
8434 (set_attr "mode" "QI,QI,SI")])
8435
8436 (define_insn "*andqi_2_slp"
8437 [(set (reg 17)
8438 (compare (and:QI
8439 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8440 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8441 (const_int 0)))
8442 (set (strict_low_part (match_dup 0))
8443 (and:QI (match_dup 0) (match_dup 1)))]
8444 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8445 && ix86_match_ccmode (insn, CCNOmode)
8446 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8447 "and{b}\t{%1, %0|%0, %1}"
8448 [(set_attr "type" "alu1")
8449 (set_attr "mode" "QI")])
8450
8451 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8452 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8453 ;; for a QImode operand, which of course failed.
8454
8455 (define_insn "andqi_ext_0"
8456 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8457 (const_int 8)
8458 (const_int 8))
8459 (and:SI
8460 (zero_extract:SI
8461 (match_operand 1 "ext_register_operand" "0")
8462 (const_int 8)
8463 (const_int 8))
8464 (match_operand 2 "const_int_operand" "n")))
8465 (clobber (reg:CC 17))]
8466 ""
8467 "and{b}\t{%2, %h0|%h0, %2}"
8468 [(set_attr "type" "alu")
8469 (set_attr "length_immediate" "1")
8470 (set_attr "mode" "QI")])
8471
8472 ;; Generated by peephole translating test to and. This shows up
8473 ;; often in fp comparisons.
8474
8475 (define_insn "*andqi_ext_0_cc"
8476 [(set (reg 17)
8477 (compare
8478 (and:SI
8479 (zero_extract:SI
8480 (match_operand 1 "ext_register_operand" "0")
8481 (const_int 8)
8482 (const_int 8))
8483 (match_operand 2 "const_int_operand" "n"))
8484 (const_int 0)))
8485 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8486 (const_int 8)
8487 (const_int 8))
8488 (and:SI
8489 (zero_extract:SI
8490 (match_dup 1)
8491 (const_int 8)
8492 (const_int 8))
8493 (match_dup 2)))]
8494 "ix86_match_ccmode (insn, CCNOmode)"
8495 "and{b}\t{%2, %h0|%h0, %2}"
8496 [(set_attr "type" "alu")
8497 (set_attr "length_immediate" "1")
8498 (set_attr "mode" "QI")])
8499
8500 (define_insn "*andqi_ext_1"
8501 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8502 (const_int 8)
8503 (const_int 8))
8504 (and:SI
8505 (zero_extract:SI
8506 (match_operand 1 "ext_register_operand" "0")
8507 (const_int 8)
8508 (const_int 8))
8509 (zero_extend:SI
8510 (match_operand:QI 2 "general_operand" "Qm"))))
8511 (clobber (reg:CC 17))]
8512 "!TARGET_64BIT"
8513 "and{b}\t{%2, %h0|%h0, %2}"
8514 [(set_attr "type" "alu")
8515 (set_attr "length_immediate" "0")
8516 (set_attr "mode" "QI")])
8517
8518 (define_insn "*andqi_ext_1_rex64"
8519 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8520 (const_int 8)
8521 (const_int 8))
8522 (and:SI
8523 (zero_extract:SI
8524 (match_operand 1 "ext_register_operand" "0")
8525 (const_int 8)
8526 (const_int 8))
8527 (zero_extend:SI
8528 (match_operand 2 "ext_register_operand" "Q"))))
8529 (clobber (reg:CC 17))]
8530 "TARGET_64BIT"
8531 "and{b}\t{%2, %h0|%h0, %2}"
8532 [(set_attr "type" "alu")
8533 (set_attr "length_immediate" "0")
8534 (set_attr "mode" "QI")])
8535
8536 (define_insn "*andqi_ext_2"
8537 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8538 (const_int 8)
8539 (const_int 8))
8540 (and:SI
8541 (zero_extract:SI
8542 (match_operand 1 "ext_register_operand" "%0")
8543 (const_int 8)
8544 (const_int 8))
8545 (zero_extract:SI
8546 (match_operand 2 "ext_register_operand" "Q")
8547 (const_int 8)
8548 (const_int 8))))
8549 (clobber (reg:CC 17))]
8550 ""
8551 "and{b}\t{%h2, %h0|%h0, %h2}"
8552 [(set_attr "type" "alu")
8553 (set_attr "length_immediate" "0")
8554 (set_attr "mode" "QI")])
8555
8556 ;; Convert wide AND instructions with immediate operand to shorter QImode
8557 ;; equivalents when possible.
8558 ;; Don't do the splitting with memory operands, since it introduces risk
8559 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8560 ;; for size, but that can (should?) be handled by generic code instead.
8561 (define_split
8562 [(set (match_operand 0 "register_operand" "")
8563 (and (match_operand 1 "register_operand" "")
8564 (match_operand 2 "const_int_operand" "")))
8565 (clobber (reg:CC 17))]
8566 "reload_completed
8567 && QI_REG_P (operands[0])
8568 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8569 && !(~INTVAL (operands[2]) & ~(255 << 8))
8570 && GET_MODE (operands[0]) != QImode"
8571 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8572 (and:SI (zero_extract:SI (match_dup 1)
8573 (const_int 8) (const_int 8))
8574 (match_dup 2)))
8575 (clobber (reg:CC 17))])]
8576 "operands[0] = gen_lowpart (SImode, operands[0]);
8577 operands[1] = gen_lowpart (SImode, operands[1]);
8578 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8579
8580 ;; Since AND can be encoded with sign extended immediate, this is only
8581 ;; profitable when 7th bit is not set.
8582 (define_split
8583 [(set (match_operand 0 "register_operand" "")
8584 (and (match_operand 1 "general_operand" "")
8585 (match_operand 2 "const_int_operand" "")))
8586 (clobber (reg:CC 17))]
8587 "reload_completed
8588 && ANY_QI_REG_P (operands[0])
8589 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8590 && !(~INTVAL (operands[2]) & ~255)
8591 && !(INTVAL (operands[2]) & 128)
8592 && GET_MODE (operands[0]) != QImode"
8593 [(parallel [(set (strict_low_part (match_dup 0))
8594 (and:QI (match_dup 1)
8595 (match_dup 2)))
8596 (clobber (reg:CC 17))])]
8597 "operands[0] = gen_lowpart (QImode, operands[0]);
8598 operands[1] = gen_lowpart (QImode, operands[1]);
8599 operands[2] = gen_lowpart (QImode, operands[2]);")
8600 \f
8601 ;; Logical inclusive OR instructions
8602
8603 ;; %%% This used to optimize known byte-wide and operations to memory.
8604 ;; If this is considered useful, it should be done with splitters.
8605
8606 (define_expand "iordi3"
8607 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8608 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8609 (match_operand:DI 2 "x86_64_general_operand" "")))
8610 (clobber (reg:CC 17))]
8611 "TARGET_64BIT"
8612 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8613
8614 (define_insn "*iordi_1_rex64"
8615 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8616 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8617 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8618 (clobber (reg:CC 17))]
8619 "TARGET_64BIT
8620 && ix86_binary_operator_ok (IOR, DImode, operands)"
8621 "or{q}\t{%2, %0|%0, %2}"
8622 [(set_attr "type" "alu")
8623 (set_attr "mode" "DI")])
8624
8625 (define_insn "*iordi_2_rex64"
8626 [(set (reg 17)
8627 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8628 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8629 (const_int 0)))
8630 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8631 (ior:DI (match_dup 1) (match_dup 2)))]
8632 "TARGET_64BIT
8633 && ix86_match_ccmode (insn, CCNOmode)
8634 && ix86_binary_operator_ok (IOR, DImode, operands)"
8635 "or{q}\t{%2, %0|%0, %2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "mode" "DI")])
8638
8639 (define_insn "*iordi_3_rex64"
8640 [(set (reg 17)
8641 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8642 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8643 (const_int 0)))
8644 (clobber (match_scratch:DI 0 "=r"))]
8645 "TARGET_64BIT
8646 && ix86_match_ccmode (insn, CCNOmode)
8647 && ix86_binary_operator_ok (IOR, DImode, operands)"
8648 "or{q}\t{%2, %0|%0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "DI")])
8651
8652
8653 (define_expand "iorsi3"
8654 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8655 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8656 (match_operand:SI 2 "general_operand" "")))
8657 (clobber (reg:CC 17))]
8658 ""
8659 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8660
8661 (define_insn "*iorsi_1"
8662 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8663 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8664 (match_operand:SI 2 "general_operand" "ri,rmi")))
8665 (clobber (reg:CC 17))]
8666 "ix86_binary_operator_ok (IOR, SImode, operands)"
8667 "or{l}\t{%2, %0|%0, %2}"
8668 [(set_attr "type" "alu")
8669 (set_attr "mode" "SI")])
8670
8671 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8672 (define_insn "*iorsi_1_zext"
8673 [(set (match_operand:DI 0 "register_operand" "=rm")
8674 (zero_extend:DI
8675 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8676 (match_operand:SI 2 "general_operand" "rim"))))
8677 (clobber (reg:CC 17))]
8678 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8679 "or{l}\t{%2, %k0|%k0, %2}"
8680 [(set_attr "type" "alu")
8681 (set_attr "mode" "SI")])
8682
8683 (define_insn "*iorsi_1_zext_imm"
8684 [(set (match_operand:DI 0 "register_operand" "=rm")
8685 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8686 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8687 (clobber (reg:CC 17))]
8688 "TARGET_64BIT"
8689 "or{l}\t{%2, %k0|%k0, %2}"
8690 [(set_attr "type" "alu")
8691 (set_attr "mode" "SI")])
8692
8693 (define_insn "*iorsi_2"
8694 [(set (reg 17)
8695 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8696 (match_operand:SI 2 "general_operand" "rim,ri"))
8697 (const_int 0)))
8698 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8699 (ior:SI (match_dup 1) (match_dup 2)))]
8700 "ix86_match_ccmode (insn, CCNOmode)
8701 && ix86_binary_operator_ok (IOR, SImode, operands)"
8702 "or{l}\t{%2, %0|%0, %2}"
8703 [(set_attr "type" "alu")
8704 (set_attr "mode" "SI")])
8705
8706 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8707 ;; ??? Special case for immediate operand is missing - it is tricky.
8708 (define_insn "*iorsi_2_zext"
8709 [(set (reg 17)
8710 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8711 (match_operand:SI 2 "general_operand" "rim"))
8712 (const_int 0)))
8713 (set (match_operand:DI 0 "register_operand" "=r")
8714 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8715 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8716 && ix86_binary_operator_ok (IOR, SImode, operands)"
8717 "or{l}\t{%2, %k0|%k0, %2}"
8718 [(set_attr "type" "alu")
8719 (set_attr "mode" "SI")])
8720
8721 (define_insn "*iorsi_2_zext_imm"
8722 [(set (reg 17)
8723 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8724 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8725 (const_int 0)))
8726 (set (match_operand:DI 0 "register_operand" "=r")
8727 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8728 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8729 && ix86_binary_operator_ok (IOR, SImode, operands)"
8730 "or{l}\t{%2, %k0|%k0, %2}"
8731 [(set_attr "type" "alu")
8732 (set_attr "mode" "SI")])
8733
8734 (define_insn "*iorsi_3"
8735 [(set (reg 17)
8736 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8737 (match_operand:SI 2 "general_operand" "rim"))
8738 (const_int 0)))
8739 (clobber (match_scratch:SI 0 "=r"))]
8740 "ix86_match_ccmode (insn, CCNOmode)
8741 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8742 "or{l}\t{%2, %0|%0, %2}"
8743 [(set_attr "type" "alu")
8744 (set_attr "mode" "SI")])
8745
8746 (define_expand "iorhi3"
8747 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8748 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8749 (match_operand:HI 2 "general_operand" "")))
8750 (clobber (reg:CC 17))]
8751 "TARGET_HIMODE_MATH"
8752 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8753
8754 (define_insn "*iorhi_1"
8755 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8756 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8757 (match_operand:HI 2 "general_operand" "rmi,ri")))
8758 (clobber (reg:CC 17))]
8759 "ix86_binary_operator_ok (IOR, HImode, operands)"
8760 "or{w}\t{%2, %0|%0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "HI")])
8763
8764 (define_insn "*iorhi_2"
8765 [(set (reg 17)
8766 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8767 (match_operand:HI 2 "general_operand" "rim,ri"))
8768 (const_int 0)))
8769 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8770 (ior:HI (match_dup 1) (match_dup 2)))]
8771 "ix86_match_ccmode (insn, CCNOmode)
8772 && ix86_binary_operator_ok (IOR, HImode, operands)"
8773 "or{w}\t{%2, %0|%0, %2}"
8774 [(set_attr "type" "alu")
8775 (set_attr "mode" "HI")])
8776
8777 (define_insn "*iorhi_3"
8778 [(set (reg 17)
8779 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8780 (match_operand:HI 2 "general_operand" "rim"))
8781 (const_int 0)))
8782 (clobber (match_scratch:HI 0 "=r"))]
8783 "ix86_match_ccmode (insn, CCNOmode)
8784 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8785 "or{w}\t{%2, %0|%0, %2}"
8786 [(set_attr "type" "alu")
8787 (set_attr "mode" "HI")])
8788
8789 (define_expand "iorqi3"
8790 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8791 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8792 (match_operand:QI 2 "general_operand" "")))
8793 (clobber (reg:CC 17))]
8794 "TARGET_QIMODE_MATH"
8795 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8796
8797 ;; %%% Potential partial reg stall on alternative 2. What to do?
8798 (define_insn "*iorqi_1"
8799 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8800 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8801 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8802 (clobber (reg:CC 17))]
8803 "ix86_binary_operator_ok (IOR, QImode, operands)"
8804 "@
8805 or{b}\t{%2, %0|%0, %2}
8806 or{b}\t{%2, %0|%0, %2}
8807 or{l}\t{%k2, %k0|%k0, %k2}"
8808 [(set_attr "type" "alu")
8809 (set_attr "mode" "QI,QI,SI")])
8810
8811 (define_insn "*iorqi_1_slp"
8812 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8813 (ior:QI (match_dup 0)
8814 (match_operand:QI 1 "general_operand" "qmi,qi")))
8815 (clobber (reg:CC 17))]
8816 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8817 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8818 "or{b}\t{%1, %0|%0, %1}"
8819 [(set_attr "type" "alu1")
8820 (set_attr "mode" "QI")])
8821
8822 (define_insn "*iorqi_2"
8823 [(set (reg 17)
8824 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8825 (match_operand:QI 2 "general_operand" "qim,qi"))
8826 (const_int 0)))
8827 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8828 (ior:QI (match_dup 1) (match_dup 2)))]
8829 "ix86_match_ccmode (insn, CCNOmode)
8830 && ix86_binary_operator_ok (IOR, QImode, operands)"
8831 "or{b}\t{%2, %0|%0, %2}"
8832 [(set_attr "type" "alu")
8833 (set_attr "mode" "QI")])
8834
8835 (define_insn "*iorqi_2_slp"
8836 [(set (reg 17)
8837 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8838 (match_operand:QI 1 "general_operand" "qim,qi"))
8839 (const_int 0)))
8840 (set (strict_low_part (match_dup 0))
8841 (ior:QI (match_dup 0) (match_dup 1)))]
8842 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8843 && ix86_match_ccmode (insn, CCNOmode)
8844 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8845 "or{b}\t{%1, %0|%0, %1}"
8846 [(set_attr "type" "alu1")
8847 (set_attr "mode" "QI")])
8848
8849 (define_insn "*iorqi_3"
8850 [(set (reg 17)
8851 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8852 (match_operand:QI 2 "general_operand" "qim"))
8853 (const_int 0)))
8854 (clobber (match_scratch:QI 0 "=q"))]
8855 "ix86_match_ccmode (insn, CCNOmode)
8856 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8857 "or{b}\t{%2, %0|%0, %2}"
8858 [(set_attr "type" "alu")
8859 (set_attr "mode" "QI")])
8860
8861 (define_insn "iorqi_ext_0"
8862 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8863 (const_int 8)
8864 (const_int 8))
8865 (ior:SI
8866 (zero_extract:SI
8867 (match_operand 1 "ext_register_operand" "0")
8868 (const_int 8)
8869 (const_int 8))
8870 (match_operand 2 "const_int_operand" "n")))
8871 (clobber (reg:CC 17))]
8872 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8873 "or{b}\t{%2, %h0|%h0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "length_immediate" "1")
8876 (set_attr "mode" "QI")])
8877
8878 (define_insn "*iorqi_ext_1"
8879 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8880 (const_int 8)
8881 (const_int 8))
8882 (ior:SI
8883 (zero_extract:SI
8884 (match_operand 1 "ext_register_operand" "0")
8885 (const_int 8)
8886 (const_int 8))
8887 (zero_extend:SI
8888 (match_operand:QI 2 "general_operand" "Qm"))))
8889 (clobber (reg:CC 17))]
8890 "!TARGET_64BIT
8891 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8892 "or{b}\t{%2, %h0|%h0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "length_immediate" "0")
8895 (set_attr "mode" "QI")])
8896
8897 (define_insn "*iorqi_ext_1_rex64"
8898 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8899 (const_int 8)
8900 (const_int 8))
8901 (ior:SI
8902 (zero_extract:SI
8903 (match_operand 1 "ext_register_operand" "0")
8904 (const_int 8)
8905 (const_int 8))
8906 (zero_extend:SI
8907 (match_operand 2 "ext_register_operand" "Q"))))
8908 (clobber (reg:CC 17))]
8909 "TARGET_64BIT
8910 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8911 "or{b}\t{%2, %h0|%h0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "length_immediate" "0")
8914 (set_attr "mode" "QI")])
8915
8916 (define_insn "*iorqi_ext_2"
8917 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8918 (const_int 8)
8919 (const_int 8))
8920 (ior:SI
8921 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8922 (const_int 8)
8923 (const_int 8))
8924 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8925 (const_int 8)
8926 (const_int 8))))
8927 (clobber (reg:CC 17))]
8928 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8929 "ior{b}\t{%h2, %h0|%h0, %h2}"
8930 [(set_attr "type" "alu")
8931 (set_attr "length_immediate" "0")
8932 (set_attr "mode" "QI")])
8933
8934 (define_split
8935 [(set (match_operand 0 "register_operand" "")
8936 (ior (match_operand 1 "register_operand" "")
8937 (match_operand 2 "const_int_operand" "")))
8938 (clobber (reg:CC 17))]
8939 "reload_completed
8940 && QI_REG_P (operands[0])
8941 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8942 && !(INTVAL (operands[2]) & ~(255 << 8))
8943 && GET_MODE (operands[0]) != QImode"
8944 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8945 (ior:SI (zero_extract:SI (match_dup 1)
8946 (const_int 8) (const_int 8))
8947 (match_dup 2)))
8948 (clobber (reg:CC 17))])]
8949 "operands[0] = gen_lowpart (SImode, operands[0]);
8950 operands[1] = gen_lowpart (SImode, operands[1]);
8951 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8952
8953 ;; Since OR can be encoded with sign extended immediate, this is only
8954 ;; profitable when 7th bit is set.
8955 (define_split
8956 [(set (match_operand 0 "register_operand" "")
8957 (ior (match_operand 1 "general_operand" "")
8958 (match_operand 2 "const_int_operand" "")))
8959 (clobber (reg:CC 17))]
8960 "reload_completed
8961 && ANY_QI_REG_P (operands[0])
8962 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8963 && !(INTVAL (operands[2]) & ~255)
8964 && (INTVAL (operands[2]) & 128)
8965 && GET_MODE (operands[0]) != QImode"
8966 [(parallel [(set (strict_low_part (match_dup 0))
8967 (ior:QI (match_dup 1)
8968 (match_dup 2)))
8969 (clobber (reg:CC 17))])]
8970 "operands[0] = gen_lowpart (QImode, operands[0]);
8971 operands[1] = gen_lowpart (QImode, operands[1]);
8972 operands[2] = gen_lowpart (QImode, operands[2]);")
8973 \f
8974 ;; Logical XOR instructions
8975
8976 ;; %%% This used to optimize known byte-wide and operations to memory.
8977 ;; If this is considered useful, it should be done with splitters.
8978
8979 (define_expand "xordi3"
8980 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8981 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8982 (match_operand:DI 2 "x86_64_general_operand" "")))
8983 (clobber (reg:CC 17))]
8984 "TARGET_64BIT"
8985 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8986
8987 (define_insn "*xordi_1_rex64"
8988 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8989 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8990 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8991 (clobber (reg:CC 17))]
8992 "TARGET_64BIT
8993 && ix86_binary_operator_ok (XOR, DImode, operands)"
8994 "@
8995 xor{q}\t{%2, %0|%0, %2}
8996 xor{q}\t{%2, %0|%0, %2}"
8997 [(set_attr "type" "alu")
8998 (set_attr "mode" "DI,DI")])
8999
9000 (define_insn "*xordi_2_rex64"
9001 [(set (reg 17)
9002 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9003 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9004 (const_int 0)))
9005 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9006 (xor:DI (match_dup 1) (match_dup 2)))]
9007 "TARGET_64BIT
9008 && ix86_match_ccmode (insn, CCNOmode)
9009 && ix86_binary_operator_ok (XOR, DImode, operands)"
9010 "@
9011 xor{q}\t{%2, %0|%0, %2}
9012 xor{q}\t{%2, %0|%0, %2}"
9013 [(set_attr "type" "alu")
9014 (set_attr "mode" "DI,DI")])
9015
9016 (define_insn "*xordi_3_rex64"
9017 [(set (reg 17)
9018 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9019 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9020 (const_int 0)))
9021 (clobber (match_scratch:DI 0 "=r"))]
9022 "TARGET_64BIT
9023 && ix86_match_ccmode (insn, CCNOmode)
9024 && ix86_binary_operator_ok (XOR, DImode, operands)"
9025 "xor{q}\t{%2, %0|%0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "DI")])
9028
9029 (define_expand "xorsi3"
9030 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9031 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9032 (match_operand:SI 2 "general_operand" "")))
9033 (clobber (reg:CC 17))]
9034 ""
9035 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9036
9037 (define_insn "*xorsi_1"
9038 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9039 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9040 (match_operand:SI 2 "general_operand" "ri,rm")))
9041 (clobber (reg:CC 17))]
9042 "ix86_binary_operator_ok (XOR, SImode, operands)"
9043 "xor{l}\t{%2, %0|%0, %2}"
9044 [(set_attr "type" "alu")
9045 (set_attr "mode" "SI")])
9046
9047 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9048 ;; Add speccase for immediates
9049 (define_insn "*xorsi_1_zext"
9050 [(set (match_operand:DI 0 "register_operand" "=r")
9051 (zero_extend:DI
9052 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9053 (match_operand:SI 2 "general_operand" "rim"))))
9054 (clobber (reg:CC 17))]
9055 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9056 "xor{l}\t{%2, %k0|%k0, %2}"
9057 [(set_attr "type" "alu")
9058 (set_attr "mode" "SI")])
9059
9060 (define_insn "*xorsi_1_zext_imm"
9061 [(set (match_operand:DI 0 "register_operand" "=r")
9062 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9063 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9064 (clobber (reg:CC 17))]
9065 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9066 "xor{l}\t{%2, %k0|%k0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "SI")])
9069
9070 (define_insn "*xorsi_2"
9071 [(set (reg 17)
9072 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9073 (match_operand:SI 2 "general_operand" "rim,ri"))
9074 (const_int 0)))
9075 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9076 (xor:SI (match_dup 1) (match_dup 2)))]
9077 "ix86_match_ccmode (insn, CCNOmode)
9078 && ix86_binary_operator_ok (XOR, SImode, operands)"
9079 "xor{l}\t{%2, %0|%0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "mode" "SI")])
9082
9083 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9084 ;; ??? Special case for immediate operand is missing - it is tricky.
9085 (define_insn "*xorsi_2_zext"
9086 [(set (reg 17)
9087 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9088 (match_operand:SI 2 "general_operand" "rim"))
9089 (const_int 0)))
9090 (set (match_operand:DI 0 "register_operand" "=r")
9091 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9092 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9093 && ix86_binary_operator_ok (XOR, SImode, operands)"
9094 "xor{l}\t{%2, %k0|%k0, %2}"
9095 [(set_attr "type" "alu")
9096 (set_attr "mode" "SI")])
9097
9098 (define_insn "*xorsi_2_zext_imm"
9099 [(set (reg 17)
9100 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9101 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9102 (const_int 0)))
9103 (set (match_operand:DI 0 "register_operand" "=r")
9104 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9105 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9106 && ix86_binary_operator_ok (XOR, SImode, operands)"
9107 "xor{l}\t{%2, %k0|%k0, %2}"
9108 [(set_attr "type" "alu")
9109 (set_attr "mode" "SI")])
9110
9111 (define_insn "*xorsi_3"
9112 [(set (reg 17)
9113 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9114 (match_operand:SI 2 "general_operand" "rim"))
9115 (const_int 0)))
9116 (clobber (match_scratch:SI 0 "=r"))]
9117 "ix86_match_ccmode (insn, CCNOmode)
9118 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9119 "xor{l}\t{%2, %0|%0, %2}"
9120 [(set_attr "type" "alu")
9121 (set_attr "mode" "SI")])
9122
9123 (define_expand "xorhi3"
9124 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9125 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9126 (match_operand:HI 2 "general_operand" "")))
9127 (clobber (reg:CC 17))]
9128 "TARGET_HIMODE_MATH"
9129 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9130
9131 (define_insn "*xorhi_1"
9132 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9133 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9134 (match_operand:HI 2 "general_operand" "rmi,ri")))
9135 (clobber (reg:CC 17))]
9136 "ix86_binary_operator_ok (XOR, HImode, operands)"
9137 "xor{w}\t{%2, %0|%0, %2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "mode" "HI")])
9140
9141 (define_insn "*xorhi_2"
9142 [(set (reg 17)
9143 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9144 (match_operand:HI 2 "general_operand" "rim,ri"))
9145 (const_int 0)))
9146 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9147 (xor:HI (match_dup 1) (match_dup 2)))]
9148 "ix86_match_ccmode (insn, CCNOmode)
9149 && ix86_binary_operator_ok (XOR, HImode, operands)"
9150 "xor{w}\t{%2, %0|%0, %2}"
9151 [(set_attr "type" "alu")
9152 (set_attr "mode" "HI")])
9153
9154 (define_insn "*xorhi_3"
9155 [(set (reg 17)
9156 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9157 (match_operand:HI 2 "general_operand" "rim"))
9158 (const_int 0)))
9159 (clobber (match_scratch:HI 0 "=r"))]
9160 "ix86_match_ccmode (insn, CCNOmode)
9161 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9162 "xor{w}\t{%2, %0|%0, %2}"
9163 [(set_attr "type" "alu")
9164 (set_attr "mode" "HI")])
9165
9166 (define_expand "xorqi3"
9167 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9168 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9169 (match_operand:QI 2 "general_operand" "")))
9170 (clobber (reg:CC 17))]
9171 "TARGET_QIMODE_MATH"
9172 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9173
9174 ;; %%% Potential partial reg stall on alternative 2. What to do?
9175 (define_insn "*xorqi_1"
9176 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9177 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9178 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9179 (clobber (reg:CC 17))]
9180 "ix86_binary_operator_ok (XOR, QImode, operands)"
9181 "@
9182 xor{b}\t{%2, %0|%0, %2}
9183 xor{b}\t{%2, %0|%0, %2}
9184 xor{l}\t{%k2, %k0|%k0, %k2}"
9185 [(set_attr "type" "alu")
9186 (set_attr "mode" "QI,QI,SI")])
9187
9188 (define_insn "*xorqi_1_slp"
9189 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9190 (xor:QI (match_dup 0)
9191 (match_operand:QI 1 "general_operand" "qi,qmi")))
9192 (clobber (reg:CC 17))]
9193 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9194 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9195 "xor{b}\t{%1, %0|%0, %1}"
9196 [(set_attr "type" "alu1")
9197 (set_attr "mode" "QI")])
9198
9199 (define_insn "xorqi_ext_0"
9200 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9201 (const_int 8)
9202 (const_int 8))
9203 (xor:SI
9204 (zero_extract:SI
9205 (match_operand 1 "ext_register_operand" "0")
9206 (const_int 8)
9207 (const_int 8))
9208 (match_operand 2 "const_int_operand" "n")))
9209 (clobber (reg:CC 17))]
9210 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9211 "xor{b}\t{%2, %h0|%h0, %2}"
9212 [(set_attr "type" "alu")
9213 (set_attr "length_immediate" "1")
9214 (set_attr "mode" "QI")])
9215
9216 (define_insn "*xorqi_ext_1"
9217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218 (const_int 8)
9219 (const_int 8))
9220 (xor:SI
9221 (zero_extract:SI
9222 (match_operand 1 "ext_register_operand" "0")
9223 (const_int 8)
9224 (const_int 8))
9225 (zero_extend:SI
9226 (match_operand:QI 2 "general_operand" "Qm"))))
9227 (clobber (reg:CC 17))]
9228 "!TARGET_64BIT
9229 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9230 "xor{b}\t{%2, %h0|%h0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "length_immediate" "0")
9233 (set_attr "mode" "QI")])
9234
9235 (define_insn "*xorqi_ext_1_rex64"
9236 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9237 (const_int 8)
9238 (const_int 8))
9239 (xor:SI
9240 (zero_extract:SI
9241 (match_operand 1 "ext_register_operand" "0")
9242 (const_int 8)
9243 (const_int 8))
9244 (zero_extend:SI
9245 (match_operand 2 "ext_register_operand" "Q"))))
9246 (clobber (reg:CC 17))]
9247 "TARGET_64BIT
9248 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9249 "xor{b}\t{%2, %h0|%h0, %2}"
9250 [(set_attr "type" "alu")
9251 (set_attr "length_immediate" "0")
9252 (set_attr "mode" "QI")])
9253
9254 (define_insn "*xorqi_ext_2"
9255 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9256 (const_int 8)
9257 (const_int 8))
9258 (xor:SI
9259 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9260 (const_int 8)
9261 (const_int 8))
9262 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9263 (const_int 8)
9264 (const_int 8))))
9265 (clobber (reg:CC 17))]
9266 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9267 "xor{b}\t{%h2, %h0|%h0, %h2}"
9268 [(set_attr "type" "alu")
9269 (set_attr "length_immediate" "0")
9270 (set_attr "mode" "QI")])
9271
9272 (define_insn "*xorqi_cc_1"
9273 [(set (reg 17)
9274 (compare
9275 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9276 (match_operand:QI 2 "general_operand" "qim,qi"))
9277 (const_int 0)))
9278 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9279 (xor:QI (match_dup 1) (match_dup 2)))]
9280 "ix86_match_ccmode (insn, CCNOmode)
9281 && ix86_binary_operator_ok (XOR, QImode, operands)"
9282 "xor{b}\t{%2, %0|%0, %2}"
9283 [(set_attr "type" "alu")
9284 (set_attr "mode" "QI")])
9285
9286 (define_insn "*xorqi_2_slp"
9287 [(set (reg 17)
9288 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9289 (match_operand:QI 1 "general_operand" "qim,qi"))
9290 (const_int 0)))
9291 (set (strict_low_part (match_dup 0))
9292 (xor:QI (match_dup 0) (match_dup 1)))]
9293 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9294 && ix86_match_ccmode (insn, CCNOmode)
9295 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9296 "xor{b}\t{%1, %0|%0, %1}"
9297 [(set_attr "type" "alu1")
9298 (set_attr "mode" "QI")])
9299
9300 (define_insn "*xorqi_cc_2"
9301 [(set (reg 17)
9302 (compare
9303 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9304 (match_operand:QI 2 "general_operand" "qim"))
9305 (const_int 0)))
9306 (clobber (match_scratch:QI 0 "=q"))]
9307 "ix86_match_ccmode (insn, CCNOmode)
9308 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9309 "xor{b}\t{%2, %0|%0, %2}"
9310 [(set_attr "type" "alu")
9311 (set_attr "mode" "QI")])
9312
9313 (define_insn "*xorqi_cc_ext_1"
9314 [(set (reg 17)
9315 (compare
9316 (xor:SI
9317 (zero_extract:SI
9318 (match_operand 1 "ext_register_operand" "0")
9319 (const_int 8)
9320 (const_int 8))
9321 (match_operand:QI 2 "general_operand" "qmn"))
9322 (const_int 0)))
9323 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9324 (const_int 8)
9325 (const_int 8))
9326 (xor:SI
9327 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9328 (match_dup 2)))]
9329 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9330 "xor{b}\t{%2, %h0|%h0, %2}"
9331 [(set_attr "type" "alu")
9332 (set_attr "mode" "QI")])
9333
9334 (define_insn "*xorqi_cc_ext_1_rex64"
9335 [(set (reg 17)
9336 (compare
9337 (xor:SI
9338 (zero_extract:SI
9339 (match_operand 1 "ext_register_operand" "0")
9340 (const_int 8)
9341 (const_int 8))
9342 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9343 (const_int 0)))
9344 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9345 (const_int 8)
9346 (const_int 8))
9347 (xor:SI
9348 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9349 (match_dup 2)))]
9350 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9351 "xor{b}\t{%2, %h0|%h0, %2}"
9352 [(set_attr "type" "alu")
9353 (set_attr "mode" "QI")])
9354
9355 (define_expand "xorqi_cc_ext_1"
9356 [(parallel [
9357 (set (reg:CCNO 17)
9358 (compare:CCNO
9359 (xor:SI
9360 (zero_extract:SI
9361 (match_operand 1 "ext_register_operand" "")
9362 (const_int 8)
9363 (const_int 8))
9364 (match_operand:QI 2 "general_operand" ""))
9365 (const_int 0)))
9366 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9367 (const_int 8)
9368 (const_int 8))
9369 (xor:SI
9370 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9371 (match_dup 2)))])]
9372 ""
9373 "")
9374
9375 (define_split
9376 [(set (match_operand 0 "register_operand" "")
9377 (xor (match_operand 1 "register_operand" "")
9378 (match_operand 2 "const_int_operand" "")))
9379 (clobber (reg:CC 17))]
9380 "reload_completed
9381 && QI_REG_P (operands[0])
9382 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9383 && !(INTVAL (operands[2]) & ~(255 << 8))
9384 && GET_MODE (operands[0]) != QImode"
9385 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9386 (xor:SI (zero_extract:SI (match_dup 1)
9387 (const_int 8) (const_int 8))
9388 (match_dup 2)))
9389 (clobber (reg:CC 17))])]
9390 "operands[0] = gen_lowpart (SImode, operands[0]);
9391 operands[1] = gen_lowpart (SImode, operands[1]);
9392 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9393
9394 ;; Since XOR can be encoded with sign extended immediate, this is only
9395 ;; profitable when 7th bit is set.
9396 (define_split
9397 [(set (match_operand 0 "register_operand" "")
9398 (xor (match_operand 1 "general_operand" "")
9399 (match_operand 2 "const_int_operand" "")))
9400 (clobber (reg:CC 17))]
9401 "reload_completed
9402 && ANY_QI_REG_P (operands[0])
9403 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9404 && !(INTVAL (operands[2]) & ~255)
9405 && (INTVAL (operands[2]) & 128)
9406 && GET_MODE (operands[0]) != QImode"
9407 [(parallel [(set (strict_low_part (match_dup 0))
9408 (xor:QI (match_dup 1)
9409 (match_dup 2)))
9410 (clobber (reg:CC 17))])]
9411 "operands[0] = gen_lowpart (QImode, operands[0]);
9412 operands[1] = gen_lowpart (QImode, operands[1]);
9413 operands[2] = gen_lowpart (QImode, operands[2]);")
9414 \f
9415 ;; Negation instructions
9416
9417 (define_expand "negdi2"
9418 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9419 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9420 (clobber (reg:CC 17))])]
9421 ""
9422 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9423
9424 (define_insn "*negdi2_1"
9425 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9426 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9427 (clobber (reg:CC 17))]
9428 "!TARGET_64BIT
9429 && ix86_unary_operator_ok (NEG, DImode, operands)"
9430 "#")
9431
9432 (define_split
9433 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9434 (neg:DI (match_operand:DI 1 "general_operand" "")))
9435 (clobber (reg:CC 17))]
9436 "!TARGET_64BIT && reload_completed"
9437 [(parallel
9438 [(set (reg:CCZ 17)
9439 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9440 (set (match_dup 0) (neg:SI (match_dup 2)))])
9441 (parallel
9442 [(set (match_dup 1)
9443 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9444 (match_dup 3))
9445 (const_int 0)))
9446 (clobber (reg:CC 17))])
9447 (parallel
9448 [(set (match_dup 1)
9449 (neg:SI (match_dup 1)))
9450 (clobber (reg:CC 17))])]
9451 "split_di (operands+1, 1, operands+2, operands+3);
9452 split_di (operands+0, 1, operands+0, operands+1);")
9453
9454 (define_insn "*negdi2_1_rex64"
9455 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9456 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9457 (clobber (reg:CC 17))]
9458 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9459 "neg{q}\t%0"
9460 [(set_attr "type" "negnot")
9461 (set_attr "mode" "DI")])
9462
9463 ;; The problem with neg is that it does not perform (compare x 0),
9464 ;; it really performs (compare 0 x), which leaves us with the zero
9465 ;; flag being the only useful item.
9466
9467 (define_insn "*negdi2_cmpz_rex64"
9468 [(set (reg:CCZ 17)
9469 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9470 (const_int 0)))
9471 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9472 (neg:DI (match_dup 1)))]
9473 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9474 "neg{q}\t%0"
9475 [(set_attr "type" "negnot")
9476 (set_attr "mode" "DI")])
9477
9478
9479 (define_expand "negsi2"
9480 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9481 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9482 (clobber (reg:CC 17))])]
9483 ""
9484 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9485
9486 (define_insn "*negsi2_1"
9487 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9488 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9489 (clobber (reg:CC 17))]
9490 "ix86_unary_operator_ok (NEG, SImode, operands)"
9491 "neg{l}\t%0"
9492 [(set_attr "type" "negnot")
9493 (set_attr "mode" "SI")])
9494
9495 ;; Combine is quite creative about this pattern.
9496 (define_insn "*negsi2_1_zext"
9497 [(set (match_operand:DI 0 "register_operand" "=r")
9498 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9499 (const_int 32)))
9500 (const_int 32)))
9501 (clobber (reg:CC 17))]
9502 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9503 "neg{l}\t%k0"
9504 [(set_attr "type" "negnot")
9505 (set_attr "mode" "SI")])
9506
9507 ;; The problem with neg is that it does not perform (compare x 0),
9508 ;; it really performs (compare 0 x), which leaves us with the zero
9509 ;; flag being the only useful item.
9510
9511 (define_insn "*negsi2_cmpz"
9512 [(set (reg:CCZ 17)
9513 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9514 (const_int 0)))
9515 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9516 (neg:SI (match_dup 1)))]
9517 "ix86_unary_operator_ok (NEG, SImode, operands)"
9518 "neg{l}\t%0"
9519 [(set_attr "type" "negnot")
9520 (set_attr "mode" "SI")])
9521
9522 (define_insn "*negsi2_cmpz_zext"
9523 [(set (reg:CCZ 17)
9524 (compare:CCZ (lshiftrt:DI
9525 (neg:DI (ashift:DI
9526 (match_operand:DI 1 "register_operand" "0")
9527 (const_int 32)))
9528 (const_int 32))
9529 (const_int 0)))
9530 (set (match_operand:DI 0 "register_operand" "=r")
9531 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9532 (const_int 32)))
9533 (const_int 32)))]
9534 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9535 "neg{l}\t%k0"
9536 [(set_attr "type" "negnot")
9537 (set_attr "mode" "SI")])
9538
9539 (define_expand "neghi2"
9540 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9541 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9542 (clobber (reg:CC 17))])]
9543 "TARGET_HIMODE_MATH"
9544 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9545
9546 (define_insn "*neghi2_1"
9547 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9548 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9549 (clobber (reg:CC 17))]
9550 "ix86_unary_operator_ok (NEG, HImode, operands)"
9551 "neg{w}\t%0"
9552 [(set_attr "type" "negnot")
9553 (set_attr "mode" "HI")])
9554
9555 (define_insn "*neghi2_cmpz"
9556 [(set (reg:CCZ 17)
9557 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9558 (const_int 0)))
9559 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9560 (neg:HI (match_dup 1)))]
9561 "ix86_unary_operator_ok (NEG, HImode, operands)"
9562 "neg{w}\t%0"
9563 [(set_attr "type" "negnot")
9564 (set_attr "mode" "HI")])
9565
9566 (define_expand "negqi2"
9567 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9568 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9569 (clobber (reg:CC 17))])]
9570 "TARGET_QIMODE_MATH"
9571 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9572
9573 (define_insn "*negqi2_1"
9574 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9575 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9576 (clobber (reg:CC 17))]
9577 "ix86_unary_operator_ok (NEG, QImode, operands)"
9578 "neg{b}\t%0"
9579 [(set_attr "type" "negnot")
9580 (set_attr "mode" "QI")])
9581
9582 (define_insn "*negqi2_cmpz"
9583 [(set (reg:CCZ 17)
9584 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9585 (const_int 0)))
9586 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9587 (neg:QI (match_dup 1)))]
9588 "ix86_unary_operator_ok (NEG, QImode, operands)"
9589 "neg{b}\t%0"
9590 [(set_attr "type" "negnot")
9591 (set_attr "mode" "QI")])
9592
9593 ;; Changing of sign for FP values is doable using integer unit too.
9594
9595 (define_expand "negsf2"
9596 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9597 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9598 (clobber (reg:CC 17))])]
9599 "TARGET_80387"
9600 "if (TARGET_SSE)
9601 {
9602 /* In case operand is in memory, we will not use SSE. */
9603 if (memory_operand (operands[0], VOIDmode)
9604 && rtx_equal_p (operands[0], operands[1]))
9605 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9606 else
9607 {
9608 /* Using SSE is tricky, since we need bitwise negation of -0
9609 in register. */
9610 rtx reg = gen_reg_rtx (SFmode);
9611 rtx dest = operands[0];
9612 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9613
9614 operands[1] = force_reg (SFmode, operands[1]);
9615 operands[0] = force_reg (SFmode, operands[0]);
9616 reg = force_reg (V4SFmode,
9617 gen_rtx_CONST_VECTOR (V4SFmode,
9618 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9619 CONST0_RTX (SFmode),
9620 CONST0_RTX (SFmode))));
9621 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9622 if (dest != operands[0])
9623 emit_move_insn (dest, operands[0]);
9624 }
9625 DONE;
9626 }
9627 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9628
9629 (define_insn "negsf2_memory"
9630 [(set (match_operand:SF 0 "memory_operand" "=m")
9631 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9632 (clobber (reg:CC 17))]
9633 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9634 "#")
9635
9636 (define_insn "negsf2_ifs"
9637 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9638 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9639 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9640 (clobber (reg:CC 17))]
9641 "TARGET_SSE
9642 && (reload_in_progress || reload_completed
9643 || (register_operand (operands[0], VOIDmode)
9644 && register_operand (operands[1], VOIDmode)))"
9645 "#")
9646
9647 (define_split
9648 [(set (match_operand:SF 0 "memory_operand" "")
9649 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9650 (use (match_operand:SF 2 "" ""))
9651 (clobber (reg:CC 17))]
9652 ""
9653 [(parallel [(set (match_dup 0)
9654 (neg:SF (match_dup 1)))
9655 (clobber (reg:CC 17))])])
9656
9657 (define_split
9658 [(set (match_operand:SF 0 "register_operand" "")
9659 (neg:SF (match_operand:SF 1 "register_operand" "")))
9660 (use (match_operand:V4SF 2 "" ""))
9661 (clobber (reg:CC 17))]
9662 "reload_completed && !SSE_REG_P (operands[0])"
9663 [(parallel [(set (match_dup 0)
9664 (neg:SF (match_dup 1)))
9665 (clobber (reg:CC 17))])])
9666
9667 (define_split
9668 [(set (match_operand:SF 0 "register_operand" "")
9669 (neg:SF (match_operand:SF 1 "register_operand" "")))
9670 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9671 (clobber (reg:CC 17))]
9672 "reload_completed && SSE_REG_P (operands[0])"
9673 [(set (match_dup 0)
9674 (xor:V4SF (match_dup 1)
9675 (match_dup 2)))]
9676 {
9677 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9678 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9679 if (operands_match_p (operands[0], operands[2]))
9680 {
9681 rtx tmp;
9682 tmp = operands[1];
9683 operands[1] = operands[2];
9684 operands[2] = tmp;
9685 }
9686 })
9687
9688
9689 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9690 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9691 ;; to itself.
9692 (define_insn "*negsf2_if"
9693 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9694 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9695 (clobber (reg:CC 17))]
9696 "TARGET_80387 && !TARGET_SSE
9697 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9698 "#")
9699
9700 (define_split
9701 [(set (match_operand:SF 0 "fp_register_operand" "")
9702 (neg:SF (match_operand:SF 1 "register_operand" "")))
9703 (clobber (reg:CC 17))]
9704 "TARGET_80387 && reload_completed"
9705 [(set (match_dup 0)
9706 (neg:SF (match_dup 1)))]
9707 "")
9708
9709 (define_split
9710 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9711 (neg:SF (match_operand:SF 1 "register_operand" "")))
9712 (clobber (reg:CC 17))]
9713 "TARGET_80387 && reload_completed"
9714 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9715 (clobber (reg:CC 17))])]
9716 "operands[1] = gen_int_mode (0x80000000, SImode);
9717 operands[0] = gen_lowpart (SImode, operands[0]);")
9718
9719 (define_split
9720 [(set (match_operand 0 "memory_operand" "")
9721 (neg (match_operand 1 "memory_operand" "")))
9722 (clobber (reg:CC 17))]
9723 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9724 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9725 (clobber (reg:CC 17))])]
9726 {
9727 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9728
9729 if (GET_MODE (operands[1]) == XFmode)
9730 size = 10;
9731 operands[0] = adjust_address (operands[0], QImode, size - 1);
9732 operands[1] = gen_int_mode (0x80, QImode);
9733 })
9734
9735 (define_expand "negdf2"
9736 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9737 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9738 (clobber (reg:CC 17))])]
9739 "TARGET_80387"
9740 "if (TARGET_SSE2)
9741 {
9742 /* In case operand is in memory, we will not use SSE. */
9743 if (memory_operand (operands[0], VOIDmode)
9744 && rtx_equal_p (operands[0], operands[1]))
9745 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9746 else
9747 {
9748 /* Using SSE is tricky, since we need bitwise negation of -0
9749 in register. */
9750 rtx reg;
9751 #if HOST_BITS_PER_WIDE_INT >= 64
9752 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9753 #else
9754 rtx imm = immed_double_const (0, 0x80000000, DImode);
9755 #endif
9756 rtx dest = operands[0];
9757
9758 operands[1] = force_reg (DFmode, operands[1]);
9759 operands[0] = force_reg (DFmode, operands[0]);
9760 imm = gen_lowpart (DFmode, imm);
9761 reg = force_reg (V2DFmode,
9762 gen_rtx_CONST_VECTOR (V2DFmode,
9763 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9764 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9765 if (dest != operands[0])
9766 emit_move_insn (dest, operands[0]);
9767 }
9768 DONE;
9769 }
9770 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9771
9772 (define_insn "negdf2_memory"
9773 [(set (match_operand:DF 0 "memory_operand" "=m")
9774 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9775 (clobber (reg:CC 17))]
9776 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9777 "#")
9778
9779 (define_insn "negdf2_ifs"
9780 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9781 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9782 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9783 (clobber (reg:CC 17))]
9784 "!TARGET_64BIT && TARGET_SSE2
9785 && (reload_in_progress || reload_completed
9786 || (register_operand (operands[0], VOIDmode)
9787 && register_operand (operands[1], VOIDmode)))"
9788 "#")
9789
9790 (define_insn "*negdf2_ifs_rex64"
9791 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9792 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9793 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9794 (clobber (reg:CC 17))]
9795 "TARGET_64BIT && TARGET_SSE2
9796 && (reload_in_progress || reload_completed
9797 || (register_operand (operands[0], VOIDmode)
9798 && register_operand (operands[1], VOIDmode)))"
9799 "#")
9800
9801 (define_split
9802 [(set (match_operand:DF 0 "memory_operand" "")
9803 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9804 (use (match_operand:V2DF 2 "" ""))
9805 (clobber (reg:CC 17))]
9806 ""
9807 [(parallel [(set (match_dup 0)
9808 (neg:DF (match_dup 1)))
9809 (clobber (reg:CC 17))])])
9810
9811 (define_split
9812 [(set (match_operand:DF 0 "register_operand" "")
9813 (neg:DF (match_operand:DF 1 "register_operand" "")))
9814 (use (match_operand:V2DF 2 "" ""))
9815 (clobber (reg:CC 17))]
9816 "reload_completed && !SSE_REG_P (operands[0])
9817 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9818 [(parallel [(set (match_dup 0)
9819 (neg:DF (match_dup 1)))
9820 (clobber (reg:CC 17))])])
9821
9822 (define_split
9823 [(set (match_operand:DF 0 "register_operand" "")
9824 (neg:DF (match_operand:DF 1 "register_operand" "")))
9825 (use (match_operand:V2DF 2 "" ""))
9826 (clobber (reg:CC 17))]
9827 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9828 [(parallel [(set (match_dup 0)
9829 (xor:DI (match_dup 1) (match_dup 2)))
9830 (clobber (reg:CC 17))])]
9831 "operands[0] = gen_lowpart (DImode, operands[0]);
9832 operands[1] = gen_lowpart (DImode, operands[1]);
9833 operands[2] = gen_lowpart (DImode, operands[2]);")
9834
9835 (define_split
9836 [(set (match_operand:DF 0 "register_operand" "")
9837 (neg:DF (match_operand:DF 1 "register_operand" "")))
9838 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9839 (clobber (reg:CC 17))]
9840 "reload_completed && SSE_REG_P (operands[0])"
9841 [(set (match_dup 0)
9842 (xor:V2DF (match_dup 1)
9843 (match_dup 2)))]
9844 {
9845 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9846 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9847 /* Avoid possible reformatting on the operands. */
9848 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9849 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9850 if (operands_match_p (operands[0], operands[2]))
9851 {
9852 rtx tmp;
9853 tmp = operands[1];
9854 operands[1] = operands[2];
9855 operands[2] = tmp;
9856 }
9857 })
9858
9859 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9860 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9861 ;; to itself.
9862 (define_insn "*negdf2_if"
9863 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9864 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9865 (clobber (reg:CC 17))]
9866 "!TARGET_64BIT && TARGET_80387
9867 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9868 "#")
9869
9870 ;; FIXME: We should to allow integer registers here. Problem is that
9871 ;; we need another scratch register to get constant from.
9872 ;; Forcing constant to mem if no register available in peep2 should be
9873 ;; safe even for PIC mode, because of RIP relative addressing.
9874 (define_insn "*negdf2_if_rex64"
9875 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9876 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9877 (clobber (reg:CC 17))]
9878 "TARGET_64BIT && TARGET_80387
9879 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9880 "#")
9881
9882 (define_split
9883 [(set (match_operand:DF 0 "fp_register_operand" "")
9884 (neg:DF (match_operand:DF 1 "register_operand" "")))
9885 (clobber (reg:CC 17))]
9886 "TARGET_80387 && reload_completed"
9887 [(set (match_dup 0)
9888 (neg:DF (match_dup 1)))]
9889 "")
9890
9891 (define_split
9892 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9893 (neg:DF (match_operand:DF 1 "register_operand" "")))
9894 (clobber (reg:CC 17))]
9895 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9896 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9897 (clobber (reg:CC 17))])]
9898 "operands[4] = gen_int_mode (0x80000000, SImode);
9899 split_di (operands+0, 1, operands+2, operands+3);")
9900
9901 (define_expand "negxf2"
9902 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9903 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9904 (clobber (reg:CC 17))])]
9905 "TARGET_80387"
9906 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9907
9908 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9909 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9910 ;; to itself.
9911 (define_insn "*negxf2_if"
9912 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9913 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9914 (clobber (reg:CC 17))]
9915 "TARGET_80387
9916 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9917 "#")
9918
9919 (define_split
9920 [(set (match_operand:XF 0 "fp_register_operand" "")
9921 (neg:XF (match_operand:XF 1 "register_operand" "")))
9922 (clobber (reg:CC 17))]
9923 "TARGET_80387 && reload_completed"
9924 [(set (match_dup 0)
9925 (neg:XF (match_dup 1)))]
9926 "")
9927
9928 (define_split
9929 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9930 (neg:XF (match_operand:XF 1 "register_operand" "")))
9931 (clobber (reg:CC 17))]
9932 "TARGET_80387 && reload_completed"
9933 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9934 (clobber (reg:CC 17))])]
9935 "operands[1] = GEN_INT (0x8000);
9936 operands[0] = gen_rtx_REG (SImode,
9937 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9938
9939 ;; Conditionalize these after reload. If they matches before reload, we
9940 ;; lose the clobber and ability to use integer instructions.
9941
9942 (define_insn "*negsf2_1"
9943 [(set (match_operand:SF 0 "register_operand" "=f")
9944 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9945 "TARGET_80387 && reload_completed"
9946 "fchs"
9947 [(set_attr "type" "fsgn")
9948 (set_attr "mode" "SF")])
9949
9950 (define_insn "*negdf2_1"
9951 [(set (match_operand:DF 0 "register_operand" "=f")
9952 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9953 "TARGET_80387 && reload_completed"
9954 "fchs"
9955 [(set_attr "type" "fsgn")
9956 (set_attr "mode" "DF")])
9957
9958 (define_insn "*negextendsfdf2"
9959 [(set (match_operand:DF 0 "register_operand" "=f")
9960 (neg:DF (float_extend:DF
9961 (match_operand:SF 1 "register_operand" "0"))))]
9962 "TARGET_80387"
9963 "fchs"
9964 [(set_attr "type" "fsgn")
9965 (set_attr "mode" "DF")])
9966
9967 (define_insn "*negxf2_1"
9968 [(set (match_operand:XF 0 "register_operand" "=f")
9969 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9970 "TARGET_80387 && reload_completed"
9971 "fchs"
9972 [(set_attr "type" "fsgn")
9973 (set_attr "mode" "XF")])
9974
9975 (define_insn "*negextenddfxf2"
9976 [(set (match_operand:XF 0 "register_operand" "=f")
9977 (neg:XF (float_extend:XF
9978 (match_operand:DF 1 "register_operand" "0"))))]
9979 "TARGET_80387"
9980 "fchs"
9981 [(set_attr "type" "fsgn")
9982 (set_attr "mode" "XF")])
9983
9984 (define_insn "*negextendsfxf2"
9985 [(set (match_operand:XF 0 "register_operand" "=f")
9986 (neg:XF (float_extend:XF
9987 (match_operand:SF 1 "register_operand" "0"))))]
9988 "TARGET_80387"
9989 "fchs"
9990 [(set_attr "type" "fsgn")
9991 (set_attr "mode" "XF")])
9992 \f
9993 ;; Absolute value instructions
9994
9995 (define_expand "abssf2"
9996 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9997 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9998 (clobber (reg:CC 17))])]
9999 "TARGET_80387"
10000 "if (TARGET_SSE)
10001 {
10002 /* In case operand is in memory, we will not use SSE. */
10003 if (memory_operand (operands[0], VOIDmode)
10004 && rtx_equal_p (operands[0], operands[1]))
10005 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10006 else
10007 {
10008 /* Using SSE is tricky, since we need bitwise negation of -0
10009 in register. */
10010 rtx reg = gen_reg_rtx (V4SFmode);
10011 rtx dest = operands[0];
10012 rtx imm;
10013
10014 operands[1] = force_reg (SFmode, operands[1]);
10015 operands[0] = force_reg (SFmode, operands[0]);
10016 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10017 reg = force_reg (V4SFmode,
10018 gen_rtx_CONST_VECTOR (V4SFmode,
10019 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10020 CONST0_RTX (SFmode),
10021 CONST0_RTX (SFmode))));
10022 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10023 if (dest != operands[0])
10024 emit_move_insn (dest, operands[0]);
10025 }
10026 DONE;
10027 }
10028 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10029
10030 (define_insn "abssf2_memory"
10031 [(set (match_operand:SF 0 "memory_operand" "=m")
10032 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10033 (clobber (reg:CC 17))]
10034 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10035 "#")
10036
10037 (define_insn "abssf2_ifs"
10038 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10039 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10040 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10041 (clobber (reg:CC 17))]
10042 "TARGET_SSE
10043 && (reload_in_progress || reload_completed
10044 || (register_operand (operands[0], VOIDmode)
10045 && register_operand (operands[1], VOIDmode)))"
10046 "#")
10047
10048 (define_split
10049 [(set (match_operand:SF 0 "memory_operand" "")
10050 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10051 (use (match_operand:V4SF 2 "" ""))
10052 (clobber (reg:CC 17))]
10053 ""
10054 [(parallel [(set (match_dup 0)
10055 (abs:SF (match_dup 1)))
10056 (clobber (reg:CC 17))])])
10057
10058 (define_split
10059 [(set (match_operand:SF 0 "register_operand" "")
10060 (abs:SF (match_operand:SF 1 "register_operand" "")))
10061 (use (match_operand:V4SF 2 "" ""))
10062 (clobber (reg:CC 17))]
10063 "reload_completed && !SSE_REG_P (operands[0])"
10064 [(parallel [(set (match_dup 0)
10065 (abs:SF (match_dup 1)))
10066 (clobber (reg:CC 17))])])
10067
10068 (define_split
10069 [(set (match_operand:SF 0 "register_operand" "")
10070 (abs:SF (match_operand:SF 1 "register_operand" "")))
10071 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10072 (clobber (reg:CC 17))]
10073 "reload_completed && SSE_REG_P (operands[0])"
10074 [(set (match_dup 0)
10075 (and:V4SF (match_dup 1)
10076 (match_dup 2)))]
10077 {
10078 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10079 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10080 if (operands_match_p (operands[0], operands[2]))
10081 {
10082 rtx tmp;
10083 tmp = operands[1];
10084 operands[1] = operands[2];
10085 operands[2] = tmp;
10086 }
10087 })
10088
10089 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10090 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10091 ;; to itself.
10092 (define_insn "*abssf2_if"
10093 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10094 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10095 (clobber (reg:CC 17))]
10096 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10097 "#")
10098
10099 (define_split
10100 [(set (match_operand:SF 0 "fp_register_operand" "")
10101 (abs:SF (match_operand:SF 1 "register_operand" "")))
10102 (clobber (reg:CC 17))]
10103 "TARGET_80387 && reload_completed"
10104 [(set (match_dup 0)
10105 (abs:SF (match_dup 1)))]
10106 "")
10107
10108 (define_split
10109 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10110 (abs:SF (match_operand:SF 1 "register_operand" "")))
10111 (clobber (reg:CC 17))]
10112 "TARGET_80387 && reload_completed"
10113 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10114 (clobber (reg:CC 17))])]
10115 "operands[1] = gen_int_mode (~0x80000000, SImode);
10116 operands[0] = gen_lowpart (SImode, operands[0]);")
10117
10118 (define_split
10119 [(set (match_operand 0 "memory_operand" "")
10120 (abs (match_operand 1 "memory_operand" "")))
10121 (clobber (reg:CC 17))]
10122 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10123 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10124 (clobber (reg:CC 17))])]
10125 {
10126 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10127
10128 if (GET_MODE (operands[1]) == XFmode)
10129 size = 10;
10130 operands[0] = adjust_address (operands[0], QImode, size - 1);
10131 operands[1] = gen_int_mode (~0x80, QImode);
10132 })
10133
10134 (define_expand "absdf2"
10135 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10136 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10137 (clobber (reg:CC 17))])]
10138 "TARGET_80387"
10139 "if (TARGET_SSE2)
10140 {
10141 /* In case operand is in memory, we will not use SSE. */
10142 if (memory_operand (operands[0], VOIDmode)
10143 && rtx_equal_p (operands[0], operands[1]))
10144 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10145 else
10146 {
10147 /* Using SSE is tricky, since we need bitwise negation of -0
10148 in register. */
10149 rtx reg = gen_reg_rtx (V2DFmode);
10150 #if HOST_BITS_PER_WIDE_INT >= 64
10151 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10152 #else
10153 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10154 #endif
10155 rtx dest = operands[0];
10156
10157 operands[1] = force_reg (DFmode, operands[1]);
10158 operands[0] = force_reg (DFmode, operands[0]);
10159
10160 /* Produce LONG_DOUBLE with the proper immediate argument. */
10161 imm = gen_lowpart (DFmode, imm);
10162 reg = force_reg (V2DFmode,
10163 gen_rtx_CONST_VECTOR (V2DFmode,
10164 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10165 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10166 if (dest != operands[0])
10167 emit_move_insn (dest, operands[0]);
10168 }
10169 DONE;
10170 }
10171 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10172
10173 (define_insn "absdf2_memory"
10174 [(set (match_operand:DF 0 "memory_operand" "=m")
10175 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10176 (clobber (reg:CC 17))]
10177 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10178 "#")
10179
10180 (define_insn "absdf2_ifs"
10181 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10182 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10183 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10184 (clobber (reg:CC 17))]
10185 "!TARGET_64BIT && TARGET_SSE2
10186 && (reload_in_progress || reload_completed
10187 || (register_operand (operands[0], VOIDmode)
10188 && register_operand (operands[1], VOIDmode)))"
10189 "#")
10190
10191 (define_insn "*absdf2_ifs_rex64"
10192 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10193 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10194 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10195 (clobber (reg:CC 17))]
10196 "TARGET_64BIT && TARGET_SSE2
10197 && (reload_in_progress || reload_completed
10198 || (register_operand (operands[0], VOIDmode)
10199 && register_operand (operands[1], VOIDmode)))"
10200 "#")
10201
10202 (define_split
10203 [(set (match_operand:DF 0 "memory_operand" "")
10204 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10205 (use (match_operand:V2DF 2 "" ""))
10206 (clobber (reg:CC 17))]
10207 ""
10208 [(parallel [(set (match_dup 0)
10209 (abs:DF (match_dup 1)))
10210 (clobber (reg:CC 17))])])
10211
10212 (define_split
10213 [(set (match_operand:DF 0 "register_operand" "")
10214 (abs:DF (match_operand:DF 1 "register_operand" "")))
10215 (use (match_operand:V2DF 2 "" ""))
10216 (clobber (reg:CC 17))]
10217 "reload_completed && !SSE_REG_P (operands[0])"
10218 [(parallel [(set (match_dup 0)
10219 (abs:DF (match_dup 1)))
10220 (clobber (reg:CC 17))])])
10221
10222 (define_split
10223 [(set (match_operand:DF 0 "register_operand" "")
10224 (abs:DF (match_operand:DF 1 "register_operand" "")))
10225 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10226 (clobber (reg:CC 17))]
10227 "reload_completed && SSE_REG_P (operands[0])"
10228 [(set (match_dup 0)
10229 (and:V2DF (match_dup 1)
10230 (match_dup 2)))]
10231 {
10232 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10233 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10234 /* Avoid possible reformatting on the operands. */
10235 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10236 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10237 if (operands_match_p (operands[0], operands[2]))
10238 {
10239 rtx tmp;
10240 tmp = operands[1];
10241 operands[1] = operands[2];
10242 operands[2] = tmp;
10243 }
10244 })
10245
10246
10247 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10248 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10249 ;; to itself.
10250 (define_insn "*absdf2_if"
10251 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10252 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10253 (clobber (reg:CC 17))]
10254 "!TARGET_64BIT && TARGET_80387
10255 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10256 "#")
10257
10258 ;; FIXME: We should to allow integer registers here. Problem is that
10259 ;; we need another scratch register to get constant from.
10260 ;; Forcing constant to mem if no register available in peep2 should be
10261 ;; safe even for PIC mode, because of RIP relative addressing.
10262 (define_insn "*absdf2_if_rex64"
10263 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10264 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10265 (clobber (reg:CC 17))]
10266 "TARGET_64BIT && TARGET_80387
10267 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10268 "#")
10269
10270 (define_split
10271 [(set (match_operand:DF 0 "fp_register_operand" "")
10272 (abs:DF (match_operand:DF 1 "register_operand" "")))
10273 (clobber (reg:CC 17))]
10274 "TARGET_80387 && reload_completed"
10275 [(set (match_dup 0)
10276 (abs:DF (match_dup 1)))]
10277 "")
10278
10279 (define_split
10280 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10281 (abs:DF (match_operand:DF 1 "register_operand" "")))
10282 (clobber (reg:CC 17))]
10283 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10284 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10285 (clobber (reg:CC 17))])]
10286 "operands[4] = gen_int_mode (~0x80000000, SImode);
10287 split_di (operands+0, 1, operands+2, operands+3);")
10288
10289 (define_expand "absxf2"
10290 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10291 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10292 (clobber (reg:CC 17))])]
10293 "TARGET_80387"
10294 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10295
10296 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10297 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10298 ;; to itself.
10299 (define_insn "*absxf2_if"
10300 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10301 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10302 (clobber (reg:CC 17))]
10303 "TARGET_80387
10304 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10305 "#")
10306
10307 (define_split
10308 [(set (match_operand:XF 0 "fp_register_operand" "")
10309 (abs:XF (match_operand:XF 1 "register_operand" "")))
10310 (clobber (reg:CC 17))]
10311 "TARGET_80387 && reload_completed"
10312 [(set (match_dup 0)
10313 (abs:XF (match_dup 1)))]
10314 "")
10315
10316 (define_split
10317 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10318 (abs:XF (match_operand:XF 1 "register_operand" "")))
10319 (clobber (reg:CC 17))]
10320 "TARGET_80387 && reload_completed"
10321 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10322 (clobber (reg:CC 17))])]
10323 "operands[1] = GEN_INT (~0x8000);
10324 operands[0] = gen_rtx_REG (SImode,
10325 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10326
10327 (define_insn "*abssf2_1"
10328 [(set (match_operand:SF 0 "register_operand" "=f")
10329 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10330 "TARGET_80387 && reload_completed"
10331 "fabs"
10332 [(set_attr "type" "fsgn")
10333 (set_attr "mode" "SF")])
10334
10335 (define_insn "*absdf2_1"
10336 [(set (match_operand:DF 0 "register_operand" "=f")
10337 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10338 "TARGET_80387 && reload_completed"
10339 "fabs"
10340 [(set_attr "type" "fsgn")
10341 (set_attr "mode" "DF")])
10342
10343 (define_insn "*absextendsfdf2"
10344 [(set (match_operand:DF 0 "register_operand" "=f")
10345 (abs:DF (float_extend:DF
10346 (match_operand:SF 1 "register_operand" "0"))))]
10347 "TARGET_80387"
10348 "fabs"
10349 [(set_attr "type" "fsgn")
10350 (set_attr "mode" "DF")])
10351
10352 (define_insn "*absxf2_1"
10353 [(set (match_operand:XF 0 "register_operand" "=f")
10354 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10355 "TARGET_80387 && reload_completed"
10356 "fabs"
10357 [(set_attr "type" "fsgn")
10358 (set_attr "mode" "DF")])
10359
10360 (define_insn "*absextenddfxf2"
10361 [(set (match_operand:XF 0 "register_operand" "=f")
10362 (abs:XF (float_extend:XF
10363 (match_operand:DF 1 "register_operand" "0"))))]
10364 "TARGET_80387"
10365 "fabs"
10366 [(set_attr "type" "fsgn")
10367 (set_attr "mode" "XF")])
10368
10369 (define_insn "*absextendsfxf2"
10370 [(set (match_operand:XF 0 "register_operand" "=f")
10371 (abs:XF (float_extend:XF
10372 (match_operand:SF 1 "register_operand" "0"))))]
10373 "TARGET_80387"
10374 "fabs"
10375 [(set_attr "type" "fsgn")
10376 (set_attr "mode" "XF")])
10377 \f
10378 ;; One complement instructions
10379
10380 (define_expand "one_cmpldi2"
10381 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10382 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10383 "TARGET_64BIT"
10384 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10385
10386 (define_insn "*one_cmpldi2_1_rex64"
10387 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10388 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10389 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10390 "not{q}\t%0"
10391 [(set_attr "type" "negnot")
10392 (set_attr "mode" "DI")])
10393
10394 (define_insn "*one_cmpldi2_2_rex64"
10395 [(set (reg 17)
10396 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10397 (const_int 0)))
10398 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10399 (not:DI (match_dup 1)))]
10400 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10401 && ix86_unary_operator_ok (NOT, DImode, operands)"
10402 "#"
10403 [(set_attr "type" "alu1")
10404 (set_attr "mode" "DI")])
10405
10406 (define_split
10407 [(set (reg 17)
10408 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10409 (const_int 0)))
10410 (set (match_operand:DI 0 "nonimmediate_operand" "")
10411 (not:DI (match_dup 1)))]
10412 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10413 [(parallel [(set (reg:CCNO 17)
10414 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10415 (const_int 0)))
10416 (set (match_dup 0)
10417 (xor:DI (match_dup 1) (const_int -1)))])]
10418 "")
10419
10420 (define_expand "one_cmplsi2"
10421 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10422 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10423 ""
10424 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10425
10426 (define_insn "*one_cmplsi2_1"
10427 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10428 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10429 "ix86_unary_operator_ok (NOT, SImode, operands)"
10430 "not{l}\t%0"
10431 [(set_attr "type" "negnot")
10432 (set_attr "mode" "SI")])
10433
10434 ;; ??? Currently never generated - xor is used instead.
10435 (define_insn "*one_cmplsi2_1_zext"
10436 [(set (match_operand:DI 0 "register_operand" "=r")
10437 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10438 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10439 "not{l}\t%k0"
10440 [(set_attr "type" "negnot")
10441 (set_attr "mode" "SI")])
10442
10443 (define_insn "*one_cmplsi2_2"
10444 [(set (reg 17)
10445 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10446 (const_int 0)))
10447 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10448 (not:SI (match_dup 1)))]
10449 "ix86_match_ccmode (insn, CCNOmode)
10450 && ix86_unary_operator_ok (NOT, SImode, operands)"
10451 "#"
10452 [(set_attr "type" "alu1")
10453 (set_attr "mode" "SI")])
10454
10455 (define_split
10456 [(set (reg 17)
10457 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10458 (const_int 0)))
10459 (set (match_operand:SI 0 "nonimmediate_operand" "")
10460 (not:SI (match_dup 1)))]
10461 "ix86_match_ccmode (insn, CCNOmode)"
10462 [(parallel [(set (reg:CCNO 17)
10463 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10464 (const_int 0)))
10465 (set (match_dup 0)
10466 (xor:SI (match_dup 1) (const_int -1)))])]
10467 "")
10468
10469 ;; ??? Currently never generated - xor is used instead.
10470 (define_insn "*one_cmplsi2_2_zext"
10471 [(set (reg 17)
10472 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10473 (const_int 0)))
10474 (set (match_operand:DI 0 "register_operand" "=r")
10475 (zero_extend:DI (not:SI (match_dup 1))))]
10476 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10477 && ix86_unary_operator_ok (NOT, SImode, operands)"
10478 "#"
10479 [(set_attr "type" "alu1")
10480 (set_attr "mode" "SI")])
10481
10482 (define_split
10483 [(set (reg 17)
10484 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10485 (const_int 0)))
10486 (set (match_operand:DI 0 "register_operand" "")
10487 (zero_extend:DI (not:SI (match_dup 1))))]
10488 "ix86_match_ccmode (insn, CCNOmode)"
10489 [(parallel [(set (reg:CCNO 17)
10490 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10491 (const_int 0)))
10492 (set (match_dup 0)
10493 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10494 "")
10495
10496 (define_expand "one_cmplhi2"
10497 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10498 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10499 "TARGET_HIMODE_MATH"
10500 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10501
10502 (define_insn "*one_cmplhi2_1"
10503 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10504 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10505 "ix86_unary_operator_ok (NOT, HImode, operands)"
10506 "not{w}\t%0"
10507 [(set_attr "type" "negnot")
10508 (set_attr "mode" "HI")])
10509
10510 (define_insn "*one_cmplhi2_2"
10511 [(set (reg 17)
10512 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10513 (const_int 0)))
10514 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10515 (not:HI (match_dup 1)))]
10516 "ix86_match_ccmode (insn, CCNOmode)
10517 && ix86_unary_operator_ok (NEG, HImode, operands)"
10518 "#"
10519 [(set_attr "type" "alu1")
10520 (set_attr "mode" "HI")])
10521
10522 (define_split
10523 [(set (reg 17)
10524 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10525 (const_int 0)))
10526 (set (match_operand:HI 0 "nonimmediate_operand" "")
10527 (not:HI (match_dup 1)))]
10528 "ix86_match_ccmode (insn, CCNOmode)"
10529 [(parallel [(set (reg:CCNO 17)
10530 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10531 (const_int 0)))
10532 (set (match_dup 0)
10533 (xor:HI (match_dup 1) (const_int -1)))])]
10534 "")
10535
10536 ;; %%% Potential partial reg stall on alternative 1. What to do?
10537 (define_expand "one_cmplqi2"
10538 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10539 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10540 "TARGET_QIMODE_MATH"
10541 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10542
10543 (define_insn "*one_cmplqi2_1"
10544 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10545 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10546 "ix86_unary_operator_ok (NOT, QImode, operands)"
10547 "@
10548 not{b}\t%0
10549 not{l}\t%k0"
10550 [(set_attr "type" "negnot")
10551 (set_attr "mode" "QI,SI")])
10552
10553 (define_insn "*one_cmplqi2_2"
10554 [(set (reg 17)
10555 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10556 (const_int 0)))
10557 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10558 (not:QI (match_dup 1)))]
10559 "ix86_match_ccmode (insn, CCNOmode)
10560 && ix86_unary_operator_ok (NOT, QImode, operands)"
10561 "#"
10562 [(set_attr "type" "alu1")
10563 (set_attr "mode" "QI")])
10564
10565 (define_split
10566 [(set (reg 17)
10567 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10568 (const_int 0)))
10569 (set (match_operand:QI 0 "nonimmediate_operand" "")
10570 (not:QI (match_dup 1)))]
10571 "ix86_match_ccmode (insn, CCNOmode)"
10572 [(parallel [(set (reg:CCNO 17)
10573 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10574 (const_int 0)))
10575 (set (match_dup 0)
10576 (xor:QI (match_dup 1) (const_int -1)))])]
10577 "")
10578 \f
10579 ;; Arithmetic shift instructions
10580
10581 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10582 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10583 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10584 ;; from the assembler input.
10585 ;;
10586 ;; This instruction shifts the target reg/mem as usual, but instead of
10587 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10588 ;; is a left shift double, bits are taken from the high order bits of
10589 ;; reg, else if the insn is a shift right double, bits are taken from the
10590 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10591 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10592 ;;
10593 ;; Since sh[lr]d does not change the `reg' operand, that is done
10594 ;; separately, making all shifts emit pairs of shift double and normal
10595 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10596 ;; support a 63 bit shift, each shift where the count is in a reg expands
10597 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10598 ;;
10599 ;; If the shift count is a constant, we need never emit more than one
10600 ;; shift pair, instead using moves and sign extension for counts greater
10601 ;; than 31.
10602
10603 (define_expand "ashldi3"
10604 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10605 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10606 (match_operand:QI 2 "nonmemory_operand" "")))
10607 (clobber (reg:CC 17))])]
10608 ""
10609 {
10610 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10611 {
10612 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10613 DONE;
10614 }
10615 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10616 DONE;
10617 })
10618
10619 (define_insn "*ashldi3_1_rex64"
10620 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10621 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10622 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10623 (clobber (reg:CC 17))]
10624 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10625 {
10626 switch (get_attr_type (insn))
10627 {
10628 case TYPE_ALU:
10629 if (operands[2] != const1_rtx)
10630 abort ();
10631 if (!rtx_equal_p (operands[0], operands[1]))
10632 abort ();
10633 return "add{q}\t{%0, %0|%0, %0}";
10634
10635 case TYPE_LEA:
10636 if (GET_CODE (operands[2]) != CONST_INT
10637 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10638 abort ();
10639 operands[1] = gen_rtx_MULT (DImode, operands[1],
10640 GEN_INT (1 << INTVAL (operands[2])));
10641 return "lea{q}\t{%a1, %0|%0, %a1}";
10642
10643 default:
10644 if (REG_P (operands[2]))
10645 return "sal{q}\t{%b2, %0|%0, %b2}";
10646 else if (operands[2] == const1_rtx
10647 && (TARGET_SHIFT1 || optimize_size))
10648 return "sal{q}\t%0";
10649 else
10650 return "sal{q}\t{%2, %0|%0, %2}";
10651 }
10652 }
10653 [(set (attr "type")
10654 (cond [(eq_attr "alternative" "1")
10655 (const_string "lea")
10656 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10657 (const_int 0))
10658 (match_operand 0 "register_operand" ""))
10659 (match_operand 2 "const1_operand" ""))
10660 (const_string "alu")
10661 ]
10662 (const_string "ishift")))
10663 (set_attr "mode" "DI")])
10664
10665 ;; Convert lea to the lea pattern to avoid flags dependency.
10666 (define_split
10667 [(set (match_operand:DI 0 "register_operand" "")
10668 (ashift:DI (match_operand:DI 1 "register_operand" "")
10669 (match_operand:QI 2 "immediate_operand" "")))
10670 (clobber (reg:CC 17))]
10671 "TARGET_64BIT && reload_completed
10672 && true_regnum (operands[0]) != true_regnum (operands[1])"
10673 [(set (match_dup 0)
10674 (mult:DI (match_dup 1)
10675 (match_dup 2)))]
10676 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10677
10678 ;; This pattern can't accept a variable shift count, since shifts by
10679 ;; zero don't affect the flags. We assume that shifts by constant
10680 ;; zero are optimized away.
10681 (define_insn "*ashldi3_cmp_rex64"
10682 [(set (reg 17)
10683 (compare
10684 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10685 (match_operand:QI 2 "immediate_operand" "e"))
10686 (const_int 0)))
10687 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10688 (ashift:DI (match_dup 1) (match_dup 2)))]
10689 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10690 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10691 {
10692 switch (get_attr_type (insn))
10693 {
10694 case TYPE_ALU:
10695 if (operands[2] != const1_rtx)
10696 abort ();
10697 return "add{q}\t{%0, %0|%0, %0}";
10698
10699 default:
10700 if (REG_P (operands[2]))
10701 return "sal{q}\t{%b2, %0|%0, %b2}";
10702 else if (operands[2] == const1_rtx
10703 && (TARGET_SHIFT1 || optimize_size))
10704 return "sal{q}\t%0";
10705 else
10706 return "sal{q}\t{%2, %0|%0, %2}";
10707 }
10708 }
10709 [(set (attr "type")
10710 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10711 (const_int 0))
10712 (match_operand 0 "register_operand" ""))
10713 (match_operand 2 "const1_operand" ""))
10714 (const_string "alu")
10715 ]
10716 (const_string "ishift")))
10717 (set_attr "mode" "DI")])
10718
10719 (define_insn "ashldi3_1"
10720 [(set (match_operand:DI 0 "register_operand" "=r")
10721 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10722 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10723 (clobber (match_scratch:SI 3 "=&r"))
10724 (clobber (reg:CC 17))]
10725 "!TARGET_64BIT && TARGET_CMOVE"
10726 "#"
10727 [(set_attr "type" "multi")])
10728
10729 (define_insn "*ashldi3_2"
10730 [(set (match_operand:DI 0 "register_operand" "=r")
10731 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10732 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10733 (clobber (reg:CC 17))]
10734 "!TARGET_64BIT"
10735 "#"
10736 [(set_attr "type" "multi")])
10737
10738 (define_split
10739 [(set (match_operand:DI 0 "register_operand" "")
10740 (ashift:DI (match_operand:DI 1 "register_operand" "")
10741 (match_operand:QI 2 "nonmemory_operand" "")))
10742 (clobber (match_scratch:SI 3 ""))
10743 (clobber (reg:CC 17))]
10744 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10745 [(const_int 0)]
10746 "ix86_split_ashldi (operands, operands[3]); DONE;")
10747
10748 (define_split
10749 [(set (match_operand:DI 0 "register_operand" "")
10750 (ashift:DI (match_operand:DI 1 "register_operand" "")
10751 (match_operand:QI 2 "nonmemory_operand" "")))
10752 (clobber (reg:CC 17))]
10753 "!TARGET_64BIT && reload_completed"
10754 [(const_int 0)]
10755 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10756
10757 (define_insn "x86_shld_1"
10758 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10759 (ior:SI (ashift:SI (match_dup 0)
10760 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10761 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10762 (minus:QI (const_int 32) (match_dup 2)))))
10763 (clobber (reg:CC 17))]
10764 ""
10765 "@
10766 shld{l}\t{%2, %1, %0|%0, %1, %2}
10767 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10768 [(set_attr "type" "ishift")
10769 (set_attr "prefix_0f" "1")
10770 (set_attr "mode" "SI")
10771 (set_attr "pent_pair" "np")
10772 (set_attr "athlon_decode" "vector")])
10773
10774 (define_expand "x86_shift_adj_1"
10775 [(set (reg:CCZ 17)
10776 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10777 (const_int 32))
10778 (const_int 0)))
10779 (set (match_operand:SI 0 "register_operand" "")
10780 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10781 (match_operand:SI 1 "register_operand" "")
10782 (match_dup 0)))
10783 (set (match_dup 1)
10784 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10785 (match_operand:SI 3 "register_operand" "r")
10786 (match_dup 1)))]
10787 "TARGET_CMOVE"
10788 "")
10789
10790 (define_expand "x86_shift_adj_2"
10791 [(use (match_operand:SI 0 "register_operand" ""))
10792 (use (match_operand:SI 1 "register_operand" ""))
10793 (use (match_operand:QI 2 "register_operand" ""))]
10794 ""
10795 {
10796 rtx label = gen_label_rtx ();
10797 rtx tmp;
10798
10799 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10800
10801 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10802 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10803 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10804 gen_rtx_LABEL_REF (VOIDmode, label),
10805 pc_rtx);
10806 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10807 JUMP_LABEL (tmp) = label;
10808
10809 emit_move_insn (operands[0], operands[1]);
10810 emit_move_insn (operands[1], const0_rtx);
10811
10812 emit_label (label);
10813 LABEL_NUSES (label) = 1;
10814
10815 DONE;
10816 })
10817
10818 (define_expand "ashlsi3"
10819 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10820 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10821 (match_operand:QI 2 "nonmemory_operand" "")))
10822 (clobber (reg:CC 17))]
10823 ""
10824 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10825
10826 (define_insn "*ashlsi3_1"
10827 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10828 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10829 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10830 (clobber (reg:CC 17))]
10831 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10832 {
10833 switch (get_attr_type (insn))
10834 {
10835 case TYPE_ALU:
10836 if (operands[2] != const1_rtx)
10837 abort ();
10838 if (!rtx_equal_p (operands[0], operands[1]))
10839 abort ();
10840 return "add{l}\t{%0, %0|%0, %0}";
10841
10842 case TYPE_LEA:
10843 return "#";
10844
10845 default:
10846 if (REG_P (operands[2]))
10847 return "sal{l}\t{%b2, %0|%0, %b2}";
10848 else if (operands[2] == const1_rtx
10849 && (TARGET_SHIFT1 || optimize_size))
10850 return "sal{l}\t%0";
10851 else
10852 return "sal{l}\t{%2, %0|%0, %2}";
10853 }
10854 }
10855 [(set (attr "type")
10856 (cond [(eq_attr "alternative" "1")
10857 (const_string "lea")
10858 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10859 (const_int 0))
10860 (match_operand 0 "register_operand" ""))
10861 (match_operand 2 "const1_operand" ""))
10862 (const_string "alu")
10863 ]
10864 (const_string "ishift")))
10865 (set_attr "mode" "SI")])
10866
10867 ;; Convert lea to the lea pattern to avoid flags dependency.
10868 (define_split
10869 [(set (match_operand 0 "register_operand" "")
10870 (ashift (match_operand 1 "index_register_operand" "")
10871 (match_operand:QI 2 "const_int_operand" "")))
10872 (clobber (reg:CC 17))]
10873 "reload_completed
10874 && true_regnum (operands[0]) != true_regnum (operands[1])"
10875 [(const_int 0)]
10876 {
10877 rtx pat;
10878 operands[0] = gen_lowpart (SImode, operands[0]);
10879 operands[1] = gen_lowpart (Pmode, operands[1]);
10880 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10881 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10882 if (Pmode != SImode)
10883 pat = gen_rtx_SUBREG (SImode, pat, 0);
10884 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10885 DONE;
10886 })
10887
10888 ;; Rare case of shifting RSP is handled by generating move and shift
10889 (define_split
10890 [(set (match_operand 0 "register_operand" "")
10891 (ashift (match_operand 1 "register_operand" "")
10892 (match_operand:QI 2 "const_int_operand" "")))
10893 (clobber (reg:CC 17))]
10894 "reload_completed
10895 && true_regnum (operands[0]) != true_regnum (operands[1])"
10896 [(const_int 0)]
10897 {
10898 rtx pat, clob;
10899 emit_move_insn (operands[1], operands[0]);
10900 pat = gen_rtx_SET (VOIDmode, operands[0],
10901 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10902 operands[0], operands[2]));
10903 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10904 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10905 DONE;
10906 })
10907
10908 (define_insn "*ashlsi3_1_zext"
10909 [(set (match_operand:DI 0 "register_operand" "=r,r")
10910 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10911 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10912 (clobber (reg:CC 17))]
10913 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10914 {
10915 switch (get_attr_type (insn))
10916 {
10917 case TYPE_ALU:
10918 if (operands[2] != const1_rtx)
10919 abort ();
10920 return "add{l}\t{%k0, %k0|%k0, %k0}";
10921
10922 case TYPE_LEA:
10923 return "#";
10924
10925 default:
10926 if (REG_P (operands[2]))
10927 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10928 else if (operands[2] == const1_rtx
10929 && (TARGET_SHIFT1 || optimize_size))
10930 return "sal{l}\t%k0";
10931 else
10932 return "sal{l}\t{%2, %k0|%k0, %2}";
10933 }
10934 }
10935 [(set (attr "type")
10936 (cond [(eq_attr "alternative" "1")
10937 (const_string "lea")
10938 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10939 (const_int 0))
10940 (match_operand 2 "const1_operand" ""))
10941 (const_string "alu")
10942 ]
10943 (const_string "ishift")))
10944 (set_attr "mode" "SI")])
10945
10946 ;; Convert lea to the lea pattern to avoid flags dependency.
10947 (define_split
10948 [(set (match_operand:DI 0 "register_operand" "")
10949 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10950 (match_operand:QI 2 "const_int_operand" ""))))
10951 (clobber (reg:CC 17))]
10952 "TARGET_64BIT && reload_completed
10953 && true_regnum (operands[0]) != true_regnum (operands[1])"
10954 [(set (match_dup 0) (zero_extend:DI
10955 (subreg:SI (mult:SI (match_dup 1)
10956 (match_dup 2)) 0)))]
10957 {
10958 operands[1] = gen_lowpart (Pmode, operands[1]);
10959 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10960 })
10961
10962 ;; This pattern can't accept a variable shift count, since shifts by
10963 ;; zero don't affect the flags. We assume that shifts by constant
10964 ;; zero are optimized away.
10965 (define_insn "*ashlsi3_cmp"
10966 [(set (reg 17)
10967 (compare
10968 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10969 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10970 (const_int 0)))
10971 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10972 (ashift:SI (match_dup 1) (match_dup 2)))]
10973 "ix86_match_ccmode (insn, CCGOCmode)
10974 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10975 {
10976 switch (get_attr_type (insn))
10977 {
10978 case TYPE_ALU:
10979 if (operands[2] != const1_rtx)
10980 abort ();
10981 return "add{l}\t{%0, %0|%0, %0}";
10982
10983 default:
10984 if (REG_P (operands[2]))
10985 return "sal{l}\t{%b2, %0|%0, %b2}";
10986 else if (operands[2] == const1_rtx
10987 && (TARGET_SHIFT1 || optimize_size))
10988 return "sal{l}\t%0";
10989 else
10990 return "sal{l}\t{%2, %0|%0, %2}";
10991 }
10992 }
10993 [(set (attr "type")
10994 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10995 (const_int 0))
10996 (match_operand 0 "register_operand" ""))
10997 (match_operand 2 "const1_operand" ""))
10998 (const_string "alu")
10999 ]
11000 (const_string "ishift")))
11001 (set_attr "mode" "SI")])
11002
11003 (define_insn "*ashlsi3_cmp_zext"
11004 [(set (reg 17)
11005 (compare
11006 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11007 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11008 (const_int 0)))
11009 (set (match_operand:DI 0 "register_operand" "=r")
11010 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11011 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11012 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11013 {
11014 switch (get_attr_type (insn))
11015 {
11016 case TYPE_ALU:
11017 if (operands[2] != const1_rtx)
11018 abort ();
11019 return "add{l}\t{%k0, %k0|%k0, %k0}";
11020
11021 default:
11022 if (REG_P (operands[2]))
11023 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11024 else if (operands[2] == const1_rtx
11025 && (TARGET_SHIFT1 || optimize_size))
11026 return "sal{l}\t%k0";
11027 else
11028 return "sal{l}\t{%2, %k0|%k0, %2}";
11029 }
11030 }
11031 [(set (attr "type")
11032 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11033 (const_int 0))
11034 (match_operand 2 "const1_operand" ""))
11035 (const_string "alu")
11036 ]
11037 (const_string "ishift")))
11038 (set_attr "mode" "SI")])
11039
11040 (define_expand "ashlhi3"
11041 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11042 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11043 (match_operand:QI 2 "nonmemory_operand" "")))
11044 (clobber (reg:CC 17))]
11045 "TARGET_HIMODE_MATH"
11046 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11047
11048 (define_insn "*ashlhi3_1_lea"
11049 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11050 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11051 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11052 (clobber (reg:CC 17))]
11053 "!TARGET_PARTIAL_REG_STALL
11054 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11055 {
11056 switch (get_attr_type (insn))
11057 {
11058 case TYPE_LEA:
11059 return "#";
11060 case TYPE_ALU:
11061 if (operands[2] != const1_rtx)
11062 abort ();
11063 return "add{w}\t{%0, %0|%0, %0}";
11064
11065 default:
11066 if (REG_P (operands[2]))
11067 return "sal{w}\t{%b2, %0|%0, %b2}";
11068 else if (operands[2] == const1_rtx
11069 && (TARGET_SHIFT1 || optimize_size))
11070 return "sal{w}\t%0";
11071 else
11072 return "sal{w}\t{%2, %0|%0, %2}";
11073 }
11074 }
11075 [(set (attr "type")
11076 (cond [(eq_attr "alternative" "1")
11077 (const_string "lea")
11078 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11079 (const_int 0))
11080 (match_operand 0 "register_operand" ""))
11081 (match_operand 2 "const1_operand" ""))
11082 (const_string "alu")
11083 ]
11084 (const_string "ishift")))
11085 (set_attr "mode" "HI,SI")])
11086
11087 (define_insn "*ashlhi3_1"
11088 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11089 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11090 (match_operand:QI 2 "nonmemory_operand" "cI")))
11091 (clobber (reg:CC 17))]
11092 "TARGET_PARTIAL_REG_STALL
11093 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11094 {
11095 switch (get_attr_type (insn))
11096 {
11097 case TYPE_ALU:
11098 if (operands[2] != const1_rtx)
11099 abort ();
11100 return "add{w}\t{%0, %0|%0, %0}";
11101
11102 default:
11103 if (REG_P (operands[2]))
11104 return "sal{w}\t{%b2, %0|%0, %b2}";
11105 else if (operands[2] == const1_rtx
11106 && (TARGET_SHIFT1 || optimize_size))
11107 return "sal{w}\t%0";
11108 else
11109 return "sal{w}\t{%2, %0|%0, %2}";
11110 }
11111 }
11112 [(set (attr "type")
11113 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11114 (const_int 0))
11115 (match_operand 0 "register_operand" ""))
11116 (match_operand 2 "const1_operand" ""))
11117 (const_string "alu")
11118 ]
11119 (const_string "ishift")))
11120 (set_attr "mode" "HI")])
11121
11122 ;; This pattern can't accept a variable shift count, since shifts by
11123 ;; zero don't affect the flags. We assume that shifts by constant
11124 ;; zero are optimized away.
11125 (define_insn "*ashlhi3_cmp"
11126 [(set (reg 17)
11127 (compare
11128 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11129 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11130 (const_int 0)))
11131 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11132 (ashift:HI (match_dup 1) (match_dup 2)))]
11133 "ix86_match_ccmode (insn, CCGOCmode)
11134 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11135 {
11136 switch (get_attr_type (insn))
11137 {
11138 case TYPE_ALU:
11139 if (operands[2] != const1_rtx)
11140 abort ();
11141 return "add{w}\t{%0, %0|%0, %0}";
11142
11143 default:
11144 if (REG_P (operands[2]))
11145 return "sal{w}\t{%b2, %0|%0, %b2}";
11146 else if (operands[2] == const1_rtx
11147 && (TARGET_SHIFT1 || optimize_size))
11148 return "sal{w}\t%0";
11149 else
11150 return "sal{w}\t{%2, %0|%0, %2}";
11151 }
11152 }
11153 [(set (attr "type")
11154 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11155 (const_int 0))
11156 (match_operand 0 "register_operand" ""))
11157 (match_operand 2 "const1_operand" ""))
11158 (const_string "alu")
11159 ]
11160 (const_string "ishift")))
11161 (set_attr "mode" "HI")])
11162
11163 (define_expand "ashlqi3"
11164 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11165 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11166 (match_operand:QI 2 "nonmemory_operand" "")))
11167 (clobber (reg:CC 17))]
11168 "TARGET_QIMODE_MATH"
11169 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11170
11171 ;; %%% Potential partial reg stall on alternative 2. What to do?
11172
11173 (define_insn "*ashlqi3_1_lea"
11174 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11175 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11176 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11177 (clobber (reg:CC 17))]
11178 "!TARGET_PARTIAL_REG_STALL
11179 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11180 {
11181 switch (get_attr_type (insn))
11182 {
11183 case TYPE_LEA:
11184 return "#";
11185 case TYPE_ALU:
11186 if (operands[2] != const1_rtx)
11187 abort ();
11188 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11189 return "add{l}\t{%k0, %k0|%k0, %k0}";
11190 else
11191 return "add{b}\t{%0, %0|%0, %0}";
11192
11193 default:
11194 if (REG_P (operands[2]))
11195 {
11196 if (get_attr_mode (insn) == MODE_SI)
11197 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11198 else
11199 return "sal{b}\t{%b2, %0|%0, %b2}";
11200 }
11201 else if (operands[2] == const1_rtx
11202 && (TARGET_SHIFT1 || optimize_size))
11203 {
11204 if (get_attr_mode (insn) == MODE_SI)
11205 return "sal{l}\t%0";
11206 else
11207 return "sal{b}\t%0";
11208 }
11209 else
11210 {
11211 if (get_attr_mode (insn) == MODE_SI)
11212 return "sal{l}\t{%2, %k0|%k0, %2}";
11213 else
11214 return "sal{b}\t{%2, %0|%0, %2}";
11215 }
11216 }
11217 }
11218 [(set (attr "type")
11219 (cond [(eq_attr "alternative" "2")
11220 (const_string "lea")
11221 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11222 (const_int 0))
11223 (match_operand 0 "register_operand" ""))
11224 (match_operand 2 "const1_operand" ""))
11225 (const_string "alu")
11226 ]
11227 (const_string "ishift")))
11228 (set_attr "mode" "QI,SI,SI")])
11229
11230 (define_insn "*ashlqi3_1"
11231 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11232 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11233 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11234 (clobber (reg:CC 17))]
11235 "TARGET_PARTIAL_REG_STALL
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 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11244 return "add{l}\t{%k0, %k0|%k0, %k0}";
11245 else
11246 return "add{b}\t{%0, %0|%0, %0}";
11247
11248 default:
11249 if (REG_P (operands[2]))
11250 {
11251 if (get_attr_mode (insn) == MODE_SI)
11252 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11253 else
11254 return "sal{b}\t{%b2, %0|%0, %b2}";
11255 }
11256 else if (operands[2] == const1_rtx
11257 && (TARGET_SHIFT1 || optimize_size))
11258 {
11259 if (get_attr_mode (insn) == MODE_SI)
11260 return "sal{l}\t%0";
11261 else
11262 return "sal{b}\t%0";
11263 }
11264 else
11265 {
11266 if (get_attr_mode (insn) == MODE_SI)
11267 return "sal{l}\t{%2, %k0|%k0, %2}";
11268 else
11269 return "sal{b}\t{%2, %0|%0, %2}";
11270 }
11271 }
11272 }
11273 [(set (attr "type")
11274 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11275 (const_int 0))
11276 (match_operand 0 "register_operand" ""))
11277 (match_operand 2 "const1_operand" ""))
11278 (const_string "alu")
11279 ]
11280 (const_string "ishift")))
11281 (set_attr "mode" "QI,SI")])
11282
11283 ;; This pattern can't accept a variable shift count, since shifts by
11284 ;; zero don't affect the flags. We assume that shifts by constant
11285 ;; zero are optimized away.
11286 (define_insn "*ashlqi3_cmp"
11287 [(set (reg 17)
11288 (compare
11289 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11290 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11291 (const_int 0)))
11292 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11293 (ashift:QI (match_dup 1) (match_dup 2)))]
11294 "ix86_match_ccmode (insn, CCGOCmode)
11295 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11296 {
11297 switch (get_attr_type (insn))
11298 {
11299 case TYPE_ALU:
11300 if (operands[2] != const1_rtx)
11301 abort ();
11302 return "add{b}\t{%0, %0|%0, %0}";
11303
11304 default:
11305 if (REG_P (operands[2]))
11306 return "sal{b}\t{%b2, %0|%0, %b2}";
11307 else if (operands[2] == const1_rtx
11308 && (TARGET_SHIFT1 || optimize_size))
11309 return "sal{b}\t%0";
11310 else
11311 return "sal{b}\t{%2, %0|%0, %2}";
11312 }
11313 }
11314 [(set (attr "type")
11315 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11316 (const_int 0))
11317 (match_operand 0 "register_operand" ""))
11318 (match_operand 2 "const1_operand" ""))
11319 (const_string "alu")
11320 ]
11321 (const_string "ishift")))
11322 (set_attr "mode" "QI")])
11323
11324 ;; See comment above `ashldi3' about how this works.
11325
11326 (define_expand "ashrdi3"
11327 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11328 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11329 (match_operand:QI 2 "nonmemory_operand" "")))
11330 (clobber (reg:CC 17))])]
11331 ""
11332 {
11333 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11334 {
11335 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11336 DONE;
11337 }
11338 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11339 DONE;
11340 })
11341
11342 (define_insn "ashrdi3_63_rex64"
11343 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11344 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11345 (match_operand:DI 2 "const_int_operand" "i,i")))
11346 (clobber (reg:CC 17))]
11347 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11348 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11349 "@
11350 {cqto|cqo}
11351 sar{q}\t{%2, %0|%0, %2}"
11352 [(set_attr "type" "imovx,ishift")
11353 (set_attr "prefix_0f" "0,*")
11354 (set_attr "length_immediate" "0,*")
11355 (set_attr "modrm" "0,1")
11356 (set_attr "mode" "DI")])
11357
11358 (define_insn "*ashrdi3_1_one_bit_rex64"
11359 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11360 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11361 (match_operand:QI 2 "const1_operand" "")))
11362 (clobber (reg:CC 17))]
11363 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11364 && (TARGET_SHIFT1 || optimize_size)"
11365 "sar{q}\t%0"
11366 [(set_attr "type" "ishift")
11367 (set (attr "length")
11368 (if_then_else (match_operand:DI 0 "register_operand" "")
11369 (const_string "2")
11370 (const_string "*")))])
11371
11372 (define_insn "*ashrdi3_1_rex64"
11373 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11374 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11375 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11376 (clobber (reg:CC 17))]
11377 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11378 "@
11379 sar{q}\t{%2, %0|%0, %2}
11380 sar{q}\t{%b2, %0|%0, %b2}"
11381 [(set_attr "type" "ishift")
11382 (set_attr "mode" "DI")])
11383
11384 ;; This pattern can't accept a variable shift count, since shifts by
11385 ;; zero don't affect the flags. We assume that shifts by constant
11386 ;; zero are optimized away.
11387 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11388 [(set (reg 17)
11389 (compare
11390 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11391 (match_operand:QI 2 "const1_operand" ""))
11392 (const_int 0)))
11393 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11394 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11395 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11396 && (TARGET_SHIFT1 || optimize_size)
11397 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11398 "sar{q}\t%0"
11399 [(set_attr "type" "ishift")
11400 (set (attr "length")
11401 (if_then_else (match_operand:DI 0 "register_operand" "")
11402 (const_string "2")
11403 (const_string "*")))])
11404
11405 ;; This pattern can't accept a variable shift count, since shifts by
11406 ;; zero don't affect the flags. We assume that shifts by constant
11407 ;; zero are optimized away.
11408 (define_insn "*ashrdi3_cmp_rex64"
11409 [(set (reg 17)
11410 (compare
11411 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412 (match_operand:QI 2 "const_int_operand" "n"))
11413 (const_int 0)))
11414 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11415 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11416 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11418 "sar{q}\t{%2, %0|%0, %2}"
11419 [(set_attr "type" "ishift")
11420 (set_attr "mode" "DI")])
11421
11422
11423 (define_insn "ashrdi3_1"
11424 [(set (match_operand:DI 0 "register_operand" "=r")
11425 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11426 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11427 (clobber (match_scratch:SI 3 "=&r"))
11428 (clobber (reg:CC 17))]
11429 "!TARGET_64BIT && TARGET_CMOVE"
11430 "#"
11431 [(set_attr "type" "multi")])
11432
11433 (define_insn "*ashrdi3_2"
11434 [(set (match_operand:DI 0 "register_operand" "=r")
11435 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11436 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11437 (clobber (reg:CC 17))]
11438 "!TARGET_64BIT"
11439 "#"
11440 [(set_attr "type" "multi")])
11441
11442 (define_split
11443 [(set (match_operand:DI 0 "register_operand" "")
11444 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11445 (match_operand:QI 2 "nonmemory_operand" "")))
11446 (clobber (match_scratch:SI 3 ""))
11447 (clobber (reg:CC 17))]
11448 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11449 [(const_int 0)]
11450 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11451
11452 (define_split
11453 [(set (match_operand:DI 0 "register_operand" "")
11454 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11455 (match_operand:QI 2 "nonmemory_operand" "")))
11456 (clobber (reg:CC 17))]
11457 "!TARGET_64BIT && reload_completed"
11458 [(const_int 0)]
11459 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11460
11461 (define_insn "x86_shrd_1"
11462 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11463 (ior:SI (ashiftrt:SI (match_dup 0)
11464 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11465 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11466 (minus:QI (const_int 32) (match_dup 2)))))
11467 (clobber (reg:CC 17))]
11468 ""
11469 "@
11470 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11471 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11472 [(set_attr "type" "ishift")
11473 (set_attr "prefix_0f" "1")
11474 (set_attr "pent_pair" "np")
11475 (set_attr "mode" "SI")])
11476
11477 (define_expand "x86_shift_adj_3"
11478 [(use (match_operand:SI 0 "register_operand" ""))
11479 (use (match_operand:SI 1 "register_operand" ""))
11480 (use (match_operand:QI 2 "register_operand" ""))]
11481 ""
11482 {
11483 rtx label = gen_label_rtx ();
11484 rtx tmp;
11485
11486 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11487
11488 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11489 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11490 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11491 gen_rtx_LABEL_REF (VOIDmode, label),
11492 pc_rtx);
11493 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11494 JUMP_LABEL (tmp) = label;
11495
11496 emit_move_insn (operands[0], operands[1]);
11497 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11498
11499 emit_label (label);
11500 LABEL_NUSES (label) = 1;
11501
11502 DONE;
11503 })
11504
11505 (define_insn "ashrsi3_31"
11506 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11507 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11508 (match_operand:SI 2 "const_int_operand" "i,i")))
11509 (clobber (reg:CC 17))]
11510 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11511 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11512 "@
11513 {cltd|cdq}
11514 sar{l}\t{%2, %0|%0, %2}"
11515 [(set_attr "type" "imovx,ishift")
11516 (set_attr "prefix_0f" "0,*")
11517 (set_attr "length_immediate" "0,*")
11518 (set_attr "modrm" "0,1")
11519 (set_attr "mode" "SI")])
11520
11521 (define_insn "*ashrsi3_31_zext"
11522 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11523 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11524 (match_operand:SI 2 "const_int_operand" "i,i"))))
11525 (clobber (reg:CC 17))]
11526 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11527 && INTVAL (operands[2]) == 31
11528 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11529 "@
11530 {cltd|cdq}
11531 sar{l}\t{%2, %k0|%k0, %2}"
11532 [(set_attr "type" "imovx,ishift")
11533 (set_attr "prefix_0f" "0,*")
11534 (set_attr "length_immediate" "0,*")
11535 (set_attr "modrm" "0,1")
11536 (set_attr "mode" "SI")])
11537
11538 (define_expand "ashrsi3"
11539 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11540 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11541 (match_operand:QI 2 "nonmemory_operand" "")))
11542 (clobber (reg:CC 17))]
11543 ""
11544 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11545
11546 (define_insn "*ashrsi3_1_one_bit"
11547 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11548 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11549 (match_operand:QI 2 "const1_operand" "")))
11550 (clobber (reg:CC 17))]
11551 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11552 && (TARGET_SHIFT1 || optimize_size)"
11553 "sar{l}\t%0"
11554 [(set_attr "type" "ishift")
11555 (set (attr "length")
11556 (if_then_else (match_operand:SI 0 "register_operand" "")
11557 (const_string "2")
11558 (const_string "*")))])
11559
11560 (define_insn "*ashrsi3_1_one_bit_zext"
11561 [(set (match_operand:DI 0 "register_operand" "=r")
11562 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11563 (match_operand:QI 2 "const1_operand" ""))))
11564 (clobber (reg:CC 17))]
11565 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11566 && (TARGET_SHIFT1 || optimize_size)"
11567 "sar{l}\t%k0"
11568 [(set_attr "type" "ishift")
11569 (set_attr "length" "2")])
11570
11571 (define_insn "*ashrsi3_1"
11572 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11573 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11574 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11575 (clobber (reg:CC 17))]
11576 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11577 "@
11578 sar{l}\t{%2, %0|%0, %2}
11579 sar{l}\t{%b2, %0|%0, %b2}"
11580 [(set_attr "type" "ishift")
11581 (set_attr "mode" "SI")])
11582
11583 (define_insn "*ashrsi3_1_zext"
11584 [(set (match_operand:DI 0 "register_operand" "=r,r")
11585 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11586 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11587 (clobber (reg:CC 17))]
11588 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11589 "@
11590 sar{l}\t{%2, %k0|%k0, %2}
11591 sar{l}\t{%b2, %k0|%k0, %b2}"
11592 [(set_attr "type" "ishift")
11593 (set_attr "mode" "SI")])
11594
11595 ;; This pattern can't accept a variable shift count, since shifts by
11596 ;; zero don't affect the flags. We assume that shifts by constant
11597 ;; zero are optimized away.
11598 (define_insn "*ashrsi3_one_bit_cmp"
11599 [(set (reg 17)
11600 (compare
11601 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11602 (match_operand:QI 2 "const1_operand" ""))
11603 (const_int 0)))
11604 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11605 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11606 "ix86_match_ccmode (insn, CCGOCmode)
11607 && (TARGET_SHIFT1 || optimize_size)
11608 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11609 "sar{l}\t%0"
11610 [(set_attr "type" "ishift")
11611 (set (attr "length")
11612 (if_then_else (match_operand:SI 0 "register_operand" "")
11613 (const_string "2")
11614 (const_string "*")))])
11615
11616 (define_insn "*ashrsi3_one_bit_cmp_zext"
11617 [(set (reg 17)
11618 (compare
11619 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11620 (match_operand:QI 2 "const1_operand" ""))
11621 (const_int 0)))
11622 (set (match_operand:DI 0 "register_operand" "=r")
11623 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11624 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11625 && (TARGET_SHIFT1 || optimize_size)
11626 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11627 "sar{l}\t%k0"
11628 [(set_attr "type" "ishift")
11629 (set_attr "length" "2")])
11630
11631 ;; This pattern can't accept a variable shift count, since shifts by
11632 ;; zero don't affect the flags. We assume that shifts by constant
11633 ;; zero are optimized away.
11634 (define_insn "*ashrsi3_cmp"
11635 [(set (reg 17)
11636 (compare
11637 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11638 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11639 (const_int 0)))
11640 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11641 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11642 "ix86_match_ccmode (insn, CCGOCmode)
11643 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11644 "sar{l}\t{%2, %0|%0, %2}"
11645 [(set_attr "type" "ishift")
11646 (set_attr "mode" "SI")])
11647
11648 (define_insn "*ashrsi3_cmp_zext"
11649 [(set (reg 17)
11650 (compare
11651 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11652 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11653 (const_int 0)))
11654 (set (match_operand:DI 0 "register_operand" "=r")
11655 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11656 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11657 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11658 "sar{l}\t{%2, %k0|%k0, %2}"
11659 [(set_attr "type" "ishift")
11660 (set_attr "mode" "SI")])
11661
11662 (define_expand "ashrhi3"
11663 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11664 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11665 (match_operand:QI 2 "nonmemory_operand" "")))
11666 (clobber (reg:CC 17))]
11667 "TARGET_HIMODE_MATH"
11668 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11669
11670 (define_insn "*ashrhi3_1_one_bit"
11671 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11672 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11673 (match_operand:QI 2 "const1_operand" "")))
11674 (clobber (reg:CC 17))]
11675 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11676 && (TARGET_SHIFT1 || optimize_size)"
11677 "sar{w}\t%0"
11678 [(set_attr "type" "ishift")
11679 (set (attr "length")
11680 (if_then_else (match_operand 0 "register_operand" "")
11681 (const_string "2")
11682 (const_string "*")))])
11683
11684 (define_insn "*ashrhi3_1"
11685 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11686 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11687 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11688 (clobber (reg:CC 17))]
11689 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11690 "@
11691 sar{w}\t{%2, %0|%0, %2}
11692 sar{w}\t{%b2, %0|%0, %b2}"
11693 [(set_attr "type" "ishift")
11694 (set_attr "mode" "HI")])
11695
11696 ;; This pattern can't accept a variable shift count, since shifts by
11697 ;; zero don't affect the flags. We assume that shifts by constant
11698 ;; zero are optimized away.
11699 (define_insn "*ashrhi3_one_bit_cmp"
11700 [(set (reg 17)
11701 (compare
11702 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11703 (match_operand:QI 2 "const1_operand" ""))
11704 (const_int 0)))
11705 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11706 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11707 "ix86_match_ccmode (insn, CCGOCmode)
11708 && (TARGET_SHIFT1 || optimize_size)
11709 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11710 "sar{w}\t%0"
11711 [(set_attr "type" "ishift")
11712 (set (attr "length")
11713 (if_then_else (match_operand 0 "register_operand" "")
11714 (const_string "2")
11715 (const_string "*")))])
11716
11717 ;; This pattern can't accept a variable shift count, since shifts by
11718 ;; zero don't affect the flags. We assume that shifts by constant
11719 ;; zero are optimized away.
11720 (define_insn "*ashrhi3_cmp"
11721 [(set (reg 17)
11722 (compare
11723 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11724 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11725 (const_int 0)))
11726 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11727 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11728 "ix86_match_ccmode (insn, CCGOCmode)
11729 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11730 "sar{w}\t{%2, %0|%0, %2}"
11731 [(set_attr "type" "ishift")
11732 (set_attr "mode" "HI")])
11733
11734 (define_expand "ashrqi3"
11735 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11736 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11737 (match_operand:QI 2 "nonmemory_operand" "")))
11738 (clobber (reg:CC 17))]
11739 "TARGET_QIMODE_MATH"
11740 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11741
11742 (define_insn "*ashrqi3_1_one_bit"
11743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11744 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11745 (match_operand:QI 2 "const1_operand" "")))
11746 (clobber (reg:CC 17))]
11747 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11748 && (TARGET_SHIFT1 || optimize_size)"
11749 "sar{b}\t%0"
11750 [(set_attr "type" "ishift")
11751 (set (attr "length")
11752 (if_then_else (match_operand 0 "register_operand" "")
11753 (const_string "2")
11754 (const_string "*")))])
11755
11756 (define_insn "*ashrqi3_1_one_bit_slp"
11757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11758 (ashiftrt:QI (match_dup 0)
11759 (match_operand:QI 1 "const1_operand" "")))
11760 (clobber (reg:CC 17))]
11761 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11762 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11763 && (TARGET_SHIFT1 || optimize_size)"
11764 "sar{b}\t%0"
11765 [(set_attr "type" "ishift1")
11766 (set (attr "length")
11767 (if_then_else (match_operand 0 "register_operand" "")
11768 (const_string "2")
11769 (const_string "*")))])
11770
11771 (define_insn "*ashrqi3_1"
11772 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11773 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11774 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11775 (clobber (reg:CC 17))]
11776 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11777 "@
11778 sar{b}\t{%2, %0|%0, %2}
11779 sar{b}\t{%b2, %0|%0, %b2}"
11780 [(set_attr "type" "ishift")
11781 (set_attr "mode" "QI")])
11782
11783 (define_insn "*ashrqi3_1_slp"
11784 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11785 (ashiftrt:QI (match_dup 0)
11786 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11787 (clobber (reg:CC 17))]
11788 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11789 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11790 "@
11791 sar{b}\t{%1, %0|%0, %1}
11792 sar{b}\t{%b1, %0|%0, %b1}"
11793 [(set_attr "type" "ishift1")
11794 (set_attr "mode" "QI")])
11795
11796 ;; This pattern can't accept a variable shift count, since shifts by
11797 ;; zero don't affect the flags. We assume that shifts by constant
11798 ;; zero are optimized away.
11799 (define_insn "*ashrqi3_one_bit_cmp"
11800 [(set (reg 17)
11801 (compare
11802 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11803 (match_operand:QI 2 "const1_operand" "I"))
11804 (const_int 0)))
11805 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11806 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11807 "ix86_match_ccmode (insn, CCGOCmode)
11808 && (TARGET_SHIFT1 || optimize_size)
11809 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11810 "sar{b}\t%0"
11811 [(set_attr "type" "ishift")
11812 (set (attr "length")
11813 (if_then_else (match_operand 0 "register_operand" "")
11814 (const_string "2")
11815 (const_string "*")))])
11816
11817 ;; This pattern can't accept a variable shift count, since shifts by
11818 ;; zero don't affect the flags. We assume that shifts by constant
11819 ;; zero are optimized away.
11820 (define_insn "*ashrqi3_cmp"
11821 [(set (reg 17)
11822 (compare
11823 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11824 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11825 (const_int 0)))
11826 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11827 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11828 "ix86_match_ccmode (insn, CCGOCmode)
11829 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11830 "sar{b}\t{%2, %0|%0, %2}"
11831 [(set_attr "type" "ishift")
11832 (set_attr "mode" "QI")])
11833 \f
11834 ;; Logical shift instructions
11835
11836 ;; See comment above `ashldi3' about how this works.
11837
11838 (define_expand "lshrdi3"
11839 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11840 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11841 (match_operand:QI 2 "nonmemory_operand" "")))
11842 (clobber (reg:CC 17))])]
11843 ""
11844 {
11845 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11846 {
11847 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11848 DONE;
11849 }
11850 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11851 DONE;
11852 })
11853
11854 (define_insn "*lshrdi3_1_one_bit_rex64"
11855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11856 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11857 (match_operand:QI 2 "const1_operand" "")))
11858 (clobber (reg:CC 17))]
11859 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11860 && (TARGET_SHIFT1 || optimize_size)"
11861 "shr{q}\t%0"
11862 [(set_attr "type" "ishift")
11863 (set (attr "length")
11864 (if_then_else (match_operand:DI 0 "register_operand" "")
11865 (const_string "2")
11866 (const_string "*")))])
11867
11868 (define_insn "*lshrdi3_1_rex64"
11869 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11870 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11871 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11872 (clobber (reg:CC 17))]
11873 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11874 "@
11875 shr{q}\t{%2, %0|%0, %2}
11876 shr{q}\t{%b2, %0|%0, %b2}"
11877 [(set_attr "type" "ishift")
11878 (set_attr "mode" "DI")])
11879
11880 ;; This pattern can't accept a variable shift count, since shifts by
11881 ;; zero don't affect the flags. We assume that shifts by constant
11882 ;; zero are optimized away.
11883 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11884 [(set (reg 17)
11885 (compare
11886 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11887 (match_operand:QI 2 "const1_operand" ""))
11888 (const_int 0)))
11889 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11890 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11891 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11892 && (TARGET_SHIFT1 || optimize_size)
11893 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11894 "shr{q}\t%0"
11895 [(set_attr "type" "ishift")
11896 (set (attr "length")
11897 (if_then_else (match_operand:DI 0 "register_operand" "")
11898 (const_string "2")
11899 (const_string "*")))])
11900
11901 ;; This pattern can't accept a variable shift count, since shifts by
11902 ;; zero don't affect the flags. We assume that shifts by constant
11903 ;; zero are optimized away.
11904 (define_insn "*lshrdi3_cmp_rex64"
11905 [(set (reg 17)
11906 (compare
11907 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11908 (match_operand:QI 2 "const_int_operand" "e"))
11909 (const_int 0)))
11910 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11911 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11912 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11913 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11914 "shr{q}\t{%2, %0|%0, %2}"
11915 [(set_attr "type" "ishift")
11916 (set_attr "mode" "DI")])
11917
11918 (define_insn "lshrdi3_1"
11919 [(set (match_operand:DI 0 "register_operand" "=r")
11920 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11921 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11922 (clobber (match_scratch:SI 3 "=&r"))
11923 (clobber (reg:CC 17))]
11924 "!TARGET_64BIT && TARGET_CMOVE"
11925 "#"
11926 [(set_attr "type" "multi")])
11927
11928 (define_insn "*lshrdi3_2"
11929 [(set (match_operand:DI 0 "register_operand" "=r")
11930 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11931 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11932 (clobber (reg:CC 17))]
11933 "!TARGET_64BIT"
11934 "#"
11935 [(set_attr "type" "multi")])
11936
11937 (define_split
11938 [(set (match_operand:DI 0 "register_operand" "")
11939 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11940 (match_operand:QI 2 "nonmemory_operand" "")))
11941 (clobber (match_scratch:SI 3 ""))
11942 (clobber (reg:CC 17))]
11943 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11944 [(const_int 0)]
11945 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11946
11947 (define_split
11948 [(set (match_operand:DI 0 "register_operand" "")
11949 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11950 (match_operand:QI 2 "nonmemory_operand" "")))
11951 (clobber (reg:CC 17))]
11952 "!TARGET_64BIT && reload_completed"
11953 [(const_int 0)]
11954 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11955
11956 (define_expand "lshrsi3"
11957 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11958 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11959 (match_operand:QI 2 "nonmemory_operand" "")))
11960 (clobber (reg:CC 17))]
11961 ""
11962 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11963
11964 (define_insn "*lshrsi3_1_one_bit"
11965 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11966 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11967 (match_operand:QI 2 "const1_operand" "")))
11968 (clobber (reg:CC 17))]
11969 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11970 && (TARGET_SHIFT1 || optimize_size)"
11971 "shr{l}\t%0"
11972 [(set_attr "type" "ishift")
11973 (set (attr "length")
11974 (if_then_else (match_operand:SI 0 "register_operand" "")
11975 (const_string "2")
11976 (const_string "*")))])
11977
11978 (define_insn "*lshrsi3_1_one_bit_zext"
11979 [(set (match_operand:DI 0 "register_operand" "=r")
11980 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11981 (match_operand:QI 2 "const1_operand" "")))
11982 (clobber (reg:CC 17))]
11983 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11984 && (TARGET_SHIFT1 || optimize_size)"
11985 "shr{l}\t%k0"
11986 [(set_attr "type" "ishift")
11987 (set_attr "length" "2")])
11988
11989 (define_insn "*lshrsi3_1"
11990 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11991 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11992 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11993 (clobber (reg:CC 17))]
11994 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11995 "@
11996 shr{l}\t{%2, %0|%0, %2}
11997 shr{l}\t{%b2, %0|%0, %b2}"
11998 [(set_attr "type" "ishift")
11999 (set_attr "mode" "SI")])
12000
12001 (define_insn "*lshrsi3_1_zext"
12002 [(set (match_operand:DI 0 "register_operand" "=r,r")
12003 (zero_extend:DI
12004 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12005 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12006 (clobber (reg:CC 17))]
12007 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12008 "@
12009 shr{l}\t{%2, %k0|%k0, %2}
12010 shr{l}\t{%b2, %k0|%k0, %b2}"
12011 [(set_attr "type" "ishift")
12012 (set_attr "mode" "SI")])
12013
12014 ;; This pattern can't accept a variable shift count, since shifts by
12015 ;; zero don't affect the flags. We assume that shifts by constant
12016 ;; zero are optimized away.
12017 (define_insn "*lshrsi3_one_bit_cmp"
12018 [(set (reg 17)
12019 (compare
12020 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12021 (match_operand:QI 2 "const1_operand" ""))
12022 (const_int 0)))
12023 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12024 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12025 "ix86_match_ccmode (insn, CCGOCmode)
12026 && (TARGET_SHIFT1 || optimize_size)
12027 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12028 "shr{l}\t%0"
12029 [(set_attr "type" "ishift")
12030 (set (attr "length")
12031 (if_then_else (match_operand:SI 0 "register_operand" "")
12032 (const_string "2")
12033 (const_string "*")))])
12034
12035 (define_insn "*lshrsi3_cmp_one_bit_zext"
12036 [(set (reg 17)
12037 (compare
12038 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12039 (match_operand:QI 2 "const1_operand" ""))
12040 (const_int 0)))
12041 (set (match_operand:DI 0 "register_operand" "=r")
12042 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12043 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12044 && (TARGET_SHIFT1 || optimize_size)
12045 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12046 "shr{l}\t%k0"
12047 [(set_attr "type" "ishift")
12048 (set_attr "length" "2")])
12049
12050 ;; This pattern can't accept a variable shift count, since shifts by
12051 ;; zero don't affect the flags. We assume that shifts by constant
12052 ;; zero are optimized away.
12053 (define_insn "*lshrsi3_cmp"
12054 [(set (reg 17)
12055 (compare
12056 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12057 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12058 (const_int 0)))
12059 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12060 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12061 "ix86_match_ccmode (insn, CCGOCmode)
12062 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12063 "shr{l}\t{%2, %0|%0, %2}"
12064 [(set_attr "type" "ishift")
12065 (set_attr "mode" "SI")])
12066
12067 (define_insn "*lshrsi3_cmp_zext"
12068 [(set (reg 17)
12069 (compare
12070 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12071 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12072 (const_int 0)))
12073 (set (match_operand:DI 0 "register_operand" "=r")
12074 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12075 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12076 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12077 "shr{l}\t{%2, %k0|%k0, %2}"
12078 [(set_attr "type" "ishift")
12079 (set_attr "mode" "SI")])
12080
12081 (define_expand "lshrhi3"
12082 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12083 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12084 (match_operand:QI 2 "nonmemory_operand" "")))
12085 (clobber (reg:CC 17))]
12086 "TARGET_HIMODE_MATH"
12087 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12088
12089 (define_insn "*lshrhi3_1_one_bit"
12090 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12091 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12092 (match_operand:QI 2 "const1_operand" "")))
12093 (clobber (reg:CC 17))]
12094 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12095 && (TARGET_SHIFT1 || optimize_size)"
12096 "shr{w}\t%0"
12097 [(set_attr "type" "ishift")
12098 (set (attr "length")
12099 (if_then_else (match_operand 0 "register_operand" "")
12100 (const_string "2")
12101 (const_string "*")))])
12102
12103 (define_insn "*lshrhi3_1"
12104 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12105 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12106 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12107 (clobber (reg:CC 17))]
12108 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12109 "@
12110 shr{w}\t{%2, %0|%0, %2}
12111 shr{w}\t{%b2, %0|%0, %b2}"
12112 [(set_attr "type" "ishift")
12113 (set_attr "mode" "HI")])
12114
12115 ;; This pattern can't accept a variable shift count, since shifts by
12116 ;; zero don't affect the flags. We assume that shifts by constant
12117 ;; zero are optimized away.
12118 (define_insn "*lshrhi3_one_bit_cmp"
12119 [(set (reg 17)
12120 (compare
12121 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12122 (match_operand:QI 2 "const1_operand" ""))
12123 (const_int 0)))
12124 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12125 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12126 "ix86_match_ccmode (insn, CCGOCmode)
12127 && (TARGET_SHIFT1 || optimize_size)
12128 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12129 "shr{w}\t%0"
12130 [(set_attr "type" "ishift")
12131 (set (attr "length")
12132 (if_then_else (match_operand:SI 0 "register_operand" "")
12133 (const_string "2")
12134 (const_string "*")))])
12135
12136 ;; This pattern can't accept a variable shift count, since shifts by
12137 ;; zero don't affect the flags. We assume that shifts by constant
12138 ;; zero are optimized away.
12139 (define_insn "*lshrhi3_cmp"
12140 [(set (reg 17)
12141 (compare
12142 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12143 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12144 (const_int 0)))
12145 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12146 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12147 "ix86_match_ccmode (insn, CCGOCmode)
12148 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12149 "shr{w}\t{%2, %0|%0, %2}"
12150 [(set_attr "type" "ishift")
12151 (set_attr "mode" "HI")])
12152
12153 (define_expand "lshrqi3"
12154 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12155 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12156 (match_operand:QI 2 "nonmemory_operand" "")))
12157 (clobber (reg:CC 17))]
12158 "TARGET_QIMODE_MATH"
12159 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12160
12161 (define_insn "*lshrqi3_1_one_bit"
12162 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12163 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12164 (match_operand:QI 2 "const1_operand" "")))
12165 (clobber (reg:CC 17))]
12166 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12167 && (TARGET_SHIFT1 || optimize_size)"
12168 "shr{b}\t%0"
12169 [(set_attr "type" "ishift")
12170 (set (attr "length")
12171 (if_then_else (match_operand 0 "register_operand" "")
12172 (const_string "2")
12173 (const_string "*")))])
12174
12175 (define_insn "*lshrqi3_1_one_bit_slp"
12176 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12177 (lshiftrt:QI (match_dup 0)
12178 (match_operand:QI 1 "const1_operand" "")))
12179 (clobber (reg:CC 17))]
12180 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12181 && (TARGET_SHIFT1 || optimize_size)"
12182 "shr{b}\t%0"
12183 [(set_attr "type" "ishift1")
12184 (set (attr "length")
12185 (if_then_else (match_operand 0 "register_operand" "")
12186 (const_string "2")
12187 (const_string "*")))])
12188
12189 (define_insn "*lshrqi3_1"
12190 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12191 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12192 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12193 (clobber (reg:CC 17))]
12194 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12195 "@
12196 shr{b}\t{%2, %0|%0, %2}
12197 shr{b}\t{%b2, %0|%0, %b2}"
12198 [(set_attr "type" "ishift")
12199 (set_attr "mode" "QI")])
12200
12201 (define_insn "*lshrqi3_1_slp"
12202 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12203 (lshiftrt:QI (match_dup 0)
12204 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12205 (clobber (reg:CC 17))]
12206 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12207 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12208 "@
12209 shr{b}\t{%1, %0|%0, %1}
12210 shr{b}\t{%b1, %0|%0, %b1}"
12211 [(set_attr "type" "ishift1")
12212 (set_attr "mode" "QI")])
12213
12214 ;; This pattern can't accept a variable shift count, since shifts by
12215 ;; zero don't affect the flags. We assume that shifts by constant
12216 ;; zero are optimized away.
12217 (define_insn "*lshrqi2_one_bit_cmp"
12218 [(set (reg 17)
12219 (compare
12220 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12221 (match_operand:QI 2 "const1_operand" ""))
12222 (const_int 0)))
12223 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12224 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12225 "ix86_match_ccmode (insn, CCGOCmode)
12226 && (TARGET_SHIFT1 || optimize_size)
12227 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12228 "shr{b}\t%0"
12229 [(set_attr "type" "ishift")
12230 (set (attr "length")
12231 (if_then_else (match_operand:SI 0 "register_operand" "")
12232 (const_string "2")
12233 (const_string "*")))])
12234
12235 ;; This pattern can't accept a variable shift count, since shifts by
12236 ;; zero don't affect the flags. We assume that shifts by constant
12237 ;; zero are optimized away.
12238 (define_insn "*lshrqi2_cmp"
12239 [(set (reg 17)
12240 (compare
12241 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12242 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12243 (const_int 0)))
12244 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12245 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12246 "ix86_match_ccmode (insn, CCGOCmode)
12247 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12248 "shr{b}\t{%2, %0|%0, %2}"
12249 [(set_attr "type" "ishift")
12250 (set_attr "mode" "QI")])
12251 \f
12252 ;; Rotate instructions
12253
12254 (define_expand "rotldi3"
12255 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12256 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12257 (match_operand:QI 2 "nonmemory_operand" "")))
12258 (clobber (reg:CC 17))]
12259 "TARGET_64BIT"
12260 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12261
12262 (define_insn "*rotlsi3_1_one_bit_rex64"
12263 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12264 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12265 (match_operand:QI 2 "const1_operand" "")))
12266 (clobber (reg:CC 17))]
12267 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12268 && (TARGET_SHIFT1 || optimize_size)"
12269 "rol{q}\t%0"
12270 [(set_attr "type" "rotate")
12271 (set (attr "length")
12272 (if_then_else (match_operand:DI 0 "register_operand" "")
12273 (const_string "2")
12274 (const_string "*")))])
12275
12276 (define_insn "*rotldi3_1_rex64"
12277 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12278 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12279 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12280 (clobber (reg:CC 17))]
12281 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12282 "@
12283 rol{q}\t{%2, %0|%0, %2}
12284 rol{q}\t{%b2, %0|%0, %b2}"
12285 [(set_attr "type" "rotate")
12286 (set_attr "mode" "DI")])
12287
12288 (define_expand "rotlsi3"
12289 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12290 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12291 (match_operand:QI 2 "nonmemory_operand" "")))
12292 (clobber (reg:CC 17))]
12293 ""
12294 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12295
12296 (define_insn "*rotlsi3_1_one_bit"
12297 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12298 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12299 (match_operand:QI 2 "const1_operand" "")))
12300 (clobber (reg:CC 17))]
12301 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12302 && (TARGET_SHIFT1 || optimize_size)"
12303 "rol{l}\t%0"
12304 [(set_attr "type" "rotate")
12305 (set (attr "length")
12306 (if_then_else (match_operand:SI 0 "register_operand" "")
12307 (const_string "2")
12308 (const_string "*")))])
12309
12310 (define_insn "*rotlsi3_1_one_bit_zext"
12311 [(set (match_operand:DI 0 "register_operand" "=r")
12312 (zero_extend:DI
12313 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12314 (match_operand:QI 2 "const1_operand" ""))))
12315 (clobber (reg:CC 17))]
12316 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12317 && (TARGET_SHIFT1 || optimize_size)"
12318 "rol{l}\t%k0"
12319 [(set_attr "type" "rotate")
12320 (set_attr "length" "2")])
12321
12322 (define_insn "*rotlsi3_1"
12323 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12324 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12325 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12326 (clobber (reg:CC 17))]
12327 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12328 "@
12329 rol{l}\t{%2, %0|%0, %2}
12330 rol{l}\t{%b2, %0|%0, %b2}"
12331 [(set_attr "type" "rotate")
12332 (set_attr "mode" "SI")])
12333
12334 (define_insn "*rotlsi3_1_zext"
12335 [(set (match_operand:DI 0 "register_operand" "=r,r")
12336 (zero_extend:DI
12337 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12338 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12339 (clobber (reg:CC 17))]
12340 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12341 "@
12342 rol{l}\t{%2, %k0|%k0, %2}
12343 rol{l}\t{%b2, %k0|%k0, %b2}"
12344 [(set_attr "type" "rotate")
12345 (set_attr "mode" "SI")])
12346
12347 (define_expand "rotlhi3"
12348 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12349 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12350 (match_operand:QI 2 "nonmemory_operand" "")))
12351 (clobber (reg:CC 17))]
12352 "TARGET_HIMODE_MATH"
12353 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12354
12355 (define_insn "*rotlhi3_1_one_bit"
12356 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12357 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12358 (match_operand:QI 2 "const1_operand" "")))
12359 (clobber (reg:CC 17))]
12360 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12361 && (TARGET_SHIFT1 || optimize_size)"
12362 "rol{w}\t%0"
12363 [(set_attr "type" "rotate")
12364 (set (attr "length")
12365 (if_then_else (match_operand 0 "register_operand" "")
12366 (const_string "2")
12367 (const_string "*")))])
12368
12369 (define_insn "*rotlhi3_1"
12370 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12371 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12372 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12373 (clobber (reg:CC 17))]
12374 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12375 "@
12376 rol{w}\t{%2, %0|%0, %2}
12377 rol{w}\t{%b2, %0|%0, %b2}"
12378 [(set_attr "type" "rotate")
12379 (set_attr "mode" "HI")])
12380
12381 (define_expand "rotlqi3"
12382 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12383 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12384 (match_operand:QI 2 "nonmemory_operand" "")))
12385 (clobber (reg:CC 17))]
12386 "TARGET_QIMODE_MATH"
12387 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12388
12389 (define_insn "*rotlqi3_1_one_bit_slp"
12390 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12391 (rotate:QI (match_dup 0)
12392 (match_operand:QI 1 "const1_operand" "")))
12393 (clobber (reg:CC 17))]
12394 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12395 && (TARGET_SHIFT1 || optimize_size)"
12396 "rol{b}\t%0"
12397 [(set_attr "type" "rotate1")
12398 (set (attr "length")
12399 (if_then_else (match_operand 0 "register_operand" "")
12400 (const_string "2")
12401 (const_string "*")))])
12402
12403 (define_insn "*rotlqi3_1_one_bit"
12404 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12405 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12406 (match_operand:QI 2 "const1_operand" "")))
12407 (clobber (reg:CC 17))]
12408 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12409 && (TARGET_SHIFT1 || optimize_size)"
12410 "rol{b}\t%0"
12411 [(set_attr "type" "rotate")
12412 (set (attr "length")
12413 (if_then_else (match_operand 0 "register_operand" "")
12414 (const_string "2")
12415 (const_string "*")))])
12416
12417 (define_insn "*rotlqi3_1_slp"
12418 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12419 (rotate:QI (match_dup 0)
12420 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12421 (clobber (reg:CC 17))]
12422 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12423 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12424 "@
12425 rol{b}\t{%1, %0|%0, %1}
12426 rol{b}\t{%b1, %0|%0, %b1}"
12427 [(set_attr "type" "rotate1")
12428 (set_attr "mode" "QI")])
12429
12430 (define_insn "*rotlqi3_1"
12431 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12432 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12433 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12434 (clobber (reg:CC 17))]
12435 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12436 "@
12437 rol{b}\t{%2, %0|%0, %2}
12438 rol{b}\t{%b2, %0|%0, %b2}"
12439 [(set_attr "type" "rotate")
12440 (set_attr "mode" "QI")])
12441
12442 (define_expand "rotrdi3"
12443 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12444 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12445 (match_operand:QI 2 "nonmemory_operand" "")))
12446 (clobber (reg:CC 17))]
12447 "TARGET_64BIT"
12448 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12449
12450 (define_insn "*rotrdi3_1_one_bit_rex64"
12451 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12452 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12453 (match_operand:QI 2 "const1_operand" "")))
12454 (clobber (reg:CC 17))]
12455 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12456 && (TARGET_SHIFT1 || optimize_size)"
12457 "ror{q}\t%0"
12458 [(set_attr "type" "rotate")
12459 (set (attr "length")
12460 (if_then_else (match_operand:DI 0 "register_operand" "")
12461 (const_string "2")
12462 (const_string "*")))])
12463
12464 (define_insn "*rotrdi3_1_rex64"
12465 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12466 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12467 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12468 (clobber (reg:CC 17))]
12469 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12470 "@
12471 ror{q}\t{%2, %0|%0, %2}
12472 ror{q}\t{%b2, %0|%0, %b2}"
12473 [(set_attr "type" "rotate")
12474 (set_attr "mode" "DI")])
12475
12476 (define_expand "rotrsi3"
12477 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12478 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12479 (match_operand:QI 2 "nonmemory_operand" "")))
12480 (clobber (reg:CC 17))]
12481 ""
12482 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12483
12484 (define_insn "*rotrsi3_1_one_bit"
12485 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12486 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12487 (match_operand:QI 2 "const1_operand" "")))
12488 (clobber (reg:CC 17))]
12489 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12490 && (TARGET_SHIFT1 || optimize_size)"
12491 "ror{l}\t%0"
12492 [(set_attr "type" "rotate")
12493 (set (attr "length")
12494 (if_then_else (match_operand:SI 0 "register_operand" "")
12495 (const_string "2")
12496 (const_string "*")))])
12497
12498 (define_insn "*rotrsi3_1_one_bit_zext"
12499 [(set (match_operand:DI 0 "register_operand" "=r")
12500 (zero_extend:DI
12501 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12502 (match_operand:QI 2 "const1_operand" ""))))
12503 (clobber (reg:CC 17))]
12504 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12505 && (TARGET_SHIFT1 || optimize_size)"
12506 "ror{l}\t%k0"
12507 [(set_attr "type" "rotate")
12508 (set (attr "length")
12509 (if_then_else (match_operand:SI 0 "register_operand" "")
12510 (const_string "2")
12511 (const_string "*")))])
12512
12513 (define_insn "*rotrsi3_1"
12514 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12515 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12516 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12517 (clobber (reg:CC 17))]
12518 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12519 "@
12520 ror{l}\t{%2, %0|%0, %2}
12521 ror{l}\t{%b2, %0|%0, %b2}"
12522 [(set_attr "type" "rotate")
12523 (set_attr "mode" "SI")])
12524
12525 (define_insn "*rotrsi3_1_zext"
12526 [(set (match_operand:DI 0 "register_operand" "=r,r")
12527 (zero_extend:DI
12528 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12529 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12530 (clobber (reg:CC 17))]
12531 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12532 "@
12533 ror{l}\t{%2, %k0|%k0, %2}
12534 ror{l}\t{%b2, %k0|%k0, %b2}"
12535 [(set_attr "type" "rotate")
12536 (set_attr "mode" "SI")])
12537
12538 (define_expand "rotrhi3"
12539 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12540 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12541 (match_operand:QI 2 "nonmemory_operand" "")))
12542 (clobber (reg:CC 17))]
12543 "TARGET_HIMODE_MATH"
12544 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12545
12546 (define_insn "*rotrhi3_one_bit"
12547 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12548 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12549 (match_operand:QI 2 "const1_operand" "")))
12550 (clobber (reg:CC 17))]
12551 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12552 && (TARGET_SHIFT1 || optimize_size)"
12553 "ror{w}\t%0"
12554 [(set_attr "type" "rotate")
12555 (set (attr "length")
12556 (if_then_else (match_operand 0 "register_operand" "")
12557 (const_string "2")
12558 (const_string "*")))])
12559
12560 (define_insn "*rotrhi3"
12561 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12562 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12563 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12564 (clobber (reg:CC 17))]
12565 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12566 "@
12567 ror{w}\t{%2, %0|%0, %2}
12568 ror{w}\t{%b2, %0|%0, %b2}"
12569 [(set_attr "type" "rotate")
12570 (set_attr "mode" "HI")])
12571
12572 (define_expand "rotrqi3"
12573 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12574 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12575 (match_operand:QI 2 "nonmemory_operand" "")))
12576 (clobber (reg:CC 17))]
12577 "TARGET_QIMODE_MATH"
12578 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12579
12580 (define_insn "*rotrqi3_1_one_bit"
12581 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12582 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12583 (match_operand:QI 2 "const1_operand" "")))
12584 (clobber (reg:CC 17))]
12585 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12586 && (TARGET_SHIFT1 || optimize_size)"
12587 "ror{b}\t%0"
12588 [(set_attr "type" "rotate")
12589 (set (attr "length")
12590 (if_then_else (match_operand 0 "register_operand" "")
12591 (const_string "2")
12592 (const_string "*")))])
12593
12594 (define_insn "*rotrqi3_1_one_bit_slp"
12595 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12596 (rotatert:QI (match_dup 0)
12597 (match_operand:QI 1 "const1_operand" "")))
12598 (clobber (reg:CC 17))]
12599 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12600 && (TARGET_SHIFT1 || optimize_size)"
12601 "ror{b}\t%0"
12602 [(set_attr "type" "rotate1")
12603 (set (attr "length")
12604 (if_then_else (match_operand 0 "register_operand" "")
12605 (const_string "2")
12606 (const_string "*")))])
12607
12608 (define_insn "*rotrqi3_1"
12609 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12610 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12611 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12612 (clobber (reg:CC 17))]
12613 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12614 "@
12615 ror{b}\t{%2, %0|%0, %2}
12616 ror{b}\t{%b2, %0|%0, %b2}"
12617 [(set_attr "type" "rotate")
12618 (set_attr "mode" "QI")])
12619
12620 (define_insn "*rotrqi3_1_slp"
12621 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12622 (rotatert:QI (match_dup 0)
12623 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12624 (clobber (reg:CC 17))]
12625 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12626 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12627 "@
12628 ror{b}\t{%1, %0|%0, %1}
12629 ror{b}\t{%b1, %0|%0, %b1}"
12630 [(set_attr "type" "rotate1")
12631 (set_attr "mode" "QI")])
12632 \f
12633 ;; Bit set / bit test instructions
12634
12635 (define_expand "extv"
12636 [(set (match_operand:SI 0 "register_operand" "")
12637 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12638 (match_operand:SI 2 "immediate_operand" "")
12639 (match_operand:SI 3 "immediate_operand" "")))]
12640 ""
12641 {
12642 /* Handle extractions from %ah et al. */
12643 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12644 FAIL;
12645
12646 /* From mips.md: extract_bit_field doesn't verify that our source
12647 matches the predicate, so check it again here. */
12648 if (! register_operand (operands[1], VOIDmode))
12649 FAIL;
12650 })
12651
12652 (define_expand "extzv"
12653 [(set (match_operand:SI 0 "register_operand" "")
12654 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12655 (match_operand:SI 2 "immediate_operand" "")
12656 (match_operand:SI 3 "immediate_operand" "")))]
12657 ""
12658 {
12659 /* Handle extractions from %ah et al. */
12660 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12661 FAIL;
12662
12663 /* From mips.md: extract_bit_field doesn't verify that our source
12664 matches the predicate, so check it again here. */
12665 if (! register_operand (operands[1], VOIDmode))
12666 FAIL;
12667 })
12668
12669 (define_expand "insv"
12670 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12671 (match_operand:SI 1 "immediate_operand" "")
12672 (match_operand:SI 2 "immediate_operand" ""))
12673 (match_operand:SI 3 "register_operand" ""))]
12674 ""
12675 {
12676 /* Handle extractions from %ah et al. */
12677 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12678 FAIL;
12679
12680 /* From mips.md: insert_bit_field doesn't verify that our source
12681 matches the predicate, so check it again here. */
12682 if (! register_operand (operands[0], VOIDmode))
12683 FAIL;
12684 })
12685
12686 ;; %%% bts, btr, btc, bt.
12687 \f
12688 ;; Store-flag instructions.
12689
12690 ;; For all sCOND expanders, also expand the compare or test insn that
12691 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12692
12693 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12694 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12695 ;; way, which can later delete the movzx if only QImode is needed.
12696
12697 (define_expand "seq"
12698 [(set (match_operand:QI 0 "register_operand" "")
12699 (eq:QI (reg:CC 17) (const_int 0)))]
12700 ""
12701 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12702
12703 (define_expand "sne"
12704 [(set (match_operand:QI 0 "register_operand" "")
12705 (ne:QI (reg:CC 17) (const_int 0)))]
12706 ""
12707 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12708
12709 (define_expand "sgt"
12710 [(set (match_operand:QI 0 "register_operand" "")
12711 (gt:QI (reg:CC 17) (const_int 0)))]
12712 ""
12713 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12714
12715 (define_expand "sgtu"
12716 [(set (match_operand:QI 0 "register_operand" "")
12717 (gtu:QI (reg:CC 17) (const_int 0)))]
12718 ""
12719 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12720
12721 (define_expand "slt"
12722 [(set (match_operand:QI 0 "register_operand" "")
12723 (lt:QI (reg:CC 17) (const_int 0)))]
12724 ""
12725 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12726
12727 (define_expand "sltu"
12728 [(set (match_operand:QI 0 "register_operand" "")
12729 (ltu:QI (reg:CC 17) (const_int 0)))]
12730 ""
12731 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12732
12733 (define_expand "sge"
12734 [(set (match_operand:QI 0 "register_operand" "")
12735 (ge:QI (reg:CC 17) (const_int 0)))]
12736 ""
12737 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12738
12739 (define_expand "sgeu"
12740 [(set (match_operand:QI 0 "register_operand" "")
12741 (geu:QI (reg:CC 17) (const_int 0)))]
12742 ""
12743 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12744
12745 (define_expand "sle"
12746 [(set (match_operand:QI 0 "register_operand" "")
12747 (le:QI (reg:CC 17) (const_int 0)))]
12748 ""
12749 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12750
12751 (define_expand "sleu"
12752 [(set (match_operand:QI 0 "register_operand" "")
12753 (leu:QI (reg:CC 17) (const_int 0)))]
12754 ""
12755 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12756
12757 (define_expand "sunordered"
12758 [(set (match_operand:QI 0 "register_operand" "")
12759 (unordered:QI (reg:CC 17) (const_int 0)))]
12760 "TARGET_80387 || TARGET_SSE"
12761 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12762
12763 (define_expand "sordered"
12764 [(set (match_operand:QI 0 "register_operand" "")
12765 (ordered:QI (reg:CC 17) (const_int 0)))]
12766 "TARGET_80387"
12767 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12768
12769 (define_expand "suneq"
12770 [(set (match_operand:QI 0 "register_operand" "")
12771 (uneq:QI (reg:CC 17) (const_int 0)))]
12772 "TARGET_80387 || TARGET_SSE"
12773 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12774
12775 (define_expand "sunge"
12776 [(set (match_operand:QI 0 "register_operand" "")
12777 (unge:QI (reg:CC 17) (const_int 0)))]
12778 "TARGET_80387 || TARGET_SSE"
12779 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12780
12781 (define_expand "sungt"
12782 [(set (match_operand:QI 0 "register_operand" "")
12783 (ungt:QI (reg:CC 17) (const_int 0)))]
12784 "TARGET_80387 || TARGET_SSE"
12785 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12786
12787 (define_expand "sunle"
12788 [(set (match_operand:QI 0 "register_operand" "")
12789 (unle:QI (reg:CC 17) (const_int 0)))]
12790 "TARGET_80387 || TARGET_SSE"
12791 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12792
12793 (define_expand "sunlt"
12794 [(set (match_operand:QI 0 "register_operand" "")
12795 (unlt:QI (reg:CC 17) (const_int 0)))]
12796 "TARGET_80387 || TARGET_SSE"
12797 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12798
12799 (define_expand "sltgt"
12800 [(set (match_operand:QI 0 "register_operand" "")
12801 (ltgt:QI (reg:CC 17) (const_int 0)))]
12802 "TARGET_80387 || TARGET_SSE"
12803 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12804
12805 (define_insn "*setcc_1"
12806 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12807 (match_operator:QI 1 "ix86_comparison_operator"
12808 [(reg 17) (const_int 0)]))]
12809 ""
12810 "set%C1\t%0"
12811 [(set_attr "type" "setcc")
12812 (set_attr "mode" "QI")])
12813
12814 (define_insn "setcc_2"
12815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12816 (match_operator:QI 1 "ix86_comparison_operator"
12817 [(reg 17) (const_int 0)]))]
12818 ""
12819 "set%C1\t%0"
12820 [(set_attr "type" "setcc")
12821 (set_attr "mode" "QI")])
12822
12823 ;; In general it is not safe to assume too much about CCmode registers,
12824 ;; so simplify-rtx stops when it sees a second one. Under certain
12825 ;; conditions this is safe on x86, so help combine not create
12826 ;;
12827 ;; seta %al
12828 ;; testb %al, %al
12829 ;; sete %al
12830
12831 (define_split
12832 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12833 (ne:QI (match_operator 1 "ix86_comparison_operator"
12834 [(reg 17) (const_int 0)])
12835 (const_int 0)))]
12836 ""
12837 [(set (match_dup 0) (match_dup 1))]
12838 {
12839 PUT_MODE (operands[1], QImode);
12840 })
12841
12842 (define_split
12843 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12844 (ne:QI (match_operator 1 "ix86_comparison_operator"
12845 [(reg 17) (const_int 0)])
12846 (const_int 0)))]
12847 ""
12848 [(set (match_dup 0) (match_dup 1))]
12849 {
12850 PUT_MODE (operands[1], QImode);
12851 })
12852
12853 (define_split
12854 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12855 (eq:QI (match_operator 1 "ix86_comparison_operator"
12856 [(reg 17) (const_int 0)])
12857 (const_int 0)))]
12858 ""
12859 [(set (match_dup 0) (match_dup 1))]
12860 {
12861 rtx new_op1 = copy_rtx (operands[1]);
12862 operands[1] = new_op1;
12863 PUT_MODE (new_op1, QImode);
12864 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12865 GET_MODE (XEXP (new_op1, 0))));
12866
12867 /* Make sure that (a) the CCmode we have for the flags is strong
12868 enough for the reversed compare or (b) we have a valid FP compare. */
12869 if (! ix86_comparison_operator (new_op1, VOIDmode))
12870 FAIL;
12871 })
12872
12873 (define_split
12874 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12875 (eq:QI (match_operator 1 "ix86_comparison_operator"
12876 [(reg 17) (const_int 0)])
12877 (const_int 0)))]
12878 ""
12879 [(set (match_dup 0) (match_dup 1))]
12880 {
12881 rtx new_op1 = copy_rtx (operands[1]);
12882 operands[1] = new_op1;
12883 PUT_MODE (new_op1, QImode);
12884 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12885 GET_MODE (XEXP (new_op1, 0))));
12886
12887 /* Make sure that (a) the CCmode we have for the flags is strong
12888 enough for the reversed compare or (b) we have a valid FP compare. */
12889 if (! ix86_comparison_operator (new_op1, VOIDmode))
12890 FAIL;
12891 })
12892
12893 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12894 ;; subsequent logical operations are used to imitate conditional moves.
12895 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12896 ;; it directly. Further holding this value in pseudo register might bring
12897 ;; problem in implicit normalization in spill code.
12898 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12899 ;; instructions after reload by splitting the conditional move patterns.
12900
12901 (define_insn "*sse_setccsf"
12902 [(set (match_operand:SF 0 "register_operand" "=x")
12903 (match_operator:SF 1 "sse_comparison_operator"
12904 [(match_operand:SF 2 "register_operand" "0")
12905 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12906 "TARGET_SSE && reload_completed"
12907 "cmp%D1ss\t{%3, %0|%0, %3}"
12908 [(set_attr "type" "ssecmp")
12909 (set_attr "mode" "SF")])
12910
12911 (define_insn "*sse_setccdf"
12912 [(set (match_operand:DF 0 "register_operand" "=Y")
12913 (match_operator:DF 1 "sse_comparison_operator"
12914 [(match_operand:DF 2 "register_operand" "0")
12915 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12916 "TARGET_SSE2 && reload_completed"
12917 "cmp%D1sd\t{%3, %0|%0, %3}"
12918 [(set_attr "type" "ssecmp")
12919 (set_attr "mode" "DF")])
12920 \f
12921 ;; Basic conditional jump instructions.
12922 ;; We ignore the overflow flag for signed branch instructions.
12923
12924 ;; For all bCOND expanders, also expand the compare or test insn that
12925 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12926
12927 (define_expand "beq"
12928 [(set (pc)
12929 (if_then_else (match_dup 1)
12930 (label_ref (match_operand 0 "" ""))
12931 (pc)))]
12932 ""
12933 "ix86_expand_branch (EQ, operands[0]); DONE;")
12934
12935 (define_expand "bne"
12936 [(set (pc)
12937 (if_then_else (match_dup 1)
12938 (label_ref (match_operand 0 "" ""))
12939 (pc)))]
12940 ""
12941 "ix86_expand_branch (NE, operands[0]); DONE;")
12942
12943 (define_expand "bgt"
12944 [(set (pc)
12945 (if_then_else (match_dup 1)
12946 (label_ref (match_operand 0 "" ""))
12947 (pc)))]
12948 ""
12949 "ix86_expand_branch (GT, operands[0]); DONE;")
12950
12951 (define_expand "bgtu"
12952 [(set (pc)
12953 (if_then_else (match_dup 1)
12954 (label_ref (match_operand 0 "" ""))
12955 (pc)))]
12956 ""
12957 "ix86_expand_branch (GTU, operands[0]); DONE;")
12958
12959 (define_expand "blt"
12960 [(set (pc)
12961 (if_then_else (match_dup 1)
12962 (label_ref (match_operand 0 "" ""))
12963 (pc)))]
12964 ""
12965 "ix86_expand_branch (LT, operands[0]); DONE;")
12966
12967 (define_expand "bltu"
12968 [(set (pc)
12969 (if_then_else (match_dup 1)
12970 (label_ref (match_operand 0 "" ""))
12971 (pc)))]
12972 ""
12973 "ix86_expand_branch (LTU, operands[0]); DONE;")
12974
12975 (define_expand "bge"
12976 [(set (pc)
12977 (if_then_else (match_dup 1)
12978 (label_ref (match_operand 0 "" ""))
12979 (pc)))]
12980 ""
12981 "ix86_expand_branch (GE, operands[0]); DONE;")
12982
12983 (define_expand "bgeu"
12984 [(set (pc)
12985 (if_then_else (match_dup 1)
12986 (label_ref (match_operand 0 "" ""))
12987 (pc)))]
12988 ""
12989 "ix86_expand_branch (GEU, operands[0]); DONE;")
12990
12991 (define_expand "ble"
12992 [(set (pc)
12993 (if_then_else (match_dup 1)
12994 (label_ref (match_operand 0 "" ""))
12995 (pc)))]
12996 ""
12997 "ix86_expand_branch (LE, operands[0]); DONE;")
12998
12999 (define_expand "bleu"
13000 [(set (pc)
13001 (if_then_else (match_dup 1)
13002 (label_ref (match_operand 0 "" ""))
13003 (pc)))]
13004 ""
13005 "ix86_expand_branch (LEU, operands[0]); DONE;")
13006
13007 (define_expand "bunordered"
13008 [(set (pc)
13009 (if_then_else (match_dup 1)
13010 (label_ref (match_operand 0 "" ""))
13011 (pc)))]
13012 "TARGET_80387 || TARGET_SSE"
13013 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13014
13015 (define_expand "bordered"
13016 [(set (pc)
13017 (if_then_else (match_dup 1)
13018 (label_ref (match_operand 0 "" ""))
13019 (pc)))]
13020 "TARGET_80387 || TARGET_SSE"
13021 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13022
13023 (define_expand "buneq"
13024 [(set (pc)
13025 (if_then_else (match_dup 1)
13026 (label_ref (match_operand 0 "" ""))
13027 (pc)))]
13028 "TARGET_80387 || TARGET_SSE"
13029 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13030
13031 (define_expand "bunge"
13032 [(set (pc)
13033 (if_then_else (match_dup 1)
13034 (label_ref (match_operand 0 "" ""))
13035 (pc)))]
13036 "TARGET_80387 || TARGET_SSE"
13037 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13038
13039 (define_expand "bungt"
13040 [(set (pc)
13041 (if_then_else (match_dup 1)
13042 (label_ref (match_operand 0 "" ""))
13043 (pc)))]
13044 "TARGET_80387 || TARGET_SSE"
13045 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13046
13047 (define_expand "bunle"
13048 [(set (pc)
13049 (if_then_else (match_dup 1)
13050 (label_ref (match_operand 0 "" ""))
13051 (pc)))]
13052 "TARGET_80387 || TARGET_SSE"
13053 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13054
13055 (define_expand "bunlt"
13056 [(set (pc)
13057 (if_then_else (match_dup 1)
13058 (label_ref (match_operand 0 "" ""))
13059 (pc)))]
13060 "TARGET_80387 || TARGET_SSE"
13061 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13062
13063 (define_expand "bltgt"
13064 [(set (pc)
13065 (if_then_else (match_dup 1)
13066 (label_ref (match_operand 0 "" ""))
13067 (pc)))]
13068 "TARGET_80387 || TARGET_SSE"
13069 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13070
13071 (define_insn "*jcc_1"
13072 [(set (pc)
13073 (if_then_else (match_operator 1 "ix86_comparison_operator"
13074 [(reg 17) (const_int 0)])
13075 (label_ref (match_operand 0 "" ""))
13076 (pc)))]
13077 ""
13078 "%+j%C1\t%l0"
13079 [(set_attr "type" "ibr")
13080 (set_attr "modrm" "0")
13081 (set (attr "length")
13082 (if_then_else (and (ge (minus (match_dup 0) (pc))
13083 (const_int -126))
13084 (lt (minus (match_dup 0) (pc))
13085 (const_int 128)))
13086 (const_int 2)
13087 (const_int 6)))])
13088
13089 (define_insn "*jcc_2"
13090 [(set (pc)
13091 (if_then_else (match_operator 1 "ix86_comparison_operator"
13092 [(reg 17) (const_int 0)])
13093 (pc)
13094 (label_ref (match_operand 0 "" ""))))]
13095 ""
13096 "%+j%c1\t%l0"
13097 [(set_attr "type" "ibr")
13098 (set_attr "modrm" "0")
13099 (set (attr "length")
13100 (if_then_else (and (ge (minus (match_dup 0) (pc))
13101 (const_int -126))
13102 (lt (minus (match_dup 0) (pc))
13103 (const_int 128)))
13104 (const_int 2)
13105 (const_int 6)))])
13106
13107 ;; In general it is not safe to assume too much about CCmode registers,
13108 ;; so simplify-rtx stops when it sees a second one. Under certain
13109 ;; conditions this is safe on x86, so help combine not create
13110 ;;
13111 ;; seta %al
13112 ;; testb %al, %al
13113 ;; je Lfoo
13114
13115 (define_split
13116 [(set (pc)
13117 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13118 [(reg 17) (const_int 0)])
13119 (const_int 0))
13120 (label_ref (match_operand 1 "" ""))
13121 (pc)))]
13122 ""
13123 [(set (pc)
13124 (if_then_else (match_dup 0)
13125 (label_ref (match_dup 1))
13126 (pc)))]
13127 {
13128 PUT_MODE (operands[0], VOIDmode);
13129 })
13130
13131 (define_split
13132 [(set (pc)
13133 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13134 [(reg 17) (const_int 0)])
13135 (const_int 0))
13136 (label_ref (match_operand 1 "" ""))
13137 (pc)))]
13138 ""
13139 [(set (pc)
13140 (if_then_else (match_dup 0)
13141 (label_ref (match_dup 1))
13142 (pc)))]
13143 {
13144 rtx new_op0 = copy_rtx (operands[0]);
13145 operands[0] = new_op0;
13146 PUT_MODE (new_op0, VOIDmode);
13147 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13148 GET_MODE (XEXP (new_op0, 0))));
13149
13150 /* Make sure that (a) the CCmode we have for the flags is strong
13151 enough for the reversed compare or (b) we have a valid FP compare. */
13152 if (! ix86_comparison_operator (new_op0, VOIDmode))
13153 FAIL;
13154 })
13155
13156 ;; Define combination compare-and-branch fp compare instructions to use
13157 ;; during early optimization. Splitting the operation apart early makes
13158 ;; for bad code when we want to reverse the operation.
13159
13160 (define_insn "*fp_jcc_1"
13161 [(set (pc)
13162 (if_then_else (match_operator 0 "comparison_operator"
13163 [(match_operand 1 "register_operand" "f")
13164 (match_operand 2 "register_operand" "f")])
13165 (label_ref (match_operand 3 "" ""))
13166 (pc)))
13167 (clobber (reg:CCFP 18))
13168 (clobber (reg:CCFP 17))]
13169 "TARGET_CMOVE && TARGET_80387
13170 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13171 && FLOAT_MODE_P (GET_MODE (operands[1]))
13172 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13173 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13174 "#")
13175
13176 (define_insn "*fp_jcc_1_sse"
13177 [(set (pc)
13178 (if_then_else (match_operator 0 "comparison_operator"
13179 [(match_operand 1 "register_operand" "f#x,x#f")
13180 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13181 (label_ref (match_operand 3 "" ""))
13182 (pc)))
13183 (clobber (reg:CCFP 18))
13184 (clobber (reg:CCFP 17))]
13185 "TARGET_80387
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_1_sse_only"
13192 [(set (pc)
13193 (if_then_else (match_operator 0 "comparison_operator"
13194 [(match_operand 1 "register_operand" "x")
13195 (match_operand 2 "nonimmediate_operand" "xm")])
13196 (label_ref (match_operand 3 "" ""))
13197 (pc)))
13198 (clobber (reg:CCFP 18))
13199 (clobber (reg:CCFP 17))]
13200 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13201 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13202 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13203 "#")
13204
13205 (define_insn "*fp_jcc_2"
13206 [(set (pc)
13207 (if_then_else (match_operator 0 "comparison_operator"
13208 [(match_operand 1 "register_operand" "f")
13209 (match_operand 2 "register_operand" "f")])
13210 (pc)
13211 (label_ref (match_operand 3 "" ""))))
13212 (clobber (reg:CCFP 18))
13213 (clobber (reg:CCFP 17))]
13214 "TARGET_CMOVE && TARGET_80387
13215 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13216 && FLOAT_MODE_P (GET_MODE (operands[1]))
13217 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13218 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13219 "#")
13220
13221 (define_insn "*fp_jcc_2_sse"
13222 [(set (pc)
13223 (if_then_else (match_operator 0 "comparison_operator"
13224 [(match_operand 1 "register_operand" "f#x,x#f")
13225 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13226 (pc)
13227 (label_ref (match_operand 3 "" ""))))
13228 (clobber (reg:CCFP 18))
13229 (clobber (reg:CCFP 17))]
13230 "TARGET_80387
13231 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13232 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13233 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13234 "#")
13235
13236 (define_insn "*fp_jcc_2_sse_only"
13237 [(set (pc)
13238 (if_then_else (match_operator 0 "comparison_operator"
13239 [(match_operand 1 "register_operand" "x")
13240 (match_operand 2 "nonimmediate_operand" "xm")])
13241 (pc)
13242 (label_ref (match_operand 3 "" ""))))
13243 (clobber (reg:CCFP 18))
13244 (clobber (reg:CCFP 17))]
13245 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13246 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13247 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13248 "#")
13249
13250 (define_insn "*fp_jcc_3"
13251 [(set (pc)
13252 (if_then_else (match_operator 0 "comparison_operator"
13253 [(match_operand 1 "register_operand" "f")
13254 (match_operand 2 "nonimmediate_operand" "fm")])
13255 (label_ref (match_operand 3 "" ""))
13256 (pc)))
13257 (clobber (reg:CCFP 18))
13258 (clobber (reg:CCFP 17))
13259 (clobber (match_scratch:HI 4 "=a"))]
13260 "TARGET_80387
13261 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13262 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13263 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13264 && SELECT_CC_MODE (GET_CODE (operands[0]),
13265 operands[1], operands[2]) == CCFPmode
13266 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13267 "#")
13268
13269 (define_insn "*fp_jcc_4"
13270 [(set (pc)
13271 (if_then_else (match_operator 0 "comparison_operator"
13272 [(match_operand 1 "register_operand" "f")
13273 (match_operand 2 "nonimmediate_operand" "fm")])
13274 (pc)
13275 (label_ref (match_operand 3 "" ""))))
13276 (clobber (reg:CCFP 18))
13277 (clobber (reg:CCFP 17))
13278 (clobber (match_scratch:HI 4 "=a"))]
13279 "TARGET_80387
13280 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13281 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13282 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13283 && SELECT_CC_MODE (GET_CODE (operands[0]),
13284 operands[1], operands[2]) == CCFPmode
13285 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13286 "#")
13287
13288 (define_insn "*fp_jcc_5"
13289 [(set (pc)
13290 (if_then_else (match_operator 0 "comparison_operator"
13291 [(match_operand 1 "register_operand" "f")
13292 (match_operand 2 "register_operand" "f")])
13293 (label_ref (match_operand 3 "" ""))
13294 (pc)))
13295 (clobber (reg:CCFP 18))
13296 (clobber (reg:CCFP 17))
13297 (clobber (match_scratch:HI 4 "=a"))]
13298 "TARGET_80387
13299 && FLOAT_MODE_P (GET_MODE (operands[1]))
13300 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13301 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13302 "#")
13303
13304 (define_insn "*fp_jcc_6"
13305 [(set (pc)
13306 (if_then_else (match_operator 0 "comparison_operator"
13307 [(match_operand 1 "register_operand" "f")
13308 (match_operand 2 "register_operand" "f")])
13309 (pc)
13310 (label_ref (match_operand 3 "" ""))))
13311 (clobber (reg:CCFP 18))
13312 (clobber (reg:CCFP 17))
13313 (clobber (match_scratch:HI 4 "=a"))]
13314 "TARGET_80387
13315 && FLOAT_MODE_P (GET_MODE (operands[1]))
13316 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13317 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13318 "#")
13319
13320 (define_split
13321 [(set (pc)
13322 (if_then_else (match_operator 0 "comparison_operator"
13323 [(match_operand 1 "register_operand" "")
13324 (match_operand 2 "nonimmediate_operand" "")])
13325 (match_operand 3 "" "")
13326 (match_operand 4 "" "")))
13327 (clobber (reg:CCFP 18))
13328 (clobber (reg:CCFP 17))]
13329 "reload_completed"
13330 [(const_int 0)]
13331 {
13332 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13333 operands[3], operands[4], NULL_RTX);
13334 DONE;
13335 })
13336
13337 (define_split
13338 [(set (pc)
13339 (if_then_else (match_operator 0 "comparison_operator"
13340 [(match_operand 1 "register_operand" "")
13341 (match_operand 2 "nonimmediate_operand" "")])
13342 (match_operand 3 "" "")
13343 (match_operand 4 "" "")))
13344 (clobber (reg:CCFP 18))
13345 (clobber (reg:CCFP 17))
13346 (clobber (match_scratch:HI 5 "=a"))]
13347 "reload_completed"
13348 [(set (pc)
13349 (if_then_else (match_dup 6)
13350 (match_dup 3)
13351 (match_dup 4)))]
13352 {
13353 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13354 operands[3], operands[4], operands[5]);
13355 DONE;
13356 })
13357 \f
13358 ;; Unconditional and other jump instructions
13359
13360 (define_insn "jump"
13361 [(set (pc)
13362 (label_ref (match_operand 0 "" "")))]
13363 ""
13364 "jmp\t%l0"
13365 [(set_attr "type" "ibr")
13366 (set (attr "length")
13367 (if_then_else (and (ge (minus (match_dup 0) (pc))
13368 (const_int -126))
13369 (lt (minus (match_dup 0) (pc))
13370 (const_int 128)))
13371 (const_int 2)
13372 (const_int 5)))
13373 (set_attr "modrm" "0")])
13374
13375 (define_expand "indirect_jump"
13376 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13377 ""
13378 "")
13379
13380 (define_insn "*indirect_jump"
13381 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13382 "!TARGET_64BIT"
13383 "jmp\t%A0"
13384 [(set_attr "type" "ibr")
13385 (set_attr "length_immediate" "0")])
13386
13387 (define_insn "*indirect_jump_rtx64"
13388 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13389 "TARGET_64BIT"
13390 "jmp\t%A0"
13391 [(set_attr "type" "ibr")
13392 (set_attr "length_immediate" "0")])
13393
13394 (define_expand "tablejump"
13395 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13396 (use (label_ref (match_operand 1 "" "")))])]
13397 ""
13398 {
13399 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13400 relative. Convert the relative address to an absolute address. */
13401 if (flag_pic)
13402 {
13403 rtx op0, op1;
13404 enum rtx_code code;
13405
13406 if (TARGET_64BIT)
13407 {
13408 code = PLUS;
13409 op0 = operands[0];
13410 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13411 }
13412 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13413 {
13414 code = PLUS;
13415 op0 = operands[0];
13416 op1 = pic_offset_table_rtx;
13417 }
13418 else
13419 {
13420 code = MINUS;
13421 op0 = pic_offset_table_rtx;
13422 op1 = operands[0];
13423 }
13424
13425 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13426 OPTAB_DIRECT);
13427 }
13428 })
13429
13430 (define_insn "*tablejump_1"
13431 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13432 (use (label_ref (match_operand 1 "" "")))]
13433 "!TARGET_64BIT"
13434 "jmp\t%A0"
13435 [(set_attr "type" "ibr")
13436 (set_attr "length_immediate" "0")])
13437
13438 (define_insn "*tablejump_1_rtx64"
13439 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13440 (use (label_ref (match_operand 1 "" "")))]
13441 "TARGET_64BIT"
13442 "jmp\t%A0"
13443 [(set_attr "type" "ibr")
13444 (set_attr "length_immediate" "0")])
13445 \f
13446 ;; Loop instruction
13447 ;;
13448 ;; This is all complicated by the fact that since this is a jump insn
13449 ;; we must handle our own reloads.
13450
13451 (define_expand "doloop_end"
13452 [(use (match_operand 0 "" "")) ; loop pseudo
13453 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13454 (use (match_operand 2 "" "")) ; max iterations
13455 (use (match_operand 3 "" "")) ; loop level
13456 (use (match_operand 4 "" ""))] ; label
13457 "!TARGET_64BIT && TARGET_USE_LOOP"
13458 "
13459 {
13460 /* Only use cloop on innermost loops. */
13461 if (INTVAL (operands[3]) > 1)
13462 FAIL;
13463 if (GET_MODE (operands[0]) != SImode)
13464 FAIL;
13465 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13466 operands[0]));
13467 DONE;
13468 }")
13469
13470 (define_insn "doloop_end_internal"
13471 [(set (pc)
13472 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13473 (const_int 1))
13474 (label_ref (match_operand 0 "" ""))
13475 (pc)))
13476 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13477 (plus:SI (match_dup 1)
13478 (const_int -1)))
13479 (clobber (match_scratch:SI 3 "=X,X,r"))
13480 (clobber (reg:CC 17))]
13481 "!TARGET_64BIT && TARGET_USE_LOOP
13482 && (reload_in_progress || reload_completed
13483 || register_operand (operands[2], VOIDmode))"
13484 {
13485 if (which_alternative != 0)
13486 return "#";
13487 if (get_attr_length (insn) == 2)
13488 return "%+loop\t%l0";
13489 else
13490 return "dec{l}\t%1\;%+jne\t%l0";
13491 }
13492 [(set (attr "length")
13493 (if_then_else (and (eq_attr "alternative" "0")
13494 (and (ge (minus (match_dup 0) (pc))
13495 (const_int -126))
13496 (lt (minus (match_dup 0) (pc))
13497 (const_int 128))))
13498 (const_int 2)
13499 (const_int 16)))
13500 ;; We don't know the type before shorten branches. Optimistically expect
13501 ;; the loop instruction to match.
13502 (set (attr "type") (const_string "ibr"))])
13503
13504 (define_split
13505 [(set (pc)
13506 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13507 (const_int 1))
13508 (match_operand 0 "" "")
13509 (pc)))
13510 (set (match_dup 1)
13511 (plus:SI (match_dup 1)
13512 (const_int -1)))
13513 (clobber (match_scratch:SI 2 ""))
13514 (clobber (reg:CC 17))]
13515 "!TARGET_64BIT && TARGET_USE_LOOP
13516 && reload_completed
13517 && REGNO (operands[1]) != 2"
13518 [(parallel [(set (reg:CCZ 17)
13519 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13520 (const_int 0)))
13521 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13522 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13523 (match_dup 0)
13524 (pc)))]
13525 "")
13526
13527 (define_split
13528 [(set (pc)
13529 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13530 (const_int 1))
13531 (match_operand 0 "" "")
13532 (pc)))
13533 (set (match_operand:SI 2 "nonimmediate_operand" "")
13534 (plus:SI (match_dup 1)
13535 (const_int -1)))
13536 (clobber (match_scratch:SI 3 ""))
13537 (clobber (reg:CC 17))]
13538 "!TARGET_64BIT && TARGET_USE_LOOP
13539 && reload_completed
13540 && (! REG_P (operands[2])
13541 || ! rtx_equal_p (operands[1], operands[2]))"
13542 [(set (match_dup 3) (match_dup 1))
13543 (parallel [(set (reg:CCZ 17)
13544 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13545 (const_int 0)))
13546 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13547 (set (match_dup 2) (match_dup 3))
13548 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13549 (match_dup 0)
13550 (pc)))]
13551 "")
13552
13553 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13554
13555 (define_peephole2
13556 [(set (reg 17) (match_operand 0 "" ""))
13557 (set (match_operand:QI 1 "register_operand" "")
13558 (match_operator:QI 2 "ix86_comparison_operator"
13559 [(reg 17) (const_int 0)]))
13560 (set (match_operand 3 "q_regs_operand" "")
13561 (zero_extend (match_dup 1)))]
13562 "(peep2_reg_dead_p (3, operands[1])
13563 || operands_match_p (operands[1], operands[3]))
13564 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13565 [(set (match_dup 4) (match_dup 0))
13566 (set (strict_low_part (match_dup 5))
13567 (match_dup 2))]
13568 {
13569 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13570 operands[5] = gen_lowpart (QImode, operands[3]);
13571 ix86_expand_clear (operands[3]);
13572 })
13573
13574 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13575
13576 (define_peephole2
13577 [(set (reg 17) (match_operand 0 "" ""))
13578 (set (match_operand:QI 1 "register_operand" "")
13579 (match_operator:QI 2 "ix86_comparison_operator"
13580 [(reg 17) (const_int 0)]))
13581 (parallel [(set (match_operand 3 "q_regs_operand" "")
13582 (zero_extend (match_dup 1)))
13583 (clobber (reg:CC 17))])]
13584 "(peep2_reg_dead_p (3, operands[1])
13585 || operands_match_p (operands[1], operands[3]))
13586 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13587 [(set (match_dup 4) (match_dup 0))
13588 (set (strict_low_part (match_dup 5))
13589 (match_dup 2))]
13590 {
13591 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13592 operands[5] = gen_lowpart (QImode, operands[3]);
13593 ix86_expand_clear (operands[3]);
13594 })
13595 \f
13596 ;; Call instructions.
13597
13598 ;; The predicates normally associated with named expanders are not properly
13599 ;; checked for calls. This is a bug in the generic code, but it isn't that
13600 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13601
13602 ;; Call subroutine returning no value.
13603
13604 (define_expand "call_pop"
13605 [(parallel [(call (match_operand:QI 0 "" "")
13606 (match_operand:SI 1 "" ""))
13607 (set (reg:SI 7)
13608 (plus:SI (reg:SI 7)
13609 (match_operand:SI 3 "" "")))])]
13610 "!TARGET_64BIT"
13611 {
13612 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13613 DONE;
13614 })
13615
13616 (define_insn "*call_pop_0"
13617 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13618 (match_operand:SI 1 "" ""))
13619 (set (reg:SI 7) (plus:SI (reg:SI 7)
13620 (match_operand:SI 2 "immediate_operand" "")))]
13621 "!TARGET_64BIT"
13622 {
13623 if (SIBLING_CALL_P (insn))
13624 return "jmp\t%P0";
13625 else
13626 return "call\t%P0";
13627 }
13628 [(set_attr "type" "call")])
13629
13630 (define_insn "*call_pop_1"
13631 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13632 (match_operand:SI 1 "" ""))
13633 (set (reg:SI 7) (plus:SI (reg:SI 7)
13634 (match_operand:SI 2 "immediate_operand" "i")))]
13635 "!TARGET_64BIT"
13636 {
13637 if (constant_call_address_operand (operands[0], Pmode))
13638 {
13639 if (SIBLING_CALL_P (insn))
13640 return "jmp\t%P0";
13641 else
13642 return "call\t%P0";
13643 }
13644 if (SIBLING_CALL_P (insn))
13645 return "jmp\t%A0";
13646 else
13647 return "call\t%A0";
13648 }
13649 [(set_attr "type" "call")])
13650
13651 (define_expand "call"
13652 [(call (match_operand:QI 0 "" "")
13653 (match_operand 1 "" ""))
13654 (use (match_operand 2 "" ""))]
13655 ""
13656 {
13657 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13658 DONE;
13659 })
13660
13661 (define_expand "sibcall"
13662 [(call (match_operand:QI 0 "" "")
13663 (match_operand 1 "" ""))
13664 (use (match_operand 2 "" ""))]
13665 ""
13666 {
13667 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13668 DONE;
13669 })
13670
13671 (define_insn "*call_0"
13672 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13673 (match_operand 1 "" ""))]
13674 ""
13675 {
13676 if (SIBLING_CALL_P (insn))
13677 return "jmp\t%P0";
13678 else
13679 return "call\t%P0";
13680 }
13681 [(set_attr "type" "call")])
13682
13683 (define_insn "*call_1"
13684 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13685 (match_operand 1 "" ""))]
13686 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13687 {
13688 if (constant_call_address_operand (operands[0], QImode))
13689 return "call\t%P0";
13690 return "call\t%A0";
13691 }
13692 [(set_attr "type" "call")])
13693
13694 (define_insn "*sibcall_1"
13695 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13696 (match_operand 1 "" ""))]
13697 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13698 {
13699 if (constant_call_address_operand (operands[0], QImode))
13700 return "jmp\t%P0";
13701 return "jmp\t%A0";
13702 }
13703 [(set_attr "type" "call")])
13704
13705 (define_insn "*call_1_rex64"
13706 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13707 (match_operand 1 "" ""))]
13708 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13709 {
13710 if (constant_call_address_operand (operands[0], QImode))
13711 return "call\t%P0";
13712 return "call\t%A0";
13713 }
13714 [(set_attr "type" "call")])
13715
13716 (define_insn "*sibcall_1_rex64"
13717 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13718 (match_operand 1 "" ""))]
13719 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13720 "jmp\t%P0"
13721 [(set_attr "type" "call")])
13722
13723 (define_insn "*sibcall_1_rex64_v"
13724 [(call (mem:QI (reg:DI 40))
13725 (match_operand 0 "" ""))]
13726 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13727 "jmp\t*%%r11"
13728 [(set_attr "type" "call")])
13729
13730
13731 ;; Call subroutine, returning value in operand 0
13732
13733 (define_expand "call_value_pop"
13734 [(parallel [(set (match_operand 0 "" "")
13735 (call (match_operand:QI 1 "" "")
13736 (match_operand:SI 2 "" "")))
13737 (set (reg:SI 7)
13738 (plus:SI (reg:SI 7)
13739 (match_operand:SI 4 "" "")))])]
13740 "!TARGET_64BIT"
13741 {
13742 ix86_expand_call (operands[0], operands[1], operands[2],
13743 operands[3], operands[4], 0);
13744 DONE;
13745 })
13746
13747 (define_expand "call_value"
13748 [(set (match_operand 0 "" "")
13749 (call (match_operand:QI 1 "" "")
13750 (match_operand:SI 2 "" "")))
13751 (use (match_operand:SI 3 "" ""))]
13752 ;; Operand 2 not used on the i386.
13753 ""
13754 {
13755 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13756 DONE;
13757 })
13758
13759 (define_expand "sibcall_value"
13760 [(set (match_operand 0 "" "")
13761 (call (match_operand:QI 1 "" "")
13762 (match_operand:SI 2 "" "")))
13763 (use (match_operand:SI 3 "" ""))]
13764 ;; Operand 2 not used on the i386.
13765 ""
13766 {
13767 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13768 DONE;
13769 })
13770
13771 ;; Call subroutine returning any type.
13772
13773 (define_expand "untyped_call"
13774 [(parallel [(call (match_operand 0 "" "")
13775 (const_int 0))
13776 (match_operand 1 "" "")
13777 (match_operand 2 "" "")])]
13778 ""
13779 {
13780 int i;
13781
13782 /* In order to give reg-stack an easier job in validating two
13783 coprocessor registers as containing a possible return value,
13784 simply pretend the untyped call returns a complex long double
13785 value. */
13786
13787 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13788 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13789 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13790 NULL, 0);
13791
13792 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13793 {
13794 rtx set = XVECEXP (operands[2], 0, i);
13795 emit_move_insn (SET_DEST (set), SET_SRC (set));
13796 }
13797
13798 /* The optimizer does not know that the call sets the function value
13799 registers we stored in the result block. We avoid problems by
13800 claiming that all hard registers are used and clobbered at this
13801 point. */
13802 emit_insn (gen_blockage (const0_rtx));
13803
13804 DONE;
13805 })
13806 \f
13807 ;; Prologue and epilogue instructions
13808
13809 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13810 ;; all of memory. This blocks insns from being moved across this point.
13811
13812 (define_insn "blockage"
13813 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13814 ""
13815 ""
13816 [(set_attr "length" "0")])
13817
13818 ;; Insn emitted into the body of a function to return from a function.
13819 ;; This is only done if the function's epilogue is known to be simple.
13820 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13821
13822 (define_expand "return"
13823 [(return)]
13824 "ix86_can_use_return_insn_p ()"
13825 {
13826 if (current_function_pops_args)
13827 {
13828 rtx popc = GEN_INT (current_function_pops_args);
13829 emit_jump_insn (gen_return_pop_internal (popc));
13830 DONE;
13831 }
13832 })
13833
13834 (define_insn "return_internal"
13835 [(return)]
13836 "reload_completed"
13837 "ret"
13838 [(set_attr "length" "1")
13839 (set_attr "length_immediate" "0")
13840 (set_attr "modrm" "0")])
13841
13842 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13843 ;; instruction Athlon and K8 have.
13844
13845 (define_insn "return_internal_long"
13846 [(return)
13847 (unspec [(const_int 0)] UNSPEC_REP)]
13848 "reload_completed"
13849 "rep {;} ret"
13850 [(set_attr "length" "1")
13851 (set_attr "length_immediate" "0")
13852 (set_attr "prefix_rep" "1")
13853 (set_attr "modrm" "0")])
13854
13855 (define_insn "return_pop_internal"
13856 [(return)
13857 (use (match_operand:SI 0 "const_int_operand" ""))]
13858 "reload_completed"
13859 "ret\t%0"
13860 [(set_attr "length" "3")
13861 (set_attr "length_immediate" "2")
13862 (set_attr "modrm" "0")])
13863
13864 (define_insn "return_indirect_internal"
13865 [(return)
13866 (use (match_operand:SI 0 "register_operand" "r"))]
13867 "reload_completed"
13868 "jmp\t%A0"
13869 [(set_attr "type" "ibr")
13870 (set_attr "length_immediate" "0")])
13871
13872 (define_insn "nop"
13873 [(const_int 0)]
13874 ""
13875 "nop"
13876 [(set_attr "length" "1")
13877 (set_attr "length_immediate" "0")
13878 (set_attr "modrm" "0")])
13879
13880 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13881 ;; branch prediction penalty for the third jump in a 16-byte
13882 ;; block on K8.
13883
13884 (define_insn "align"
13885 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13886 ""
13887 {
13888 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13889 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13890 #else
13891 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13892 The align insn is used to avoid 3 jump instructions in the row to improve
13893 branch prediction and the benefits hardly outweight the cost of extra 8
13894 nops on the average inserted by full alignment pseudo operation. */
13895 #endif
13896 return "";
13897 }
13898 [(set_attr "length" "16")])
13899
13900 (define_expand "prologue"
13901 [(const_int 1)]
13902 ""
13903 "ix86_expand_prologue (); DONE;")
13904
13905 (define_insn "set_got"
13906 [(set (match_operand:SI 0 "register_operand" "=r")
13907 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13908 (clobber (reg:CC 17))]
13909 "!TARGET_64BIT"
13910 { return output_set_got (operands[0]); }
13911 [(set_attr "type" "multi")
13912 (set_attr "length" "12")])
13913
13914 (define_expand "epilogue"
13915 [(const_int 1)]
13916 ""
13917 "ix86_expand_epilogue (1); DONE;")
13918
13919 (define_expand "sibcall_epilogue"
13920 [(const_int 1)]
13921 ""
13922 "ix86_expand_epilogue (0); DONE;")
13923
13924 (define_expand "eh_return"
13925 [(use (match_operand 0 "register_operand" ""))]
13926 ""
13927 {
13928 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13929
13930 /* Tricky bit: we write the address of the handler to which we will
13931 be returning into someone else's stack frame, one word below the
13932 stack address we wish to restore. */
13933 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13934 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13935 tmp = gen_rtx_MEM (Pmode, tmp);
13936 emit_move_insn (tmp, ra);
13937
13938 if (Pmode == SImode)
13939 emit_insn (gen_eh_return_si (sa));
13940 else
13941 emit_insn (gen_eh_return_di (sa));
13942 emit_barrier ();
13943 DONE;
13944 })
13945
13946 (define_insn_and_split "eh_return_si"
13947 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13948 UNSPECV_EH_RETURN)]
13949 "!TARGET_64BIT"
13950 "#"
13951 "reload_completed"
13952 [(const_int 1)]
13953 "ix86_expand_epilogue (2); DONE;")
13954
13955 (define_insn_and_split "eh_return_di"
13956 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13957 UNSPECV_EH_RETURN)]
13958 "TARGET_64BIT"
13959 "#"
13960 "reload_completed"
13961 [(const_int 1)]
13962 "ix86_expand_epilogue (2); DONE;")
13963
13964 (define_insn "leave"
13965 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13966 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13967 (clobber (mem:BLK (scratch)))]
13968 "!TARGET_64BIT"
13969 "leave"
13970 [(set_attr "type" "leave")])
13971
13972 (define_insn "leave_rex64"
13973 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13974 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13975 (clobber (mem:BLK (scratch)))]
13976 "TARGET_64BIT"
13977 "leave"
13978 [(set_attr "type" "leave")])
13979 \f
13980 (define_expand "ffssi2"
13981 [(parallel
13982 [(set (match_operand:SI 0 "register_operand" "")
13983 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13984 (clobber (match_scratch:SI 2 ""))
13985 (clobber (reg:CC 17))])]
13986 ""
13987 "")
13988
13989 (define_insn_and_split "*ffs_cmove"
13990 [(set (match_operand:SI 0 "register_operand" "=r")
13991 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13992 (clobber (match_scratch:SI 2 "=&r"))
13993 (clobber (reg:CC 17))]
13994 "TARGET_CMOVE"
13995 "#"
13996 "&& reload_completed"
13997 [(set (match_dup 2) (const_int -1))
13998 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13999 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14000 (set (match_dup 0) (if_then_else:SI
14001 (eq (reg:CCZ 17) (const_int 0))
14002 (match_dup 2)
14003 (match_dup 0)))
14004 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14005 (clobber (reg:CC 17))])]
14006 "")
14007
14008 (define_insn_and_split "*ffs_no_cmove"
14009 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14010 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14011 (clobber (match_scratch:SI 2 "=&q"))
14012 (clobber (reg:CC 17))]
14013 ""
14014 "#"
14015 "reload_completed"
14016 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14017 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14018 (set (strict_low_part (match_dup 3))
14019 (eq:QI (reg:CCZ 17) (const_int 0)))
14020 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14021 (clobber (reg:CC 17))])
14022 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14023 (clobber (reg:CC 17))])
14024 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14025 (clobber (reg:CC 17))])]
14026 {
14027 operands[3] = gen_lowpart (QImode, operands[2]);
14028 ix86_expand_clear (operands[2]);
14029 })
14030
14031 (define_insn "*ffssi_1"
14032 [(set (reg:CCZ 17)
14033 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14034 (const_int 0)))
14035 (set (match_operand:SI 0 "register_operand" "=r")
14036 (ctz:SI (match_dup 1)))]
14037 ""
14038 "bsf{l}\t{%1, %0|%0, %1}"
14039 [(set_attr "prefix_0f" "1")])
14040
14041 (define_insn "ctzsi2"
14042 [(set (match_operand:SI 0 "register_operand" "=r")
14043 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14044 (clobber (reg:CC 17))]
14045 ""
14046 "bsf{l}\t{%1, %0|%0, %1}"
14047 [(set_attr "prefix_0f" "1")])
14048
14049 (define_expand "clzsi2"
14050 [(parallel
14051 [(set (match_operand:SI 0 "register_operand" "")
14052 (minus:SI (const_int 31)
14053 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14054 (clobber (reg:CC 17))])
14055 (parallel
14056 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14057 (clobber (reg:CC 17))])]
14058 ""
14059 "")
14060
14061 (define_insn "*bsr"
14062 [(set (match_operand:SI 0 "register_operand" "=r")
14063 (minus:SI (const_int 31)
14064 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14065 (clobber (reg:CC 17))]
14066 ""
14067 "bsr{l}\t{%1, %0|%0, %1}"
14068 [(set_attr "prefix_0f" "1")])
14069 \f
14070 ;; Thread-local storage patterns for ELF.
14071 ;;
14072 ;; Note that these code sequences must appear exactly as shown
14073 ;; in order to allow linker relaxation.
14074
14075 (define_insn "*tls_global_dynamic_32_gnu"
14076 [(set (match_operand:SI 0 "register_operand" "=a")
14077 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14078 (match_operand:SI 2 "tls_symbolic_operand" "")
14079 (match_operand:SI 3 "call_insn_operand" "")]
14080 UNSPEC_TLS_GD))
14081 (clobber (match_scratch:SI 4 "=d"))
14082 (clobber (match_scratch:SI 5 "=c"))
14083 (clobber (reg:CC 17))]
14084 "!TARGET_64BIT && TARGET_GNU_TLS"
14085 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14086 [(set_attr "type" "multi")
14087 (set_attr "length" "12")])
14088
14089 (define_insn "*tls_global_dynamic_32_sun"
14090 [(set (match_operand:SI 0 "register_operand" "=a")
14091 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14092 (match_operand:SI 2 "tls_symbolic_operand" "")
14093 (match_operand:SI 3 "call_insn_operand" "")]
14094 UNSPEC_TLS_GD))
14095 (clobber (match_scratch:SI 4 "=d"))
14096 (clobber (match_scratch:SI 5 "=c"))
14097 (clobber (reg:CC 17))]
14098 "!TARGET_64BIT && TARGET_SUN_TLS"
14099 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14100 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14101 [(set_attr "type" "multi")
14102 (set_attr "length" "14")])
14103
14104 (define_expand "tls_global_dynamic_32"
14105 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14106 (unspec:SI
14107 [(match_dup 2)
14108 (match_operand:SI 1 "tls_symbolic_operand" "")
14109 (match_dup 3)]
14110 UNSPEC_TLS_GD))
14111 (clobber (match_scratch:SI 4 ""))
14112 (clobber (match_scratch:SI 5 ""))
14113 (clobber (reg:CC 17))])]
14114 ""
14115 {
14116 if (flag_pic)
14117 operands[2] = pic_offset_table_rtx;
14118 else
14119 {
14120 operands[2] = gen_reg_rtx (Pmode);
14121 emit_insn (gen_set_got (operands[2]));
14122 }
14123 operands[3] = ix86_tls_get_addr ();
14124 })
14125
14126 (define_insn "*tls_global_dynamic_64"
14127 [(set (match_operand:DI 0 "register_operand" "=a")
14128 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14129 (match_operand:DI 3 "" "")))
14130 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14131 UNSPEC_TLS_GD)]
14132 "TARGET_64BIT"
14133 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14134 [(set_attr "type" "multi")
14135 (set_attr "length" "16")])
14136
14137 (define_expand "tls_global_dynamic_64"
14138 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14139 (call (mem:QI (match_dup 2)) (const_int 0)))
14140 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14141 UNSPEC_TLS_GD)])]
14142 ""
14143 {
14144 operands[2] = ix86_tls_get_addr ();
14145 })
14146
14147 (define_insn "*tls_local_dynamic_base_32_gnu"
14148 [(set (match_operand:SI 0 "register_operand" "=a")
14149 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14150 (match_operand:SI 2 "call_insn_operand" "")]
14151 UNSPEC_TLS_LD_BASE))
14152 (clobber (match_scratch:SI 3 "=d"))
14153 (clobber (match_scratch:SI 4 "=c"))
14154 (clobber (reg:CC 17))]
14155 "!TARGET_64BIT && TARGET_GNU_TLS"
14156 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14157 [(set_attr "type" "multi")
14158 (set_attr "length" "11")])
14159
14160 (define_insn "*tls_local_dynamic_base_32_sun"
14161 [(set (match_operand:SI 0 "register_operand" "=a")
14162 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14163 (match_operand:SI 2 "call_insn_operand" "")]
14164 UNSPEC_TLS_LD_BASE))
14165 (clobber (match_scratch:SI 3 "=d"))
14166 (clobber (match_scratch:SI 4 "=c"))
14167 (clobber (reg:CC 17))]
14168 "!TARGET_64BIT && TARGET_SUN_TLS"
14169 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14170 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14171 [(set_attr "type" "multi")
14172 (set_attr "length" "13")])
14173
14174 (define_expand "tls_local_dynamic_base_32"
14175 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14176 (unspec:SI [(match_dup 1) (match_dup 2)]
14177 UNSPEC_TLS_LD_BASE))
14178 (clobber (match_scratch:SI 3 ""))
14179 (clobber (match_scratch:SI 4 ""))
14180 (clobber (reg:CC 17))])]
14181 ""
14182 {
14183 if (flag_pic)
14184 operands[1] = pic_offset_table_rtx;
14185 else
14186 {
14187 operands[1] = gen_reg_rtx (Pmode);
14188 emit_insn (gen_set_got (operands[1]));
14189 }
14190 operands[2] = ix86_tls_get_addr ();
14191 })
14192
14193 (define_insn "*tls_local_dynamic_base_64"
14194 [(set (match_operand:DI 0 "register_operand" "=a")
14195 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14196 (match_operand:DI 2 "" "")))
14197 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14198 "TARGET_64BIT"
14199 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14200 [(set_attr "type" "multi")
14201 (set_attr "length" "12")])
14202
14203 (define_expand "tls_local_dynamic_base_64"
14204 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14205 (call (mem:QI (match_dup 1)) (const_int 0)))
14206 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14207 ""
14208 {
14209 operands[1] = ix86_tls_get_addr ();
14210 })
14211
14212 ;; Local dynamic of a single variable is a lose. Show combine how
14213 ;; to convert that back to global dynamic.
14214
14215 (define_insn_and_split "*tls_local_dynamic_32_once"
14216 [(set (match_operand:SI 0 "register_operand" "=a")
14217 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14218 (match_operand:SI 2 "call_insn_operand" "")]
14219 UNSPEC_TLS_LD_BASE)
14220 (const:SI (unspec:SI
14221 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14222 UNSPEC_DTPOFF))))
14223 (clobber (match_scratch:SI 4 "=d"))
14224 (clobber (match_scratch:SI 5 "=c"))
14225 (clobber (reg:CC 17))]
14226 ""
14227 "#"
14228 ""
14229 [(parallel [(set (match_dup 0)
14230 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14231 UNSPEC_TLS_GD))
14232 (clobber (match_dup 4))
14233 (clobber (match_dup 5))
14234 (clobber (reg:CC 17))])]
14235 "")
14236
14237 ;; Load and add the thread base pointer from %gs:0.
14238
14239 (define_insn "*load_tp_si"
14240 [(set (match_operand:SI 0 "register_operand" "=r")
14241 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14242 "!TARGET_64BIT"
14243 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14244 [(set_attr "type" "imov")
14245 (set_attr "modrm" "0")
14246 (set_attr "length" "7")
14247 (set_attr "memory" "load")
14248 (set_attr "imm_disp" "false")])
14249
14250 (define_insn "*add_tp_si"
14251 [(set (match_operand:SI 0 "register_operand" "=r")
14252 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14253 (match_operand:SI 1 "register_operand" "0")))
14254 (clobber (reg:CC 17))]
14255 "!TARGET_64BIT"
14256 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14257 [(set_attr "type" "alu")
14258 (set_attr "modrm" "0")
14259 (set_attr "length" "7")
14260 (set_attr "memory" "load")
14261 (set_attr "imm_disp" "false")])
14262
14263 (define_insn "*load_tp_di"
14264 [(set (match_operand:DI 0 "register_operand" "=r")
14265 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14266 "TARGET_64BIT"
14267 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14268 [(set_attr "type" "imov")
14269 (set_attr "modrm" "0")
14270 (set_attr "length" "7")
14271 (set_attr "memory" "load")
14272 (set_attr "imm_disp" "false")])
14273
14274 (define_insn "*add_tp_di"
14275 [(set (match_operand:DI 0 "register_operand" "=r")
14276 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14277 (match_operand:DI 1 "register_operand" "0")))
14278 (clobber (reg:CC 17))]
14279 "TARGET_64BIT"
14280 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14281 [(set_attr "type" "alu")
14282 (set_attr "modrm" "0")
14283 (set_attr "length" "7")
14284 (set_attr "memory" "load")
14285 (set_attr "imm_disp" "false")])
14286 \f
14287 ;; These patterns match the binary 387 instructions for addM3, subM3,
14288 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14289 ;; SFmode. The first is the normal insn, the second the same insn but
14290 ;; with one operand a conversion, and the third the same insn but with
14291 ;; the other operand a conversion. The conversion may be SFmode or
14292 ;; SImode if the target mode DFmode, but only SImode if the target mode
14293 ;; is SFmode.
14294
14295 ;; Gcc is slightly more smart about handling normal two address instructions
14296 ;; so use special patterns for add and mull.
14297 (define_insn "*fop_sf_comm_nosse"
14298 [(set (match_operand:SF 0 "register_operand" "=f")
14299 (match_operator:SF 3 "binary_fp_operator"
14300 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14301 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14302 "TARGET_80387 && !TARGET_SSE_MATH
14303 && COMMUTATIVE_ARITH_P (operands[3])
14304 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14305 "* return output_387_binary_op (insn, operands);"
14306 [(set (attr "type")
14307 (if_then_else (match_operand:SF 3 "mult_operator" "")
14308 (const_string "fmul")
14309 (const_string "fop")))
14310 (set_attr "mode" "SF")])
14311
14312 (define_insn "*fop_sf_comm"
14313 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14314 (match_operator:SF 3 "binary_fp_operator"
14315 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14316 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14317 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14318 && COMMUTATIVE_ARITH_P (operands[3])
14319 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14320 "* return output_387_binary_op (insn, operands);"
14321 [(set (attr "type")
14322 (if_then_else (eq_attr "alternative" "1")
14323 (if_then_else (match_operand:SF 3 "mult_operator" "")
14324 (const_string "ssemul")
14325 (const_string "sseadd"))
14326 (if_then_else (match_operand:SF 3 "mult_operator" "")
14327 (const_string "fmul")
14328 (const_string "fop"))))
14329 (set_attr "mode" "SF")])
14330
14331 (define_insn "*fop_sf_comm_sse"
14332 [(set (match_operand:SF 0 "register_operand" "=x")
14333 (match_operator:SF 3 "binary_fp_operator"
14334 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14335 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14336 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14337 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14338 "* return output_387_binary_op (insn, operands);"
14339 [(set (attr "type")
14340 (if_then_else (match_operand:SF 3 "mult_operator" "")
14341 (const_string "ssemul")
14342 (const_string "sseadd")))
14343 (set_attr "mode" "SF")])
14344
14345 (define_insn "*fop_df_comm_nosse"
14346 [(set (match_operand:DF 0 "register_operand" "=f")
14347 (match_operator:DF 3 "binary_fp_operator"
14348 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14349 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14350 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14351 && COMMUTATIVE_ARITH_P (operands[3])
14352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14353 "* return output_387_binary_op (insn, operands);"
14354 [(set (attr "type")
14355 (if_then_else (match_operand:SF 3 "mult_operator" "")
14356 (const_string "fmul")
14357 (const_string "fop")))
14358 (set_attr "mode" "DF")])
14359
14360 (define_insn "*fop_df_comm"
14361 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14362 (match_operator:DF 3 "binary_fp_operator"
14363 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14364 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14365 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14366 && COMMUTATIVE_ARITH_P (operands[3])
14367 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14368 "* return output_387_binary_op (insn, operands);"
14369 [(set (attr "type")
14370 (if_then_else (eq_attr "alternative" "1")
14371 (if_then_else (match_operand:SF 3 "mult_operator" "")
14372 (const_string "ssemul")
14373 (const_string "sseadd"))
14374 (if_then_else (match_operand:SF 3 "mult_operator" "")
14375 (const_string "fmul")
14376 (const_string "fop"))))
14377 (set_attr "mode" "DF")])
14378
14379 (define_insn "*fop_df_comm_sse"
14380 [(set (match_operand:DF 0 "register_operand" "=Y")
14381 (match_operator:DF 3 "binary_fp_operator"
14382 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14383 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14384 "TARGET_SSE2 && TARGET_SSE_MATH
14385 && COMMUTATIVE_ARITH_P (operands[3])
14386 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14387 "* return output_387_binary_op (insn, operands);"
14388 [(set (attr "type")
14389 (if_then_else (match_operand:SF 3 "mult_operator" "")
14390 (const_string "ssemul")
14391 (const_string "sseadd")))
14392 (set_attr "mode" "DF")])
14393
14394 (define_insn "*fop_xf_comm"
14395 [(set (match_operand:XF 0 "register_operand" "=f")
14396 (match_operator:XF 3 "binary_fp_operator"
14397 [(match_operand:XF 1 "register_operand" "%0")
14398 (match_operand:XF 2 "register_operand" "f")]))]
14399 "TARGET_80387
14400 && COMMUTATIVE_ARITH_P (operands[3])"
14401 "* return output_387_binary_op (insn, operands);"
14402 [(set (attr "type")
14403 (if_then_else (match_operand:XF 3 "mult_operator" "")
14404 (const_string "fmul")
14405 (const_string "fop")))
14406 (set_attr "mode" "XF")])
14407
14408 (define_insn "*fop_sf_1_nosse"
14409 [(set (match_operand:SF 0 "register_operand" "=f,f")
14410 (match_operator:SF 3 "binary_fp_operator"
14411 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14412 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14413 "TARGET_80387 && !TARGET_SSE_MATH
14414 && !COMMUTATIVE_ARITH_P (operands[3])
14415 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14416 "* return output_387_binary_op (insn, operands);"
14417 [(set (attr "type")
14418 (cond [(match_operand:SF 3 "mult_operator" "")
14419 (const_string "fmul")
14420 (match_operand:SF 3 "div_operator" "")
14421 (const_string "fdiv")
14422 ]
14423 (const_string "fop")))
14424 (set_attr "mode" "SF")])
14425
14426 (define_insn "*fop_sf_1"
14427 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14428 (match_operator:SF 3 "binary_fp_operator"
14429 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14430 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14431 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14432 && !COMMUTATIVE_ARITH_P (operands[3])
14433 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14434 "* return output_387_binary_op (insn, operands);"
14435 [(set (attr "type")
14436 (cond [(and (eq_attr "alternative" "2")
14437 (match_operand:SF 3 "mult_operator" ""))
14438 (const_string "ssemul")
14439 (and (eq_attr "alternative" "2")
14440 (match_operand:SF 3 "div_operator" ""))
14441 (const_string "ssediv")
14442 (eq_attr "alternative" "2")
14443 (const_string "sseadd")
14444 (match_operand:SF 3 "mult_operator" "")
14445 (const_string "fmul")
14446 (match_operand:SF 3 "div_operator" "")
14447 (const_string "fdiv")
14448 ]
14449 (const_string "fop")))
14450 (set_attr "mode" "SF")])
14451
14452 (define_insn "*fop_sf_1_sse"
14453 [(set (match_operand:SF 0 "register_operand" "=x")
14454 (match_operator:SF 3 "binary_fp_operator"
14455 [(match_operand:SF 1 "register_operand" "0")
14456 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14457 "TARGET_SSE_MATH
14458 && !COMMUTATIVE_ARITH_P (operands[3])"
14459 "* return output_387_binary_op (insn, operands);"
14460 [(set (attr "type")
14461 (cond [(match_operand:SF 3 "mult_operator" "")
14462 (const_string "ssemul")
14463 (match_operand:SF 3 "div_operator" "")
14464 (const_string "ssediv")
14465 ]
14466 (const_string "sseadd")))
14467 (set_attr "mode" "SF")])
14468
14469 ;; ??? Add SSE splitters for these!
14470 (define_insn "*fop_sf_2"
14471 [(set (match_operand:SF 0 "register_operand" "=f,f")
14472 (match_operator:SF 3 "binary_fp_operator"
14473 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14474 (match_operand:SF 2 "register_operand" "0,0")]))]
14475 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14476 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14477 [(set (attr "type")
14478 (cond [(match_operand:SF 3 "mult_operator" "")
14479 (const_string "fmul")
14480 (match_operand:SF 3 "div_operator" "")
14481 (const_string "fdiv")
14482 ]
14483 (const_string "fop")))
14484 (set_attr "fp_int_src" "true")
14485 (set_attr "mode" "SI")])
14486
14487 (define_insn "*fop_sf_3"
14488 [(set (match_operand:SF 0 "register_operand" "=f,f")
14489 (match_operator:SF 3 "binary_fp_operator"
14490 [(match_operand:SF 1 "register_operand" "0,0")
14491 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14492 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14493 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14494 [(set (attr "type")
14495 (cond [(match_operand:SF 3 "mult_operator" "")
14496 (const_string "fmul")
14497 (match_operand:SF 3 "div_operator" "")
14498 (const_string "fdiv")
14499 ]
14500 (const_string "fop")))
14501 (set_attr "fp_int_src" "true")
14502 (set_attr "mode" "SI")])
14503
14504 (define_insn "*fop_df_1_nosse"
14505 [(set (match_operand:DF 0 "register_operand" "=f,f")
14506 (match_operator:DF 3 "binary_fp_operator"
14507 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14508 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14509 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14510 && !COMMUTATIVE_ARITH_P (operands[3])
14511 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14512 "* return output_387_binary_op (insn, operands);"
14513 [(set (attr "type")
14514 (cond [(match_operand:DF 3 "mult_operator" "")
14515 (const_string "fmul")
14516 (match_operand:DF 3 "div_operator" "")
14517 (const_string "fdiv")
14518 ]
14519 (const_string "fop")))
14520 (set_attr "mode" "DF")])
14521
14522
14523 (define_insn "*fop_df_1"
14524 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14525 (match_operator:DF 3 "binary_fp_operator"
14526 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14527 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14528 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14529 && !COMMUTATIVE_ARITH_P (operands[3])
14530 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14531 "* return output_387_binary_op (insn, operands);"
14532 [(set (attr "type")
14533 (cond [(and (eq_attr "alternative" "2")
14534 (match_operand:SF 3 "mult_operator" ""))
14535 (const_string "ssemul")
14536 (and (eq_attr "alternative" "2")
14537 (match_operand:SF 3 "div_operator" ""))
14538 (const_string "ssediv")
14539 (eq_attr "alternative" "2")
14540 (const_string "sseadd")
14541 (match_operand:DF 3 "mult_operator" "")
14542 (const_string "fmul")
14543 (match_operand:DF 3 "div_operator" "")
14544 (const_string "fdiv")
14545 ]
14546 (const_string "fop")))
14547 (set_attr "mode" "DF")])
14548
14549 (define_insn "*fop_df_1_sse"
14550 [(set (match_operand:DF 0 "register_operand" "=Y")
14551 (match_operator:DF 3 "binary_fp_operator"
14552 [(match_operand:DF 1 "register_operand" "0")
14553 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14554 "TARGET_SSE2 && TARGET_SSE_MATH
14555 && !COMMUTATIVE_ARITH_P (operands[3])"
14556 "* return output_387_binary_op (insn, operands);"
14557 [(set_attr "mode" "DF")
14558 (set (attr "type")
14559 (cond [(match_operand:SF 3 "mult_operator" "")
14560 (const_string "ssemul")
14561 (match_operand:SF 3 "div_operator" "")
14562 (const_string "ssediv")
14563 ]
14564 (const_string "sseadd")))])
14565
14566 ;; ??? Add SSE splitters for these!
14567 (define_insn "*fop_df_2"
14568 [(set (match_operand:DF 0 "register_operand" "=f,f")
14569 (match_operator:DF 3 "binary_fp_operator"
14570 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14571 (match_operand:DF 2 "register_operand" "0,0")]))]
14572 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14573 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14574 [(set (attr "type")
14575 (cond [(match_operand:DF 3 "mult_operator" "")
14576 (const_string "fmul")
14577 (match_operand:DF 3 "div_operator" "")
14578 (const_string "fdiv")
14579 ]
14580 (const_string "fop")))
14581 (set_attr "fp_int_src" "true")
14582 (set_attr "mode" "SI")])
14583
14584 (define_insn "*fop_df_3"
14585 [(set (match_operand:DF 0 "register_operand" "=f,f")
14586 (match_operator:DF 3 "binary_fp_operator"
14587 [(match_operand:DF 1 "register_operand" "0,0")
14588 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14589 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14590 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14591 [(set (attr "type")
14592 (cond [(match_operand:DF 3 "mult_operator" "")
14593 (const_string "fmul")
14594 (match_operand:DF 3 "div_operator" "")
14595 (const_string "fdiv")
14596 ]
14597 (const_string "fop")))
14598 (set_attr "fp_int_src" "true")
14599 (set_attr "mode" "SI")])
14600
14601 (define_insn "*fop_df_4"
14602 [(set (match_operand:DF 0 "register_operand" "=f,f")
14603 (match_operator:DF 3 "binary_fp_operator"
14604 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14605 (match_operand:DF 2 "register_operand" "0,f")]))]
14606 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14607 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14608 "* return output_387_binary_op (insn, operands);"
14609 [(set (attr "type")
14610 (cond [(match_operand:DF 3 "mult_operator" "")
14611 (const_string "fmul")
14612 (match_operand:DF 3 "div_operator" "")
14613 (const_string "fdiv")
14614 ]
14615 (const_string "fop")))
14616 (set_attr "mode" "SF")])
14617
14618 (define_insn "*fop_df_5"
14619 [(set (match_operand:DF 0 "register_operand" "=f,f")
14620 (match_operator:DF 3 "binary_fp_operator"
14621 [(match_operand:DF 1 "register_operand" "0,f")
14622 (float_extend:DF
14623 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14624 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14625 "* return output_387_binary_op (insn, operands);"
14626 [(set (attr "type")
14627 (cond [(match_operand:DF 3 "mult_operator" "")
14628 (const_string "fmul")
14629 (match_operand:DF 3 "div_operator" "")
14630 (const_string "fdiv")
14631 ]
14632 (const_string "fop")))
14633 (set_attr "mode" "SF")])
14634
14635 (define_insn "*fop_df_6"
14636 [(set (match_operand:DF 0 "register_operand" "=f,f")
14637 (match_operator:DF 3 "binary_fp_operator"
14638 [(float_extend:DF
14639 (match_operand:SF 1 "register_operand" "0,f"))
14640 (float_extend:DF
14641 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14642 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14643 "* return output_387_binary_op (insn, operands);"
14644 [(set (attr "type")
14645 (cond [(match_operand:DF 3 "mult_operator" "")
14646 (const_string "fmul")
14647 (match_operand:DF 3 "div_operator" "")
14648 (const_string "fdiv")
14649 ]
14650 (const_string "fop")))
14651 (set_attr "mode" "SF")])
14652
14653 (define_insn "*fop_xf_1"
14654 [(set (match_operand:XF 0 "register_operand" "=f,f")
14655 (match_operator:XF 3 "binary_fp_operator"
14656 [(match_operand:XF 1 "register_operand" "0,f")
14657 (match_operand:XF 2 "register_operand" "f,0")]))]
14658 "TARGET_80387
14659 && !COMMUTATIVE_ARITH_P (operands[3])"
14660 "* return output_387_binary_op (insn, operands);"
14661 [(set (attr "type")
14662 (cond [(match_operand:XF 3 "mult_operator" "")
14663 (const_string "fmul")
14664 (match_operand:XF 3 "div_operator" "")
14665 (const_string "fdiv")
14666 ]
14667 (const_string "fop")))
14668 (set_attr "mode" "XF")])
14669
14670 (define_insn "*fop_xf_2"
14671 [(set (match_operand:XF 0 "register_operand" "=f,f")
14672 (match_operator:XF 3 "binary_fp_operator"
14673 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14674 (match_operand:XF 2 "register_operand" "0,0")]))]
14675 "TARGET_80387 && TARGET_USE_FIOP"
14676 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14677 [(set (attr "type")
14678 (cond [(match_operand:XF 3 "mult_operator" "")
14679 (const_string "fmul")
14680 (match_operand:XF 3 "div_operator" "")
14681 (const_string "fdiv")
14682 ]
14683 (const_string "fop")))
14684 (set_attr "fp_int_src" "true")
14685 (set_attr "mode" "SI")])
14686
14687 (define_insn "*fop_xf_3"
14688 [(set (match_operand:XF 0 "register_operand" "=f,f")
14689 (match_operator:XF 3 "binary_fp_operator"
14690 [(match_operand:XF 1 "register_operand" "0,0")
14691 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14692 "TARGET_80387 && TARGET_USE_FIOP"
14693 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14694 [(set (attr "type")
14695 (cond [(match_operand:XF 3 "mult_operator" "")
14696 (const_string "fmul")
14697 (match_operand:XF 3 "div_operator" "")
14698 (const_string "fdiv")
14699 ]
14700 (const_string "fop")))
14701 (set_attr "fp_int_src" "true")
14702 (set_attr "mode" "SI")])
14703
14704 (define_insn "*fop_xf_4"
14705 [(set (match_operand:XF 0 "register_operand" "=f,f")
14706 (match_operator:XF 3 "binary_fp_operator"
14707 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14708 (match_operand:XF 2 "register_operand" "0,f")]))]
14709 "TARGET_80387"
14710 "* return output_387_binary_op (insn, operands);"
14711 [(set (attr "type")
14712 (cond [(match_operand:XF 3 "mult_operator" "")
14713 (const_string "fmul")
14714 (match_operand:XF 3 "div_operator" "")
14715 (const_string "fdiv")
14716 ]
14717 (const_string "fop")))
14718 (set_attr "mode" "SF")])
14719
14720 (define_insn "*fop_xf_5"
14721 [(set (match_operand:XF 0 "register_operand" "=f,f")
14722 (match_operator:XF 3 "binary_fp_operator"
14723 [(match_operand:XF 1 "register_operand" "0,f")
14724 (float_extend:XF
14725 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14726 "TARGET_80387"
14727 "* return output_387_binary_op (insn, operands);"
14728 [(set (attr "type")
14729 (cond [(match_operand:XF 3 "mult_operator" "")
14730 (const_string "fmul")
14731 (match_operand:XF 3 "div_operator" "")
14732 (const_string "fdiv")
14733 ]
14734 (const_string "fop")))
14735 (set_attr "mode" "SF")])
14736
14737 (define_insn "*fop_xf_6"
14738 [(set (match_operand:XF 0 "register_operand" "=f,f")
14739 (match_operator:XF 3 "binary_fp_operator"
14740 [(float_extend:XF
14741 (match_operand 1 "register_operand" "0,f"))
14742 (float_extend:XF
14743 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14744 "TARGET_80387"
14745 "* return output_387_binary_op (insn, operands);"
14746 [(set (attr "type")
14747 (cond [(match_operand:XF 3 "mult_operator" "")
14748 (const_string "fmul")
14749 (match_operand:XF 3 "div_operator" "")
14750 (const_string "fdiv")
14751 ]
14752 (const_string "fop")))
14753 (set_attr "mode" "SF")])
14754
14755 (define_split
14756 [(set (match_operand 0 "register_operand" "")
14757 (match_operator 3 "binary_fp_operator"
14758 [(float (match_operand:SI 1 "register_operand" ""))
14759 (match_operand 2 "register_operand" "")]))]
14760 "TARGET_80387 && reload_completed
14761 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14762 [(const_int 0)]
14763 {
14764 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14765 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14766 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14767 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14768 GET_MODE (operands[3]),
14769 operands[4],
14770 operands[2])));
14771 ix86_free_from_memory (GET_MODE (operands[1]));
14772 DONE;
14773 })
14774
14775 (define_split
14776 [(set (match_operand 0 "register_operand" "")
14777 (match_operator 3 "binary_fp_operator"
14778 [(match_operand 1 "register_operand" "")
14779 (float (match_operand:SI 2 "register_operand" ""))]))]
14780 "TARGET_80387 && reload_completed
14781 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14782 [(const_int 0)]
14783 {
14784 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14785 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14786 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14787 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14788 GET_MODE (operands[3]),
14789 operands[1],
14790 operands[4])));
14791 ix86_free_from_memory (GET_MODE (operands[2]));
14792 DONE;
14793 })
14794 \f
14795 ;; FPU special functions.
14796
14797 (define_expand "sqrtsf2"
14798 [(set (match_operand:SF 0 "register_operand" "")
14799 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14800 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14801 {
14802 if (!TARGET_SSE_MATH)
14803 operands[1] = force_reg (SFmode, operands[1]);
14804 })
14805
14806 (define_insn "sqrtsf2_1"
14807 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14808 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14809 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14810 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14811 "@
14812 fsqrt
14813 sqrtss\t{%1, %0|%0, %1}"
14814 [(set_attr "type" "fpspc,sse")
14815 (set_attr "mode" "SF,SF")
14816 (set_attr "athlon_decode" "direct,*")])
14817
14818 (define_insn "sqrtsf2_1_sse_only"
14819 [(set (match_operand:SF 0 "register_operand" "=x")
14820 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14821 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14822 "sqrtss\t{%1, %0|%0, %1}"
14823 [(set_attr "type" "sse")
14824 (set_attr "mode" "SF")
14825 (set_attr "athlon_decode" "*")])
14826
14827 (define_insn "sqrtsf2_i387"
14828 [(set (match_operand:SF 0 "register_operand" "=f")
14829 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14830 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14831 && !TARGET_SSE_MATH"
14832 "fsqrt"
14833 [(set_attr "type" "fpspc")
14834 (set_attr "mode" "SF")
14835 (set_attr "athlon_decode" "direct")])
14836
14837 (define_expand "sqrtdf2"
14838 [(set (match_operand:DF 0 "register_operand" "")
14839 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14840 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14841 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14842 {
14843 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14844 operands[1] = force_reg (DFmode, operands[1]);
14845 })
14846
14847 (define_insn "sqrtdf2_1"
14848 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14849 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14850 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14851 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14852 "@
14853 fsqrt
14854 sqrtsd\t{%1, %0|%0, %1}"
14855 [(set_attr "type" "fpspc,sse")
14856 (set_attr "mode" "DF,DF")
14857 (set_attr "athlon_decode" "direct,*")])
14858
14859 (define_insn "sqrtdf2_1_sse_only"
14860 [(set (match_operand:DF 0 "register_operand" "=Y")
14861 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14862 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14863 "sqrtsd\t{%1, %0|%0, %1}"
14864 [(set_attr "type" "sse")
14865 (set_attr "mode" "DF")
14866 (set_attr "athlon_decode" "*")])
14867
14868 (define_insn "sqrtdf2_i387"
14869 [(set (match_operand:DF 0 "register_operand" "=f")
14870 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14871 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14872 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14873 "fsqrt"
14874 [(set_attr "type" "fpspc")
14875 (set_attr "mode" "DF")
14876 (set_attr "athlon_decode" "direct")])
14877
14878 (define_insn "*sqrtextendsfdf2"
14879 [(set (match_operand:DF 0 "register_operand" "=f")
14880 (sqrt:DF (float_extend:DF
14881 (match_operand:SF 1 "register_operand" "0"))))]
14882 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14883 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14884 "fsqrt"
14885 [(set_attr "type" "fpspc")
14886 (set_attr "mode" "DF")
14887 (set_attr "athlon_decode" "direct")])
14888
14889 (define_insn "sqrtxf2"
14890 [(set (match_operand:XF 0 "register_operand" "=f")
14891 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14892 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14893 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14894 "fsqrt"
14895 [(set_attr "type" "fpspc")
14896 (set_attr "mode" "XF")
14897 (set_attr "athlon_decode" "direct")])
14898
14899 (define_insn "*sqrtextenddfxf2"
14900 [(set (match_operand:XF 0 "register_operand" "=f")
14901 (sqrt:XF (float_extend:XF
14902 (match_operand:DF 1 "register_operand" "0"))))]
14903 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14904 "fsqrt"
14905 [(set_attr "type" "fpspc")
14906 (set_attr "mode" "XF")
14907 (set_attr "athlon_decode" "direct")])
14908
14909 (define_insn "*sqrtextendsfxf2"
14910 [(set (match_operand:XF 0 "register_operand" "=f")
14911 (sqrt:XF (float_extend:XF
14912 (match_operand:SF 1 "register_operand" "0"))))]
14913 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14914 "fsqrt"
14915 [(set_attr "type" "fpspc")
14916 (set_attr "mode" "XF")
14917 (set_attr "athlon_decode" "direct")])
14918
14919 (define_insn "sindf2"
14920 [(set (match_operand:DF 0 "register_operand" "=f")
14921 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14922 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14923 && flag_unsafe_math_optimizations"
14924 "fsin"
14925 [(set_attr "type" "fpspc")
14926 (set_attr "mode" "DF")])
14927
14928 (define_insn "sinsf2"
14929 [(set (match_operand:SF 0 "register_operand" "=f")
14930 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14931 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14932 && flag_unsafe_math_optimizations"
14933 "fsin"
14934 [(set_attr "type" "fpspc")
14935 (set_attr "mode" "SF")])
14936
14937 (define_insn "*sinextendsfdf2"
14938 [(set (match_operand:DF 0 "register_operand" "=f")
14939 (unspec:DF [(float_extend:DF
14940 (match_operand:SF 1 "register_operand" "0"))]
14941 UNSPEC_SIN))]
14942 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14943 && flag_unsafe_math_optimizations"
14944 "fsin"
14945 [(set_attr "type" "fpspc")
14946 (set_attr "mode" "DF")])
14947
14948 (define_insn "sinxf2"
14949 [(set (match_operand:XF 0 "register_operand" "=f")
14950 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14951 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14952 && flag_unsafe_math_optimizations"
14953 "fsin"
14954 [(set_attr "type" "fpspc")
14955 (set_attr "mode" "XF")])
14956
14957 (define_insn "cosdf2"
14958 [(set (match_operand:DF 0 "register_operand" "=f")
14959 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14960 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14961 && flag_unsafe_math_optimizations"
14962 "fcos"
14963 [(set_attr "type" "fpspc")
14964 (set_attr "mode" "DF")])
14965
14966 (define_insn "cossf2"
14967 [(set (match_operand:SF 0 "register_operand" "=f")
14968 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14969 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14970 && flag_unsafe_math_optimizations"
14971 "fcos"
14972 [(set_attr "type" "fpspc")
14973 (set_attr "mode" "SF")])
14974
14975 (define_insn "*cosextendsfdf2"
14976 [(set (match_operand:DF 0 "register_operand" "=f")
14977 (unspec:DF [(float_extend:DF
14978 (match_operand:SF 1 "register_operand" "0"))]
14979 UNSPEC_COS))]
14980 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14981 && flag_unsafe_math_optimizations"
14982 "fcos"
14983 [(set_attr "type" "fpspc")
14984 (set_attr "mode" "DF")])
14985
14986 (define_insn "cosxf2"
14987 [(set (match_operand:XF 0 "register_operand" "=f")
14988 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14989 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14990 && flag_unsafe_math_optimizations"
14991 "fcos"
14992 [(set_attr "type" "fpspc")
14993 (set_attr "mode" "XF")])
14994
14995 (define_insn "atan2df3_1"
14996 [(set (match_operand:DF 0 "register_operand" "=f")
14997 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
14998 (match_operand:DF 1 "register_operand" "u")]
14999 UNSPEC_FPATAN))
15000 (clobber (match_scratch:DF 3 "=1"))]
15001 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15002 && flag_unsafe_math_optimizations"
15003 "fpatan"
15004 [(set_attr "type" "fpspc")
15005 (set_attr "mode" "DF")])
15006
15007 (define_expand "atan2df3"
15008 [(use (match_operand:DF 0 "register_operand" "=f"))
15009 (use (match_operand:DF 2 "register_operand" "0"))
15010 (use (match_operand:DF 1 "register_operand" "u"))]
15011 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15012 && flag_unsafe_math_optimizations"
15013 {
15014 rtx copy = gen_reg_rtx (DFmode);
15015 emit_move_insn (copy, operands[1]);
15016 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15017 DONE;
15018 })
15019
15020 (define_insn "atan2sf3_1"
15021 [(set (match_operand:SF 0 "register_operand" "=f")
15022 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15023 (match_operand:SF 1 "register_operand" "u")]
15024 UNSPEC_FPATAN))
15025 (clobber (match_scratch:SF 3 "=1"))]
15026 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15027 && flag_unsafe_math_optimizations"
15028 "fpatan"
15029 [(set_attr "type" "fpspc")
15030 (set_attr "mode" "SF")])
15031
15032 (define_expand "atan2sf3"
15033 [(use (match_operand:SF 0 "register_operand" "=f"))
15034 (use (match_operand:SF 2 "register_operand" "0"))
15035 (use (match_operand:SF 1 "register_operand" "u"))]
15036 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15037 && flag_unsafe_math_optimizations"
15038 {
15039 rtx copy = gen_reg_rtx (SFmode);
15040 emit_move_insn (copy, operands[1]);
15041 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15042 DONE;
15043 })
15044
15045 (define_insn "atan2xf3_1"
15046 [(set (match_operand:XF 0 "register_operand" "=f")
15047 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15048 (match_operand:XF 1 "register_operand" "u")]
15049 UNSPEC_FPATAN))
15050 (clobber (match_scratch:XF 3 "=1"))]
15051 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15052 && flag_unsafe_math_optimizations"
15053 "fpatan"
15054 [(set_attr "type" "fpspc")
15055 (set_attr "mode" "XF")])
15056
15057 (define_expand "atan2xf3"
15058 [(use (match_operand:XF 0 "register_operand" "=f"))
15059 (use (match_operand:XF 2 "register_operand" "0"))
15060 (use (match_operand:XF 1 "register_operand" "u"))]
15061 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15062 && flag_unsafe_math_optimizations"
15063 {
15064 rtx copy = gen_reg_rtx (XFmode);
15065 emit_move_insn (copy, operands[1]);
15066 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15067 DONE;
15068 })
15069
15070 (define_insn "*fyl2x_sfxf3"
15071 [(set (match_operand:SF 0 "register_operand" "=f")
15072 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15073 (match_operand:XF 1 "register_operand" "u")]
15074 UNSPEC_FYL2X))
15075 (clobber (match_scratch:SF 3 "=1"))]
15076 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15077 && flag_unsafe_math_optimizations"
15078 "fyl2x"
15079 [(set_attr "type" "fpspc")
15080 (set_attr "mode" "SF")])
15081
15082 (define_insn "*fyl2x_dfxf3"
15083 [(set (match_operand:DF 0 "register_operand" "=f")
15084 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15085 (match_operand:XF 1 "register_operand" "u")]
15086 UNSPEC_FYL2X))
15087 (clobber (match_scratch:DF 3 "=1"))]
15088 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15089 && flag_unsafe_math_optimizations"
15090 "fyl2x"
15091 [(set_attr "type" "fpspc")
15092 (set_attr "mode" "DF")])
15093
15094 (define_insn "*fyl2x_xf3"
15095 [(set (match_operand:XF 0 "register_operand" "=f")
15096 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15097 (match_operand:XF 1 "register_operand" "u")]
15098 UNSPEC_FYL2X))
15099 (clobber (match_scratch:XF 3 "=1"))]
15100 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15101 && flag_unsafe_math_optimizations"
15102 "fyl2x"
15103 [(set_attr "type" "fpspc")
15104 (set_attr "mode" "XF")])
15105
15106 (define_expand "logsf2"
15107 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15108 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15109 (match_dup 2)] UNSPEC_FYL2X))
15110 (clobber (match_scratch:SF 3 ""))])]
15111 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15112 && flag_unsafe_math_optimizations"
15113 {
15114 rtx temp;
15115
15116 operands[2] = gen_reg_rtx (XFmode);
15117 temp = standard_80387_constant_rtx (4); /* fldln2 */
15118 emit_move_insn (operands[2], temp);
15119 })
15120
15121 (define_expand "logdf2"
15122 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15123 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15124 (match_dup 2)] UNSPEC_FYL2X))
15125 (clobber (match_scratch:DF 3 ""))])]
15126 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15127 && flag_unsafe_math_optimizations"
15128 {
15129 rtx temp;
15130
15131 operands[2] = gen_reg_rtx (XFmode);
15132 temp = standard_80387_constant_rtx (4); /* fldln2 */
15133 emit_move_insn (operands[2], temp);
15134 })
15135
15136 (define_expand "logxf2"
15137 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15138 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15139 (match_dup 2)] UNSPEC_FYL2X))
15140 (clobber (match_scratch:XF 3 ""))])]
15141 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15142 && flag_unsafe_math_optimizations"
15143 {
15144 rtx temp;
15145
15146 operands[2] = gen_reg_rtx (XFmode);
15147 temp = standard_80387_constant_rtx (4); /* fldln2 */
15148 emit_move_insn (operands[2], temp);
15149 })
15150
15151 (define_expand "log10sf2"
15152 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15153 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15154 (match_dup 2)] UNSPEC_FYL2X))
15155 (clobber (match_scratch:SF 3 ""))])]
15156 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15157 && flag_unsafe_math_optimizations"
15158 {
15159 rtx temp;
15160
15161 operands[2] = gen_reg_rtx (XFmode);
15162 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15163 emit_move_insn (operands[2], temp);
15164 })
15165
15166 (define_expand "log10df2"
15167 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15168 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15169 (match_dup 2)] UNSPEC_FYL2X))
15170 (clobber (match_scratch:DF 3 ""))])]
15171 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15172 && flag_unsafe_math_optimizations"
15173 {
15174 rtx temp;
15175
15176 operands[2] = gen_reg_rtx (XFmode);
15177 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15178 emit_move_insn (operands[2], temp);
15179 })
15180
15181 (define_expand "log10xf2"
15182 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15183 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15184 (match_dup 2)] UNSPEC_FYL2X))
15185 (clobber (match_scratch:XF 3 ""))])]
15186 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15187 && flag_unsafe_math_optimizations"
15188 {
15189 rtx temp;
15190
15191 operands[2] = gen_reg_rtx (XFmode);
15192 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15193 emit_move_insn (operands[2], temp);
15194 })
15195
15196 (define_expand "log2sf2"
15197 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15198 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15199 (match_dup 2)] UNSPEC_FYL2X))
15200 (clobber (match_scratch:SF 3 ""))])]
15201 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15202 && flag_unsafe_math_optimizations"
15203 {
15204 operands[2] = gen_reg_rtx (XFmode);
15205 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15206
15207 })
15208
15209 (define_expand "log2df2"
15210 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15211 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15212 (match_dup 2)] UNSPEC_FYL2X))
15213 (clobber (match_scratch:DF 3 ""))])]
15214 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15215 && flag_unsafe_math_optimizations"
15216 {
15217 operands[2] = gen_reg_rtx (XFmode);
15218 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15219 })
15220
15221 (define_expand "log2xf2"
15222 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15223 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15224 (match_dup 2)] UNSPEC_FYL2X))
15225 (clobber (match_scratch:XF 3 ""))])]
15226 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15227 && flag_unsafe_math_optimizations"
15228 {
15229 operands[2] = gen_reg_rtx (XFmode);
15230 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15231 })
15232
15233 (define_insn "*fscale_sfxf3"
15234 [(set (match_operand:SF 0 "register_operand" "=f")
15235 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15236 (match_operand:XF 1 "register_operand" "u")]
15237 UNSPEC_FSCALE))
15238 (clobber (match_scratch:SF 3 "=1"))]
15239 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15240 && flag_unsafe_math_optimizations"
15241 "fscale\;fstp\t%y1"
15242 [(set_attr "type" "fpspc")
15243 (set_attr "mode" "SF")])
15244
15245 (define_insn "*fscale_dfxf3"
15246 [(set (match_operand:DF 0 "register_operand" "=f")
15247 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15248 (match_operand:XF 1 "register_operand" "u")]
15249 UNSPEC_FSCALE))
15250 (clobber (match_scratch:DF 3 "=1"))]
15251 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15252 && flag_unsafe_math_optimizations"
15253 "fscale\;fstp\t%y1"
15254 [(set_attr "type" "fpspc")
15255 (set_attr "mode" "DF")])
15256
15257 (define_insn "*fscale_xf3"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15260 (match_operand:XF 1 "register_operand" "u")]
15261 UNSPEC_FSCALE))
15262 (clobber (match_scratch:XF 3 "=1"))]
15263 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15264 && flag_unsafe_math_optimizations"
15265 "fscale\;fstp\t%y1"
15266 [(set_attr "type" "fpspc")
15267 (set_attr "mode" "XF")])
15268
15269 (define_insn "*frndintxf2"
15270 [(set (match_operand:XF 0 "register_operand" "=f")
15271 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15272 UNSPEC_FRNDINT))]
15273 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15274 && flag_unsafe_math_optimizations"
15275 "frndint"
15276 [(set_attr "type" "fpspc")
15277 (set_attr "mode" "XF")])
15278
15279 (define_insn "*f2xm1xf2"
15280 [(set (match_operand:XF 0 "register_operand" "=f")
15281 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15282 UNSPEC_F2XM1))]
15283 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15284 && flag_unsafe_math_optimizations"
15285 "f2xm1"
15286 [(set_attr "type" "fpspc")
15287 (set_attr "mode" "XF")])
15288
15289 (define_expand "expsf2"
15290 [(set (match_dup 2)
15291 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15292 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15293 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15294 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15295 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15296 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15297 (parallel [(set (match_operand:SF 0 "register_operand" "")
15298 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15299 (clobber (match_scratch:SF 5 ""))])]
15300 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15301 && flag_unsafe_math_optimizations"
15302 {
15303 rtx temp;
15304 int i;
15305
15306 for (i=2; i<10; i++)
15307 operands[i] = gen_reg_rtx (XFmode);
15308 temp = standard_80387_constant_rtx (5); /* fldl2e */
15309 emit_move_insn (operands[3], temp);
15310 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15311 })
15312
15313 (define_expand "expdf2"
15314 [(set (match_dup 2)
15315 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15316 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15317 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15318 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15319
15320 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15321 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15322 (parallel [(set (match_operand:DF 0 "register_operand" "")
15323 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15324 (clobber (match_scratch:DF 5 ""))])]
15325 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15326 && flag_unsafe_math_optimizations"
15327 {
15328 rtx temp;
15329 int i;
15330
15331 for (i=2; i<10; i++)
15332 operands[i] = gen_reg_rtx (XFmode);
15333 temp = standard_80387_constant_rtx (5); /* fldl2e */
15334 emit_move_insn (operands[3], temp);
15335 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15336 })
15337
15338 (define_expand "expxf2"
15339 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15340 (match_dup 2)))
15341 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15342 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15343 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15344 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15345 (parallel [(set (match_operand:XF 0 "register_operand" "")
15346 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15347 (clobber (match_scratch:XF 5 ""))])]
15348 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15349 && flag_unsafe_math_optimizations"
15350 {
15351 rtx temp;
15352 int i;
15353
15354 for (i=2; i<9; i++)
15355 operands[i] = gen_reg_rtx (XFmode);
15356 temp = standard_80387_constant_rtx (5); /* fldl2e */
15357 emit_move_insn (operands[2], temp);
15358 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15359 })
15360
15361 (define_expand "exp10sf2"
15362 [(set (match_dup 2)
15363 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15364 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15365 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15366 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15367 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15368 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15369 (parallel [(set (match_operand:SF 0 "register_operand" "")
15370 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15371 (clobber (match_scratch:SF 5 ""))])]
15372 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15373 && flag_unsafe_math_optimizations"
15374 {
15375 rtx temp;
15376 int i;
15377
15378 for (i=2; i<10; i++)
15379 operands[i] = gen_reg_rtx (XFmode);
15380 temp = standard_80387_constant_rtx (6); /* fldl2t */
15381 emit_move_insn (operands[3], temp);
15382 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15383 })
15384
15385 (define_expand "exp10df2"
15386 [(set (match_dup 2)
15387 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15388 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15389 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15390 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15391 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15392 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15393 (parallel [(set (match_operand:DF 0 "register_operand" "")
15394 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15395 (clobber (match_scratch:DF 5 ""))])]
15396 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15397 && flag_unsafe_math_optimizations"
15398 {
15399 rtx temp;
15400 int i;
15401
15402 for (i=2; i<10; i++)
15403 operands[i] = gen_reg_rtx (XFmode);
15404 temp = standard_80387_constant_rtx (6); /* fldl2t */
15405 emit_move_insn (operands[3], temp);
15406 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15407 })
15408
15409 (define_expand "exp10xf2"
15410 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15411 (match_dup 2)))
15412 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15413 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15414 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15415 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15416 (parallel [(set (match_operand:XF 0 "register_operand" "")
15417 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15418 (clobber (match_scratch:XF 5 ""))])]
15419 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15420 && flag_unsafe_math_optimizations"
15421 {
15422 rtx temp;
15423 int i;
15424
15425 for (i=2; i<9; i++)
15426 operands[i] = gen_reg_rtx (XFmode);
15427 temp = standard_80387_constant_rtx (6); /* fldl2t */
15428 emit_move_insn (operands[2], temp);
15429 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15430 })
15431
15432 (define_expand "exp2sf2"
15433 [(set (match_dup 2)
15434 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15435 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15436 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15437 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15438 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15439 (parallel [(set (match_operand:SF 0 "register_operand" "")
15440 (unspec:SF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15441 (clobber (match_scratch:SF 3 ""))])]
15442 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15443 && flag_unsafe_math_optimizations"
15444 {
15445 int i;
15446
15447 for (i=2; i<8; i++)
15448 operands[i] = gen_reg_rtx (XFmode);
15449 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15450 })
15451
15452 (define_expand "exp2df2"
15453 [(set (match_dup 2)
15454 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15455 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15456 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15457 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15458 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15459 (parallel [(set (match_operand:DF 0 "register_operand" "")
15460 (unspec:DF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15461 (clobber (match_scratch:DF 3 ""))])]
15462 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15463 && flag_unsafe_math_optimizations"
15464 {
15465 int i;
15466
15467 for (i=2; i<8; i++)
15468 operands[i] = gen_reg_rtx (XFmode);
15469 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15470 })
15471
15472 (define_expand "exp2xf2"
15473 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15474 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15475 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15476 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15477 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15478 (parallel [(set (match_operand:XF 0 "register_operand" "")
15479 (unspec:XF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15480 (clobber (match_scratch:XF 3 ""))])]
15481 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15482 && flag_unsafe_math_optimizations"
15483 {
15484 int i;
15485
15486 for (i=2; i<8; i++)
15487 operands[i] = gen_reg_rtx (XFmode);
15488 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15489 })
15490
15491 (define_expand "atansf2"
15492 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15493 (unspec:SF [(match_dup 2)
15494 (match_operand:SF 1 "register_operand" "")]
15495 UNSPEC_FPATAN))
15496 (clobber (match_scratch:SF 3 ""))])]
15497 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15498 && flag_unsafe_math_optimizations"
15499 {
15500 operands[2] = gen_reg_rtx (SFmode);
15501 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15502 })
15503
15504 (define_expand "atandf2"
15505 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15506 (unspec:DF [(match_dup 2)
15507 (match_operand:DF 1 "register_operand" "")]
15508 UNSPEC_FPATAN))
15509 (clobber (match_scratch:DF 3 ""))])]
15510 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15511 && flag_unsafe_math_optimizations"
15512 {
15513 operands[2] = gen_reg_rtx (DFmode);
15514 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15515 })
15516
15517 (define_expand "atanxf2"
15518 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15519 (unspec:XF [(match_dup 2)
15520 (match_operand:XF 1 "register_operand" "")]
15521 UNSPEC_FPATAN))
15522 (clobber (match_scratch:XF 3 ""))])]
15523 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15524 && flag_unsafe_math_optimizations"
15525 {
15526 operands[2] = gen_reg_rtx (XFmode);
15527 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15528 })
15529 \f
15530 ;; Block operation instructions
15531
15532 (define_insn "cld"
15533 [(set (reg:SI 19) (const_int 0))]
15534 ""
15535 "cld"
15536 [(set_attr "type" "cld")])
15537
15538 (define_expand "movstrsi"
15539 [(use (match_operand:BLK 0 "memory_operand" ""))
15540 (use (match_operand:BLK 1 "memory_operand" ""))
15541 (use (match_operand:SI 2 "nonmemory_operand" ""))
15542 (use (match_operand:SI 3 "const_int_operand" ""))]
15543 "! optimize_size"
15544 {
15545 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15546 DONE;
15547 else
15548 FAIL;
15549 })
15550
15551 (define_expand "movstrdi"
15552 [(use (match_operand:BLK 0 "memory_operand" ""))
15553 (use (match_operand:BLK 1 "memory_operand" ""))
15554 (use (match_operand:DI 2 "nonmemory_operand" ""))
15555 (use (match_operand:DI 3 "const_int_operand" ""))]
15556 "TARGET_64BIT"
15557 {
15558 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15559 DONE;
15560 else
15561 FAIL;
15562 })
15563
15564 ;; Most CPUs don't like single string operations
15565 ;; Handle this case here to simplify previous expander.
15566
15567 (define_expand "strmov"
15568 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15569 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15570 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15571 (clobber (reg:CC 17))])
15572 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15573 (clobber (reg:CC 17))])]
15574 ""
15575 {
15576 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15577
15578 /* If .md ever supports :P for Pmode, these can be directly
15579 in the pattern above. */
15580 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15581 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15582
15583 if (TARGET_SINGLE_STRINGOP || optimize_size)
15584 {
15585 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15586 operands[2], operands[3],
15587 operands[5], operands[6]));
15588 DONE;
15589 }
15590
15591 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15592 })
15593
15594 (define_expand "strmov_singleop"
15595 [(parallel [(set (match_operand 1 "memory_operand" "")
15596 (match_operand 3 "memory_operand" ""))
15597 (set (match_operand 0 "register_operand" "")
15598 (match_operand 4 "" ""))
15599 (set (match_operand 2 "register_operand" "")
15600 (match_operand 5 "" ""))
15601 (use (reg:SI 19))])]
15602 "TARGET_SINGLE_STRINGOP || optimize_size"
15603 "")
15604
15605 (define_insn "*strmovdi_rex_1"
15606 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15607 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15608 (set (match_operand:DI 0 "register_operand" "=D")
15609 (plus:DI (match_dup 2)
15610 (const_int 8)))
15611 (set (match_operand:DI 1 "register_operand" "=S")
15612 (plus:DI (match_dup 3)
15613 (const_int 8)))
15614 (use (reg:SI 19))]
15615 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15616 "movsq"
15617 [(set_attr "type" "str")
15618 (set_attr "mode" "DI")
15619 (set_attr "memory" "both")])
15620
15621 (define_insn "*strmovsi_1"
15622 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15623 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15624 (set (match_operand:SI 0 "register_operand" "=D")
15625 (plus:SI (match_dup 2)
15626 (const_int 4)))
15627 (set (match_operand:SI 1 "register_operand" "=S")
15628 (plus:SI (match_dup 3)
15629 (const_int 4)))
15630 (use (reg:SI 19))]
15631 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15632 "{movsl|movsd}"
15633 [(set_attr "type" "str")
15634 (set_attr "mode" "SI")
15635 (set_attr "memory" "both")])
15636
15637 (define_insn "*strmovsi_rex_1"
15638 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15639 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15640 (set (match_operand:DI 0 "register_operand" "=D")
15641 (plus:DI (match_dup 2)
15642 (const_int 4)))
15643 (set (match_operand:DI 1 "register_operand" "=S")
15644 (plus:DI (match_dup 3)
15645 (const_int 4)))
15646 (use (reg:SI 19))]
15647 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15648 "{movsl|movsd}"
15649 [(set_attr "type" "str")
15650 (set_attr "mode" "SI")
15651 (set_attr "memory" "both")])
15652
15653 (define_insn "*strmovhi_1"
15654 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15655 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15656 (set (match_operand:SI 0 "register_operand" "=D")
15657 (plus:SI (match_dup 2)
15658 (const_int 2)))
15659 (set (match_operand:SI 1 "register_operand" "=S")
15660 (plus:SI (match_dup 3)
15661 (const_int 2)))
15662 (use (reg:SI 19))]
15663 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15664 "movsw"
15665 [(set_attr "type" "str")
15666 (set_attr "memory" "both")
15667 (set_attr "mode" "HI")])
15668
15669 (define_insn "*strmovhi_rex_1"
15670 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15671 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15672 (set (match_operand:DI 0 "register_operand" "=D")
15673 (plus:DI (match_dup 2)
15674 (const_int 2)))
15675 (set (match_operand:DI 1 "register_operand" "=S")
15676 (plus:DI (match_dup 3)
15677 (const_int 2)))
15678 (use (reg:SI 19))]
15679 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15680 "movsw"
15681 [(set_attr "type" "str")
15682 (set_attr "memory" "both")
15683 (set_attr "mode" "HI")])
15684
15685 (define_insn "*strmovqi_1"
15686 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15687 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15688 (set (match_operand:SI 0 "register_operand" "=D")
15689 (plus:SI (match_dup 2)
15690 (const_int 1)))
15691 (set (match_operand:SI 1 "register_operand" "=S")
15692 (plus:SI (match_dup 3)
15693 (const_int 1)))
15694 (use (reg:SI 19))]
15695 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15696 "movsb"
15697 [(set_attr "type" "str")
15698 (set_attr "memory" "both")
15699 (set_attr "mode" "QI")])
15700
15701 (define_insn "*strmovqi_rex_1"
15702 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15703 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15704 (set (match_operand:DI 0 "register_operand" "=D")
15705 (plus:DI (match_dup 2)
15706 (const_int 1)))
15707 (set (match_operand:DI 1 "register_operand" "=S")
15708 (plus:DI (match_dup 3)
15709 (const_int 1)))
15710 (use (reg:SI 19))]
15711 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15712 "movsb"
15713 [(set_attr "type" "str")
15714 (set_attr "memory" "both")
15715 (set_attr "mode" "QI")])
15716
15717 (define_expand "rep_mov"
15718 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15719 (set (match_operand 0 "register_operand" "")
15720 (match_operand 5 "" ""))
15721 (set (match_operand 2 "register_operand" "")
15722 (match_operand 6 "" ""))
15723 (set (match_operand 1 "memory_operand" "")
15724 (match_operand 3 "memory_operand" ""))
15725 (use (match_dup 4))
15726 (use (reg:SI 19))])]
15727 ""
15728 "")
15729
15730 (define_insn "*rep_movdi_rex64"
15731 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15732 (set (match_operand:DI 0 "register_operand" "=D")
15733 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15734 (const_int 3))
15735 (match_operand:DI 3 "register_operand" "0")))
15736 (set (match_operand:DI 1 "register_operand" "=S")
15737 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15738 (match_operand:DI 4 "register_operand" "1")))
15739 (set (mem:BLK (match_dup 3))
15740 (mem:BLK (match_dup 4)))
15741 (use (match_dup 5))
15742 (use (reg:SI 19))]
15743 "TARGET_64BIT"
15744 "{rep\;movsq|rep movsq}"
15745 [(set_attr "type" "str")
15746 (set_attr "prefix_rep" "1")
15747 (set_attr "memory" "both")
15748 (set_attr "mode" "DI")])
15749
15750 (define_insn "*rep_movsi"
15751 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15752 (set (match_operand:SI 0 "register_operand" "=D")
15753 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15754 (const_int 2))
15755 (match_operand:SI 3 "register_operand" "0")))
15756 (set (match_operand:SI 1 "register_operand" "=S")
15757 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15758 (match_operand:SI 4 "register_operand" "1")))
15759 (set (mem:BLK (match_dup 3))
15760 (mem:BLK (match_dup 4)))
15761 (use (match_dup 5))
15762 (use (reg:SI 19))]
15763 "!TARGET_64BIT"
15764 "{rep\;movsl|rep movsd}"
15765 [(set_attr "type" "str")
15766 (set_attr "prefix_rep" "1")
15767 (set_attr "memory" "both")
15768 (set_attr "mode" "SI")])
15769
15770 (define_insn "*rep_movsi_rex64"
15771 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15772 (set (match_operand:DI 0 "register_operand" "=D")
15773 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15774 (const_int 2))
15775 (match_operand:DI 3 "register_operand" "0")))
15776 (set (match_operand:DI 1 "register_operand" "=S")
15777 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15778 (match_operand:DI 4 "register_operand" "1")))
15779 (set (mem:BLK (match_dup 3))
15780 (mem:BLK (match_dup 4)))
15781 (use (match_dup 5))
15782 (use (reg:SI 19))]
15783 "TARGET_64BIT"
15784 "{rep\;movsl|rep movsd}"
15785 [(set_attr "type" "str")
15786 (set_attr "prefix_rep" "1")
15787 (set_attr "memory" "both")
15788 (set_attr "mode" "SI")])
15789
15790 (define_insn "*rep_movqi"
15791 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15792 (set (match_operand:SI 0 "register_operand" "=D")
15793 (plus:SI (match_operand:SI 3 "register_operand" "0")
15794 (match_operand:SI 5 "register_operand" "2")))
15795 (set (match_operand:SI 1 "register_operand" "=S")
15796 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15797 (set (mem:BLK (match_dup 3))
15798 (mem:BLK (match_dup 4)))
15799 (use (match_dup 5))
15800 (use (reg:SI 19))]
15801 "!TARGET_64BIT"
15802 "{rep\;movsb|rep movsb}"
15803 [(set_attr "type" "str")
15804 (set_attr "prefix_rep" "1")
15805 (set_attr "memory" "both")
15806 (set_attr "mode" "SI")])
15807
15808 (define_insn "*rep_movqi_rex64"
15809 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15810 (set (match_operand:DI 0 "register_operand" "=D")
15811 (plus:DI (match_operand:DI 3 "register_operand" "0")
15812 (match_operand:DI 5 "register_operand" "2")))
15813 (set (match_operand:DI 1 "register_operand" "=S")
15814 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15815 (set (mem:BLK (match_dup 3))
15816 (mem:BLK (match_dup 4)))
15817 (use (match_dup 5))
15818 (use (reg:SI 19))]
15819 "TARGET_64BIT"
15820 "{rep\;movsb|rep movsb}"
15821 [(set_attr "type" "str")
15822 (set_attr "prefix_rep" "1")
15823 (set_attr "memory" "both")
15824 (set_attr "mode" "SI")])
15825
15826 (define_expand "clrstrsi"
15827 [(use (match_operand:BLK 0 "memory_operand" ""))
15828 (use (match_operand:SI 1 "nonmemory_operand" ""))
15829 (use (match_operand 2 "const_int_operand" ""))]
15830 ""
15831 {
15832 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15833 DONE;
15834 else
15835 FAIL;
15836 })
15837
15838 (define_expand "clrstrdi"
15839 [(use (match_operand:BLK 0 "memory_operand" ""))
15840 (use (match_operand:DI 1 "nonmemory_operand" ""))
15841 (use (match_operand 2 "const_int_operand" ""))]
15842 "TARGET_64BIT"
15843 {
15844 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15845 DONE;
15846 else
15847 FAIL;
15848 })
15849
15850 ;; Most CPUs don't like single string operations
15851 ;; Handle this case here to simplify previous expander.
15852
15853 (define_expand "strset"
15854 [(set (match_operand 1 "memory_operand" "")
15855 (match_operand 2 "register_operand" ""))
15856 (parallel [(set (match_operand 0 "register_operand" "")
15857 (match_dup 3))
15858 (clobber (reg:CC 17))])]
15859 ""
15860 {
15861 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15862 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15863
15864 /* If .md ever supports :P for Pmode, this can be directly
15865 in the pattern above. */
15866 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15867 GEN_INT (GET_MODE_SIZE (GET_MODE
15868 (operands[2]))));
15869 if (TARGET_SINGLE_STRINGOP || optimize_size)
15870 {
15871 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15872 operands[3]));
15873 DONE;
15874 }
15875 })
15876
15877 (define_expand "strset_singleop"
15878 [(parallel [(set (match_operand 1 "memory_operand" "")
15879 (match_operand 2 "register_operand" ""))
15880 (set (match_operand 0 "register_operand" "")
15881 (match_operand 3 "" ""))
15882 (use (reg:SI 19))])]
15883 "TARGET_SINGLE_STRINGOP || optimize_size"
15884 "")
15885
15886 (define_insn "*strsetdi_rex_1"
15887 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15888 (match_operand:SI 2 "register_operand" "a"))
15889 (set (match_operand:DI 0 "register_operand" "=D")
15890 (plus:DI (match_dup 1)
15891 (const_int 8)))
15892 (use (reg:SI 19))]
15893 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15894 "stosq"
15895 [(set_attr "type" "str")
15896 (set_attr "memory" "store")
15897 (set_attr "mode" "DI")])
15898
15899 (define_insn "*strsetsi_1"
15900 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15901 (match_operand:SI 2 "register_operand" "a"))
15902 (set (match_operand:SI 0 "register_operand" "=D")
15903 (plus:SI (match_dup 1)
15904 (const_int 4)))
15905 (use (reg:SI 19))]
15906 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15907 "{stosl|stosd}"
15908 [(set_attr "type" "str")
15909 (set_attr "memory" "store")
15910 (set_attr "mode" "SI")])
15911
15912 (define_insn "*strsetsi_rex_1"
15913 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15914 (match_operand:SI 2 "register_operand" "a"))
15915 (set (match_operand:DI 0 "register_operand" "=D")
15916 (plus:DI (match_dup 1)
15917 (const_int 4)))
15918 (use (reg:SI 19))]
15919 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15920 "{stosl|stosd}"
15921 [(set_attr "type" "str")
15922 (set_attr "memory" "store")
15923 (set_attr "mode" "SI")])
15924
15925 (define_insn "*strsethi_1"
15926 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15927 (match_operand:HI 2 "register_operand" "a"))
15928 (set (match_operand:SI 0 "register_operand" "=D")
15929 (plus:SI (match_dup 1)
15930 (const_int 2)))
15931 (use (reg:SI 19))]
15932 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15933 "stosw"
15934 [(set_attr "type" "str")
15935 (set_attr "memory" "store")
15936 (set_attr "mode" "HI")])
15937
15938 (define_insn "*strsethi_rex_1"
15939 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15940 (match_operand:HI 2 "register_operand" "a"))
15941 (set (match_operand:DI 0 "register_operand" "=D")
15942 (plus:DI (match_dup 1)
15943 (const_int 2)))
15944 (use (reg:SI 19))]
15945 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15946 "stosw"
15947 [(set_attr "type" "str")
15948 (set_attr "memory" "store")
15949 (set_attr "mode" "HI")])
15950
15951 (define_insn "*strsetqi_1"
15952 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15953 (match_operand:QI 2 "register_operand" "a"))
15954 (set (match_operand:SI 0 "register_operand" "=D")
15955 (plus:SI (match_dup 1)
15956 (const_int 1)))
15957 (use (reg:SI 19))]
15958 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15959 "stosb"
15960 [(set_attr "type" "str")
15961 (set_attr "memory" "store")
15962 (set_attr "mode" "QI")])
15963
15964 (define_insn "*strsetqi_rex_1"
15965 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15966 (match_operand:QI 2 "register_operand" "a"))
15967 (set (match_operand:DI 0 "register_operand" "=D")
15968 (plus:DI (match_dup 1)
15969 (const_int 1)))
15970 (use (reg:SI 19))]
15971 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15972 "stosb"
15973 [(set_attr "type" "str")
15974 (set_attr "memory" "store")
15975 (set_attr "mode" "QI")])
15976
15977 (define_expand "rep_stos"
15978 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15979 (set (match_operand 0 "register_operand" "")
15980 (match_operand 4 "" ""))
15981 (set (match_operand 2 "memory_operand" "") (const_int 0))
15982 (use (match_operand 3 "register_operand" ""))
15983 (use (match_dup 1))
15984 (use (reg:SI 19))])]
15985 ""
15986 "")
15987
15988 (define_insn "*rep_stosdi_rex64"
15989 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15990 (set (match_operand:DI 0 "register_operand" "=D")
15991 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15992 (const_int 3))
15993 (match_operand:DI 3 "register_operand" "0")))
15994 (set (mem:BLK (match_dup 3))
15995 (const_int 0))
15996 (use (match_operand:DI 2 "register_operand" "a"))
15997 (use (match_dup 4))
15998 (use (reg:SI 19))]
15999 "TARGET_64BIT"
16000 "{rep\;stosq|rep stosq}"
16001 [(set_attr "type" "str")
16002 (set_attr "prefix_rep" "1")
16003 (set_attr "memory" "store")
16004 (set_attr "mode" "DI")])
16005
16006 (define_insn "*rep_stossi"
16007 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16008 (set (match_operand:SI 0 "register_operand" "=D")
16009 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16010 (const_int 2))
16011 (match_operand:SI 3 "register_operand" "0")))
16012 (set (mem:BLK (match_dup 3))
16013 (const_int 0))
16014 (use (match_operand:SI 2 "register_operand" "a"))
16015 (use (match_dup 4))
16016 (use (reg:SI 19))]
16017 "!TARGET_64BIT"
16018 "{rep\;stosl|rep stosd}"
16019 [(set_attr "type" "str")
16020 (set_attr "prefix_rep" "1")
16021 (set_attr "memory" "store")
16022 (set_attr "mode" "SI")])
16023
16024 (define_insn "*rep_stossi_rex64"
16025 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16026 (set (match_operand:DI 0 "register_operand" "=D")
16027 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16028 (const_int 2))
16029 (match_operand:DI 3 "register_operand" "0")))
16030 (set (mem:BLK (match_dup 3))
16031 (const_int 0))
16032 (use (match_operand:SI 2 "register_operand" "a"))
16033 (use (match_dup 4))
16034 (use (reg:SI 19))]
16035 "TARGET_64BIT"
16036 "{rep\;stosl|rep stosd}"
16037 [(set_attr "type" "str")
16038 (set_attr "prefix_rep" "1")
16039 (set_attr "memory" "store")
16040 (set_attr "mode" "SI")])
16041
16042 (define_insn "*rep_stosqi"
16043 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16044 (set (match_operand:SI 0 "register_operand" "=D")
16045 (plus:SI (match_operand:SI 3 "register_operand" "0")
16046 (match_operand:SI 4 "register_operand" "1")))
16047 (set (mem:BLK (match_dup 3))
16048 (const_int 0))
16049 (use (match_operand:QI 2 "register_operand" "a"))
16050 (use (match_dup 4))
16051 (use (reg:SI 19))]
16052 "!TARGET_64BIT"
16053 "{rep\;stosb|rep stosb}"
16054 [(set_attr "type" "str")
16055 (set_attr "prefix_rep" "1")
16056 (set_attr "memory" "store")
16057 (set_attr "mode" "QI")])
16058
16059 (define_insn "*rep_stosqi_rex64"
16060 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16061 (set (match_operand:DI 0 "register_operand" "=D")
16062 (plus:DI (match_operand:DI 3 "register_operand" "0")
16063 (match_operand:DI 4 "register_operand" "1")))
16064 (set (mem:BLK (match_dup 3))
16065 (const_int 0))
16066 (use (match_operand:QI 2 "register_operand" "a"))
16067 (use (match_dup 4))
16068 (use (reg:SI 19))]
16069 "TARGET_64BIT"
16070 "{rep\;stosb|rep stosb}"
16071 [(set_attr "type" "str")
16072 (set_attr "prefix_rep" "1")
16073 (set_attr "memory" "store")
16074 (set_attr "mode" "QI")])
16075
16076 (define_expand "cmpstrsi"
16077 [(set (match_operand:SI 0 "register_operand" "")
16078 (compare:SI (match_operand:BLK 1 "general_operand" "")
16079 (match_operand:BLK 2 "general_operand" "")))
16080 (use (match_operand 3 "general_operand" ""))
16081 (use (match_operand 4 "immediate_operand" ""))]
16082 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16083 {
16084 rtx addr1, addr2, out, outlow, count, countreg, align;
16085
16086 /* Can't use this if the user has appropriated esi or edi. */
16087 if (global_regs[4] || global_regs[5])
16088 FAIL;
16089
16090 out = operands[0];
16091 if (GET_CODE (out) != REG)
16092 out = gen_reg_rtx (SImode);
16093
16094 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16095 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16096 if (addr1 != XEXP (operands[1], 0))
16097 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16098 if (addr2 != XEXP (operands[2], 0))
16099 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16100
16101 count = operands[3];
16102 countreg = ix86_zero_extend_to_Pmode (count);
16103
16104 /* %%% Iff we are testing strict equality, we can use known alignment
16105 to good advantage. This may be possible with combine, particularly
16106 once cc0 is dead. */
16107 align = operands[4];
16108
16109 emit_insn (gen_cld ());
16110 if (GET_CODE (count) == CONST_INT)
16111 {
16112 if (INTVAL (count) == 0)
16113 {
16114 emit_move_insn (operands[0], const0_rtx);
16115 DONE;
16116 }
16117 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16118 operands[1], operands[2]));
16119 }
16120 else
16121 {
16122 if (TARGET_64BIT)
16123 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16124 else
16125 emit_insn (gen_cmpsi_1 (countreg, countreg));
16126 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16127 operands[1], operands[2]));
16128 }
16129
16130 outlow = gen_lowpart (QImode, out);
16131 emit_insn (gen_cmpintqi (outlow));
16132 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16133
16134 if (operands[0] != out)
16135 emit_move_insn (operands[0], out);
16136
16137 DONE;
16138 })
16139
16140 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16141
16142 (define_expand "cmpintqi"
16143 [(set (match_dup 1)
16144 (gtu:QI (reg:CC 17) (const_int 0)))
16145 (set (match_dup 2)
16146 (ltu:QI (reg:CC 17) (const_int 0)))
16147 (parallel [(set (match_operand:QI 0 "register_operand" "")
16148 (minus:QI (match_dup 1)
16149 (match_dup 2)))
16150 (clobber (reg:CC 17))])]
16151 ""
16152 "operands[1] = gen_reg_rtx (QImode);
16153 operands[2] = gen_reg_rtx (QImode);")
16154
16155 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16156 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16157
16158 (define_expand "cmpstrqi_nz_1"
16159 [(parallel [(set (reg:CC 17)
16160 (compare:CC (match_operand 4 "memory_operand" "")
16161 (match_operand 5 "memory_operand" "")))
16162 (use (match_operand 2 "register_operand" ""))
16163 (use (match_operand:SI 3 "immediate_operand" ""))
16164 (use (reg:SI 19))
16165 (clobber (match_operand 0 "register_operand" ""))
16166 (clobber (match_operand 1 "register_operand" ""))
16167 (clobber (match_dup 2))])]
16168 ""
16169 "")
16170
16171 (define_insn "*cmpstrqi_nz_1"
16172 [(set (reg:CC 17)
16173 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16174 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16175 (use (match_operand:SI 6 "register_operand" "2"))
16176 (use (match_operand:SI 3 "immediate_operand" "i"))
16177 (use (reg:SI 19))
16178 (clobber (match_operand:SI 0 "register_operand" "=S"))
16179 (clobber (match_operand:SI 1 "register_operand" "=D"))
16180 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16181 "!TARGET_64BIT"
16182 "repz{\;| }cmpsb"
16183 [(set_attr "type" "str")
16184 (set_attr "mode" "QI")
16185 (set_attr "prefix_rep" "1")])
16186
16187 (define_insn "*cmpstrqi_nz_rex_1"
16188 [(set (reg:CC 17)
16189 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16190 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16191 (use (match_operand:DI 6 "register_operand" "2"))
16192 (use (match_operand:SI 3 "immediate_operand" "i"))
16193 (use (reg:SI 19))
16194 (clobber (match_operand:DI 0 "register_operand" "=S"))
16195 (clobber (match_operand:DI 1 "register_operand" "=D"))
16196 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16197 "TARGET_64BIT"
16198 "repz{\;| }cmpsb"
16199 [(set_attr "type" "str")
16200 (set_attr "mode" "QI")
16201 (set_attr "prefix_rep" "1")])
16202
16203 ;; The same, but the count is not known to not be zero.
16204
16205 (define_expand "cmpstrqi_1"
16206 [(parallel [(set (reg:CC 17)
16207 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16208 (const_int 0))
16209 (compare:CC (match_operand 4 "memory_operand" "")
16210 (match_operand 5 "memory_operand" ""))
16211 (const_int 0)))
16212 (use (match_operand:SI 3 "immediate_operand" ""))
16213 (use (reg:CC 17))
16214 (use (reg:SI 19))
16215 (clobber (match_operand 0 "register_operand" ""))
16216 (clobber (match_operand 1 "register_operand" ""))
16217 (clobber (match_dup 2))])]
16218 ""
16219 "")
16220
16221 (define_insn "*cmpstrqi_1"
16222 [(set (reg:CC 17)
16223 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16224 (const_int 0))
16225 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16226 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16227 (const_int 0)))
16228 (use (match_operand:SI 3 "immediate_operand" "i"))
16229 (use (reg:CC 17))
16230 (use (reg:SI 19))
16231 (clobber (match_operand:SI 0 "register_operand" "=S"))
16232 (clobber (match_operand:SI 1 "register_operand" "=D"))
16233 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16234 "!TARGET_64BIT"
16235 "repz{\;| }cmpsb"
16236 [(set_attr "type" "str")
16237 (set_attr "mode" "QI")
16238 (set_attr "prefix_rep" "1")])
16239
16240 (define_insn "*cmpstrqi_rex_1"
16241 [(set (reg:CC 17)
16242 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16243 (const_int 0))
16244 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16245 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16246 (const_int 0)))
16247 (use (match_operand:SI 3 "immediate_operand" "i"))
16248 (use (reg:CC 17))
16249 (use (reg:SI 19))
16250 (clobber (match_operand:DI 0 "register_operand" "=S"))
16251 (clobber (match_operand:DI 1 "register_operand" "=D"))
16252 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16253 "TARGET_64BIT"
16254 "repz{\;| }cmpsb"
16255 [(set_attr "type" "str")
16256 (set_attr "mode" "QI")
16257 (set_attr "prefix_rep" "1")])
16258
16259 (define_expand "strlensi"
16260 [(set (match_operand:SI 0 "register_operand" "")
16261 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16262 (match_operand:QI 2 "immediate_operand" "")
16263 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16264 ""
16265 {
16266 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16267 DONE;
16268 else
16269 FAIL;
16270 })
16271
16272 (define_expand "strlendi"
16273 [(set (match_operand:DI 0 "register_operand" "")
16274 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16275 (match_operand:QI 2 "immediate_operand" "")
16276 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16277 ""
16278 {
16279 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16280 DONE;
16281 else
16282 FAIL;
16283 })
16284
16285 (define_expand "strlenqi_1"
16286 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16287 (use (reg:SI 19))
16288 (clobber (match_operand 1 "register_operand" ""))
16289 (clobber (reg:CC 17))])]
16290 ""
16291 "")
16292
16293 (define_insn "*strlenqi_1"
16294 [(set (match_operand:SI 0 "register_operand" "=&c")
16295 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16296 (match_operand:QI 2 "register_operand" "a")
16297 (match_operand:SI 3 "immediate_operand" "i")
16298 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16299 (use (reg:SI 19))
16300 (clobber (match_operand:SI 1 "register_operand" "=D"))
16301 (clobber (reg:CC 17))]
16302 "!TARGET_64BIT"
16303 "repnz{\;| }scasb"
16304 [(set_attr "type" "str")
16305 (set_attr "mode" "QI")
16306 (set_attr "prefix_rep" "1")])
16307
16308 (define_insn "*strlenqi_rex_1"
16309 [(set (match_operand:DI 0 "register_operand" "=&c")
16310 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16311 (match_operand:QI 2 "register_operand" "a")
16312 (match_operand:DI 3 "immediate_operand" "i")
16313 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16314 (use (reg:SI 19))
16315 (clobber (match_operand:DI 1 "register_operand" "=D"))
16316 (clobber (reg:CC 17))]
16317 "TARGET_64BIT"
16318 "repnz{\;| }scasb"
16319 [(set_attr "type" "str")
16320 (set_attr "mode" "QI")
16321 (set_attr "prefix_rep" "1")])
16322
16323 ;; Peephole optimizations to clean up after cmpstr*. This should be
16324 ;; handled in combine, but it is not currently up to the task.
16325 ;; When used for their truth value, the cmpstr* expanders generate
16326 ;; code like this:
16327 ;;
16328 ;; repz cmpsb
16329 ;; seta %al
16330 ;; setb %dl
16331 ;; cmpb %al, %dl
16332 ;; jcc label
16333 ;;
16334 ;; The intermediate three instructions are unnecessary.
16335
16336 ;; This one handles cmpstr*_nz_1...
16337 (define_peephole2
16338 [(parallel[
16339 (set (reg:CC 17)
16340 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16341 (mem:BLK (match_operand 5 "register_operand" ""))))
16342 (use (match_operand 6 "register_operand" ""))
16343 (use (match_operand:SI 3 "immediate_operand" ""))
16344 (use (reg:SI 19))
16345 (clobber (match_operand 0 "register_operand" ""))
16346 (clobber (match_operand 1 "register_operand" ""))
16347 (clobber (match_operand 2 "register_operand" ""))])
16348 (set (match_operand:QI 7 "register_operand" "")
16349 (gtu:QI (reg:CC 17) (const_int 0)))
16350 (set (match_operand:QI 8 "register_operand" "")
16351 (ltu:QI (reg:CC 17) (const_int 0)))
16352 (set (reg 17)
16353 (compare (match_dup 7) (match_dup 8)))
16354 ]
16355 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16356 [(parallel[
16357 (set (reg:CC 17)
16358 (compare:CC (mem:BLK (match_dup 4))
16359 (mem:BLK (match_dup 5))))
16360 (use (match_dup 6))
16361 (use (match_dup 3))
16362 (use (reg:SI 19))
16363 (clobber (match_dup 0))
16364 (clobber (match_dup 1))
16365 (clobber (match_dup 2))])]
16366 "")
16367
16368 ;; ...and this one handles cmpstr*_1.
16369 (define_peephole2
16370 [(parallel[
16371 (set (reg:CC 17)
16372 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16373 (const_int 0))
16374 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16375 (mem:BLK (match_operand 5 "register_operand" "")))
16376 (const_int 0)))
16377 (use (match_operand:SI 3 "immediate_operand" ""))
16378 (use (reg:CC 17))
16379 (use (reg:SI 19))
16380 (clobber (match_operand 0 "register_operand" ""))
16381 (clobber (match_operand 1 "register_operand" ""))
16382 (clobber (match_operand 2 "register_operand" ""))])
16383 (set (match_operand:QI 7 "register_operand" "")
16384 (gtu:QI (reg:CC 17) (const_int 0)))
16385 (set (match_operand:QI 8 "register_operand" "")
16386 (ltu:QI (reg:CC 17) (const_int 0)))
16387 (set (reg 17)
16388 (compare (match_dup 7) (match_dup 8)))
16389 ]
16390 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16391 [(parallel[
16392 (set (reg:CC 17)
16393 (if_then_else:CC (ne (match_dup 6)
16394 (const_int 0))
16395 (compare:CC (mem:BLK (match_dup 4))
16396 (mem:BLK (match_dup 5)))
16397 (const_int 0)))
16398 (use (match_dup 3))
16399 (use (reg:CC 17))
16400 (use (reg:SI 19))
16401 (clobber (match_dup 0))
16402 (clobber (match_dup 1))
16403 (clobber (match_dup 2))])]
16404 "")
16405
16406
16407 \f
16408 ;; Conditional move instructions.
16409
16410 (define_expand "movdicc"
16411 [(set (match_operand:DI 0 "register_operand" "")
16412 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16413 (match_operand:DI 2 "general_operand" "")
16414 (match_operand:DI 3 "general_operand" "")))]
16415 "TARGET_64BIT"
16416 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16417
16418 (define_insn "x86_movdicc_0_m1_rex64"
16419 [(set (match_operand:DI 0 "register_operand" "=r")
16420 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16421 (const_int -1)
16422 (const_int 0)))
16423 (clobber (reg:CC 17))]
16424 "TARGET_64BIT"
16425 "sbb{q}\t%0, %0"
16426 ; Since we don't have the proper number of operands for an alu insn,
16427 ; fill in all the blanks.
16428 [(set_attr "type" "alu")
16429 (set_attr "pent_pair" "pu")
16430 (set_attr "memory" "none")
16431 (set_attr "imm_disp" "false")
16432 (set_attr "mode" "DI")
16433 (set_attr "length_immediate" "0")])
16434
16435 (define_insn "movdicc_c_rex64"
16436 [(set (match_operand:DI 0 "register_operand" "=r,r")
16437 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16438 [(reg 17) (const_int 0)])
16439 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16440 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16441 "TARGET_64BIT && TARGET_CMOVE
16442 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16443 "@
16444 cmov%O2%C1\t{%2, %0|%0, %2}
16445 cmov%O2%c1\t{%3, %0|%0, %3}"
16446 [(set_attr "type" "icmov")
16447 (set_attr "mode" "DI")])
16448
16449 (define_expand "movsicc"
16450 [(set (match_operand:SI 0 "register_operand" "")
16451 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16452 (match_operand:SI 2 "general_operand" "")
16453 (match_operand:SI 3 "general_operand" "")))]
16454 ""
16455 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16456
16457 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16458 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16459 ;; So just document what we're doing explicitly.
16460
16461 (define_insn "x86_movsicc_0_m1"
16462 [(set (match_operand:SI 0 "register_operand" "=r")
16463 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16464 (const_int -1)
16465 (const_int 0)))
16466 (clobber (reg:CC 17))]
16467 ""
16468 "sbb{l}\t%0, %0"
16469 ; Since we don't have the proper number of operands for an alu insn,
16470 ; fill in all the blanks.
16471 [(set_attr "type" "alu")
16472 (set_attr "pent_pair" "pu")
16473 (set_attr "memory" "none")
16474 (set_attr "imm_disp" "false")
16475 (set_attr "mode" "SI")
16476 (set_attr "length_immediate" "0")])
16477
16478 (define_insn "*movsicc_noc"
16479 [(set (match_operand:SI 0 "register_operand" "=r,r")
16480 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16481 [(reg 17) (const_int 0)])
16482 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16483 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16484 "TARGET_CMOVE
16485 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16486 "@
16487 cmov%O2%C1\t{%2, %0|%0, %2}
16488 cmov%O2%c1\t{%3, %0|%0, %3}"
16489 [(set_attr "type" "icmov")
16490 (set_attr "mode" "SI")])
16491
16492 (define_expand "movhicc"
16493 [(set (match_operand:HI 0 "register_operand" "")
16494 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16495 (match_operand:HI 2 "general_operand" "")
16496 (match_operand:HI 3 "general_operand" "")))]
16497 "TARGET_HIMODE_MATH"
16498 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16499
16500 (define_insn "*movhicc_noc"
16501 [(set (match_operand:HI 0 "register_operand" "=r,r")
16502 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16503 [(reg 17) (const_int 0)])
16504 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16505 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16506 "TARGET_CMOVE
16507 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16508 "@
16509 cmov%O2%C1\t{%2, %0|%0, %2}
16510 cmov%O2%c1\t{%3, %0|%0, %3}"
16511 [(set_attr "type" "icmov")
16512 (set_attr "mode" "HI")])
16513
16514 (define_expand "movqicc"
16515 [(set (match_operand:QI 0 "register_operand" "")
16516 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16517 (match_operand:QI 2 "general_operand" "")
16518 (match_operand:QI 3 "general_operand" "")))]
16519 "TARGET_QIMODE_MATH"
16520 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16521
16522 (define_insn_and_split "*movqicc_noc"
16523 [(set (match_operand:QI 0 "register_operand" "=r,r")
16524 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16525 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16526 (match_operand:QI 2 "register_operand" "r,0")
16527 (match_operand:QI 3 "register_operand" "0,r")))]
16528 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16529 "#"
16530 "&& reload_completed"
16531 [(set (match_dup 0)
16532 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16533 (match_dup 2)
16534 (match_dup 3)))]
16535 "operands[0] = gen_lowpart (SImode, operands[0]);
16536 operands[2] = gen_lowpart (SImode, operands[2]);
16537 operands[3] = gen_lowpart (SImode, operands[3]);"
16538 [(set_attr "type" "icmov")
16539 (set_attr "mode" "SI")])
16540
16541 (define_expand "movsfcc"
16542 [(set (match_operand:SF 0 "register_operand" "")
16543 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16544 (match_operand:SF 2 "register_operand" "")
16545 (match_operand:SF 3 "register_operand" "")))]
16546 "TARGET_CMOVE"
16547 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16548
16549 (define_insn "*movsfcc_1"
16550 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16551 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16552 [(reg 17) (const_int 0)])
16553 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16554 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16555 "TARGET_CMOVE
16556 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16557 "@
16558 fcmov%F1\t{%2, %0|%0, %2}
16559 fcmov%f1\t{%3, %0|%0, %3}
16560 cmov%O2%C1\t{%2, %0|%0, %2}
16561 cmov%O2%c1\t{%3, %0|%0, %3}"
16562 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16563 (set_attr "mode" "SF,SF,SI,SI")])
16564
16565 (define_expand "movdfcc"
16566 [(set (match_operand:DF 0 "register_operand" "")
16567 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16568 (match_operand:DF 2 "register_operand" "")
16569 (match_operand:DF 3 "register_operand" "")))]
16570 "TARGET_CMOVE"
16571 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16572
16573 (define_insn "*movdfcc_1"
16574 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16575 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16576 [(reg 17) (const_int 0)])
16577 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16578 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16579 "!TARGET_64BIT && TARGET_CMOVE
16580 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16581 "@
16582 fcmov%F1\t{%2, %0|%0, %2}
16583 fcmov%f1\t{%3, %0|%0, %3}
16584 #
16585 #"
16586 [(set_attr "type" "fcmov,fcmov,multi,multi")
16587 (set_attr "mode" "DF")])
16588
16589 (define_insn "*movdfcc_1_rex64"
16590 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16591 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16592 [(reg 17) (const_int 0)])
16593 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16594 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16595 "TARGET_64BIT && TARGET_CMOVE
16596 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16597 "@
16598 fcmov%F1\t{%2, %0|%0, %2}
16599 fcmov%f1\t{%3, %0|%0, %3}
16600 cmov%O2%C1\t{%2, %0|%0, %2}
16601 cmov%O2%c1\t{%3, %0|%0, %3}"
16602 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16603 (set_attr "mode" "DF")])
16604
16605 (define_split
16606 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16607 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16608 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16609 (match_operand:DF 2 "nonimmediate_operand" "")
16610 (match_operand:DF 3 "nonimmediate_operand" "")))]
16611 "!TARGET_64BIT && reload_completed"
16612 [(set (match_dup 2)
16613 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16614 (match_dup 5)
16615 (match_dup 7)))
16616 (set (match_dup 3)
16617 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16618 (match_dup 6)
16619 (match_dup 8)))]
16620 "split_di (operands+2, 1, operands+5, operands+6);
16621 split_di (operands+3, 1, operands+7, operands+8);
16622 split_di (operands, 1, operands+2, operands+3);")
16623
16624 (define_expand "movxfcc"
16625 [(set (match_operand:XF 0 "register_operand" "")
16626 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16627 (match_operand:XF 2 "register_operand" "")
16628 (match_operand:XF 3 "register_operand" "")))]
16629 "TARGET_CMOVE"
16630 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16631
16632 (define_insn "*movxfcc_1"
16633 [(set (match_operand:XF 0 "register_operand" "=f,f")
16634 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16635 [(reg 17) (const_int 0)])
16636 (match_operand:XF 2 "register_operand" "f,0")
16637 (match_operand:XF 3 "register_operand" "0,f")))]
16638 "TARGET_CMOVE"
16639 "@
16640 fcmov%F1\t{%2, %0|%0, %2}
16641 fcmov%f1\t{%3, %0|%0, %3}"
16642 [(set_attr "type" "fcmov")
16643 (set_attr "mode" "XF")])
16644
16645 (define_expand "minsf3"
16646 [(parallel [
16647 (set (match_operand:SF 0 "register_operand" "")
16648 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16649 (match_operand:SF 2 "nonimmediate_operand" ""))
16650 (match_dup 1)
16651 (match_dup 2)))
16652 (clobber (reg:CC 17))])]
16653 "TARGET_SSE"
16654 "")
16655
16656 (define_insn "*minsf"
16657 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16658 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16659 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16660 (match_dup 1)
16661 (match_dup 2)))
16662 (clobber (reg:CC 17))]
16663 "TARGET_SSE && TARGET_IEEE_FP"
16664 "#")
16665
16666 (define_insn "*minsf_nonieee"
16667 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16668 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16669 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16670 (match_dup 1)
16671 (match_dup 2)))
16672 (clobber (reg:CC 17))]
16673 "TARGET_SSE && !TARGET_IEEE_FP
16674 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16675 "#")
16676
16677 (define_split
16678 [(set (match_operand:SF 0 "register_operand" "")
16679 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16680 (match_operand:SF 2 "nonimmediate_operand" ""))
16681 (match_operand:SF 3 "register_operand" "")
16682 (match_operand:SF 4 "nonimmediate_operand" "")))
16683 (clobber (reg:CC 17))]
16684 "SSE_REG_P (operands[0]) && reload_completed
16685 && ((operands_match_p (operands[1], operands[3])
16686 && operands_match_p (operands[2], operands[4]))
16687 || (operands_match_p (operands[1], operands[4])
16688 && operands_match_p (operands[2], operands[3])))"
16689 [(set (match_dup 0)
16690 (if_then_else:SF (lt (match_dup 1)
16691 (match_dup 2))
16692 (match_dup 1)
16693 (match_dup 2)))])
16694
16695 ;; Conditional addition patterns
16696 (define_expand "addqicc"
16697 [(match_operand:QI 0 "register_operand" "")
16698 (match_operand 1 "comparison_operator" "")
16699 (match_operand:QI 2 "register_operand" "")
16700 (match_operand:QI 3 "const_int_operand" "")]
16701 ""
16702 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16703
16704 (define_expand "addhicc"
16705 [(match_operand:HI 0 "register_operand" "")
16706 (match_operand 1 "comparison_operator" "")
16707 (match_operand:HI 2 "register_operand" "")
16708 (match_operand:HI 3 "const_int_operand" "")]
16709 ""
16710 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16711
16712 (define_expand "addsicc"
16713 [(match_operand:SI 0 "register_operand" "")
16714 (match_operand 1 "comparison_operator" "")
16715 (match_operand:SI 2 "register_operand" "")
16716 (match_operand:SI 3 "const_int_operand" "")]
16717 ""
16718 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16719
16720 (define_expand "adddicc"
16721 [(match_operand:DI 0 "register_operand" "")
16722 (match_operand 1 "comparison_operator" "")
16723 (match_operand:DI 2 "register_operand" "")
16724 (match_operand:DI 3 "const_int_operand" "")]
16725 "TARGET_64BIT"
16726 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16727
16728 ;; We can't represent the LT test directly. Do this by swapping the operands.
16729
16730 (define_split
16731 [(set (match_operand:SF 0 "fp_register_operand" "")
16732 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16733 (match_operand:SF 2 "register_operand" ""))
16734 (match_operand:SF 3 "register_operand" "")
16735 (match_operand:SF 4 "register_operand" "")))
16736 (clobber (reg:CC 17))]
16737 "reload_completed
16738 && ((operands_match_p (operands[1], operands[3])
16739 && operands_match_p (operands[2], operands[4]))
16740 || (operands_match_p (operands[1], operands[4])
16741 && operands_match_p (operands[2], operands[3])))"
16742 [(set (reg:CCFP 17)
16743 (compare:CCFP (match_dup 2)
16744 (match_dup 1)))
16745 (set (match_dup 0)
16746 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16747 (match_dup 1)
16748 (match_dup 2)))])
16749
16750 (define_insn "*minsf_sse"
16751 [(set (match_operand:SF 0 "register_operand" "=x")
16752 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16753 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16754 (match_dup 1)
16755 (match_dup 2)))]
16756 "TARGET_SSE && reload_completed"
16757 "minss\t{%2, %0|%0, %2}"
16758 [(set_attr "type" "sse")
16759 (set_attr "mode" "SF")])
16760
16761 (define_expand "mindf3"
16762 [(parallel [
16763 (set (match_operand:DF 0 "register_operand" "")
16764 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16765 (match_operand:DF 2 "nonimmediate_operand" ""))
16766 (match_dup 1)
16767 (match_dup 2)))
16768 (clobber (reg:CC 17))])]
16769 "TARGET_SSE2 && TARGET_SSE_MATH"
16770 "#")
16771
16772 (define_insn "*mindf"
16773 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16774 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16775 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16776 (match_dup 1)
16777 (match_dup 2)))
16778 (clobber (reg:CC 17))]
16779 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16780 "#")
16781
16782 (define_insn "*mindf_nonieee"
16783 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16784 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16785 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16786 (match_dup 1)
16787 (match_dup 2)))
16788 (clobber (reg:CC 17))]
16789 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16790 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16791 "#")
16792
16793 (define_split
16794 [(set (match_operand:DF 0 "register_operand" "")
16795 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16796 (match_operand:DF 2 "nonimmediate_operand" ""))
16797 (match_operand:DF 3 "register_operand" "")
16798 (match_operand:DF 4 "nonimmediate_operand" "")))
16799 (clobber (reg:CC 17))]
16800 "SSE_REG_P (operands[0]) && reload_completed
16801 && ((operands_match_p (operands[1], operands[3])
16802 && operands_match_p (operands[2], operands[4]))
16803 || (operands_match_p (operands[1], operands[4])
16804 && operands_match_p (operands[2], operands[3])))"
16805 [(set (match_dup 0)
16806 (if_then_else:DF (lt (match_dup 1)
16807 (match_dup 2))
16808 (match_dup 1)
16809 (match_dup 2)))])
16810
16811 ;; We can't represent the LT test directly. Do this by swapping the operands.
16812 (define_split
16813 [(set (match_operand:DF 0 "fp_register_operand" "")
16814 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16815 (match_operand:DF 2 "register_operand" ""))
16816 (match_operand:DF 3 "register_operand" "")
16817 (match_operand:DF 4 "register_operand" "")))
16818 (clobber (reg:CC 17))]
16819 "reload_completed
16820 && ((operands_match_p (operands[1], operands[3])
16821 && operands_match_p (operands[2], operands[4]))
16822 || (operands_match_p (operands[1], operands[4])
16823 && operands_match_p (operands[2], operands[3])))"
16824 [(set (reg:CCFP 17)
16825 (compare:CCFP (match_dup 2)
16826 (match_dup 1)))
16827 (set (match_dup 0)
16828 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16829 (match_dup 1)
16830 (match_dup 2)))])
16831
16832 (define_insn "*mindf_sse"
16833 [(set (match_operand:DF 0 "register_operand" "=Y")
16834 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16835 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16836 (match_dup 1)
16837 (match_dup 2)))]
16838 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16839 "minsd\t{%2, %0|%0, %2}"
16840 [(set_attr "type" "sse")
16841 (set_attr "mode" "DF")])
16842
16843 (define_expand "maxsf3"
16844 [(parallel [
16845 (set (match_operand:SF 0 "register_operand" "")
16846 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16847 (match_operand:SF 2 "nonimmediate_operand" ""))
16848 (match_dup 1)
16849 (match_dup 2)))
16850 (clobber (reg:CC 17))])]
16851 "TARGET_SSE"
16852 "#")
16853
16854 (define_insn "*maxsf"
16855 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16856 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16857 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16858 (match_dup 1)
16859 (match_dup 2)))
16860 (clobber (reg:CC 17))]
16861 "TARGET_SSE && TARGET_IEEE_FP"
16862 "#")
16863
16864 (define_insn "*maxsf_nonieee"
16865 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16866 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16867 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16868 (match_dup 1)
16869 (match_dup 2)))
16870 (clobber (reg:CC 17))]
16871 "TARGET_SSE && !TARGET_IEEE_FP
16872 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16873 "#")
16874
16875 (define_split
16876 [(set (match_operand:SF 0 "register_operand" "")
16877 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16878 (match_operand:SF 2 "nonimmediate_operand" ""))
16879 (match_operand:SF 3 "register_operand" "")
16880 (match_operand:SF 4 "nonimmediate_operand" "")))
16881 (clobber (reg:CC 17))]
16882 "SSE_REG_P (operands[0]) && reload_completed
16883 && ((operands_match_p (operands[1], operands[3])
16884 && operands_match_p (operands[2], operands[4]))
16885 || (operands_match_p (operands[1], operands[4])
16886 && operands_match_p (operands[2], operands[3])))"
16887 [(set (match_dup 0)
16888 (if_then_else:SF (gt (match_dup 1)
16889 (match_dup 2))
16890 (match_dup 1)
16891 (match_dup 2)))])
16892
16893 (define_split
16894 [(set (match_operand:SF 0 "fp_register_operand" "")
16895 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16896 (match_operand:SF 2 "register_operand" ""))
16897 (match_operand:SF 3 "register_operand" "")
16898 (match_operand:SF 4 "register_operand" "")))
16899 (clobber (reg:CC 17))]
16900 "reload_completed
16901 && ((operands_match_p (operands[1], operands[3])
16902 && operands_match_p (operands[2], operands[4]))
16903 || (operands_match_p (operands[1], operands[4])
16904 && operands_match_p (operands[2], operands[3])))"
16905 [(set (reg:CCFP 17)
16906 (compare:CCFP (match_dup 1)
16907 (match_dup 2)))
16908 (set (match_dup 0)
16909 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16910 (match_dup 1)
16911 (match_dup 2)))])
16912
16913 (define_insn "*maxsf_sse"
16914 [(set (match_operand:SF 0 "register_operand" "=x")
16915 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16916 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16917 (match_dup 1)
16918 (match_dup 2)))]
16919 "TARGET_SSE && reload_completed"
16920 "maxss\t{%2, %0|%0, %2}"
16921 [(set_attr "type" "sse")
16922 (set_attr "mode" "SF")])
16923
16924 (define_expand "maxdf3"
16925 [(parallel [
16926 (set (match_operand:DF 0 "register_operand" "")
16927 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16928 (match_operand:DF 2 "nonimmediate_operand" ""))
16929 (match_dup 1)
16930 (match_dup 2)))
16931 (clobber (reg:CC 17))])]
16932 "TARGET_SSE2 && TARGET_SSE_MATH"
16933 "#")
16934
16935 (define_insn "*maxdf"
16936 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16937 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16938 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16939 (match_dup 1)
16940 (match_dup 2)))
16941 (clobber (reg:CC 17))]
16942 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16943 "#")
16944
16945 (define_insn "*maxdf_nonieee"
16946 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16947 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16948 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16949 (match_dup 1)
16950 (match_dup 2)))
16951 (clobber (reg:CC 17))]
16952 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16953 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16954 "#")
16955
16956 (define_split
16957 [(set (match_operand:DF 0 "register_operand" "")
16958 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16959 (match_operand:DF 2 "nonimmediate_operand" ""))
16960 (match_operand:DF 3 "register_operand" "")
16961 (match_operand:DF 4 "nonimmediate_operand" "")))
16962 (clobber (reg:CC 17))]
16963 "SSE_REG_P (operands[0]) && reload_completed
16964 && ((operands_match_p (operands[1], operands[3])
16965 && operands_match_p (operands[2], operands[4]))
16966 || (operands_match_p (operands[1], operands[4])
16967 && operands_match_p (operands[2], operands[3])))"
16968 [(set (match_dup 0)
16969 (if_then_else:DF (gt (match_dup 1)
16970 (match_dup 2))
16971 (match_dup 1)
16972 (match_dup 2)))])
16973
16974 (define_split
16975 [(set (match_operand:DF 0 "fp_register_operand" "")
16976 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16977 (match_operand:DF 2 "register_operand" ""))
16978 (match_operand:DF 3 "register_operand" "")
16979 (match_operand:DF 4 "register_operand" "")))
16980 (clobber (reg:CC 17))]
16981 "reload_completed
16982 && ((operands_match_p (operands[1], operands[3])
16983 && operands_match_p (operands[2], operands[4]))
16984 || (operands_match_p (operands[1], operands[4])
16985 && operands_match_p (operands[2], operands[3])))"
16986 [(set (reg:CCFP 17)
16987 (compare:CCFP (match_dup 1)
16988 (match_dup 2)))
16989 (set (match_dup 0)
16990 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16991 (match_dup 1)
16992 (match_dup 2)))])
16993
16994 (define_insn "*maxdf_sse"
16995 [(set (match_operand:DF 0 "register_operand" "=Y")
16996 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16997 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16998 (match_dup 1)
16999 (match_dup 2)))]
17000 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17001 "maxsd\t{%2, %0|%0, %2}"
17002 [(set_attr "type" "sse")
17003 (set_attr "mode" "DF")])
17004 \f
17005 ;; Misc patterns (?)
17006
17007 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17008 ;; Otherwise there will be nothing to keep
17009 ;;
17010 ;; [(set (reg ebp) (reg esp))]
17011 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17012 ;; (clobber (eflags)]
17013 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17014 ;;
17015 ;; in proper program order.
17016 (define_insn "pro_epilogue_adjust_stack_1"
17017 [(set (match_operand:SI 0 "register_operand" "=r,r")
17018 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17019 (match_operand:SI 2 "immediate_operand" "i,i")))
17020 (clobber (reg:CC 17))
17021 (clobber (mem:BLK (scratch)))]
17022 "!TARGET_64BIT"
17023 {
17024 switch (get_attr_type (insn))
17025 {
17026 case TYPE_IMOV:
17027 return "mov{l}\t{%1, %0|%0, %1}";
17028
17029 case TYPE_ALU:
17030 if (GET_CODE (operands[2]) == CONST_INT
17031 && (INTVAL (operands[2]) == 128
17032 || (INTVAL (operands[2]) < 0
17033 && INTVAL (operands[2]) != -128)))
17034 {
17035 operands[2] = GEN_INT (-INTVAL (operands[2]));
17036 return "sub{l}\t{%2, %0|%0, %2}";
17037 }
17038 return "add{l}\t{%2, %0|%0, %2}";
17039
17040 case TYPE_LEA:
17041 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17042 return "lea{l}\t{%a2, %0|%0, %a2}";
17043
17044 default:
17045 abort ();
17046 }
17047 }
17048 [(set (attr "type")
17049 (cond [(eq_attr "alternative" "0")
17050 (const_string "alu")
17051 (match_operand:SI 2 "const0_operand" "")
17052 (const_string "imov")
17053 ]
17054 (const_string "lea")))
17055 (set_attr "mode" "SI")])
17056
17057 (define_insn "pro_epilogue_adjust_stack_rex64"
17058 [(set (match_operand:DI 0 "register_operand" "=r,r")
17059 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17060 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17061 (clobber (reg:CC 17))
17062 (clobber (mem:BLK (scratch)))]
17063 "TARGET_64BIT"
17064 {
17065 switch (get_attr_type (insn))
17066 {
17067 case TYPE_IMOV:
17068 return "mov{q}\t{%1, %0|%0, %1}";
17069
17070 case TYPE_ALU:
17071 if (GET_CODE (operands[2]) == CONST_INT
17072 /* Avoid overflows. */
17073 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17074 && (INTVAL (operands[2]) == 128
17075 || (INTVAL (operands[2]) < 0
17076 && INTVAL (operands[2]) != -128)))
17077 {
17078 operands[2] = GEN_INT (-INTVAL (operands[2]));
17079 return "sub{q}\t{%2, %0|%0, %2}";
17080 }
17081 return "add{q}\t{%2, %0|%0, %2}";
17082
17083 case TYPE_LEA:
17084 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17085 return "lea{q}\t{%a2, %0|%0, %a2}";
17086
17087 default:
17088 abort ();
17089 }
17090 }
17091 [(set (attr "type")
17092 (cond [(eq_attr "alternative" "0")
17093 (const_string "alu")
17094 (match_operand:DI 2 "const0_operand" "")
17095 (const_string "imov")
17096 ]
17097 (const_string "lea")))
17098 (set_attr "mode" "DI")])
17099
17100 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17101 [(set (match_operand:DI 0 "register_operand" "=r,r")
17102 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17103 (match_operand:DI 3 "immediate_operand" "i,i")))
17104 (use (match_operand:DI 2 "register_operand" "r,r"))
17105 (clobber (reg:CC 17))
17106 (clobber (mem:BLK (scratch)))]
17107 "TARGET_64BIT"
17108 {
17109 switch (get_attr_type (insn))
17110 {
17111 case TYPE_ALU:
17112 return "add{q}\t{%2, %0|%0, %2}";
17113
17114 case TYPE_LEA:
17115 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17116 return "lea{q}\t{%a2, %0|%0, %a2}";
17117
17118 default:
17119 abort ();
17120 }
17121 }
17122 [(set_attr "type" "alu,lea")
17123 (set_attr "mode" "DI")])
17124
17125 ;; Placeholder for the conditional moves. This one is split either to SSE
17126 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17127 ;; fact is that compares supported by the cmp??ss instructions are exactly
17128 ;; swapped of those supported by cmove sequence.
17129 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17130 ;; supported by i387 comparisons and we do need to emit two conditional moves
17131 ;; in tandem.
17132
17133 (define_insn "sse_movsfcc"
17134 [(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")
17135 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17136 [(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")
17137 (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")])
17138 (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")
17139 (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")))
17140 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17141 (clobber (reg:CC 17))]
17142 "TARGET_SSE
17143 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17144 /* Avoid combine from being smart and converting min/max
17145 instruction patterns into conditional moves. */
17146 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17147 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17148 || !rtx_equal_p (operands[4], operands[2])
17149 || !rtx_equal_p (operands[5], operands[3]))
17150 && (!TARGET_IEEE_FP
17151 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17152 "#")
17153
17154 (define_insn "sse_movsfcc_eq"
17155 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17156 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17157 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17158 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17159 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17160 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17161 (clobber (reg:CC 17))]
17162 "TARGET_SSE
17163 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17164 "#")
17165
17166 (define_insn "sse_movdfcc"
17167 [(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")
17168 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17169 [(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")
17170 (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")])
17171 (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")
17172 (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")))
17173 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17174 (clobber (reg:CC 17))]
17175 "TARGET_SSE2
17176 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17177 /* Avoid combine from being smart and converting min/max
17178 instruction patterns into conditional moves. */
17179 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17180 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17181 || !rtx_equal_p (operands[4], operands[2])
17182 || !rtx_equal_p (operands[5], operands[3]))
17183 && (!TARGET_IEEE_FP
17184 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17185 "#")
17186
17187 (define_insn "sse_movdfcc_eq"
17188 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17189 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17190 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17191 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17192 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17193 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17194 (clobber (reg:CC 17))]
17195 "TARGET_SSE
17196 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17197 "#")
17198
17199 ;; For non-sse moves just expand the usual cmove sequence.
17200 (define_split
17201 [(set (match_operand 0 "register_operand" "")
17202 (if_then_else (match_operator 1 "comparison_operator"
17203 [(match_operand 4 "nonimmediate_operand" "")
17204 (match_operand 5 "register_operand" "")])
17205 (match_operand 2 "nonimmediate_operand" "")
17206 (match_operand 3 "nonimmediate_operand" "")))
17207 (clobber (match_operand 6 "" ""))
17208 (clobber (reg:CC 17))]
17209 "!SSE_REG_P (operands[0]) && reload_completed
17210 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17211 [(const_int 0)]
17212 {
17213 ix86_compare_op0 = operands[5];
17214 ix86_compare_op1 = operands[4];
17215 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17216 VOIDmode, operands[5], operands[4]);
17217 ix86_expand_fp_movcc (operands);
17218 DONE;
17219 })
17220
17221 ;; Split SSE based conditional move into sequence:
17222 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17223 ;; and op2, op0 - zero op2 if comparison was false
17224 ;; nand op0, op3 - load op3 to op0 if comparison was false
17225 ;; or op2, op0 - get the nonzero one into the result.
17226 (define_split
17227 [(set (match_operand:SF 0 "register_operand" "")
17228 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
17229 [(match_operand:SF 4 "register_operand" "")
17230 (match_operand:SF 5 "nonimmediate_operand" "")])
17231 (match_operand:SF 2 "register_operand" "")
17232 (match_operand:SF 3 "register_operand" "")))
17233 (clobber (match_operand 6 "" ""))
17234 (clobber (reg:CC 17))]
17235 "SSE_REG_P (operands[0]) && reload_completed"
17236 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17237 (set (match_dup 2) (and:V4SF (match_dup 2)
17238 (match_dup 8)))
17239 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17240 (match_dup 3)))
17241 (set (match_dup 0) (ior:V4SF (match_dup 6)
17242 (match_dup 7)))]
17243 {
17244 /* If op2 == op3, op3 would be clobbered before it is used. */
17245 if (operands_match_p (operands[2], operands[3]))
17246 {
17247 emit_move_insn (operands[0], operands[2]);
17248 DONE;
17249 }
17250
17251 PUT_MODE (operands[1], GET_MODE (operands[0]));
17252 if (operands_match_p (operands[0], operands[4]))
17253 operands[6] = operands[4], operands[7] = operands[2];
17254 else
17255 operands[6] = operands[2], operands[7] = operands[4];
17256 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17257 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17258 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17259 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17260 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17261 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17262 })
17263
17264 (define_split
17265 [(set (match_operand:DF 0 "register_operand" "")
17266 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
17267 [(match_operand:DF 4 "register_operand" "")
17268 (match_operand:DF 5 "nonimmediate_operand" "")])
17269 (match_operand:DF 2 "register_operand" "")
17270 (match_operand:DF 3 "register_operand" "")))
17271 (clobber (match_operand 6 "" ""))
17272 (clobber (reg:CC 17))]
17273 "SSE_REG_P (operands[0]) && reload_completed"
17274 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17275 (set (match_dup 2) (and:V2DF (match_dup 2)
17276 (match_dup 8)))
17277 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17278 (match_dup 3)))
17279 (set (match_dup 0) (ior:V2DF (match_dup 6)
17280 (match_dup 7)))]
17281 {
17282 if (GET_MODE (operands[2]) == DFmode
17283 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17284 {
17285 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17286 emit_insn (gen_sse2_unpcklpd (op, op, op));
17287 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17288 emit_insn (gen_sse2_unpcklpd (op, op, op));
17289 }
17290
17291 /* If op2 == op3, op3 would be clobbered before it is used. */
17292 if (operands_match_p (operands[2], operands[3]))
17293 {
17294 emit_move_insn (operands[0], operands[2]);
17295 DONE;
17296 }
17297
17298 PUT_MODE (operands[1], GET_MODE (operands[0]));
17299 if (operands_match_p (operands[0], operands[4]))
17300 operands[6] = operands[4], operands[7] = operands[2];
17301 else
17302 operands[6] = operands[2], operands[7] = operands[4];
17303 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17304 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17305 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17306 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17307 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17308 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17309 })
17310
17311 ;; Special case of conditional move we can handle effectively.
17312 ;; Do not brother with the integer/floating point case, since these are
17313 ;; bot considerably slower, unlike in the generic case.
17314 (define_insn "*sse_movsfcc_const0_1"
17315 [(set (match_operand:SF 0 "register_operand" "=&x")
17316 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17317 [(match_operand:SF 4 "register_operand" "0")
17318 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17319 (match_operand:SF 2 "register_operand" "x")
17320 (match_operand:SF 3 "const0_operand" "X")))]
17321 "TARGET_SSE"
17322 "#")
17323
17324 (define_insn "*sse_movsfcc_const0_2"
17325 [(set (match_operand:SF 0 "register_operand" "=&x")
17326 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17327 [(match_operand:SF 4 "register_operand" "0")
17328 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17329 (match_operand:SF 2 "const0_operand" "X")
17330 (match_operand:SF 3 "register_operand" "x")))]
17331 "TARGET_SSE"
17332 "#")
17333
17334 (define_insn "*sse_movsfcc_const0_3"
17335 [(set (match_operand:SF 0 "register_operand" "=&x")
17336 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17337 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17338 (match_operand:SF 5 "register_operand" "0")])
17339 (match_operand:SF 2 "register_operand" "x")
17340 (match_operand:SF 3 "const0_operand" "X")))]
17341 "TARGET_SSE"
17342 "#")
17343
17344 (define_insn "*sse_movsfcc_const0_4"
17345 [(set (match_operand:SF 0 "register_operand" "=&x")
17346 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17347 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17348 (match_operand:SF 5 "register_operand" "0")])
17349 (match_operand:SF 2 "const0_operand" "X")
17350 (match_operand:SF 3 "register_operand" "x")))]
17351 "TARGET_SSE"
17352 "#")
17353
17354 (define_insn "*sse_movdfcc_const0_1"
17355 [(set (match_operand:DF 0 "register_operand" "=&Y")
17356 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17357 [(match_operand:DF 4 "register_operand" "0")
17358 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17359 (match_operand:DF 2 "register_operand" "Y")
17360 (match_operand:DF 3 "const0_operand" "X")))]
17361 "TARGET_SSE2"
17362 "#")
17363
17364 (define_insn "*sse_movdfcc_const0_2"
17365 [(set (match_operand:DF 0 "register_operand" "=&Y")
17366 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17367 [(match_operand:DF 4 "register_operand" "0")
17368 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17369 (match_operand:DF 2 "const0_operand" "X")
17370 (match_operand:DF 3 "register_operand" "Y")))]
17371 "TARGET_SSE2"
17372 "#")
17373
17374 (define_insn "*sse_movdfcc_const0_3"
17375 [(set (match_operand:DF 0 "register_operand" "=&Y")
17376 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17377 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17378 (match_operand:DF 5 "register_operand" "0")])
17379 (match_operand:DF 2 "register_operand" "Y")
17380 (match_operand:DF 3 "const0_operand" "X")))]
17381 "TARGET_SSE2"
17382 "#")
17383
17384 (define_insn "*sse_movdfcc_const0_4"
17385 [(set (match_operand:DF 0 "register_operand" "=&Y")
17386 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17387 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17388 (match_operand:DF 5 "register_operand" "0")])
17389 (match_operand:DF 2 "const0_operand" "X")
17390 (match_operand:DF 3 "register_operand" "Y")))]
17391 "TARGET_SSE2"
17392 "#")
17393
17394 (define_split
17395 [(set (match_operand:SF 0 "register_operand" "")
17396 (if_then_else (match_operator:SF 1 "comparison_operator"
17397 [(match_operand:SF 4 "nonimmediate_operand" "")
17398 (match_operand:SF 5 "nonimmediate_operand" "")])
17399 (match_operand:SF 2 "nonmemory_operand" "")
17400 (match_operand:SF 3 "nonmemory_operand" "")))]
17401 "SSE_REG_P (operands[0]) && reload_completed
17402 && (const0_operand (operands[2], GET_MODE (operands[0]))
17403 || const0_operand (operands[3], GET_MODE (operands[0])))"
17404 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17405 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17406 {
17407 PUT_MODE (operands[1], GET_MODE (operands[0]));
17408 if (!sse_comparison_operator (operands[1], VOIDmode)
17409 || !rtx_equal_p (operands[0], operands[4]))
17410 {
17411 rtx tmp = operands[5];
17412 operands[5] = operands[4];
17413 operands[4] = tmp;
17414 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17415 }
17416 if (!rtx_equal_p (operands[0], operands[4]))
17417 abort ();
17418 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17419 if (const0_operand (operands[2], GET_MODE (operands[2])))
17420 {
17421 operands[7] = operands[3];
17422 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17423 }
17424 else
17425 {
17426 operands[7] = operands[2];
17427 operands[6] = operands[0];
17428 }
17429 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17430 })
17431
17432 (define_split
17433 [(set (match_operand:DF 0 "register_operand" "")
17434 (if_then_else (match_operator:DF 1 "comparison_operator"
17435 [(match_operand:DF 4 "nonimmediate_operand" "")
17436 (match_operand:DF 5 "nonimmediate_operand" "")])
17437 (match_operand:DF 2 "nonmemory_operand" "")
17438 (match_operand:DF 3 "nonmemory_operand" "")))]
17439 "SSE_REG_P (operands[0]) && reload_completed
17440 && (const0_operand (operands[2], GET_MODE (operands[0]))
17441 || const0_operand (operands[3], GET_MODE (operands[0])))"
17442 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17443 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17444 {
17445 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17446 && GET_MODE (operands[2]) == DFmode)
17447 {
17448 if (REG_P (operands[2]))
17449 {
17450 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17451 emit_insn (gen_sse2_unpcklpd (op, op, op));
17452 }
17453 if (REG_P (operands[3]))
17454 {
17455 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17456 emit_insn (gen_sse2_unpcklpd (op, op, op));
17457 }
17458 }
17459 PUT_MODE (operands[1], GET_MODE (operands[0]));
17460 if (!sse_comparison_operator (operands[1], VOIDmode)
17461 || !rtx_equal_p (operands[0], operands[4]))
17462 {
17463 rtx tmp = operands[5];
17464 operands[5] = operands[4];
17465 operands[4] = tmp;
17466 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17467 }
17468 if (!rtx_equal_p (operands[0], operands[4]))
17469 abort ();
17470 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17471 if (const0_operand (operands[2], GET_MODE (operands[2])))
17472 {
17473 operands[7] = operands[3];
17474 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
17475 }
17476 else
17477 {
17478 operands[7] = operands[2];
17479 operands[6] = operands[8];
17480 }
17481 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17482 })
17483
17484 (define_expand "allocate_stack_worker"
17485 [(match_operand:SI 0 "register_operand" "")]
17486 "TARGET_STACK_PROBE"
17487 {
17488 if (reload_completed)
17489 {
17490 if (TARGET_64BIT)
17491 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17492 else
17493 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17494 }
17495 else
17496 {
17497 if (TARGET_64BIT)
17498 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17499 else
17500 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17501 }
17502 DONE;
17503 })
17504
17505 (define_insn "allocate_stack_worker_1"
17506 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17507 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17508 (clobber (match_scratch:SI 1 "=0"))
17509 (clobber (reg:CC 17))]
17510 "!TARGET_64BIT && TARGET_STACK_PROBE"
17511 "call\t__alloca"
17512 [(set_attr "type" "multi")
17513 (set_attr "length" "5")])
17514
17515 (define_expand "allocate_stack_worker_postreload"
17516 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17517 UNSPEC_STACK_PROBE)
17518 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17519 (clobber (match_dup 0))
17520 (clobber (reg:CC 17))])]
17521 ""
17522 "")
17523
17524 (define_insn "allocate_stack_worker_rex64"
17525 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17526 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17527 (clobber (match_scratch:DI 1 "=0"))
17528 (clobber (reg:CC 17))]
17529 "TARGET_64BIT && TARGET_STACK_PROBE"
17530 "call\t__alloca"
17531 [(set_attr "type" "multi")
17532 (set_attr "length" "5")])
17533
17534 (define_expand "allocate_stack_worker_rex64_postreload"
17535 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17536 UNSPEC_STACK_PROBE)
17537 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17538 (clobber (match_dup 0))
17539 (clobber (reg:CC 17))])]
17540 ""
17541 "")
17542
17543 (define_expand "allocate_stack"
17544 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17545 (minus:SI (reg:SI 7)
17546 (match_operand:SI 1 "general_operand" "")))
17547 (clobber (reg:CC 17))])
17548 (parallel [(set (reg:SI 7)
17549 (minus:SI (reg:SI 7) (match_dup 1)))
17550 (clobber (reg:CC 17))])]
17551 "TARGET_STACK_PROBE"
17552 {
17553 #ifdef CHECK_STACK_LIMIT
17554 if (GET_CODE (operands[1]) == CONST_INT
17555 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17556 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17557 operands[1]));
17558 else
17559 #endif
17560 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17561 operands[1])));
17562
17563 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17564 DONE;
17565 })
17566
17567 (define_expand "builtin_setjmp_receiver"
17568 [(label_ref (match_operand 0 "" ""))]
17569 "!TARGET_64BIT && flag_pic"
17570 {
17571 emit_insn (gen_set_got (pic_offset_table_rtx));
17572 DONE;
17573 })
17574 \f
17575 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17576
17577 (define_split
17578 [(set (match_operand 0 "register_operand" "")
17579 (match_operator 3 "promotable_binary_operator"
17580 [(match_operand 1 "register_operand" "")
17581 (match_operand 2 "aligned_operand" "")]))
17582 (clobber (reg:CC 17))]
17583 "! TARGET_PARTIAL_REG_STALL && reload_completed
17584 && ((GET_MODE (operands[0]) == HImode
17585 && ((!optimize_size && !TARGET_FAST_PREFIX)
17586 || GET_CODE (operands[2]) != CONST_INT
17587 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17588 || (GET_MODE (operands[0]) == QImode
17589 && (TARGET_PROMOTE_QImode || optimize_size)))"
17590 [(parallel [(set (match_dup 0)
17591 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17592 (clobber (reg:CC 17))])]
17593 "operands[0] = gen_lowpart (SImode, operands[0]);
17594 operands[1] = gen_lowpart (SImode, operands[1]);
17595 if (GET_CODE (operands[3]) != ASHIFT)
17596 operands[2] = gen_lowpart (SImode, operands[2]);
17597 PUT_MODE (operands[3], SImode);")
17598
17599 ; Promote the QImode tests, as i386 has encoding of the AND
17600 ; instruction with 32-bit sign-extended immediate and thus the
17601 ; instruction size is unchanged, except in the %eax case for
17602 ; which it is increased by one byte, hence the ! optimize_size.
17603 (define_split
17604 [(set (reg 17)
17605 (compare (and (match_operand 1 "aligned_operand" "")
17606 (match_operand 2 "const_int_operand" ""))
17607 (const_int 0)))
17608 (set (match_operand 0 "register_operand" "")
17609 (and (match_dup 1) (match_dup 2)))]
17610 "! TARGET_PARTIAL_REG_STALL && reload_completed
17611 /* Ensure that the operand will remain sign-extended immediate. */
17612 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17613 && ! optimize_size
17614 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17615 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17616 [(parallel [(set (reg:CCNO 17)
17617 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17618 (const_int 0)))
17619 (set (match_dup 0)
17620 (and:SI (match_dup 1) (match_dup 2)))])]
17621 "operands[2]
17622 = gen_int_mode (INTVAL (operands[2])
17623 & GET_MODE_MASK (GET_MODE (operands[0])),
17624 SImode);
17625 operands[0] = gen_lowpart (SImode, operands[0]);
17626 operands[1] = gen_lowpart (SImode, operands[1]);")
17627
17628 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17629 ; the TEST instruction with 32-bit sign-extended immediate and thus
17630 ; the instruction size would at least double, which is not what we
17631 ; want even with ! optimize_size.
17632 (define_split
17633 [(set (reg 17)
17634 (compare (and (match_operand:HI 0 "aligned_operand" "")
17635 (match_operand:HI 1 "const_int_operand" ""))
17636 (const_int 0)))]
17637 "! TARGET_PARTIAL_REG_STALL && reload_completed
17638 /* Ensure that the operand will remain sign-extended immediate. */
17639 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17640 && ! TARGET_FAST_PREFIX
17641 && ! optimize_size"
17642 [(set (reg:CCNO 17)
17643 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17644 (const_int 0)))]
17645 "operands[1]
17646 = gen_int_mode (INTVAL (operands[1])
17647 & GET_MODE_MASK (GET_MODE (operands[0])),
17648 SImode);
17649 operands[0] = gen_lowpart (SImode, operands[0]);")
17650
17651 (define_split
17652 [(set (match_operand 0 "register_operand" "")
17653 (neg (match_operand 1 "register_operand" "")))
17654 (clobber (reg:CC 17))]
17655 "! TARGET_PARTIAL_REG_STALL && reload_completed
17656 && (GET_MODE (operands[0]) == HImode
17657 || (GET_MODE (operands[0]) == QImode
17658 && (TARGET_PROMOTE_QImode || optimize_size)))"
17659 [(parallel [(set (match_dup 0)
17660 (neg:SI (match_dup 1)))
17661 (clobber (reg:CC 17))])]
17662 "operands[0] = gen_lowpart (SImode, operands[0]);
17663 operands[1] = gen_lowpart (SImode, operands[1]);")
17664
17665 (define_split
17666 [(set (match_operand 0 "register_operand" "")
17667 (not (match_operand 1 "register_operand" "")))]
17668 "! TARGET_PARTIAL_REG_STALL && reload_completed
17669 && (GET_MODE (operands[0]) == HImode
17670 || (GET_MODE (operands[0]) == QImode
17671 && (TARGET_PROMOTE_QImode || optimize_size)))"
17672 [(set (match_dup 0)
17673 (not:SI (match_dup 1)))]
17674 "operands[0] = gen_lowpart (SImode, operands[0]);
17675 operands[1] = gen_lowpart (SImode, operands[1]);")
17676
17677 (define_split
17678 [(set (match_operand 0 "register_operand" "")
17679 (if_then_else (match_operator 1 "comparison_operator"
17680 [(reg 17) (const_int 0)])
17681 (match_operand 2 "register_operand" "")
17682 (match_operand 3 "register_operand" "")))]
17683 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17684 && (GET_MODE (operands[0]) == HImode
17685 || (GET_MODE (operands[0]) == QImode
17686 && (TARGET_PROMOTE_QImode || optimize_size)))"
17687 [(set (match_dup 0)
17688 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17689 "operands[0] = gen_lowpart (SImode, operands[0]);
17690 operands[2] = gen_lowpart (SImode, operands[2]);
17691 operands[3] = gen_lowpart (SImode, operands[3]);")
17692
17693 \f
17694 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17695 ;; transform a complex memory operation into two memory to register operations.
17696
17697 ;; Don't push memory operands
17698 (define_peephole2
17699 [(set (match_operand:SI 0 "push_operand" "")
17700 (match_operand:SI 1 "memory_operand" ""))
17701 (match_scratch:SI 2 "r")]
17702 "! optimize_size && ! TARGET_PUSH_MEMORY"
17703 [(set (match_dup 2) (match_dup 1))
17704 (set (match_dup 0) (match_dup 2))]
17705 "")
17706
17707 (define_peephole2
17708 [(set (match_operand:DI 0 "push_operand" "")
17709 (match_operand:DI 1 "memory_operand" ""))
17710 (match_scratch:DI 2 "r")]
17711 "! optimize_size && ! TARGET_PUSH_MEMORY"
17712 [(set (match_dup 2) (match_dup 1))
17713 (set (match_dup 0) (match_dup 2))]
17714 "")
17715
17716 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17717 ;; SImode pushes.
17718 (define_peephole2
17719 [(set (match_operand:SF 0 "push_operand" "")
17720 (match_operand:SF 1 "memory_operand" ""))
17721 (match_scratch:SF 2 "r")]
17722 "! optimize_size && ! TARGET_PUSH_MEMORY"
17723 [(set (match_dup 2) (match_dup 1))
17724 (set (match_dup 0) (match_dup 2))]
17725 "")
17726
17727 (define_peephole2
17728 [(set (match_operand:HI 0 "push_operand" "")
17729 (match_operand:HI 1 "memory_operand" ""))
17730 (match_scratch:HI 2 "r")]
17731 "! optimize_size && ! TARGET_PUSH_MEMORY"
17732 [(set (match_dup 2) (match_dup 1))
17733 (set (match_dup 0) (match_dup 2))]
17734 "")
17735
17736 (define_peephole2
17737 [(set (match_operand:QI 0 "push_operand" "")
17738 (match_operand:QI 1 "memory_operand" ""))
17739 (match_scratch:QI 2 "q")]
17740 "! optimize_size && ! TARGET_PUSH_MEMORY"
17741 [(set (match_dup 2) (match_dup 1))
17742 (set (match_dup 0) (match_dup 2))]
17743 "")
17744
17745 ;; Don't move an immediate directly to memory when the instruction
17746 ;; gets too big.
17747 (define_peephole2
17748 [(match_scratch:SI 1 "r")
17749 (set (match_operand:SI 0 "memory_operand" "")
17750 (const_int 0))]
17751 "! optimize_size
17752 && ! TARGET_USE_MOV0
17753 && TARGET_SPLIT_LONG_MOVES
17754 && get_attr_length (insn) >= ix86_cost->large_insn
17755 && peep2_regno_dead_p (0, FLAGS_REG)"
17756 [(parallel [(set (match_dup 1) (const_int 0))
17757 (clobber (reg:CC 17))])
17758 (set (match_dup 0) (match_dup 1))]
17759 "")
17760
17761 (define_peephole2
17762 [(match_scratch:HI 1 "r")
17763 (set (match_operand:HI 0 "memory_operand" "")
17764 (const_int 0))]
17765 "! optimize_size
17766 && ! TARGET_USE_MOV0
17767 && TARGET_SPLIT_LONG_MOVES
17768 && get_attr_length (insn) >= ix86_cost->large_insn
17769 && peep2_regno_dead_p (0, FLAGS_REG)"
17770 [(parallel [(set (match_dup 2) (const_int 0))
17771 (clobber (reg:CC 17))])
17772 (set (match_dup 0) (match_dup 1))]
17773 "operands[2] = gen_lowpart (SImode, operands[1]);")
17774
17775 (define_peephole2
17776 [(match_scratch:QI 1 "q")
17777 (set (match_operand:QI 0 "memory_operand" "")
17778 (const_int 0))]
17779 "! optimize_size
17780 && ! TARGET_USE_MOV0
17781 && TARGET_SPLIT_LONG_MOVES
17782 && get_attr_length (insn) >= ix86_cost->large_insn
17783 && peep2_regno_dead_p (0, FLAGS_REG)"
17784 [(parallel [(set (match_dup 2) (const_int 0))
17785 (clobber (reg:CC 17))])
17786 (set (match_dup 0) (match_dup 1))]
17787 "operands[2] = gen_lowpart (SImode, operands[1]);")
17788
17789 (define_peephole2
17790 [(match_scratch:SI 2 "r")
17791 (set (match_operand:SI 0 "memory_operand" "")
17792 (match_operand:SI 1 "immediate_operand" ""))]
17793 "! optimize_size
17794 && get_attr_length (insn) >= ix86_cost->large_insn
17795 && TARGET_SPLIT_LONG_MOVES"
17796 [(set (match_dup 2) (match_dup 1))
17797 (set (match_dup 0) (match_dup 2))]
17798 "")
17799
17800 (define_peephole2
17801 [(match_scratch:HI 2 "r")
17802 (set (match_operand:HI 0 "memory_operand" "")
17803 (match_operand:HI 1 "immediate_operand" ""))]
17804 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17805 && TARGET_SPLIT_LONG_MOVES"
17806 [(set (match_dup 2) (match_dup 1))
17807 (set (match_dup 0) (match_dup 2))]
17808 "")
17809
17810 (define_peephole2
17811 [(match_scratch:QI 2 "q")
17812 (set (match_operand:QI 0 "memory_operand" "")
17813 (match_operand:QI 1 "immediate_operand" ""))]
17814 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17815 && TARGET_SPLIT_LONG_MOVES"
17816 [(set (match_dup 2) (match_dup 1))
17817 (set (match_dup 0) (match_dup 2))]
17818 "")
17819
17820 ;; Don't compare memory with zero, load and use a test instead.
17821 (define_peephole2
17822 [(set (reg 17)
17823 (compare (match_operand:SI 0 "memory_operand" "")
17824 (const_int 0)))
17825 (match_scratch:SI 3 "r")]
17826 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17827 [(set (match_dup 3) (match_dup 0))
17828 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17829 "")
17830
17831 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17832 ;; Don't split NOTs with a displacement operand, because resulting XOR
17833 ;; will not be pairable anyway.
17834 ;;
17835 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17836 ;; represented using a modRM byte. The XOR replacement is long decoded,
17837 ;; so this split helps here as well.
17838 ;;
17839 ;; Note: Can't do this as a regular split because we can't get proper
17840 ;; lifetime information then.
17841
17842 (define_peephole2
17843 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17844 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17845 "!optimize_size
17846 && peep2_regno_dead_p (0, FLAGS_REG)
17847 && ((TARGET_PENTIUM
17848 && (GET_CODE (operands[0]) != MEM
17849 || !memory_displacement_operand (operands[0], SImode)))
17850 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17851 [(parallel [(set (match_dup 0)
17852 (xor:SI (match_dup 1) (const_int -1)))
17853 (clobber (reg:CC 17))])]
17854 "")
17855
17856 (define_peephole2
17857 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17858 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17859 "!optimize_size
17860 && peep2_regno_dead_p (0, FLAGS_REG)
17861 && ((TARGET_PENTIUM
17862 && (GET_CODE (operands[0]) != MEM
17863 || !memory_displacement_operand (operands[0], HImode)))
17864 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17865 [(parallel [(set (match_dup 0)
17866 (xor:HI (match_dup 1) (const_int -1)))
17867 (clobber (reg:CC 17))])]
17868 "")
17869
17870 (define_peephole2
17871 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17872 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17873 "!optimize_size
17874 && peep2_regno_dead_p (0, FLAGS_REG)
17875 && ((TARGET_PENTIUM
17876 && (GET_CODE (operands[0]) != MEM
17877 || !memory_displacement_operand (operands[0], QImode)))
17878 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17879 [(parallel [(set (match_dup 0)
17880 (xor:QI (match_dup 1) (const_int -1)))
17881 (clobber (reg:CC 17))])]
17882 "")
17883
17884 ;; Non pairable "test imm, reg" instructions can be translated to
17885 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17886 ;; byte opcode instead of two, have a short form for byte operands),
17887 ;; so do it for other CPUs as well. Given that the value was dead,
17888 ;; this should not create any new dependencies. Pass on the sub-word
17889 ;; versions if we're concerned about partial register stalls.
17890
17891 (define_peephole2
17892 [(set (reg 17)
17893 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17894 (match_operand:SI 1 "immediate_operand" ""))
17895 (const_int 0)))]
17896 "ix86_match_ccmode (insn, CCNOmode)
17897 && (true_regnum (operands[0]) != 0
17898 || (GET_CODE (operands[1]) == CONST_INT
17899 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17900 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17901 [(parallel
17902 [(set (reg:CCNO 17)
17903 (compare:CCNO (and:SI (match_dup 0)
17904 (match_dup 1))
17905 (const_int 0)))
17906 (set (match_dup 0)
17907 (and:SI (match_dup 0) (match_dup 1)))])]
17908 "")
17909
17910 ;; We don't need to handle HImode case, because it will be promoted to SImode
17911 ;; on ! TARGET_PARTIAL_REG_STALL
17912
17913 (define_peephole2
17914 [(set (reg 17)
17915 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17916 (match_operand:QI 1 "immediate_operand" ""))
17917 (const_int 0)))]
17918 "! TARGET_PARTIAL_REG_STALL
17919 && ix86_match_ccmode (insn, CCNOmode)
17920 && true_regnum (operands[0]) != 0
17921 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17922 [(parallel
17923 [(set (reg:CCNO 17)
17924 (compare:CCNO (and:QI (match_dup 0)
17925 (match_dup 1))
17926 (const_int 0)))
17927 (set (match_dup 0)
17928 (and:QI (match_dup 0) (match_dup 1)))])]
17929 "")
17930
17931 (define_peephole2
17932 [(set (reg 17)
17933 (compare
17934 (and:SI
17935 (zero_extract:SI
17936 (match_operand 0 "ext_register_operand" "")
17937 (const_int 8)
17938 (const_int 8))
17939 (match_operand 1 "const_int_operand" ""))
17940 (const_int 0)))]
17941 "! TARGET_PARTIAL_REG_STALL
17942 && ix86_match_ccmode (insn, CCNOmode)
17943 && true_regnum (operands[0]) != 0
17944 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17945 [(parallel [(set (reg:CCNO 17)
17946 (compare:CCNO
17947 (and:SI
17948 (zero_extract:SI
17949 (match_dup 0)
17950 (const_int 8)
17951 (const_int 8))
17952 (match_dup 1))
17953 (const_int 0)))
17954 (set (zero_extract:SI (match_dup 0)
17955 (const_int 8)
17956 (const_int 8))
17957 (and:SI
17958 (zero_extract:SI
17959 (match_dup 0)
17960 (const_int 8)
17961 (const_int 8))
17962 (match_dup 1)))])]
17963 "")
17964
17965 ;; Don't do logical operations with memory inputs.
17966 (define_peephole2
17967 [(match_scratch:SI 2 "r")
17968 (parallel [(set (match_operand:SI 0 "register_operand" "")
17969 (match_operator:SI 3 "arith_or_logical_operator"
17970 [(match_dup 0)
17971 (match_operand:SI 1 "memory_operand" "")]))
17972 (clobber (reg:CC 17))])]
17973 "! optimize_size && ! TARGET_READ_MODIFY"
17974 [(set (match_dup 2) (match_dup 1))
17975 (parallel [(set (match_dup 0)
17976 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17977 (clobber (reg:CC 17))])]
17978 "")
17979
17980 (define_peephole2
17981 [(match_scratch:SI 2 "r")
17982 (parallel [(set (match_operand:SI 0 "register_operand" "")
17983 (match_operator:SI 3 "arith_or_logical_operator"
17984 [(match_operand:SI 1 "memory_operand" "")
17985 (match_dup 0)]))
17986 (clobber (reg:CC 17))])]
17987 "! optimize_size && ! TARGET_READ_MODIFY"
17988 [(set (match_dup 2) (match_dup 1))
17989 (parallel [(set (match_dup 0)
17990 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17991 (clobber (reg:CC 17))])]
17992 "")
17993
17994 ; Don't do logical operations with memory outputs
17995 ;
17996 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17997 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17998 ; the same decoder scheduling characteristics as the original.
17999
18000 (define_peephole2
18001 [(match_scratch:SI 2 "r")
18002 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18003 (match_operator:SI 3 "arith_or_logical_operator"
18004 [(match_dup 0)
18005 (match_operand:SI 1 "nonmemory_operand" "")]))
18006 (clobber (reg:CC 17))])]
18007 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18008 [(set (match_dup 2) (match_dup 0))
18009 (parallel [(set (match_dup 2)
18010 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18011 (clobber (reg:CC 17))])
18012 (set (match_dup 0) (match_dup 2))]
18013 "")
18014
18015 (define_peephole2
18016 [(match_scratch:SI 2 "r")
18017 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18018 (match_operator:SI 3 "arith_or_logical_operator"
18019 [(match_operand:SI 1 "nonmemory_operand" "")
18020 (match_dup 0)]))
18021 (clobber (reg:CC 17))])]
18022 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18023 [(set (match_dup 2) (match_dup 0))
18024 (parallel [(set (match_dup 2)
18025 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18026 (clobber (reg:CC 17))])
18027 (set (match_dup 0) (match_dup 2))]
18028 "")
18029
18030 ;; Attempt to always use XOR for zeroing registers.
18031 (define_peephole2
18032 [(set (match_operand 0 "register_operand" "")
18033 (const_int 0))]
18034 "(GET_MODE (operands[0]) == QImode
18035 || GET_MODE (operands[0]) == HImode
18036 || GET_MODE (operands[0]) == SImode
18037 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18038 && (! TARGET_USE_MOV0 || optimize_size)
18039 && peep2_regno_dead_p (0, FLAGS_REG)"
18040 [(parallel [(set (match_dup 0) (const_int 0))
18041 (clobber (reg:CC 17))])]
18042 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18043 operands[0]);")
18044
18045 (define_peephole2
18046 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18047 (const_int 0))]
18048 "(GET_MODE (operands[0]) == QImode
18049 || GET_MODE (operands[0]) == HImode)
18050 && (! TARGET_USE_MOV0 || optimize_size)
18051 && peep2_regno_dead_p (0, FLAGS_REG)"
18052 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18053 (clobber (reg:CC 17))])])
18054
18055 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18056 (define_peephole2
18057 [(set (match_operand 0 "register_operand" "")
18058 (const_int -1))]
18059 "(GET_MODE (operands[0]) == HImode
18060 || GET_MODE (operands[0]) == SImode
18061 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18062 && (optimize_size || TARGET_PENTIUM)
18063 && peep2_regno_dead_p (0, FLAGS_REG)"
18064 [(parallel [(set (match_dup 0) (const_int -1))
18065 (clobber (reg:CC 17))])]
18066 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18067 operands[0]);")
18068
18069 ;; Attempt to convert simple leas to adds. These can be created by
18070 ;; move expanders.
18071 (define_peephole2
18072 [(set (match_operand:SI 0 "register_operand" "")
18073 (plus:SI (match_dup 0)
18074 (match_operand:SI 1 "nonmemory_operand" "")))]
18075 "peep2_regno_dead_p (0, FLAGS_REG)"
18076 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18077 (clobber (reg:CC 17))])]
18078 "")
18079
18080 (define_peephole2
18081 [(set (match_operand:SI 0 "register_operand" "")
18082 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18083 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18084 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18085 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18086 (clobber (reg:CC 17))])]
18087 "operands[2] = gen_lowpart (SImode, operands[2]);")
18088
18089 (define_peephole2
18090 [(set (match_operand:DI 0 "register_operand" "")
18091 (plus:DI (match_dup 0)
18092 (match_operand:DI 1 "x86_64_general_operand" "")))]
18093 "peep2_regno_dead_p (0, FLAGS_REG)"
18094 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18095 (clobber (reg:CC 17))])]
18096 "")
18097
18098 (define_peephole2
18099 [(set (match_operand:SI 0 "register_operand" "")
18100 (mult:SI (match_dup 0)
18101 (match_operand:SI 1 "const_int_operand" "")))]
18102 "exact_log2 (INTVAL (operands[1])) >= 0
18103 && peep2_regno_dead_p (0, FLAGS_REG)"
18104 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18105 (clobber (reg:CC 17))])]
18106 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18107
18108 (define_peephole2
18109 [(set (match_operand:DI 0 "register_operand" "")
18110 (mult:DI (match_dup 0)
18111 (match_operand:DI 1 "const_int_operand" "")))]
18112 "exact_log2 (INTVAL (operands[1])) >= 0
18113 && peep2_regno_dead_p (0, FLAGS_REG)"
18114 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18115 (clobber (reg:CC 17))])]
18116 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18117
18118 (define_peephole2
18119 [(set (match_operand:SI 0 "register_operand" "")
18120 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18121 (match_operand:DI 2 "const_int_operand" "")) 0))]
18122 "exact_log2 (INTVAL (operands[2])) >= 0
18123 && REGNO (operands[0]) == REGNO (operands[1])
18124 && peep2_regno_dead_p (0, FLAGS_REG)"
18125 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18126 (clobber (reg:CC 17))])]
18127 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18128
18129 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18130 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18131 ;; many CPUs it is also faster, since special hardware to avoid esp
18132 ;; dependencies is present.
18133
18134 ;; While some of these conversions may be done using splitters, we use peepholes
18135 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18136
18137 ;; Convert prologue esp subtractions to push.
18138 ;; We need register to push. In order to keep verify_flow_info happy we have
18139 ;; two choices
18140 ;; - use scratch and clobber it in order to avoid dependencies
18141 ;; - use already live register
18142 ;; We can't use the second way right now, since there is no reliable way how to
18143 ;; verify that given register is live. First choice will also most likely in
18144 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18145 ;; call clobbered registers are dead. We may want to use base pointer as an
18146 ;; alternative when no register is available later.
18147
18148 (define_peephole2
18149 [(match_scratch:SI 0 "r")
18150 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18151 (clobber (reg:CC 17))
18152 (clobber (mem:BLK (scratch)))])]
18153 "optimize_size || !TARGET_SUB_ESP_4"
18154 [(clobber (match_dup 0))
18155 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18156 (clobber (mem:BLK (scratch)))])])
18157
18158 (define_peephole2
18159 [(match_scratch:SI 0 "r")
18160 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18161 (clobber (reg:CC 17))
18162 (clobber (mem:BLK (scratch)))])]
18163 "optimize_size || !TARGET_SUB_ESP_8"
18164 [(clobber (match_dup 0))
18165 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18166 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18167 (clobber (mem:BLK (scratch)))])])
18168
18169 ;; Convert esp subtractions to push.
18170 (define_peephole2
18171 [(match_scratch:SI 0 "r")
18172 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18173 (clobber (reg:CC 17))])]
18174 "optimize_size || !TARGET_SUB_ESP_4"
18175 [(clobber (match_dup 0))
18176 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18177
18178 (define_peephole2
18179 [(match_scratch:SI 0 "r")
18180 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18181 (clobber (reg:CC 17))])]
18182 "optimize_size || !TARGET_SUB_ESP_8"
18183 [(clobber (match_dup 0))
18184 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18185 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18186
18187 ;; Convert epilogue deallocator to pop.
18188 (define_peephole2
18189 [(match_scratch:SI 0 "r")
18190 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18191 (clobber (reg:CC 17))
18192 (clobber (mem:BLK (scratch)))])]
18193 "optimize_size || !TARGET_ADD_ESP_4"
18194 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18195 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18196 (clobber (mem:BLK (scratch)))])]
18197 "")
18198
18199 ;; Two pops case is tricky, since pop causes dependency on destination register.
18200 ;; We use two registers if available.
18201 (define_peephole2
18202 [(match_scratch:SI 0 "r")
18203 (match_scratch:SI 1 "r")
18204 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18205 (clobber (reg:CC 17))
18206 (clobber (mem:BLK (scratch)))])]
18207 "optimize_size || !TARGET_ADD_ESP_8"
18208 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18209 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18210 (clobber (mem:BLK (scratch)))])
18211 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18212 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18213 "")
18214
18215 (define_peephole2
18216 [(match_scratch:SI 0 "r")
18217 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18218 (clobber (reg:CC 17))
18219 (clobber (mem:BLK (scratch)))])]
18220 "optimize_size"
18221 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18222 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18223 (clobber (mem:BLK (scratch)))])
18224 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18225 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18226 "")
18227
18228 ;; Convert esp additions to pop.
18229 (define_peephole2
18230 [(match_scratch:SI 0 "r")
18231 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18232 (clobber (reg:CC 17))])]
18233 ""
18234 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18235 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18236 "")
18237
18238 ;; Two pops case is tricky, since pop causes dependency on destination register.
18239 ;; We use two registers if available.
18240 (define_peephole2
18241 [(match_scratch:SI 0 "r")
18242 (match_scratch:SI 1 "r")
18243 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18244 (clobber (reg:CC 17))])]
18245 ""
18246 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18247 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18248 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18249 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18250 "")
18251
18252 (define_peephole2
18253 [(match_scratch:SI 0 "r")
18254 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18255 (clobber (reg:CC 17))])]
18256 "optimize_size"
18257 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18258 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18259 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18260 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18261 "")
18262 \f
18263 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18264 ;; required and register dies.
18265 (define_peephole2
18266 [(set (reg 17)
18267 (compare (match_operand:SI 0 "register_operand" "")
18268 (match_operand:SI 1 "incdec_operand" "")))]
18269 "ix86_match_ccmode (insn, CCGCmode)
18270 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18271 [(parallel [(set (reg:CCGC 17)
18272 (compare:CCGC (match_dup 0)
18273 (match_dup 1)))
18274 (clobber (match_dup 0))])]
18275 "")
18276
18277 (define_peephole2
18278 [(set (reg 17)
18279 (compare (match_operand:HI 0 "register_operand" "")
18280 (match_operand:HI 1 "incdec_operand" "")))]
18281 "ix86_match_ccmode (insn, CCGCmode)
18282 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18283 [(parallel [(set (reg:CCGC 17)
18284 (compare:CCGC (match_dup 0)
18285 (match_dup 1)))
18286 (clobber (match_dup 0))])]
18287 "")
18288
18289 (define_peephole2
18290 [(set (reg 17)
18291 (compare (match_operand:QI 0 "register_operand" "")
18292 (match_operand:QI 1 "incdec_operand" "")))]
18293 "ix86_match_ccmode (insn, CCGCmode)
18294 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18295 [(parallel [(set (reg:CCGC 17)
18296 (compare:CCGC (match_dup 0)
18297 (match_dup 1)))
18298 (clobber (match_dup 0))])]
18299 "")
18300
18301 ;; Convert compares with 128 to shorter add -128
18302 (define_peephole2
18303 [(set (reg 17)
18304 (compare (match_operand:SI 0 "register_operand" "")
18305 (const_int 128)))]
18306 "ix86_match_ccmode (insn, CCGCmode)
18307 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18308 [(parallel [(set (reg:CCGC 17)
18309 (compare:CCGC (match_dup 0)
18310 (const_int 128)))
18311 (clobber (match_dup 0))])]
18312 "")
18313
18314 (define_peephole2
18315 [(set (reg 17)
18316 (compare (match_operand:HI 0 "register_operand" "")
18317 (const_int 128)))]
18318 "ix86_match_ccmode (insn, CCGCmode)
18319 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18320 [(parallel [(set (reg:CCGC 17)
18321 (compare:CCGC (match_dup 0)
18322 (const_int 128)))
18323 (clobber (match_dup 0))])]
18324 "")
18325 \f
18326 (define_peephole2
18327 [(match_scratch:DI 0 "r")
18328 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18329 (clobber (reg:CC 17))
18330 (clobber (mem:BLK (scratch)))])]
18331 "optimize_size || !TARGET_SUB_ESP_4"
18332 [(clobber (match_dup 0))
18333 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18334 (clobber (mem:BLK (scratch)))])])
18335
18336 (define_peephole2
18337 [(match_scratch:DI 0 "r")
18338 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18339 (clobber (reg:CC 17))
18340 (clobber (mem:BLK (scratch)))])]
18341 "optimize_size || !TARGET_SUB_ESP_8"
18342 [(clobber (match_dup 0))
18343 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18344 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18345 (clobber (mem:BLK (scratch)))])])
18346
18347 ;; Convert esp subtractions to push.
18348 (define_peephole2
18349 [(match_scratch:DI 0 "r")
18350 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18351 (clobber (reg:CC 17))])]
18352 "optimize_size || !TARGET_SUB_ESP_4"
18353 [(clobber (match_dup 0))
18354 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18355
18356 (define_peephole2
18357 [(match_scratch:DI 0 "r")
18358 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18359 (clobber (reg:CC 17))])]
18360 "optimize_size || !TARGET_SUB_ESP_8"
18361 [(clobber (match_dup 0))
18362 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18363 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18364
18365 ;; Convert epilogue deallocator to pop.
18366 (define_peephole2
18367 [(match_scratch:DI 0 "r")
18368 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18369 (clobber (reg:CC 17))
18370 (clobber (mem:BLK (scratch)))])]
18371 "optimize_size || !TARGET_ADD_ESP_4"
18372 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18373 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18374 (clobber (mem:BLK (scratch)))])]
18375 "")
18376
18377 ;; Two pops case is tricky, since pop causes dependency on destination register.
18378 ;; We use two registers if available.
18379 (define_peephole2
18380 [(match_scratch:DI 0 "r")
18381 (match_scratch:DI 1 "r")
18382 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18383 (clobber (reg:CC 17))
18384 (clobber (mem:BLK (scratch)))])]
18385 "optimize_size || !TARGET_ADD_ESP_8"
18386 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18387 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18388 (clobber (mem:BLK (scratch)))])
18389 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18390 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18391 "")
18392
18393 (define_peephole2
18394 [(match_scratch:DI 0 "r")
18395 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18396 (clobber (reg:CC 17))
18397 (clobber (mem:BLK (scratch)))])]
18398 "optimize_size"
18399 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18400 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18401 (clobber (mem:BLK (scratch)))])
18402 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18403 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18404 "")
18405
18406 ;; Convert esp additions to pop.
18407 (define_peephole2
18408 [(match_scratch:DI 0 "r")
18409 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18410 (clobber (reg:CC 17))])]
18411 ""
18412 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18413 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18414 "")
18415
18416 ;; Two pops case is tricky, since pop causes dependency on destination register.
18417 ;; We use two registers if available.
18418 (define_peephole2
18419 [(match_scratch:DI 0 "r")
18420 (match_scratch:DI 1 "r")
18421 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18422 (clobber (reg:CC 17))])]
18423 ""
18424 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18425 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18426 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18427 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18428 "")
18429
18430 (define_peephole2
18431 [(match_scratch:DI 0 "r")
18432 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18433 (clobber (reg:CC 17))])]
18434 "optimize_size"
18435 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18436 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18437 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18438 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18439 "")
18440 \f
18441 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18442 ;; imul $32bit_imm, reg, reg is direct decoded.
18443 (define_peephole2
18444 [(match_scratch:DI 3 "r")
18445 (parallel [(set (match_operand:DI 0 "register_operand" "")
18446 (mult:DI (match_operand:DI 1 "memory_operand" "")
18447 (match_operand:DI 2 "immediate_operand" "")))
18448 (clobber (reg:CC 17))])]
18449 "TARGET_K8 && !optimize_size
18450 && (GET_CODE (operands[2]) != CONST_INT
18451 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18452 [(set (match_dup 3) (match_dup 1))
18453 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18454 (clobber (reg:CC 17))])]
18455 "")
18456
18457 (define_peephole2
18458 [(match_scratch:SI 3 "r")
18459 (parallel [(set (match_operand:SI 0 "register_operand" "")
18460 (mult:SI (match_operand:SI 1 "memory_operand" "")
18461 (match_operand:SI 2 "immediate_operand" "")))
18462 (clobber (reg:CC 17))])]
18463 "TARGET_K8 && !optimize_size
18464 && (GET_CODE (operands[2]) != CONST_INT
18465 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18466 [(set (match_dup 3) (match_dup 1))
18467 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18468 (clobber (reg:CC 17))])]
18469 "")
18470
18471 (define_peephole2
18472 [(match_scratch:SI 3 "r")
18473 (parallel [(set (match_operand:DI 0 "register_operand" "")
18474 (zero_extend:DI
18475 (mult:SI (match_operand:SI 1 "memory_operand" "")
18476 (match_operand:SI 2 "immediate_operand" ""))))
18477 (clobber (reg:CC 17))])]
18478 "TARGET_K8 && !optimize_size
18479 && (GET_CODE (operands[2]) != CONST_INT
18480 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18481 [(set (match_dup 3) (match_dup 1))
18482 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18483 (clobber (reg:CC 17))])]
18484 "")
18485
18486 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18487 ;; Convert it into imul reg, reg
18488 ;; It would be better to force assembler to encode instruction using long
18489 ;; immediate, but there is apparently no way to do so.
18490 (define_peephole2
18491 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18492 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18493 (match_operand:DI 2 "const_int_operand" "")))
18494 (clobber (reg:CC 17))])
18495 (match_scratch:DI 3 "r")]
18496 "TARGET_K8 && !optimize_size
18497 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18498 [(set (match_dup 3) (match_dup 2))
18499 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18500 (clobber (reg:CC 17))])]
18501 {
18502 if (!rtx_equal_p (operands[0], operands[1]))
18503 emit_move_insn (operands[0], operands[1]);
18504 })
18505
18506 (define_peephole2
18507 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18508 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18509 (match_operand:SI 2 "const_int_operand" "")))
18510 (clobber (reg:CC 17))])
18511 (match_scratch:SI 3 "r")]
18512 "TARGET_K8 && !optimize_size
18513 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18514 [(set (match_dup 3) (match_dup 2))
18515 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18516 (clobber (reg:CC 17))])]
18517 {
18518 if (!rtx_equal_p (operands[0], operands[1]))
18519 emit_move_insn (operands[0], operands[1]);
18520 })
18521
18522 (define_peephole2
18523 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18524 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18525 (match_operand:HI 2 "immediate_operand" "")))
18526 (clobber (reg:CC 17))])
18527 (match_scratch:HI 3 "r")]
18528 "TARGET_K8 && !optimize_size"
18529 [(set (match_dup 3) (match_dup 2))
18530 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18531 (clobber (reg:CC 17))])]
18532 {
18533 if (!rtx_equal_p (operands[0], operands[1]))
18534 emit_move_insn (operands[0], operands[1]);
18535 })
18536 \f
18537 ;; Call-value patterns last so that the wildcard operand does not
18538 ;; disrupt insn-recog's switch tables.
18539
18540 (define_insn "*call_value_pop_0"
18541 [(set (match_operand 0 "" "")
18542 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18543 (match_operand:SI 2 "" "")))
18544 (set (reg:SI 7) (plus:SI (reg:SI 7)
18545 (match_operand:SI 3 "immediate_operand" "")))]
18546 "!TARGET_64BIT"
18547 {
18548 if (SIBLING_CALL_P (insn))
18549 return "jmp\t%P1";
18550 else
18551 return "call\t%P1";
18552 }
18553 [(set_attr "type" "callv")])
18554
18555 (define_insn "*call_value_pop_1"
18556 [(set (match_operand 0 "" "")
18557 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18558 (match_operand:SI 2 "" "")))
18559 (set (reg:SI 7) (plus:SI (reg:SI 7)
18560 (match_operand:SI 3 "immediate_operand" "i")))]
18561 "!TARGET_64BIT"
18562 {
18563 if (constant_call_address_operand (operands[1], QImode))
18564 {
18565 if (SIBLING_CALL_P (insn))
18566 return "jmp\t%P1";
18567 else
18568 return "call\t%P1";
18569 }
18570 if (SIBLING_CALL_P (insn))
18571 return "jmp\t%A1";
18572 else
18573 return "call\t%A1";
18574 }
18575 [(set_attr "type" "callv")])
18576
18577 (define_insn "*call_value_0"
18578 [(set (match_operand 0 "" "")
18579 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18580 (match_operand:SI 2 "" "")))]
18581 "!TARGET_64BIT"
18582 {
18583 if (SIBLING_CALL_P (insn))
18584 return "jmp\t%P1";
18585 else
18586 return "call\t%P1";
18587 }
18588 [(set_attr "type" "callv")])
18589
18590 (define_insn "*call_value_0_rex64"
18591 [(set (match_operand 0 "" "")
18592 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18593 (match_operand:DI 2 "const_int_operand" "")))]
18594 "TARGET_64BIT"
18595 {
18596 if (SIBLING_CALL_P (insn))
18597 return "jmp\t%P1";
18598 else
18599 return "call\t%P1";
18600 }
18601 [(set_attr "type" "callv")])
18602
18603 (define_insn "*call_value_1"
18604 [(set (match_operand 0 "" "")
18605 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18606 (match_operand:SI 2 "" "")))]
18607 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18608 {
18609 if (constant_call_address_operand (operands[1], QImode))
18610 return "call\t%P1";
18611 return "call\t%*%1";
18612 }
18613 [(set_attr "type" "callv")])
18614
18615 (define_insn "*sibcall_value_1"
18616 [(set (match_operand 0 "" "")
18617 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18618 (match_operand:SI 2 "" "")))]
18619 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18620 {
18621 if (constant_call_address_operand (operands[1], QImode))
18622 return "jmp\t%P1";
18623 return "jmp\t%*%1";
18624 }
18625 [(set_attr "type" "callv")])
18626
18627 (define_insn "*call_value_1_rex64"
18628 [(set (match_operand 0 "" "")
18629 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18630 (match_operand:DI 2 "" "")))]
18631 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18632 {
18633 if (constant_call_address_operand (operands[1], QImode))
18634 return "call\t%P1";
18635 return "call\t%A1";
18636 }
18637 [(set_attr "type" "callv")])
18638
18639 (define_insn "*sibcall_value_1_rex64"
18640 [(set (match_operand 0 "" "")
18641 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18642 (match_operand:DI 2 "" "")))]
18643 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18644 "jmp\t%P1"
18645 [(set_attr "type" "callv")])
18646
18647 (define_insn "*sibcall_value_1_rex64_v"
18648 [(set (match_operand 0 "" "")
18649 (call (mem:QI (reg:DI 40))
18650 (match_operand:DI 1 "" "")))]
18651 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18652 "jmp\t*%%r11"
18653 [(set_attr "type" "callv")])
18654 \f
18655 (define_insn "trap"
18656 [(trap_if (const_int 1) (const_int 5))]
18657 ""
18658 "int\t$5")
18659
18660 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18661 ;;; for the sake of bounds checking. By emitting bounds checks as
18662 ;;; conditional traps rather than as conditional jumps around
18663 ;;; unconditional traps we avoid introducing spurious basic-block
18664 ;;; boundaries and facilitate elimination of redundant checks. In
18665 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18666 ;;; interrupt 5.
18667 ;;;
18668 ;;; FIXME: Static branch prediction rules for ix86 are such that
18669 ;;; forward conditional branches predict as untaken. As implemented
18670 ;;; below, pseudo conditional traps violate that rule. We should use
18671 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18672 ;;; section loaded at the end of the text segment and branch forward
18673 ;;; there on bounds-failure, and then jump back immediately (in case
18674 ;;; the system chooses to ignore bounds violations, or to report
18675 ;;; violations and continue execution).
18676
18677 (define_expand "conditional_trap"
18678 [(trap_if (match_operator 0 "comparison_operator"
18679 [(match_dup 2) (const_int 0)])
18680 (match_operand 1 "const_int_operand" ""))]
18681 ""
18682 {
18683 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18684 ix86_expand_compare (GET_CODE (operands[0]),
18685 NULL, NULL),
18686 operands[1]));
18687 DONE;
18688 })
18689
18690 (define_insn "*conditional_trap_1"
18691 [(trap_if (match_operator 0 "comparison_operator"
18692 [(reg 17) (const_int 0)])
18693 (match_operand 1 "const_int_operand" ""))]
18694 ""
18695 {
18696 operands[2] = gen_label_rtx ();
18697 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18698 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18699 CODE_LABEL_NUMBER (operands[2]));
18700 RET;
18701 })
18702
18703 ;; Pentium III SIMD instructions.
18704
18705 ;; Moves for SSE/MMX regs.
18706
18707 (define_insn "movv4sf_internal"
18708 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18709 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18710 "TARGET_SSE"
18711 "@
18712 xorps\t%0, %0
18713 movaps\t{%1, %0|%0, %1}
18714 movaps\t{%1, %0|%0, %1}"
18715 [(set_attr "type" "ssemov")
18716 (set_attr "mode" "V4SF")])
18717
18718 (define_split
18719 [(set (match_operand:V4SF 0 "register_operand" "")
18720 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18721 "TARGET_SSE"
18722 [(set (match_dup 0)
18723 (vec_merge:V4SF
18724 (vec_duplicate:V4SF (match_dup 1))
18725 (match_dup 2)
18726 (const_int 1)))]
18727 {
18728 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18729 operands[2] = CONST0_RTX (V4SFmode);
18730 })
18731
18732 (define_insn "movv4si_internal"
18733 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18734 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18735 "TARGET_SSE"
18736 {
18737 switch (which_alternative)
18738 {
18739 case 0:
18740 if (get_attr_mode (insn) == MODE_V4SF)
18741 return "xorps\t%0, %0";
18742 else
18743 return "pxor\t%0, %0";
18744 case 1:
18745 case 2:
18746 if (get_attr_mode (insn) == MODE_V4SF)
18747 return "movaps\t{%1, %0|%0, %1}";
18748 else
18749 return "movdqa\t{%1, %0|%0, %1}";
18750 default:
18751 abort ();
18752 }
18753 }
18754 [(set_attr "type" "ssemov")
18755 (set (attr "mode")
18756 (cond [(eq_attr "alternative" "0,1")
18757 (if_then_else
18758 (ne (symbol_ref "optimize_size")
18759 (const_int 0))
18760 (const_string "V4SF")
18761 (const_string "TI"))
18762 (eq_attr "alternative" "2")
18763 (if_then_else
18764 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18765 (const_int 0))
18766 (ne (symbol_ref "optimize_size")
18767 (const_int 0)))
18768 (const_string "V4SF")
18769 (const_string "TI"))]
18770 (const_string "TI")))])
18771
18772 (define_insn "movv2di_internal"
18773 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18774 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18775 "TARGET_SSE"
18776 {
18777 switch (which_alternative)
18778 {
18779 case 0:
18780 if (get_attr_mode (insn) == MODE_V4SF)
18781 return "xorps\t%0, %0";
18782 else
18783 return "pxor\t%0, %0";
18784 case 1:
18785 case 2:
18786 if (get_attr_mode (insn) == MODE_V4SF)
18787 return "movaps\t{%1, %0|%0, %1}";
18788 else
18789 return "movdqa\t{%1, %0|%0, %1}";
18790 default:
18791 abort ();
18792 }
18793 }
18794 [(set_attr "type" "ssemov")
18795 (set (attr "mode")
18796 (cond [(eq_attr "alternative" "0,1")
18797 (if_then_else
18798 (ne (symbol_ref "optimize_size")
18799 (const_int 0))
18800 (const_string "V4SF")
18801 (const_string "TI"))
18802 (eq_attr "alternative" "2")
18803 (if_then_else
18804 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18805 (const_int 0))
18806 (ne (symbol_ref "optimize_size")
18807 (const_int 0)))
18808 (const_string "V4SF")
18809 (const_string "TI"))]
18810 (const_string "TI")))])
18811
18812 (define_split
18813 [(set (match_operand:V2DF 0 "register_operand" "")
18814 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18815 "TARGET_SSE2"
18816 [(set (match_dup 0)
18817 (vec_merge:V2DF
18818 (vec_duplicate:V2DF (match_dup 1))
18819 (match_dup 2)
18820 (const_int 1)))]
18821 {
18822 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18823 operands[2] = CONST0_RTX (V2DFmode);
18824 })
18825
18826 (define_insn "movv8qi_internal"
18827 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18828 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18829 "TARGET_MMX
18830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18831 "@
18832 pxor\t%0, %0
18833 movq\t{%1, %0|%0, %1}
18834 movq\t{%1, %0|%0, %1}"
18835 [(set_attr "type" "mmxmov")
18836 (set_attr "mode" "DI")])
18837
18838 (define_insn "movv4hi_internal"
18839 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18840 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18841 "TARGET_MMX
18842 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18843 "@
18844 pxor\t%0, %0
18845 movq\t{%1, %0|%0, %1}
18846 movq\t{%1, %0|%0, %1}"
18847 [(set_attr "type" "mmxmov")
18848 (set_attr "mode" "DI")])
18849
18850 (define_insn "movv2si_internal"
18851 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18852 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18853 "TARGET_MMX
18854 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18855 "@
18856 pxor\t%0, %0
18857 movq\t{%1, %0|%0, %1}
18858 movq\t{%1, %0|%0, %1}"
18859 [(set_attr "type" "mmxcvt")
18860 (set_attr "mode" "DI")])
18861
18862 (define_insn "movv2sf_internal"
18863 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18864 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18865 "TARGET_3DNOW
18866 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18867 "@
18868 pxor\t%0, %0
18869 movq\t{%1, %0|%0, %1}
18870 movq\t{%1, %0|%0, %1}"
18871 [(set_attr "type" "mmxcvt")
18872 (set_attr "mode" "DI")])
18873
18874 (define_expand "movti"
18875 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18876 (match_operand:TI 1 "nonimmediate_operand" ""))]
18877 "TARGET_SSE || TARGET_64BIT"
18878 {
18879 if (TARGET_64BIT)
18880 ix86_expand_move (TImode, operands);
18881 else
18882 ix86_expand_vector_move (TImode, operands);
18883 DONE;
18884 })
18885
18886 (define_expand "movtf"
18887 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18888 (match_operand:TF 1 "nonimmediate_operand" ""))]
18889 "TARGET_64BIT"
18890 {
18891 if (TARGET_64BIT)
18892 ix86_expand_move (TFmode, operands);
18893 else
18894 ix86_expand_vector_move (TFmode, operands);
18895 DONE;
18896 })
18897
18898 (define_insn "movv2df_internal"
18899 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18900 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18901 "TARGET_SSE2
18902 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18903 {
18904 switch (which_alternative)
18905 {
18906 case 0:
18907 if (get_attr_mode (insn) == MODE_V4SF)
18908 return "xorps\t%0, %0";
18909 else
18910 return "xorpd\t%0, %0";
18911 case 1:
18912 case 2:
18913 if (get_attr_mode (insn) == MODE_V4SF)
18914 return "movaps\t{%1, %0|%0, %1}";
18915 else
18916 return "movapd\t{%1, %0|%0, %1}";
18917 default:
18918 abort ();
18919 }
18920 }
18921 [(set_attr "type" "ssemov")
18922 (set (attr "mode")
18923 (cond [(eq_attr "alternative" "0,1")
18924 (if_then_else
18925 (ne (symbol_ref "optimize_size")
18926 (const_int 0))
18927 (const_string "V4SF")
18928 (const_string "V2DF"))
18929 (eq_attr "alternative" "2")
18930 (if_then_else
18931 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18932 (const_int 0))
18933 (ne (symbol_ref "optimize_size")
18934 (const_int 0)))
18935 (const_string "V4SF")
18936 (const_string "V2DF"))]
18937 (const_string "V2DF")))])
18938
18939 (define_insn "movv8hi_internal"
18940 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18941 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18942 "TARGET_SSE2
18943 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18944 {
18945 switch (which_alternative)
18946 {
18947 case 0:
18948 if (get_attr_mode (insn) == MODE_V4SF)
18949 return "xorps\t%0, %0";
18950 else
18951 return "pxor\t%0, %0";
18952 case 1:
18953 case 2:
18954 if (get_attr_mode (insn) == MODE_V4SF)
18955 return "movaps\t{%1, %0|%0, %1}";
18956 else
18957 return "movdqa\t{%1, %0|%0, %1}";
18958 default:
18959 abort ();
18960 }
18961 }
18962 [(set_attr "type" "ssemov")
18963 (set (attr "mode")
18964 (cond [(eq_attr "alternative" "0,1")
18965 (if_then_else
18966 (ne (symbol_ref "optimize_size")
18967 (const_int 0))
18968 (const_string "V4SF")
18969 (const_string "TI"))
18970 (eq_attr "alternative" "2")
18971 (if_then_else
18972 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18973 (const_int 0))
18974 (ne (symbol_ref "optimize_size")
18975 (const_int 0)))
18976 (const_string "V4SF")
18977 (const_string "TI"))]
18978 (const_string "TI")))])
18979
18980 (define_insn "movv16qi_internal"
18981 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18982 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18983 "TARGET_SSE2
18984 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18985 {
18986 switch (which_alternative)
18987 {
18988 case 0:
18989 if (get_attr_mode (insn) == MODE_V4SF)
18990 return "xorps\t%0, %0";
18991 else
18992 return "pxor\t%0, %0";
18993 case 1:
18994 case 2:
18995 if (get_attr_mode (insn) == MODE_V4SF)
18996 return "movaps\t{%1, %0|%0, %1}";
18997 else
18998 return "movdqa\t{%1, %0|%0, %1}";
18999 default:
19000 abort ();
19001 }
19002 }
19003 [(set_attr "type" "ssemov")
19004 (set (attr "mode")
19005 (cond [(eq_attr "alternative" "0,1")
19006 (if_then_else
19007 (ne (symbol_ref "optimize_size")
19008 (const_int 0))
19009 (const_string "V4SF")
19010 (const_string "TI"))
19011 (eq_attr "alternative" "2")
19012 (if_then_else
19013 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19014 (const_int 0))
19015 (ne (symbol_ref "optimize_size")
19016 (const_int 0)))
19017 (const_string "V4SF")
19018 (const_string "TI"))]
19019 (const_string "TI")))])
19020
19021 (define_expand "movv2df"
19022 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19023 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19024 "TARGET_SSE2"
19025 {
19026 ix86_expand_vector_move (V2DFmode, operands);
19027 DONE;
19028 })
19029
19030 (define_expand "movv8hi"
19031 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19032 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19033 "TARGET_SSE2"
19034 {
19035 ix86_expand_vector_move (V8HImode, operands);
19036 DONE;
19037 })
19038
19039 (define_expand "movv16qi"
19040 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19041 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19042 "TARGET_SSE2"
19043 {
19044 ix86_expand_vector_move (V16QImode, operands);
19045 DONE;
19046 })
19047
19048 (define_expand "movv4sf"
19049 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19050 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19051 "TARGET_SSE"
19052 {
19053 ix86_expand_vector_move (V4SFmode, operands);
19054 DONE;
19055 })
19056
19057 (define_expand "movv4si"
19058 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19059 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19060 "TARGET_SSE"
19061 {
19062 ix86_expand_vector_move (V4SImode, operands);
19063 DONE;
19064 })
19065
19066 (define_expand "movv2di"
19067 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19068 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19069 "TARGET_SSE"
19070 {
19071 ix86_expand_vector_move (V2DImode, operands);
19072 DONE;
19073 })
19074
19075 (define_expand "movv2si"
19076 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19077 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19078 "TARGET_MMX"
19079 {
19080 ix86_expand_vector_move (V2SImode, operands);
19081 DONE;
19082 })
19083
19084 (define_expand "movv4hi"
19085 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19086 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19087 "TARGET_MMX"
19088 {
19089 ix86_expand_vector_move (V4HImode, operands);
19090 DONE;
19091 })
19092
19093 (define_expand "movv8qi"
19094 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19095 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19096 "TARGET_MMX"
19097 {
19098 ix86_expand_vector_move (V8QImode, operands);
19099 DONE;
19100 })
19101
19102 (define_expand "movv2sf"
19103 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19104 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19105 "TARGET_3DNOW"
19106 {
19107 ix86_expand_vector_move (V2SFmode, operands);
19108 DONE;
19109 })
19110
19111 (define_insn "*pushti"
19112 [(set (match_operand:TI 0 "push_operand" "=<")
19113 (match_operand:TI 1 "register_operand" "x"))]
19114 "TARGET_SSE"
19115 "#")
19116
19117 (define_insn "*pushv2df"
19118 [(set (match_operand:V2DF 0 "push_operand" "=<")
19119 (match_operand:V2DF 1 "register_operand" "x"))]
19120 "TARGET_SSE"
19121 "#")
19122
19123 (define_insn "*pushv2di"
19124 [(set (match_operand:V2DI 0 "push_operand" "=<")
19125 (match_operand:V2DI 1 "register_operand" "x"))]
19126 "TARGET_SSE2"
19127 "#")
19128
19129 (define_insn "*pushv8hi"
19130 [(set (match_operand:V8HI 0 "push_operand" "=<")
19131 (match_operand:V8HI 1 "register_operand" "x"))]
19132 "TARGET_SSE2"
19133 "#")
19134
19135 (define_insn "*pushv16qi"
19136 [(set (match_operand:V16QI 0 "push_operand" "=<")
19137 (match_operand:V16QI 1 "register_operand" "x"))]
19138 "TARGET_SSE2"
19139 "#")
19140
19141 (define_insn "*pushv4sf"
19142 [(set (match_operand:V4SF 0 "push_operand" "=<")
19143 (match_operand:V4SF 1 "register_operand" "x"))]
19144 "TARGET_SSE"
19145 "#")
19146
19147 (define_insn "*pushv4si"
19148 [(set (match_operand:V4SI 0 "push_operand" "=<")
19149 (match_operand:V4SI 1 "register_operand" "x"))]
19150 "TARGET_SSE2"
19151 "#")
19152
19153 (define_insn "*pushv2si"
19154 [(set (match_operand:V2SI 0 "push_operand" "=<")
19155 (match_operand:V2SI 1 "register_operand" "y"))]
19156 "TARGET_MMX"
19157 "#")
19158
19159 (define_insn "*pushv4hi"
19160 [(set (match_operand:V4HI 0 "push_operand" "=<")
19161 (match_operand:V4HI 1 "register_operand" "y"))]
19162 "TARGET_MMX"
19163 "#")
19164
19165 (define_insn "*pushv8qi"
19166 [(set (match_operand:V8QI 0 "push_operand" "=<")
19167 (match_operand:V8QI 1 "register_operand" "y"))]
19168 "TARGET_MMX"
19169 "#")
19170
19171 (define_insn "*pushv2sf"
19172 [(set (match_operand:V2SF 0 "push_operand" "=<")
19173 (match_operand:V2SF 1 "register_operand" "y"))]
19174 "TARGET_3DNOW"
19175 "#")
19176
19177 (define_split
19178 [(set (match_operand 0 "push_operand" "")
19179 (match_operand 1 "register_operand" ""))]
19180 "!TARGET_64BIT && reload_completed
19181 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19182 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19183 (set (match_dup 2) (match_dup 1))]
19184 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19185 stack_pointer_rtx);
19186 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19187
19188 (define_split
19189 [(set (match_operand 0 "push_operand" "")
19190 (match_operand 1 "register_operand" ""))]
19191 "TARGET_64BIT && reload_completed
19192 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19193 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19194 (set (match_dup 2) (match_dup 1))]
19195 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19196 stack_pointer_rtx);
19197 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19198
19199
19200 (define_insn "movti_internal"
19201 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19202 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19203 "TARGET_SSE && !TARGET_64BIT
19204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19205 {
19206 switch (which_alternative)
19207 {
19208 case 0:
19209 if (get_attr_mode (insn) == MODE_V4SF)
19210 return "xorps\t%0, %0";
19211 else
19212 return "pxor\t%0, %0";
19213 case 1:
19214 case 2:
19215 if (get_attr_mode (insn) == MODE_V4SF)
19216 return "movaps\t{%1, %0|%0, %1}";
19217 else
19218 return "movdqa\t{%1, %0|%0, %1}";
19219 default:
19220 abort ();
19221 }
19222 }
19223 [(set_attr "type" "ssemov,ssemov,ssemov")
19224 (set (attr "mode")
19225 (cond [(eq_attr "alternative" "0,1")
19226 (if_then_else
19227 (ne (symbol_ref "optimize_size")
19228 (const_int 0))
19229 (const_string "V4SF")
19230 (const_string "TI"))
19231 (eq_attr "alternative" "2")
19232 (if_then_else
19233 (ne (symbol_ref "optimize_size")
19234 (const_int 0))
19235 (const_string "V4SF")
19236 (const_string "TI"))]
19237 (const_string "TI")))])
19238
19239 (define_insn "*movti_rex64"
19240 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19241 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19242 "TARGET_64BIT
19243 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19244 {
19245 switch (which_alternative)
19246 {
19247 case 0:
19248 case 1:
19249 return "#";
19250 case 2:
19251 if (get_attr_mode (insn) == MODE_V4SF)
19252 return "xorps\t%0, %0";
19253 else
19254 return "pxor\t%0, %0";
19255 case 3:
19256 case 4:
19257 if (get_attr_mode (insn) == MODE_V4SF)
19258 return "movaps\t{%1, %0|%0, %1}";
19259 else
19260 return "movdqa\t{%1, %0|%0, %1}";
19261 default:
19262 abort ();
19263 }
19264 }
19265 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19266 (set (attr "mode")
19267 (cond [(eq_attr "alternative" "2,3")
19268 (if_then_else
19269 (ne (symbol_ref "optimize_size")
19270 (const_int 0))
19271 (const_string "V4SF")
19272 (const_string "TI"))
19273 (eq_attr "alternative" "4")
19274 (if_then_else
19275 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19276 (const_int 0))
19277 (ne (symbol_ref "optimize_size")
19278 (const_int 0)))
19279 (const_string "V4SF")
19280 (const_string "TI"))]
19281 (const_string "DI")))])
19282
19283 (define_insn "*movtf_rex64"
19284 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19285 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19286 "TARGET_64BIT
19287 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19288 {
19289 switch (which_alternative)
19290 {
19291 case 0:
19292 case 1:
19293 return "#";
19294 case 2:
19295 if (get_attr_mode (insn) == MODE_V4SF)
19296 return "xorps\t%0, %0";
19297 else
19298 return "pxor\t%0, %0";
19299 case 3:
19300 case 4:
19301 if (get_attr_mode (insn) == MODE_V4SF)
19302 return "movaps\t{%1, %0|%0, %1}";
19303 else
19304 return "movdqa\t{%1, %0|%0, %1}";
19305 default:
19306 abort ();
19307 }
19308 }
19309 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19310 (set (attr "mode")
19311 (cond [(eq_attr "alternative" "2,3")
19312 (if_then_else
19313 (ne (symbol_ref "optimize_size")
19314 (const_int 0))
19315 (const_string "V4SF")
19316 (const_string "TI"))
19317 (eq_attr "alternative" "4")
19318 (if_then_else
19319 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19320 (const_int 0))
19321 (ne (symbol_ref "optimize_size")
19322 (const_int 0)))
19323 (const_string "V4SF")
19324 (const_string "TI"))]
19325 (const_string "DI")))])
19326
19327 (define_split
19328 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19329 (match_operand:TI 1 "general_operand" ""))]
19330 "reload_completed && !SSE_REG_P (operands[0])
19331 && !SSE_REG_P (operands[1])"
19332 [(const_int 0)]
19333 "ix86_split_long_move (operands); DONE;")
19334
19335 (define_split
19336 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19337 (match_operand:TF 1 "general_operand" ""))]
19338 "reload_completed && !SSE_REG_P (operands[0])
19339 && !SSE_REG_P (operands[1])"
19340 [(const_int 0)]
19341 "ix86_split_long_move (operands); DONE;")
19342
19343 ;; These two patterns are useful for specifying exactly whether to use
19344 ;; movaps or movups
19345 (define_expand "sse_movaps"
19346 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19347 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19348 UNSPEC_MOVA))]
19349 "TARGET_SSE"
19350 {
19351 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19352 {
19353 rtx tmp = gen_reg_rtx (V4SFmode);
19354 emit_insn (gen_sse_movaps (tmp, operands[1]));
19355 emit_move_insn (operands[0], tmp);
19356 DONE;
19357 }
19358 })
19359
19360 (define_insn "*sse_movaps_1"
19361 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19362 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19363 UNSPEC_MOVA))]
19364 "TARGET_SSE
19365 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19366 "movaps\t{%1, %0|%0, %1}"
19367 [(set_attr "type" "ssemov,ssemov")
19368 (set_attr "mode" "V4SF")])
19369
19370 (define_expand "sse_movups"
19371 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19372 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19373 UNSPEC_MOVU))]
19374 "TARGET_SSE"
19375 {
19376 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19377 {
19378 rtx tmp = gen_reg_rtx (V4SFmode);
19379 emit_insn (gen_sse_movups (tmp, operands[1]));
19380 emit_move_insn (operands[0], tmp);
19381 DONE;
19382 }
19383 })
19384
19385 (define_insn "*sse_movups_1"
19386 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19387 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19388 UNSPEC_MOVU))]
19389 "TARGET_SSE
19390 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19391 "movups\t{%1, %0|%0, %1}"
19392 [(set_attr "type" "ssecvt,ssecvt")
19393 (set_attr "mode" "V4SF")])
19394
19395 ;; SSE Strange Moves.
19396
19397 (define_insn "sse_movmskps"
19398 [(set (match_operand:SI 0 "register_operand" "=r")
19399 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19400 UNSPEC_MOVMSK))]
19401 "TARGET_SSE"
19402 "movmskps\t{%1, %0|%0, %1}"
19403 [(set_attr "type" "ssecvt")
19404 (set_attr "mode" "V4SF")])
19405
19406 (define_insn "mmx_pmovmskb"
19407 [(set (match_operand:SI 0 "register_operand" "=r")
19408 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19409 UNSPEC_MOVMSK))]
19410 "TARGET_SSE || TARGET_3DNOW_A"
19411 "pmovmskb\t{%1, %0|%0, %1}"
19412 [(set_attr "type" "ssecvt")
19413 (set_attr "mode" "V4SF")])
19414
19415
19416 (define_insn "mmx_maskmovq"
19417 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19418 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19419 (match_operand:V8QI 2 "register_operand" "y")]
19420 UNSPEC_MASKMOV))]
19421 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19422 ;; @@@ check ordering of operands in intel/nonintel syntax
19423 "maskmovq\t{%2, %1|%1, %2}"
19424 [(set_attr "type" "mmxcvt")
19425 (set_attr "mode" "DI")])
19426
19427 (define_insn "mmx_maskmovq_rex"
19428 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19429 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19430 (match_operand:V8QI 2 "register_operand" "y")]
19431 UNSPEC_MASKMOV))]
19432 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19433 ;; @@@ check ordering of operands in intel/nonintel syntax
19434 "maskmovq\t{%2, %1|%1, %2}"
19435 [(set_attr "type" "mmxcvt")
19436 (set_attr "mode" "DI")])
19437
19438 (define_insn "sse_movntv4sf"
19439 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19440 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19441 UNSPEC_MOVNT))]
19442 "TARGET_SSE"
19443 "movntps\t{%1, %0|%0, %1}"
19444 [(set_attr "type" "ssemov")
19445 (set_attr "mode" "V4SF")])
19446
19447 (define_insn "sse_movntdi"
19448 [(set (match_operand:DI 0 "memory_operand" "=m")
19449 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19450 UNSPEC_MOVNT))]
19451 "TARGET_SSE || TARGET_3DNOW_A"
19452 "movntq\t{%1, %0|%0, %1}"
19453 [(set_attr "type" "mmxmov")
19454 (set_attr "mode" "DI")])
19455
19456 (define_insn "sse_movhlps"
19457 [(set (match_operand:V4SF 0 "register_operand" "=x")
19458 (vec_merge:V4SF
19459 (match_operand:V4SF 1 "register_operand" "0")
19460 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19461 (parallel [(const_int 2)
19462 (const_int 3)
19463 (const_int 0)
19464 (const_int 1)]))
19465 (const_int 3)))]
19466 "TARGET_SSE"
19467 "movhlps\t{%2, %0|%0, %2}"
19468 [(set_attr "type" "ssecvt")
19469 (set_attr "mode" "V4SF")])
19470
19471 (define_insn "sse_movlhps"
19472 [(set (match_operand:V4SF 0 "register_operand" "=x")
19473 (vec_merge:V4SF
19474 (match_operand:V4SF 1 "register_operand" "0")
19475 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19476 (parallel [(const_int 2)
19477 (const_int 3)
19478 (const_int 0)
19479 (const_int 1)]))
19480 (const_int 12)))]
19481 "TARGET_SSE"
19482 "movlhps\t{%2, %0|%0, %2}"
19483 [(set_attr "type" "ssecvt")
19484 (set_attr "mode" "V4SF")])
19485
19486 (define_insn "sse_movhps"
19487 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19488 (vec_merge:V4SF
19489 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19490 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19491 (const_int 12)))]
19492 "TARGET_SSE
19493 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19494 "movhps\t{%2, %0|%0, %2}"
19495 [(set_attr "type" "ssecvt")
19496 (set_attr "mode" "V4SF")])
19497
19498 (define_insn "sse_movlps"
19499 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19500 (vec_merge:V4SF
19501 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19502 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19503 (const_int 3)))]
19504 "TARGET_SSE
19505 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19506 "movlps\t{%2, %0|%0, %2}"
19507 [(set_attr "type" "ssecvt")
19508 (set_attr "mode" "V4SF")])
19509
19510 (define_expand "sse_loadss"
19511 [(match_operand:V4SF 0 "register_operand" "")
19512 (match_operand:SF 1 "memory_operand" "")]
19513 "TARGET_SSE"
19514 {
19515 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19516 CONST0_RTX (V4SFmode)));
19517 DONE;
19518 })
19519
19520 (define_insn "sse_loadss_1"
19521 [(set (match_operand:V4SF 0 "register_operand" "=x")
19522 (vec_merge:V4SF
19523 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19524 (match_operand:V4SF 2 "const0_operand" "X")
19525 (const_int 1)))]
19526 "TARGET_SSE"
19527 "movss\t{%1, %0|%0, %1}"
19528 [(set_attr "type" "ssemov")
19529 (set_attr "mode" "SF")])
19530
19531 (define_insn "sse_movss"
19532 [(set (match_operand:V4SF 0 "register_operand" "=x")
19533 (vec_merge:V4SF
19534 (match_operand:V4SF 1 "register_operand" "0")
19535 (match_operand:V4SF 2 "register_operand" "x")
19536 (const_int 1)))]
19537 "TARGET_SSE"
19538 "movss\t{%2, %0|%0, %2}"
19539 [(set_attr "type" "ssemov")
19540 (set_attr "mode" "SF")])
19541
19542 (define_insn "sse_storess"
19543 [(set (match_operand:SF 0 "memory_operand" "=m")
19544 (vec_select:SF
19545 (match_operand:V4SF 1 "register_operand" "x")
19546 (parallel [(const_int 0)])))]
19547 "TARGET_SSE"
19548 "movss\t{%1, %0|%0, %1}"
19549 [(set_attr "type" "ssemov")
19550 (set_attr "mode" "SF")])
19551
19552 (define_insn "sse_shufps"
19553 [(set (match_operand:V4SF 0 "register_operand" "=x")
19554 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19555 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19556 (match_operand:SI 3 "immediate_operand" "i")]
19557 UNSPEC_SHUFFLE))]
19558 "TARGET_SSE"
19559 ;; @@@ check operand order for intel/nonintel syntax
19560 "shufps\t{%3, %2, %0|%0, %2, %3}"
19561 [(set_attr "type" "ssecvt")
19562 (set_attr "mode" "V4SF")])
19563
19564
19565 ;; SSE arithmetic
19566
19567 (define_insn "addv4sf3"
19568 [(set (match_operand:V4SF 0 "register_operand" "=x")
19569 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19570 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19571 "TARGET_SSE"
19572 "addps\t{%2, %0|%0, %2}"
19573 [(set_attr "type" "sseadd")
19574 (set_attr "mode" "V4SF")])
19575
19576 (define_insn "vmaddv4sf3"
19577 [(set (match_operand:V4SF 0 "register_operand" "=x")
19578 (vec_merge:V4SF
19579 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19580 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19581 (match_dup 1)
19582 (const_int 1)))]
19583 "TARGET_SSE"
19584 "addss\t{%2, %0|%0, %2}"
19585 [(set_attr "type" "sseadd")
19586 (set_attr "mode" "SF")])
19587
19588 (define_insn "subv4sf3"
19589 [(set (match_operand:V4SF 0 "register_operand" "=x")
19590 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19591 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19592 "TARGET_SSE"
19593 "subps\t{%2, %0|%0, %2}"
19594 [(set_attr "type" "sseadd")
19595 (set_attr "mode" "V4SF")])
19596
19597 (define_insn "vmsubv4sf3"
19598 [(set (match_operand:V4SF 0 "register_operand" "=x")
19599 (vec_merge:V4SF
19600 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19601 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19602 (match_dup 1)
19603 (const_int 1)))]
19604 "TARGET_SSE"
19605 "subss\t{%2, %0|%0, %2}"
19606 [(set_attr "type" "sseadd")
19607 (set_attr "mode" "SF")])
19608
19609 (define_insn "mulv4sf3"
19610 [(set (match_operand:V4SF 0 "register_operand" "=x")
19611 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19612 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19613 "TARGET_SSE"
19614 "mulps\t{%2, %0|%0, %2}"
19615 [(set_attr "type" "ssemul")
19616 (set_attr "mode" "V4SF")])
19617
19618 (define_insn "vmmulv4sf3"
19619 [(set (match_operand:V4SF 0 "register_operand" "=x")
19620 (vec_merge:V4SF
19621 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19622 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19623 (match_dup 1)
19624 (const_int 1)))]
19625 "TARGET_SSE"
19626 "mulss\t{%2, %0|%0, %2}"
19627 [(set_attr "type" "ssemul")
19628 (set_attr "mode" "SF")])
19629
19630 (define_insn "divv4sf3"
19631 [(set (match_operand:V4SF 0 "register_operand" "=x")
19632 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19633 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19634 "TARGET_SSE"
19635 "divps\t{%2, %0|%0, %2}"
19636 [(set_attr "type" "ssediv")
19637 (set_attr "mode" "V4SF")])
19638
19639 (define_insn "vmdivv4sf3"
19640 [(set (match_operand:V4SF 0 "register_operand" "=x")
19641 (vec_merge:V4SF
19642 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19643 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19644 (match_dup 1)
19645 (const_int 1)))]
19646 "TARGET_SSE"
19647 "divss\t{%2, %0|%0, %2}"
19648 [(set_attr "type" "ssediv")
19649 (set_attr "mode" "SF")])
19650
19651
19652 ;; SSE square root/reciprocal
19653
19654 (define_insn "rcpv4sf2"
19655 [(set (match_operand:V4SF 0 "register_operand" "=x")
19656 (unspec:V4SF
19657 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19658 "TARGET_SSE"
19659 "rcpps\t{%1, %0|%0, %1}"
19660 [(set_attr "type" "sse")
19661 (set_attr "mode" "V4SF")])
19662
19663 (define_insn "vmrcpv4sf2"
19664 [(set (match_operand:V4SF 0 "register_operand" "=x")
19665 (vec_merge:V4SF
19666 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19667 UNSPEC_RCP)
19668 (match_operand:V4SF 2 "register_operand" "0")
19669 (const_int 1)))]
19670 "TARGET_SSE"
19671 "rcpss\t{%1, %0|%0, %1}"
19672 [(set_attr "type" "sse")
19673 (set_attr "mode" "SF")])
19674
19675 (define_insn "rsqrtv4sf2"
19676 [(set (match_operand:V4SF 0 "register_operand" "=x")
19677 (unspec:V4SF
19678 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19679 "TARGET_SSE"
19680 "rsqrtps\t{%1, %0|%0, %1}"
19681 [(set_attr "type" "sse")
19682 (set_attr "mode" "V4SF")])
19683
19684 (define_insn "vmrsqrtv4sf2"
19685 [(set (match_operand:V4SF 0 "register_operand" "=x")
19686 (vec_merge:V4SF
19687 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19688 UNSPEC_RSQRT)
19689 (match_operand:V4SF 2 "register_operand" "0")
19690 (const_int 1)))]
19691 "TARGET_SSE"
19692 "rsqrtss\t{%1, %0|%0, %1}"
19693 [(set_attr "type" "sse")
19694 (set_attr "mode" "SF")])
19695
19696 (define_insn "sqrtv4sf2"
19697 [(set (match_operand:V4SF 0 "register_operand" "=x")
19698 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19699 "TARGET_SSE"
19700 "sqrtps\t{%1, %0|%0, %1}"
19701 [(set_attr "type" "sse")
19702 (set_attr "mode" "V4SF")])
19703
19704 (define_insn "vmsqrtv4sf2"
19705 [(set (match_operand:V4SF 0 "register_operand" "=x")
19706 (vec_merge:V4SF
19707 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19708 (match_operand:V4SF 2 "register_operand" "0")
19709 (const_int 1)))]
19710 "TARGET_SSE"
19711 "sqrtss\t{%1, %0|%0, %1}"
19712 [(set_attr "type" "sse")
19713 (set_attr "mode" "SF")])
19714
19715 ;; SSE logical operations.
19716
19717 ;; SSE defines logical operations on floating point values. This brings
19718 ;; interesting challenge to RTL representation where logicals are only valid
19719 ;; on integral types. We deal with this by representing the floating point
19720 ;; logical as logical on arguments casted to TImode as this is what hardware
19721 ;; really does. Unfortunately hardware requires the type information to be
19722 ;; present and thus we must avoid subregs from being simplified and eliminated
19723 ;; in later compilation phases.
19724 ;;
19725 ;; We have following variants from each instruction:
19726 ;; sse_andsf3 - the operation taking V4SF vector operands
19727 ;; and doing TImode cast on them
19728 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19729 ;; TImode, since backend insist on eliminating casts
19730 ;; on memory operands
19731 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19732 ;; We can not accept memory operand here as instruction reads
19733 ;; whole scalar. This is generated only post reload by GCC
19734 ;; scalar float operations that expands to logicals (fabs)
19735 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19736 ;; memory operand. Eventually combine can be able
19737 ;; to synthesize these using splitter.
19738 ;; sse2_anddf3, *sse2_anddf3_memory
19739 ;;
19740 ;;
19741 ;; These are not called andti3 etc. because we really really don't want
19742 ;; the compiler to widen DImode ands to TImode ands and then try to move
19743 ;; into DImode subregs of SSE registers, and them together, and move out
19744 ;; of DImode subregs again!
19745 ;; SSE1 single precision floating point logical operation
19746 (define_expand "sse_andv4sf3"
19747 [(set (match_operand:V4SF 0 "register_operand" "")
19748 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
19749 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19750 "TARGET_SSE"
19751 "")
19752
19753 (define_insn "*sse_andv4sf3"
19754 [(set (match_operand:V4SF 0 "register_operand" "=x")
19755 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19756 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19757 "TARGET_SSE
19758 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19759 "andps\t{%2, %0|%0, %2}"
19760 [(set_attr "type" "sselog")
19761 (set_attr "mode" "V4SF")])
19762
19763 (define_expand "sse_nandv4sf3"
19764 [(set (match_operand:V4SF 0 "register_operand" "")
19765 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
19766 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19767 "TARGET_SSE"
19768 "")
19769
19770 (define_insn "*sse_nandv4sf3"
19771 [(set (match_operand:V4SF 0 "register_operand" "=x")
19772 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
19773 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19774 "TARGET_SSE"
19775 "andnps\t{%2, %0|%0, %2}"
19776 [(set_attr "type" "sselog")
19777 (set_attr "mode" "V4SF")])
19778
19779 (define_expand "sse_iorv4sf3"
19780 [(set (match_operand:V4SF 0 "register_operand" "")
19781 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
19782 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19783 "TARGET_SSE"
19784 "")
19785
19786 (define_insn "*sse_iorv4sf3"
19787 [(set (match_operand:V4SF 0 "register_operand" "=x")
19788 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19789 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19790 "TARGET_SSE
19791 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19792 "orps\t{%2, %0|%0, %2}"
19793 [(set_attr "type" "sselog")
19794 (set_attr "mode" "V4SF")])
19795
19796 (define_expand "sse_xorv4sf3"
19797 [(set (match_operand:V4SF 0 "register_operand" "")
19798 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
19799 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19800 "TARGET_SSE"
19801 "")
19802
19803 (define_insn "*sse_xorv4sf3"
19804 [(set (match_operand:V4SF 0 "register_operand" "=x")
19805 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19806 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19807 "TARGET_SSE
19808 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19809 "xorps\t{%2, %0|%0, %2}"
19810 [(set_attr "type" "sselog")
19811 (set_attr "mode" "V4SF")])
19812
19813 ;; SSE2 double precision floating point logical operation
19814
19815 (define_expand "sse2_andv2df3"
19816 [(set (match_operand:V2DF 0 "register_operand" "")
19817 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
19818 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19819 "TARGET_SSE2"
19820 "")
19821
19822 (define_insn "*sse2_andv2df3"
19823 [(set (match_operand:V2DF 0 "register_operand" "=x")
19824 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19825 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19826 "TARGET_SSE2
19827 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19828 "andpd\t{%2, %0|%0, %2}"
19829 [(set_attr "type" "sselog")
19830 (set_attr "mode" "V2DF")])
19831
19832 (define_expand "sse2_nandv2df3"
19833 [(set (match_operand:V2DF 0 "register_operand" "")
19834 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
19835 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19836 "TARGET_SSE2"
19837 "")
19838
19839 (define_insn "*sse2_nandv2df3"
19840 [(set (match_operand:V2DF 0 "register_operand" "=x")
19841 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
19842 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19843 "TARGET_SSE2"
19844 "andnpd\t{%2, %0|%0, %2}"
19845 [(set_attr "type" "sselog")
19846 (set_attr "mode" "V2DF")])
19847
19848 (define_expand "sse2_iorv2df3"
19849 [(set (match_operand:V2DF 0 "register_operand" "")
19850 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
19851 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19852 "TARGET_SSE2"
19853 "")
19854
19855 (define_insn "*sse2_iorv2df3"
19856 [(set (match_operand:V2DF 0 "register_operand" "=x")
19857 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19858 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19859 "TARGET_SSE2
19860 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19861 "orpd\t{%2, %0|%0, %2}"
19862 [(set_attr "type" "sselog")
19863 (set_attr "mode" "V2DF")])
19864
19865 (define_expand "sse2_xorv2df3"
19866 [(set (match_operand:V2DF 0 "register_operand" "")
19867 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
19868 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19869 "TARGET_SSE2"
19870 "")
19871
19872 (define_insn "*sse2_xorv2df3"
19873 [(set (match_operand:V2DF 0 "register_operand" "=x")
19874 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19875 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19876 "TARGET_SSE2
19877 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19878 "xorpd\t{%2, %0|%0, %2}"
19879 [(set_attr "type" "sselog")
19880 (set_attr "mode" "V2DF")])
19881
19882 ;; SSE2 integral logicals. These patterns must always come after floating
19883 ;; point ones since we don't want compiler to use integer opcodes on floating
19884 ;; point SSE values to avoid matching of subregs in the match_operand.
19885 (define_insn "*sse2_andti3"
19886 [(set (match_operand:TI 0 "register_operand" "=x")
19887 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19888 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19889 "TARGET_SSE2
19890 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19891 "pand\t{%2, %0|%0, %2}"
19892 [(set_attr "type" "sselog")
19893 (set_attr "mode" "TI")])
19894
19895 (define_insn "sse2_andv2di3"
19896 [(set (match_operand:V2DI 0 "register_operand" "=x")
19897 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19898 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19899 "TARGET_SSE2
19900 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19901 "pand\t{%2, %0|%0, %2}"
19902 [(set_attr "type" "sselog")
19903 (set_attr "mode" "TI")])
19904
19905 (define_insn "*sse2_nandti3"
19906 [(set (match_operand:TI 0 "register_operand" "=x")
19907 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19908 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19909 "TARGET_SSE2"
19910 "pandn\t{%2, %0|%0, %2}"
19911 [(set_attr "type" "sselog")
19912 (set_attr "mode" "TI")])
19913
19914 (define_insn "sse2_nandv2di3"
19915 [(set (match_operand:V2DI 0 "register_operand" "=x")
19916 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19917 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19918 "TARGET_SSE2
19919 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19920 "pandn\t{%2, %0|%0, %2}"
19921 [(set_attr "type" "sselog")
19922 (set_attr "mode" "TI")])
19923
19924 (define_insn "*sse2_iorti3"
19925 [(set (match_operand:TI 0 "register_operand" "=x")
19926 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19927 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19928 "TARGET_SSE2
19929 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19930 "por\t{%2, %0|%0, %2}"
19931 [(set_attr "type" "sselog")
19932 (set_attr "mode" "TI")])
19933
19934 (define_insn "sse2_iorv2di3"
19935 [(set (match_operand:V2DI 0 "register_operand" "=x")
19936 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19937 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19938 "TARGET_SSE2
19939 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19940 "por\t{%2, %0|%0, %2}"
19941 [(set_attr "type" "sselog")
19942 (set_attr "mode" "TI")])
19943
19944 (define_insn "*sse2_xorti3"
19945 [(set (match_operand:TI 0 "register_operand" "=x")
19946 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19947 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19948 "TARGET_SSE2
19949 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19950 "pxor\t{%2, %0|%0, %2}"
19951 [(set_attr "type" "sselog")
19952 (set_attr "mode" "TI")])
19953
19954 (define_insn "sse2_xorv2di3"
19955 [(set (match_operand:V2DI 0 "register_operand" "=x")
19956 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19957 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19958 "TARGET_SSE2
19959 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19960 "pxor\t{%2, %0|%0, %2}"
19961 [(set_attr "type" "sselog")
19962 (set_attr "mode" "TI")])
19963
19964 ;; Use xor, but don't show input operands so they aren't live before
19965 ;; this insn.
19966 (define_insn "sse_clrv4sf"
19967 [(set (match_operand:V4SF 0 "register_operand" "=x")
19968 (match_operand:V4SF 1 "const0_operand" "X"))]
19969 "TARGET_SSE"
19970 {
19971 if (get_attr_mode (insn) == MODE_TI)
19972 return "pxor\t{%0, %0|%0, %0}";
19973 else
19974 return "xorps\t{%0, %0|%0, %0}";
19975 }
19976 [(set_attr "type" "sselog")
19977 (set_attr "memory" "none")
19978 (set (attr "mode")
19979 (if_then_else
19980 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19981 (const_int 0))
19982 (ne (symbol_ref "TARGET_SSE2")
19983 (const_int 0)))
19984 (eq (symbol_ref "optimize_size")
19985 (const_int 0)))
19986 (const_string "TI")
19987 (const_string "V4SF")))])
19988
19989 ;; Use xor, but don't show input operands so they aren't live before
19990 ;; this insn.
19991 (define_insn "sse_clrv2df"
19992 [(set (match_operand:V2DF 0 "register_operand" "=x")
19993 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19994 "TARGET_SSE2"
19995 "xorpd\t{%0, %0|%0, %0}"
19996 [(set_attr "type" "sselog")
19997 (set_attr "memory" "none")
19998 (set_attr "mode" "V4SF")])
19999
20000 ;; SSE mask-generating compares
20001
20002 (define_insn "maskcmpv4sf3"
20003 [(set (match_operand:V4SI 0 "register_operand" "=x")
20004 (match_operator:V4SI 3 "sse_comparison_operator"
20005 [(match_operand:V4SF 1 "register_operand" "0")
20006 (match_operand:V4SF 2 "register_operand" "x")]))]
20007 "TARGET_SSE"
20008 "cmp%D3ps\t{%2, %0|%0, %2}"
20009 [(set_attr "type" "ssecmp")
20010 (set_attr "mode" "V4SF")])
20011
20012 (define_insn "maskncmpv4sf3"
20013 [(set (match_operand:V4SI 0 "register_operand" "=x")
20014 (not:V4SI
20015 (match_operator:V4SI 3 "sse_comparison_operator"
20016 [(match_operand:V4SF 1 "register_operand" "0")
20017 (match_operand:V4SF 2 "register_operand" "x")])))]
20018 "TARGET_SSE"
20019 {
20020 if (GET_CODE (operands[3]) == UNORDERED)
20021 return "cmpordps\t{%2, %0|%0, %2}";
20022 else
20023 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20024 }
20025 [(set_attr "type" "ssecmp")
20026 (set_attr "mode" "V4SF")])
20027
20028 (define_insn "vmmaskcmpv4sf3"
20029 [(set (match_operand:V4SI 0 "register_operand" "=x")
20030 (vec_merge:V4SI
20031 (match_operator:V4SI 3 "sse_comparison_operator"
20032 [(match_operand:V4SF 1 "register_operand" "0")
20033 (match_operand:V4SF 2 "register_operand" "x")])
20034 (subreg:V4SI (match_dup 1) 0)
20035 (const_int 1)))]
20036 "TARGET_SSE"
20037 "cmp%D3ss\t{%2, %0|%0, %2}"
20038 [(set_attr "type" "ssecmp")
20039 (set_attr "mode" "SF")])
20040
20041 (define_insn "vmmaskncmpv4sf3"
20042 [(set (match_operand:V4SI 0 "register_operand" "=x")
20043 (vec_merge:V4SI
20044 (not:V4SI
20045 (match_operator:V4SI 3 "sse_comparison_operator"
20046 [(match_operand:V4SF 1 "register_operand" "0")
20047 (match_operand:V4SF 2 "register_operand" "x")]))
20048 (subreg:V4SI (match_dup 1) 0)
20049 (const_int 1)))]
20050 "TARGET_SSE"
20051 {
20052 if (GET_CODE (operands[3]) == UNORDERED)
20053 return "cmpordss\t{%2, %0|%0, %2}";
20054 else
20055 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20056 }
20057 [(set_attr "type" "ssecmp")
20058 (set_attr "mode" "SF")])
20059
20060 (define_insn "sse_comi"
20061 [(set (reg:CCFP 17)
20062 (compare:CCFP (vec_select:SF
20063 (match_operand:V4SF 0 "register_operand" "x")
20064 (parallel [(const_int 0)]))
20065 (vec_select:SF
20066 (match_operand:V4SF 1 "register_operand" "x")
20067 (parallel [(const_int 0)]))))]
20068 "TARGET_SSE"
20069 "comiss\t{%1, %0|%0, %1}"
20070 [(set_attr "type" "ssecomi")
20071 (set_attr "mode" "SF")])
20072
20073 (define_insn "sse_ucomi"
20074 [(set (reg:CCFPU 17)
20075 (compare:CCFPU (vec_select:SF
20076 (match_operand:V4SF 0 "register_operand" "x")
20077 (parallel [(const_int 0)]))
20078 (vec_select:SF
20079 (match_operand:V4SF 1 "register_operand" "x")
20080 (parallel [(const_int 0)]))))]
20081 "TARGET_SSE"
20082 "ucomiss\t{%1, %0|%0, %1}"
20083 [(set_attr "type" "ssecomi")
20084 (set_attr "mode" "SF")])
20085
20086
20087 ;; SSE unpack
20088
20089 (define_insn "sse_unpckhps"
20090 [(set (match_operand:V4SF 0 "register_operand" "=x")
20091 (vec_merge:V4SF
20092 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20093 (parallel [(const_int 2)
20094 (const_int 0)
20095 (const_int 3)
20096 (const_int 1)]))
20097 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20098 (parallel [(const_int 0)
20099 (const_int 2)
20100 (const_int 1)
20101 (const_int 3)]))
20102 (const_int 5)))]
20103 "TARGET_SSE"
20104 "unpckhps\t{%2, %0|%0, %2}"
20105 [(set_attr "type" "ssecvt")
20106 (set_attr "mode" "V4SF")])
20107
20108 (define_insn "sse_unpcklps"
20109 [(set (match_operand:V4SF 0 "register_operand" "=x")
20110 (vec_merge:V4SF
20111 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20112 (parallel [(const_int 0)
20113 (const_int 2)
20114 (const_int 1)
20115 (const_int 3)]))
20116 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20117 (parallel [(const_int 2)
20118 (const_int 0)
20119 (const_int 3)
20120 (const_int 1)]))
20121 (const_int 5)))]
20122 "TARGET_SSE"
20123 "unpcklps\t{%2, %0|%0, %2}"
20124 [(set_attr "type" "ssecvt")
20125 (set_attr "mode" "V4SF")])
20126
20127
20128 ;; SSE min/max
20129
20130 (define_insn "smaxv4sf3"
20131 [(set (match_operand:V4SF 0 "register_operand" "=x")
20132 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20133 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20134 "TARGET_SSE"
20135 "maxps\t{%2, %0|%0, %2}"
20136 [(set_attr "type" "sse")
20137 (set_attr "mode" "V4SF")])
20138
20139 (define_insn "vmsmaxv4sf3"
20140 [(set (match_operand:V4SF 0 "register_operand" "=x")
20141 (vec_merge:V4SF
20142 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20143 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20144 (match_dup 1)
20145 (const_int 1)))]
20146 "TARGET_SSE"
20147 "maxss\t{%2, %0|%0, %2}"
20148 [(set_attr "type" "sse")
20149 (set_attr "mode" "SF")])
20150
20151 (define_insn "sminv4sf3"
20152 [(set (match_operand:V4SF 0 "register_operand" "=x")
20153 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20154 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20155 "TARGET_SSE"
20156 "minps\t{%2, %0|%0, %2}"
20157 [(set_attr "type" "sse")
20158 (set_attr "mode" "V4SF")])
20159
20160 (define_insn "vmsminv4sf3"
20161 [(set (match_operand:V4SF 0 "register_operand" "=x")
20162 (vec_merge:V4SF
20163 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20164 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20165 (match_dup 1)
20166 (const_int 1)))]
20167 "TARGET_SSE"
20168 "minss\t{%2, %0|%0, %2}"
20169 [(set_attr "type" "sse")
20170 (set_attr "mode" "SF")])
20171
20172 ;; SSE <-> integer/MMX conversions
20173
20174 (define_insn "cvtpi2ps"
20175 [(set (match_operand:V4SF 0 "register_operand" "=x")
20176 (vec_merge:V4SF
20177 (match_operand:V4SF 1 "register_operand" "0")
20178 (vec_duplicate:V4SF
20179 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20180 (const_int 12)))]
20181 "TARGET_SSE"
20182 "cvtpi2ps\t{%2, %0|%0, %2}"
20183 [(set_attr "type" "ssecvt")
20184 (set_attr "mode" "V4SF")])
20185
20186 (define_insn "cvtps2pi"
20187 [(set (match_operand:V2SI 0 "register_operand" "=y")
20188 (vec_select:V2SI
20189 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20190 (parallel [(const_int 0) (const_int 1)])))]
20191 "TARGET_SSE"
20192 "cvtps2pi\t{%1, %0|%0, %1}"
20193 [(set_attr "type" "ssecvt")
20194 (set_attr "mode" "V4SF")])
20195
20196 (define_insn "cvttps2pi"
20197 [(set (match_operand:V2SI 0 "register_operand" "=y")
20198 (vec_select:V2SI
20199 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20200 UNSPEC_FIX)
20201 (parallel [(const_int 0) (const_int 1)])))]
20202 "TARGET_SSE"
20203 "cvttps2pi\t{%1, %0|%0, %1}"
20204 [(set_attr "type" "ssecvt")
20205 (set_attr "mode" "SF")])
20206
20207 (define_insn "cvtsi2ss"
20208 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20209 (vec_merge:V4SF
20210 (match_operand:V4SF 1 "register_operand" "0,0")
20211 (vec_duplicate:V4SF
20212 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20213 (const_int 14)))]
20214 "TARGET_SSE"
20215 "cvtsi2ss\t{%2, %0|%0, %2}"
20216 [(set_attr "type" "sseicvt")
20217 (set_attr "athlon_decode" "vector,double")
20218 (set_attr "mode" "SF")])
20219
20220 (define_insn "cvtsi2ssq"
20221 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20222 (vec_merge:V4SF
20223 (match_operand:V4SF 1 "register_operand" "0,0")
20224 (vec_duplicate:V4SF
20225 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20226 (const_int 14)))]
20227 "TARGET_SSE && TARGET_64BIT"
20228 "cvtsi2ssq\t{%2, %0|%0, %2}"
20229 [(set_attr "type" "sseicvt")
20230 (set_attr "athlon_decode" "vector,double")
20231 (set_attr "mode" "SF")])
20232
20233 (define_insn "cvtss2si"
20234 [(set (match_operand:SI 0 "register_operand" "=r,r")
20235 (vec_select:SI
20236 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20237 (parallel [(const_int 0)])))]
20238 "TARGET_SSE"
20239 "cvtss2si\t{%1, %0|%0, %1}"
20240 [(set_attr "type" "sseicvt")
20241 (set_attr "athlon_decode" "double,vector")
20242 (set_attr "mode" "SI")])
20243
20244 (define_insn "cvtss2siq"
20245 [(set (match_operand:DI 0 "register_operand" "=r,r")
20246 (vec_select:DI
20247 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20248 (parallel [(const_int 0)])))]
20249 "TARGET_SSE"
20250 "cvtss2siq\t{%1, %0|%0, %1}"
20251 [(set_attr "type" "sseicvt")
20252 (set_attr "athlon_decode" "double,vector")
20253 (set_attr "mode" "DI")])
20254
20255 (define_insn "cvttss2si"
20256 [(set (match_operand:SI 0 "register_operand" "=r,r")
20257 (vec_select:SI
20258 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20259 UNSPEC_FIX)
20260 (parallel [(const_int 0)])))]
20261 "TARGET_SSE"
20262 "cvttss2si\t{%1, %0|%0, %1}"
20263 [(set_attr "type" "sseicvt")
20264 (set_attr "mode" "SF")
20265 (set_attr "athlon_decode" "double,vector")])
20266
20267 (define_insn "cvttss2siq"
20268 [(set (match_operand:DI 0 "register_operand" "=r,r")
20269 (vec_select:DI
20270 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20271 UNSPEC_FIX)
20272 (parallel [(const_int 0)])))]
20273 "TARGET_SSE && TARGET_64BIT"
20274 "cvttss2siq\t{%1, %0|%0, %1}"
20275 [(set_attr "type" "sseicvt")
20276 (set_attr "mode" "SF")
20277 (set_attr "athlon_decode" "double,vector")])
20278
20279
20280 ;; MMX insns
20281
20282 ;; MMX arithmetic
20283
20284 (define_insn "addv8qi3"
20285 [(set (match_operand:V8QI 0 "register_operand" "=y")
20286 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20287 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20288 "TARGET_MMX"
20289 "paddb\t{%2, %0|%0, %2}"
20290 [(set_attr "type" "mmxadd")
20291 (set_attr "mode" "DI")])
20292
20293 (define_insn "addv4hi3"
20294 [(set (match_operand:V4HI 0 "register_operand" "=y")
20295 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20296 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20297 "TARGET_MMX"
20298 "paddw\t{%2, %0|%0, %2}"
20299 [(set_attr "type" "mmxadd")
20300 (set_attr "mode" "DI")])
20301
20302 (define_insn "addv2si3"
20303 [(set (match_operand:V2SI 0 "register_operand" "=y")
20304 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20305 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20306 "TARGET_MMX"
20307 "paddd\t{%2, %0|%0, %2}"
20308 [(set_attr "type" "mmxadd")
20309 (set_attr "mode" "DI")])
20310
20311 (define_insn "mmx_adddi3"
20312 [(set (match_operand:DI 0 "register_operand" "=y")
20313 (unspec:DI
20314 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20315 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20316 UNSPEC_NOP))]
20317 "TARGET_MMX"
20318 "paddq\t{%2, %0|%0, %2}"
20319 [(set_attr "type" "mmxadd")
20320 (set_attr "mode" "DI")])
20321
20322 (define_insn "ssaddv8qi3"
20323 [(set (match_operand:V8QI 0 "register_operand" "=y")
20324 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20325 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20326 "TARGET_MMX"
20327 "paddsb\t{%2, %0|%0, %2}"
20328 [(set_attr "type" "mmxadd")
20329 (set_attr "mode" "DI")])
20330
20331 (define_insn "ssaddv4hi3"
20332 [(set (match_operand:V4HI 0 "register_operand" "=y")
20333 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20334 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20335 "TARGET_MMX"
20336 "paddsw\t{%2, %0|%0, %2}"
20337 [(set_attr "type" "mmxadd")
20338 (set_attr "mode" "DI")])
20339
20340 (define_insn "usaddv8qi3"
20341 [(set (match_operand:V8QI 0 "register_operand" "=y")
20342 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20343 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20344 "TARGET_MMX"
20345 "paddusb\t{%2, %0|%0, %2}"
20346 [(set_attr "type" "mmxadd")
20347 (set_attr "mode" "DI")])
20348
20349 (define_insn "usaddv4hi3"
20350 [(set (match_operand:V4HI 0 "register_operand" "=y")
20351 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20352 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20353 "TARGET_MMX"
20354 "paddusw\t{%2, %0|%0, %2}"
20355 [(set_attr "type" "mmxadd")
20356 (set_attr "mode" "DI")])
20357
20358 (define_insn "subv8qi3"
20359 [(set (match_operand:V8QI 0 "register_operand" "=y")
20360 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20361 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20362 "TARGET_MMX"
20363 "psubb\t{%2, %0|%0, %2}"
20364 [(set_attr "type" "mmxadd")
20365 (set_attr "mode" "DI")])
20366
20367 (define_insn "subv4hi3"
20368 [(set (match_operand:V4HI 0 "register_operand" "=y")
20369 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20370 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20371 "TARGET_MMX"
20372 "psubw\t{%2, %0|%0, %2}"
20373 [(set_attr "type" "mmxadd")
20374 (set_attr "mode" "DI")])
20375
20376 (define_insn "subv2si3"
20377 [(set (match_operand:V2SI 0 "register_operand" "=y")
20378 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20379 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20380 "TARGET_MMX"
20381 "psubd\t{%2, %0|%0, %2}"
20382 [(set_attr "type" "mmxadd")
20383 (set_attr "mode" "DI")])
20384
20385 (define_insn "mmx_subdi3"
20386 [(set (match_operand:DI 0 "register_operand" "=y")
20387 (unspec:DI
20388 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20389 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20390 UNSPEC_NOP))]
20391 "TARGET_MMX"
20392 "psubq\t{%2, %0|%0, %2}"
20393 [(set_attr "type" "mmxadd")
20394 (set_attr "mode" "DI")])
20395
20396 (define_insn "sssubv8qi3"
20397 [(set (match_operand:V8QI 0 "register_operand" "=y")
20398 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20399 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20400 "TARGET_MMX"
20401 "psubsb\t{%2, %0|%0, %2}"
20402 [(set_attr "type" "mmxadd")
20403 (set_attr "mode" "DI")])
20404
20405 (define_insn "sssubv4hi3"
20406 [(set (match_operand:V4HI 0 "register_operand" "=y")
20407 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20408 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20409 "TARGET_MMX"
20410 "psubsw\t{%2, %0|%0, %2}"
20411 [(set_attr "type" "mmxadd")
20412 (set_attr "mode" "DI")])
20413
20414 (define_insn "ussubv8qi3"
20415 [(set (match_operand:V8QI 0 "register_operand" "=y")
20416 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20417 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20418 "TARGET_MMX"
20419 "psubusb\t{%2, %0|%0, %2}"
20420 [(set_attr "type" "mmxadd")
20421 (set_attr "mode" "DI")])
20422
20423 (define_insn "ussubv4hi3"
20424 [(set (match_operand:V4HI 0 "register_operand" "=y")
20425 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20426 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20427 "TARGET_MMX"
20428 "psubusw\t{%2, %0|%0, %2}"
20429 [(set_attr "type" "mmxadd")
20430 (set_attr "mode" "DI")])
20431
20432 (define_insn "mulv4hi3"
20433 [(set (match_operand:V4HI 0 "register_operand" "=y")
20434 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20435 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20436 "TARGET_MMX"
20437 "pmullw\t{%2, %0|%0, %2}"
20438 [(set_attr "type" "mmxmul")
20439 (set_attr "mode" "DI")])
20440
20441 (define_insn "smulv4hi3_highpart"
20442 [(set (match_operand:V4HI 0 "register_operand" "=y")
20443 (truncate:V4HI
20444 (lshiftrt:V4SI
20445 (mult:V4SI (sign_extend:V4SI
20446 (match_operand:V4HI 1 "register_operand" "0"))
20447 (sign_extend:V4SI
20448 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20449 (const_int 16))))]
20450 "TARGET_MMX"
20451 "pmulhw\t{%2, %0|%0, %2}"
20452 [(set_attr "type" "mmxmul")
20453 (set_attr "mode" "DI")])
20454
20455 (define_insn "umulv4hi3_highpart"
20456 [(set (match_operand:V4HI 0 "register_operand" "=y")
20457 (truncate:V4HI
20458 (lshiftrt:V4SI
20459 (mult:V4SI (zero_extend:V4SI
20460 (match_operand:V4HI 1 "register_operand" "0"))
20461 (zero_extend:V4SI
20462 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20463 (const_int 16))))]
20464 "TARGET_SSE || TARGET_3DNOW_A"
20465 "pmulhuw\t{%2, %0|%0, %2}"
20466 [(set_attr "type" "mmxmul")
20467 (set_attr "mode" "DI")])
20468
20469 (define_insn "mmx_pmaddwd"
20470 [(set (match_operand:V2SI 0 "register_operand" "=y")
20471 (plus:V2SI
20472 (mult:V2SI
20473 (sign_extend:V2SI
20474 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20475 (parallel [(const_int 0) (const_int 2)])))
20476 (sign_extend:V2SI
20477 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20478 (parallel [(const_int 0) (const_int 2)]))))
20479 (mult:V2SI
20480 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20481 (parallel [(const_int 1)
20482 (const_int 3)])))
20483 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20484 (parallel [(const_int 1)
20485 (const_int 3)]))))))]
20486 "TARGET_MMX"
20487 "pmaddwd\t{%2, %0|%0, %2}"
20488 [(set_attr "type" "mmxmul")
20489 (set_attr "mode" "DI")])
20490
20491
20492 ;; MMX logical operations
20493 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20494 ;; normal code that also wants to use the FPU from getting broken.
20495 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20496 (define_insn "mmx_iordi3"
20497 [(set (match_operand:DI 0 "register_operand" "=y")
20498 (unspec:DI
20499 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20500 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20501 UNSPEC_NOP))]
20502 "TARGET_MMX"
20503 "por\t{%2, %0|%0, %2}"
20504 [(set_attr "type" "mmxadd")
20505 (set_attr "mode" "DI")])
20506
20507 (define_insn "mmx_xordi3"
20508 [(set (match_operand:DI 0 "register_operand" "=y")
20509 (unspec:DI
20510 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20511 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20512 UNSPEC_NOP))]
20513 "TARGET_MMX"
20514 "pxor\t{%2, %0|%0, %2}"
20515 [(set_attr "type" "mmxadd")
20516 (set_attr "mode" "DI")
20517 (set_attr "memory" "none")])
20518
20519 ;; Same as pxor, but don't show input operands so that we don't think
20520 ;; they are live.
20521 (define_insn "mmx_clrdi"
20522 [(set (match_operand:DI 0 "register_operand" "=y")
20523 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20524 "TARGET_MMX"
20525 "pxor\t{%0, %0|%0, %0}"
20526 [(set_attr "type" "mmxadd")
20527 (set_attr "mode" "DI")
20528 (set_attr "memory" "none")])
20529
20530 (define_insn "mmx_anddi3"
20531 [(set (match_operand:DI 0 "register_operand" "=y")
20532 (unspec:DI
20533 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20534 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20535 UNSPEC_NOP))]
20536 "TARGET_MMX"
20537 "pand\t{%2, %0|%0, %2}"
20538 [(set_attr "type" "mmxadd")
20539 (set_attr "mode" "DI")])
20540
20541 (define_insn "mmx_nanddi3"
20542 [(set (match_operand:DI 0 "register_operand" "=y")
20543 (unspec:DI
20544 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20545 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20546 UNSPEC_NOP))]
20547 "TARGET_MMX"
20548 "pandn\t{%2, %0|%0, %2}"
20549 [(set_attr "type" "mmxadd")
20550 (set_attr "mode" "DI")])
20551
20552
20553 ;; MMX unsigned averages/sum of absolute differences
20554
20555 (define_insn "mmx_uavgv8qi3"
20556 [(set (match_operand:V8QI 0 "register_operand" "=y")
20557 (ashiftrt:V8QI
20558 (plus:V8QI (plus:V8QI
20559 (match_operand:V8QI 1 "register_operand" "0")
20560 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20561 (const_vector:V8QI [(const_int 1)
20562 (const_int 1)
20563 (const_int 1)
20564 (const_int 1)
20565 (const_int 1)
20566 (const_int 1)
20567 (const_int 1)
20568 (const_int 1)]))
20569 (const_int 1)))]
20570 "TARGET_SSE || TARGET_3DNOW_A"
20571 "pavgb\t{%2, %0|%0, %2}"
20572 [(set_attr "type" "mmxshft")
20573 (set_attr "mode" "DI")])
20574
20575 (define_insn "mmx_uavgv4hi3"
20576 [(set (match_operand:V4HI 0 "register_operand" "=y")
20577 (ashiftrt:V4HI
20578 (plus:V4HI (plus:V4HI
20579 (match_operand:V4HI 1 "register_operand" "0")
20580 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20581 (const_vector:V4HI [(const_int 1)
20582 (const_int 1)
20583 (const_int 1)
20584 (const_int 1)]))
20585 (const_int 1)))]
20586 "TARGET_SSE || TARGET_3DNOW_A"
20587 "pavgw\t{%2, %0|%0, %2}"
20588 [(set_attr "type" "mmxshft")
20589 (set_attr "mode" "DI")])
20590
20591 (define_insn "mmx_psadbw"
20592 [(set (match_operand:DI 0 "register_operand" "=y")
20593 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20594 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20595 UNSPEC_PSADBW))]
20596 "TARGET_SSE || TARGET_3DNOW_A"
20597 "psadbw\t{%2, %0|%0, %2}"
20598 [(set_attr "type" "mmxshft")
20599 (set_attr "mode" "DI")])
20600
20601
20602 ;; MMX insert/extract/shuffle
20603
20604 (define_insn "mmx_pinsrw"
20605 [(set (match_operand:V4HI 0 "register_operand" "=y")
20606 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20607 (vec_duplicate:V4HI
20608 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20609 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20610 "TARGET_SSE || TARGET_3DNOW_A"
20611 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20612 [(set_attr "type" "mmxcvt")
20613 (set_attr "mode" "DI")])
20614
20615 (define_insn "mmx_pextrw"
20616 [(set (match_operand:SI 0 "register_operand" "=r")
20617 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20618 (parallel
20619 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20620 "TARGET_SSE || TARGET_3DNOW_A"
20621 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20622 [(set_attr "type" "mmxcvt")
20623 (set_attr "mode" "DI")])
20624
20625 (define_insn "mmx_pshufw"
20626 [(set (match_operand:V4HI 0 "register_operand" "=y")
20627 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
20628 (match_operand:SI 2 "immediate_operand" "i")]
20629 UNSPEC_SHUFFLE))]
20630 "TARGET_SSE || TARGET_3DNOW_A"
20631 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20632 [(set_attr "type" "mmxcvt")
20633 (set_attr "mode" "DI")])
20634
20635
20636 ;; MMX mask-generating comparisons
20637
20638 (define_insn "eqv8qi3"
20639 [(set (match_operand:V8QI 0 "register_operand" "=y")
20640 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20641 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20642 "TARGET_MMX"
20643 "pcmpeqb\t{%2, %0|%0, %2}"
20644 [(set_attr "type" "mmxcmp")
20645 (set_attr "mode" "DI")])
20646
20647 (define_insn "eqv4hi3"
20648 [(set (match_operand:V4HI 0 "register_operand" "=y")
20649 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20650 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20651 "TARGET_MMX"
20652 "pcmpeqw\t{%2, %0|%0, %2}"
20653 [(set_attr "type" "mmxcmp")
20654 (set_attr "mode" "DI")])
20655
20656 (define_insn "eqv2si3"
20657 [(set (match_operand:V2SI 0 "register_operand" "=y")
20658 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20659 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20660 "TARGET_MMX"
20661 "pcmpeqd\t{%2, %0|%0, %2}"
20662 [(set_attr "type" "mmxcmp")
20663 (set_attr "mode" "DI")])
20664
20665 (define_insn "gtv8qi3"
20666 [(set (match_operand:V8QI 0 "register_operand" "=y")
20667 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20668 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20669 "TARGET_MMX"
20670 "pcmpgtb\t{%2, %0|%0, %2}"
20671 [(set_attr "type" "mmxcmp")
20672 (set_attr "mode" "DI")])
20673
20674 (define_insn "gtv4hi3"
20675 [(set (match_operand:V4HI 0 "register_operand" "=y")
20676 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20677 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20678 "TARGET_MMX"
20679 "pcmpgtw\t{%2, %0|%0, %2}"
20680 [(set_attr "type" "mmxcmp")
20681 (set_attr "mode" "DI")])
20682
20683 (define_insn "gtv2si3"
20684 [(set (match_operand:V2SI 0 "register_operand" "=y")
20685 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20686 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20687 "TARGET_MMX"
20688 "pcmpgtd\t{%2, %0|%0, %2}"
20689 [(set_attr "type" "mmxcmp")
20690 (set_attr "mode" "DI")])
20691
20692
20693 ;; MMX max/min insns
20694
20695 (define_insn "umaxv8qi3"
20696 [(set (match_operand:V8QI 0 "register_operand" "=y")
20697 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20698 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20699 "TARGET_SSE || TARGET_3DNOW_A"
20700 "pmaxub\t{%2, %0|%0, %2}"
20701 [(set_attr "type" "mmxadd")
20702 (set_attr "mode" "DI")])
20703
20704 (define_insn "smaxv4hi3"
20705 [(set (match_operand:V4HI 0 "register_operand" "=y")
20706 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20707 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20708 "TARGET_SSE || TARGET_3DNOW_A"
20709 "pmaxsw\t{%2, %0|%0, %2}"
20710 [(set_attr "type" "mmxadd")
20711 (set_attr "mode" "DI")])
20712
20713 (define_insn "uminv8qi3"
20714 [(set (match_operand:V8QI 0 "register_operand" "=y")
20715 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20716 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20717 "TARGET_SSE || TARGET_3DNOW_A"
20718 "pminub\t{%2, %0|%0, %2}"
20719 [(set_attr "type" "mmxadd")
20720 (set_attr "mode" "DI")])
20721
20722 (define_insn "sminv4hi3"
20723 [(set (match_operand:V4HI 0 "register_operand" "=y")
20724 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20725 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20726 "TARGET_SSE || TARGET_3DNOW_A"
20727 "pminsw\t{%2, %0|%0, %2}"
20728 [(set_attr "type" "mmxadd")
20729 (set_attr "mode" "DI")])
20730
20731
20732 ;; MMX shifts
20733
20734 (define_insn "ashrv4hi3"
20735 [(set (match_operand:V4HI 0 "register_operand" "=y")
20736 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20737 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20738 "TARGET_MMX"
20739 "psraw\t{%2, %0|%0, %2}"
20740 [(set_attr "type" "mmxshft")
20741 (set_attr "mode" "DI")])
20742
20743 (define_insn "ashrv2si3"
20744 [(set (match_operand:V2SI 0 "register_operand" "=y")
20745 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20746 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20747 "TARGET_MMX"
20748 "psrad\t{%2, %0|%0, %2}"
20749 [(set_attr "type" "mmxshft")
20750 (set_attr "mode" "DI")])
20751
20752 (define_insn "lshrv4hi3"
20753 [(set (match_operand:V4HI 0 "register_operand" "=y")
20754 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20755 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20756 "TARGET_MMX"
20757 "psrlw\t{%2, %0|%0, %2}"
20758 [(set_attr "type" "mmxshft")
20759 (set_attr "mode" "DI")])
20760
20761 (define_insn "lshrv2si3"
20762 [(set (match_operand:V2SI 0 "register_operand" "=y")
20763 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20764 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20765 "TARGET_MMX"
20766 "psrld\t{%2, %0|%0, %2}"
20767 [(set_attr "type" "mmxshft")
20768 (set_attr "mode" "DI")])
20769
20770 ;; See logical MMX insns.
20771 (define_insn "mmx_lshrdi3"
20772 [(set (match_operand:DI 0 "register_operand" "=y")
20773 (unspec:DI
20774 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20775 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20776 UNSPEC_NOP))]
20777 "TARGET_MMX"
20778 "psrlq\t{%2, %0|%0, %2}"
20779 [(set_attr "type" "mmxshft")
20780 (set_attr "mode" "DI")])
20781
20782 (define_insn "ashlv4hi3"
20783 [(set (match_operand:V4HI 0 "register_operand" "=y")
20784 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20785 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20786 "TARGET_MMX"
20787 "psllw\t{%2, %0|%0, %2}"
20788 [(set_attr "type" "mmxshft")
20789 (set_attr "mode" "DI")])
20790
20791 (define_insn "ashlv2si3"
20792 [(set (match_operand:V2SI 0 "register_operand" "=y")
20793 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20794 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20795 "TARGET_MMX"
20796 "pslld\t{%2, %0|%0, %2}"
20797 [(set_attr "type" "mmxshft")
20798 (set_attr "mode" "DI")])
20799
20800 ;; See logical MMX insns.
20801 (define_insn "mmx_ashldi3"
20802 [(set (match_operand:DI 0 "register_operand" "=y")
20803 (unspec:DI
20804 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20805 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20806 UNSPEC_NOP))]
20807 "TARGET_MMX"
20808 "psllq\t{%2, %0|%0, %2}"
20809 [(set_attr "type" "mmxshft")
20810 (set_attr "mode" "DI")])
20811
20812
20813 ;; MMX pack/unpack insns.
20814
20815 (define_insn "mmx_packsswb"
20816 [(set (match_operand:V8QI 0 "register_operand" "=y")
20817 (vec_concat:V8QI
20818 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20819 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20820 "TARGET_MMX"
20821 "packsswb\t{%2, %0|%0, %2}"
20822 [(set_attr "type" "mmxshft")
20823 (set_attr "mode" "DI")])
20824
20825 (define_insn "mmx_packssdw"
20826 [(set (match_operand:V4HI 0 "register_operand" "=y")
20827 (vec_concat:V4HI
20828 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20829 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20830 "TARGET_MMX"
20831 "packssdw\t{%2, %0|%0, %2}"
20832 [(set_attr "type" "mmxshft")
20833 (set_attr "mode" "DI")])
20834
20835 (define_insn "mmx_packuswb"
20836 [(set (match_operand:V8QI 0 "register_operand" "=y")
20837 (vec_concat:V8QI
20838 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20839 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20840 "TARGET_MMX"
20841 "packuswb\t{%2, %0|%0, %2}"
20842 [(set_attr "type" "mmxshft")
20843 (set_attr "mode" "DI")])
20844
20845 (define_insn "mmx_punpckhbw"
20846 [(set (match_operand:V8QI 0 "register_operand" "=y")
20847 (vec_merge:V8QI
20848 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20849 (parallel [(const_int 4)
20850 (const_int 0)
20851 (const_int 5)
20852 (const_int 1)
20853 (const_int 6)
20854 (const_int 2)
20855 (const_int 7)
20856 (const_int 3)]))
20857 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20858 (parallel [(const_int 0)
20859 (const_int 4)
20860 (const_int 1)
20861 (const_int 5)
20862 (const_int 2)
20863 (const_int 6)
20864 (const_int 3)
20865 (const_int 7)]))
20866 (const_int 85)))]
20867 "TARGET_MMX"
20868 "punpckhbw\t{%2, %0|%0, %2}"
20869 [(set_attr "type" "mmxcvt")
20870 (set_attr "mode" "DI")])
20871
20872 (define_insn "mmx_punpckhwd"
20873 [(set (match_operand:V4HI 0 "register_operand" "=y")
20874 (vec_merge:V4HI
20875 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20876 (parallel [(const_int 0)
20877 (const_int 2)
20878 (const_int 1)
20879 (const_int 3)]))
20880 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20881 (parallel [(const_int 2)
20882 (const_int 0)
20883 (const_int 3)
20884 (const_int 1)]))
20885 (const_int 5)))]
20886 "TARGET_MMX"
20887 "punpckhwd\t{%2, %0|%0, %2}"
20888 [(set_attr "type" "mmxcvt")
20889 (set_attr "mode" "DI")])
20890
20891 (define_insn "mmx_punpckhdq"
20892 [(set (match_operand:V2SI 0 "register_operand" "=y")
20893 (vec_merge:V2SI
20894 (match_operand:V2SI 1 "register_operand" "0")
20895 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20896 (parallel [(const_int 1)
20897 (const_int 0)]))
20898 (const_int 1)))]
20899 "TARGET_MMX"
20900 "punpckhdq\t{%2, %0|%0, %2}"
20901 [(set_attr "type" "mmxcvt")
20902 (set_attr "mode" "DI")])
20903
20904 (define_insn "mmx_punpcklbw"
20905 [(set (match_operand:V8QI 0 "register_operand" "=y")
20906 (vec_merge:V8QI
20907 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20908 (parallel [(const_int 0)
20909 (const_int 4)
20910 (const_int 1)
20911 (const_int 5)
20912 (const_int 2)
20913 (const_int 6)
20914 (const_int 3)
20915 (const_int 7)]))
20916 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20917 (parallel [(const_int 4)
20918 (const_int 0)
20919 (const_int 5)
20920 (const_int 1)
20921 (const_int 6)
20922 (const_int 2)
20923 (const_int 7)
20924 (const_int 3)]))
20925 (const_int 85)))]
20926 "TARGET_MMX"
20927 "punpcklbw\t{%2, %0|%0, %2}"
20928 [(set_attr "type" "mmxcvt")
20929 (set_attr "mode" "DI")])
20930
20931 (define_insn "mmx_punpcklwd"
20932 [(set (match_operand:V4HI 0 "register_operand" "=y")
20933 (vec_merge:V4HI
20934 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20935 (parallel [(const_int 2)
20936 (const_int 0)
20937 (const_int 3)
20938 (const_int 1)]))
20939 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20940 (parallel [(const_int 0)
20941 (const_int 2)
20942 (const_int 1)
20943 (const_int 3)]))
20944 (const_int 5)))]
20945 "TARGET_MMX"
20946 "punpcklwd\t{%2, %0|%0, %2}"
20947 [(set_attr "type" "mmxcvt")
20948 (set_attr "mode" "DI")])
20949
20950 (define_insn "mmx_punpckldq"
20951 [(set (match_operand:V2SI 0 "register_operand" "=y")
20952 (vec_merge:V2SI
20953 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20954 (parallel [(const_int 1)
20955 (const_int 0)]))
20956 (match_operand:V2SI 2 "register_operand" "y")
20957 (const_int 1)))]
20958 "TARGET_MMX"
20959 "punpckldq\t{%2, %0|%0, %2}"
20960 [(set_attr "type" "mmxcvt")
20961 (set_attr "mode" "DI")])
20962
20963
20964 ;; Miscellaneous stuff
20965
20966 (define_insn "emms"
20967 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20968 (clobber (reg:XF 8))
20969 (clobber (reg:XF 9))
20970 (clobber (reg:XF 10))
20971 (clobber (reg:XF 11))
20972 (clobber (reg:XF 12))
20973 (clobber (reg:XF 13))
20974 (clobber (reg:XF 14))
20975 (clobber (reg:XF 15))
20976 (clobber (reg:DI 29))
20977 (clobber (reg:DI 30))
20978 (clobber (reg:DI 31))
20979 (clobber (reg:DI 32))
20980 (clobber (reg:DI 33))
20981 (clobber (reg:DI 34))
20982 (clobber (reg:DI 35))
20983 (clobber (reg:DI 36))]
20984 "TARGET_MMX"
20985 "emms"
20986 [(set_attr "type" "mmx")
20987 (set_attr "memory" "unknown")])
20988
20989 (define_insn "ldmxcsr"
20990 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20991 UNSPECV_LDMXCSR)]
20992 "TARGET_SSE"
20993 "ldmxcsr\t%0"
20994 [(set_attr "type" "sse")
20995 (set_attr "memory" "load")])
20996
20997 (define_insn "stmxcsr"
20998 [(set (match_operand:SI 0 "memory_operand" "=m")
20999 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21000 "TARGET_SSE"
21001 "stmxcsr\t%0"
21002 [(set_attr "type" "sse")
21003 (set_attr "memory" "store")])
21004
21005 (define_expand "sfence"
21006 [(set (match_dup 0)
21007 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21008 "TARGET_SSE || TARGET_3DNOW_A"
21009 {
21010 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21011 MEM_VOLATILE_P (operands[0]) = 1;
21012 })
21013
21014 (define_insn "*sfence_insn"
21015 [(set (match_operand:BLK 0 "" "")
21016 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21017 "TARGET_SSE || TARGET_3DNOW_A"
21018 "sfence"
21019 [(set_attr "type" "sse")
21020 (set_attr "memory" "unknown")])
21021
21022 (define_expand "sse_prologue_save"
21023 [(parallel [(set (match_operand:BLK 0 "" "")
21024 (unspec:BLK [(reg:DI 21)
21025 (reg:DI 22)
21026 (reg:DI 23)
21027 (reg:DI 24)
21028 (reg:DI 25)
21029 (reg:DI 26)
21030 (reg:DI 27)
21031 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21032 (use (match_operand:DI 1 "register_operand" ""))
21033 (use (match_operand:DI 2 "immediate_operand" ""))
21034 (use (label_ref:DI (match_operand 3 "" "")))])]
21035 "TARGET_64BIT"
21036 "")
21037
21038 (define_insn "*sse_prologue_save_insn"
21039 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21040 (match_operand:DI 4 "const_int_operand" "n")))
21041 (unspec:BLK [(reg:DI 21)
21042 (reg:DI 22)
21043 (reg:DI 23)
21044 (reg:DI 24)
21045 (reg:DI 25)
21046 (reg:DI 26)
21047 (reg:DI 27)
21048 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21049 (use (match_operand:DI 1 "register_operand" "r"))
21050 (use (match_operand:DI 2 "const_int_operand" "i"))
21051 (use (label_ref:DI (match_operand 3 "" "X")))]
21052 "TARGET_64BIT
21053 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21054 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21055 "*
21056 {
21057 int i;
21058 operands[0] = gen_rtx_MEM (Pmode,
21059 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21060 output_asm_insn (\"jmp\\t%A1\", operands);
21061 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21062 {
21063 operands[4] = adjust_address (operands[0], DImode, i*16);
21064 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21065 PUT_MODE (operands[4], TImode);
21066 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21067 output_asm_insn (\"rex\", operands);
21068 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21069 }
21070 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21071 CODE_LABEL_NUMBER (operands[3]));
21072 RET;
21073 }
21074 "
21075 [(set_attr "type" "other")
21076 (set_attr "length_immediate" "0")
21077 (set_attr "length_address" "0")
21078 (set_attr "length" "135")
21079 (set_attr "memory" "store")
21080 (set_attr "modrm" "0")
21081 (set_attr "mode" "DI")])
21082
21083 ;; 3Dnow! instructions
21084
21085 (define_insn "addv2sf3"
21086 [(set (match_operand:V2SF 0 "register_operand" "=y")
21087 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21088 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21089 "TARGET_3DNOW"
21090 "pfadd\\t{%2, %0|%0, %2}"
21091 [(set_attr "type" "mmxadd")
21092 (set_attr "mode" "V2SF")])
21093
21094 (define_insn "subv2sf3"
21095 [(set (match_operand:V2SF 0 "register_operand" "=y")
21096 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21097 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21098 "TARGET_3DNOW"
21099 "pfsub\\t{%2, %0|%0, %2}"
21100 [(set_attr "type" "mmxadd")
21101 (set_attr "mode" "V2SF")])
21102
21103 (define_insn "subrv2sf3"
21104 [(set (match_operand:V2SF 0 "register_operand" "=y")
21105 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21106 (match_operand:V2SF 1 "register_operand" "0")))]
21107 "TARGET_3DNOW"
21108 "pfsubr\\t{%2, %0|%0, %2}"
21109 [(set_attr "type" "mmxadd")
21110 (set_attr "mode" "V2SF")])
21111
21112 (define_insn "gtv2sf3"
21113 [(set (match_operand:V2SI 0 "register_operand" "=y")
21114 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21115 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21116 "TARGET_3DNOW"
21117 "pfcmpgt\\t{%2, %0|%0, %2}"
21118 [(set_attr "type" "mmxcmp")
21119 (set_attr "mode" "V2SF")])
21120
21121 (define_insn "gev2sf3"
21122 [(set (match_operand:V2SI 0 "register_operand" "=y")
21123 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21124 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21125 "TARGET_3DNOW"
21126 "pfcmpge\\t{%2, %0|%0, %2}"
21127 [(set_attr "type" "mmxcmp")
21128 (set_attr "mode" "V2SF")])
21129
21130 (define_insn "eqv2sf3"
21131 [(set (match_operand:V2SI 0 "register_operand" "=y")
21132 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21133 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21134 "TARGET_3DNOW"
21135 "pfcmpeq\\t{%2, %0|%0, %2}"
21136 [(set_attr "type" "mmxcmp")
21137 (set_attr "mode" "V2SF")])
21138
21139 (define_insn "pfmaxv2sf3"
21140 [(set (match_operand:V2SF 0 "register_operand" "=y")
21141 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21142 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21143 "TARGET_3DNOW"
21144 "pfmax\\t{%2, %0|%0, %2}"
21145 [(set_attr "type" "mmxadd")
21146 (set_attr "mode" "V2SF")])
21147
21148 (define_insn "pfminv2sf3"
21149 [(set (match_operand:V2SF 0 "register_operand" "=y")
21150 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21151 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21152 "TARGET_3DNOW"
21153 "pfmin\\t{%2, %0|%0, %2}"
21154 [(set_attr "type" "mmxadd")
21155 (set_attr "mode" "V2SF")])
21156
21157 (define_insn "mulv2sf3"
21158 [(set (match_operand:V2SF 0 "register_operand" "=y")
21159 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21160 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21161 "TARGET_3DNOW"
21162 "pfmul\\t{%2, %0|%0, %2}"
21163 [(set_attr "type" "mmxmul")
21164 (set_attr "mode" "V2SF")])
21165
21166 (define_insn "femms"
21167 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21168 (clobber (reg:XF 8))
21169 (clobber (reg:XF 9))
21170 (clobber (reg:XF 10))
21171 (clobber (reg:XF 11))
21172 (clobber (reg:XF 12))
21173 (clobber (reg:XF 13))
21174 (clobber (reg:XF 14))
21175 (clobber (reg:XF 15))
21176 (clobber (reg:DI 29))
21177 (clobber (reg:DI 30))
21178 (clobber (reg:DI 31))
21179 (clobber (reg:DI 32))
21180 (clobber (reg:DI 33))
21181 (clobber (reg:DI 34))
21182 (clobber (reg:DI 35))
21183 (clobber (reg:DI 36))]
21184 "TARGET_3DNOW"
21185 "femms"
21186 [(set_attr "type" "mmx")
21187 (set_attr "memory" "none")])
21188
21189 (define_insn "pf2id"
21190 [(set (match_operand:V2SI 0 "register_operand" "=y")
21191 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21192 "TARGET_3DNOW"
21193 "pf2id\\t{%1, %0|%0, %1}"
21194 [(set_attr "type" "mmxcvt")
21195 (set_attr "mode" "V2SF")])
21196
21197 (define_insn "pf2iw"
21198 [(set (match_operand:V2SI 0 "register_operand" "=y")
21199 (sign_extend:V2SI
21200 (ss_truncate:V2HI
21201 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21202 "TARGET_3DNOW_A"
21203 "pf2iw\\t{%1, %0|%0, %1}"
21204 [(set_attr "type" "mmxcvt")
21205 (set_attr "mode" "V2SF")])
21206
21207 (define_insn "pfacc"
21208 [(set (match_operand:V2SF 0 "register_operand" "=y")
21209 (vec_concat:V2SF
21210 (plus:SF
21211 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21212 (parallel [(const_int 0)]))
21213 (vec_select:SF (match_dup 1)
21214 (parallel [(const_int 1)])))
21215 (plus:SF
21216 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21217 (parallel [(const_int 0)]))
21218 (vec_select:SF (match_dup 2)
21219 (parallel [(const_int 1)])))))]
21220 "TARGET_3DNOW"
21221 "pfacc\\t{%2, %0|%0, %2}"
21222 [(set_attr "type" "mmxadd")
21223 (set_attr "mode" "V2SF")])
21224
21225 (define_insn "pfnacc"
21226 [(set (match_operand:V2SF 0 "register_operand" "=y")
21227 (vec_concat:V2SF
21228 (minus:SF
21229 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21230 (parallel [(const_int 0)]))
21231 (vec_select:SF (match_dup 1)
21232 (parallel [(const_int 1)])))
21233 (minus:SF
21234 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21235 (parallel [(const_int 0)]))
21236 (vec_select:SF (match_dup 2)
21237 (parallel [(const_int 1)])))))]
21238 "TARGET_3DNOW_A"
21239 "pfnacc\\t{%2, %0|%0, %2}"
21240 [(set_attr "type" "mmxadd")
21241 (set_attr "mode" "V2SF")])
21242
21243 (define_insn "pfpnacc"
21244 [(set (match_operand:V2SF 0 "register_operand" "=y")
21245 (vec_concat:V2SF
21246 (minus:SF
21247 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21248 (parallel [(const_int 0)]))
21249 (vec_select:SF (match_dup 1)
21250 (parallel [(const_int 1)])))
21251 (plus:SF
21252 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21253 (parallel [(const_int 0)]))
21254 (vec_select:SF (match_dup 2)
21255 (parallel [(const_int 1)])))))]
21256 "TARGET_3DNOW_A"
21257 "pfpnacc\\t{%2, %0|%0, %2}"
21258 [(set_attr "type" "mmxadd")
21259 (set_attr "mode" "V2SF")])
21260
21261 (define_insn "pi2fw"
21262 [(set (match_operand:V2SF 0 "register_operand" "=y")
21263 (float:V2SF
21264 (vec_concat:V2SI
21265 (sign_extend:SI
21266 (truncate:HI
21267 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21268 (parallel [(const_int 0)]))))
21269 (sign_extend:SI
21270 (truncate:HI
21271 (vec_select:SI (match_dup 1)
21272 (parallel [(const_int 1)])))))))]
21273 "TARGET_3DNOW_A"
21274 "pi2fw\\t{%1, %0|%0, %1}"
21275 [(set_attr "type" "mmxcvt")
21276 (set_attr "mode" "V2SF")])
21277
21278 (define_insn "floatv2si2"
21279 [(set (match_operand:V2SF 0 "register_operand" "=y")
21280 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21281 "TARGET_3DNOW"
21282 "pi2fd\\t{%1, %0|%0, %1}"
21283 [(set_attr "type" "mmxcvt")
21284 (set_attr "mode" "V2SF")])
21285
21286 ;; This insn is identical to pavgb in operation, but the opcode is
21287 ;; different. To avoid accidentally matching pavgb, use an unspec.
21288
21289 (define_insn "pavgusb"
21290 [(set (match_operand:V8QI 0 "register_operand" "=y")
21291 (unspec:V8QI
21292 [(match_operand:V8QI 1 "register_operand" "0")
21293 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21294 UNSPEC_PAVGUSB))]
21295 "TARGET_3DNOW"
21296 "pavgusb\\t{%2, %0|%0, %2}"
21297 [(set_attr "type" "mmxshft")
21298 (set_attr "mode" "TI")])
21299
21300 ;; 3DNow reciprocal and sqrt
21301
21302 (define_insn "pfrcpv2sf2"
21303 [(set (match_operand:V2SF 0 "register_operand" "=y")
21304 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21305 UNSPEC_PFRCP))]
21306 "TARGET_3DNOW"
21307 "pfrcp\\t{%1, %0|%0, %1}"
21308 [(set_attr "type" "mmx")
21309 (set_attr "mode" "TI")])
21310
21311 (define_insn "pfrcpit1v2sf3"
21312 [(set (match_operand:V2SF 0 "register_operand" "=y")
21313 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21314 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21315 UNSPEC_PFRCPIT1))]
21316 "TARGET_3DNOW"
21317 "pfrcpit1\\t{%2, %0|%0, %2}"
21318 [(set_attr "type" "mmx")
21319 (set_attr "mode" "TI")])
21320
21321 (define_insn "pfrcpit2v2sf3"
21322 [(set (match_operand:V2SF 0 "register_operand" "=y")
21323 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21324 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21325 UNSPEC_PFRCPIT2))]
21326 "TARGET_3DNOW"
21327 "pfrcpit2\\t{%2, %0|%0, %2}"
21328 [(set_attr "type" "mmx")
21329 (set_attr "mode" "TI")])
21330
21331 (define_insn "pfrsqrtv2sf2"
21332 [(set (match_operand:V2SF 0 "register_operand" "=y")
21333 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21334 UNSPEC_PFRSQRT))]
21335 "TARGET_3DNOW"
21336 "pfrsqrt\\t{%1, %0|%0, %1}"
21337 [(set_attr "type" "mmx")
21338 (set_attr "mode" "TI")])
21339
21340 (define_insn "pfrsqit1v2sf3"
21341 [(set (match_operand:V2SF 0 "register_operand" "=y")
21342 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21343 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21344 UNSPEC_PFRSQIT1))]
21345 "TARGET_3DNOW"
21346 "pfrsqit1\\t{%2, %0|%0, %2}"
21347 [(set_attr "type" "mmx")
21348 (set_attr "mode" "TI")])
21349
21350 (define_insn "pmulhrwv4hi3"
21351 [(set (match_operand:V4HI 0 "register_operand" "=y")
21352 (truncate:V4HI
21353 (lshiftrt:V4SI
21354 (plus:V4SI
21355 (mult:V4SI
21356 (sign_extend:V4SI
21357 (match_operand:V4HI 1 "register_operand" "0"))
21358 (sign_extend:V4SI
21359 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21360 (const_vector:V4SI [(const_int 32768)
21361 (const_int 32768)
21362 (const_int 32768)
21363 (const_int 32768)]))
21364 (const_int 16))))]
21365 "TARGET_3DNOW"
21366 "pmulhrw\\t{%2, %0|%0, %2}"
21367 [(set_attr "type" "mmxmul")
21368 (set_attr "mode" "TI")])
21369
21370 (define_insn "pswapdv2si2"
21371 [(set (match_operand:V2SI 0 "register_operand" "=y")
21372 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21373 (parallel [(const_int 1) (const_int 0)])))]
21374 "TARGET_3DNOW_A"
21375 "pswapd\\t{%1, %0|%0, %1}"
21376 [(set_attr "type" "mmxcvt")
21377 (set_attr "mode" "TI")])
21378
21379 (define_insn "pswapdv2sf2"
21380 [(set (match_operand:V2SF 0 "register_operand" "=y")
21381 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21382 (parallel [(const_int 1) (const_int 0)])))]
21383 "TARGET_3DNOW_A"
21384 "pswapd\\t{%1, %0|%0, %1}"
21385 [(set_attr "type" "mmxcvt")
21386 (set_attr "mode" "TI")])
21387
21388 (define_expand "prefetch"
21389 [(prefetch (match_operand 0 "address_operand" "")
21390 (match_operand:SI 1 "const_int_operand" "")
21391 (match_operand:SI 2 "const_int_operand" ""))]
21392 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21393 {
21394 int rw = INTVAL (operands[1]);
21395 int locality = INTVAL (operands[2]);
21396
21397 if (rw != 0 && rw != 1)
21398 abort ();
21399 if (locality < 0 || locality > 3)
21400 abort ();
21401 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21402 abort ();
21403
21404 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21405 suported by SSE counterpart or the SSE prefetch is not available
21406 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21407 of locality. */
21408 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21409 operands[2] = GEN_INT (3);
21410 else
21411 operands[1] = const0_rtx;
21412 })
21413
21414 (define_insn "*prefetch_sse"
21415 [(prefetch (match_operand:SI 0 "address_operand" "p")
21416 (const_int 0)
21417 (match_operand:SI 1 "const_int_operand" ""))]
21418 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21419 {
21420 static const char * const patterns[4] = {
21421 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21422 };
21423
21424 int locality = INTVAL (operands[1]);
21425 if (locality < 0 || locality > 3)
21426 abort ();
21427
21428 return patterns[locality];
21429 }
21430 [(set_attr "type" "sse")
21431 (set_attr "memory" "none")])
21432
21433 (define_insn "*prefetch_sse_rex"
21434 [(prefetch (match_operand:DI 0 "address_operand" "p")
21435 (const_int 0)
21436 (match_operand:SI 1 "const_int_operand" ""))]
21437 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21438 {
21439 static const char * const patterns[4] = {
21440 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21441 };
21442
21443 int locality = INTVAL (operands[1]);
21444 if (locality < 0 || locality > 3)
21445 abort ();
21446
21447 return patterns[locality];
21448 }
21449 [(set_attr "type" "sse")
21450 (set_attr "memory" "none")])
21451
21452 (define_insn "*prefetch_3dnow"
21453 [(prefetch (match_operand:SI 0 "address_operand" "p")
21454 (match_operand:SI 1 "const_int_operand" "n")
21455 (const_int 3))]
21456 "TARGET_3DNOW && !TARGET_64BIT"
21457 {
21458 if (INTVAL (operands[1]) == 0)
21459 return "prefetch\t%a0";
21460 else
21461 return "prefetchw\t%a0";
21462 }
21463 [(set_attr "type" "mmx")
21464 (set_attr "memory" "none")])
21465
21466 (define_insn "*prefetch_3dnow_rex"
21467 [(prefetch (match_operand:DI 0 "address_operand" "p")
21468 (match_operand:SI 1 "const_int_operand" "n")
21469 (const_int 3))]
21470 "TARGET_3DNOW && TARGET_64BIT"
21471 {
21472 if (INTVAL (operands[1]) == 0)
21473 return "prefetch\t%a0";
21474 else
21475 return "prefetchw\t%a0";
21476 }
21477 [(set_attr "type" "mmx")
21478 (set_attr "memory" "none")])
21479
21480 ;; SSE2 support
21481
21482 (define_insn "addv2df3"
21483 [(set (match_operand:V2DF 0 "register_operand" "=x")
21484 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21485 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21486 "TARGET_SSE2"
21487 "addpd\t{%2, %0|%0, %2}"
21488 [(set_attr "type" "sseadd")
21489 (set_attr "mode" "V2DF")])
21490
21491 (define_insn "vmaddv2df3"
21492 [(set (match_operand:V2DF 0 "register_operand" "=x")
21493 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21494 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21495 (match_dup 1)
21496 (const_int 1)))]
21497 "TARGET_SSE2"
21498 "addsd\t{%2, %0|%0, %2}"
21499 [(set_attr "type" "sseadd")
21500 (set_attr "mode" "DF")])
21501
21502 (define_insn "subv2df3"
21503 [(set (match_operand:V2DF 0 "register_operand" "=x")
21504 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21505 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21506 "TARGET_SSE2"
21507 "subpd\t{%2, %0|%0, %2}"
21508 [(set_attr "type" "sseadd")
21509 (set_attr "mode" "V2DF")])
21510
21511 (define_insn "vmsubv2df3"
21512 [(set (match_operand:V2DF 0 "register_operand" "=x")
21513 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21514 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21515 (match_dup 1)
21516 (const_int 1)))]
21517 "TARGET_SSE2"
21518 "subsd\t{%2, %0|%0, %2}"
21519 [(set_attr "type" "sseadd")
21520 (set_attr "mode" "DF")])
21521
21522 (define_insn "mulv2df3"
21523 [(set (match_operand:V2DF 0 "register_operand" "=x")
21524 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21525 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21526 "TARGET_SSE2"
21527 "mulpd\t{%2, %0|%0, %2}"
21528 [(set_attr "type" "ssemul")
21529 (set_attr "mode" "V2DF")])
21530
21531 (define_insn "vmmulv2df3"
21532 [(set (match_operand:V2DF 0 "register_operand" "=x")
21533 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21534 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21535 (match_dup 1)
21536 (const_int 1)))]
21537 "TARGET_SSE2"
21538 "mulsd\t{%2, %0|%0, %2}"
21539 [(set_attr "type" "ssemul")
21540 (set_attr "mode" "DF")])
21541
21542 (define_insn "divv2df3"
21543 [(set (match_operand:V2DF 0 "register_operand" "=x")
21544 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21545 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21546 "TARGET_SSE2"
21547 "divpd\t{%2, %0|%0, %2}"
21548 [(set_attr "type" "ssediv")
21549 (set_attr "mode" "V2DF")])
21550
21551 (define_insn "vmdivv2df3"
21552 [(set (match_operand:V2DF 0 "register_operand" "=x")
21553 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21554 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21555 (match_dup 1)
21556 (const_int 1)))]
21557 "TARGET_SSE2"
21558 "divsd\t{%2, %0|%0, %2}"
21559 [(set_attr "type" "ssediv")
21560 (set_attr "mode" "DF")])
21561
21562 ;; SSE min/max
21563
21564 (define_insn "smaxv2df3"
21565 [(set (match_operand:V2DF 0 "register_operand" "=x")
21566 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21567 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21568 "TARGET_SSE2"
21569 "maxpd\t{%2, %0|%0, %2}"
21570 [(set_attr "type" "sseadd")
21571 (set_attr "mode" "V2DF")])
21572
21573 (define_insn "vmsmaxv2df3"
21574 [(set (match_operand:V2DF 0 "register_operand" "=x")
21575 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21576 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21577 (match_dup 1)
21578 (const_int 1)))]
21579 "TARGET_SSE2"
21580 "maxsd\t{%2, %0|%0, %2}"
21581 [(set_attr "type" "sseadd")
21582 (set_attr "mode" "DF")])
21583
21584 (define_insn "sminv2df3"
21585 [(set (match_operand:V2DF 0 "register_operand" "=x")
21586 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21587 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21588 "TARGET_SSE2"
21589 "minpd\t{%2, %0|%0, %2}"
21590 [(set_attr "type" "sseadd")
21591 (set_attr "mode" "V2DF")])
21592
21593 (define_insn "vmsminv2df3"
21594 [(set (match_operand:V2DF 0 "register_operand" "=x")
21595 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21596 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21597 (match_dup 1)
21598 (const_int 1)))]
21599 "TARGET_SSE2"
21600 "minsd\t{%2, %0|%0, %2}"
21601 [(set_attr "type" "sseadd")
21602 (set_attr "mode" "DF")])
21603 ;; SSE2 square root. There doesn't appear to be an extension for the
21604 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21605
21606 (define_insn "sqrtv2df2"
21607 [(set (match_operand:V2DF 0 "register_operand" "=x")
21608 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21609 "TARGET_SSE2"
21610 "sqrtpd\t{%1, %0|%0, %1}"
21611 [(set_attr "type" "sse")
21612 (set_attr "mode" "V2DF")])
21613
21614 (define_insn "vmsqrtv2df2"
21615 [(set (match_operand:V2DF 0 "register_operand" "=x")
21616 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21617 (match_operand:V2DF 2 "register_operand" "0")
21618 (const_int 1)))]
21619 "TARGET_SSE2"
21620 "sqrtsd\t{%1, %0|%0, %1}"
21621 [(set_attr "type" "sse")
21622 (set_attr "mode" "SF")])
21623
21624 ;; SSE mask-generating compares
21625
21626 (define_insn "maskcmpv2df3"
21627 [(set (match_operand:V2DI 0 "register_operand" "=x")
21628 (match_operator:V2DI 3 "sse_comparison_operator"
21629 [(match_operand:V2DF 1 "register_operand" "0")
21630 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21631 "TARGET_SSE2"
21632 "cmp%D3pd\t{%2, %0|%0, %2}"
21633 [(set_attr "type" "ssecmp")
21634 (set_attr "mode" "V2DF")])
21635
21636 (define_insn "maskncmpv2df3"
21637 [(set (match_operand:V2DI 0 "register_operand" "=x")
21638 (not:V2DI
21639 (match_operator:V2DI 3 "sse_comparison_operator"
21640 [(match_operand:V2DF 1 "register_operand" "0")
21641 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21642 "TARGET_SSE2"
21643 {
21644 if (GET_CODE (operands[3]) == UNORDERED)
21645 return "cmpordps\t{%2, %0|%0, %2}";
21646 else
21647 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21648 }
21649 [(set_attr "type" "ssecmp")
21650 (set_attr "mode" "V2DF")])
21651
21652 (define_insn "vmmaskcmpv2df3"
21653 [(set (match_operand:V2DI 0 "register_operand" "=x")
21654 (vec_merge:V2DI
21655 (match_operator:V2DI 3 "sse_comparison_operator"
21656 [(match_operand:V2DF 1 "register_operand" "0")
21657 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21658 (subreg:V2DI (match_dup 1) 0)
21659 (const_int 1)))]
21660 "TARGET_SSE2"
21661 "cmp%D3sd\t{%2, %0|%0, %2}"
21662 [(set_attr "type" "ssecmp")
21663 (set_attr "mode" "DF")])
21664
21665 (define_insn "vmmaskncmpv2df3"
21666 [(set (match_operand:V2DI 0 "register_operand" "=x")
21667 (vec_merge:V2DI
21668 (not:V2DI
21669 (match_operator:V2DI 3 "sse_comparison_operator"
21670 [(match_operand:V2DF 1 "register_operand" "0")
21671 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21672 (subreg:V2DI (match_dup 1) 0)
21673 (const_int 1)))]
21674 "TARGET_SSE2"
21675 {
21676 if (GET_CODE (operands[3]) == UNORDERED)
21677 return "cmpordsd\t{%2, %0|%0, %2}";
21678 else
21679 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21680 }
21681 [(set_attr "type" "ssecmp")
21682 (set_attr "mode" "DF")])
21683
21684 (define_insn "sse2_comi"
21685 [(set (reg:CCFP 17)
21686 (compare:CCFP (vec_select:DF
21687 (match_operand:V2DF 0 "register_operand" "x")
21688 (parallel [(const_int 0)]))
21689 (vec_select:DF
21690 (match_operand:V2DF 1 "register_operand" "x")
21691 (parallel [(const_int 0)]))))]
21692 "TARGET_SSE2"
21693 "comisd\t{%1, %0|%0, %1}"
21694 [(set_attr "type" "ssecomi")
21695 (set_attr "mode" "DF")])
21696
21697 (define_insn "sse2_ucomi"
21698 [(set (reg:CCFPU 17)
21699 (compare:CCFPU (vec_select:DF
21700 (match_operand:V2DF 0 "register_operand" "x")
21701 (parallel [(const_int 0)]))
21702 (vec_select:DF
21703 (match_operand:V2DF 1 "register_operand" "x")
21704 (parallel [(const_int 0)]))))]
21705 "TARGET_SSE2"
21706 "ucomisd\t{%1, %0|%0, %1}"
21707 [(set_attr "type" "ssecomi")
21708 (set_attr "mode" "DF")])
21709
21710 ;; SSE Strange Moves.
21711
21712 (define_insn "sse2_movmskpd"
21713 [(set (match_operand:SI 0 "register_operand" "=r")
21714 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21715 UNSPEC_MOVMSK))]
21716 "TARGET_SSE2"
21717 "movmskpd\t{%1, %0|%0, %1}"
21718 [(set_attr "type" "ssecvt")
21719 (set_attr "mode" "V2DF")])
21720
21721 (define_insn "sse2_pmovmskb"
21722 [(set (match_operand:SI 0 "register_operand" "=r")
21723 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21724 UNSPEC_MOVMSK))]
21725 "TARGET_SSE2"
21726 "pmovmskb\t{%1, %0|%0, %1}"
21727 [(set_attr "type" "ssecvt")
21728 (set_attr "mode" "V2DF")])
21729
21730 (define_insn "sse2_maskmovdqu"
21731 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21732 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21733 (match_operand:V16QI 2 "register_operand" "x")]
21734 UNSPEC_MASKMOV))]
21735 "TARGET_SSE2"
21736 ;; @@@ check ordering of operands in intel/nonintel syntax
21737 "maskmovdqu\t{%2, %1|%1, %2}"
21738 [(set_attr "type" "ssecvt")
21739 (set_attr "mode" "TI")])
21740
21741 (define_insn "sse2_maskmovdqu_rex64"
21742 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21743 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21744 (match_operand:V16QI 2 "register_operand" "x")]
21745 UNSPEC_MASKMOV))]
21746 "TARGET_SSE2"
21747 ;; @@@ check ordering of operands in intel/nonintel syntax
21748 "maskmovdqu\t{%2, %1|%1, %2}"
21749 [(set_attr "type" "ssecvt")
21750 (set_attr "mode" "TI")])
21751
21752 (define_insn "sse2_movntv2df"
21753 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21754 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21755 UNSPEC_MOVNT))]
21756 "TARGET_SSE2"
21757 "movntpd\t{%1, %0|%0, %1}"
21758 [(set_attr "type" "ssecvt")
21759 (set_attr "mode" "V2DF")])
21760
21761 (define_insn "sse2_movntv2di"
21762 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21763 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21764 UNSPEC_MOVNT))]
21765 "TARGET_SSE2"
21766 "movntdq\t{%1, %0|%0, %1}"
21767 [(set_attr "type" "ssecvt")
21768 (set_attr "mode" "TI")])
21769
21770 (define_insn "sse2_movntsi"
21771 [(set (match_operand:SI 0 "memory_operand" "=m")
21772 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21773 UNSPEC_MOVNT))]
21774 "TARGET_SSE2"
21775 "movnti\t{%1, %0|%0, %1}"
21776 [(set_attr "type" "ssecvt")
21777 (set_attr "mode" "V2DF")])
21778
21779 ;; SSE <-> integer/MMX conversions
21780
21781 ;; Conversions between SI and SF
21782
21783 (define_insn "cvtdq2ps"
21784 [(set (match_operand:V4SF 0 "register_operand" "=x")
21785 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21786 "TARGET_SSE2"
21787 "cvtdq2ps\t{%1, %0|%0, %1}"
21788 [(set_attr "type" "ssecvt")
21789 (set_attr "mode" "V2DF")])
21790
21791 (define_insn "cvtps2dq"
21792 [(set (match_operand:V4SI 0 "register_operand" "=x")
21793 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21794 "TARGET_SSE2"
21795 "cvtps2dq\t{%1, %0|%0, %1}"
21796 [(set_attr "type" "ssecvt")
21797 (set_attr "mode" "TI")])
21798
21799 (define_insn "cvttps2dq"
21800 [(set (match_operand:V4SI 0 "register_operand" "=x")
21801 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21802 UNSPEC_FIX))]
21803 "TARGET_SSE2"
21804 "cvttps2dq\t{%1, %0|%0, %1}"
21805 [(set_attr "type" "ssecvt")
21806 (set_attr "mode" "TI")])
21807
21808 ;; Conversions between SI and DF
21809
21810 (define_insn "cvtdq2pd"
21811 [(set (match_operand:V2DF 0 "register_operand" "=x")
21812 (float:V2DF (vec_select:V2SI
21813 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21814 (parallel
21815 [(const_int 0)
21816 (const_int 1)]))))]
21817 "TARGET_SSE2"
21818 "cvtdq2pd\t{%1, %0|%0, %1}"
21819 [(set_attr "type" "ssecvt")
21820 (set_attr "mode" "V2DF")])
21821
21822 (define_insn "cvtpd2dq"
21823 [(set (match_operand:V4SI 0 "register_operand" "=x")
21824 (vec_concat:V4SI
21825 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21826 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21827 "TARGET_SSE2"
21828 "cvtpd2dq\t{%1, %0|%0, %1}"
21829 [(set_attr "type" "ssecvt")
21830 (set_attr "mode" "TI")])
21831
21832 (define_insn "cvttpd2dq"
21833 [(set (match_operand:V4SI 0 "register_operand" "=x")
21834 (vec_concat:V4SI
21835 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21836 UNSPEC_FIX)
21837 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21838 "TARGET_SSE2"
21839 "cvttpd2dq\t{%1, %0|%0, %1}"
21840 [(set_attr "type" "ssecvt")
21841 (set_attr "mode" "TI")])
21842
21843 (define_insn "cvtpd2pi"
21844 [(set (match_operand:V2SI 0 "register_operand" "=y")
21845 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21846 "TARGET_SSE2"
21847 "cvtpd2pi\t{%1, %0|%0, %1}"
21848 [(set_attr "type" "ssecvt")
21849 (set_attr "mode" "TI")])
21850
21851 (define_insn "cvttpd2pi"
21852 [(set (match_operand:V2SI 0 "register_operand" "=y")
21853 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21854 UNSPEC_FIX))]
21855 "TARGET_SSE2"
21856 "cvttpd2pi\t{%1, %0|%0, %1}"
21857 [(set_attr "type" "ssecvt")
21858 (set_attr "mode" "TI")])
21859
21860 (define_insn "cvtpi2pd"
21861 [(set (match_operand:V2DF 0 "register_operand" "=x")
21862 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21863 "TARGET_SSE2"
21864 "cvtpi2pd\t{%1, %0|%0, %1}"
21865 [(set_attr "type" "ssecvt")
21866 (set_attr "mode" "TI")])
21867
21868 ;; Conversions between SI and DF
21869
21870 (define_insn "cvtsd2si"
21871 [(set (match_operand:SI 0 "register_operand" "=r,r")
21872 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21873 (parallel [(const_int 0)]))))]
21874 "TARGET_SSE2"
21875 "cvtsd2si\t{%1, %0|%0, %1}"
21876 [(set_attr "type" "sseicvt")
21877 (set_attr "athlon_decode" "double,vector")
21878 (set_attr "mode" "SI")])
21879
21880 (define_insn "cvtsd2siq"
21881 [(set (match_operand:DI 0 "register_operand" "=r,r")
21882 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21883 (parallel [(const_int 0)]))))]
21884 "TARGET_SSE2 && TARGET_64BIT"
21885 "cvtsd2siq\t{%1, %0|%0, %1}"
21886 [(set_attr "type" "sseicvt")
21887 (set_attr "athlon_decode" "double,vector")
21888 (set_attr "mode" "DI")])
21889
21890 (define_insn "cvttsd2si"
21891 [(set (match_operand:SI 0 "register_operand" "=r,r")
21892 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21893 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21894 "TARGET_SSE2"
21895 "cvttsd2si\t{%1, %0|%0, %1}"
21896 [(set_attr "type" "sseicvt")
21897 (set_attr "mode" "SI")
21898 (set_attr "athlon_decode" "double,vector")])
21899
21900 (define_insn "cvttsd2siq"
21901 [(set (match_operand:DI 0 "register_operand" "=r,r")
21902 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21903 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21904 "TARGET_SSE2 && TARGET_64BIT"
21905 "cvttsd2siq\t{%1, %0|%0, %1}"
21906 [(set_attr "type" "sseicvt")
21907 (set_attr "mode" "DI")
21908 (set_attr "athlon_decode" "double,vector")])
21909
21910 (define_insn "cvtsi2sd"
21911 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21912 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21913 (vec_duplicate:V2DF
21914 (float:DF
21915 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21916 (const_int 2)))]
21917 "TARGET_SSE2"
21918 "cvtsi2sd\t{%2, %0|%0, %2}"
21919 [(set_attr "type" "sseicvt")
21920 (set_attr "mode" "DF")
21921 (set_attr "athlon_decode" "double,direct")])
21922
21923 (define_insn "cvtsi2sdq"
21924 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21925 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21926 (vec_duplicate:V2DF
21927 (float:DF
21928 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21929 (const_int 2)))]
21930 "TARGET_SSE2 && TARGET_64BIT"
21931 "cvtsi2sdq\t{%2, %0|%0, %2}"
21932 [(set_attr "type" "sseicvt")
21933 (set_attr "mode" "DF")
21934 (set_attr "athlon_decode" "double,direct")])
21935
21936 ;; Conversions between SF and DF
21937
21938 (define_insn "cvtsd2ss"
21939 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21940 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21941 (vec_duplicate:V4SF
21942 (float_truncate:V2SF
21943 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21944 (const_int 14)))]
21945 "TARGET_SSE2"
21946 "cvtsd2ss\t{%2, %0|%0, %2}"
21947 [(set_attr "type" "ssecvt")
21948 (set_attr "athlon_decode" "vector,double")
21949 (set_attr "mode" "SF")])
21950
21951 (define_insn "cvtss2sd"
21952 [(set (match_operand:V2DF 0 "register_operand" "=x")
21953 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21954 (float_extend:V2DF
21955 (vec_select:V2SF
21956 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21957 (parallel [(const_int 0)
21958 (const_int 1)])))
21959 (const_int 2)))]
21960 "TARGET_SSE2"
21961 "cvtss2sd\t{%2, %0|%0, %2}"
21962 [(set_attr "type" "ssecvt")
21963 (set_attr "mode" "DF")])
21964
21965 (define_insn "cvtpd2ps"
21966 [(set (match_operand:V4SF 0 "register_operand" "=x")
21967 (subreg:V4SF
21968 (vec_concat:V4SI
21969 (subreg:V2SI (float_truncate:V2SF
21970 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21971 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21972 "TARGET_SSE2"
21973 "cvtpd2ps\t{%1, %0|%0, %1}"
21974 [(set_attr "type" "ssecvt")
21975 (set_attr "mode" "V4SF")])
21976
21977 (define_insn "cvtps2pd"
21978 [(set (match_operand:V2DF 0 "register_operand" "=x")
21979 (float_extend:V2DF
21980 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21981 (parallel [(const_int 0)
21982 (const_int 1)]))))]
21983 "TARGET_SSE2"
21984 "cvtps2pd\t{%1, %0|%0, %1}"
21985 [(set_attr "type" "ssecvt")
21986 (set_attr "mode" "V2DF")])
21987
21988 ;; SSE2 variants of MMX insns
21989
21990 ;; MMX arithmetic
21991
21992 (define_insn "addv16qi3"
21993 [(set (match_operand:V16QI 0 "register_operand" "=x")
21994 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21995 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21996 "TARGET_SSE2"
21997 "paddb\t{%2, %0|%0, %2}"
21998 [(set_attr "type" "sseiadd")
21999 (set_attr "mode" "TI")])
22000
22001 (define_insn "addv8hi3"
22002 [(set (match_operand:V8HI 0 "register_operand" "=x")
22003 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22004 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22005 "TARGET_SSE2"
22006 "paddw\t{%2, %0|%0, %2}"
22007 [(set_attr "type" "sseiadd")
22008 (set_attr "mode" "TI")])
22009
22010 (define_insn "addv4si3"
22011 [(set (match_operand:V4SI 0 "register_operand" "=x")
22012 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22013 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22014 "TARGET_SSE2"
22015 "paddd\t{%2, %0|%0, %2}"
22016 [(set_attr "type" "sseiadd")
22017 (set_attr "mode" "TI")])
22018
22019 (define_insn "addv2di3"
22020 [(set (match_operand:V2DI 0 "register_operand" "=x")
22021 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22022 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22023 "TARGET_SSE2"
22024 "paddq\t{%2, %0|%0, %2}"
22025 [(set_attr "type" "sseiadd")
22026 (set_attr "mode" "TI")])
22027
22028 (define_insn "ssaddv16qi3"
22029 [(set (match_operand:V16QI 0 "register_operand" "=x")
22030 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22031 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22032 "TARGET_SSE2"
22033 "paddsb\t{%2, %0|%0, %2}"
22034 [(set_attr "type" "sseiadd")
22035 (set_attr "mode" "TI")])
22036
22037 (define_insn "ssaddv8hi3"
22038 [(set (match_operand:V8HI 0 "register_operand" "=x")
22039 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22040 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22041 "TARGET_SSE2"
22042 "paddsw\t{%2, %0|%0, %2}"
22043 [(set_attr "type" "sseiadd")
22044 (set_attr "mode" "TI")])
22045
22046 (define_insn "usaddv16qi3"
22047 [(set (match_operand:V16QI 0 "register_operand" "=x")
22048 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22049 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22050 "TARGET_SSE2"
22051 "paddusb\t{%2, %0|%0, %2}"
22052 [(set_attr "type" "sseiadd")
22053 (set_attr "mode" "TI")])
22054
22055 (define_insn "usaddv8hi3"
22056 [(set (match_operand:V8HI 0 "register_operand" "=x")
22057 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22058 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22059 "TARGET_SSE2"
22060 "paddusw\t{%2, %0|%0, %2}"
22061 [(set_attr "type" "sseiadd")
22062 (set_attr "mode" "TI")])
22063
22064 (define_insn "subv16qi3"
22065 [(set (match_operand:V16QI 0 "register_operand" "=x")
22066 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22067 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22068 "TARGET_SSE2"
22069 "psubb\t{%2, %0|%0, %2}"
22070 [(set_attr "type" "sseiadd")
22071 (set_attr "mode" "TI")])
22072
22073 (define_insn "subv8hi3"
22074 [(set (match_operand:V8HI 0 "register_operand" "=x")
22075 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22076 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22077 "TARGET_SSE2"
22078 "psubw\t{%2, %0|%0, %2}"
22079 [(set_attr "type" "sseiadd")
22080 (set_attr "mode" "TI")])
22081
22082 (define_insn "subv4si3"
22083 [(set (match_operand:V4SI 0 "register_operand" "=x")
22084 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22085 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22086 "TARGET_SSE2"
22087 "psubd\t{%2, %0|%0, %2}"
22088 [(set_attr "type" "sseiadd")
22089 (set_attr "mode" "TI")])
22090
22091 (define_insn "subv2di3"
22092 [(set (match_operand:V2DI 0 "register_operand" "=x")
22093 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22094 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22095 "TARGET_SSE2"
22096 "psubq\t{%2, %0|%0, %2}"
22097 [(set_attr "type" "sseiadd")
22098 (set_attr "mode" "TI")])
22099
22100 (define_insn "sssubv16qi3"
22101 [(set (match_operand:V16QI 0 "register_operand" "=x")
22102 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22103 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22104 "TARGET_SSE2"
22105 "psubsb\t{%2, %0|%0, %2}"
22106 [(set_attr "type" "sseiadd")
22107 (set_attr "mode" "TI")])
22108
22109 (define_insn "sssubv8hi3"
22110 [(set (match_operand:V8HI 0 "register_operand" "=x")
22111 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22112 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22113 "TARGET_SSE2"
22114 "psubsw\t{%2, %0|%0, %2}"
22115 [(set_attr "type" "sseiadd")
22116 (set_attr "mode" "TI")])
22117
22118 (define_insn "ussubv16qi3"
22119 [(set (match_operand:V16QI 0 "register_operand" "=x")
22120 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22121 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22122 "TARGET_SSE2"
22123 "psubusb\t{%2, %0|%0, %2}"
22124 [(set_attr "type" "sseiadd")
22125 (set_attr "mode" "TI")])
22126
22127 (define_insn "ussubv8hi3"
22128 [(set (match_operand:V8HI 0 "register_operand" "=x")
22129 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22130 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22131 "TARGET_SSE2"
22132 "psubusw\t{%2, %0|%0, %2}"
22133 [(set_attr "type" "sseiadd")
22134 (set_attr "mode" "TI")])
22135
22136 (define_insn "mulv8hi3"
22137 [(set (match_operand:V8HI 0 "register_operand" "=x")
22138 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22139 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22140 "TARGET_SSE2"
22141 "pmullw\t{%2, %0|%0, %2}"
22142 [(set_attr "type" "sseimul")
22143 (set_attr "mode" "TI")])
22144
22145 (define_insn "smulv8hi3_highpart"
22146 [(set (match_operand:V8HI 0 "register_operand" "=x")
22147 (truncate:V8HI
22148 (lshiftrt:V8SI
22149 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22150 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22151 (const_int 16))))]
22152 "TARGET_SSE2"
22153 "pmulhw\t{%2, %0|%0, %2}"
22154 [(set_attr "type" "sseimul")
22155 (set_attr "mode" "TI")])
22156
22157 (define_insn "umulv8hi3_highpart"
22158 [(set (match_operand:V8HI 0 "register_operand" "=x")
22159 (truncate:V8HI
22160 (lshiftrt:V8SI
22161 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22162 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22163 (const_int 16))))]
22164 "TARGET_SSE2"
22165 "pmulhuw\t{%2, %0|%0, %2}"
22166 [(set_attr "type" "sseimul")
22167 (set_attr "mode" "TI")])
22168
22169 (define_insn "sse2_umulsidi3"
22170 [(set (match_operand:DI 0 "register_operand" "=y")
22171 (mult:DI (zero_extend:DI (vec_select:SI
22172 (match_operand:V2SI 1 "register_operand" "0")
22173 (parallel [(const_int 0)])))
22174 (zero_extend:DI (vec_select:SI
22175 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22176 (parallel [(const_int 0)])))))]
22177 "TARGET_SSE2"
22178 "pmuludq\t{%2, %0|%0, %2}"
22179 [(set_attr "type" "sseimul")
22180 (set_attr "mode" "TI")])
22181
22182 (define_insn "sse2_umulv2siv2di3"
22183 [(set (match_operand:V2DI 0 "register_operand" "=x")
22184 (mult:V2DI (zero_extend:V2DI
22185 (vec_select:V2SI
22186 (match_operand:V4SI 1 "register_operand" "0")
22187 (parallel [(const_int 0) (const_int 2)])))
22188 (zero_extend:V2DI
22189 (vec_select:V2SI
22190 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22191 (parallel [(const_int 0) (const_int 2)])))))]
22192 "TARGET_SSE2"
22193 "pmuludq\t{%2, %0|%0, %2}"
22194 [(set_attr "type" "sseimul")
22195 (set_attr "mode" "TI")])
22196
22197 (define_insn "sse2_pmaddwd"
22198 [(set (match_operand:V4SI 0 "register_operand" "=x")
22199 (plus:V4SI
22200 (mult:V4SI
22201 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22202 (parallel [(const_int 0)
22203 (const_int 2)
22204 (const_int 4)
22205 (const_int 6)])))
22206 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22207 (parallel [(const_int 0)
22208 (const_int 2)
22209 (const_int 4)
22210 (const_int 6)]))))
22211 (mult:V4SI
22212 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22213 (parallel [(const_int 1)
22214 (const_int 3)
22215 (const_int 5)
22216 (const_int 7)])))
22217 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22218 (parallel [(const_int 1)
22219 (const_int 3)
22220 (const_int 5)
22221 (const_int 7)]))))))]
22222 "TARGET_SSE2"
22223 "pmaddwd\t{%2, %0|%0, %2}"
22224 [(set_attr "type" "sseiadd")
22225 (set_attr "mode" "TI")])
22226
22227 ;; Same as pxor, but don't show input operands so that we don't think
22228 ;; they are live.
22229 (define_insn "sse2_clrti"
22230 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22231 "TARGET_SSE2"
22232 {
22233 if (get_attr_mode (insn) == MODE_TI)
22234 return "pxor\t%0, %0";
22235 else
22236 return "xorps\t%0, %0";
22237 }
22238 [(set_attr "type" "ssemov")
22239 (set_attr "memory" "none")
22240 (set (attr "mode")
22241 (if_then_else
22242 (ne (symbol_ref "optimize_size")
22243 (const_int 0))
22244 (const_string "V4SF")
22245 (const_string "TI")))])
22246
22247 ;; MMX unsigned averages/sum of absolute differences
22248
22249 (define_insn "sse2_uavgv16qi3"
22250 [(set (match_operand:V16QI 0 "register_operand" "=x")
22251 (ashiftrt:V16QI
22252 (plus:V16QI (plus:V16QI
22253 (match_operand:V16QI 1 "register_operand" "0")
22254 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22255 (const_vector:V16QI [(const_int 1) (const_int 1)
22256 (const_int 1) (const_int 1)
22257 (const_int 1) (const_int 1)
22258 (const_int 1) (const_int 1)
22259 (const_int 1) (const_int 1)
22260 (const_int 1) (const_int 1)
22261 (const_int 1) (const_int 1)
22262 (const_int 1) (const_int 1)]))
22263 (const_int 1)))]
22264 "TARGET_SSE2"
22265 "pavgb\t{%2, %0|%0, %2}"
22266 [(set_attr "type" "sseiadd")
22267 (set_attr "mode" "TI")])
22268
22269 (define_insn "sse2_uavgv8hi3"
22270 [(set (match_operand:V8HI 0 "register_operand" "=x")
22271 (ashiftrt:V8HI
22272 (plus:V8HI (plus:V8HI
22273 (match_operand:V8HI 1 "register_operand" "0")
22274 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22275 (const_vector:V8HI [(const_int 1) (const_int 1)
22276 (const_int 1) (const_int 1)
22277 (const_int 1) (const_int 1)
22278 (const_int 1) (const_int 1)]))
22279 (const_int 1)))]
22280 "TARGET_SSE2"
22281 "pavgw\t{%2, %0|%0, %2}"
22282 [(set_attr "type" "sseiadd")
22283 (set_attr "mode" "TI")])
22284
22285 ;; @@@ this isn't the right representation.
22286 (define_insn "sse2_psadbw"
22287 [(set (match_operand:V2DI 0 "register_operand" "=x")
22288 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22289 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22290 UNSPEC_PSADBW))]
22291 "TARGET_SSE2"
22292 "psadbw\t{%2, %0|%0, %2}"
22293 [(set_attr "type" "sseiadd")
22294 (set_attr "mode" "TI")])
22295
22296
22297 ;; MMX insert/extract/shuffle
22298
22299 (define_insn "sse2_pinsrw"
22300 [(set (match_operand:V8HI 0 "register_operand" "=x")
22301 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22302 (vec_duplicate:V8HI
22303 (truncate:HI
22304 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22305 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22306 "TARGET_SSE2"
22307 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22308 [(set_attr "type" "ssecvt")
22309 (set_attr "mode" "TI")])
22310
22311 (define_insn "sse2_pextrw"
22312 [(set (match_operand:SI 0 "register_operand" "=r")
22313 (zero_extend:SI
22314 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22315 (parallel
22316 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22317 "TARGET_SSE2"
22318 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22319 [(set_attr "type" "ssecvt")
22320 (set_attr "mode" "TI")])
22321
22322 (define_insn "sse2_pshufd"
22323 [(set (match_operand:V4SI 0 "register_operand" "=x")
22324 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
22325 (match_operand:SI 2 "immediate_operand" "i")]
22326 UNSPEC_SHUFFLE))]
22327 "TARGET_SSE2"
22328 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22329 [(set_attr "type" "ssecvt")
22330 (set_attr "mode" "TI")])
22331
22332 (define_insn "sse2_pshuflw"
22333 [(set (match_operand:V8HI 0 "register_operand" "=x")
22334 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
22335 (match_operand:SI 2 "immediate_operand" "i")]
22336 UNSPEC_PSHUFLW))]
22337 "TARGET_SSE2"
22338 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22339 [(set_attr "type" "ssecvt")
22340 (set_attr "mode" "TI")])
22341
22342 (define_insn "sse2_pshufhw"
22343 [(set (match_operand:V8HI 0 "register_operand" "=x")
22344 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
22345 (match_operand:SI 2 "immediate_operand" "i")]
22346 UNSPEC_PSHUFHW))]
22347 "TARGET_SSE2"
22348 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22349 [(set_attr "type" "ssecvt")
22350 (set_attr "mode" "TI")])
22351
22352 ;; MMX mask-generating comparisons
22353
22354 (define_insn "eqv16qi3"
22355 [(set (match_operand:V16QI 0 "register_operand" "=x")
22356 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22357 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22358 "TARGET_SSE2"
22359 "pcmpeqb\t{%2, %0|%0, %2}"
22360 [(set_attr "type" "ssecmp")
22361 (set_attr "mode" "TI")])
22362
22363 (define_insn "eqv8hi3"
22364 [(set (match_operand:V8HI 0 "register_operand" "=x")
22365 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22366 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22367 "TARGET_SSE2"
22368 "pcmpeqw\t{%2, %0|%0, %2}"
22369 [(set_attr "type" "ssecmp")
22370 (set_attr "mode" "TI")])
22371
22372 (define_insn "eqv4si3"
22373 [(set (match_operand:V4SI 0 "register_operand" "=x")
22374 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22375 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22376 "TARGET_SSE2"
22377 "pcmpeqd\t{%2, %0|%0, %2}"
22378 [(set_attr "type" "ssecmp")
22379 (set_attr "mode" "TI")])
22380
22381 (define_insn "gtv16qi3"
22382 [(set (match_operand:V16QI 0 "register_operand" "=x")
22383 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22384 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22385 "TARGET_SSE2"
22386 "pcmpgtb\t{%2, %0|%0, %2}"
22387 [(set_attr "type" "ssecmp")
22388 (set_attr "mode" "TI")])
22389
22390 (define_insn "gtv8hi3"
22391 [(set (match_operand:V8HI 0 "register_operand" "=x")
22392 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22393 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22394 "TARGET_SSE2"
22395 "pcmpgtw\t{%2, %0|%0, %2}"
22396 [(set_attr "type" "ssecmp")
22397 (set_attr "mode" "TI")])
22398
22399 (define_insn "gtv4si3"
22400 [(set (match_operand:V4SI 0 "register_operand" "=x")
22401 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22402 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22403 "TARGET_SSE2"
22404 "pcmpgtd\t{%2, %0|%0, %2}"
22405 [(set_attr "type" "ssecmp")
22406 (set_attr "mode" "TI")])
22407
22408
22409 ;; MMX max/min insns
22410
22411 (define_insn "umaxv16qi3"
22412 [(set (match_operand:V16QI 0 "register_operand" "=x")
22413 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22414 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22415 "TARGET_SSE2"
22416 "pmaxub\t{%2, %0|%0, %2}"
22417 [(set_attr "type" "sseiadd")
22418 (set_attr "mode" "TI")])
22419
22420 (define_insn "smaxv8hi3"
22421 [(set (match_operand:V8HI 0 "register_operand" "=x")
22422 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22423 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22424 "TARGET_SSE2"
22425 "pmaxsw\t{%2, %0|%0, %2}"
22426 [(set_attr "type" "sseiadd")
22427 (set_attr "mode" "TI")])
22428
22429 (define_insn "uminv16qi3"
22430 [(set (match_operand:V16QI 0 "register_operand" "=x")
22431 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22432 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22433 "TARGET_SSE2"
22434 "pminub\t{%2, %0|%0, %2}"
22435 [(set_attr "type" "sseiadd")
22436 (set_attr "mode" "TI")])
22437
22438 (define_insn "sminv8hi3"
22439 [(set (match_operand:V8HI 0 "register_operand" "=x")
22440 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22441 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22442 "TARGET_SSE2"
22443 "pminsw\t{%2, %0|%0, %2}"
22444 [(set_attr "type" "sseiadd")
22445 (set_attr "mode" "TI")])
22446
22447
22448 ;; MMX shifts
22449
22450 (define_insn "ashrv8hi3"
22451 [(set (match_operand:V8HI 0 "register_operand" "=x")
22452 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22453 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22454 "TARGET_SSE2"
22455 "psraw\t{%2, %0|%0, %2}"
22456 [(set_attr "type" "sseishft")
22457 (set_attr "mode" "TI")])
22458
22459 (define_insn "ashrv4si3"
22460 [(set (match_operand:V4SI 0 "register_operand" "=x")
22461 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22462 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22463 "TARGET_SSE2"
22464 "psrad\t{%2, %0|%0, %2}"
22465 [(set_attr "type" "sseishft")
22466 (set_attr "mode" "TI")])
22467
22468 (define_insn "lshrv8hi3"
22469 [(set (match_operand:V8HI 0 "register_operand" "=x")
22470 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22471 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22472 "TARGET_SSE2"
22473 "psrlw\t{%2, %0|%0, %2}"
22474 [(set_attr "type" "sseishft")
22475 (set_attr "mode" "TI")])
22476
22477 (define_insn "lshrv4si3"
22478 [(set (match_operand:V4SI 0 "register_operand" "=x")
22479 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22480 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22481 "TARGET_SSE2"
22482 "psrld\t{%2, %0|%0, %2}"
22483 [(set_attr "type" "sseishft")
22484 (set_attr "mode" "TI")])
22485
22486 (define_insn "lshrv2di3"
22487 [(set (match_operand:V2DI 0 "register_operand" "=x")
22488 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22489 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22490 "TARGET_SSE2"
22491 "psrlq\t{%2, %0|%0, %2}"
22492 [(set_attr "type" "sseishft")
22493 (set_attr "mode" "TI")])
22494
22495 (define_insn "ashlv8hi3"
22496 [(set (match_operand:V8HI 0 "register_operand" "=x")
22497 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22498 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22499 "TARGET_SSE2"
22500 "psllw\t{%2, %0|%0, %2}"
22501 [(set_attr "type" "sseishft")
22502 (set_attr "mode" "TI")])
22503
22504 (define_insn "ashlv4si3"
22505 [(set (match_operand:V4SI 0 "register_operand" "=x")
22506 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22507 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22508 "TARGET_SSE2"
22509 "pslld\t{%2, %0|%0, %2}"
22510 [(set_attr "type" "sseishft")
22511 (set_attr "mode" "TI")])
22512
22513 (define_insn "ashlv2di3"
22514 [(set (match_operand:V2DI 0 "register_operand" "=x")
22515 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22516 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22517 "TARGET_SSE2"
22518 "psllq\t{%2, %0|%0, %2}"
22519 [(set_attr "type" "sseishft")
22520 (set_attr "mode" "TI")])
22521
22522 (define_insn "ashrv8hi3_ti"
22523 [(set (match_operand:V8HI 0 "register_operand" "=x")
22524 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22525 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22526 "TARGET_SSE2"
22527 "psraw\t{%2, %0|%0, %2}"
22528 [(set_attr "type" "sseishft")
22529 (set_attr "mode" "TI")])
22530
22531 (define_insn "ashrv4si3_ti"
22532 [(set (match_operand:V4SI 0 "register_operand" "=x")
22533 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22534 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22535 "TARGET_SSE2"
22536 "psrad\t{%2, %0|%0, %2}"
22537 [(set_attr "type" "sseishft")
22538 (set_attr "mode" "TI")])
22539
22540 (define_insn "lshrv8hi3_ti"
22541 [(set (match_operand:V8HI 0 "register_operand" "=x")
22542 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22543 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22544 "TARGET_SSE2"
22545 "psrlw\t{%2, %0|%0, %2}"
22546 [(set_attr "type" "sseishft")
22547 (set_attr "mode" "TI")])
22548
22549 (define_insn "lshrv4si3_ti"
22550 [(set (match_operand:V4SI 0 "register_operand" "=x")
22551 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22552 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22553 "TARGET_SSE2"
22554 "psrld\t{%2, %0|%0, %2}"
22555 [(set_attr "type" "sseishft")
22556 (set_attr "mode" "TI")])
22557
22558 (define_insn "lshrv2di3_ti"
22559 [(set (match_operand:V2DI 0 "register_operand" "=x")
22560 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22561 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22562 "TARGET_SSE2"
22563 "psrlq\t{%2, %0|%0, %2}"
22564 [(set_attr "type" "sseishft")
22565 (set_attr "mode" "TI")])
22566
22567 (define_insn "ashlv8hi3_ti"
22568 [(set (match_operand:V8HI 0 "register_operand" "=x")
22569 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22570 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22571 "TARGET_SSE2"
22572 "psllw\t{%2, %0|%0, %2}"
22573 [(set_attr "type" "sseishft")
22574 (set_attr "mode" "TI")])
22575
22576 (define_insn "ashlv4si3_ti"
22577 [(set (match_operand:V4SI 0 "register_operand" "=x")
22578 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22579 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22580 "TARGET_SSE2"
22581 "pslld\t{%2, %0|%0, %2}"
22582 [(set_attr "type" "sseishft")
22583 (set_attr "mode" "TI")])
22584
22585 (define_insn "ashlv2di3_ti"
22586 [(set (match_operand:V2DI 0 "register_operand" "=x")
22587 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22588 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22589 "TARGET_SSE2"
22590 "psllq\t{%2, %0|%0, %2}"
22591 [(set_attr "type" "sseishft")
22592 (set_attr "mode" "TI")])
22593
22594 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22595 ;; we wouldn't need here it since we never generate TImode arithmetic.
22596
22597 ;; There has to be some kind of prize for the weirdest new instruction...
22598 (define_insn "sse2_ashlti3"
22599 [(set (match_operand:TI 0 "register_operand" "=x")
22600 (unspec:TI
22601 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22602 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22603 (const_int 8)))] UNSPEC_NOP))]
22604 "TARGET_SSE2"
22605 "pslldq\t{%2, %0|%0, %2}"
22606 [(set_attr "type" "sseishft")
22607 (set_attr "mode" "TI")])
22608
22609 (define_insn "sse2_lshrti3"
22610 [(set (match_operand:TI 0 "register_operand" "=x")
22611 (unspec:TI
22612 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22613 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22614 (const_int 8)))] UNSPEC_NOP))]
22615 "TARGET_SSE2"
22616 "psrldq\t{%2, %0|%0, %2}"
22617 [(set_attr "type" "sseishft")
22618 (set_attr "mode" "TI")])
22619
22620 ;; SSE unpack
22621
22622 (define_insn "sse2_unpckhpd"
22623 [(set (match_operand:V2DF 0 "register_operand" "=x")
22624 (vec_concat:V2DF
22625 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22626 (parallel [(const_int 1)]))
22627 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22628 (parallel [(const_int 1)]))))]
22629 "TARGET_SSE2"
22630 "unpckhpd\t{%2, %0|%0, %2}"
22631 [(set_attr "type" "ssecvt")
22632 (set_attr "mode" "V2DF")])
22633
22634 (define_insn "sse2_unpcklpd"
22635 [(set (match_operand:V2DF 0 "register_operand" "=x")
22636 (vec_concat:V2DF
22637 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22638 (parallel [(const_int 0)]))
22639 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22640 (parallel [(const_int 0)]))))]
22641 "TARGET_SSE2"
22642 "unpcklpd\t{%2, %0|%0, %2}"
22643 [(set_attr "type" "ssecvt")
22644 (set_attr "mode" "V2DF")])
22645
22646 ;; MMX pack/unpack insns.
22647
22648 (define_insn "sse2_packsswb"
22649 [(set (match_operand:V16QI 0 "register_operand" "=x")
22650 (vec_concat:V16QI
22651 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22652 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22653 "TARGET_SSE2"
22654 "packsswb\t{%2, %0|%0, %2}"
22655 [(set_attr "type" "ssecvt")
22656 (set_attr "mode" "TI")])
22657
22658 (define_insn "sse2_packssdw"
22659 [(set (match_operand:V8HI 0 "register_operand" "=x")
22660 (vec_concat:V8HI
22661 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22662 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22663 "TARGET_SSE2"
22664 "packssdw\t{%2, %0|%0, %2}"
22665 [(set_attr "type" "ssecvt")
22666 (set_attr "mode" "TI")])
22667
22668 (define_insn "sse2_packuswb"
22669 [(set (match_operand:V16QI 0 "register_operand" "=x")
22670 (vec_concat:V16QI
22671 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22672 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22673 "TARGET_SSE2"
22674 "packuswb\t{%2, %0|%0, %2}"
22675 [(set_attr "type" "ssecvt")
22676 (set_attr "mode" "TI")])
22677
22678 (define_insn "sse2_punpckhbw"
22679 [(set (match_operand:V16QI 0 "register_operand" "=x")
22680 (vec_merge:V16QI
22681 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22682 (parallel [(const_int 8) (const_int 0)
22683 (const_int 9) (const_int 1)
22684 (const_int 10) (const_int 2)
22685 (const_int 11) (const_int 3)
22686 (const_int 12) (const_int 4)
22687 (const_int 13) (const_int 5)
22688 (const_int 14) (const_int 6)
22689 (const_int 15) (const_int 7)]))
22690 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22691 (parallel [(const_int 0) (const_int 8)
22692 (const_int 1) (const_int 9)
22693 (const_int 2) (const_int 10)
22694 (const_int 3) (const_int 11)
22695 (const_int 4) (const_int 12)
22696 (const_int 5) (const_int 13)
22697 (const_int 6) (const_int 14)
22698 (const_int 7) (const_int 15)]))
22699 (const_int 21845)))]
22700 "TARGET_SSE2"
22701 "punpckhbw\t{%2, %0|%0, %2}"
22702 [(set_attr "type" "ssecvt")
22703 (set_attr "mode" "TI")])
22704
22705 (define_insn "sse2_punpckhwd"
22706 [(set (match_operand:V8HI 0 "register_operand" "=x")
22707 (vec_merge:V8HI
22708 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22709 (parallel [(const_int 4) (const_int 0)
22710 (const_int 5) (const_int 1)
22711 (const_int 6) (const_int 2)
22712 (const_int 7) (const_int 3)]))
22713 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22714 (parallel [(const_int 0) (const_int 4)
22715 (const_int 1) (const_int 5)
22716 (const_int 2) (const_int 6)
22717 (const_int 3) (const_int 7)]))
22718 (const_int 85)))]
22719 "TARGET_SSE2"
22720 "punpckhwd\t{%2, %0|%0, %2}"
22721 [(set_attr "type" "ssecvt")
22722 (set_attr "mode" "TI")])
22723
22724 (define_insn "sse2_punpckhdq"
22725 [(set (match_operand:V4SI 0 "register_operand" "=x")
22726 (vec_merge:V4SI
22727 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22728 (parallel [(const_int 2) (const_int 0)
22729 (const_int 3) (const_int 1)]))
22730 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22731 (parallel [(const_int 0) (const_int 2)
22732 (const_int 1) (const_int 3)]))
22733 (const_int 5)))]
22734 "TARGET_SSE2"
22735 "punpckhdq\t{%2, %0|%0, %2}"
22736 [(set_attr "type" "ssecvt")
22737 (set_attr "mode" "TI")])
22738
22739 (define_insn "sse2_punpcklbw"
22740 [(set (match_operand:V16QI 0 "register_operand" "=x")
22741 (vec_merge:V16QI
22742 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22743 (parallel [(const_int 0) (const_int 8)
22744 (const_int 1) (const_int 9)
22745 (const_int 2) (const_int 10)
22746 (const_int 3) (const_int 11)
22747 (const_int 4) (const_int 12)
22748 (const_int 5) (const_int 13)
22749 (const_int 6) (const_int 14)
22750 (const_int 7) (const_int 15)]))
22751 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22752 (parallel [(const_int 8) (const_int 0)
22753 (const_int 9) (const_int 1)
22754 (const_int 10) (const_int 2)
22755 (const_int 11) (const_int 3)
22756 (const_int 12) (const_int 4)
22757 (const_int 13) (const_int 5)
22758 (const_int 14) (const_int 6)
22759 (const_int 15) (const_int 7)]))
22760 (const_int 21845)))]
22761 "TARGET_SSE2"
22762 "punpcklbw\t{%2, %0|%0, %2}"
22763 [(set_attr "type" "ssecvt")
22764 (set_attr "mode" "TI")])
22765
22766 (define_insn "sse2_punpcklwd"
22767 [(set (match_operand:V8HI 0 "register_operand" "=x")
22768 (vec_merge:V8HI
22769 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22770 (parallel [(const_int 0) (const_int 4)
22771 (const_int 1) (const_int 5)
22772 (const_int 2) (const_int 6)
22773 (const_int 3) (const_int 7)]))
22774 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22775 (parallel [(const_int 4) (const_int 0)
22776 (const_int 5) (const_int 1)
22777 (const_int 6) (const_int 2)
22778 (const_int 7) (const_int 3)]))
22779 (const_int 85)))]
22780 "TARGET_SSE2"
22781 "punpcklwd\t{%2, %0|%0, %2}"
22782 [(set_attr "type" "ssecvt")
22783 (set_attr "mode" "TI")])
22784
22785 (define_insn "sse2_punpckldq"
22786 [(set (match_operand:V4SI 0 "register_operand" "=x")
22787 (vec_merge:V4SI
22788 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22789 (parallel [(const_int 0) (const_int 2)
22790 (const_int 1) (const_int 3)]))
22791 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22792 (parallel [(const_int 2) (const_int 0)
22793 (const_int 3) (const_int 1)]))
22794 (const_int 5)))]
22795 "TARGET_SSE2"
22796 "punpckldq\t{%2, %0|%0, %2}"
22797 [(set_attr "type" "ssecvt")
22798 (set_attr "mode" "TI")])
22799
22800 (define_insn "sse2_punpcklqdq"
22801 [(set (match_operand:V2DI 0 "register_operand" "=x")
22802 (vec_merge:V2DI
22803 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22804 (parallel [(const_int 1)
22805 (const_int 0)]))
22806 (match_operand:V2DI 1 "register_operand" "0")
22807 (const_int 1)))]
22808 "TARGET_SSE2"
22809 "punpcklqdq\t{%2, %0|%0, %2}"
22810 [(set_attr "type" "ssecvt")
22811 (set_attr "mode" "TI")])
22812
22813 (define_insn "sse2_punpckhqdq"
22814 [(set (match_operand:V2DI 0 "register_operand" "=x")
22815 (vec_merge:V2DI
22816 (match_operand:V2DI 1 "register_operand" "0")
22817 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22818 (parallel [(const_int 1)
22819 (const_int 0)]))
22820 (const_int 1)))]
22821 "TARGET_SSE2"
22822 "punpckhqdq\t{%2, %0|%0, %2}"
22823 [(set_attr "type" "ssecvt")
22824 (set_attr "mode" "TI")])
22825
22826 ;; SSE2 moves
22827
22828 (define_insn "sse2_movapd"
22829 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22830 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22831 UNSPEC_MOVA))]
22832 "TARGET_SSE2
22833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22834 "movapd\t{%1, %0|%0, %1}"
22835 [(set_attr "type" "ssemov")
22836 (set_attr "mode" "V2DF")])
22837
22838 (define_insn "sse2_movupd"
22839 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22840 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22841 UNSPEC_MOVU))]
22842 "TARGET_SSE2
22843 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22844 "movupd\t{%1, %0|%0, %1}"
22845 [(set_attr "type" "ssecvt")
22846 (set_attr "mode" "V2DF")])
22847
22848 (define_insn "sse2_movdqa"
22849 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22850 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22851 UNSPEC_MOVA))]
22852 "TARGET_SSE2
22853 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22854 "movdqa\t{%1, %0|%0, %1}"
22855 [(set_attr "type" "ssemov")
22856 (set_attr "mode" "TI")])
22857
22858 (define_insn "sse2_movdqu"
22859 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22860 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22861 UNSPEC_MOVU))]
22862 "TARGET_SSE2
22863 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22864 "movdqu\t{%1, %0|%0, %1}"
22865 [(set_attr "type" "ssecvt")
22866 (set_attr "mode" "TI")])
22867
22868 (define_insn "sse2_movdq2q"
22869 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22870 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22871 (parallel [(const_int 0)])))]
22872 "TARGET_SSE2 && !TARGET_64BIT"
22873 "@
22874 movq\t{%1, %0|%0, %1}
22875 movdq2q\t{%1, %0|%0, %1}"
22876 [(set_attr "type" "ssecvt")
22877 (set_attr "mode" "TI")])
22878
22879 (define_insn "sse2_movdq2q_rex64"
22880 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22881 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22882 (parallel [(const_int 0)])))]
22883 "TARGET_SSE2 && TARGET_64BIT"
22884 "@
22885 movq\t{%1, %0|%0, %1}
22886 movdq2q\t{%1, %0|%0, %1}
22887 movd\t{%1, %0|%0, %1}"
22888 [(set_attr "type" "ssecvt")
22889 (set_attr "mode" "TI")])
22890
22891 (define_insn "sse2_movq2dq"
22892 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22893 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22894 (const_int 0)))]
22895 "TARGET_SSE2 && !TARGET_64BIT"
22896 "@
22897 movq\t{%1, %0|%0, %1}
22898 movq2dq\t{%1, %0|%0, %1}"
22899 [(set_attr "type" "ssecvt,ssemov")
22900 (set_attr "mode" "TI")])
22901
22902 (define_insn "sse2_movq2dq_rex64"
22903 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22904 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22905 (const_int 0)))]
22906 "TARGET_SSE2 && TARGET_64BIT"
22907 "@
22908 movq\t{%1, %0|%0, %1}
22909 movq2dq\t{%1, %0|%0, %1}
22910 movd\t{%1, %0|%0, %1}"
22911 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22912 (set_attr "mode" "TI")])
22913
22914 (define_insn "sse2_movq"
22915 [(set (match_operand:V2DI 0 "register_operand" "=x")
22916 (vec_concat:V2DI (vec_select:DI
22917 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22918 (parallel [(const_int 0)]))
22919 (const_int 0)))]
22920 "TARGET_SSE2"
22921 "movq\t{%1, %0|%0, %1}"
22922 [(set_attr "type" "ssemov")
22923 (set_attr "mode" "TI")])
22924
22925 (define_insn "sse2_loadd"
22926 [(set (match_operand:V4SI 0 "register_operand" "=x")
22927 (vec_merge:V4SI
22928 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22929 (const_vector:V4SI [(const_int 0)
22930 (const_int 0)
22931 (const_int 0)
22932 (const_int 0)])
22933 (const_int 1)))]
22934 "TARGET_SSE2"
22935 "movd\t{%1, %0|%0, %1}"
22936 [(set_attr "type" "ssemov")
22937 (set_attr "mode" "TI")])
22938
22939 (define_insn "sse2_stored"
22940 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22941 (vec_select:SI
22942 (match_operand:V4SI 1 "register_operand" "x")
22943 (parallel [(const_int 0)])))]
22944 "TARGET_SSE2"
22945 "movd\t{%1, %0|%0, %1}"
22946 [(set_attr "type" "ssemov")
22947 (set_attr "mode" "TI")])
22948
22949 (define_insn "sse2_movhpd"
22950 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22951 (vec_merge:V2DF
22952 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22953 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22954 (const_int 2)))]
22955 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22956 "movhpd\t{%2, %0|%0, %2}"
22957 [(set_attr "type" "ssecvt")
22958 (set_attr "mode" "V2DF")])
22959
22960 (define_expand "sse2_loadsd"
22961 [(match_operand:V2DF 0 "register_operand" "")
22962 (match_operand:DF 1 "memory_operand" "")]
22963 "TARGET_SSE2"
22964 {
22965 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22966 CONST0_RTX (V2DFmode)));
22967 DONE;
22968 })
22969
22970 (define_insn "sse2_loadsd_1"
22971 [(set (match_operand:V2DF 0 "register_operand" "=x")
22972 (vec_merge:V2DF
22973 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22974 (match_operand:V2DF 2 "const0_operand" "X")
22975 (const_int 1)))]
22976 "TARGET_SSE2"
22977 "movsd\t{%1, %0|%0, %1}"
22978 [(set_attr "type" "ssecvt")
22979 (set_attr "mode" "DF")])
22980
22981 (define_insn "sse2_movsd"
22982 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22983 (vec_merge:V2DF
22984 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22985 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22986 (const_int 1)))]
22987 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22988 "@movsd\t{%2, %0|%0, %2}
22989 movlpd\t{%2, %0|%0, %2}
22990 movlpd\t{%2, %0|%0, %2}"
22991 [(set_attr "type" "ssecvt")
22992 (set_attr "mode" "DF,V2DF,V2DF")])
22993
22994 (define_insn "sse2_storesd"
22995 [(set (match_operand:DF 0 "memory_operand" "=m")
22996 (vec_select:DF
22997 (match_operand:V2DF 1 "register_operand" "x")
22998 (parallel [(const_int 0)])))]
22999 "TARGET_SSE2"
23000 "movsd\t{%1, %0|%0, %1}"
23001 [(set_attr "type" "ssecvt")
23002 (set_attr "mode" "DF")])
23003
23004 (define_insn "sse2_shufpd"
23005 [(set (match_operand:V2DF 0 "register_operand" "=x")
23006 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23007 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23008 (match_operand:SI 3 "immediate_operand" "i")]
23009 UNSPEC_SHUFFLE))]
23010 "TARGET_SSE2"
23011 ;; @@@ check operand order for intel/nonintel syntax
23012 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23013 [(set_attr "type" "ssecvt")
23014 (set_attr "mode" "V2DF")])
23015
23016 (define_insn "sse2_clflush"
23017 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23018 UNSPECV_CLFLUSH)]
23019 "TARGET_SSE2"
23020 "clflush %0"
23021 [(set_attr "type" "sse")
23022 (set_attr "memory" "unknown")])
23023
23024 (define_expand "sse2_mfence"
23025 [(set (match_dup 0)
23026 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23027 "TARGET_SSE2"
23028 {
23029 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23030 MEM_VOLATILE_P (operands[0]) = 1;
23031 })
23032
23033 (define_insn "*mfence_insn"
23034 [(set (match_operand:BLK 0 "" "")
23035 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23036 "TARGET_SSE2"
23037 "mfence"
23038 [(set_attr "type" "sse")
23039 (set_attr "memory" "unknown")])
23040
23041 (define_expand "sse2_lfence"
23042 [(set (match_dup 0)
23043 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23044 "TARGET_SSE2"
23045 {
23046 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23047 MEM_VOLATILE_P (operands[0]) = 1;
23048 })
23049
23050 (define_insn "*lfence_insn"
23051 [(set (match_operand:BLK 0 "" "")
23052 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23053 "TARGET_SSE2"
23054 "lfence"
23055 [(set_attr "type" "sse")
23056 (set_attr "memory" "unknown")])
23057
23058 ;; SSE3
23059
23060 (define_insn "mwait"
23061 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23062 (match_operand:SI 1 "register_operand" "c")]
23063 UNSPECV_MWAIT)]
23064 "TARGET_SSE3"
23065 "mwait\t%0, %1"
23066 [(set_attr "length" "3")])
23067
23068 (define_insn "monitor"
23069 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23070 (match_operand:SI 1 "register_operand" "c")
23071 (match_operand:SI 2 "register_operand" "d")]
23072 UNSPECV_MONITOR)]
23073 "TARGET_SSE3"
23074 "monitor\t%0, %1, %2"
23075 [(set_attr "length" "3")])
23076
23077 ;; SSE3 arithmetic
23078
23079 (define_insn "addsubv4sf3"
23080 [(set (match_operand:V4SF 0 "register_operand" "=x")
23081 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23082 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23083 UNSPEC_ADDSUB))]
23084 "TARGET_SSE3"
23085 "addsubps\t{%2, %0|%0, %2}"
23086 [(set_attr "type" "sseadd")
23087 (set_attr "mode" "V4SF")])
23088
23089 (define_insn "addsubv2df3"
23090 [(set (match_operand:V2DF 0 "register_operand" "=x")
23091 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23092 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23093 UNSPEC_ADDSUB))]
23094 "TARGET_SSE3"
23095 "addsubpd\t{%2, %0|%0, %2}"
23096 [(set_attr "type" "sseadd")
23097 (set_attr "mode" "V2DF")])
23098
23099 (define_insn "haddv4sf3"
23100 [(set (match_operand:V4SF 0 "register_operand" "=x")
23101 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23102 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23103 UNSPEC_HADD))]
23104 "TARGET_SSE3"
23105 "haddps\t{%2, %0|%0, %2}"
23106 [(set_attr "type" "sseadd")
23107 (set_attr "mode" "V4SF")])
23108
23109 (define_insn "haddv2df3"
23110 [(set (match_operand:V2DF 0 "register_operand" "=x")
23111 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23112 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23113 UNSPEC_HADD))]
23114 "TARGET_SSE3"
23115 "haddpd\t{%2, %0|%0, %2}"
23116 [(set_attr "type" "sseadd")
23117 (set_attr "mode" "V2DF")])
23118
23119 (define_insn "hsubv4sf3"
23120 [(set (match_operand:V4SF 0 "register_operand" "=x")
23121 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23122 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23123 UNSPEC_HSUB))]
23124 "TARGET_SSE3"
23125 "hsubps\t{%2, %0|%0, %2}"
23126 [(set_attr "type" "sseadd")
23127 (set_attr "mode" "V4SF")])
23128
23129 (define_insn "hsubv2df3"
23130 [(set (match_operand:V2DF 0 "register_operand" "=x")
23131 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23132 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23133 UNSPEC_HSUB))]
23134 "TARGET_SSE3"
23135 "hsubpd\t{%2, %0|%0, %2}"
23136 [(set_attr "type" "sseadd")
23137 (set_attr "mode" "V2DF")])
23138
23139 (define_insn "movshdup"
23140 [(set (match_operand:V4SF 0 "register_operand" "=x")
23141 (unspec:V4SF
23142 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23143 "TARGET_SSE3"
23144 "movshdup\t{%1, %0|%0, %1}"
23145 [(set_attr "type" "sse")
23146 (set_attr "mode" "V4SF")])
23147
23148 (define_insn "movsldup"
23149 [(set (match_operand:V4SF 0 "register_operand" "=x")
23150 (unspec:V4SF
23151 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23152 "TARGET_SSE3"
23153 "movsldup\t{%1, %0|%0, %1}"
23154 [(set_attr "type" "sse")
23155 (set_attr "mode" "V4SF")])
23156
23157 (define_insn "lddqu"
23158 [(set (match_operand:V16QI 0 "register_operand" "=x")
23159 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23160 UNSPEC_LDQQU))]
23161 "TARGET_SSE3"
23162 "lddqu\t{%1, %0|%0, %1}"
23163 [(set_attr "type" "ssecvt")
23164 (set_attr "mode" "TI")])
23165
23166 (define_insn "loadddup"
23167 [(set (match_operand:V2DF 0 "register_operand" "=x")
23168 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23169 "TARGET_SSE3"
23170 "movddup\t{%1, %0|%0, %1}"
23171 [(set_attr "type" "ssecvt")
23172 (set_attr "mode" "DF")])
23173
23174 (define_insn "movddup"
23175 [(set (match_operand:V2DF 0 "register_operand" "=x")
23176 (vec_duplicate:V2DF
23177 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23178 (parallel [(const_int 0)]))))]
23179 "TARGET_SSE3"
23180 "movddup\t{%1, %0|%0, %1}"
23181 [(set_attr "type" "ssecvt")
23182 (set_attr "mode" "DF")])