optabs.h (enum optab_index): Add new OTI_exp10 and OTI_exp2.
[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 operands[2] = assign_386_stack_local (SFmode, 0);
3658 else
3659 {
3660 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3661 DONE;
3662 }
3663 ")
3664
3665 (define_insn "*truncdfsf2_1"
3666 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3667 (float_truncate:SF
3668 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3669 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3670 "TARGET_80387 && !TARGET_SSE2"
3671 {
3672 switch (which_alternative)
3673 {
3674 case 0:
3675 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3676 return "fstp%z0\t%y0";
3677 else
3678 return "fst%z0\t%y0";
3679 default:
3680 abort ();
3681 }
3682 }
3683 [(set_attr "type" "fmov,multi,multi,multi")
3684 (set_attr "mode" "SF,SF,SF,SF")])
3685
3686 (define_insn "*truncdfsf2_1_sse"
3687 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3688 (float_truncate:SF
3689 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3690 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3691 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3692 {
3693 switch (which_alternative)
3694 {
3695 case 0:
3696 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697 return "fstp%z0\t%y0";
3698 else
3699 return "fst%z0\t%y0";
3700 case 4:
3701 return "#";
3702 default:
3703 abort ();
3704 }
3705 }
3706 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3707 (set_attr "mode" "SF,SF,SF,SF,DF")])
3708
3709 (define_insn "*truncdfsf2_1_sse_nooverlap"
3710 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3711 (float_truncate:SF
3712 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3713 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3714 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3715 {
3716 switch (which_alternative)
3717 {
3718 case 0:
3719 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3720 return "fstp%z0\t%y0";
3721 else
3722 return "fst%z0\t%y0";
3723 case 4:
3724 return "#";
3725 default:
3726 abort ();
3727 }
3728 }
3729 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3730 (set_attr "mode" "SF,SF,SF,SF,DF")])
3731
3732 (define_insn "*truncdfsf2_2"
3733 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3734 (float_truncate:SF
3735 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3736 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3737 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3738 {
3739 switch (which_alternative)
3740 {
3741 case 0:
3742 case 1:
3743 return "cvtsd2ss\t{%1, %0|%0, %1}";
3744 case 2:
3745 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3746 return "fstp%z0\t%y0";
3747 else
3748 return "fst%z0\t%y0";
3749 default:
3750 abort ();
3751 }
3752 }
3753 [(set_attr "type" "ssecvt,ssecvt,fmov")
3754 (set_attr "athlon_decode" "vector,double,*")
3755 (set_attr "mode" "SF,SF,SF")])
3756
3757 (define_insn "*truncdfsf2_2_nooverlap"
3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3759 (float_truncate:SF
3760 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3761 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3762 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3763 {
3764 switch (which_alternative)
3765 {
3766 case 0:
3767 return "#";
3768 case 1:
3769 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3770 return "fstp%z0\t%y0";
3771 else
3772 return "fst%z0\t%y0";
3773 default:
3774 abort ();
3775 }
3776 }
3777 [(set_attr "type" "ssecvt,fmov")
3778 (set_attr "mode" "DF,SF")])
3779
3780 (define_insn "*truncdfsf2_3"
3781 [(set (match_operand:SF 0 "memory_operand" "=m")
3782 (float_truncate:SF
3783 (match_operand:DF 1 "register_operand" "f")))]
3784 "TARGET_80387"
3785 {
3786 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3787 return "fstp%z0\t%y0";
3788 else
3789 return "fst%z0\t%y0";
3790 }
3791 [(set_attr "type" "fmov")
3792 (set_attr "mode" "SF")])
3793
3794 (define_insn "truncdfsf2_sse_only"
3795 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3796 (float_truncate:SF
3797 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3798 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3799 "cvtsd2ss\t{%1, %0|%0, %1}"
3800 [(set_attr "type" "ssecvt")
3801 (set_attr "athlon_decode" "vector,double")
3802 (set_attr "mode" "SF")])
3803
3804 (define_insn "*truncdfsf2_sse_only_nooverlap"
3805 [(set (match_operand:SF 0 "register_operand" "=&Y")
3806 (float_truncate:SF
3807 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3808 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3809 "#"
3810 [(set_attr "type" "ssecvt")
3811 (set_attr "mode" "DF")])
3812
3813 (define_split
3814 [(set (match_operand:SF 0 "memory_operand" "")
3815 (float_truncate:SF
3816 (match_operand:DF 1 "register_operand" "")))
3817 (clobber (match_operand:SF 2 "memory_operand" ""))]
3818 "TARGET_80387"
3819 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3820 "")
3821
3822 ; Avoid possible reformatting penalty on the destination by first
3823 ; zeroing it out
3824 (define_split
3825 [(set (match_operand:SF 0 "register_operand" "")
3826 (float_truncate:SF
3827 (match_operand:DF 1 "nonimmediate_operand" "")))
3828 (clobber (match_operand 2 "" ""))]
3829 "TARGET_80387 && reload_completed
3830 && SSE_REG_P (operands[0])
3831 && !STACK_REG_P (operands[1])"
3832 [(const_int 0)]
3833 {
3834 rtx src, dest;
3835 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3836 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3837 else
3838 {
3839 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3840 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3841 /* simplify_gen_subreg refuses to widen memory references. */
3842 if (GET_CODE (src) == SUBREG)
3843 alter_subreg (&src);
3844 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3845 abort ();
3846 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3847 emit_insn (gen_cvtsd2ss (dest, dest, src));
3848 }
3849 DONE;
3850 })
3851
3852 (define_split
3853 [(set (match_operand:SF 0 "register_operand" "")
3854 (float_truncate:SF
3855 (match_operand:DF 1 "nonimmediate_operand" "")))]
3856 "TARGET_80387 && reload_completed
3857 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3858 [(const_int 0)]
3859 {
3860 rtx src, dest;
3861 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3862 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3863 /* simplify_gen_subreg refuses to widen memory references. */
3864 if (GET_CODE (src) == SUBREG)
3865 alter_subreg (&src);
3866 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3867 abort ();
3868 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3869 emit_insn (gen_cvtsd2ss (dest, dest, src));
3870 DONE;
3871 })
3872
3873 (define_split
3874 [(set (match_operand:SF 0 "register_operand" "")
3875 (float_truncate:SF
3876 (match_operand:DF 1 "fp_register_operand" "")))
3877 (clobber (match_operand:SF 2 "memory_operand" ""))]
3878 "TARGET_80387 && reload_completed"
3879 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3880 (set (match_dup 0) (match_dup 2))]
3881 "")
3882
3883 (define_expand "truncxfsf2"
3884 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3885 (float_truncate:SF
3886 (match_operand:XF 1 "register_operand" "")))
3887 (clobber (match_dup 2))])]
3888 "TARGET_80387"
3889 "operands[2] = assign_386_stack_local (SFmode, 0);")
3890
3891 (define_insn "*truncxfsf2_1"
3892 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3893 (float_truncate:SF
3894 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3895 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3896 "TARGET_80387"
3897 {
3898 switch (which_alternative)
3899 {
3900 case 0:
3901 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3902 return "fstp%z0\t%y0";
3903 else
3904 return "fst%z0\t%y0";
3905 default:
3906 abort();
3907 }
3908 }
3909 [(set_attr "type" "fmov,multi,multi,multi")
3910 (set_attr "mode" "SF")])
3911
3912 (define_insn "*truncxfsf2_2"
3913 [(set (match_operand:SF 0 "memory_operand" "=m")
3914 (float_truncate:SF
3915 (match_operand:XF 1 "register_operand" "f")))]
3916 "TARGET_80387"
3917 {
3918 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3919 return "fstp%z0\t%y0";
3920 else
3921 return "fst%z0\t%y0";
3922 }
3923 [(set_attr "type" "fmov")
3924 (set_attr "mode" "SF")])
3925
3926 (define_split
3927 [(set (match_operand:SF 0 "memory_operand" "")
3928 (float_truncate:SF
3929 (match_operand:XF 1 "register_operand" "")))
3930 (clobber (match_operand:SF 2 "memory_operand" ""))]
3931 "TARGET_80387"
3932 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3933 "")
3934
3935 (define_split
3936 [(set (match_operand:SF 0 "register_operand" "")
3937 (float_truncate:SF
3938 (match_operand:XF 1 "register_operand" "")))
3939 (clobber (match_operand:SF 2 "memory_operand" ""))]
3940 "TARGET_80387 && reload_completed"
3941 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3942 (set (match_dup 0) (match_dup 2))]
3943 "")
3944
3945 (define_expand "truncxfdf2"
3946 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3947 (float_truncate:DF
3948 (match_operand:XF 1 "register_operand" "")))
3949 (clobber (match_dup 2))])]
3950 "TARGET_80387"
3951 "operands[2] = assign_386_stack_local (DFmode, 0);")
3952
3953 (define_insn "*truncxfdf2_1"
3954 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3955 (float_truncate:DF
3956 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3957 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3958 "TARGET_80387"
3959 {
3960 switch (which_alternative)
3961 {
3962 case 0:
3963 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3964 return "fstp%z0\t%y0";
3965 else
3966 return "fst%z0\t%y0";
3967 default:
3968 abort();
3969 }
3970 abort ();
3971 }
3972 [(set_attr "type" "fmov,multi,multi,multi")
3973 (set_attr "mode" "DF")])
3974
3975 (define_insn "*truncxfdf2_2"
3976 [(set (match_operand:DF 0 "memory_operand" "=m")
3977 (float_truncate:DF
3978 (match_operand:XF 1 "register_operand" "f")))]
3979 "TARGET_80387"
3980 {
3981 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3982 return "fstp%z0\t%y0";
3983 else
3984 return "fst%z0\t%y0";
3985 }
3986 [(set_attr "type" "fmov")
3987 (set_attr "mode" "DF")])
3988
3989 (define_split
3990 [(set (match_operand:DF 0 "memory_operand" "")
3991 (float_truncate:DF
3992 (match_operand:XF 1 "register_operand" "")))
3993 (clobber (match_operand:DF 2 "memory_operand" ""))]
3994 "TARGET_80387"
3995 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3996 "")
3997
3998 (define_split
3999 [(set (match_operand:DF 0 "register_operand" "")
4000 (float_truncate:DF
4001 (match_operand:XF 1 "register_operand" "")))
4002 (clobber (match_operand:DF 2 "memory_operand" ""))]
4003 "TARGET_80387 && reload_completed"
4004 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4005 (set (match_dup 0) (match_dup 2))]
4006 "")
4007
4008 \f
4009 ;; %%% Break up all these bad boys.
4010
4011 ;; Signed conversion to DImode.
4012
4013 (define_expand "fix_truncxfdi2"
4014 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4015 (fix:DI (match_operand:XF 1 "register_operand" "")))
4016 (clobber (reg:CC 17))])]
4017 "TARGET_80387"
4018 "")
4019
4020 (define_expand "fix_truncdfdi2"
4021 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4022 (fix:DI (match_operand:DF 1 "register_operand" "")))
4023 (clobber (reg:CC 17))])]
4024 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4025 {
4026 if (TARGET_64BIT && TARGET_SSE2)
4027 {
4028 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4029 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4030 if (out != operands[0])
4031 emit_move_insn (operands[0], out);
4032 DONE;
4033 }
4034 })
4035
4036 (define_expand "fix_truncsfdi2"
4037 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4038 (fix:DI (match_operand:SF 1 "register_operand" "")))
4039 (clobber (reg:CC 17))])]
4040 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4041 {
4042 if (TARGET_SSE && TARGET_64BIT)
4043 {
4044 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4045 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4046 if (out != operands[0])
4047 emit_move_insn (operands[0], out);
4048 DONE;
4049 }
4050 })
4051
4052 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4053 ;; of the machinery.
4054 (define_insn_and_split "*fix_truncdi_1"
4055 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4056 (fix:DI (match_operand 1 "register_operand" "f,f")))
4057 (clobber (reg:CC 17))]
4058 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4059 && !reload_completed && !reload_in_progress
4060 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4061 "#"
4062 "&& 1"
4063 [(const_int 0)]
4064 {
4065 ix86_optimize_mode_switching = 1;
4066 operands[2] = assign_386_stack_local (HImode, 1);
4067 operands[3] = assign_386_stack_local (HImode, 2);
4068 if (memory_operand (operands[0], VOIDmode))
4069 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4070 operands[2], operands[3]));
4071 else
4072 {
4073 operands[4] = assign_386_stack_local (DImode, 0);
4074 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4075 operands[2], operands[3],
4076 operands[4]));
4077 }
4078 DONE;
4079 }
4080 [(set_attr "type" "fistp")
4081 (set_attr "mode" "DI")])
4082
4083 (define_insn "fix_truncdi_nomemory"
4084 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4085 (fix:DI (match_operand 1 "register_operand" "f,f")))
4086 (use (match_operand:HI 2 "memory_operand" "m,m"))
4087 (use (match_operand:HI 3 "memory_operand" "m,m"))
4088 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4089 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4090 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4091 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4092 "#"
4093 [(set_attr "type" "fistp")
4094 (set_attr "mode" "DI")])
4095
4096 (define_insn "fix_truncdi_memory"
4097 [(set (match_operand:DI 0 "memory_operand" "=m")
4098 (fix:DI (match_operand 1 "register_operand" "f")))
4099 (use (match_operand:HI 2 "memory_operand" "m"))
4100 (use (match_operand:HI 3 "memory_operand" "m"))
4101 (clobber (match_scratch:DF 4 "=&1f"))]
4102 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4103 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4104 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4105 [(set_attr "type" "fistp")
4106 (set_attr "mode" "DI")])
4107
4108 (define_split
4109 [(set (match_operand:DI 0 "register_operand" "")
4110 (fix:DI (match_operand 1 "register_operand" "")))
4111 (use (match_operand:HI 2 "memory_operand" ""))
4112 (use (match_operand:HI 3 "memory_operand" ""))
4113 (clobber (match_operand:DI 4 "memory_operand" ""))
4114 (clobber (match_scratch 5 ""))]
4115 "reload_completed"
4116 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4117 (use (match_dup 2))
4118 (use (match_dup 3))
4119 (clobber (match_dup 5))])
4120 (set (match_dup 0) (match_dup 4))]
4121 "")
4122
4123 (define_split
4124 [(set (match_operand:DI 0 "memory_operand" "")
4125 (fix:DI (match_operand 1 "register_operand" "")))
4126 (use (match_operand:HI 2 "memory_operand" ""))
4127 (use (match_operand:HI 3 "memory_operand" ""))
4128 (clobber (match_operand:DI 4 "memory_operand" ""))
4129 (clobber (match_scratch 5 ""))]
4130 "reload_completed"
4131 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4132 (use (match_dup 2))
4133 (use (match_dup 3))
4134 (clobber (match_dup 5))])]
4135 "")
4136
4137 ;; When SSE available, it is always faster to use it!
4138 (define_insn "fix_truncsfdi_sse"
4139 [(set (match_operand:DI 0 "register_operand" "=r,r")
4140 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4141 "TARGET_64BIT && TARGET_SSE"
4142 "cvttss2si{q}\t{%1, %0|%0, %1}"
4143 [(set_attr "type" "sseicvt")
4144 (set_attr "mode" "SF")
4145 (set_attr "athlon_decode" "double,vector")])
4146
4147 ;; Avoid vector decoded form of the instruction.
4148 (define_peephole2
4149 [(match_scratch:SF 2 "x")
4150 (set (match_operand:DI 0 "register_operand" "")
4151 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4152 "TARGET_K8 && !optimize_size"
4153 [(set (match_dup 2) (match_dup 1))
4154 (set (match_dup 0) (fix:DI (match_dup 2)))]
4155 "")
4156
4157 (define_insn "fix_truncdfdi_sse"
4158 [(set (match_operand:DI 0 "register_operand" "=r,r")
4159 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4160 "TARGET_64BIT && TARGET_SSE2"
4161 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4162 [(set_attr "type" "sseicvt,sseicvt")
4163 (set_attr "mode" "DF")
4164 (set_attr "athlon_decode" "double,vector")])
4165
4166 ;; Avoid vector decoded form of the instruction.
4167 (define_peephole2
4168 [(match_scratch:DF 2 "Y")
4169 (set (match_operand:DI 0 "register_operand" "")
4170 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4171 "TARGET_K8 && !optimize_size"
4172 [(set (match_dup 2) (match_dup 1))
4173 (set (match_dup 0) (fix:DI (match_dup 2)))]
4174 "")
4175
4176 ;; Signed conversion to SImode.
4177
4178 (define_expand "fix_truncxfsi2"
4179 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4180 (fix:SI (match_operand:XF 1 "register_operand" "")))
4181 (clobber (reg:CC 17))])]
4182 "TARGET_80387"
4183 "")
4184
4185 (define_expand "fix_truncdfsi2"
4186 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4187 (fix:SI (match_operand:DF 1 "register_operand" "")))
4188 (clobber (reg:CC 17))])]
4189 "TARGET_80387 || TARGET_SSE2"
4190 {
4191 if (TARGET_SSE2)
4192 {
4193 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4194 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4195 if (out != operands[0])
4196 emit_move_insn (operands[0], out);
4197 DONE;
4198 }
4199 })
4200
4201 (define_expand "fix_truncsfsi2"
4202 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4203 (fix:SI (match_operand:SF 1 "register_operand" "")))
4204 (clobber (reg:CC 17))])]
4205 "TARGET_80387 || TARGET_SSE"
4206 {
4207 if (TARGET_SSE)
4208 {
4209 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4210 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4211 if (out != operands[0])
4212 emit_move_insn (operands[0], out);
4213 DONE;
4214 }
4215 })
4216
4217 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4218 ;; of the machinery.
4219 (define_insn_and_split "*fix_truncsi_1"
4220 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4221 (fix:SI (match_operand 1 "register_operand" "f,f")))
4222 (clobber (reg:CC 17))]
4223 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4224 && !reload_completed && !reload_in_progress
4225 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4226 "#"
4227 "&& 1"
4228 [(const_int 0)]
4229 {
4230 ix86_optimize_mode_switching = 1;
4231 operands[2] = assign_386_stack_local (HImode, 1);
4232 operands[3] = assign_386_stack_local (HImode, 2);
4233 if (memory_operand (operands[0], VOIDmode))
4234 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4235 operands[2], operands[3]));
4236 else
4237 {
4238 operands[4] = assign_386_stack_local (SImode, 0);
4239 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4240 operands[2], operands[3],
4241 operands[4]));
4242 }
4243 DONE;
4244 }
4245 [(set_attr "type" "fistp")
4246 (set_attr "mode" "SI")])
4247
4248 (define_insn "fix_truncsi_nomemory"
4249 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4250 (fix:SI (match_operand 1 "register_operand" "f,f")))
4251 (use (match_operand:HI 2 "memory_operand" "m,m"))
4252 (use (match_operand:HI 3 "memory_operand" "m,m"))
4253 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4254 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4255 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4256 "#"
4257 [(set_attr "type" "fistp")
4258 (set_attr "mode" "SI")])
4259
4260 (define_insn "fix_truncsi_memory"
4261 [(set (match_operand:SI 0 "memory_operand" "=m")
4262 (fix:SI (match_operand 1 "register_operand" "f")))
4263 (use (match_operand:HI 2 "memory_operand" "m"))
4264 (use (match_operand:HI 3 "memory_operand" "m"))]
4265 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4266 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4267 "* return output_fix_trunc (insn, operands);"
4268 [(set_attr "type" "fistp")
4269 (set_attr "mode" "SI")])
4270
4271 ;; When SSE available, it is always faster to use it!
4272 (define_insn "fix_truncsfsi_sse"
4273 [(set (match_operand:SI 0 "register_operand" "=r,r")
4274 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4275 "TARGET_SSE"
4276 "cvttss2si\t{%1, %0|%0, %1}"
4277 [(set_attr "type" "sseicvt")
4278 (set_attr "mode" "DF")
4279 (set_attr "athlon_decode" "double,vector")])
4280
4281 ;; Avoid vector decoded form of the instruction.
4282 (define_peephole2
4283 [(match_scratch:SF 2 "x")
4284 (set (match_operand:SI 0 "register_operand" "")
4285 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4286 "TARGET_K8 && !optimize_size"
4287 [(set (match_dup 2) (match_dup 1))
4288 (set (match_dup 0) (fix:SI (match_dup 2)))]
4289 "")
4290
4291 (define_insn "fix_truncdfsi_sse"
4292 [(set (match_operand:SI 0 "register_operand" "=r,r")
4293 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4294 "TARGET_SSE2"
4295 "cvttsd2si\t{%1, %0|%0, %1}"
4296 [(set_attr "type" "sseicvt")
4297 (set_attr "mode" "DF")
4298 (set_attr "athlon_decode" "double,vector")])
4299
4300 ;; Avoid vector decoded form of the instruction.
4301 (define_peephole2
4302 [(match_scratch:DF 2 "Y")
4303 (set (match_operand:SI 0 "register_operand" "")
4304 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4305 "TARGET_K8 && !optimize_size"
4306 [(set (match_dup 2) (match_dup 1))
4307 (set (match_dup 0) (fix:SI (match_dup 2)))]
4308 "")
4309
4310 (define_split
4311 [(set (match_operand:SI 0 "register_operand" "")
4312 (fix:SI (match_operand 1 "register_operand" "")))
4313 (use (match_operand:HI 2 "memory_operand" ""))
4314 (use (match_operand:HI 3 "memory_operand" ""))
4315 (clobber (match_operand:SI 4 "memory_operand" ""))]
4316 "reload_completed"
4317 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4318 (use (match_dup 2))
4319 (use (match_dup 3))])
4320 (set (match_dup 0) (match_dup 4))]
4321 "")
4322
4323 (define_split
4324 [(set (match_operand:SI 0 "memory_operand" "")
4325 (fix:SI (match_operand 1 "register_operand" "")))
4326 (use (match_operand:HI 2 "memory_operand" ""))
4327 (use (match_operand:HI 3 "memory_operand" ""))
4328 (clobber (match_operand:SI 4 "memory_operand" ""))]
4329 "reload_completed"
4330 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4331 (use (match_dup 2))
4332 (use (match_dup 3))])]
4333 "")
4334
4335 ;; Signed conversion to HImode.
4336
4337 (define_expand "fix_truncxfhi2"
4338 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4339 (fix:HI (match_operand:XF 1 "register_operand" "")))
4340 (clobber (reg:CC 17))])]
4341 "TARGET_80387"
4342 "")
4343
4344 (define_expand "fix_truncdfhi2"
4345 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4346 (fix:HI (match_operand:DF 1 "register_operand" "")))
4347 (clobber (reg:CC 17))])]
4348 "TARGET_80387 && !TARGET_SSE2"
4349 "")
4350
4351 (define_expand "fix_truncsfhi2"
4352 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4353 (fix:HI (match_operand:SF 1 "register_operand" "")))
4354 (clobber (reg:CC 17))])]
4355 "TARGET_80387 && !TARGET_SSE"
4356 "")
4357
4358 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4359 ;; of the machinery.
4360 (define_insn_and_split "*fix_trunchi_1"
4361 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4362 (fix:HI (match_operand 1 "register_operand" "f,f")))
4363 (clobber (reg:CC 17))]
4364 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4365 && !reload_completed && !reload_in_progress
4366 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4367 "#"
4368 ""
4369 [(const_int 0)]
4370 {
4371 ix86_optimize_mode_switching = 1;
4372 operands[2] = assign_386_stack_local (HImode, 1);
4373 operands[3] = assign_386_stack_local (HImode, 2);
4374 if (memory_operand (operands[0], VOIDmode))
4375 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4376 operands[2], operands[3]));
4377 else
4378 {
4379 operands[4] = assign_386_stack_local (HImode, 0);
4380 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4381 operands[2], operands[3],
4382 operands[4]));
4383 }
4384 DONE;
4385 }
4386 [(set_attr "type" "fistp")
4387 (set_attr "mode" "HI")])
4388
4389 (define_insn "fix_trunchi_nomemory"
4390 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4391 (fix:HI (match_operand 1 "register_operand" "f,f")))
4392 (use (match_operand:HI 2 "memory_operand" "m,m"))
4393 (use (match_operand:HI 3 "memory_operand" "m,m"))
4394 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4395 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4396 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4397 "#"
4398 [(set_attr "type" "fistp")
4399 (set_attr "mode" "HI")])
4400
4401 (define_insn "fix_trunchi_memory"
4402 [(set (match_operand:HI 0 "memory_operand" "=m")
4403 (fix:HI (match_operand 1 "register_operand" "f")))
4404 (use (match_operand:HI 2 "memory_operand" "m"))
4405 (use (match_operand:HI 3 "memory_operand" "m"))]
4406 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4407 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4408 "* return output_fix_trunc (insn, operands);"
4409 [(set_attr "type" "fistp")
4410 (set_attr "mode" "HI")])
4411
4412 (define_split
4413 [(set (match_operand:HI 0 "memory_operand" "")
4414 (fix:HI (match_operand 1 "register_operand" "")))
4415 (use (match_operand:HI 2 "memory_operand" ""))
4416 (use (match_operand:HI 3 "memory_operand" ""))
4417 (clobber (match_operand:HI 4 "memory_operand" ""))]
4418 "reload_completed"
4419 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4420 (use (match_dup 2))
4421 (use (match_dup 3))])]
4422 "")
4423
4424 (define_split
4425 [(set (match_operand:HI 0 "register_operand" "")
4426 (fix:HI (match_operand 1 "register_operand" "")))
4427 (use (match_operand:HI 2 "memory_operand" ""))
4428 (use (match_operand:HI 3 "memory_operand" ""))
4429 (clobber (match_operand:HI 4 "memory_operand" ""))]
4430 "reload_completed"
4431 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4432 (use (match_dup 2))
4433 (use (match_dup 3))
4434 (clobber (match_dup 4))])
4435 (set (match_dup 0) (match_dup 4))]
4436 "")
4437
4438 ;; %% Not used yet.
4439 (define_insn "x86_fnstcw_1"
4440 [(set (match_operand:HI 0 "memory_operand" "=m")
4441 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4442 "TARGET_80387"
4443 "fnstcw\t%0"
4444 [(set_attr "length" "2")
4445 (set_attr "mode" "HI")
4446 (set_attr "unit" "i387")])
4447
4448 (define_insn "x86_fldcw_1"
4449 [(set (reg:HI 18)
4450 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4451 "TARGET_80387"
4452 "fldcw\t%0"
4453 [(set_attr "length" "2")
4454 (set_attr "mode" "HI")
4455 (set_attr "unit" "i387")
4456 (set_attr "athlon_decode" "vector")])
4457 \f
4458 ;; Conversion between fixed point and floating point.
4459
4460 ;; Even though we only accept memory inputs, the backend _really_
4461 ;; wants to be able to do this between registers.
4462
4463 (define_expand "floathisf2"
4464 [(set (match_operand:SF 0 "register_operand" "")
4465 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4466 "TARGET_SSE || TARGET_80387"
4467 {
4468 if (TARGET_SSE && TARGET_SSE_MATH)
4469 {
4470 emit_insn (gen_floatsisf2 (operands[0],
4471 convert_to_mode (SImode, operands[1], 0)));
4472 DONE;
4473 }
4474 })
4475
4476 (define_insn "*floathisf2_1"
4477 [(set (match_operand:SF 0 "register_operand" "=f,f")
4478 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4479 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4480 "@
4481 fild%z1\t%1
4482 #"
4483 [(set_attr "type" "fmov,multi")
4484 (set_attr "mode" "SF")
4485 (set_attr "fp_int_src" "true")])
4486
4487 (define_expand "floatsisf2"
4488 [(set (match_operand:SF 0 "register_operand" "")
4489 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4490 "TARGET_SSE || TARGET_80387"
4491 "")
4492
4493 (define_insn "*floatsisf2_i387"
4494 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4495 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4496 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4497 "@
4498 fild%z1\t%1
4499 #
4500 cvtsi2ss\t{%1, %0|%0, %1}
4501 cvtsi2ss\t{%1, %0|%0, %1}"
4502 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4503 (set_attr "mode" "SF")
4504 (set_attr "athlon_decode" "*,*,vector,double")
4505 (set_attr "fp_int_src" "true")])
4506
4507 (define_insn "*floatsisf2_sse"
4508 [(set (match_operand:SF 0 "register_operand" "=x,x")
4509 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4510 "TARGET_SSE"
4511 "cvtsi2ss\t{%1, %0|%0, %1}"
4512 [(set_attr "type" "sseicvt")
4513 (set_attr "mode" "SF")
4514 (set_attr "athlon_decode" "vector,double")
4515 (set_attr "fp_int_src" "true")])
4516
4517 ; Avoid possible reformatting penalty on the destination by first
4518 ; zeroing it out
4519 (define_split
4520 [(set (match_operand:SF 0 "register_operand" "")
4521 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4522 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4523 && SSE_REG_P (operands[0])"
4524 [(const_int 0)]
4525 {
4526 rtx dest;
4527 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4528 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4529 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4530 DONE;
4531 })
4532
4533 (define_expand "floatdisf2"
4534 [(set (match_operand:SF 0 "register_operand" "")
4535 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4536 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4537 "")
4538
4539 (define_insn "*floatdisf2_i387_only"
4540 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4541 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4542 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4543 "@
4544 fild%z1\t%1
4545 #"
4546 [(set_attr "type" "fmov,multi")
4547 (set_attr "mode" "SF")
4548 (set_attr "fp_int_src" "true")])
4549
4550 (define_insn "*floatdisf2_i387"
4551 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4552 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4553 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4554 "@
4555 fild%z1\t%1
4556 #
4557 cvtsi2ss{q}\t{%1, %0|%0, %1}
4558 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4559 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4560 (set_attr "mode" "SF")
4561 (set_attr "athlon_decode" "*,*,vector,double")
4562 (set_attr "fp_int_src" "true")])
4563
4564 (define_insn "*floatdisf2_sse"
4565 [(set (match_operand:SF 0 "register_operand" "=x,x")
4566 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4567 "TARGET_64BIT && TARGET_SSE"
4568 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4569 [(set_attr "type" "sseicvt")
4570 (set_attr "mode" "SF")
4571 (set_attr "athlon_decode" "vector,double")
4572 (set_attr "fp_int_src" "true")])
4573
4574 ; Avoid possible reformatting penalty on the destination by first
4575 ; zeroing it out
4576 (define_split
4577 [(set (match_operand:SF 0 "register_operand" "")
4578 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4579 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4580 && SSE_REG_P (operands[0])"
4581 [(const_int 0)]
4582 {
4583 rtx dest;
4584 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4585 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4586 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4587 DONE;
4588 })
4589
4590 (define_expand "floathidf2"
4591 [(set (match_operand:DF 0 "register_operand" "")
4592 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4593 "TARGET_SSE2 || TARGET_80387"
4594 {
4595 if (TARGET_SSE && TARGET_SSE_MATH)
4596 {
4597 emit_insn (gen_floatsidf2 (operands[0],
4598 convert_to_mode (SImode, operands[1], 0)));
4599 DONE;
4600 }
4601 })
4602
4603 (define_insn "*floathidf2_1"
4604 [(set (match_operand:DF 0 "register_operand" "=f,f")
4605 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4606 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4607 "@
4608 fild%z1\t%1
4609 #"
4610 [(set_attr "type" "fmov,multi")
4611 (set_attr "mode" "DF")
4612 (set_attr "fp_int_src" "true")])
4613
4614 (define_expand "floatsidf2"
4615 [(set (match_operand:DF 0 "register_operand" "")
4616 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4617 "TARGET_80387 || TARGET_SSE2"
4618 "")
4619
4620 (define_insn "*floatsidf2_i387"
4621 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4622 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4623 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4624 "@
4625 fild%z1\t%1
4626 #
4627 cvtsi2sd\t{%1, %0|%0, %1}
4628 cvtsi2sd\t{%1, %0|%0, %1}"
4629 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4630 (set_attr "mode" "DF")
4631 (set_attr "athlon_decode" "*,*,double,direct")
4632 (set_attr "fp_int_src" "true")])
4633
4634 (define_insn "*floatsidf2_sse"
4635 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4636 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4637 "TARGET_SSE2"
4638 "cvtsi2sd\t{%1, %0|%0, %1}"
4639 [(set_attr "type" "sseicvt")
4640 (set_attr "mode" "DF")
4641 (set_attr "athlon_decode" "double,direct")
4642 (set_attr "fp_int_src" "true")])
4643
4644 (define_expand "floatdidf2"
4645 [(set (match_operand:DF 0 "register_operand" "")
4646 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4647 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4648 "")
4649
4650 (define_insn "*floatdidf2_i387_only"
4651 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4652 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4653 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4654 "@
4655 fild%z1\t%1
4656 #"
4657 [(set_attr "type" "fmov,multi")
4658 (set_attr "mode" "DF")
4659 (set_attr "fp_int_src" "true")])
4660
4661 (define_insn "*floatdidf2_i387"
4662 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4663 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4664 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4665 "@
4666 fild%z1\t%1
4667 #
4668 cvtsi2sd{q}\t{%1, %0|%0, %1}
4669 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4670 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4671 (set_attr "mode" "DF")
4672 (set_attr "athlon_decode" "*,*,double,direct")
4673 (set_attr "fp_int_src" "true")])
4674
4675 (define_insn "*floatdidf2_sse"
4676 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4677 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4678 "TARGET_SSE2"
4679 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4680 [(set_attr "type" "sseicvt")
4681 (set_attr "mode" "DF")
4682 (set_attr "athlon_decode" "double,direct")
4683 (set_attr "fp_int_src" "true")])
4684
4685 (define_insn "floathixf2"
4686 [(set (match_operand:XF 0 "register_operand" "=f,f")
4687 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4688 "TARGET_80387"
4689 "@
4690 fild%z1\t%1
4691 #"
4692 [(set_attr "type" "fmov,multi")
4693 (set_attr "mode" "XF")
4694 (set_attr "fp_int_src" "true")])
4695
4696 (define_insn "floatsixf2"
4697 [(set (match_operand:XF 0 "register_operand" "=f,f")
4698 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4699 "TARGET_80387"
4700 "@
4701 fild%z1\t%1
4702 #"
4703 [(set_attr "type" "fmov,multi")
4704 (set_attr "mode" "XF")
4705 (set_attr "fp_int_src" "true")])
4706
4707 (define_insn "floatdixf2"
4708 [(set (match_operand:XF 0 "register_operand" "=f,f")
4709 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4710 "TARGET_80387"
4711 "@
4712 fild%z1\t%1
4713 #"
4714 [(set_attr "type" "fmov,multi")
4715 (set_attr "mode" "XF")
4716 (set_attr "fp_int_src" "true")])
4717
4718 ;; %%% Kill these when reload knows how to do it.
4719 (define_split
4720 [(set (match_operand 0 "fp_register_operand" "")
4721 (float (match_operand 1 "register_operand" "")))]
4722 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4723 [(const_int 0)]
4724 {
4725 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4726 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4727 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4728 ix86_free_from_memory (GET_MODE (operands[1]));
4729 DONE;
4730 })
4731
4732 (define_expand "floatunssisf2"
4733 [(use (match_operand:SF 0 "register_operand" ""))
4734 (use (match_operand:SI 1 "register_operand" ""))]
4735 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4736 "x86_emit_floatuns (operands); DONE;")
4737
4738 (define_expand "floatunsdisf2"
4739 [(use (match_operand:SF 0 "register_operand" ""))
4740 (use (match_operand:DI 1 "register_operand" ""))]
4741 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4742 "x86_emit_floatuns (operands); DONE;")
4743
4744 (define_expand "floatunsdidf2"
4745 [(use (match_operand:DF 0 "register_operand" ""))
4746 (use (match_operand:DI 1 "register_operand" ""))]
4747 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4748 "x86_emit_floatuns (operands); DONE;")
4749 \f
4750 ;; SSE extract/set expanders
4751
4752 (define_expand "vec_setv2df"
4753 [(match_operand:V2DF 0 "register_operand" "")
4754 (match_operand:DF 1 "register_operand" "")
4755 (match_operand 2 "const_int_operand" "")]
4756 "TARGET_SSE2"
4757 {
4758 switch (INTVAL (operands[2]))
4759 {
4760 case 0:
4761 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4762 simplify_gen_subreg (V2DFmode, operands[1],
4763 DFmode, 0)));
4764 break;
4765 case 1:
4766 {
4767 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4768
4769 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4770 }
4771 break;
4772 default:
4773 abort ();
4774 }
4775 DONE;
4776 })
4777
4778 (define_expand "vec_extractv2df"
4779 [(match_operand:DF 0 "register_operand" "")
4780 (match_operand:V2DF 1 "register_operand" "")
4781 (match_operand 2 "const_int_operand" "")]
4782 "TARGET_SSE2"
4783 {
4784 switch (INTVAL (operands[2]))
4785 {
4786 case 0:
4787 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4788 break;
4789 case 1:
4790 {
4791 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4792
4793 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4794 }
4795 break;
4796 default:
4797 abort ();
4798 }
4799 DONE;
4800 })
4801
4802 (define_expand "vec_initv2df"
4803 [(match_operand:V2DF 0 "register_operand" "")
4804 (match_operand 1 "" "")]
4805 "TARGET_SSE2"
4806 {
4807 ix86_expand_vector_init (operands[0], operands[1]);
4808 DONE;
4809 })
4810
4811 (define_expand "vec_setv4sf"
4812 [(match_operand:V4SF 0 "register_operand" "")
4813 (match_operand:SF 1 "register_operand" "")
4814 (match_operand 2 "const_int_operand" "")]
4815 "TARGET_SSE"
4816 {
4817 switch (INTVAL (operands[2]))
4818 {
4819 case 0:
4820 emit_insn (gen_sse_movss (operands[0], operands[0],
4821 simplify_gen_subreg (V4SFmode, operands[1],
4822 SFmode, 0)));
4823 break;
4824 case 1:
4825 {
4826 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4827 rtx tmp = gen_reg_rtx (V4SFmode);
4828
4829 emit_move_insn (tmp, operands[0]);
4830 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4831 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4832 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4833 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4834 }
4835 case 2:
4836 {
4837 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4838 rtx tmp = gen_reg_rtx (V4SFmode);
4839
4840 emit_move_insn (tmp, operands[0]);
4841 emit_insn (gen_sse_movss (tmp, tmp, op1));
4842 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4843 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4844 }
4845 break;
4846 case 3:
4847 {
4848 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4849 rtx tmp = gen_reg_rtx (V4SFmode);
4850
4851 emit_move_insn (tmp, operands[0]);
4852 emit_insn (gen_sse_movss (tmp, tmp, op1));
4853 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4854 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4855 }
4856 break;
4857 default:
4858 abort ();
4859 }
4860 DONE;
4861 })
4862
4863 (define_expand "vec_extractv4sf"
4864 [(match_operand:SF 0 "register_operand" "")
4865 (match_operand:V4SF 1 "register_operand" "")
4866 (match_operand 2 "const_int_operand" "")]
4867 "TARGET_SSE"
4868 {
4869 switch (INTVAL (operands[2]))
4870 {
4871 case 0:
4872 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4873 break;
4874 case 1:
4875 {
4876 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4877 rtx tmp = gen_reg_rtx (V4SFmode);
4878
4879 emit_move_insn (tmp, operands[1]);
4880 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4881 const1_rtx));
4882 }
4883 case 2:
4884 {
4885 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4886 rtx tmp = gen_reg_rtx (V4SFmode);
4887
4888 emit_move_insn (tmp, operands[1]);
4889 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4890 }
4891 case 3:
4892 {
4893 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4894 rtx tmp = gen_reg_rtx (V4SFmode);
4895
4896 emit_move_insn (tmp, operands[1]);
4897 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4898 GEN_INT (3)));
4899 }
4900 default:
4901 abort ();
4902 }
4903 DONE;
4904 })
4905
4906 (define_expand "vec_initv4sf"
4907 [(match_operand:V4SF 0 "register_operand" "")
4908 (match_operand 1 "" "")]
4909 "TARGET_SSE"
4910 {
4911 ix86_expand_vector_init (operands[0], operands[1]);
4912 DONE;
4913 })
4914 \f
4915 ;; Add instructions
4916
4917 ;; %%% splits for addsidi3
4918 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4919 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4920 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4921
4922 (define_expand "adddi3"
4923 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4924 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4925 (match_operand:DI 2 "x86_64_general_operand" "")))
4926 (clobber (reg:CC 17))]
4927 ""
4928 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4929
4930 (define_insn "*adddi3_1"
4931 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4932 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4933 (match_operand:DI 2 "general_operand" "roiF,riF")))
4934 (clobber (reg:CC 17))]
4935 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4936 "#")
4937
4938 (define_split
4939 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4940 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4941 (match_operand:DI 2 "general_operand" "")))
4942 (clobber (reg:CC 17))]
4943 "!TARGET_64BIT && reload_completed"
4944 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4945 UNSPEC_ADD_CARRY))
4946 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4947 (parallel [(set (match_dup 3)
4948 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4949 (match_dup 4))
4950 (match_dup 5)))
4951 (clobber (reg:CC 17))])]
4952 "split_di (operands+0, 1, operands+0, operands+3);
4953 split_di (operands+1, 1, operands+1, operands+4);
4954 split_di (operands+2, 1, operands+2, operands+5);")
4955
4956 (define_insn "adddi3_carry_rex64"
4957 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4958 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4959 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4960 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4961 (clobber (reg:CC 17))]
4962 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4963 "adc{q}\t{%2, %0|%0, %2}"
4964 [(set_attr "type" "alu")
4965 (set_attr "pent_pair" "pu")
4966 (set_attr "mode" "DI")])
4967
4968 (define_insn "*adddi3_cc_rex64"
4969 [(set (reg:CC 17)
4970 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4971 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4972 UNSPEC_ADD_CARRY))
4973 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4974 (plus:DI (match_dup 1) (match_dup 2)))]
4975 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4976 "add{q}\t{%2, %0|%0, %2}"
4977 [(set_attr "type" "alu")
4978 (set_attr "mode" "DI")])
4979
4980 (define_insn "addqi3_carry"
4981 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4982 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4983 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4984 (match_operand:QI 2 "general_operand" "qi,qm")))
4985 (clobber (reg:CC 17))]
4986 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4987 "adc{b}\t{%2, %0|%0, %2}"
4988 [(set_attr "type" "alu")
4989 (set_attr "pent_pair" "pu")
4990 (set_attr "mode" "QI")])
4991
4992 (define_insn "addhi3_carry"
4993 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4994 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4995 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4996 (match_operand:HI 2 "general_operand" "ri,rm")))
4997 (clobber (reg:CC 17))]
4998 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4999 "adc{w}\t{%2, %0|%0, %2}"
5000 [(set_attr "type" "alu")
5001 (set_attr "pent_pair" "pu")
5002 (set_attr "mode" "HI")])
5003
5004 (define_insn "addsi3_carry"
5005 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5006 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5007 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5008 (match_operand:SI 2 "general_operand" "ri,rm")))
5009 (clobber (reg:CC 17))]
5010 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5011 "adc{l}\t{%2, %0|%0, %2}"
5012 [(set_attr "type" "alu")
5013 (set_attr "pent_pair" "pu")
5014 (set_attr "mode" "SI")])
5015
5016 (define_insn "*addsi3_carry_zext"
5017 [(set (match_operand:DI 0 "register_operand" "=r")
5018 (zero_extend:DI
5019 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5020 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5021 (match_operand:SI 2 "general_operand" "rim"))))
5022 (clobber (reg:CC 17))]
5023 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5024 "adc{l}\t{%2, %k0|%k0, %2}"
5025 [(set_attr "type" "alu")
5026 (set_attr "pent_pair" "pu")
5027 (set_attr "mode" "SI")])
5028
5029 (define_insn "*addsi3_cc"
5030 [(set (reg:CC 17)
5031 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5032 (match_operand:SI 2 "general_operand" "ri,rm")]
5033 UNSPEC_ADD_CARRY))
5034 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5035 (plus:SI (match_dup 1) (match_dup 2)))]
5036 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5037 "add{l}\t{%2, %0|%0, %2}"
5038 [(set_attr "type" "alu")
5039 (set_attr "mode" "SI")])
5040
5041 (define_insn "addqi3_cc"
5042 [(set (reg:CC 17)
5043 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5044 (match_operand:QI 2 "general_operand" "qi,qm")]
5045 UNSPEC_ADD_CARRY))
5046 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5047 (plus:QI (match_dup 1) (match_dup 2)))]
5048 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5049 "add{b}\t{%2, %0|%0, %2}"
5050 [(set_attr "type" "alu")
5051 (set_attr "mode" "QI")])
5052
5053 (define_expand "addsi3"
5054 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5055 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5056 (match_operand:SI 2 "general_operand" "")))
5057 (clobber (reg:CC 17))])]
5058 ""
5059 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5060
5061 (define_insn "*lea_1"
5062 [(set (match_operand:SI 0 "register_operand" "=r")
5063 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5064 "!TARGET_64BIT"
5065 "lea{l}\t{%a1, %0|%0, %a1}"
5066 [(set_attr "type" "lea")
5067 (set_attr "mode" "SI")])
5068
5069 (define_insn "*lea_1_rex64"
5070 [(set (match_operand:SI 0 "register_operand" "=r")
5071 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5072 "TARGET_64BIT"
5073 "lea{l}\t{%a1, %0|%0, %a1}"
5074 [(set_attr "type" "lea")
5075 (set_attr "mode" "SI")])
5076
5077 (define_insn "*lea_1_zext"
5078 [(set (match_operand:DI 0 "register_operand" "=r")
5079 (zero_extend:DI
5080 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5081 "TARGET_64BIT"
5082 "lea{l}\t{%a1, %k0|%k0, %a1}"
5083 [(set_attr "type" "lea")
5084 (set_attr "mode" "SI")])
5085
5086 (define_insn "*lea_2_rex64"
5087 [(set (match_operand:DI 0 "register_operand" "=r")
5088 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5089 "TARGET_64BIT"
5090 "lea{q}\t{%a1, %0|%0, %a1}"
5091 [(set_attr "type" "lea")
5092 (set_attr "mode" "DI")])
5093
5094 ;; The lea patterns for non-Pmodes needs to be matched by several
5095 ;; insns converted to real lea by splitters.
5096
5097 (define_insn_and_split "*lea_general_1"
5098 [(set (match_operand 0 "register_operand" "=r")
5099 (plus (plus (match_operand 1 "index_register_operand" "r")
5100 (match_operand 2 "register_operand" "r"))
5101 (match_operand 3 "immediate_operand" "i")))]
5102 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5107 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5108 || GET_MODE (operands[3]) == VOIDmode)"
5109 "#"
5110 "&& reload_completed"
5111 [(const_int 0)]
5112 {
5113 rtx pat;
5114 operands[0] = gen_lowpart (SImode, operands[0]);
5115 operands[1] = gen_lowpart (Pmode, operands[1]);
5116 operands[2] = gen_lowpart (Pmode, operands[2]);
5117 operands[3] = gen_lowpart (Pmode, operands[3]);
5118 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5119 operands[3]);
5120 if (Pmode != SImode)
5121 pat = gen_rtx_SUBREG (SImode, pat, 0);
5122 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5123 DONE;
5124 }
5125 [(set_attr "type" "lea")
5126 (set_attr "mode" "SI")])
5127
5128 (define_insn_and_split "*lea_general_1_zext"
5129 [(set (match_operand:DI 0 "register_operand" "=r")
5130 (zero_extend:DI
5131 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5132 (match_operand:SI 2 "register_operand" "r"))
5133 (match_operand:SI 3 "immediate_operand" "i"))))]
5134 "TARGET_64BIT"
5135 "#"
5136 "&& reload_completed"
5137 [(set (match_dup 0)
5138 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5139 (match_dup 2))
5140 (match_dup 3)) 0)))]
5141 {
5142 operands[1] = gen_lowpart (Pmode, operands[1]);
5143 operands[2] = gen_lowpart (Pmode, operands[2]);
5144 operands[3] = gen_lowpart (Pmode, operands[3]);
5145 }
5146 [(set_attr "type" "lea")
5147 (set_attr "mode" "SI")])
5148
5149 (define_insn_and_split "*lea_general_2"
5150 [(set (match_operand 0 "register_operand" "=r")
5151 (plus (mult (match_operand 1 "index_register_operand" "r")
5152 (match_operand 2 "const248_operand" "i"))
5153 (match_operand 3 "nonmemory_operand" "ri")))]
5154 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5155 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5156 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5157 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5158 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5159 || GET_MODE (operands[3]) == VOIDmode)"
5160 "#"
5161 "&& reload_completed"
5162 [(const_int 0)]
5163 {
5164 rtx pat;
5165 operands[0] = gen_lowpart (SImode, operands[0]);
5166 operands[1] = gen_lowpart (Pmode, operands[1]);
5167 operands[3] = gen_lowpart (Pmode, operands[3]);
5168 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5169 operands[3]);
5170 if (Pmode != SImode)
5171 pat = gen_rtx_SUBREG (SImode, pat, 0);
5172 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5173 DONE;
5174 }
5175 [(set_attr "type" "lea")
5176 (set_attr "mode" "SI")])
5177
5178 (define_insn_and_split "*lea_general_2_zext"
5179 [(set (match_operand:DI 0 "register_operand" "=r")
5180 (zero_extend:DI
5181 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5182 (match_operand:SI 2 "const248_operand" "n"))
5183 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5184 "TARGET_64BIT"
5185 "#"
5186 "&& reload_completed"
5187 [(set (match_dup 0)
5188 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5189 (match_dup 2))
5190 (match_dup 3)) 0)))]
5191 {
5192 operands[1] = gen_lowpart (Pmode, operands[1]);
5193 operands[3] = gen_lowpart (Pmode, operands[3]);
5194 }
5195 [(set_attr "type" "lea")
5196 (set_attr "mode" "SI")])
5197
5198 (define_insn_and_split "*lea_general_3"
5199 [(set (match_operand 0 "register_operand" "=r")
5200 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5201 (match_operand 2 "const248_operand" "i"))
5202 (match_operand 3 "register_operand" "r"))
5203 (match_operand 4 "immediate_operand" "i")))]
5204 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5205 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5206 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5207 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5208 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5209 "#"
5210 "&& reload_completed"
5211 [(const_int 0)]
5212 {
5213 rtx pat;
5214 operands[0] = gen_lowpart (SImode, operands[0]);
5215 operands[1] = gen_lowpart (Pmode, operands[1]);
5216 operands[3] = gen_lowpart (Pmode, operands[3]);
5217 operands[4] = gen_lowpart (Pmode, operands[4]);
5218 pat = gen_rtx_PLUS (Pmode,
5219 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5220 operands[2]),
5221 operands[3]),
5222 operands[4]);
5223 if (Pmode != SImode)
5224 pat = gen_rtx_SUBREG (SImode, pat, 0);
5225 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5226 DONE;
5227 }
5228 [(set_attr "type" "lea")
5229 (set_attr "mode" "SI")])
5230
5231 (define_insn_and_split "*lea_general_3_zext"
5232 [(set (match_operand:DI 0 "register_operand" "=r")
5233 (zero_extend:DI
5234 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5235 (match_operand:SI 2 "const248_operand" "n"))
5236 (match_operand:SI 3 "register_operand" "r"))
5237 (match_operand:SI 4 "immediate_operand" "i"))))]
5238 "TARGET_64BIT"
5239 "#"
5240 "&& reload_completed"
5241 [(set (match_dup 0)
5242 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5243 (match_dup 2))
5244 (match_dup 3))
5245 (match_dup 4)) 0)))]
5246 {
5247 operands[1] = gen_lowpart (Pmode, operands[1]);
5248 operands[3] = gen_lowpart (Pmode, operands[3]);
5249 operands[4] = gen_lowpart (Pmode, operands[4]);
5250 }
5251 [(set_attr "type" "lea")
5252 (set_attr "mode" "SI")])
5253
5254 (define_insn "*adddi_1_rex64"
5255 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5256 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5257 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5258 (clobber (reg:CC 17))]
5259 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5260 {
5261 switch (get_attr_type (insn))
5262 {
5263 case TYPE_LEA:
5264 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5265 return "lea{q}\t{%a2, %0|%0, %a2}";
5266
5267 case TYPE_INCDEC:
5268 if (! rtx_equal_p (operands[0], operands[1]))
5269 abort ();
5270 if (operands[2] == const1_rtx)
5271 return "inc{q}\t%0";
5272 else if (operands[2] == constm1_rtx)
5273 return "dec{q}\t%0";
5274 else
5275 abort ();
5276
5277 default:
5278 if (! rtx_equal_p (operands[0], operands[1]))
5279 abort ();
5280
5281 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5282 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5283 if (GET_CODE (operands[2]) == CONST_INT
5284 /* Avoid overflows. */
5285 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5286 && (INTVAL (operands[2]) == 128
5287 || (INTVAL (operands[2]) < 0
5288 && INTVAL (operands[2]) != -128)))
5289 {
5290 operands[2] = GEN_INT (-INTVAL (operands[2]));
5291 return "sub{q}\t{%2, %0|%0, %2}";
5292 }
5293 return "add{q}\t{%2, %0|%0, %2}";
5294 }
5295 }
5296 [(set (attr "type")
5297 (cond [(eq_attr "alternative" "2")
5298 (const_string "lea")
5299 ; Current assemblers are broken and do not allow @GOTOFF in
5300 ; ought but a memory context.
5301 (match_operand:DI 2 "pic_symbolic_operand" "")
5302 (const_string "lea")
5303 (match_operand:DI 2 "incdec_operand" "")
5304 (const_string "incdec")
5305 ]
5306 (const_string "alu")))
5307 (set_attr "mode" "DI")])
5308
5309 ;; Convert lea to the lea pattern to avoid flags dependency.
5310 (define_split
5311 [(set (match_operand:DI 0 "register_operand" "")
5312 (plus:DI (match_operand:DI 1 "register_operand" "")
5313 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5314 (clobber (reg:CC 17))]
5315 "TARGET_64BIT && reload_completed
5316 && true_regnum (operands[0]) != true_regnum (operands[1])"
5317 [(set (match_dup 0)
5318 (plus:DI (match_dup 1)
5319 (match_dup 2)))]
5320 "")
5321
5322 (define_insn "*adddi_2_rex64"
5323 [(set (reg 17)
5324 (compare
5325 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5326 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5327 (const_int 0)))
5328 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5329 (plus:DI (match_dup 1) (match_dup 2)))]
5330 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5331 && ix86_binary_operator_ok (PLUS, DImode, operands)
5332 /* Current assemblers are broken and do not allow @GOTOFF in
5333 ought but a memory context. */
5334 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5335 {
5336 switch (get_attr_type (insn))
5337 {
5338 case TYPE_INCDEC:
5339 if (! rtx_equal_p (operands[0], operands[1]))
5340 abort ();
5341 if (operands[2] == const1_rtx)
5342 return "inc{q}\t%0";
5343 else if (operands[2] == constm1_rtx)
5344 return "dec{q}\t%0";
5345 else
5346 abort ();
5347
5348 default:
5349 if (! rtx_equal_p (operands[0], operands[1]))
5350 abort ();
5351 /* ???? We ought to handle there the 32bit case too
5352 - do we need new constraint? */
5353 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5354 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5355 if (GET_CODE (operands[2]) == CONST_INT
5356 /* Avoid overflows. */
5357 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5358 && (INTVAL (operands[2]) == 128
5359 || (INTVAL (operands[2]) < 0
5360 && INTVAL (operands[2]) != -128)))
5361 {
5362 operands[2] = GEN_INT (-INTVAL (operands[2]));
5363 return "sub{q}\t{%2, %0|%0, %2}";
5364 }
5365 return "add{q}\t{%2, %0|%0, %2}";
5366 }
5367 }
5368 [(set (attr "type")
5369 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5370 (const_string "incdec")
5371 (const_string "alu")))
5372 (set_attr "mode" "DI")])
5373
5374 (define_insn "*adddi_3_rex64"
5375 [(set (reg 17)
5376 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5377 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5378 (clobber (match_scratch:DI 0 "=r"))]
5379 "TARGET_64BIT
5380 && ix86_match_ccmode (insn, CCZmode)
5381 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5382 /* Current assemblers are broken and do not allow @GOTOFF in
5383 ought but a memory context. */
5384 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5385 {
5386 switch (get_attr_type (insn))
5387 {
5388 case TYPE_INCDEC:
5389 if (! rtx_equal_p (operands[0], operands[1]))
5390 abort ();
5391 if (operands[2] == const1_rtx)
5392 return "inc{q}\t%0";
5393 else if (operands[2] == constm1_rtx)
5394 return "dec{q}\t%0";
5395 else
5396 abort ();
5397
5398 default:
5399 if (! rtx_equal_p (operands[0], operands[1]))
5400 abort ();
5401 /* ???? We ought to handle there the 32bit case too
5402 - do we need new constraint? */
5403 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5405 if (GET_CODE (operands[2]) == CONST_INT
5406 /* Avoid overflows. */
5407 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5408 && (INTVAL (operands[2]) == 128
5409 || (INTVAL (operands[2]) < 0
5410 && INTVAL (operands[2]) != -128)))
5411 {
5412 operands[2] = GEN_INT (-INTVAL (operands[2]));
5413 return "sub{q}\t{%2, %0|%0, %2}";
5414 }
5415 return "add{q}\t{%2, %0|%0, %2}";
5416 }
5417 }
5418 [(set (attr "type")
5419 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5420 (const_string "incdec")
5421 (const_string "alu")))
5422 (set_attr "mode" "DI")])
5423
5424 ; For comparisons against 1, -1 and 128, we may generate better code
5425 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5426 ; is matched then. We can't accept general immediate, because for
5427 ; case of overflows, the result is messed up.
5428 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5429 ; when negated.
5430 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5431 ; only for comparisons not depending on it.
5432 (define_insn "*adddi_4_rex64"
5433 [(set (reg 17)
5434 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5435 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5436 (clobber (match_scratch:DI 0 "=rm"))]
5437 "TARGET_64BIT
5438 && ix86_match_ccmode (insn, CCGCmode)"
5439 {
5440 switch (get_attr_type (insn))
5441 {
5442 case TYPE_INCDEC:
5443 if (operands[2] == constm1_rtx)
5444 return "inc{q}\t%0";
5445 else if (operands[2] == const1_rtx)
5446 return "dec{q}\t%0";
5447 else
5448 abort();
5449
5450 default:
5451 if (! rtx_equal_p (operands[0], operands[1]))
5452 abort ();
5453 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5454 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5455 if ((INTVAL (operands[2]) == -128
5456 || (INTVAL (operands[2]) > 0
5457 && INTVAL (operands[2]) != 128))
5458 /* Avoid overflows. */
5459 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5460 return "sub{q}\t{%2, %0|%0, %2}";
5461 operands[2] = GEN_INT (-INTVAL (operands[2]));
5462 return "add{q}\t{%2, %0|%0, %2}";
5463 }
5464 }
5465 [(set (attr "type")
5466 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5467 (const_string "incdec")
5468 (const_string "alu")))
5469 (set_attr "mode" "DI")])
5470
5471 (define_insn "*adddi_5_rex64"
5472 [(set (reg 17)
5473 (compare
5474 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5475 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5476 (const_int 0)))
5477 (clobber (match_scratch:DI 0 "=r"))]
5478 "TARGET_64BIT
5479 && ix86_match_ccmode (insn, CCGOCmode)
5480 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5481 /* Current assemblers are broken and do not allow @GOTOFF in
5482 ought but a memory context. */
5483 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5484 {
5485 switch (get_attr_type (insn))
5486 {
5487 case TYPE_INCDEC:
5488 if (! rtx_equal_p (operands[0], operands[1]))
5489 abort ();
5490 if (operands[2] == const1_rtx)
5491 return "inc{q}\t%0";
5492 else if (operands[2] == constm1_rtx)
5493 return "dec{q}\t%0";
5494 else
5495 abort();
5496
5497 default:
5498 if (! rtx_equal_p (operands[0], operands[1]))
5499 abort ();
5500 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5501 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5502 if (GET_CODE (operands[2]) == CONST_INT
5503 /* Avoid overflows. */
5504 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5505 && (INTVAL (operands[2]) == 128
5506 || (INTVAL (operands[2]) < 0
5507 && INTVAL (operands[2]) != -128)))
5508 {
5509 operands[2] = GEN_INT (-INTVAL (operands[2]));
5510 return "sub{q}\t{%2, %0|%0, %2}";
5511 }
5512 return "add{q}\t{%2, %0|%0, %2}";
5513 }
5514 }
5515 [(set (attr "type")
5516 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5517 (const_string "incdec")
5518 (const_string "alu")))
5519 (set_attr "mode" "DI")])
5520
5521
5522 (define_insn "*addsi_1"
5523 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5524 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5525 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5526 (clobber (reg:CC 17))]
5527 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5528 {
5529 switch (get_attr_type (insn))
5530 {
5531 case TYPE_LEA:
5532 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5533 return "lea{l}\t{%a2, %0|%0, %a2}";
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{l}\t%0";
5540 else if (operands[2] == constm1_rtx)
5541 return "dec{l}\t%0";
5542 else
5543 abort();
5544
5545 default:
5546 if (! rtx_equal_p (operands[0], operands[1]))
5547 abort ();
5548
5549 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5550 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5551 if (GET_CODE (operands[2]) == CONST_INT
5552 && (INTVAL (operands[2]) == 128
5553 || (INTVAL (operands[2]) < 0
5554 && INTVAL (operands[2]) != -128)))
5555 {
5556 operands[2] = GEN_INT (-INTVAL (operands[2]));
5557 return "sub{l}\t{%2, %0|%0, %2}";
5558 }
5559 return "add{l}\t{%2, %0|%0, %2}";
5560 }
5561 }
5562 [(set (attr "type")
5563 (cond [(eq_attr "alternative" "2")
5564 (const_string "lea")
5565 ; Current assemblers are broken and do not allow @GOTOFF in
5566 ; ought but a memory context.
5567 (match_operand:SI 2 "pic_symbolic_operand" "")
5568 (const_string "lea")
5569 (match_operand:SI 2 "incdec_operand" "")
5570 (const_string "incdec")
5571 ]
5572 (const_string "alu")))
5573 (set_attr "mode" "SI")])
5574
5575 ;; Convert lea to the lea pattern to avoid flags dependency.
5576 (define_split
5577 [(set (match_operand 0 "register_operand" "")
5578 (plus (match_operand 1 "register_operand" "")
5579 (match_operand 2 "nonmemory_operand" "")))
5580 (clobber (reg:CC 17))]
5581 "reload_completed
5582 && true_regnum (operands[0]) != true_regnum (operands[1])"
5583 [(const_int 0)]
5584 {
5585 rtx pat;
5586 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5587 may confuse gen_lowpart. */
5588 if (GET_MODE (operands[0]) != Pmode)
5589 {
5590 operands[1] = gen_lowpart (Pmode, operands[1]);
5591 operands[2] = gen_lowpart (Pmode, operands[2]);
5592 }
5593 operands[0] = gen_lowpart (SImode, operands[0]);
5594 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5595 if (Pmode != SImode)
5596 pat = gen_rtx_SUBREG (SImode, pat, 0);
5597 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5598 DONE;
5599 })
5600
5601 ;; It may seem that nonimmediate operand is proper one for operand 1.
5602 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5603 ;; we take care in ix86_binary_operator_ok to not allow two memory
5604 ;; operands so proper swapping will be done in reload. This allow
5605 ;; patterns constructed from addsi_1 to match.
5606 (define_insn "addsi_1_zext"
5607 [(set (match_operand:DI 0 "register_operand" "=r,r")
5608 (zero_extend:DI
5609 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5610 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5611 (clobber (reg:CC 17))]
5612 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5613 {
5614 switch (get_attr_type (insn))
5615 {
5616 case TYPE_LEA:
5617 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5618 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5619
5620 case TYPE_INCDEC:
5621 if (operands[2] == const1_rtx)
5622 return "inc{l}\t%k0";
5623 else if (operands[2] == constm1_rtx)
5624 return "dec{l}\t%k0";
5625 else
5626 abort();
5627
5628 default:
5629 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5630 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5631 if (GET_CODE (operands[2]) == CONST_INT
5632 && (INTVAL (operands[2]) == 128
5633 || (INTVAL (operands[2]) < 0
5634 && INTVAL (operands[2]) != -128)))
5635 {
5636 operands[2] = GEN_INT (-INTVAL (operands[2]));
5637 return "sub{l}\t{%2, %k0|%k0, %2}";
5638 }
5639 return "add{l}\t{%2, %k0|%k0, %2}";
5640 }
5641 }
5642 [(set (attr "type")
5643 (cond [(eq_attr "alternative" "1")
5644 (const_string "lea")
5645 ; Current assemblers are broken and do not allow @GOTOFF in
5646 ; ought but a memory context.
5647 (match_operand:SI 2 "pic_symbolic_operand" "")
5648 (const_string "lea")
5649 (match_operand:SI 2 "incdec_operand" "")
5650 (const_string "incdec")
5651 ]
5652 (const_string "alu")))
5653 (set_attr "mode" "SI")])
5654
5655 ;; Convert lea to the lea pattern to avoid flags dependency.
5656 (define_split
5657 [(set (match_operand:DI 0 "register_operand" "")
5658 (zero_extend:DI
5659 (plus:SI (match_operand:SI 1 "register_operand" "")
5660 (match_operand:SI 2 "nonmemory_operand" ""))))
5661 (clobber (reg:CC 17))]
5662 "TARGET_64BIT && reload_completed
5663 && true_regnum (operands[0]) != true_regnum (operands[1])"
5664 [(set (match_dup 0)
5665 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5666 {
5667 operands[1] = gen_lowpart (Pmode, operands[1]);
5668 operands[2] = gen_lowpart (Pmode, operands[2]);
5669 })
5670
5671 (define_insn "*addsi_2"
5672 [(set (reg 17)
5673 (compare
5674 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5675 (match_operand:SI 2 "general_operand" "rmni,rni"))
5676 (const_int 0)))
5677 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5678 (plus:SI (match_dup 1) (match_dup 2)))]
5679 "ix86_match_ccmode (insn, CCGOCmode)
5680 && ix86_binary_operator_ok (PLUS, SImode, operands)
5681 /* Current assemblers are broken and do not allow @GOTOFF in
5682 ought but a memory context. */
5683 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5684 {
5685 switch (get_attr_type (insn))
5686 {
5687 case TYPE_INCDEC:
5688 if (! rtx_equal_p (operands[0], operands[1]))
5689 abort ();
5690 if (operands[2] == const1_rtx)
5691 return "inc{l}\t%0";
5692 else if (operands[2] == constm1_rtx)
5693 return "dec{l}\t%0";
5694 else
5695 abort();
5696
5697 default:
5698 if (! rtx_equal_p (operands[0], operands[1]))
5699 abort ();
5700 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5701 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5702 if (GET_CODE (operands[2]) == CONST_INT
5703 && (INTVAL (operands[2]) == 128
5704 || (INTVAL (operands[2]) < 0
5705 && INTVAL (operands[2]) != -128)))
5706 {
5707 operands[2] = GEN_INT (-INTVAL (operands[2]));
5708 return "sub{l}\t{%2, %0|%0, %2}";
5709 }
5710 return "add{l}\t{%2, %0|%0, %2}";
5711 }
5712 }
5713 [(set (attr "type")
5714 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715 (const_string "incdec")
5716 (const_string "alu")))
5717 (set_attr "mode" "SI")])
5718
5719 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5720 (define_insn "*addsi_2_zext"
5721 [(set (reg 17)
5722 (compare
5723 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5724 (match_operand:SI 2 "general_operand" "rmni"))
5725 (const_int 0)))
5726 (set (match_operand:DI 0 "register_operand" "=r")
5727 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5728 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5729 && ix86_binary_operator_ok (PLUS, SImode, operands)
5730 /* Current assemblers are broken and do not allow @GOTOFF in
5731 ought but a memory context. */
5732 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5733 {
5734 switch (get_attr_type (insn))
5735 {
5736 case TYPE_INCDEC:
5737 if (operands[2] == const1_rtx)
5738 return "inc{l}\t%k0";
5739 else if (operands[2] == constm1_rtx)
5740 return "dec{l}\t%k0";
5741 else
5742 abort();
5743
5744 default:
5745 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5746 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5747 if (GET_CODE (operands[2]) == CONST_INT
5748 && (INTVAL (operands[2]) == 128
5749 || (INTVAL (operands[2]) < 0
5750 && INTVAL (operands[2]) != -128)))
5751 {
5752 operands[2] = GEN_INT (-INTVAL (operands[2]));
5753 return "sub{l}\t{%2, %k0|%k0, %2}";
5754 }
5755 return "add{l}\t{%2, %k0|%k0, %2}";
5756 }
5757 }
5758 [(set (attr "type")
5759 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5760 (const_string "incdec")
5761 (const_string "alu")))
5762 (set_attr "mode" "SI")])
5763
5764 (define_insn "*addsi_3"
5765 [(set (reg 17)
5766 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5767 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5768 (clobber (match_scratch:SI 0 "=r"))]
5769 "ix86_match_ccmode (insn, CCZmode)
5770 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5771 /* Current assemblers are broken and do not allow @GOTOFF in
5772 ought but a memory context. */
5773 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5774 {
5775 switch (get_attr_type (insn))
5776 {
5777 case TYPE_INCDEC:
5778 if (! rtx_equal_p (operands[0], operands[1]))
5779 abort ();
5780 if (operands[2] == const1_rtx)
5781 return "inc{l}\t%0";
5782 else if (operands[2] == constm1_rtx)
5783 return "dec{l}\t%0";
5784 else
5785 abort();
5786
5787 default:
5788 if (! rtx_equal_p (operands[0], operands[1]))
5789 abort ();
5790 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5791 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5792 if (GET_CODE (operands[2]) == CONST_INT
5793 && (INTVAL (operands[2]) == 128
5794 || (INTVAL (operands[2]) < 0
5795 && INTVAL (operands[2]) != -128)))
5796 {
5797 operands[2] = GEN_INT (-INTVAL (operands[2]));
5798 return "sub{l}\t{%2, %0|%0, %2}";
5799 }
5800 return "add{l}\t{%2, %0|%0, %2}";
5801 }
5802 }
5803 [(set (attr "type")
5804 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5805 (const_string "incdec")
5806 (const_string "alu")))
5807 (set_attr "mode" "SI")])
5808
5809 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5810 (define_insn "*addsi_3_zext"
5811 [(set (reg 17)
5812 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5813 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5814 (set (match_operand:DI 0 "register_operand" "=r")
5815 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5816 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5817 && ix86_binary_operator_ok (PLUS, SImode, operands)
5818 /* Current assemblers are broken and do not allow @GOTOFF in
5819 ought but a memory context. */
5820 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5821 {
5822 switch (get_attr_type (insn))
5823 {
5824 case TYPE_INCDEC:
5825 if (operands[2] == const1_rtx)
5826 return "inc{l}\t%k0";
5827 else if (operands[2] == constm1_rtx)
5828 return "dec{l}\t%k0";
5829 else
5830 abort();
5831
5832 default:
5833 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5834 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5835 if (GET_CODE (operands[2]) == CONST_INT
5836 && (INTVAL (operands[2]) == 128
5837 || (INTVAL (operands[2]) < 0
5838 && INTVAL (operands[2]) != -128)))
5839 {
5840 operands[2] = GEN_INT (-INTVAL (operands[2]));
5841 return "sub{l}\t{%2, %k0|%k0, %2}";
5842 }
5843 return "add{l}\t{%2, %k0|%k0, %2}";
5844 }
5845 }
5846 [(set (attr "type")
5847 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5848 (const_string "incdec")
5849 (const_string "alu")))
5850 (set_attr "mode" "SI")])
5851
5852 ; For comparisons against 1, -1 and 128, we may generate better code
5853 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5854 ; is matched then. We can't accept general immediate, because for
5855 ; case of overflows, the result is messed up.
5856 ; This pattern also don't hold of 0x80000000, since the value overflows
5857 ; when negated.
5858 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5859 ; only for comparisons not depending on it.
5860 (define_insn "*addsi_4"
5861 [(set (reg 17)
5862 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5863 (match_operand:SI 2 "const_int_operand" "n")))
5864 (clobber (match_scratch:SI 0 "=rm"))]
5865 "ix86_match_ccmode (insn, CCGCmode)
5866 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5867 {
5868 switch (get_attr_type (insn))
5869 {
5870 case TYPE_INCDEC:
5871 if (operands[2] == constm1_rtx)
5872 return "inc{l}\t%0";
5873 else if (operands[2] == const1_rtx)
5874 return "dec{l}\t%0";
5875 else
5876 abort();
5877
5878 default:
5879 if (! rtx_equal_p (operands[0], operands[1]))
5880 abort ();
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 ((INTVAL (operands[2]) == -128
5884 || (INTVAL (operands[2]) > 0
5885 && INTVAL (operands[2]) != 128)))
5886 return "sub{l}\t{%2, %0|%0, %2}";
5887 operands[2] = GEN_INT (-INTVAL (operands[2]));
5888 return "add{l}\t{%2, %0|%0, %2}";
5889 }
5890 }
5891 [(set (attr "type")
5892 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5893 (const_string "incdec")
5894 (const_string "alu")))
5895 (set_attr "mode" "SI")])
5896
5897 (define_insn "*addsi_5"
5898 [(set (reg 17)
5899 (compare
5900 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5901 (match_operand:SI 2 "general_operand" "rmni"))
5902 (const_int 0)))
5903 (clobber (match_scratch:SI 0 "=r"))]
5904 "ix86_match_ccmode (insn, CCGOCmode)
5905 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5906 /* Current assemblers are broken and do not allow @GOTOFF in
5907 ought but a memory context. */
5908 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5909 {
5910 switch (get_attr_type (insn))
5911 {
5912 case TYPE_INCDEC:
5913 if (! rtx_equal_p (operands[0], operands[1]))
5914 abort ();
5915 if (operands[2] == const1_rtx)
5916 return "inc{l}\t%0";
5917 else if (operands[2] == constm1_rtx)
5918 return "dec{l}\t%0";
5919 else
5920 abort();
5921
5922 default:
5923 if (! rtx_equal_p (operands[0], operands[1]))
5924 abort ();
5925 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5926 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5927 if (GET_CODE (operands[2]) == CONST_INT
5928 && (INTVAL (operands[2]) == 128
5929 || (INTVAL (operands[2]) < 0
5930 && INTVAL (operands[2]) != -128)))
5931 {
5932 operands[2] = GEN_INT (-INTVAL (operands[2]));
5933 return "sub{l}\t{%2, %0|%0, %2}";
5934 }
5935 return "add{l}\t{%2, %0|%0, %2}";
5936 }
5937 }
5938 [(set (attr "type")
5939 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5940 (const_string "incdec")
5941 (const_string "alu")))
5942 (set_attr "mode" "SI")])
5943
5944 (define_expand "addhi3"
5945 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5946 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5947 (match_operand:HI 2 "general_operand" "")))
5948 (clobber (reg:CC 17))])]
5949 "TARGET_HIMODE_MATH"
5950 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5951
5952 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5953 ;; type optimizations enabled by define-splits. This is not important
5954 ;; for PII, and in fact harmful because of partial register stalls.
5955
5956 (define_insn "*addhi_1_lea"
5957 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5958 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5959 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5960 (clobber (reg:CC 17))]
5961 "!TARGET_PARTIAL_REG_STALL
5962 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5963 {
5964 switch (get_attr_type (insn))
5965 {
5966 case TYPE_LEA:
5967 return "#";
5968 case TYPE_INCDEC:
5969 if (operands[2] == const1_rtx)
5970 return "inc{w}\t%0";
5971 else if (operands[2] == constm1_rtx)
5972 return "dec{w}\t%0";
5973 abort();
5974
5975 default:
5976 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5977 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5978 if (GET_CODE (operands[2]) == CONST_INT
5979 && (INTVAL (operands[2]) == 128
5980 || (INTVAL (operands[2]) < 0
5981 && INTVAL (operands[2]) != -128)))
5982 {
5983 operands[2] = GEN_INT (-INTVAL (operands[2]));
5984 return "sub{w}\t{%2, %0|%0, %2}";
5985 }
5986 return "add{w}\t{%2, %0|%0, %2}";
5987 }
5988 }
5989 [(set (attr "type")
5990 (if_then_else (eq_attr "alternative" "2")
5991 (const_string "lea")
5992 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5993 (const_string "incdec")
5994 (const_string "alu"))))
5995 (set_attr "mode" "HI,HI,SI")])
5996
5997 (define_insn "*addhi_1"
5998 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5999 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6000 (match_operand:HI 2 "general_operand" "ri,rm")))
6001 (clobber (reg:CC 17))]
6002 "TARGET_PARTIAL_REG_STALL
6003 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6004 {
6005 switch (get_attr_type (insn))
6006 {
6007 case TYPE_INCDEC:
6008 if (operands[2] == const1_rtx)
6009 return "inc{w}\t%0";
6010 else if (operands[2] == constm1_rtx)
6011 return "dec{w}\t%0";
6012 abort();
6013
6014 default:
6015 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6016 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6017 if (GET_CODE (operands[2]) == CONST_INT
6018 && (INTVAL (operands[2]) == 128
6019 || (INTVAL (operands[2]) < 0
6020 && INTVAL (operands[2]) != -128)))
6021 {
6022 operands[2] = GEN_INT (-INTVAL (operands[2]));
6023 return "sub{w}\t{%2, %0|%0, %2}";
6024 }
6025 return "add{w}\t{%2, %0|%0, %2}";
6026 }
6027 }
6028 [(set (attr "type")
6029 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6030 (const_string "incdec")
6031 (const_string "alu")))
6032 (set_attr "mode" "HI")])
6033
6034 (define_insn "*addhi_2"
6035 [(set (reg 17)
6036 (compare
6037 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6038 (match_operand:HI 2 "general_operand" "rmni,rni"))
6039 (const_int 0)))
6040 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6041 (plus:HI (match_dup 1) (match_dup 2)))]
6042 "ix86_match_ccmode (insn, CCGOCmode)
6043 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6044 {
6045 switch (get_attr_type (insn))
6046 {
6047 case TYPE_INCDEC:
6048 if (operands[2] == const1_rtx)
6049 return "inc{w}\t%0";
6050 else if (operands[2] == constm1_rtx)
6051 return "dec{w}\t%0";
6052 abort();
6053
6054 default:
6055 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6056 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6057 if (GET_CODE (operands[2]) == CONST_INT
6058 && (INTVAL (operands[2]) == 128
6059 || (INTVAL (operands[2]) < 0
6060 && INTVAL (operands[2]) != -128)))
6061 {
6062 operands[2] = GEN_INT (-INTVAL (operands[2]));
6063 return "sub{w}\t{%2, %0|%0, %2}";
6064 }
6065 return "add{w}\t{%2, %0|%0, %2}";
6066 }
6067 }
6068 [(set (attr "type")
6069 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6070 (const_string "incdec")
6071 (const_string "alu")))
6072 (set_attr "mode" "HI")])
6073
6074 (define_insn "*addhi_3"
6075 [(set (reg 17)
6076 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6077 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6078 (clobber (match_scratch:HI 0 "=r"))]
6079 "ix86_match_ccmode (insn, CCZmode)
6080 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6081 {
6082 switch (get_attr_type (insn))
6083 {
6084 case TYPE_INCDEC:
6085 if (operands[2] == const1_rtx)
6086 return "inc{w}\t%0";
6087 else if (operands[2] == constm1_rtx)
6088 return "dec{w}\t%0";
6089 abort();
6090
6091 default:
6092 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6093 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6094 if (GET_CODE (operands[2]) == CONST_INT
6095 && (INTVAL (operands[2]) == 128
6096 || (INTVAL (operands[2]) < 0
6097 && INTVAL (operands[2]) != -128)))
6098 {
6099 operands[2] = GEN_INT (-INTVAL (operands[2]));
6100 return "sub{w}\t{%2, %0|%0, %2}";
6101 }
6102 return "add{w}\t{%2, %0|%0, %2}";
6103 }
6104 }
6105 [(set (attr "type")
6106 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6107 (const_string "incdec")
6108 (const_string "alu")))
6109 (set_attr "mode" "HI")])
6110
6111 ; See comments above addsi_3_imm for details.
6112 (define_insn "*addhi_4"
6113 [(set (reg 17)
6114 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6115 (match_operand:HI 2 "const_int_operand" "n")))
6116 (clobber (match_scratch:HI 0 "=rm"))]
6117 "ix86_match_ccmode (insn, CCGCmode)
6118 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6119 {
6120 switch (get_attr_type (insn))
6121 {
6122 case TYPE_INCDEC:
6123 if (operands[2] == constm1_rtx)
6124 return "inc{w}\t%0";
6125 else if (operands[2] == const1_rtx)
6126 return "dec{w}\t%0";
6127 else
6128 abort();
6129
6130 default:
6131 if (! rtx_equal_p (operands[0], operands[1]))
6132 abort ();
6133 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6135 if ((INTVAL (operands[2]) == -128
6136 || (INTVAL (operands[2]) > 0
6137 && INTVAL (operands[2]) != 128)))
6138 return "sub{w}\t{%2, %0|%0, %2}";
6139 operands[2] = GEN_INT (-INTVAL (operands[2]));
6140 return "add{w}\t{%2, %0|%0, %2}";
6141 }
6142 }
6143 [(set (attr "type")
6144 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6145 (const_string "incdec")
6146 (const_string "alu")))
6147 (set_attr "mode" "SI")])
6148
6149
6150 (define_insn "*addhi_5"
6151 [(set (reg 17)
6152 (compare
6153 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6154 (match_operand:HI 2 "general_operand" "rmni"))
6155 (const_int 0)))
6156 (clobber (match_scratch:HI 0 "=r"))]
6157 "ix86_match_ccmode (insn, CCGOCmode)
6158 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6159 {
6160 switch (get_attr_type (insn))
6161 {
6162 case TYPE_INCDEC:
6163 if (operands[2] == const1_rtx)
6164 return "inc{w}\t%0";
6165 else if (operands[2] == constm1_rtx)
6166 return "dec{w}\t%0";
6167 abort();
6168
6169 default:
6170 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6171 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6172 if (GET_CODE (operands[2]) == CONST_INT
6173 && (INTVAL (operands[2]) == 128
6174 || (INTVAL (operands[2]) < 0
6175 && INTVAL (operands[2]) != -128)))
6176 {
6177 operands[2] = GEN_INT (-INTVAL (operands[2]));
6178 return "sub{w}\t{%2, %0|%0, %2}";
6179 }
6180 return "add{w}\t{%2, %0|%0, %2}";
6181 }
6182 }
6183 [(set (attr "type")
6184 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6185 (const_string "incdec")
6186 (const_string "alu")))
6187 (set_attr "mode" "HI")])
6188
6189 (define_expand "addqi3"
6190 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6191 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6192 (match_operand:QI 2 "general_operand" "")))
6193 (clobber (reg:CC 17))])]
6194 "TARGET_QIMODE_MATH"
6195 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6196
6197 ;; %%% Potential partial reg stall on alternative 2. What to do?
6198 (define_insn "*addqi_1_lea"
6199 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6200 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6201 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6202 (clobber (reg:CC 17))]
6203 "!TARGET_PARTIAL_REG_STALL
6204 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6205 {
6206 int widen = (which_alternative == 2);
6207 switch (get_attr_type (insn))
6208 {
6209 case TYPE_LEA:
6210 return "#";
6211 case TYPE_INCDEC:
6212 if (operands[2] == const1_rtx)
6213 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6214 else if (operands[2] == constm1_rtx)
6215 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6216 abort();
6217
6218 default:
6219 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6220 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6221 if (GET_CODE (operands[2]) == CONST_INT
6222 && (INTVAL (operands[2]) == 128
6223 || (INTVAL (operands[2]) < 0
6224 && INTVAL (operands[2]) != -128)))
6225 {
6226 operands[2] = GEN_INT (-INTVAL (operands[2]));
6227 if (widen)
6228 return "sub{l}\t{%2, %k0|%k0, %2}";
6229 else
6230 return "sub{b}\t{%2, %0|%0, %2}";
6231 }
6232 if (widen)
6233 return "add{l}\t{%k2, %k0|%k0, %k2}";
6234 else
6235 return "add{b}\t{%2, %0|%0, %2}";
6236 }
6237 }
6238 [(set (attr "type")
6239 (if_then_else (eq_attr "alternative" "3")
6240 (const_string "lea")
6241 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6242 (const_string "incdec")
6243 (const_string "alu"))))
6244 (set_attr "mode" "QI,QI,SI,SI")])
6245
6246 (define_insn "*addqi_1"
6247 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6248 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6249 (match_operand:QI 2 "general_operand" "qn,qmn,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_INCDEC:
6258 if (operands[2] == const1_rtx)
6259 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6260 else if (operands[2] == constm1_rtx)
6261 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6262 abort();
6263
6264 default:
6265 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6266 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6267 if (GET_CODE (operands[2]) == CONST_INT
6268 && (INTVAL (operands[2]) == 128
6269 || (INTVAL (operands[2]) < 0
6270 && INTVAL (operands[2]) != -128)))
6271 {
6272 operands[2] = GEN_INT (-INTVAL (operands[2]));
6273 if (widen)
6274 return "sub{l}\t{%2, %k0|%k0, %2}";
6275 else
6276 return "sub{b}\t{%2, %0|%0, %2}";
6277 }
6278 if (widen)
6279 return "add{l}\t{%k2, %k0|%k0, %k2}";
6280 else
6281 return "add{b}\t{%2, %0|%0, %2}";
6282 }
6283 }
6284 [(set (attr "type")
6285 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6286 (const_string "incdec")
6287 (const_string "alu")))
6288 (set_attr "mode" "QI,QI,SI")])
6289
6290 (define_insn "*addqi_1_slp"
6291 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6292 (plus:QI (match_dup 0)
6293 (match_operand:QI 1 "general_operand" "qn,qnm")))
6294 (clobber (reg:CC 17))]
6295 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6296 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6297 {
6298 switch (get_attr_type (insn))
6299 {
6300 case TYPE_INCDEC:
6301 if (operands[1] == const1_rtx)
6302 return "inc{b}\t%0";
6303 else if (operands[1] == constm1_rtx)
6304 return "dec{b}\t%0";
6305 abort();
6306
6307 default:
6308 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6309 if (GET_CODE (operands[1]) == CONST_INT
6310 && INTVAL (operands[1]) < 0)
6311 {
6312 operands[1] = GEN_INT (-INTVAL (operands[1]));
6313 return "sub{b}\t{%1, %0|%0, %1}";
6314 }
6315 return "add{b}\t{%1, %0|%0, %1}";
6316 }
6317 }
6318 [(set (attr "type")
6319 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6320 (const_string "incdec")
6321 (const_string "alu1")))
6322 (set_attr "mode" "QI")])
6323
6324 (define_insn "*addqi_2"
6325 [(set (reg 17)
6326 (compare
6327 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6328 (match_operand:QI 2 "general_operand" "qmni,qni"))
6329 (const_int 0)))
6330 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6331 (plus:QI (match_dup 1) (match_dup 2)))]
6332 "ix86_match_ccmode (insn, CCGOCmode)
6333 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6334 {
6335 switch (get_attr_type (insn))
6336 {
6337 case TYPE_INCDEC:
6338 if (operands[2] == const1_rtx)
6339 return "inc{b}\t%0";
6340 else if (operands[2] == constm1_rtx
6341 || (GET_CODE (operands[2]) == CONST_INT
6342 && INTVAL (operands[2]) == 255))
6343 return "dec{b}\t%0";
6344 abort();
6345
6346 default:
6347 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6348 if (GET_CODE (operands[2]) == CONST_INT
6349 && INTVAL (operands[2]) < 0)
6350 {
6351 operands[2] = GEN_INT (-INTVAL (operands[2]));
6352 return "sub{b}\t{%2, %0|%0, %2}";
6353 }
6354 return "add{b}\t{%2, %0|%0, %2}";
6355 }
6356 }
6357 [(set (attr "type")
6358 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6359 (const_string "incdec")
6360 (const_string "alu")))
6361 (set_attr "mode" "QI")])
6362
6363 (define_insn "*addqi_3"
6364 [(set (reg 17)
6365 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6366 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6367 (clobber (match_scratch:QI 0 "=q"))]
6368 "ix86_match_ccmode (insn, CCZmode)
6369 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6370 {
6371 switch (get_attr_type (insn))
6372 {
6373 case TYPE_INCDEC:
6374 if (operands[2] == const1_rtx)
6375 return "inc{b}\t%0";
6376 else if (operands[2] == constm1_rtx
6377 || (GET_CODE (operands[2]) == CONST_INT
6378 && INTVAL (operands[2]) == 255))
6379 return "dec{b}\t%0";
6380 abort();
6381
6382 default:
6383 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6384 if (GET_CODE (operands[2]) == CONST_INT
6385 && INTVAL (operands[2]) < 0)
6386 {
6387 operands[2] = GEN_INT (-INTVAL (operands[2]));
6388 return "sub{b}\t{%2, %0|%0, %2}";
6389 }
6390 return "add{b}\t{%2, %0|%0, %2}";
6391 }
6392 }
6393 [(set (attr "type")
6394 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6395 (const_string "incdec")
6396 (const_string "alu")))
6397 (set_attr "mode" "QI")])
6398
6399 ; See comments above addsi_3_imm for details.
6400 (define_insn "*addqi_4"
6401 [(set (reg 17)
6402 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6403 (match_operand:QI 2 "const_int_operand" "n")))
6404 (clobber (match_scratch:QI 0 "=qm"))]
6405 "ix86_match_ccmode (insn, CCGCmode)
6406 && (INTVAL (operands[2]) & 0xff) != 0x80"
6407 {
6408 switch (get_attr_type (insn))
6409 {
6410 case TYPE_INCDEC:
6411 if (operands[2] == constm1_rtx
6412 || (GET_CODE (operands[2]) == CONST_INT
6413 && INTVAL (operands[2]) == 255))
6414 return "inc{b}\t%0";
6415 else if (operands[2] == const1_rtx)
6416 return "dec{b}\t%0";
6417 else
6418 abort();
6419
6420 default:
6421 if (! rtx_equal_p (operands[0], operands[1]))
6422 abort ();
6423 if (INTVAL (operands[2]) < 0)
6424 {
6425 operands[2] = GEN_INT (-INTVAL (operands[2]));
6426 return "add{b}\t{%2, %0|%0, %2}";
6427 }
6428 return "sub{b}\t{%2, %0|%0, %2}";
6429 }
6430 }
6431 [(set (attr "type")
6432 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6433 (const_string "incdec")
6434 (const_string "alu")))
6435 (set_attr "mode" "QI")])
6436
6437
6438 (define_insn "*addqi_5"
6439 [(set (reg 17)
6440 (compare
6441 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6442 (match_operand:QI 2 "general_operand" "qmni"))
6443 (const_int 0)))
6444 (clobber (match_scratch:QI 0 "=q"))]
6445 "ix86_match_ccmode (insn, CCGOCmode)
6446 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6447 {
6448 switch (get_attr_type (insn))
6449 {
6450 case TYPE_INCDEC:
6451 if (operands[2] == const1_rtx)
6452 return "inc{b}\t%0";
6453 else if (operands[2] == constm1_rtx
6454 || (GET_CODE (operands[2]) == CONST_INT
6455 && INTVAL (operands[2]) == 255))
6456 return "dec{b}\t%0";
6457 abort();
6458
6459 default:
6460 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6461 if (GET_CODE (operands[2]) == CONST_INT
6462 && INTVAL (operands[2]) < 0)
6463 {
6464 operands[2] = GEN_INT (-INTVAL (operands[2]));
6465 return "sub{b}\t{%2, %0|%0, %2}";
6466 }
6467 return "add{b}\t{%2, %0|%0, %2}";
6468 }
6469 }
6470 [(set (attr "type")
6471 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6472 (const_string "incdec")
6473 (const_string "alu")))
6474 (set_attr "mode" "QI")])
6475
6476
6477 (define_insn "addqi_ext_1"
6478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6479 (const_int 8)
6480 (const_int 8))
6481 (plus:SI
6482 (zero_extract:SI
6483 (match_operand 1 "ext_register_operand" "0")
6484 (const_int 8)
6485 (const_int 8))
6486 (match_operand:QI 2 "general_operand" "Qmn")))
6487 (clobber (reg:CC 17))]
6488 "!TARGET_64BIT"
6489 {
6490 switch (get_attr_type (insn))
6491 {
6492 case TYPE_INCDEC:
6493 if (operands[2] == const1_rtx)
6494 return "inc{b}\t%h0";
6495 else if (operands[2] == constm1_rtx
6496 || (GET_CODE (operands[2]) == CONST_INT
6497 && INTVAL (operands[2]) == 255))
6498 return "dec{b}\t%h0";
6499 abort();
6500
6501 default:
6502 return "add{b}\t{%2, %h0|%h0, %2}";
6503 }
6504 }
6505 [(set (attr "type")
6506 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6507 (const_string "incdec")
6508 (const_string "alu")))
6509 (set_attr "mode" "QI")])
6510
6511 (define_insn "*addqi_ext_1_rex64"
6512 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6513 (const_int 8)
6514 (const_int 8))
6515 (plus:SI
6516 (zero_extract:SI
6517 (match_operand 1 "ext_register_operand" "0")
6518 (const_int 8)
6519 (const_int 8))
6520 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6521 (clobber (reg:CC 17))]
6522 "TARGET_64BIT"
6523 {
6524 switch (get_attr_type (insn))
6525 {
6526 case TYPE_INCDEC:
6527 if (operands[2] == const1_rtx)
6528 return "inc{b}\t%h0";
6529 else if (operands[2] == constm1_rtx
6530 || (GET_CODE (operands[2]) == CONST_INT
6531 && INTVAL (operands[2]) == 255))
6532 return "dec{b}\t%h0";
6533 abort();
6534
6535 default:
6536 return "add{b}\t{%2, %h0|%h0, %2}";
6537 }
6538 }
6539 [(set (attr "type")
6540 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6541 (const_string "incdec")
6542 (const_string "alu")))
6543 (set_attr "mode" "QI")])
6544
6545 (define_insn "*addqi_ext_2"
6546 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6547 (const_int 8)
6548 (const_int 8))
6549 (plus:SI
6550 (zero_extract:SI
6551 (match_operand 1 "ext_register_operand" "%0")
6552 (const_int 8)
6553 (const_int 8))
6554 (zero_extract:SI
6555 (match_operand 2 "ext_register_operand" "Q")
6556 (const_int 8)
6557 (const_int 8))))
6558 (clobber (reg:CC 17))]
6559 ""
6560 "add{b}\t{%h2, %h0|%h0, %h2}"
6561 [(set_attr "type" "alu")
6562 (set_attr "mode" "QI")])
6563
6564 ;; The patterns that match these are at the end of this file.
6565
6566 (define_expand "addxf3"
6567 [(set (match_operand:XF 0 "register_operand" "")
6568 (plus:XF (match_operand:XF 1 "register_operand" "")
6569 (match_operand:XF 2 "register_operand" "")))]
6570 "TARGET_80387"
6571 "")
6572
6573 (define_expand "adddf3"
6574 [(set (match_operand:DF 0 "register_operand" "")
6575 (plus:DF (match_operand:DF 1 "register_operand" "")
6576 (match_operand:DF 2 "nonimmediate_operand" "")))]
6577 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6578 "")
6579
6580 (define_expand "addsf3"
6581 [(set (match_operand:SF 0 "register_operand" "")
6582 (plus:SF (match_operand:SF 1 "register_operand" "")
6583 (match_operand:SF 2 "nonimmediate_operand" "")))]
6584 "TARGET_80387 || TARGET_SSE_MATH"
6585 "")
6586 \f
6587 ;; Subtract instructions
6588
6589 ;; %%% splits for subsidi3
6590
6591 (define_expand "subdi3"
6592 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6593 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6594 (match_operand:DI 2 "x86_64_general_operand" "")))
6595 (clobber (reg:CC 17))])]
6596 ""
6597 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6598
6599 (define_insn "*subdi3_1"
6600 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6601 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6602 (match_operand:DI 2 "general_operand" "roiF,riF")))
6603 (clobber (reg:CC 17))]
6604 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6605 "#")
6606
6607 (define_split
6608 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6609 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6610 (match_operand:DI 2 "general_operand" "")))
6611 (clobber (reg:CC 17))]
6612 "!TARGET_64BIT && reload_completed"
6613 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6614 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6615 (parallel [(set (match_dup 3)
6616 (minus:SI (match_dup 4)
6617 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6618 (match_dup 5))))
6619 (clobber (reg:CC 17))])]
6620 "split_di (operands+0, 1, operands+0, operands+3);
6621 split_di (operands+1, 1, operands+1, operands+4);
6622 split_di (operands+2, 1, operands+2, operands+5);")
6623
6624 (define_insn "subdi3_carry_rex64"
6625 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6626 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6627 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6628 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6629 (clobber (reg:CC 17))]
6630 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6631 "sbb{q}\t{%2, %0|%0, %2}"
6632 [(set_attr "type" "alu")
6633 (set_attr "pent_pair" "pu")
6634 (set_attr "mode" "DI")])
6635
6636 (define_insn "*subdi_1_rex64"
6637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6638 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6639 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6640 (clobber (reg:CC 17))]
6641 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6642 "sub{q}\t{%2, %0|%0, %2}"
6643 [(set_attr "type" "alu")
6644 (set_attr "mode" "DI")])
6645
6646 (define_insn "*subdi_2_rex64"
6647 [(set (reg 17)
6648 (compare
6649 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6650 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6651 (const_int 0)))
6652 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6653 (minus:DI (match_dup 1) (match_dup 2)))]
6654 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6655 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6656 "sub{q}\t{%2, %0|%0, %2}"
6657 [(set_attr "type" "alu")
6658 (set_attr "mode" "DI")])
6659
6660 (define_insn "*subdi_3_rex63"
6661 [(set (reg 17)
6662 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6663 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6664 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6665 (minus:DI (match_dup 1) (match_dup 2)))]
6666 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6667 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6668 "sub{q}\t{%2, %0|%0, %2}"
6669 [(set_attr "type" "alu")
6670 (set_attr "mode" "DI")])
6671
6672 (define_insn "subqi3_carry"
6673 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6674 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6675 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6676 (match_operand:QI 2 "general_operand" "qi,qm"))))
6677 (clobber (reg:CC 17))]
6678 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6679 "sbb{b}\t{%2, %0|%0, %2}"
6680 [(set_attr "type" "alu")
6681 (set_attr "pent_pair" "pu")
6682 (set_attr "mode" "QI")])
6683
6684 (define_insn "subhi3_carry"
6685 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6686 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6687 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6688 (match_operand:HI 2 "general_operand" "ri,rm"))))
6689 (clobber (reg:CC 17))]
6690 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6691 "sbb{w}\t{%2, %0|%0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "pent_pair" "pu")
6694 (set_attr "mode" "HI")])
6695
6696 (define_insn "subsi3_carry"
6697 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6698 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6699 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6700 (match_operand:SI 2 "general_operand" "ri,rm"))))
6701 (clobber (reg:CC 17))]
6702 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6703 "sbb{l}\t{%2, %0|%0, %2}"
6704 [(set_attr "type" "alu")
6705 (set_attr "pent_pair" "pu")
6706 (set_attr "mode" "SI")])
6707
6708 (define_insn "subsi3_carry_zext"
6709 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6710 (zero_extend:DI
6711 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6712 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6713 (match_operand:SI 2 "general_operand" "ri,rm")))))
6714 (clobber (reg:CC 17))]
6715 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6716 "sbb{l}\t{%2, %k0|%k0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "pent_pair" "pu")
6719 (set_attr "mode" "SI")])
6720
6721 (define_expand "subsi3"
6722 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6723 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6724 (match_operand:SI 2 "general_operand" "")))
6725 (clobber (reg:CC 17))])]
6726 ""
6727 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6728
6729 (define_insn "*subsi_1"
6730 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6731 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6732 (match_operand:SI 2 "general_operand" "ri,rm")))
6733 (clobber (reg:CC 17))]
6734 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %0|%0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6738
6739 (define_insn "*subsi_1_zext"
6740 [(set (match_operand:DI 0 "register_operand" "=r")
6741 (zero_extend:DI
6742 (minus:SI (match_operand:SI 1 "register_operand" "0")
6743 (match_operand:SI 2 "general_operand" "rim"))))
6744 (clobber (reg:CC 17))]
6745 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6746 "sub{l}\t{%2, %k0|%k0, %2}"
6747 [(set_attr "type" "alu")
6748 (set_attr "mode" "SI")])
6749
6750 (define_insn "*subsi_2"
6751 [(set (reg 17)
6752 (compare
6753 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6754 (match_operand:SI 2 "general_operand" "ri,rm"))
6755 (const_int 0)))
6756 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6757 (minus:SI (match_dup 1) (match_dup 2)))]
6758 "ix86_match_ccmode (insn, CCGOCmode)
6759 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6760 "sub{l}\t{%2, %0|%0, %2}"
6761 [(set_attr "type" "alu")
6762 (set_attr "mode" "SI")])
6763
6764 (define_insn "*subsi_2_zext"
6765 [(set (reg 17)
6766 (compare
6767 (minus:SI (match_operand:SI 1 "register_operand" "0")
6768 (match_operand:SI 2 "general_operand" "rim"))
6769 (const_int 0)))
6770 (set (match_operand:DI 0 "register_operand" "=r")
6771 (zero_extend:DI
6772 (minus:SI (match_dup 1)
6773 (match_dup 2))))]
6774 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6775 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6776 "sub{l}\t{%2, %k0|%k0, %2}"
6777 [(set_attr "type" "alu")
6778 (set_attr "mode" "SI")])
6779
6780 (define_insn "*subsi_3"
6781 [(set (reg 17)
6782 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6783 (match_operand:SI 2 "general_operand" "ri,rm")))
6784 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6785 (minus:SI (match_dup 1) (match_dup 2)))]
6786 "ix86_match_ccmode (insn, CCmode)
6787 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6788 "sub{l}\t{%2, %0|%0, %2}"
6789 [(set_attr "type" "alu")
6790 (set_attr "mode" "SI")])
6791
6792 (define_insn "*subsi_3_zext"
6793 [(set (reg 17)
6794 (compare (match_operand:SI 1 "register_operand" "0")
6795 (match_operand:SI 2 "general_operand" "rim")))
6796 (set (match_operand:DI 0 "register_operand" "=r")
6797 (zero_extend:DI
6798 (minus:SI (match_dup 1)
6799 (match_dup 2))))]
6800 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6801 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6802 "sub{q}\t{%2, %0|%0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "DI")])
6805
6806 (define_expand "subhi3"
6807 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6808 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6809 (match_operand:HI 2 "general_operand" "")))
6810 (clobber (reg:CC 17))])]
6811 "TARGET_HIMODE_MATH"
6812 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6813
6814 (define_insn "*subhi_1"
6815 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6816 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6817 (match_operand:HI 2 "general_operand" "ri,rm")))
6818 (clobber (reg:CC 17))]
6819 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6820 "sub{w}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "HI")])
6823
6824 (define_insn "*subhi_2"
6825 [(set (reg 17)
6826 (compare
6827 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6828 (match_operand:HI 2 "general_operand" "ri,rm"))
6829 (const_int 0)))
6830 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6831 (minus:HI (match_dup 1) (match_dup 2)))]
6832 "ix86_match_ccmode (insn, CCGOCmode)
6833 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6834 "sub{w}\t{%2, %0|%0, %2}"
6835 [(set_attr "type" "alu")
6836 (set_attr "mode" "HI")])
6837
6838 (define_insn "*subhi_3"
6839 [(set (reg 17)
6840 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6841 (match_operand:HI 2 "general_operand" "ri,rm")))
6842 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6843 (minus:HI (match_dup 1) (match_dup 2)))]
6844 "ix86_match_ccmode (insn, CCmode)
6845 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6846 "sub{w}\t{%2, %0|%0, %2}"
6847 [(set_attr "type" "alu")
6848 (set_attr "mode" "HI")])
6849
6850 (define_expand "subqi3"
6851 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6852 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6853 (match_operand:QI 2 "general_operand" "")))
6854 (clobber (reg:CC 17))])]
6855 "TARGET_QIMODE_MATH"
6856 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6857
6858 (define_insn "*subqi_1"
6859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6860 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6861 (match_operand:QI 2 "general_operand" "qn,qmn")))
6862 (clobber (reg:CC 17))]
6863 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6864 "sub{b}\t{%2, %0|%0, %2}"
6865 [(set_attr "type" "alu")
6866 (set_attr "mode" "QI")])
6867
6868 (define_insn "*subqi_1_slp"
6869 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6870 (minus:QI (match_dup 0)
6871 (match_operand:QI 1 "general_operand" "qn,qmn")))
6872 (clobber (reg:CC 17))]
6873 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6874 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6875 "sub{b}\t{%1, %0|%0, %1}"
6876 [(set_attr "type" "alu1")
6877 (set_attr "mode" "QI")])
6878
6879 (define_insn "*subqi_2"
6880 [(set (reg 17)
6881 (compare
6882 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6883 (match_operand:QI 2 "general_operand" "qi,qm"))
6884 (const_int 0)))
6885 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6886 (minus:HI (match_dup 1) (match_dup 2)))]
6887 "ix86_match_ccmode (insn, CCGOCmode)
6888 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6889 "sub{b}\t{%2, %0|%0, %2}"
6890 [(set_attr "type" "alu")
6891 (set_attr "mode" "QI")])
6892
6893 (define_insn "*subqi_3"
6894 [(set (reg 17)
6895 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6896 (match_operand:QI 2 "general_operand" "qi,qm")))
6897 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6898 (minus:HI (match_dup 1) (match_dup 2)))]
6899 "ix86_match_ccmode (insn, CCmode)
6900 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6901 "sub{b}\t{%2, %0|%0, %2}"
6902 [(set_attr "type" "alu")
6903 (set_attr "mode" "QI")])
6904
6905 ;; The patterns that match these are at the end of this file.
6906
6907 (define_expand "subxf3"
6908 [(set (match_operand:XF 0 "register_operand" "")
6909 (minus:XF (match_operand:XF 1 "register_operand" "")
6910 (match_operand:XF 2 "register_operand" "")))]
6911 "TARGET_80387"
6912 "")
6913
6914 (define_expand "subdf3"
6915 [(set (match_operand:DF 0 "register_operand" "")
6916 (minus:DF (match_operand:DF 1 "register_operand" "")
6917 (match_operand:DF 2 "nonimmediate_operand" "")))]
6918 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6919 "")
6920
6921 (define_expand "subsf3"
6922 [(set (match_operand:SF 0 "register_operand" "")
6923 (minus:SF (match_operand:SF 1 "register_operand" "")
6924 (match_operand:SF 2 "nonimmediate_operand" "")))]
6925 "TARGET_80387 || TARGET_SSE_MATH"
6926 "")
6927 \f
6928 ;; Multiply instructions
6929
6930 (define_expand "muldi3"
6931 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6932 (mult:DI (match_operand:DI 1 "register_operand" "")
6933 (match_operand:DI 2 "x86_64_general_operand" "")))
6934 (clobber (reg:CC 17))])]
6935 "TARGET_64BIT"
6936 "")
6937
6938 (define_insn "*muldi3_1_rex64"
6939 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6940 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6941 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6942 (clobber (reg:CC 17))]
6943 "TARGET_64BIT
6944 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6945 "@
6946 imul{q}\t{%2, %1, %0|%0, %1, %2}
6947 imul{q}\t{%2, %1, %0|%0, %1, %2}
6948 imul{q}\t{%2, %0|%0, %2}"
6949 [(set_attr "type" "imul")
6950 (set_attr "prefix_0f" "0,0,1")
6951 (set (attr "athlon_decode")
6952 (cond [(eq_attr "cpu" "athlon")
6953 (const_string "vector")
6954 (eq_attr "alternative" "1")
6955 (const_string "vector")
6956 (and (eq_attr "alternative" "2")
6957 (match_operand 1 "memory_operand" ""))
6958 (const_string "vector")]
6959 (const_string "direct")))
6960 (set_attr "mode" "DI")])
6961
6962 (define_expand "mulsi3"
6963 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6964 (mult:SI (match_operand:SI 1 "register_operand" "")
6965 (match_operand:SI 2 "general_operand" "")))
6966 (clobber (reg:CC 17))])]
6967 ""
6968 "")
6969
6970 (define_insn "*mulsi3_1"
6971 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6972 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6973 (match_operand:SI 2 "general_operand" "K,i,mr")))
6974 (clobber (reg:CC 17))]
6975 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6976 "@
6977 imul{l}\t{%2, %1, %0|%0, %1, %2}
6978 imul{l}\t{%2, %1, %0|%0, %1, %2}
6979 imul{l}\t{%2, %0|%0, %2}"
6980 [(set_attr "type" "imul")
6981 (set_attr "prefix_0f" "0,0,1")
6982 (set (attr "athlon_decode")
6983 (cond [(eq_attr "cpu" "athlon")
6984 (const_string "vector")
6985 (eq_attr "alternative" "1")
6986 (const_string "vector")
6987 (and (eq_attr "alternative" "2")
6988 (match_operand 1 "memory_operand" ""))
6989 (const_string "vector")]
6990 (const_string "direct")))
6991 (set_attr "mode" "SI")])
6992
6993 (define_insn "*mulsi3_1_zext"
6994 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6995 (zero_extend:DI
6996 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6997 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6998 (clobber (reg:CC 17))]
6999 "TARGET_64BIT
7000 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7001 "@
7002 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7003 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7004 imul{l}\t{%2, %k0|%k0, %2}"
7005 [(set_attr "type" "imul")
7006 (set_attr "prefix_0f" "0,0,1")
7007 (set (attr "athlon_decode")
7008 (cond [(eq_attr "cpu" "athlon")
7009 (const_string "vector")
7010 (eq_attr "alternative" "1")
7011 (const_string "vector")
7012 (and (eq_attr "alternative" "2")
7013 (match_operand 1 "memory_operand" ""))
7014 (const_string "vector")]
7015 (const_string "direct")))
7016 (set_attr "mode" "SI")])
7017
7018 (define_expand "mulhi3"
7019 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7020 (mult:HI (match_operand:HI 1 "register_operand" "")
7021 (match_operand:HI 2 "general_operand" "")))
7022 (clobber (reg:CC 17))])]
7023 "TARGET_HIMODE_MATH"
7024 "")
7025
7026 (define_insn "*mulhi3_1"
7027 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7028 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7029 (match_operand:HI 2 "general_operand" "K,i,mr")))
7030 (clobber (reg:CC 17))]
7031 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7032 "@
7033 imul{w}\t{%2, %1, %0|%0, %1, %2}
7034 imul{w}\t{%2, %1, %0|%0, %1, %2}
7035 imul{w}\t{%2, %0|%0, %2}"
7036 [(set_attr "type" "imul")
7037 (set_attr "prefix_0f" "0,0,1")
7038 (set (attr "athlon_decode")
7039 (cond [(eq_attr "cpu" "athlon")
7040 (const_string "vector")
7041 (eq_attr "alternative" "1,2")
7042 (const_string "vector")]
7043 (const_string "direct")))
7044 (set_attr "mode" "HI")])
7045
7046 (define_expand "mulqi3"
7047 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7048 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7049 (match_operand:QI 2 "register_operand" "")))
7050 (clobber (reg:CC 17))])]
7051 "TARGET_QIMODE_MATH"
7052 "")
7053
7054 (define_insn "*mulqi3_1"
7055 [(set (match_operand:QI 0 "register_operand" "=a")
7056 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7057 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7058 (clobber (reg:CC 17))]
7059 "TARGET_QIMODE_MATH
7060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7061 "mul{b}\t%2"
7062 [(set_attr "type" "imul")
7063 (set_attr "length_immediate" "0")
7064 (set (attr "athlon_decode")
7065 (if_then_else (eq_attr "cpu" "athlon")
7066 (const_string "vector")
7067 (const_string "direct")))
7068 (set_attr "mode" "QI")])
7069
7070 (define_expand "umulqihi3"
7071 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7072 (mult:HI (zero_extend:HI
7073 (match_operand:QI 1 "nonimmediate_operand" ""))
7074 (zero_extend:HI
7075 (match_operand:QI 2 "register_operand" ""))))
7076 (clobber (reg:CC 17))])]
7077 "TARGET_QIMODE_MATH"
7078 "")
7079
7080 (define_insn "*umulqihi3_1"
7081 [(set (match_operand:HI 0 "register_operand" "=a")
7082 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7083 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7084 (clobber (reg:CC 17))]
7085 "TARGET_QIMODE_MATH
7086 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7087 "mul{b}\t%2"
7088 [(set_attr "type" "imul")
7089 (set_attr "length_immediate" "0")
7090 (set (attr "athlon_decode")
7091 (if_then_else (eq_attr "cpu" "athlon")
7092 (const_string "vector")
7093 (const_string "direct")))
7094 (set_attr "mode" "QI")])
7095
7096 (define_expand "mulqihi3"
7097 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7098 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7099 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7100 (clobber (reg:CC 17))])]
7101 "TARGET_QIMODE_MATH"
7102 "")
7103
7104 (define_insn "*mulqihi3_insn"
7105 [(set (match_operand:HI 0 "register_operand" "=a")
7106 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7107 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7108 (clobber (reg:CC 17))]
7109 "TARGET_QIMODE_MATH
7110 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7111 "imul{b}\t%2"
7112 [(set_attr "type" "imul")
7113 (set_attr "length_immediate" "0")
7114 (set (attr "athlon_decode")
7115 (if_then_else (eq_attr "cpu" "athlon")
7116 (const_string "vector")
7117 (const_string "direct")))
7118 (set_attr "mode" "QI")])
7119
7120 (define_expand "umulditi3"
7121 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7122 (mult:TI (zero_extend:TI
7123 (match_operand:DI 1 "nonimmediate_operand" ""))
7124 (zero_extend:TI
7125 (match_operand:DI 2 "register_operand" ""))))
7126 (clobber (reg:CC 17))])]
7127 "TARGET_64BIT"
7128 "")
7129
7130 (define_insn "*umulditi3_insn"
7131 [(set (match_operand:TI 0 "register_operand" "=A")
7132 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7133 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7134 (clobber (reg:CC 17))]
7135 "TARGET_64BIT
7136 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7137 "mul{q}\t%2"
7138 [(set_attr "type" "imul")
7139 (set_attr "length_immediate" "0")
7140 (set (attr "athlon_decode")
7141 (if_then_else (eq_attr "cpu" "athlon")
7142 (const_string "vector")
7143 (const_string "double")))
7144 (set_attr "mode" "DI")])
7145
7146 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7147 (define_expand "umulsidi3"
7148 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7149 (mult:DI (zero_extend:DI
7150 (match_operand:SI 1 "nonimmediate_operand" ""))
7151 (zero_extend:DI
7152 (match_operand:SI 2 "register_operand" ""))))
7153 (clobber (reg:CC 17))])]
7154 "!TARGET_64BIT"
7155 "")
7156
7157 (define_insn "*umulsidi3_insn"
7158 [(set (match_operand:DI 0 "register_operand" "=A")
7159 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7160 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7161 (clobber (reg:CC 17))]
7162 "!TARGET_64BIT
7163 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7164 "mul{l}\t%2"
7165 [(set_attr "type" "imul")
7166 (set_attr "length_immediate" "0")
7167 (set (attr "athlon_decode")
7168 (if_then_else (eq_attr "cpu" "athlon")
7169 (const_string "vector")
7170 (const_string "double")))
7171 (set_attr "mode" "SI")])
7172
7173 (define_expand "mulditi3"
7174 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7175 (mult:TI (sign_extend:TI
7176 (match_operand:DI 1 "nonimmediate_operand" ""))
7177 (sign_extend:TI
7178 (match_operand:DI 2 "register_operand" ""))))
7179 (clobber (reg:CC 17))])]
7180 "TARGET_64BIT"
7181 "")
7182
7183 (define_insn "*mulditi3_insn"
7184 [(set (match_operand:TI 0 "register_operand" "=A")
7185 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7186 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7187 (clobber (reg:CC 17))]
7188 "TARGET_64BIT
7189 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7190 "imul{q}\t%2"
7191 [(set_attr "type" "imul")
7192 (set_attr "length_immediate" "0")
7193 (set (attr "athlon_decode")
7194 (if_then_else (eq_attr "cpu" "athlon")
7195 (const_string "vector")
7196 (const_string "double")))
7197 (set_attr "mode" "DI")])
7198
7199 (define_expand "mulsidi3"
7200 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7201 (mult:DI (sign_extend:DI
7202 (match_operand:SI 1 "nonimmediate_operand" ""))
7203 (sign_extend:DI
7204 (match_operand:SI 2 "register_operand" ""))))
7205 (clobber (reg:CC 17))])]
7206 "!TARGET_64BIT"
7207 "")
7208
7209 (define_insn "*mulsidi3_insn"
7210 [(set (match_operand:DI 0 "register_operand" "=A")
7211 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7212 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7213 (clobber (reg:CC 17))]
7214 "!TARGET_64BIT
7215 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7216 "imul{l}\t%2"
7217 [(set_attr "type" "imul")
7218 (set_attr "length_immediate" "0")
7219 (set (attr "athlon_decode")
7220 (if_then_else (eq_attr "cpu" "athlon")
7221 (const_string "vector")
7222 (const_string "double")))
7223 (set_attr "mode" "SI")])
7224
7225 (define_expand "umuldi3_highpart"
7226 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7227 (truncate:DI
7228 (lshiftrt:TI
7229 (mult:TI (zero_extend:TI
7230 (match_operand:DI 1 "nonimmediate_operand" ""))
7231 (zero_extend:TI
7232 (match_operand:DI 2 "register_operand" "")))
7233 (const_int 64))))
7234 (clobber (match_scratch:DI 3 ""))
7235 (clobber (reg:CC 17))])]
7236 "TARGET_64BIT"
7237 "")
7238
7239 (define_insn "*umuldi3_highpart_rex64"
7240 [(set (match_operand:DI 0 "register_operand" "=d")
7241 (truncate:DI
7242 (lshiftrt:TI
7243 (mult:TI (zero_extend:TI
7244 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7245 (zero_extend:TI
7246 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7247 (const_int 64))))
7248 (clobber (match_scratch:DI 3 "=1"))
7249 (clobber (reg:CC 17))]
7250 "TARGET_64BIT
7251 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7252 "mul{q}\t%2"
7253 [(set_attr "type" "imul")
7254 (set_attr "length_immediate" "0")
7255 (set (attr "athlon_decode")
7256 (if_then_else (eq_attr "cpu" "athlon")
7257 (const_string "vector")
7258 (const_string "double")))
7259 (set_attr "mode" "DI")])
7260
7261 (define_expand "umulsi3_highpart"
7262 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7263 (truncate:SI
7264 (lshiftrt:DI
7265 (mult:DI (zero_extend:DI
7266 (match_operand:SI 1 "nonimmediate_operand" ""))
7267 (zero_extend:DI
7268 (match_operand:SI 2 "register_operand" "")))
7269 (const_int 32))))
7270 (clobber (match_scratch:SI 3 ""))
7271 (clobber (reg:CC 17))])]
7272 ""
7273 "")
7274
7275 (define_insn "*umulsi3_highpart_insn"
7276 [(set (match_operand:SI 0 "register_operand" "=d")
7277 (truncate:SI
7278 (lshiftrt:DI
7279 (mult:DI (zero_extend:DI
7280 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7281 (zero_extend:DI
7282 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7283 (const_int 32))))
7284 (clobber (match_scratch:SI 3 "=1"))
7285 (clobber (reg:CC 17))]
7286 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7287 "mul{l}\t%2"
7288 [(set_attr "type" "imul")
7289 (set_attr "length_immediate" "0")
7290 (set (attr "athlon_decode")
7291 (if_then_else (eq_attr "cpu" "athlon")
7292 (const_string "vector")
7293 (const_string "double")))
7294 (set_attr "mode" "SI")])
7295
7296 (define_insn "*umulsi3_highpart_zext"
7297 [(set (match_operand:DI 0 "register_operand" "=d")
7298 (zero_extend:DI (truncate:SI
7299 (lshiftrt:DI
7300 (mult:DI (zero_extend:DI
7301 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7302 (zero_extend:DI
7303 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7304 (const_int 32)))))
7305 (clobber (match_scratch:SI 3 "=1"))
7306 (clobber (reg:CC 17))]
7307 "TARGET_64BIT
7308 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7309 "mul{l}\t%2"
7310 [(set_attr "type" "imul")
7311 (set_attr "length_immediate" "0")
7312 (set (attr "athlon_decode")
7313 (if_then_else (eq_attr "cpu" "athlon")
7314 (const_string "vector")
7315 (const_string "double")))
7316 (set_attr "mode" "SI")])
7317
7318 (define_expand "smuldi3_highpart"
7319 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7320 (truncate:DI
7321 (lshiftrt:TI
7322 (mult:TI (sign_extend:TI
7323 (match_operand:DI 1 "nonimmediate_operand" ""))
7324 (sign_extend:TI
7325 (match_operand:DI 2 "register_operand" "")))
7326 (const_int 64))))
7327 (clobber (match_scratch:DI 3 ""))
7328 (clobber (reg:CC 17))])]
7329 "TARGET_64BIT"
7330 "")
7331
7332 (define_insn "*smuldi3_highpart_rex64"
7333 [(set (match_operand:DI 0 "register_operand" "=d")
7334 (truncate:DI
7335 (lshiftrt:TI
7336 (mult:TI (sign_extend:TI
7337 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7338 (sign_extend:TI
7339 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7340 (const_int 64))))
7341 (clobber (match_scratch:DI 3 "=1"))
7342 (clobber (reg:CC 17))]
7343 "TARGET_64BIT
7344 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7345 "imul{q}\t%2"
7346 [(set_attr "type" "imul")
7347 (set (attr "athlon_decode")
7348 (if_then_else (eq_attr "cpu" "athlon")
7349 (const_string "vector")
7350 (const_string "double")))
7351 (set_attr "mode" "DI")])
7352
7353 (define_expand "smulsi3_highpart"
7354 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7355 (truncate:SI
7356 (lshiftrt:DI
7357 (mult:DI (sign_extend:DI
7358 (match_operand:SI 1 "nonimmediate_operand" ""))
7359 (sign_extend:DI
7360 (match_operand:SI 2 "register_operand" "")))
7361 (const_int 32))))
7362 (clobber (match_scratch:SI 3 ""))
7363 (clobber (reg:CC 17))])]
7364 ""
7365 "")
7366
7367 (define_insn "*smulsi3_highpart_insn"
7368 [(set (match_operand:SI 0 "register_operand" "=d")
7369 (truncate:SI
7370 (lshiftrt:DI
7371 (mult:DI (sign_extend:DI
7372 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7373 (sign_extend:DI
7374 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7375 (const_int 32))))
7376 (clobber (match_scratch:SI 3 "=1"))
7377 (clobber (reg:CC 17))]
7378 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7379 "imul{l}\t%2"
7380 [(set_attr "type" "imul")
7381 (set (attr "athlon_decode")
7382 (if_then_else (eq_attr "cpu" "athlon")
7383 (const_string "vector")
7384 (const_string "double")))
7385 (set_attr "mode" "SI")])
7386
7387 (define_insn "*smulsi3_highpart_zext"
7388 [(set (match_operand:DI 0 "register_operand" "=d")
7389 (zero_extend:DI (truncate:SI
7390 (lshiftrt:DI
7391 (mult:DI (sign_extend:DI
7392 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7393 (sign_extend:DI
7394 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7395 (const_int 32)))))
7396 (clobber (match_scratch:SI 3 "=1"))
7397 (clobber (reg:CC 17))]
7398 "TARGET_64BIT
7399 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7400 "imul{l}\t%2"
7401 [(set_attr "type" "imul")
7402 (set (attr "athlon_decode")
7403 (if_then_else (eq_attr "cpu" "athlon")
7404 (const_string "vector")
7405 (const_string "double")))
7406 (set_attr "mode" "SI")])
7407
7408 ;; The patterns that match these are at the end of this file.
7409
7410 (define_expand "mulxf3"
7411 [(set (match_operand:XF 0 "register_operand" "")
7412 (mult:XF (match_operand:XF 1 "register_operand" "")
7413 (match_operand:XF 2 "register_operand" "")))]
7414 "TARGET_80387"
7415 "")
7416
7417 (define_expand "muldf3"
7418 [(set (match_operand:DF 0 "register_operand" "")
7419 (mult:DF (match_operand:DF 1 "register_operand" "")
7420 (match_operand:DF 2 "nonimmediate_operand" "")))]
7421 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7422 "")
7423
7424 (define_expand "mulsf3"
7425 [(set (match_operand:SF 0 "register_operand" "")
7426 (mult:SF (match_operand:SF 1 "register_operand" "")
7427 (match_operand:SF 2 "nonimmediate_operand" "")))]
7428 "TARGET_80387 || TARGET_SSE_MATH"
7429 "")
7430 \f
7431 ;; Divide instructions
7432
7433 (define_insn "divqi3"
7434 [(set (match_operand:QI 0 "register_operand" "=a")
7435 (div:QI (match_operand:HI 1 "register_operand" "0")
7436 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7437 (clobber (reg:CC 17))]
7438 "TARGET_QIMODE_MATH"
7439 "idiv{b}\t%2"
7440 [(set_attr "type" "idiv")
7441 (set_attr "mode" "QI")])
7442
7443 (define_insn "udivqi3"
7444 [(set (match_operand:QI 0 "register_operand" "=a")
7445 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7446 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7447 (clobber (reg:CC 17))]
7448 "TARGET_QIMODE_MATH"
7449 "div{b}\t%2"
7450 [(set_attr "type" "idiv")
7451 (set_attr "mode" "QI")])
7452
7453 ;; The patterns that match these are at the end of this file.
7454
7455 (define_expand "divxf3"
7456 [(set (match_operand:XF 0 "register_operand" "")
7457 (div:XF (match_operand:XF 1 "register_operand" "")
7458 (match_operand:XF 2 "register_operand" "")))]
7459 "TARGET_80387"
7460 "")
7461
7462 (define_expand "divdf3"
7463 [(set (match_operand:DF 0 "register_operand" "")
7464 (div:DF (match_operand:DF 1 "register_operand" "")
7465 (match_operand:DF 2 "nonimmediate_operand" "")))]
7466 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7467 "")
7468
7469 (define_expand "divsf3"
7470 [(set (match_operand:SF 0 "register_operand" "")
7471 (div:SF (match_operand:SF 1 "register_operand" "")
7472 (match_operand:SF 2 "nonimmediate_operand" "")))]
7473 "TARGET_80387 || TARGET_SSE_MATH"
7474 "")
7475 \f
7476 ;; Remainder instructions.
7477
7478 (define_expand "divmoddi4"
7479 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7480 (div:DI (match_operand:DI 1 "register_operand" "")
7481 (match_operand:DI 2 "nonimmediate_operand" "")))
7482 (set (match_operand:DI 3 "register_operand" "")
7483 (mod:DI (match_dup 1) (match_dup 2)))
7484 (clobber (reg:CC 17))])]
7485 "TARGET_64BIT"
7486 "")
7487
7488 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7489 ;; Penalize eax case slightly because it results in worse scheduling
7490 ;; of code.
7491 (define_insn "*divmoddi4_nocltd_rex64"
7492 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7493 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7494 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7495 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7496 (mod:DI (match_dup 2) (match_dup 3)))
7497 (clobber (reg:CC 17))]
7498 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7499 "#"
7500 [(set_attr "type" "multi")])
7501
7502 (define_insn "*divmoddi4_cltd_rex64"
7503 [(set (match_operand:DI 0 "register_operand" "=a")
7504 (div:DI (match_operand:DI 2 "register_operand" "a")
7505 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7506 (set (match_operand:DI 1 "register_operand" "=&d")
7507 (mod:DI (match_dup 2) (match_dup 3)))
7508 (clobber (reg:CC 17))]
7509 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7510 "#"
7511 [(set_attr "type" "multi")])
7512
7513 (define_insn "*divmoddi_noext_rex64"
7514 [(set (match_operand:DI 0 "register_operand" "=a")
7515 (div:DI (match_operand:DI 1 "register_operand" "0")
7516 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7517 (set (match_operand:DI 3 "register_operand" "=d")
7518 (mod:DI (match_dup 1) (match_dup 2)))
7519 (use (match_operand:DI 4 "register_operand" "3"))
7520 (clobber (reg:CC 17))]
7521 "TARGET_64BIT"
7522 "idiv{q}\t%2"
7523 [(set_attr "type" "idiv")
7524 (set_attr "mode" "DI")])
7525
7526 (define_split
7527 [(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 && reload_completed"
7534 [(parallel [(set (match_dup 3)
7535 (ashiftrt:DI (match_dup 4) (const_int 63)))
7536 (clobber (reg:CC 17))])
7537 (parallel [(set (match_dup 0)
7538 (div:DI (reg:DI 0) (match_dup 2)))
7539 (set (match_dup 3)
7540 (mod:DI (reg:DI 0) (match_dup 2)))
7541 (use (match_dup 3))
7542 (clobber (reg:CC 17))])]
7543 {
7544 /* Avoid use of cltd in favor of a mov+shift. */
7545 if (!TARGET_USE_CLTD && !optimize_size)
7546 {
7547 if (true_regnum (operands[1]))
7548 emit_move_insn (operands[0], operands[1]);
7549 else
7550 emit_move_insn (operands[3], operands[1]);
7551 operands[4] = operands[3];
7552 }
7553 else
7554 {
7555 if (true_regnum (operands[1]))
7556 abort();
7557 operands[4] = operands[1];
7558 }
7559 })
7560
7561
7562 (define_expand "divmodsi4"
7563 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7564 (div:SI (match_operand:SI 1 "register_operand" "")
7565 (match_operand:SI 2 "nonimmediate_operand" "")))
7566 (set (match_operand:SI 3 "register_operand" "")
7567 (mod:SI (match_dup 1) (match_dup 2)))
7568 (clobber (reg:CC 17))])]
7569 ""
7570 "")
7571
7572 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7573 ;; Penalize eax case slightly because it results in worse scheduling
7574 ;; of code.
7575 (define_insn "*divmodsi4_nocltd"
7576 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7577 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7578 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7579 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7580 (mod:SI (match_dup 2) (match_dup 3)))
7581 (clobber (reg:CC 17))]
7582 "!optimize_size && !TARGET_USE_CLTD"
7583 "#"
7584 [(set_attr "type" "multi")])
7585
7586 (define_insn "*divmodsi4_cltd"
7587 [(set (match_operand:SI 0 "register_operand" "=a")
7588 (div:SI (match_operand:SI 2 "register_operand" "a")
7589 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7590 (set (match_operand:SI 1 "register_operand" "=&d")
7591 (mod:SI (match_dup 2) (match_dup 3)))
7592 (clobber (reg:CC 17))]
7593 "optimize_size || TARGET_USE_CLTD"
7594 "#"
7595 [(set_attr "type" "multi")])
7596
7597 (define_insn "*divmodsi_noext"
7598 [(set (match_operand:SI 0 "register_operand" "=a")
7599 (div:SI (match_operand:SI 1 "register_operand" "0")
7600 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7601 (set (match_operand:SI 3 "register_operand" "=d")
7602 (mod:SI (match_dup 1) (match_dup 2)))
7603 (use (match_operand:SI 4 "register_operand" "3"))
7604 (clobber (reg:CC 17))]
7605 ""
7606 "idiv{l}\t%2"
7607 [(set_attr "type" "idiv")
7608 (set_attr "mode" "SI")])
7609
7610 (define_split
7611 [(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 "reload_completed"
7618 [(parallel [(set (match_dup 3)
7619 (ashiftrt:SI (match_dup 4) (const_int 31)))
7620 (clobber (reg:CC 17))])
7621 (parallel [(set (match_dup 0)
7622 (div:SI (reg:SI 0) (match_dup 2)))
7623 (set (match_dup 3)
7624 (mod:SI (reg:SI 0) (match_dup 2)))
7625 (use (match_dup 3))
7626 (clobber (reg:CC 17))])]
7627 {
7628 /* Avoid use of cltd in favor of a mov+shift. */
7629 if (!TARGET_USE_CLTD && !optimize_size)
7630 {
7631 if (true_regnum (operands[1]))
7632 emit_move_insn (operands[0], operands[1]);
7633 else
7634 emit_move_insn (operands[3], operands[1]);
7635 operands[4] = operands[3];
7636 }
7637 else
7638 {
7639 if (true_regnum (operands[1]))
7640 abort();
7641 operands[4] = operands[1];
7642 }
7643 })
7644 ;; %%% Split me.
7645 (define_insn "divmodhi4"
7646 [(set (match_operand:HI 0 "register_operand" "=a")
7647 (div:HI (match_operand:HI 1 "register_operand" "0")
7648 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7649 (set (match_operand:HI 3 "register_operand" "=&d")
7650 (mod:HI (match_dup 1) (match_dup 2)))
7651 (clobber (reg:CC 17))]
7652 "TARGET_HIMODE_MATH"
7653 "cwtd\;idiv{w}\t%2"
7654 [(set_attr "type" "multi")
7655 (set_attr "length_immediate" "0")
7656 (set_attr "mode" "SI")])
7657
7658 (define_insn "udivmoddi4"
7659 [(set (match_operand:DI 0 "register_operand" "=a")
7660 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7661 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7662 (set (match_operand:DI 3 "register_operand" "=&d")
7663 (umod:DI (match_dup 1) (match_dup 2)))
7664 (clobber (reg:CC 17))]
7665 "TARGET_64BIT"
7666 "xor{q}\t%3, %3\;div{q}\t%2"
7667 [(set_attr "type" "multi")
7668 (set_attr "length_immediate" "0")
7669 (set_attr "mode" "DI")])
7670
7671 (define_insn "*udivmoddi4_noext"
7672 [(set (match_operand:DI 0 "register_operand" "=a")
7673 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7674 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7675 (set (match_operand:DI 3 "register_operand" "=d")
7676 (umod:DI (match_dup 1) (match_dup 2)))
7677 (use (match_dup 3))
7678 (clobber (reg:CC 17))]
7679 "TARGET_64BIT"
7680 "div{q}\t%2"
7681 [(set_attr "type" "idiv")
7682 (set_attr "mode" "DI")])
7683
7684 (define_split
7685 [(set (match_operand:DI 0 "register_operand" "")
7686 (udiv:DI (match_operand:DI 1 "register_operand" "")
7687 (match_operand:DI 2 "nonimmediate_operand" "")))
7688 (set (match_operand:DI 3 "register_operand" "")
7689 (umod:DI (match_dup 1) (match_dup 2)))
7690 (clobber (reg:CC 17))]
7691 "TARGET_64BIT && reload_completed"
7692 [(set (match_dup 3) (const_int 0))
7693 (parallel [(set (match_dup 0)
7694 (udiv:DI (match_dup 1) (match_dup 2)))
7695 (set (match_dup 3)
7696 (umod:DI (match_dup 1) (match_dup 2)))
7697 (use (match_dup 3))
7698 (clobber (reg:CC 17))])]
7699 "")
7700
7701 (define_insn "udivmodsi4"
7702 [(set (match_operand:SI 0 "register_operand" "=a")
7703 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7704 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7705 (set (match_operand:SI 3 "register_operand" "=&d")
7706 (umod:SI (match_dup 1) (match_dup 2)))
7707 (clobber (reg:CC 17))]
7708 ""
7709 "xor{l}\t%3, %3\;div{l}\t%2"
7710 [(set_attr "type" "multi")
7711 (set_attr "length_immediate" "0")
7712 (set_attr "mode" "SI")])
7713
7714 (define_insn "*udivmodsi4_noext"
7715 [(set (match_operand:SI 0 "register_operand" "=a")
7716 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7717 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7718 (set (match_operand:SI 3 "register_operand" "=d")
7719 (umod:SI (match_dup 1) (match_dup 2)))
7720 (use (match_dup 3))
7721 (clobber (reg:CC 17))]
7722 ""
7723 "div{l}\t%2"
7724 [(set_attr "type" "idiv")
7725 (set_attr "mode" "SI")])
7726
7727 (define_split
7728 [(set (match_operand:SI 0 "register_operand" "")
7729 (udiv:SI (match_operand:SI 1 "register_operand" "")
7730 (match_operand:SI 2 "nonimmediate_operand" "")))
7731 (set (match_operand:SI 3 "register_operand" "")
7732 (umod:SI (match_dup 1) (match_dup 2)))
7733 (clobber (reg:CC 17))]
7734 "reload_completed"
7735 [(set (match_dup 3) (const_int 0))
7736 (parallel [(set (match_dup 0)
7737 (udiv:SI (match_dup 1) (match_dup 2)))
7738 (set (match_dup 3)
7739 (umod:SI (match_dup 1) (match_dup 2)))
7740 (use (match_dup 3))
7741 (clobber (reg:CC 17))])]
7742 "")
7743
7744 (define_expand "udivmodhi4"
7745 [(set (match_dup 4) (const_int 0))
7746 (parallel [(set (match_operand:HI 0 "register_operand" "")
7747 (udiv:HI (match_operand:HI 1 "register_operand" "")
7748 (match_operand:HI 2 "nonimmediate_operand" "")))
7749 (set (match_operand:HI 3 "register_operand" "")
7750 (umod:HI (match_dup 1) (match_dup 2)))
7751 (use (match_dup 4))
7752 (clobber (reg:CC 17))])]
7753 "TARGET_HIMODE_MATH"
7754 "operands[4] = gen_reg_rtx (HImode);")
7755
7756 (define_insn "*udivmodhi_noext"
7757 [(set (match_operand:HI 0 "register_operand" "=a")
7758 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7759 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7760 (set (match_operand:HI 3 "register_operand" "=d")
7761 (umod:HI (match_dup 1) (match_dup 2)))
7762 (use (match_operand:HI 4 "register_operand" "3"))
7763 (clobber (reg:CC 17))]
7764 ""
7765 "div{w}\t%2"
7766 [(set_attr "type" "idiv")
7767 (set_attr "mode" "HI")])
7768
7769 ;; We can not use div/idiv for double division, because it causes
7770 ;; "division by zero" on the overflow and that's not what we expect
7771 ;; from truncate. Because true (non truncating) double division is
7772 ;; never generated, we can't create this insn anyway.
7773 ;
7774 ;(define_insn ""
7775 ; [(set (match_operand:SI 0 "register_operand" "=a")
7776 ; (truncate:SI
7777 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7778 ; (zero_extend:DI
7779 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7780 ; (set (match_operand:SI 3 "register_operand" "=d")
7781 ; (truncate:SI
7782 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7783 ; (clobber (reg:CC 17))]
7784 ; ""
7785 ; "div{l}\t{%2, %0|%0, %2}"
7786 ; [(set_attr "type" "idiv")])
7787 \f
7788 ;;- Logical AND instructions
7789
7790 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7791 ;; Note that this excludes ah.
7792
7793 (define_insn "*testdi_1_rex64"
7794 [(set (reg 17)
7795 (compare
7796 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7797 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7798 (const_int 0)))]
7799 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7800 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7801 "@
7802 test{l}\t{%k1, %k0|%k0, %k1}
7803 test{l}\t{%k1, %k0|%k0, %k1}
7804 test{q}\t{%1, %0|%0, %1}
7805 test{q}\t{%1, %0|%0, %1}
7806 test{q}\t{%1, %0|%0, %1}"
7807 [(set_attr "type" "test")
7808 (set_attr "modrm" "0,1,0,1,1")
7809 (set_attr "mode" "SI,SI,DI,DI,DI")
7810 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7811
7812 (define_insn "testsi_1"
7813 [(set (reg 17)
7814 (compare
7815 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7816 (match_operand:SI 1 "general_operand" "in,in,rin"))
7817 (const_int 0)))]
7818 "ix86_match_ccmode (insn, CCNOmode)
7819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7820 "test{l}\t{%1, %0|%0, %1}"
7821 [(set_attr "type" "test")
7822 (set_attr "modrm" "0,1,1")
7823 (set_attr "mode" "SI")
7824 (set_attr "pent_pair" "uv,np,uv")])
7825
7826 (define_expand "testsi_ccno_1"
7827 [(set (reg:CCNO 17)
7828 (compare:CCNO
7829 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7830 (match_operand:SI 1 "nonmemory_operand" ""))
7831 (const_int 0)))]
7832 ""
7833 "")
7834
7835 (define_insn "*testhi_1"
7836 [(set (reg 17)
7837 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7838 (match_operand:HI 1 "general_operand" "n,n,rn"))
7839 (const_int 0)))]
7840 "ix86_match_ccmode (insn, CCNOmode)
7841 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7842 "test{w}\t{%1, %0|%0, %1}"
7843 [(set_attr "type" "test")
7844 (set_attr "modrm" "0,1,1")
7845 (set_attr "mode" "HI")
7846 (set_attr "pent_pair" "uv,np,uv")])
7847
7848 (define_expand "testqi_ccz_1"
7849 [(set (reg:CCZ 17)
7850 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7851 (match_operand:QI 1 "nonmemory_operand" ""))
7852 (const_int 0)))]
7853 ""
7854 "")
7855
7856 (define_insn "*testqi_1"
7857 [(set (reg 17)
7858 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7859 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7860 (const_int 0)))]
7861 "ix86_match_ccmode (insn, CCNOmode)
7862 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7863 {
7864 if (which_alternative == 3)
7865 {
7866 if (GET_CODE (operands[1]) == CONST_INT
7867 && (INTVAL (operands[1]) & 0xffffff00))
7868 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7869 return "test{l}\t{%1, %k0|%k0, %1}";
7870 }
7871 return "test{b}\t{%1, %0|%0, %1}";
7872 }
7873 [(set_attr "type" "test")
7874 (set_attr "modrm" "0,1,1,1")
7875 (set_attr "mode" "QI,QI,QI,SI")
7876 (set_attr "pent_pair" "uv,np,uv,np")])
7877
7878 (define_expand "testqi_ext_ccno_0"
7879 [(set (reg:CCNO 17)
7880 (compare:CCNO
7881 (and:SI
7882 (zero_extract:SI
7883 (match_operand 0 "ext_register_operand" "")
7884 (const_int 8)
7885 (const_int 8))
7886 (match_operand 1 "const_int_operand" ""))
7887 (const_int 0)))]
7888 ""
7889 "")
7890
7891 (define_insn "*testqi_ext_0"
7892 [(set (reg 17)
7893 (compare
7894 (and:SI
7895 (zero_extract:SI
7896 (match_operand 0 "ext_register_operand" "Q")
7897 (const_int 8)
7898 (const_int 8))
7899 (match_operand 1 "const_int_operand" "n"))
7900 (const_int 0)))]
7901 "ix86_match_ccmode (insn, CCNOmode)"
7902 "test{b}\t{%1, %h0|%h0, %1}"
7903 [(set_attr "type" "test")
7904 (set_attr "mode" "QI")
7905 (set_attr "length_immediate" "1")
7906 (set_attr "pent_pair" "np")])
7907
7908 (define_insn "*testqi_ext_1"
7909 [(set (reg 17)
7910 (compare
7911 (and:SI
7912 (zero_extract:SI
7913 (match_operand 0 "ext_register_operand" "Q")
7914 (const_int 8)
7915 (const_int 8))
7916 (zero_extend:SI
7917 (match_operand:QI 1 "general_operand" "Qm")))
7918 (const_int 0)))]
7919 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7921 "test{b}\t{%1, %h0|%h0, %1}"
7922 [(set_attr "type" "test")
7923 (set_attr "mode" "QI")])
7924
7925 (define_insn "*testqi_ext_1_rex64"
7926 [(set (reg 17)
7927 (compare
7928 (and:SI
7929 (zero_extract:SI
7930 (match_operand 0 "ext_register_operand" "Q")
7931 (const_int 8)
7932 (const_int 8))
7933 (zero_extend:SI
7934 (match_operand:QI 1 "register_operand" "Q")))
7935 (const_int 0)))]
7936 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7937 "test{b}\t{%1, %h0|%h0, %1}"
7938 [(set_attr "type" "test")
7939 (set_attr "mode" "QI")])
7940
7941 (define_insn "*testqi_ext_2"
7942 [(set (reg 17)
7943 (compare
7944 (and:SI
7945 (zero_extract:SI
7946 (match_operand 0 "ext_register_operand" "Q")
7947 (const_int 8)
7948 (const_int 8))
7949 (zero_extract:SI
7950 (match_operand 1 "ext_register_operand" "Q")
7951 (const_int 8)
7952 (const_int 8)))
7953 (const_int 0)))]
7954 "ix86_match_ccmode (insn, CCNOmode)"
7955 "test{b}\t{%h1, %h0|%h0, %h1}"
7956 [(set_attr "type" "test")
7957 (set_attr "mode" "QI")])
7958
7959 ;; Combine likes to form bit extractions for some tests. Humor it.
7960 (define_insn "*testqi_ext_3"
7961 [(set (reg 17)
7962 (compare (zero_extract:SI
7963 (match_operand 0 "nonimmediate_operand" "rm")
7964 (match_operand:SI 1 "const_int_operand" "")
7965 (match_operand:SI 2 "const_int_operand" ""))
7966 (const_int 0)))]
7967 "ix86_match_ccmode (insn, CCNOmode)
7968 && (GET_MODE (operands[0]) == SImode
7969 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7970 || GET_MODE (operands[0]) == HImode
7971 || GET_MODE (operands[0]) == QImode)"
7972 "#")
7973
7974 (define_insn "*testqi_ext_3_rex64"
7975 [(set (reg 17)
7976 (compare (zero_extract:DI
7977 (match_operand 0 "nonimmediate_operand" "rm")
7978 (match_operand:DI 1 "const_int_operand" "")
7979 (match_operand:DI 2 "const_int_operand" ""))
7980 (const_int 0)))]
7981 "TARGET_64BIT
7982 && ix86_match_ccmode (insn, CCNOmode)
7983 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7984 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7985 /* Ensure that resulting mask is zero or sign extended operand. */
7986 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7987 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7988 && INTVAL (operands[1]) > 32))
7989 && (GET_MODE (operands[0]) == SImode
7990 || GET_MODE (operands[0]) == DImode
7991 || GET_MODE (operands[0]) == HImode
7992 || GET_MODE (operands[0]) == QImode)"
7993 "#")
7994
7995 (define_split
7996 [(set (reg 17)
7997 (compare (zero_extract
7998 (match_operand 0 "nonimmediate_operand" "")
7999 (match_operand 1 "const_int_operand" "")
8000 (match_operand 2 "const_int_operand" ""))
8001 (const_int 0)))]
8002 "ix86_match_ccmode (insn, CCNOmode)"
8003 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8004 {
8005 HOST_WIDE_INT len = INTVAL (operands[1]);
8006 HOST_WIDE_INT pos = INTVAL (operands[2]);
8007 HOST_WIDE_INT mask;
8008 enum machine_mode mode, submode;
8009
8010 mode = GET_MODE (operands[0]);
8011 if (GET_CODE (operands[0]) == MEM)
8012 {
8013 /* ??? Combine likes to put non-volatile mem extractions in QImode
8014 no matter the size of the test. So find a mode that works. */
8015 if (! MEM_VOLATILE_P (operands[0]))
8016 {
8017 mode = smallest_mode_for_size (pos + len, MODE_INT);
8018 operands[0] = adjust_address (operands[0], mode, 0);
8019 }
8020 }
8021 else if (GET_CODE (operands[0]) == SUBREG
8022 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8023 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8024 && pos + len <= GET_MODE_BITSIZE (submode))
8025 {
8026 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8027 mode = submode;
8028 operands[0] = SUBREG_REG (operands[0]);
8029 }
8030 else if (mode == HImode && pos + len <= 8)
8031 {
8032 /* Small HImode tests can be converted to QImode. */
8033 mode = QImode;
8034 operands[0] = gen_lowpart (QImode, operands[0]);
8035 }
8036
8037 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8038 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8039
8040 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8041 })
8042
8043 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8044 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8045 ;; this is relatively important trick.
8046 ;; Do the conversion only post-reload to avoid limiting of the register class
8047 ;; to QI regs.
8048 (define_split
8049 [(set (reg 17)
8050 (compare
8051 (and (match_operand 0 "register_operand" "")
8052 (match_operand 1 "const_int_operand" ""))
8053 (const_int 0)))]
8054 "reload_completed
8055 && QI_REG_P (operands[0])
8056 && ((ix86_match_ccmode (insn, CCZmode)
8057 && !(INTVAL (operands[1]) & ~(255 << 8)))
8058 || (ix86_match_ccmode (insn, CCNOmode)
8059 && !(INTVAL (operands[1]) & ~(127 << 8))))
8060 && GET_MODE (operands[0]) != QImode"
8061 [(set (reg:CCNO 17)
8062 (compare:CCNO
8063 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8064 (match_dup 1))
8065 (const_int 0)))]
8066 "operands[0] = gen_lowpart (SImode, operands[0]);
8067 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8068
8069 (define_split
8070 [(set (reg 17)
8071 (compare
8072 (and (match_operand 0 "nonimmediate_operand" "")
8073 (match_operand 1 "const_int_operand" ""))
8074 (const_int 0)))]
8075 "reload_completed
8076 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8077 && ((ix86_match_ccmode (insn, CCZmode)
8078 && !(INTVAL (operands[1]) & ~255))
8079 || (ix86_match_ccmode (insn, CCNOmode)
8080 && !(INTVAL (operands[1]) & ~127)))
8081 && GET_MODE (operands[0]) != QImode"
8082 [(set (reg:CCNO 17)
8083 (compare:CCNO
8084 (and:QI (match_dup 0)
8085 (match_dup 1))
8086 (const_int 0)))]
8087 "operands[0] = gen_lowpart (QImode, operands[0]);
8088 operands[1] = gen_lowpart (QImode, operands[1]);")
8089
8090
8091 ;; %%% This used to optimize known byte-wide and operations to memory,
8092 ;; and sometimes to QImode registers. If this is considered useful,
8093 ;; it should be done with splitters.
8094
8095 (define_expand "anddi3"
8096 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8097 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8098 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8099 (clobber (reg:CC 17))]
8100 "TARGET_64BIT"
8101 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8102
8103 (define_insn "*anddi_1_rex64"
8104 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8105 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8106 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8107 (clobber (reg:CC 17))]
8108 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8109 {
8110 switch (get_attr_type (insn))
8111 {
8112 case TYPE_IMOVX:
8113 {
8114 enum machine_mode mode;
8115
8116 if (GET_CODE (operands[2]) != CONST_INT)
8117 abort ();
8118 if (INTVAL (operands[2]) == 0xff)
8119 mode = QImode;
8120 else if (INTVAL (operands[2]) == 0xffff)
8121 mode = HImode;
8122 else
8123 abort ();
8124
8125 operands[1] = gen_lowpart (mode, operands[1]);
8126 if (mode == QImode)
8127 return "movz{bq|x}\t{%1,%0|%0, %1}";
8128 else
8129 return "movz{wq|x}\t{%1,%0|%0, %1}";
8130 }
8131
8132 default:
8133 if (! rtx_equal_p (operands[0], operands[1]))
8134 abort ();
8135 if (get_attr_mode (insn) == MODE_SI)
8136 return "and{l}\t{%k2, %k0|%k0, %k2}";
8137 else
8138 return "and{q}\t{%2, %0|%0, %2}";
8139 }
8140 }
8141 [(set_attr "type" "alu,alu,alu,imovx")
8142 (set_attr "length_immediate" "*,*,*,0")
8143 (set_attr "mode" "SI,DI,DI,DI")])
8144
8145 (define_insn "*anddi_2"
8146 [(set (reg 17)
8147 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8148 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8149 (const_int 0)))
8150 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8151 (and:DI (match_dup 1) (match_dup 2)))]
8152 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8153 && ix86_binary_operator_ok (AND, DImode, operands)"
8154 "@
8155 and{l}\t{%k2, %k0|%k0, %k2}
8156 and{q}\t{%2, %0|%0, %2}
8157 and{q}\t{%2, %0|%0, %2}"
8158 [(set_attr "type" "alu")
8159 (set_attr "mode" "SI,DI,DI")])
8160
8161 (define_expand "andsi3"
8162 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8163 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8164 (match_operand:SI 2 "general_operand" "")))
8165 (clobber (reg:CC 17))]
8166 ""
8167 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8168
8169 (define_insn "*andsi_1"
8170 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8171 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8172 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8173 (clobber (reg:CC 17))]
8174 "ix86_binary_operator_ok (AND, SImode, operands)"
8175 {
8176 switch (get_attr_type (insn))
8177 {
8178 case TYPE_IMOVX:
8179 {
8180 enum machine_mode mode;
8181
8182 if (GET_CODE (operands[2]) != CONST_INT)
8183 abort ();
8184 if (INTVAL (operands[2]) == 0xff)
8185 mode = QImode;
8186 else if (INTVAL (operands[2]) == 0xffff)
8187 mode = HImode;
8188 else
8189 abort ();
8190
8191 operands[1] = gen_lowpart (mode, operands[1]);
8192 if (mode == QImode)
8193 return "movz{bl|x}\t{%1,%0|%0, %1}";
8194 else
8195 return "movz{wl|x}\t{%1,%0|%0, %1}";
8196 }
8197
8198 default:
8199 if (! rtx_equal_p (operands[0], operands[1]))
8200 abort ();
8201 return "and{l}\t{%2, %0|%0, %2}";
8202 }
8203 }
8204 [(set_attr "type" "alu,alu,imovx")
8205 (set_attr "length_immediate" "*,*,0")
8206 (set_attr "mode" "SI")])
8207
8208 (define_split
8209 [(set (match_operand 0 "register_operand" "")
8210 (and (match_dup 0)
8211 (const_int -65536)))
8212 (clobber (reg:CC 17))]
8213 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8214 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8215 "operands[1] = gen_lowpart (HImode, operands[0]);")
8216
8217 (define_split
8218 [(set (match_operand 0 "ext_register_operand" "")
8219 (and (match_dup 0)
8220 (const_int -256)))
8221 (clobber (reg:CC 17))]
8222 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8223 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8224 "operands[1] = gen_lowpart (QImode, operands[0]);")
8225
8226 (define_split
8227 [(set (match_operand 0 "ext_register_operand" "")
8228 (and (match_dup 0)
8229 (const_int -65281)))
8230 (clobber (reg:CC 17))]
8231 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8232 [(parallel [(set (zero_extract:SI (match_dup 0)
8233 (const_int 8)
8234 (const_int 8))
8235 (xor:SI
8236 (zero_extract:SI (match_dup 0)
8237 (const_int 8)
8238 (const_int 8))
8239 (zero_extract:SI (match_dup 0)
8240 (const_int 8)
8241 (const_int 8))))
8242 (clobber (reg:CC 17))])]
8243 "operands[0] = gen_lowpart (SImode, operands[0]);")
8244
8245 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8246 (define_insn "*andsi_1_zext"
8247 [(set (match_operand:DI 0 "register_operand" "=r")
8248 (zero_extend:DI
8249 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250 (match_operand:SI 2 "general_operand" "rim"))))
8251 (clobber (reg:CC 17))]
8252 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8253 "and{l}\t{%2, %k0|%k0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "mode" "SI")])
8256
8257 (define_insn "*andsi_2"
8258 [(set (reg 17)
8259 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8260 (match_operand:SI 2 "general_operand" "rim,ri"))
8261 (const_int 0)))
8262 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8263 (and:SI (match_dup 1) (match_dup 2)))]
8264 "ix86_match_ccmode (insn, CCNOmode)
8265 && ix86_binary_operator_ok (AND, SImode, operands)"
8266 "and{l}\t{%2, %0|%0, %2}"
8267 [(set_attr "type" "alu")
8268 (set_attr "mode" "SI")])
8269
8270 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8271 (define_insn "*andsi_2_zext"
8272 [(set (reg 17)
8273 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8274 (match_operand:SI 2 "general_operand" "rim"))
8275 (const_int 0)))
8276 (set (match_operand:DI 0 "register_operand" "=r")
8277 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8278 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8279 && ix86_binary_operator_ok (AND, SImode, operands)"
8280 "and{l}\t{%2, %k0|%k0, %2}"
8281 [(set_attr "type" "alu")
8282 (set_attr "mode" "SI")])
8283
8284 (define_expand "andhi3"
8285 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8286 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8287 (match_operand:HI 2 "general_operand" "")))
8288 (clobber (reg:CC 17))]
8289 "TARGET_HIMODE_MATH"
8290 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8291
8292 (define_insn "*andhi_1"
8293 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8294 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8295 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8296 (clobber (reg:CC 17))]
8297 "ix86_binary_operator_ok (AND, HImode, operands)"
8298 {
8299 switch (get_attr_type (insn))
8300 {
8301 case TYPE_IMOVX:
8302 if (GET_CODE (operands[2]) != CONST_INT)
8303 abort ();
8304 if (INTVAL (operands[2]) == 0xff)
8305 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8306 abort ();
8307
8308 default:
8309 if (! rtx_equal_p (operands[0], operands[1]))
8310 abort ();
8311
8312 return "and{w}\t{%2, %0|%0, %2}";
8313 }
8314 }
8315 [(set_attr "type" "alu,alu,imovx")
8316 (set_attr "length_immediate" "*,*,0")
8317 (set_attr "mode" "HI,HI,SI")])
8318
8319 (define_insn "*andhi_2"
8320 [(set (reg 17)
8321 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8322 (match_operand:HI 2 "general_operand" "rim,ri"))
8323 (const_int 0)))
8324 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8325 (and:HI (match_dup 1) (match_dup 2)))]
8326 "ix86_match_ccmode (insn, CCNOmode)
8327 && ix86_binary_operator_ok (AND, HImode, operands)"
8328 "and{w}\t{%2, %0|%0, %2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "mode" "HI")])
8331
8332 (define_expand "andqi3"
8333 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8334 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8335 (match_operand:QI 2 "general_operand" "")))
8336 (clobber (reg:CC 17))]
8337 "TARGET_QIMODE_MATH"
8338 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8339
8340 ;; %%% Potential partial reg stall on alternative 2. What to do?
8341 (define_insn "*andqi_1"
8342 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8343 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8344 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8345 (clobber (reg:CC 17))]
8346 "ix86_binary_operator_ok (AND, QImode, operands)"
8347 "@
8348 and{b}\t{%2, %0|%0, %2}
8349 and{b}\t{%2, %0|%0, %2}
8350 and{l}\t{%k2, %k0|%k0, %k2}"
8351 [(set_attr "type" "alu")
8352 (set_attr "mode" "QI,QI,SI")])
8353
8354 (define_insn "*andqi_1_slp"
8355 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8356 (and:QI (match_dup 0)
8357 (match_operand:QI 1 "general_operand" "qi,qmi")))
8358 (clobber (reg:CC 17))]
8359 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8360 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8361 "and{b}\t{%1, %0|%0, %1}"
8362 [(set_attr "type" "alu1")
8363 (set_attr "mode" "QI")])
8364
8365 (define_insn "*andqi_2"
8366 [(set (reg 17)
8367 (compare (and:QI
8368 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8369 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8370 (const_int 0)))
8371 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8372 (and:QI (match_dup 1) (match_dup 2)))]
8373 "ix86_match_ccmode (insn, CCNOmode)
8374 && ix86_binary_operator_ok (AND, QImode, operands)"
8375 {
8376 if (which_alternative == 2)
8377 {
8378 if (GET_CODE (operands[2]) == CONST_INT
8379 && (INTVAL (operands[2]) & 0xffffff00))
8380 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8381 return "and{l}\t{%2, %k0|%k0, %2}";
8382 }
8383 return "and{b}\t{%2, %0|%0, %2}";
8384 }
8385 [(set_attr "type" "alu")
8386 (set_attr "mode" "QI,QI,SI")])
8387
8388 (define_insn "*andqi_2_slp"
8389 [(set (reg 17)
8390 (compare (and:QI
8391 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8392 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8393 (const_int 0)))
8394 (set (strict_low_part (match_dup 0))
8395 (and:QI (match_dup 0) (match_dup 1)))]
8396 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8397 && ix86_match_ccmode (insn, CCNOmode)
8398 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8399 "and{b}\t{%1, %0|%0, %1}"
8400 [(set_attr "type" "alu1")
8401 (set_attr "mode" "QI")])
8402
8403 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8404 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8405 ;; for a QImode operand, which of course failed.
8406
8407 (define_insn "andqi_ext_0"
8408 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8409 (const_int 8)
8410 (const_int 8))
8411 (and:SI
8412 (zero_extract:SI
8413 (match_operand 1 "ext_register_operand" "0")
8414 (const_int 8)
8415 (const_int 8))
8416 (match_operand 2 "const_int_operand" "n")))
8417 (clobber (reg:CC 17))]
8418 ""
8419 "and{b}\t{%2, %h0|%h0, %2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "length_immediate" "1")
8422 (set_attr "mode" "QI")])
8423
8424 ;; Generated by peephole translating test to and. This shows up
8425 ;; often in fp comparisons.
8426
8427 (define_insn "*andqi_ext_0_cc"
8428 [(set (reg 17)
8429 (compare
8430 (and:SI
8431 (zero_extract:SI
8432 (match_operand 1 "ext_register_operand" "0")
8433 (const_int 8)
8434 (const_int 8))
8435 (match_operand 2 "const_int_operand" "n"))
8436 (const_int 0)))
8437 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438 (const_int 8)
8439 (const_int 8))
8440 (and:SI
8441 (zero_extract:SI
8442 (match_dup 1)
8443 (const_int 8)
8444 (const_int 8))
8445 (match_dup 2)))]
8446 "ix86_match_ccmode (insn, CCNOmode)"
8447 "and{b}\t{%2, %h0|%h0, %2}"
8448 [(set_attr "type" "alu")
8449 (set_attr "length_immediate" "1")
8450 (set_attr "mode" "QI")])
8451
8452 (define_insn "*andqi_ext_1"
8453 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8454 (const_int 8)
8455 (const_int 8))
8456 (and:SI
8457 (zero_extract:SI
8458 (match_operand 1 "ext_register_operand" "0")
8459 (const_int 8)
8460 (const_int 8))
8461 (zero_extend:SI
8462 (match_operand:QI 2 "general_operand" "Qm"))))
8463 (clobber (reg:CC 17))]
8464 "!TARGET_64BIT"
8465 "and{b}\t{%2, %h0|%h0, %2}"
8466 [(set_attr "type" "alu")
8467 (set_attr "length_immediate" "0")
8468 (set_attr "mode" "QI")])
8469
8470 (define_insn "*andqi_ext_1_rex64"
8471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8472 (const_int 8)
8473 (const_int 8))
8474 (and:SI
8475 (zero_extract:SI
8476 (match_operand 1 "ext_register_operand" "0")
8477 (const_int 8)
8478 (const_int 8))
8479 (zero_extend:SI
8480 (match_operand 2 "ext_register_operand" "Q"))))
8481 (clobber (reg:CC 17))]
8482 "TARGET_64BIT"
8483 "and{b}\t{%2, %h0|%h0, %2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "length_immediate" "0")
8486 (set_attr "mode" "QI")])
8487
8488 (define_insn "*andqi_ext_2"
8489 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8490 (const_int 8)
8491 (const_int 8))
8492 (and:SI
8493 (zero_extract:SI
8494 (match_operand 1 "ext_register_operand" "%0")
8495 (const_int 8)
8496 (const_int 8))
8497 (zero_extract:SI
8498 (match_operand 2 "ext_register_operand" "Q")
8499 (const_int 8)
8500 (const_int 8))))
8501 (clobber (reg:CC 17))]
8502 ""
8503 "and{b}\t{%h2, %h0|%h0, %h2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "length_immediate" "0")
8506 (set_attr "mode" "QI")])
8507
8508 ;; Convert wide AND instructions with immediate operand to shorter QImode
8509 ;; equivalents when possible.
8510 ;; Don't do the splitting with memory operands, since it introduces risk
8511 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8512 ;; for size, but that can (should?) be handled by generic code instead.
8513 (define_split
8514 [(set (match_operand 0 "register_operand" "")
8515 (and (match_operand 1 "register_operand" "")
8516 (match_operand 2 "const_int_operand" "")))
8517 (clobber (reg:CC 17))]
8518 "reload_completed
8519 && QI_REG_P (operands[0])
8520 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8521 && !(~INTVAL (operands[2]) & ~(255 << 8))
8522 && GET_MODE (operands[0]) != QImode"
8523 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8524 (and:SI (zero_extract:SI (match_dup 1)
8525 (const_int 8) (const_int 8))
8526 (match_dup 2)))
8527 (clobber (reg:CC 17))])]
8528 "operands[0] = gen_lowpart (SImode, operands[0]);
8529 operands[1] = gen_lowpart (SImode, operands[1]);
8530 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8531
8532 ;; Since AND can be encoded with sign extended immediate, this is only
8533 ;; profitable when 7th bit is not set.
8534 (define_split
8535 [(set (match_operand 0 "register_operand" "")
8536 (and (match_operand 1 "general_operand" "")
8537 (match_operand 2 "const_int_operand" "")))
8538 (clobber (reg:CC 17))]
8539 "reload_completed
8540 && ANY_QI_REG_P (operands[0])
8541 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8542 && !(~INTVAL (operands[2]) & ~255)
8543 && !(INTVAL (operands[2]) & 128)
8544 && GET_MODE (operands[0]) != QImode"
8545 [(parallel [(set (strict_low_part (match_dup 0))
8546 (and:QI (match_dup 1)
8547 (match_dup 2)))
8548 (clobber (reg:CC 17))])]
8549 "operands[0] = gen_lowpart (QImode, operands[0]);
8550 operands[1] = gen_lowpart (QImode, operands[1]);
8551 operands[2] = gen_lowpart (QImode, operands[2]);")
8552 \f
8553 ;; Logical inclusive OR instructions
8554
8555 ;; %%% This used to optimize known byte-wide and operations to memory.
8556 ;; If this is considered useful, it should be done with splitters.
8557
8558 (define_expand "iordi3"
8559 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8560 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8561 (match_operand:DI 2 "x86_64_general_operand" "")))
8562 (clobber (reg:CC 17))]
8563 "TARGET_64BIT"
8564 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8565
8566 (define_insn "*iordi_1_rex64"
8567 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8568 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8569 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8570 (clobber (reg:CC 17))]
8571 "TARGET_64BIT
8572 && ix86_binary_operator_ok (IOR, DImode, operands)"
8573 "or{q}\t{%2, %0|%0, %2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "mode" "DI")])
8576
8577 (define_insn "*iordi_2_rex64"
8578 [(set (reg 17)
8579 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8580 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8581 (const_int 0)))
8582 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8583 (ior:DI (match_dup 1) (match_dup 2)))]
8584 "TARGET_64BIT
8585 && ix86_match_ccmode (insn, CCNOmode)
8586 && ix86_binary_operator_ok (IOR, DImode, operands)"
8587 "or{q}\t{%2, %0|%0, %2}"
8588 [(set_attr "type" "alu")
8589 (set_attr "mode" "DI")])
8590
8591 (define_insn "*iordi_3_rex64"
8592 [(set (reg 17)
8593 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8594 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8595 (const_int 0)))
8596 (clobber (match_scratch:DI 0 "=r"))]
8597 "TARGET_64BIT
8598 && ix86_match_ccmode (insn, CCNOmode)
8599 && ix86_binary_operator_ok (IOR, DImode, operands)"
8600 "or{q}\t{%2, %0|%0, %2}"
8601 [(set_attr "type" "alu")
8602 (set_attr "mode" "DI")])
8603
8604
8605 (define_expand "iorsi3"
8606 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8607 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8608 (match_operand:SI 2 "general_operand" "")))
8609 (clobber (reg:CC 17))]
8610 ""
8611 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8612
8613 (define_insn "*iorsi_1"
8614 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8615 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8616 (match_operand:SI 2 "general_operand" "ri,rmi")))
8617 (clobber (reg:CC 17))]
8618 "ix86_binary_operator_ok (IOR, SImode, operands)"
8619 "or{l}\t{%2, %0|%0, %2}"
8620 [(set_attr "type" "alu")
8621 (set_attr "mode" "SI")])
8622
8623 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8624 (define_insn "*iorsi_1_zext"
8625 [(set (match_operand:DI 0 "register_operand" "=rm")
8626 (zero_extend:DI
8627 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8628 (match_operand:SI 2 "general_operand" "rim"))))
8629 (clobber (reg:CC 17))]
8630 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8631 "or{l}\t{%2, %k0|%k0, %2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "SI")])
8634
8635 (define_insn "*iorsi_1_zext_imm"
8636 [(set (match_operand:DI 0 "register_operand" "=rm")
8637 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8638 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8639 (clobber (reg:CC 17))]
8640 "TARGET_64BIT"
8641 "or{l}\t{%2, %k0|%k0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "SI")])
8644
8645 (define_insn "*iorsi_2"
8646 [(set (reg 17)
8647 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8648 (match_operand:SI 2 "general_operand" "rim,ri"))
8649 (const_int 0)))
8650 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8651 (ior:SI (match_dup 1) (match_dup 2)))]
8652 "ix86_match_ccmode (insn, CCNOmode)
8653 && ix86_binary_operator_ok (IOR, SImode, operands)"
8654 "or{l}\t{%2, %0|%0, %2}"
8655 [(set_attr "type" "alu")
8656 (set_attr "mode" "SI")])
8657
8658 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8659 ;; ??? Special case for immediate operand is missing - it is tricky.
8660 (define_insn "*iorsi_2_zext"
8661 [(set (reg 17)
8662 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8663 (match_operand:SI 2 "general_operand" "rim"))
8664 (const_int 0)))
8665 (set (match_operand:DI 0 "register_operand" "=r")
8666 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8667 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8668 && ix86_binary_operator_ok (IOR, SImode, operands)"
8669 "or{l}\t{%2, %k0|%k0, %2}"
8670 [(set_attr "type" "alu")
8671 (set_attr "mode" "SI")])
8672
8673 (define_insn "*iorsi_2_zext_imm"
8674 [(set (reg 17)
8675 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8676 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8677 (const_int 0)))
8678 (set (match_operand:DI 0 "register_operand" "=r")
8679 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8680 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8681 && ix86_binary_operator_ok (IOR, SImode, operands)"
8682 "or{l}\t{%2, %k0|%k0, %2}"
8683 [(set_attr "type" "alu")
8684 (set_attr "mode" "SI")])
8685
8686 (define_insn "*iorsi_3"
8687 [(set (reg 17)
8688 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8689 (match_operand:SI 2 "general_operand" "rim"))
8690 (const_int 0)))
8691 (clobber (match_scratch:SI 0 "=r"))]
8692 "ix86_match_ccmode (insn, CCNOmode)
8693 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8694 "or{l}\t{%2, %0|%0, %2}"
8695 [(set_attr "type" "alu")
8696 (set_attr "mode" "SI")])
8697
8698 (define_expand "iorhi3"
8699 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8700 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8701 (match_operand:HI 2 "general_operand" "")))
8702 (clobber (reg:CC 17))]
8703 "TARGET_HIMODE_MATH"
8704 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8705
8706 (define_insn "*iorhi_1"
8707 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8708 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8709 (match_operand:HI 2 "general_operand" "rmi,ri")))
8710 (clobber (reg:CC 17))]
8711 "ix86_binary_operator_ok (IOR, HImode, operands)"
8712 "or{w}\t{%2, %0|%0, %2}"
8713 [(set_attr "type" "alu")
8714 (set_attr "mode" "HI")])
8715
8716 (define_insn "*iorhi_2"
8717 [(set (reg 17)
8718 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8719 (match_operand:HI 2 "general_operand" "rim,ri"))
8720 (const_int 0)))
8721 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8722 (ior:HI (match_dup 1) (match_dup 2)))]
8723 "ix86_match_ccmode (insn, CCNOmode)
8724 && ix86_binary_operator_ok (IOR, HImode, operands)"
8725 "or{w}\t{%2, %0|%0, %2}"
8726 [(set_attr "type" "alu")
8727 (set_attr "mode" "HI")])
8728
8729 (define_insn "*iorhi_3"
8730 [(set (reg 17)
8731 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8732 (match_operand:HI 2 "general_operand" "rim"))
8733 (const_int 0)))
8734 (clobber (match_scratch:HI 0 "=r"))]
8735 "ix86_match_ccmode (insn, CCNOmode)
8736 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8737 "or{w}\t{%2, %0|%0, %2}"
8738 [(set_attr "type" "alu")
8739 (set_attr "mode" "HI")])
8740
8741 (define_expand "iorqi3"
8742 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8743 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8744 (match_operand:QI 2 "general_operand" "")))
8745 (clobber (reg:CC 17))]
8746 "TARGET_QIMODE_MATH"
8747 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8748
8749 ;; %%% Potential partial reg stall on alternative 2. What to do?
8750 (define_insn "*iorqi_1"
8751 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8752 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8753 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8754 (clobber (reg:CC 17))]
8755 "ix86_binary_operator_ok (IOR, QImode, operands)"
8756 "@
8757 or{b}\t{%2, %0|%0, %2}
8758 or{b}\t{%2, %0|%0, %2}
8759 or{l}\t{%k2, %k0|%k0, %k2}"
8760 [(set_attr "type" "alu")
8761 (set_attr "mode" "QI,QI,SI")])
8762
8763 (define_insn "*iorqi_1_slp"
8764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8765 (ior:QI (match_dup 0)
8766 (match_operand:QI 1 "general_operand" "qmi,qi")))
8767 (clobber (reg:CC 17))]
8768 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8769 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8770 "or{b}\t{%1, %0|%0, %1}"
8771 [(set_attr "type" "alu1")
8772 (set_attr "mode" "QI")])
8773
8774 (define_insn "*iorqi_2"
8775 [(set (reg 17)
8776 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8777 (match_operand:QI 2 "general_operand" "qim,qi"))
8778 (const_int 0)))
8779 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8780 (ior:QI (match_dup 1) (match_dup 2)))]
8781 "ix86_match_ccmode (insn, CCNOmode)
8782 && ix86_binary_operator_ok (IOR, QImode, operands)"
8783 "or{b}\t{%2, %0|%0, %2}"
8784 [(set_attr "type" "alu")
8785 (set_attr "mode" "QI")])
8786
8787 (define_insn "*iorqi_2_slp"
8788 [(set (reg 17)
8789 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8790 (match_operand:QI 1 "general_operand" "qim,qi"))
8791 (const_int 0)))
8792 (set (strict_low_part (match_dup 0))
8793 (ior:QI (match_dup 0) (match_dup 1)))]
8794 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8795 && ix86_match_ccmode (insn, CCNOmode)
8796 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8797 "or{b}\t{%1, %0|%0, %1}"
8798 [(set_attr "type" "alu1")
8799 (set_attr "mode" "QI")])
8800
8801 (define_insn "*iorqi_3"
8802 [(set (reg 17)
8803 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8804 (match_operand:QI 2 "general_operand" "qim"))
8805 (const_int 0)))
8806 (clobber (match_scratch:QI 0 "=q"))]
8807 "ix86_match_ccmode (insn, CCNOmode)
8808 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8809 "or{b}\t{%2, %0|%0, %2}"
8810 [(set_attr "type" "alu")
8811 (set_attr "mode" "QI")])
8812
8813 (define_insn "iorqi_ext_0"
8814 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8815 (const_int 8)
8816 (const_int 8))
8817 (ior:SI
8818 (zero_extract:SI
8819 (match_operand 1 "ext_register_operand" "0")
8820 (const_int 8)
8821 (const_int 8))
8822 (match_operand 2 "const_int_operand" "n")))
8823 (clobber (reg:CC 17))]
8824 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8825 "or{b}\t{%2, %h0|%h0, %2}"
8826 [(set_attr "type" "alu")
8827 (set_attr "length_immediate" "1")
8828 (set_attr "mode" "QI")])
8829
8830 (define_insn "*iorqi_ext_1"
8831 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8832 (const_int 8)
8833 (const_int 8))
8834 (ior:SI
8835 (zero_extract:SI
8836 (match_operand 1 "ext_register_operand" "0")
8837 (const_int 8)
8838 (const_int 8))
8839 (zero_extend:SI
8840 (match_operand:QI 2 "general_operand" "Qm"))))
8841 (clobber (reg:CC 17))]
8842 "!TARGET_64BIT
8843 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8844 "or{b}\t{%2, %h0|%h0, %2}"
8845 [(set_attr "type" "alu")
8846 (set_attr "length_immediate" "0")
8847 (set_attr "mode" "QI")])
8848
8849 (define_insn "*iorqi_ext_1_rex64"
8850 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8851 (const_int 8)
8852 (const_int 8))
8853 (ior:SI
8854 (zero_extract:SI
8855 (match_operand 1 "ext_register_operand" "0")
8856 (const_int 8)
8857 (const_int 8))
8858 (zero_extend:SI
8859 (match_operand 2 "ext_register_operand" "Q"))))
8860 (clobber (reg:CC 17))]
8861 "TARGET_64BIT
8862 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8863 "or{b}\t{%2, %h0|%h0, %2}"
8864 [(set_attr "type" "alu")
8865 (set_attr "length_immediate" "0")
8866 (set_attr "mode" "QI")])
8867
8868 (define_insn "*iorqi_ext_2"
8869 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8870 (const_int 8)
8871 (const_int 8))
8872 (ior:SI
8873 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8874 (const_int 8)
8875 (const_int 8))
8876 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8877 (const_int 8)
8878 (const_int 8))))
8879 (clobber (reg:CC 17))]
8880 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8881 "ior{b}\t{%h2, %h0|%h0, %h2}"
8882 [(set_attr "type" "alu")
8883 (set_attr "length_immediate" "0")
8884 (set_attr "mode" "QI")])
8885
8886 (define_split
8887 [(set (match_operand 0 "register_operand" "")
8888 (ior (match_operand 1 "register_operand" "")
8889 (match_operand 2 "const_int_operand" "")))
8890 (clobber (reg:CC 17))]
8891 "reload_completed
8892 && QI_REG_P (operands[0])
8893 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8894 && !(INTVAL (operands[2]) & ~(255 << 8))
8895 && GET_MODE (operands[0]) != QImode"
8896 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8897 (ior:SI (zero_extract:SI (match_dup 1)
8898 (const_int 8) (const_int 8))
8899 (match_dup 2)))
8900 (clobber (reg:CC 17))])]
8901 "operands[0] = gen_lowpart (SImode, operands[0]);
8902 operands[1] = gen_lowpart (SImode, operands[1]);
8903 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8904
8905 ;; Since OR can be encoded with sign extended immediate, this is only
8906 ;; profitable when 7th bit is set.
8907 (define_split
8908 [(set (match_operand 0 "register_operand" "")
8909 (ior (match_operand 1 "general_operand" "")
8910 (match_operand 2 "const_int_operand" "")))
8911 (clobber (reg:CC 17))]
8912 "reload_completed
8913 && ANY_QI_REG_P (operands[0])
8914 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8915 && !(INTVAL (operands[2]) & ~255)
8916 && (INTVAL (operands[2]) & 128)
8917 && GET_MODE (operands[0]) != QImode"
8918 [(parallel [(set (strict_low_part (match_dup 0))
8919 (ior:QI (match_dup 1)
8920 (match_dup 2)))
8921 (clobber (reg:CC 17))])]
8922 "operands[0] = gen_lowpart (QImode, operands[0]);
8923 operands[1] = gen_lowpart (QImode, operands[1]);
8924 operands[2] = gen_lowpart (QImode, operands[2]);")
8925 \f
8926 ;; Logical XOR instructions
8927
8928 ;; %%% This used to optimize known byte-wide and operations to memory.
8929 ;; If this is considered useful, it should be done with splitters.
8930
8931 (define_expand "xordi3"
8932 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8933 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8934 (match_operand:DI 2 "x86_64_general_operand" "")))
8935 (clobber (reg:CC 17))]
8936 "TARGET_64BIT"
8937 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8938
8939 (define_insn "*xordi_1_rex64"
8940 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8941 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8942 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8943 (clobber (reg:CC 17))]
8944 "TARGET_64BIT
8945 && ix86_binary_operator_ok (XOR, DImode, operands)"
8946 "@
8947 xor{q}\t{%2, %0|%0, %2}
8948 xor{q}\t{%2, %0|%0, %2}"
8949 [(set_attr "type" "alu")
8950 (set_attr "mode" "DI,DI")])
8951
8952 (define_insn "*xordi_2_rex64"
8953 [(set (reg 17)
8954 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8955 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8956 (const_int 0)))
8957 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8958 (xor:DI (match_dup 1) (match_dup 2)))]
8959 "TARGET_64BIT
8960 && ix86_match_ccmode (insn, CCNOmode)
8961 && ix86_binary_operator_ok (XOR, DImode, operands)"
8962 "@
8963 xor{q}\t{%2, %0|%0, %2}
8964 xor{q}\t{%2, %0|%0, %2}"
8965 [(set_attr "type" "alu")
8966 (set_attr "mode" "DI,DI")])
8967
8968 (define_insn "*xordi_3_rex64"
8969 [(set (reg 17)
8970 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8971 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8972 (const_int 0)))
8973 (clobber (match_scratch:DI 0 "=r"))]
8974 "TARGET_64BIT
8975 && ix86_match_ccmode (insn, CCNOmode)
8976 && ix86_binary_operator_ok (XOR, DImode, operands)"
8977 "xor{q}\t{%2, %0|%0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "DI")])
8980
8981 (define_expand "xorsi3"
8982 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8983 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8984 (match_operand:SI 2 "general_operand" "")))
8985 (clobber (reg:CC 17))]
8986 ""
8987 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8988
8989 (define_insn "*xorsi_1"
8990 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8991 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8992 (match_operand:SI 2 "general_operand" "ri,rm")))
8993 (clobber (reg:CC 17))]
8994 "ix86_binary_operator_ok (XOR, SImode, operands)"
8995 "xor{l}\t{%2, %0|%0, %2}"
8996 [(set_attr "type" "alu")
8997 (set_attr "mode" "SI")])
8998
8999 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9000 ;; Add speccase for immediates
9001 (define_insn "*xorsi_1_zext"
9002 [(set (match_operand:DI 0 "register_operand" "=r")
9003 (zero_extend:DI
9004 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9005 (match_operand:SI 2 "general_operand" "rim"))))
9006 (clobber (reg:CC 17))]
9007 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9008 "xor{l}\t{%2, %k0|%k0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "SI")])
9011
9012 (define_insn "*xorsi_1_zext_imm"
9013 [(set (match_operand:DI 0 "register_operand" "=r")
9014 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9015 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9016 (clobber (reg:CC 17))]
9017 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9018 "xor{l}\t{%2, %k0|%k0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "SI")])
9021
9022 (define_insn "*xorsi_2"
9023 [(set (reg 17)
9024 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9025 (match_operand:SI 2 "general_operand" "rim,ri"))
9026 (const_int 0)))
9027 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9028 (xor:SI (match_dup 1) (match_dup 2)))]
9029 "ix86_match_ccmode (insn, CCNOmode)
9030 && ix86_binary_operator_ok (XOR, SImode, operands)"
9031 "xor{l}\t{%2, %0|%0, %2}"
9032 [(set_attr "type" "alu")
9033 (set_attr "mode" "SI")])
9034
9035 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9036 ;; ??? Special case for immediate operand is missing - it is tricky.
9037 (define_insn "*xorsi_2_zext"
9038 [(set (reg 17)
9039 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9040 (match_operand:SI 2 "general_operand" "rim"))
9041 (const_int 0)))
9042 (set (match_operand:DI 0 "register_operand" "=r")
9043 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9044 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9045 && ix86_binary_operator_ok (XOR, SImode, operands)"
9046 "xor{l}\t{%2, %k0|%k0, %2}"
9047 [(set_attr "type" "alu")
9048 (set_attr "mode" "SI")])
9049
9050 (define_insn "*xorsi_2_zext_imm"
9051 [(set (reg 17)
9052 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9053 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9054 (const_int 0)))
9055 (set (match_operand:DI 0 "register_operand" "=r")
9056 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9057 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9058 && ix86_binary_operator_ok (XOR, SImode, operands)"
9059 "xor{l}\t{%2, %k0|%k0, %2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "SI")])
9062
9063 (define_insn "*xorsi_3"
9064 [(set (reg 17)
9065 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9066 (match_operand:SI 2 "general_operand" "rim"))
9067 (const_int 0)))
9068 (clobber (match_scratch:SI 0 "=r"))]
9069 "ix86_match_ccmode (insn, CCNOmode)
9070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9071 "xor{l}\t{%2, %0|%0, %2}"
9072 [(set_attr "type" "alu")
9073 (set_attr "mode" "SI")])
9074
9075 (define_expand "xorhi3"
9076 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9077 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9078 (match_operand:HI 2 "general_operand" "")))
9079 (clobber (reg:CC 17))]
9080 "TARGET_HIMODE_MATH"
9081 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9082
9083 (define_insn "*xorhi_1"
9084 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9085 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9086 (match_operand:HI 2 "general_operand" "rmi,ri")))
9087 (clobber (reg:CC 17))]
9088 "ix86_binary_operator_ok (XOR, HImode, operands)"
9089 "xor{w}\t{%2, %0|%0, %2}"
9090 [(set_attr "type" "alu")
9091 (set_attr "mode" "HI")])
9092
9093 (define_insn "*xorhi_2"
9094 [(set (reg 17)
9095 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9096 (match_operand:HI 2 "general_operand" "rim,ri"))
9097 (const_int 0)))
9098 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9099 (xor:HI (match_dup 1) (match_dup 2)))]
9100 "ix86_match_ccmode (insn, CCNOmode)
9101 && ix86_binary_operator_ok (XOR, HImode, operands)"
9102 "xor{w}\t{%2, %0|%0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "mode" "HI")])
9105
9106 (define_insn "*xorhi_3"
9107 [(set (reg 17)
9108 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9109 (match_operand:HI 2 "general_operand" "rim"))
9110 (const_int 0)))
9111 (clobber (match_scratch:HI 0 "=r"))]
9112 "ix86_match_ccmode (insn, CCNOmode)
9113 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9114 "xor{w}\t{%2, %0|%0, %2}"
9115 [(set_attr "type" "alu")
9116 (set_attr "mode" "HI")])
9117
9118 (define_expand "xorqi3"
9119 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9120 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9121 (match_operand:QI 2 "general_operand" "")))
9122 (clobber (reg:CC 17))]
9123 "TARGET_QIMODE_MATH"
9124 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9125
9126 ;; %%% Potential partial reg stall on alternative 2. What to do?
9127 (define_insn "*xorqi_1"
9128 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9129 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9130 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9131 (clobber (reg:CC 17))]
9132 "ix86_binary_operator_ok (XOR, QImode, operands)"
9133 "@
9134 xor{b}\t{%2, %0|%0, %2}
9135 xor{b}\t{%2, %0|%0, %2}
9136 xor{l}\t{%k2, %k0|%k0, %k2}"
9137 [(set_attr "type" "alu")
9138 (set_attr "mode" "QI,QI,SI")])
9139
9140 (define_insn "*xorqi_1_slp"
9141 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9142 (xor:QI (match_dup 0)
9143 (match_operand:QI 1 "general_operand" "qi,qmi")))
9144 (clobber (reg:CC 17))]
9145 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9146 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9147 "xor{b}\t{%1, %0|%0, %1}"
9148 [(set_attr "type" "alu1")
9149 (set_attr "mode" "QI")])
9150
9151 (define_insn "xorqi_ext_0"
9152 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9153 (const_int 8)
9154 (const_int 8))
9155 (xor:SI
9156 (zero_extract:SI
9157 (match_operand 1 "ext_register_operand" "0")
9158 (const_int 8)
9159 (const_int 8))
9160 (match_operand 2 "const_int_operand" "n")))
9161 (clobber (reg:CC 17))]
9162 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9163 "xor{b}\t{%2, %h0|%h0, %2}"
9164 [(set_attr "type" "alu")
9165 (set_attr "length_immediate" "1")
9166 (set_attr "mode" "QI")])
9167
9168 (define_insn "*xorqi_ext_1"
9169 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9170 (const_int 8)
9171 (const_int 8))
9172 (xor:SI
9173 (zero_extract:SI
9174 (match_operand 1 "ext_register_operand" "0")
9175 (const_int 8)
9176 (const_int 8))
9177 (zero_extend:SI
9178 (match_operand:QI 2 "general_operand" "Qm"))))
9179 (clobber (reg:CC 17))]
9180 "!TARGET_64BIT
9181 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9182 "xor{b}\t{%2, %h0|%h0, %2}"
9183 [(set_attr "type" "alu")
9184 (set_attr "length_immediate" "0")
9185 (set_attr "mode" "QI")])
9186
9187 (define_insn "*xorqi_ext_1_rex64"
9188 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9189 (const_int 8)
9190 (const_int 8))
9191 (xor:SI
9192 (zero_extract:SI
9193 (match_operand 1 "ext_register_operand" "0")
9194 (const_int 8)
9195 (const_int 8))
9196 (zero_extend:SI
9197 (match_operand 2 "ext_register_operand" "Q"))))
9198 (clobber (reg:CC 17))]
9199 "TARGET_64BIT
9200 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9201 "xor{b}\t{%2, %h0|%h0, %2}"
9202 [(set_attr "type" "alu")
9203 (set_attr "length_immediate" "0")
9204 (set_attr "mode" "QI")])
9205
9206 (define_insn "*xorqi_ext_2"
9207 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9208 (const_int 8)
9209 (const_int 8))
9210 (xor:SI
9211 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9212 (const_int 8)
9213 (const_int 8))
9214 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9215 (const_int 8)
9216 (const_int 8))))
9217 (clobber (reg:CC 17))]
9218 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9219 "xor{b}\t{%h2, %h0|%h0, %h2}"
9220 [(set_attr "type" "alu")
9221 (set_attr "length_immediate" "0")
9222 (set_attr "mode" "QI")])
9223
9224 (define_insn "*xorqi_cc_1"
9225 [(set (reg 17)
9226 (compare
9227 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9228 (match_operand:QI 2 "general_operand" "qim,qi"))
9229 (const_int 0)))
9230 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9231 (xor:QI (match_dup 1) (match_dup 2)))]
9232 "ix86_match_ccmode (insn, CCNOmode)
9233 && ix86_binary_operator_ok (XOR, QImode, operands)"
9234 "xor{b}\t{%2, %0|%0, %2}"
9235 [(set_attr "type" "alu")
9236 (set_attr "mode" "QI")])
9237
9238 (define_insn "*xorqi_2_slp"
9239 [(set (reg 17)
9240 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9241 (match_operand:QI 1 "general_operand" "qim,qi"))
9242 (const_int 0)))
9243 (set (strict_low_part (match_dup 0))
9244 (xor:QI (match_dup 0) (match_dup 1)))]
9245 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9246 && ix86_match_ccmode (insn, CCNOmode)
9247 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9248 "xor{b}\t{%1, %0|%0, %1}"
9249 [(set_attr "type" "alu1")
9250 (set_attr "mode" "QI")])
9251
9252 (define_insn "*xorqi_cc_2"
9253 [(set (reg 17)
9254 (compare
9255 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9256 (match_operand:QI 2 "general_operand" "qim"))
9257 (const_int 0)))
9258 (clobber (match_scratch:QI 0 "=q"))]
9259 "ix86_match_ccmode (insn, CCNOmode)
9260 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9261 "xor{b}\t{%2, %0|%0, %2}"
9262 [(set_attr "type" "alu")
9263 (set_attr "mode" "QI")])
9264
9265 (define_insn "*xorqi_cc_ext_1"
9266 [(set (reg 17)
9267 (compare
9268 (xor:SI
9269 (zero_extract:SI
9270 (match_operand 1 "ext_register_operand" "0")
9271 (const_int 8)
9272 (const_int 8))
9273 (match_operand:QI 2 "general_operand" "qmn"))
9274 (const_int 0)))
9275 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9276 (const_int 8)
9277 (const_int 8))
9278 (xor:SI
9279 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9280 (match_dup 2)))]
9281 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9282 "xor{b}\t{%2, %h0|%h0, %2}"
9283 [(set_attr "type" "alu")
9284 (set_attr "mode" "QI")])
9285
9286 (define_insn "*xorqi_cc_ext_1_rex64"
9287 [(set (reg 17)
9288 (compare
9289 (xor:SI
9290 (zero_extract:SI
9291 (match_operand 1 "ext_register_operand" "0")
9292 (const_int 8)
9293 (const_int 8))
9294 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9295 (const_int 0)))
9296 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9297 (const_int 8)
9298 (const_int 8))
9299 (xor:SI
9300 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9301 (match_dup 2)))]
9302 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9303 "xor{b}\t{%2, %h0|%h0, %2}"
9304 [(set_attr "type" "alu")
9305 (set_attr "mode" "QI")])
9306
9307 (define_expand "xorqi_cc_ext_1"
9308 [(parallel [
9309 (set (reg:CCNO 17)
9310 (compare:CCNO
9311 (xor:SI
9312 (zero_extract:SI
9313 (match_operand 1 "ext_register_operand" "")
9314 (const_int 8)
9315 (const_int 8))
9316 (match_operand:QI 2 "general_operand" ""))
9317 (const_int 0)))
9318 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9319 (const_int 8)
9320 (const_int 8))
9321 (xor:SI
9322 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9323 (match_dup 2)))])]
9324 ""
9325 "")
9326
9327 (define_split
9328 [(set (match_operand 0 "register_operand" "")
9329 (xor (match_operand 1 "register_operand" "")
9330 (match_operand 2 "const_int_operand" "")))
9331 (clobber (reg:CC 17))]
9332 "reload_completed
9333 && QI_REG_P (operands[0])
9334 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9335 && !(INTVAL (operands[2]) & ~(255 << 8))
9336 && GET_MODE (operands[0]) != QImode"
9337 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9338 (xor:SI (zero_extract:SI (match_dup 1)
9339 (const_int 8) (const_int 8))
9340 (match_dup 2)))
9341 (clobber (reg:CC 17))])]
9342 "operands[0] = gen_lowpart (SImode, operands[0]);
9343 operands[1] = gen_lowpart (SImode, operands[1]);
9344 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9345
9346 ;; Since XOR can be encoded with sign extended immediate, this is only
9347 ;; profitable when 7th bit is set.
9348 (define_split
9349 [(set (match_operand 0 "register_operand" "")
9350 (xor (match_operand 1 "general_operand" "")
9351 (match_operand 2 "const_int_operand" "")))
9352 (clobber (reg:CC 17))]
9353 "reload_completed
9354 && ANY_QI_REG_P (operands[0])
9355 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9356 && !(INTVAL (operands[2]) & ~255)
9357 && (INTVAL (operands[2]) & 128)
9358 && GET_MODE (operands[0]) != QImode"
9359 [(parallel [(set (strict_low_part (match_dup 0))
9360 (xor:QI (match_dup 1)
9361 (match_dup 2)))
9362 (clobber (reg:CC 17))])]
9363 "operands[0] = gen_lowpart (QImode, operands[0]);
9364 operands[1] = gen_lowpart (QImode, operands[1]);
9365 operands[2] = gen_lowpart (QImode, operands[2]);")
9366 \f
9367 ;; Negation instructions
9368
9369 (define_expand "negdi2"
9370 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9371 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9372 (clobber (reg:CC 17))])]
9373 ""
9374 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9375
9376 (define_insn "*negdi2_1"
9377 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9378 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9379 (clobber (reg:CC 17))]
9380 "!TARGET_64BIT
9381 && ix86_unary_operator_ok (NEG, DImode, operands)"
9382 "#")
9383
9384 (define_split
9385 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9386 (neg:DI (match_operand:DI 1 "general_operand" "")))
9387 (clobber (reg:CC 17))]
9388 "!TARGET_64BIT && reload_completed"
9389 [(parallel
9390 [(set (reg:CCZ 17)
9391 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9392 (set (match_dup 0) (neg:SI (match_dup 2)))])
9393 (parallel
9394 [(set (match_dup 1)
9395 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9396 (match_dup 3))
9397 (const_int 0)))
9398 (clobber (reg:CC 17))])
9399 (parallel
9400 [(set (match_dup 1)
9401 (neg:SI (match_dup 1)))
9402 (clobber (reg:CC 17))])]
9403 "split_di (operands+1, 1, operands+2, operands+3);
9404 split_di (operands+0, 1, operands+0, operands+1);")
9405
9406 (define_insn "*negdi2_1_rex64"
9407 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9408 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9409 (clobber (reg:CC 17))]
9410 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9411 "neg{q}\t%0"
9412 [(set_attr "type" "negnot")
9413 (set_attr "mode" "DI")])
9414
9415 ;; The problem with neg is that it does not perform (compare x 0),
9416 ;; it really performs (compare 0 x), which leaves us with the zero
9417 ;; flag being the only useful item.
9418
9419 (define_insn "*negdi2_cmpz_rex64"
9420 [(set (reg:CCZ 17)
9421 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9422 (const_int 0)))
9423 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9424 (neg:DI (match_dup 1)))]
9425 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9426 "neg{q}\t%0"
9427 [(set_attr "type" "negnot")
9428 (set_attr "mode" "DI")])
9429
9430
9431 (define_expand "negsi2"
9432 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9433 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9434 (clobber (reg:CC 17))])]
9435 ""
9436 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9437
9438 (define_insn "*negsi2_1"
9439 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9440 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9441 (clobber (reg:CC 17))]
9442 "ix86_unary_operator_ok (NEG, SImode, operands)"
9443 "neg{l}\t%0"
9444 [(set_attr "type" "negnot")
9445 (set_attr "mode" "SI")])
9446
9447 ;; Combine is quite creative about this pattern.
9448 (define_insn "*negsi2_1_zext"
9449 [(set (match_operand:DI 0 "register_operand" "=r")
9450 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9451 (const_int 32)))
9452 (const_int 32)))
9453 (clobber (reg:CC 17))]
9454 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9455 "neg{l}\t%k0"
9456 [(set_attr "type" "negnot")
9457 (set_attr "mode" "SI")])
9458
9459 ;; The problem with neg is that it does not perform (compare x 0),
9460 ;; it really performs (compare 0 x), which leaves us with the zero
9461 ;; flag being the only useful item.
9462
9463 (define_insn "*negsi2_cmpz"
9464 [(set (reg:CCZ 17)
9465 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9466 (const_int 0)))
9467 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9468 (neg:SI (match_dup 1)))]
9469 "ix86_unary_operator_ok (NEG, SImode, operands)"
9470 "neg{l}\t%0"
9471 [(set_attr "type" "negnot")
9472 (set_attr "mode" "SI")])
9473
9474 (define_insn "*negsi2_cmpz_zext"
9475 [(set (reg:CCZ 17)
9476 (compare:CCZ (lshiftrt:DI
9477 (neg:DI (ashift:DI
9478 (match_operand:DI 1 "register_operand" "0")
9479 (const_int 32)))
9480 (const_int 32))
9481 (const_int 0)))
9482 (set (match_operand:DI 0 "register_operand" "=r")
9483 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9484 (const_int 32)))
9485 (const_int 32)))]
9486 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9487 "neg{l}\t%k0"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "SI")])
9490
9491 (define_expand "neghi2"
9492 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9493 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9494 (clobber (reg:CC 17))])]
9495 "TARGET_HIMODE_MATH"
9496 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9497
9498 (define_insn "*neghi2_1"
9499 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9501 (clobber (reg:CC 17))]
9502 "ix86_unary_operator_ok (NEG, HImode, operands)"
9503 "neg{w}\t%0"
9504 [(set_attr "type" "negnot")
9505 (set_attr "mode" "HI")])
9506
9507 (define_insn "*neghi2_cmpz"
9508 [(set (reg:CCZ 17)
9509 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9510 (const_int 0)))
9511 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9512 (neg:HI (match_dup 1)))]
9513 "ix86_unary_operator_ok (NEG, HImode, operands)"
9514 "neg{w}\t%0"
9515 [(set_attr "type" "negnot")
9516 (set_attr "mode" "HI")])
9517
9518 (define_expand "negqi2"
9519 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9520 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9521 (clobber (reg:CC 17))])]
9522 "TARGET_QIMODE_MATH"
9523 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9524
9525 (define_insn "*negqi2_1"
9526 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9528 (clobber (reg:CC 17))]
9529 "ix86_unary_operator_ok (NEG, QImode, operands)"
9530 "neg{b}\t%0"
9531 [(set_attr "type" "negnot")
9532 (set_attr "mode" "QI")])
9533
9534 (define_insn "*negqi2_cmpz"
9535 [(set (reg:CCZ 17)
9536 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9537 (const_int 0)))
9538 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9539 (neg:QI (match_dup 1)))]
9540 "ix86_unary_operator_ok (NEG, QImode, operands)"
9541 "neg{b}\t%0"
9542 [(set_attr "type" "negnot")
9543 (set_attr "mode" "QI")])
9544
9545 ;; Changing of sign for FP values is doable using integer unit too.
9546
9547 (define_expand "negsf2"
9548 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9549 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9550 (clobber (reg:CC 17))])]
9551 "TARGET_80387"
9552 "if (TARGET_SSE)
9553 {
9554 /* In case operand is in memory, we will not use SSE. */
9555 if (memory_operand (operands[0], VOIDmode)
9556 && rtx_equal_p (operands[0], operands[1]))
9557 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9558 else
9559 {
9560 /* Using SSE is tricky, since we need bitwise negation of -0
9561 in register. */
9562 rtx reg = gen_reg_rtx (SFmode);
9563 rtx dest = operands[0];
9564 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9565
9566 operands[1] = force_reg (SFmode, operands[1]);
9567 operands[0] = force_reg (SFmode, operands[0]);
9568 reg = force_reg (V4SFmode,
9569 gen_rtx_CONST_VECTOR (V4SFmode,
9570 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9571 CONST0_RTX (SFmode),
9572 CONST0_RTX (SFmode))));
9573 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9574 if (dest != operands[0])
9575 emit_move_insn (dest, operands[0]);
9576 }
9577 DONE;
9578 }
9579 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9580
9581 (define_insn "negsf2_memory"
9582 [(set (match_operand:SF 0 "memory_operand" "=m")
9583 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9584 (clobber (reg:CC 17))]
9585 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9586 "#")
9587
9588 (define_insn "negsf2_ifs"
9589 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9590 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9591 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9592 (clobber (reg:CC 17))]
9593 "TARGET_SSE
9594 && (reload_in_progress || reload_completed
9595 || (register_operand (operands[0], VOIDmode)
9596 && register_operand (operands[1], VOIDmode)))"
9597 "#")
9598
9599 (define_split
9600 [(set (match_operand:SF 0 "memory_operand" "")
9601 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9602 (use (match_operand:SF 2 "" ""))
9603 (clobber (reg:CC 17))]
9604 ""
9605 [(parallel [(set (match_dup 0)
9606 (neg:SF (match_dup 1)))
9607 (clobber (reg:CC 17))])])
9608
9609 (define_split
9610 [(set (match_operand:SF 0 "register_operand" "")
9611 (neg:SF (match_operand:SF 1 "register_operand" "")))
9612 (use (match_operand:V4SF 2 "" ""))
9613 (clobber (reg:CC 17))]
9614 "reload_completed && !SSE_REG_P (operands[0])"
9615 [(parallel [(set (match_dup 0)
9616 (neg:SF (match_dup 1)))
9617 (clobber (reg:CC 17))])])
9618
9619 (define_split
9620 [(set (match_operand:SF 0 "register_operand" "")
9621 (neg:SF (match_operand:SF 1 "register_operand" "")))
9622 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9623 (clobber (reg:CC 17))]
9624 "reload_completed && SSE_REG_P (operands[0])"
9625 [(set (match_dup 0)
9626 (xor:V4SF (match_dup 1)
9627 (match_dup 2)))]
9628 {
9629 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9630 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9631 if (operands_match_p (operands[0], operands[2]))
9632 {
9633 rtx tmp;
9634 tmp = operands[1];
9635 operands[1] = operands[2];
9636 operands[2] = tmp;
9637 }
9638 })
9639
9640
9641 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9642 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9643 ;; to itself.
9644 (define_insn "*negsf2_if"
9645 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9646 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9647 (clobber (reg:CC 17))]
9648 "TARGET_80387 && !TARGET_SSE
9649 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9650 "#")
9651
9652 (define_split
9653 [(set (match_operand:SF 0 "fp_register_operand" "")
9654 (neg:SF (match_operand:SF 1 "register_operand" "")))
9655 (clobber (reg:CC 17))]
9656 "TARGET_80387 && reload_completed"
9657 [(set (match_dup 0)
9658 (neg:SF (match_dup 1)))]
9659 "")
9660
9661 (define_split
9662 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9663 (neg:SF (match_operand:SF 1 "register_operand" "")))
9664 (clobber (reg:CC 17))]
9665 "TARGET_80387 && reload_completed"
9666 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9667 (clobber (reg:CC 17))])]
9668 "operands[1] = gen_int_mode (0x80000000, SImode);
9669 operands[0] = gen_lowpart (SImode, operands[0]);")
9670
9671 (define_split
9672 [(set (match_operand 0 "memory_operand" "")
9673 (neg (match_operand 1 "memory_operand" "")))
9674 (clobber (reg:CC 17))]
9675 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9676 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9677 (clobber (reg:CC 17))])]
9678 {
9679 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9680
9681 if (GET_MODE (operands[1]) == XFmode)
9682 size = 10;
9683 operands[0] = adjust_address (operands[0], QImode, size - 1);
9684 operands[1] = gen_int_mode (0x80, QImode);
9685 })
9686
9687 (define_expand "negdf2"
9688 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9689 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9690 (clobber (reg:CC 17))])]
9691 "TARGET_80387"
9692 "if (TARGET_SSE2)
9693 {
9694 /* In case operand is in memory, we will not use SSE. */
9695 if (memory_operand (operands[0], VOIDmode)
9696 && rtx_equal_p (operands[0], operands[1]))
9697 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9698 else
9699 {
9700 /* Using SSE is tricky, since we need bitwise negation of -0
9701 in register. */
9702 rtx reg;
9703 #if HOST_BITS_PER_WIDE_INT >= 64
9704 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9705 #else
9706 rtx imm = immed_double_const (0, 0x80000000, DImode);
9707 #endif
9708 rtx dest = operands[0];
9709
9710 operands[1] = force_reg (DFmode, operands[1]);
9711 operands[0] = force_reg (DFmode, operands[0]);
9712 imm = gen_lowpart (DFmode, imm);
9713 reg = force_reg (V2DFmode,
9714 gen_rtx_CONST_VECTOR (V2DFmode,
9715 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9716 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9717 if (dest != operands[0])
9718 emit_move_insn (dest, operands[0]);
9719 }
9720 DONE;
9721 }
9722 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9723
9724 (define_insn "negdf2_memory"
9725 [(set (match_operand:DF 0 "memory_operand" "=m")
9726 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9727 (clobber (reg:CC 17))]
9728 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9729 "#")
9730
9731 (define_insn "negdf2_ifs"
9732 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9733 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9734 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9735 (clobber (reg:CC 17))]
9736 "!TARGET_64BIT && TARGET_SSE2
9737 && (reload_in_progress || reload_completed
9738 || (register_operand (operands[0], VOIDmode)
9739 && register_operand (operands[1], VOIDmode)))"
9740 "#")
9741
9742 (define_insn "*negdf2_ifs_rex64"
9743 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9744 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9745 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9746 (clobber (reg:CC 17))]
9747 "TARGET_64BIT && TARGET_SSE2
9748 && (reload_in_progress || reload_completed
9749 || (register_operand (operands[0], VOIDmode)
9750 && register_operand (operands[1], VOIDmode)))"
9751 "#")
9752
9753 (define_split
9754 [(set (match_operand:DF 0 "memory_operand" "")
9755 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9756 (use (match_operand:V2DF 2 "" ""))
9757 (clobber (reg:CC 17))]
9758 ""
9759 [(parallel [(set (match_dup 0)
9760 (neg:DF (match_dup 1)))
9761 (clobber (reg:CC 17))])])
9762
9763 (define_split
9764 [(set (match_operand:DF 0 "register_operand" "")
9765 (neg:DF (match_operand:DF 1 "register_operand" "")))
9766 (use (match_operand:V2DF 2 "" ""))
9767 (clobber (reg:CC 17))]
9768 "reload_completed && !SSE_REG_P (operands[0])
9769 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9770 [(parallel [(set (match_dup 0)
9771 (neg:DF (match_dup 1)))
9772 (clobber (reg:CC 17))])])
9773
9774 (define_split
9775 [(set (match_operand:DF 0 "register_operand" "")
9776 (neg:DF (match_operand:DF 1 "register_operand" "")))
9777 (use (match_operand:V2DF 2 "" ""))
9778 (clobber (reg:CC 17))]
9779 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9780 [(parallel [(set (match_dup 0)
9781 (xor:DI (match_dup 1) (match_dup 2)))
9782 (clobber (reg:CC 17))])]
9783 "operands[0] = gen_lowpart (DImode, operands[0]);
9784 operands[1] = gen_lowpart (DImode, operands[1]);
9785 operands[2] = gen_lowpart (DImode, operands[2]);")
9786
9787 (define_split
9788 [(set (match_operand:DF 0 "register_operand" "")
9789 (neg:DF (match_operand:DF 1 "register_operand" "")))
9790 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9791 (clobber (reg:CC 17))]
9792 "reload_completed && SSE_REG_P (operands[0])"
9793 [(set (match_dup 0)
9794 (xor:V2DF (match_dup 1)
9795 (match_dup 2)))]
9796 {
9797 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9798 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9799 /* Avoid possible reformatting on the operands. */
9800 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9801 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9802 if (operands_match_p (operands[0], operands[2]))
9803 {
9804 rtx tmp;
9805 tmp = operands[1];
9806 operands[1] = operands[2];
9807 operands[2] = tmp;
9808 }
9809 })
9810
9811 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9812 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9813 ;; to itself.
9814 (define_insn "*negdf2_if"
9815 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9816 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9817 (clobber (reg:CC 17))]
9818 "!TARGET_64BIT && TARGET_80387
9819 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9820 "#")
9821
9822 ;; FIXME: We should to allow integer registers here. Problem is that
9823 ;; we need another scratch register to get constant from.
9824 ;; Forcing constant to mem if no register available in peep2 should be
9825 ;; safe even for PIC mode, because of RIP relative addressing.
9826 (define_insn "*negdf2_if_rex64"
9827 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9828 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9829 (clobber (reg:CC 17))]
9830 "TARGET_64BIT && TARGET_80387
9831 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9832 "#")
9833
9834 (define_split
9835 [(set (match_operand:DF 0 "fp_register_operand" "")
9836 (neg:DF (match_operand:DF 1 "register_operand" "")))
9837 (clobber (reg:CC 17))]
9838 "TARGET_80387 && reload_completed"
9839 [(set (match_dup 0)
9840 (neg:DF (match_dup 1)))]
9841 "")
9842
9843 (define_split
9844 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9845 (neg:DF (match_operand:DF 1 "register_operand" "")))
9846 (clobber (reg:CC 17))]
9847 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9848 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9849 (clobber (reg:CC 17))])]
9850 "operands[4] = gen_int_mode (0x80000000, SImode);
9851 split_di (operands+0, 1, operands+2, operands+3);")
9852
9853 (define_expand "negxf2"
9854 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9855 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9856 (clobber (reg:CC 17))])]
9857 "TARGET_80387"
9858 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9859
9860 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9861 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9862 ;; to itself.
9863 (define_insn "*negxf2_if"
9864 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9865 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9866 (clobber (reg:CC 17))]
9867 "TARGET_80387
9868 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9869 "#")
9870
9871 (define_split
9872 [(set (match_operand:XF 0 "fp_register_operand" "")
9873 (neg:XF (match_operand:XF 1 "register_operand" "")))
9874 (clobber (reg:CC 17))]
9875 "TARGET_80387 && reload_completed"
9876 [(set (match_dup 0)
9877 (neg:XF (match_dup 1)))]
9878 "")
9879
9880 (define_split
9881 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9882 (neg:XF (match_operand:XF 1 "register_operand" "")))
9883 (clobber (reg:CC 17))]
9884 "TARGET_80387 && reload_completed"
9885 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9886 (clobber (reg:CC 17))])]
9887 "operands[1] = GEN_INT (0x8000);
9888 operands[0] = gen_rtx_REG (SImode,
9889 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9890
9891 ;; Conditionalize these after reload. If they matches before reload, we
9892 ;; lose the clobber and ability to use integer instructions.
9893
9894 (define_insn "*negsf2_1"
9895 [(set (match_operand:SF 0 "register_operand" "=f")
9896 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9897 "TARGET_80387 && reload_completed"
9898 "fchs"
9899 [(set_attr "type" "fsgn")
9900 (set_attr "mode" "SF")])
9901
9902 (define_insn "*negdf2_1"
9903 [(set (match_operand:DF 0 "register_operand" "=f")
9904 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9905 "TARGET_80387 && reload_completed"
9906 "fchs"
9907 [(set_attr "type" "fsgn")
9908 (set_attr "mode" "DF")])
9909
9910 (define_insn "*negextendsfdf2"
9911 [(set (match_operand:DF 0 "register_operand" "=f")
9912 (neg:DF (float_extend:DF
9913 (match_operand:SF 1 "register_operand" "0"))))]
9914 "TARGET_80387"
9915 "fchs"
9916 [(set_attr "type" "fsgn")
9917 (set_attr "mode" "DF")])
9918
9919 (define_insn "*negxf2_1"
9920 [(set (match_operand:XF 0 "register_operand" "=f")
9921 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9922 "TARGET_80387 && reload_completed"
9923 "fchs"
9924 [(set_attr "type" "fsgn")
9925 (set_attr "mode" "XF")])
9926
9927 (define_insn "*negextenddfxf2"
9928 [(set (match_operand:XF 0 "register_operand" "=f")
9929 (neg:XF (float_extend:XF
9930 (match_operand:DF 1 "register_operand" "0"))))]
9931 "TARGET_80387"
9932 "fchs"
9933 [(set_attr "type" "fsgn")
9934 (set_attr "mode" "XF")])
9935
9936 (define_insn "*negextendsfxf2"
9937 [(set (match_operand:XF 0 "register_operand" "=f")
9938 (neg:XF (float_extend:XF
9939 (match_operand:SF 1 "register_operand" "0"))))]
9940 "TARGET_80387"
9941 "fchs"
9942 [(set_attr "type" "fsgn")
9943 (set_attr "mode" "XF")])
9944 \f
9945 ;; Absolute value instructions
9946
9947 (define_expand "abssf2"
9948 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9949 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9950 (clobber (reg:CC 17))])]
9951 "TARGET_80387"
9952 "if (TARGET_SSE)
9953 {
9954 /* In case operand is in memory, we will not use SSE. */
9955 if (memory_operand (operands[0], VOIDmode)
9956 && rtx_equal_p (operands[0], operands[1]))
9957 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9958 else
9959 {
9960 /* Using SSE is tricky, since we need bitwise negation of -0
9961 in register. */
9962 rtx reg = gen_reg_rtx (V4SFmode);
9963 rtx dest = operands[0];
9964 rtx imm;
9965
9966 operands[1] = force_reg (SFmode, operands[1]);
9967 operands[0] = force_reg (SFmode, operands[0]);
9968 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9969 reg = force_reg (V4SFmode,
9970 gen_rtx_CONST_VECTOR (V4SFmode,
9971 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9972 CONST0_RTX (SFmode),
9973 CONST0_RTX (SFmode))));
9974 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9975 if (dest != operands[0])
9976 emit_move_insn (dest, operands[0]);
9977 }
9978 DONE;
9979 }
9980 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9981
9982 (define_insn "abssf2_memory"
9983 [(set (match_operand:SF 0 "memory_operand" "=m")
9984 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9985 (clobber (reg:CC 17))]
9986 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9987 "#")
9988
9989 (define_insn "abssf2_ifs"
9990 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9991 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9992 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9993 (clobber (reg:CC 17))]
9994 "TARGET_SSE
9995 && (reload_in_progress || reload_completed
9996 || (register_operand (operands[0], VOIDmode)
9997 && register_operand (operands[1], VOIDmode)))"
9998 "#")
9999
10000 (define_split
10001 [(set (match_operand:SF 0 "memory_operand" "")
10002 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10003 (use (match_operand:V4SF 2 "" ""))
10004 (clobber (reg:CC 17))]
10005 ""
10006 [(parallel [(set (match_dup 0)
10007 (abs:SF (match_dup 1)))
10008 (clobber (reg:CC 17))])])
10009
10010 (define_split
10011 [(set (match_operand:SF 0 "register_operand" "")
10012 (abs:SF (match_operand:SF 1 "register_operand" "")))
10013 (use (match_operand:V4SF 2 "" ""))
10014 (clobber (reg:CC 17))]
10015 "reload_completed && !SSE_REG_P (operands[0])"
10016 [(parallel [(set (match_dup 0)
10017 (abs:SF (match_dup 1)))
10018 (clobber (reg:CC 17))])])
10019
10020 (define_split
10021 [(set (match_operand:SF 0 "register_operand" "")
10022 (abs:SF (match_operand:SF 1 "register_operand" "")))
10023 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10024 (clobber (reg:CC 17))]
10025 "reload_completed && SSE_REG_P (operands[0])"
10026 [(set (match_dup 0)
10027 (and:V4SF (match_dup 1)
10028 (match_dup 2)))]
10029 {
10030 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10031 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10032 if (operands_match_p (operands[0], operands[2]))
10033 {
10034 rtx tmp;
10035 tmp = operands[1];
10036 operands[1] = operands[2];
10037 operands[2] = tmp;
10038 }
10039 })
10040
10041 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10042 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10043 ;; to itself.
10044 (define_insn "*abssf2_if"
10045 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10046 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10047 (clobber (reg:CC 17))]
10048 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10049 "#")
10050
10051 (define_split
10052 [(set (match_operand:SF 0 "fp_register_operand" "")
10053 (abs:SF (match_operand:SF 1 "register_operand" "")))
10054 (clobber (reg:CC 17))]
10055 "TARGET_80387 && reload_completed"
10056 [(set (match_dup 0)
10057 (abs:SF (match_dup 1)))]
10058 "")
10059
10060 (define_split
10061 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10062 (abs:SF (match_operand:SF 1 "register_operand" "")))
10063 (clobber (reg:CC 17))]
10064 "TARGET_80387 && reload_completed"
10065 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10066 (clobber (reg:CC 17))])]
10067 "operands[1] = gen_int_mode (~0x80000000, SImode);
10068 operands[0] = gen_lowpart (SImode, operands[0]);")
10069
10070 (define_split
10071 [(set (match_operand 0 "memory_operand" "")
10072 (abs (match_operand 1 "memory_operand" "")))
10073 (clobber (reg:CC 17))]
10074 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10075 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10076 (clobber (reg:CC 17))])]
10077 {
10078 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10079
10080 if (GET_MODE (operands[1]) == XFmode)
10081 size = 10;
10082 operands[0] = adjust_address (operands[0], QImode, size - 1);
10083 operands[1] = gen_int_mode (~0x80, QImode);
10084 })
10085
10086 (define_expand "absdf2"
10087 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10088 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10089 (clobber (reg:CC 17))])]
10090 "TARGET_80387"
10091 "if (TARGET_SSE2)
10092 {
10093 /* In case operand is in memory, we will not use SSE. */
10094 if (memory_operand (operands[0], VOIDmode)
10095 && rtx_equal_p (operands[0], operands[1]))
10096 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10097 else
10098 {
10099 /* Using SSE is tricky, since we need bitwise negation of -0
10100 in register. */
10101 rtx reg = gen_reg_rtx (V2DFmode);
10102 #if HOST_BITS_PER_WIDE_INT >= 64
10103 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10104 #else
10105 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10106 #endif
10107 rtx dest = operands[0];
10108
10109 operands[1] = force_reg (DFmode, operands[1]);
10110 operands[0] = force_reg (DFmode, operands[0]);
10111
10112 /* Produce LONG_DOUBLE with the proper immediate argument. */
10113 imm = gen_lowpart (DFmode, imm);
10114 reg = force_reg (V2DFmode,
10115 gen_rtx_CONST_VECTOR (V2DFmode,
10116 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10117 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10118 if (dest != operands[0])
10119 emit_move_insn (dest, operands[0]);
10120 }
10121 DONE;
10122 }
10123 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10124
10125 (define_insn "absdf2_memory"
10126 [(set (match_operand:DF 0 "memory_operand" "=m")
10127 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10128 (clobber (reg:CC 17))]
10129 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10130 "#")
10131
10132 (define_insn "absdf2_ifs"
10133 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10134 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10135 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10136 (clobber (reg:CC 17))]
10137 "!TARGET_64BIT && TARGET_SSE2
10138 && (reload_in_progress || reload_completed
10139 || (register_operand (operands[0], VOIDmode)
10140 && register_operand (operands[1], VOIDmode)))"
10141 "#")
10142
10143 (define_insn "*absdf2_ifs_rex64"
10144 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10145 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10146 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10147 (clobber (reg:CC 17))]
10148 "TARGET_64BIT && TARGET_SSE2
10149 && (reload_in_progress || reload_completed
10150 || (register_operand (operands[0], VOIDmode)
10151 && register_operand (operands[1], VOIDmode)))"
10152 "#")
10153
10154 (define_split
10155 [(set (match_operand:DF 0 "memory_operand" "")
10156 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10157 (use (match_operand:V2DF 2 "" ""))
10158 (clobber (reg:CC 17))]
10159 ""
10160 [(parallel [(set (match_dup 0)
10161 (abs:DF (match_dup 1)))
10162 (clobber (reg:CC 17))])])
10163
10164 (define_split
10165 [(set (match_operand:DF 0 "register_operand" "")
10166 (abs:DF (match_operand:DF 1 "register_operand" "")))
10167 (use (match_operand:V2DF 2 "" ""))
10168 (clobber (reg:CC 17))]
10169 "reload_completed && !SSE_REG_P (operands[0])"
10170 [(parallel [(set (match_dup 0)
10171 (abs:DF (match_dup 1)))
10172 (clobber (reg:CC 17))])])
10173
10174 (define_split
10175 [(set (match_operand:DF 0 "register_operand" "")
10176 (abs:DF (match_operand:DF 1 "register_operand" "")))
10177 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10178 (clobber (reg:CC 17))]
10179 "reload_completed && SSE_REG_P (operands[0])"
10180 [(set (match_dup 0)
10181 (and:V2DF (match_dup 1)
10182 (match_dup 2)))]
10183 {
10184 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10185 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10186 /* Avoid possible reformatting on the operands. */
10187 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10188 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10189 if (operands_match_p (operands[0], operands[2]))
10190 {
10191 rtx tmp;
10192 tmp = operands[1];
10193 operands[1] = operands[2];
10194 operands[2] = tmp;
10195 }
10196 })
10197
10198
10199 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10200 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10201 ;; to itself.
10202 (define_insn "*absdf2_if"
10203 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10204 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10205 (clobber (reg:CC 17))]
10206 "!TARGET_64BIT && TARGET_80387
10207 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10208 "#")
10209
10210 ;; FIXME: We should to allow integer registers here. Problem is that
10211 ;; we need another scratch register to get constant from.
10212 ;; Forcing constant to mem if no register available in peep2 should be
10213 ;; safe even for PIC mode, because of RIP relative addressing.
10214 (define_insn "*absdf2_if_rex64"
10215 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10216 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10217 (clobber (reg:CC 17))]
10218 "TARGET_64BIT && TARGET_80387
10219 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10220 "#")
10221
10222 (define_split
10223 [(set (match_operand:DF 0 "fp_register_operand" "")
10224 (abs:DF (match_operand:DF 1 "register_operand" "")))
10225 (clobber (reg:CC 17))]
10226 "TARGET_80387 && reload_completed"
10227 [(set (match_dup 0)
10228 (abs:DF (match_dup 1)))]
10229 "")
10230
10231 (define_split
10232 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10233 (abs:DF (match_operand:DF 1 "register_operand" "")))
10234 (clobber (reg:CC 17))]
10235 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10236 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10237 (clobber (reg:CC 17))])]
10238 "operands[4] = gen_int_mode (~0x80000000, SImode);
10239 split_di (operands+0, 1, operands+2, operands+3);")
10240
10241 (define_expand "absxf2"
10242 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10243 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10244 (clobber (reg:CC 17))])]
10245 "TARGET_80387"
10246 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10247
10248 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10249 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10250 ;; to itself.
10251 (define_insn "*absxf2_if"
10252 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10253 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10254 (clobber (reg:CC 17))]
10255 "TARGET_80387
10256 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10257 "#")
10258
10259 (define_split
10260 [(set (match_operand:XF 0 "fp_register_operand" "")
10261 (abs:XF (match_operand:XF 1 "register_operand" "")))
10262 (clobber (reg:CC 17))]
10263 "TARGET_80387 && reload_completed"
10264 [(set (match_dup 0)
10265 (abs:XF (match_dup 1)))]
10266 "")
10267
10268 (define_split
10269 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10270 (abs:XF (match_operand:XF 1 "register_operand" "")))
10271 (clobber (reg:CC 17))]
10272 "TARGET_80387 && reload_completed"
10273 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10274 (clobber (reg:CC 17))])]
10275 "operands[1] = GEN_INT (~0x8000);
10276 operands[0] = gen_rtx_REG (SImode,
10277 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10278
10279 (define_insn "*abssf2_1"
10280 [(set (match_operand:SF 0 "register_operand" "=f")
10281 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10282 "TARGET_80387 && reload_completed"
10283 "fabs"
10284 [(set_attr "type" "fsgn")
10285 (set_attr "mode" "SF")])
10286
10287 (define_insn "*absdf2_1"
10288 [(set (match_operand:DF 0 "register_operand" "=f")
10289 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10290 "TARGET_80387 && reload_completed"
10291 "fabs"
10292 [(set_attr "type" "fsgn")
10293 (set_attr "mode" "DF")])
10294
10295 (define_insn "*absextendsfdf2"
10296 [(set (match_operand:DF 0 "register_operand" "=f")
10297 (abs:DF (float_extend:DF
10298 (match_operand:SF 1 "register_operand" "0"))))]
10299 "TARGET_80387"
10300 "fabs"
10301 [(set_attr "type" "fsgn")
10302 (set_attr "mode" "DF")])
10303
10304 (define_insn "*absxf2_1"
10305 [(set (match_operand:XF 0 "register_operand" "=f")
10306 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10307 "TARGET_80387 && reload_completed"
10308 "fabs"
10309 [(set_attr "type" "fsgn")
10310 (set_attr "mode" "DF")])
10311
10312 (define_insn "*absextenddfxf2"
10313 [(set (match_operand:XF 0 "register_operand" "=f")
10314 (abs:XF (float_extend:XF
10315 (match_operand:DF 1 "register_operand" "0"))))]
10316 "TARGET_80387"
10317 "fabs"
10318 [(set_attr "type" "fsgn")
10319 (set_attr "mode" "XF")])
10320
10321 (define_insn "*absextendsfxf2"
10322 [(set (match_operand:XF 0 "register_operand" "=f")
10323 (abs:XF (float_extend:XF
10324 (match_operand:SF 1 "register_operand" "0"))))]
10325 "TARGET_80387"
10326 "fabs"
10327 [(set_attr "type" "fsgn")
10328 (set_attr "mode" "XF")])
10329 \f
10330 ;; One complement instructions
10331
10332 (define_expand "one_cmpldi2"
10333 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10334 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10335 "TARGET_64BIT"
10336 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10337
10338 (define_insn "*one_cmpldi2_1_rex64"
10339 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10340 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10341 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10342 "not{q}\t%0"
10343 [(set_attr "type" "negnot")
10344 (set_attr "mode" "DI")])
10345
10346 (define_insn "*one_cmpldi2_2_rex64"
10347 [(set (reg 17)
10348 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10349 (const_int 0)))
10350 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10351 (not:DI (match_dup 1)))]
10352 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10353 && ix86_unary_operator_ok (NOT, DImode, operands)"
10354 "#"
10355 [(set_attr "type" "alu1")
10356 (set_attr "mode" "DI")])
10357
10358 (define_split
10359 [(set (reg 17)
10360 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10361 (const_int 0)))
10362 (set (match_operand:DI 0 "nonimmediate_operand" "")
10363 (not:DI (match_dup 1)))]
10364 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10365 [(parallel [(set (reg:CCNO 17)
10366 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10367 (const_int 0)))
10368 (set (match_dup 0)
10369 (xor:DI (match_dup 1) (const_int -1)))])]
10370 "")
10371
10372 (define_expand "one_cmplsi2"
10373 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10374 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10375 ""
10376 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10377
10378 (define_insn "*one_cmplsi2_1"
10379 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10380 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10381 "ix86_unary_operator_ok (NOT, SImode, operands)"
10382 "not{l}\t%0"
10383 [(set_attr "type" "negnot")
10384 (set_attr "mode" "SI")])
10385
10386 ;; ??? Currently never generated - xor is used instead.
10387 (define_insn "*one_cmplsi2_1_zext"
10388 [(set (match_operand:DI 0 "register_operand" "=r")
10389 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10390 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10391 "not{l}\t%k0"
10392 [(set_attr "type" "negnot")
10393 (set_attr "mode" "SI")])
10394
10395 (define_insn "*one_cmplsi2_2"
10396 [(set (reg 17)
10397 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10398 (const_int 0)))
10399 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10400 (not:SI (match_dup 1)))]
10401 "ix86_match_ccmode (insn, CCNOmode)
10402 && ix86_unary_operator_ok (NOT, SImode, operands)"
10403 "#"
10404 [(set_attr "type" "alu1")
10405 (set_attr "mode" "SI")])
10406
10407 (define_split
10408 [(set (reg 17)
10409 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10410 (const_int 0)))
10411 (set (match_operand:SI 0 "nonimmediate_operand" "")
10412 (not:SI (match_dup 1)))]
10413 "ix86_match_ccmode (insn, CCNOmode)"
10414 [(parallel [(set (reg:CCNO 17)
10415 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10416 (const_int 0)))
10417 (set (match_dup 0)
10418 (xor:SI (match_dup 1) (const_int -1)))])]
10419 "")
10420
10421 ;; ??? Currently never generated - xor is used instead.
10422 (define_insn "*one_cmplsi2_2_zext"
10423 [(set (reg 17)
10424 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10425 (const_int 0)))
10426 (set (match_operand:DI 0 "register_operand" "=r")
10427 (zero_extend:DI (not:SI (match_dup 1))))]
10428 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10429 && ix86_unary_operator_ok (NOT, SImode, operands)"
10430 "#"
10431 [(set_attr "type" "alu1")
10432 (set_attr "mode" "SI")])
10433
10434 (define_split
10435 [(set (reg 17)
10436 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10437 (const_int 0)))
10438 (set (match_operand:DI 0 "register_operand" "")
10439 (zero_extend:DI (not:SI (match_dup 1))))]
10440 "ix86_match_ccmode (insn, CCNOmode)"
10441 [(parallel [(set (reg:CCNO 17)
10442 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10443 (const_int 0)))
10444 (set (match_dup 0)
10445 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10446 "")
10447
10448 (define_expand "one_cmplhi2"
10449 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10450 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10451 "TARGET_HIMODE_MATH"
10452 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10453
10454 (define_insn "*one_cmplhi2_1"
10455 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10456 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10457 "ix86_unary_operator_ok (NOT, HImode, operands)"
10458 "not{w}\t%0"
10459 [(set_attr "type" "negnot")
10460 (set_attr "mode" "HI")])
10461
10462 (define_insn "*one_cmplhi2_2"
10463 [(set (reg 17)
10464 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10465 (const_int 0)))
10466 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10467 (not:HI (match_dup 1)))]
10468 "ix86_match_ccmode (insn, CCNOmode)
10469 && ix86_unary_operator_ok (NEG, HImode, operands)"
10470 "#"
10471 [(set_attr "type" "alu1")
10472 (set_attr "mode" "HI")])
10473
10474 (define_split
10475 [(set (reg 17)
10476 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10477 (const_int 0)))
10478 (set (match_operand:HI 0 "nonimmediate_operand" "")
10479 (not:HI (match_dup 1)))]
10480 "ix86_match_ccmode (insn, CCNOmode)"
10481 [(parallel [(set (reg:CCNO 17)
10482 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10483 (const_int 0)))
10484 (set (match_dup 0)
10485 (xor:HI (match_dup 1) (const_int -1)))])]
10486 "")
10487
10488 ;; %%% Potential partial reg stall on alternative 1. What to do?
10489 (define_expand "one_cmplqi2"
10490 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10491 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10492 "TARGET_QIMODE_MATH"
10493 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10494
10495 (define_insn "*one_cmplqi2_1"
10496 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10497 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10498 "ix86_unary_operator_ok (NOT, QImode, operands)"
10499 "@
10500 not{b}\t%0
10501 not{l}\t%k0"
10502 [(set_attr "type" "negnot")
10503 (set_attr "mode" "QI,SI")])
10504
10505 (define_insn "*one_cmplqi2_2"
10506 [(set (reg 17)
10507 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10508 (const_int 0)))
10509 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10510 (not:QI (match_dup 1)))]
10511 "ix86_match_ccmode (insn, CCNOmode)
10512 && ix86_unary_operator_ok (NOT, QImode, operands)"
10513 "#"
10514 [(set_attr "type" "alu1")
10515 (set_attr "mode" "QI")])
10516
10517 (define_split
10518 [(set (reg 17)
10519 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10520 (const_int 0)))
10521 (set (match_operand:QI 0 "nonimmediate_operand" "")
10522 (not:QI (match_dup 1)))]
10523 "ix86_match_ccmode (insn, CCNOmode)"
10524 [(parallel [(set (reg:CCNO 17)
10525 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10526 (const_int 0)))
10527 (set (match_dup 0)
10528 (xor:QI (match_dup 1) (const_int -1)))])]
10529 "")
10530 \f
10531 ;; Arithmetic shift instructions
10532
10533 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10534 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10535 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10536 ;; from the assembler input.
10537 ;;
10538 ;; This instruction shifts the target reg/mem as usual, but instead of
10539 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10540 ;; is a left shift double, bits are taken from the high order bits of
10541 ;; reg, else if the insn is a shift right double, bits are taken from the
10542 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10543 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10544 ;;
10545 ;; Since sh[lr]d does not change the `reg' operand, that is done
10546 ;; separately, making all shifts emit pairs of shift double and normal
10547 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10548 ;; support a 63 bit shift, each shift where the count is in a reg expands
10549 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10550 ;;
10551 ;; If the shift count is a constant, we need never emit more than one
10552 ;; shift pair, instead using moves and sign extension for counts greater
10553 ;; than 31.
10554
10555 (define_expand "ashldi3"
10556 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10557 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10558 (match_operand:QI 2 "nonmemory_operand" "")))
10559 (clobber (reg:CC 17))])]
10560 ""
10561 {
10562 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10563 {
10564 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10565 DONE;
10566 }
10567 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10568 DONE;
10569 })
10570
10571 (define_insn "*ashldi3_1_rex64"
10572 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10573 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10574 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10575 (clobber (reg:CC 17))]
10576 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10577 {
10578 switch (get_attr_type (insn))
10579 {
10580 case TYPE_ALU:
10581 if (operands[2] != const1_rtx)
10582 abort ();
10583 if (!rtx_equal_p (operands[0], operands[1]))
10584 abort ();
10585 return "add{q}\t{%0, %0|%0, %0}";
10586
10587 case TYPE_LEA:
10588 if (GET_CODE (operands[2]) != CONST_INT
10589 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10590 abort ();
10591 operands[1] = gen_rtx_MULT (DImode, operands[1],
10592 GEN_INT (1 << INTVAL (operands[2])));
10593 return "lea{q}\t{%a1, %0|%0, %a1}";
10594
10595 default:
10596 if (REG_P (operands[2]))
10597 return "sal{q}\t{%b2, %0|%0, %b2}";
10598 else if (operands[2] == const1_rtx
10599 && (TARGET_SHIFT1 || optimize_size))
10600 return "sal{q}\t%0";
10601 else
10602 return "sal{q}\t{%2, %0|%0, %2}";
10603 }
10604 }
10605 [(set (attr "type")
10606 (cond [(eq_attr "alternative" "1")
10607 (const_string "lea")
10608 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10609 (const_int 0))
10610 (match_operand 0 "register_operand" ""))
10611 (match_operand 2 "const1_operand" ""))
10612 (const_string "alu")
10613 ]
10614 (const_string "ishift")))
10615 (set_attr "mode" "DI")])
10616
10617 ;; Convert lea to the lea pattern to avoid flags dependency.
10618 (define_split
10619 [(set (match_operand:DI 0 "register_operand" "")
10620 (ashift:DI (match_operand:DI 1 "register_operand" "")
10621 (match_operand:QI 2 "immediate_operand" "")))
10622 (clobber (reg:CC 17))]
10623 "TARGET_64BIT && reload_completed
10624 && true_regnum (operands[0]) != true_regnum (operands[1])"
10625 [(set (match_dup 0)
10626 (mult:DI (match_dup 1)
10627 (match_dup 2)))]
10628 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10629
10630 ;; This pattern can't accept a variable shift count, since shifts by
10631 ;; zero don't affect the flags. We assume that shifts by constant
10632 ;; zero are optimized away.
10633 (define_insn "*ashldi3_cmp_rex64"
10634 [(set (reg 17)
10635 (compare
10636 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10637 (match_operand:QI 2 "immediate_operand" "e"))
10638 (const_int 0)))
10639 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10640 (ashift:DI (match_dup 1) (match_dup 2)))]
10641 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10642 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10643 {
10644 switch (get_attr_type (insn))
10645 {
10646 case TYPE_ALU:
10647 if (operands[2] != const1_rtx)
10648 abort ();
10649 return "add{q}\t{%0, %0|%0, %0}";
10650
10651 default:
10652 if (REG_P (operands[2]))
10653 return "sal{q}\t{%b2, %0|%0, %b2}";
10654 else if (operands[2] == const1_rtx
10655 && (TARGET_SHIFT1 || optimize_size))
10656 return "sal{q}\t%0";
10657 else
10658 return "sal{q}\t{%2, %0|%0, %2}";
10659 }
10660 }
10661 [(set (attr "type")
10662 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10663 (const_int 0))
10664 (match_operand 0 "register_operand" ""))
10665 (match_operand 2 "const1_operand" ""))
10666 (const_string "alu")
10667 ]
10668 (const_string "ishift")))
10669 (set_attr "mode" "DI")])
10670
10671 (define_insn "ashldi3_1"
10672 [(set (match_operand:DI 0 "register_operand" "=r")
10673 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10674 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10675 (clobber (match_scratch:SI 3 "=&r"))
10676 (clobber (reg:CC 17))]
10677 "!TARGET_64BIT && TARGET_CMOVE"
10678 "#"
10679 [(set_attr "type" "multi")])
10680
10681 (define_insn "*ashldi3_2"
10682 [(set (match_operand:DI 0 "register_operand" "=r")
10683 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10684 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10685 (clobber (reg:CC 17))]
10686 "!TARGET_64BIT"
10687 "#"
10688 [(set_attr "type" "multi")])
10689
10690 (define_split
10691 [(set (match_operand:DI 0 "register_operand" "")
10692 (ashift:DI (match_operand:DI 1 "register_operand" "")
10693 (match_operand:QI 2 "nonmemory_operand" "")))
10694 (clobber (match_scratch:SI 3 ""))
10695 (clobber (reg:CC 17))]
10696 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10697 [(const_int 0)]
10698 "ix86_split_ashldi (operands, operands[3]); DONE;")
10699
10700 (define_split
10701 [(set (match_operand:DI 0 "register_operand" "")
10702 (ashift:DI (match_operand:DI 1 "register_operand" "")
10703 (match_operand:QI 2 "nonmemory_operand" "")))
10704 (clobber (reg:CC 17))]
10705 "!TARGET_64BIT && reload_completed"
10706 [(const_int 0)]
10707 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10708
10709 (define_insn "x86_shld_1"
10710 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10711 (ior:SI (ashift:SI (match_dup 0)
10712 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10713 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10714 (minus:QI (const_int 32) (match_dup 2)))))
10715 (clobber (reg:CC 17))]
10716 ""
10717 "@
10718 shld{l}\t{%2, %1, %0|%0, %1, %2}
10719 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10720 [(set_attr "type" "ishift")
10721 (set_attr "prefix_0f" "1")
10722 (set_attr "mode" "SI")
10723 (set_attr "pent_pair" "np")
10724 (set_attr "athlon_decode" "vector")])
10725
10726 (define_expand "x86_shift_adj_1"
10727 [(set (reg:CCZ 17)
10728 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10729 (const_int 32))
10730 (const_int 0)))
10731 (set (match_operand:SI 0 "register_operand" "")
10732 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10733 (match_operand:SI 1 "register_operand" "")
10734 (match_dup 0)))
10735 (set (match_dup 1)
10736 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10737 (match_operand:SI 3 "register_operand" "r")
10738 (match_dup 1)))]
10739 "TARGET_CMOVE"
10740 "")
10741
10742 (define_expand "x86_shift_adj_2"
10743 [(use (match_operand:SI 0 "register_operand" ""))
10744 (use (match_operand:SI 1 "register_operand" ""))
10745 (use (match_operand:QI 2 "register_operand" ""))]
10746 ""
10747 {
10748 rtx label = gen_label_rtx ();
10749 rtx tmp;
10750
10751 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10752
10753 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10754 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10755 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10756 gen_rtx_LABEL_REF (VOIDmode, label),
10757 pc_rtx);
10758 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10759 JUMP_LABEL (tmp) = label;
10760
10761 emit_move_insn (operands[0], operands[1]);
10762 emit_move_insn (operands[1], const0_rtx);
10763
10764 emit_label (label);
10765 LABEL_NUSES (label) = 1;
10766
10767 DONE;
10768 })
10769
10770 (define_expand "ashlsi3"
10771 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10772 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10773 (match_operand:QI 2 "nonmemory_operand" "")))
10774 (clobber (reg:CC 17))]
10775 ""
10776 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10777
10778 (define_insn "*ashlsi3_1"
10779 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10780 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10781 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10782 (clobber (reg:CC 17))]
10783 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10784 {
10785 switch (get_attr_type (insn))
10786 {
10787 case TYPE_ALU:
10788 if (operands[2] != const1_rtx)
10789 abort ();
10790 if (!rtx_equal_p (operands[0], operands[1]))
10791 abort ();
10792 return "add{l}\t{%0, %0|%0, %0}";
10793
10794 case TYPE_LEA:
10795 return "#";
10796
10797 default:
10798 if (REG_P (operands[2]))
10799 return "sal{l}\t{%b2, %0|%0, %b2}";
10800 else if (operands[2] == const1_rtx
10801 && (TARGET_SHIFT1 || optimize_size))
10802 return "sal{l}\t%0";
10803 else
10804 return "sal{l}\t{%2, %0|%0, %2}";
10805 }
10806 }
10807 [(set (attr "type")
10808 (cond [(eq_attr "alternative" "1")
10809 (const_string "lea")
10810 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10811 (const_int 0))
10812 (match_operand 0 "register_operand" ""))
10813 (match_operand 2 "const1_operand" ""))
10814 (const_string "alu")
10815 ]
10816 (const_string "ishift")))
10817 (set_attr "mode" "SI")])
10818
10819 ;; Convert lea to the lea pattern to avoid flags dependency.
10820 (define_split
10821 [(set (match_operand 0 "register_operand" "")
10822 (ashift (match_operand 1 "index_register_operand" "")
10823 (match_operand:QI 2 "const_int_operand" "")))
10824 (clobber (reg:CC 17))]
10825 "reload_completed
10826 && true_regnum (operands[0]) != true_regnum (operands[1])"
10827 [(const_int 0)]
10828 {
10829 rtx pat;
10830 operands[0] = gen_lowpart (SImode, operands[0]);
10831 operands[1] = gen_lowpart (Pmode, operands[1]);
10832 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10833 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10834 if (Pmode != SImode)
10835 pat = gen_rtx_SUBREG (SImode, pat, 0);
10836 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10837 DONE;
10838 })
10839
10840 ;; Rare case of shifting RSP is handled by generating move and shift
10841 (define_split
10842 [(set (match_operand 0 "register_operand" "")
10843 (ashift (match_operand 1 "register_operand" "")
10844 (match_operand:QI 2 "const_int_operand" "")))
10845 (clobber (reg:CC 17))]
10846 "reload_completed
10847 && true_regnum (operands[0]) != true_regnum (operands[1])"
10848 [(const_int 0)]
10849 {
10850 rtx pat, clob;
10851 emit_move_insn (operands[1], operands[0]);
10852 pat = gen_rtx_SET (VOIDmode, operands[0],
10853 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10854 operands[0], operands[2]));
10855 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10856 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10857 DONE;
10858 })
10859
10860 (define_insn "*ashlsi3_1_zext"
10861 [(set (match_operand:DI 0 "register_operand" "=r,r")
10862 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10863 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10864 (clobber (reg:CC 17))]
10865 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10866 {
10867 switch (get_attr_type (insn))
10868 {
10869 case TYPE_ALU:
10870 if (operands[2] != const1_rtx)
10871 abort ();
10872 return "add{l}\t{%k0, %k0|%k0, %k0}";
10873
10874 case TYPE_LEA:
10875 return "#";
10876
10877 default:
10878 if (REG_P (operands[2]))
10879 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10880 else if (operands[2] == const1_rtx
10881 && (TARGET_SHIFT1 || optimize_size))
10882 return "sal{l}\t%k0";
10883 else
10884 return "sal{l}\t{%2, %k0|%k0, %2}";
10885 }
10886 }
10887 [(set (attr "type")
10888 (cond [(eq_attr "alternative" "1")
10889 (const_string "lea")
10890 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10891 (const_int 0))
10892 (match_operand 2 "const1_operand" ""))
10893 (const_string "alu")
10894 ]
10895 (const_string "ishift")))
10896 (set_attr "mode" "SI")])
10897
10898 ;; Convert lea to the lea pattern to avoid flags dependency.
10899 (define_split
10900 [(set (match_operand:DI 0 "register_operand" "")
10901 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10902 (match_operand:QI 2 "const_int_operand" ""))))
10903 (clobber (reg:CC 17))]
10904 "TARGET_64BIT && reload_completed
10905 && true_regnum (operands[0]) != true_regnum (operands[1])"
10906 [(set (match_dup 0) (zero_extend:DI
10907 (subreg:SI (mult:SI (match_dup 1)
10908 (match_dup 2)) 0)))]
10909 {
10910 operands[1] = gen_lowpart (Pmode, operands[1]);
10911 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10912 })
10913
10914 ;; This pattern can't accept a variable shift count, since shifts by
10915 ;; zero don't affect the flags. We assume that shifts by constant
10916 ;; zero are optimized away.
10917 (define_insn "*ashlsi3_cmp"
10918 [(set (reg 17)
10919 (compare
10920 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10921 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10922 (const_int 0)))
10923 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10924 (ashift:SI (match_dup 1) (match_dup 2)))]
10925 "ix86_match_ccmode (insn, CCGOCmode)
10926 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10927 {
10928 switch (get_attr_type (insn))
10929 {
10930 case TYPE_ALU:
10931 if (operands[2] != const1_rtx)
10932 abort ();
10933 return "add{l}\t{%0, %0|%0, %0}";
10934
10935 default:
10936 if (REG_P (operands[2]))
10937 return "sal{l}\t{%b2, %0|%0, %b2}";
10938 else if (operands[2] == const1_rtx
10939 && (TARGET_SHIFT1 || optimize_size))
10940 return "sal{l}\t%0";
10941 else
10942 return "sal{l}\t{%2, %0|%0, %2}";
10943 }
10944 }
10945 [(set (attr "type")
10946 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10947 (const_int 0))
10948 (match_operand 0 "register_operand" ""))
10949 (match_operand 2 "const1_operand" ""))
10950 (const_string "alu")
10951 ]
10952 (const_string "ishift")))
10953 (set_attr "mode" "SI")])
10954
10955 (define_insn "*ashlsi3_cmp_zext"
10956 [(set (reg 17)
10957 (compare
10958 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10959 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10960 (const_int 0)))
10961 (set (match_operand:DI 0 "register_operand" "=r")
10962 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10963 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10964 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10965 {
10966 switch (get_attr_type (insn))
10967 {
10968 case TYPE_ALU:
10969 if (operands[2] != const1_rtx)
10970 abort ();
10971 return "add{l}\t{%k0, %k0|%k0, %k0}";
10972
10973 default:
10974 if (REG_P (operands[2]))
10975 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10976 else if (operands[2] == const1_rtx
10977 && (TARGET_SHIFT1 || optimize_size))
10978 return "sal{l}\t%k0";
10979 else
10980 return "sal{l}\t{%2, %k0|%k0, %2}";
10981 }
10982 }
10983 [(set (attr "type")
10984 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10985 (const_int 0))
10986 (match_operand 2 "const1_operand" ""))
10987 (const_string "alu")
10988 ]
10989 (const_string "ishift")))
10990 (set_attr "mode" "SI")])
10991
10992 (define_expand "ashlhi3"
10993 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10994 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10995 (match_operand:QI 2 "nonmemory_operand" "")))
10996 (clobber (reg:CC 17))]
10997 "TARGET_HIMODE_MATH"
10998 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10999
11000 (define_insn "*ashlhi3_1_lea"
11001 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11002 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11003 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11004 (clobber (reg:CC 17))]
11005 "!TARGET_PARTIAL_REG_STALL
11006 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11007 {
11008 switch (get_attr_type (insn))
11009 {
11010 case TYPE_LEA:
11011 return "#";
11012 case TYPE_ALU:
11013 if (operands[2] != const1_rtx)
11014 abort ();
11015 return "add{w}\t{%0, %0|%0, %0}";
11016
11017 default:
11018 if (REG_P (operands[2]))
11019 return "sal{w}\t{%b2, %0|%0, %b2}";
11020 else if (operands[2] == const1_rtx
11021 && (TARGET_SHIFT1 || optimize_size))
11022 return "sal{w}\t%0";
11023 else
11024 return "sal{w}\t{%2, %0|%0, %2}";
11025 }
11026 }
11027 [(set (attr "type")
11028 (cond [(eq_attr "alternative" "1")
11029 (const_string "lea")
11030 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11031 (const_int 0))
11032 (match_operand 0 "register_operand" ""))
11033 (match_operand 2 "const1_operand" ""))
11034 (const_string "alu")
11035 ]
11036 (const_string "ishift")))
11037 (set_attr "mode" "HI,SI")])
11038
11039 (define_insn "*ashlhi3_1"
11040 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11041 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11042 (match_operand:QI 2 "nonmemory_operand" "cI")))
11043 (clobber (reg:CC 17))]
11044 "TARGET_PARTIAL_REG_STALL
11045 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11046 {
11047 switch (get_attr_type (insn))
11048 {
11049 case TYPE_ALU:
11050 if (operands[2] != const1_rtx)
11051 abort ();
11052 return "add{w}\t{%0, %0|%0, %0}";
11053
11054 default:
11055 if (REG_P (operands[2]))
11056 return "sal{w}\t{%b2, %0|%0, %b2}";
11057 else if (operands[2] == const1_rtx
11058 && (TARGET_SHIFT1 || optimize_size))
11059 return "sal{w}\t%0";
11060 else
11061 return "sal{w}\t{%2, %0|%0, %2}";
11062 }
11063 }
11064 [(set (attr "type")
11065 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11066 (const_int 0))
11067 (match_operand 0 "register_operand" ""))
11068 (match_operand 2 "const1_operand" ""))
11069 (const_string "alu")
11070 ]
11071 (const_string "ishift")))
11072 (set_attr "mode" "HI")])
11073
11074 ;; This pattern can't accept a variable shift count, since shifts by
11075 ;; zero don't affect the flags. We assume that shifts by constant
11076 ;; zero are optimized away.
11077 (define_insn "*ashlhi3_cmp"
11078 [(set (reg 17)
11079 (compare
11080 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11081 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11082 (const_int 0)))
11083 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11084 (ashift:HI (match_dup 1) (match_dup 2)))]
11085 "ix86_match_ccmode (insn, CCGOCmode)
11086 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11087 {
11088 switch (get_attr_type (insn))
11089 {
11090 case TYPE_ALU:
11091 if (operands[2] != const1_rtx)
11092 abort ();
11093 return "add{w}\t{%0, %0|%0, %0}";
11094
11095 default:
11096 if (REG_P (operands[2]))
11097 return "sal{w}\t{%b2, %0|%0, %b2}";
11098 else if (operands[2] == const1_rtx
11099 && (TARGET_SHIFT1 || optimize_size))
11100 return "sal{w}\t%0";
11101 else
11102 return "sal{w}\t{%2, %0|%0, %2}";
11103 }
11104 }
11105 [(set (attr "type")
11106 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11107 (const_int 0))
11108 (match_operand 0 "register_operand" ""))
11109 (match_operand 2 "const1_operand" ""))
11110 (const_string "alu")
11111 ]
11112 (const_string "ishift")))
11113 (set_attr "mode" "HI")])
11114
11115 (define_expand "ashlqi3"
11116 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11117 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11118 (match_operand:QI 2 "nonmemory_operand" "")))
11119 (clobber (reg:CC 17))]
11120 "TARGET_QIMODE_MATH"
11121 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11122
11123 ;; %%% Potential partial reg stall on alternative 2. What to do?
11124
11125 (define_insn "*ashlqi3_1_lea"
11126 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11127 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11128 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11129 (clobber (reg:CC 17))]
11130 "!TARGET_PARTIAL_REG_STALL
11131 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11132 {
11133 switch (get_attr_type (insn))
11134 {
11135 case TYPE_LEA:
11136 return "#";
11137 case TYPE_ALU:
11138 if (operands[2] != const1_rtx)
11139 abort ();
11140 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11141 return "add{l}\t{%k0, %k0|%k0, %k0}";
11142 else
11143 return "add{b}\t{%0, %0|%0, %0}";
11144
11145 default:
11146 if (REG_P (operands[2]))
11147 {
11148 if (get_attr_mode (insn) == MODE_SI)
11149 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11150 else
11151 return "sal{b}\t{%b2, %0|%0, %b2}";
11152 }
11153 else if (operands[2] == const1_rtx
11154 && (TARGET_SHIFT1 || optimize_size))
11155 {
11156 if (get_attr_mode (insn) == MODE_SI)
11157 return "sal{l}\t%0";
11158 else
11159 return "sal{b}\t%0";
11160 }
11161 else
11162 {
11163 if (get_attr_mode (insn) == MODE_SI)
11164 return "sal{l}\t{%2, %k0|%k0, %2}";
11165 else
11166 return "sal{b}\t{%2, %0|%0, %2}";
11167 }
11168 }
11169 }
11170 [(set (attr "type")
11171 (cond [(eq_attr "alternative" "2")
11172 (const_string "lea")
11173 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11174 (const_int 0))
11175 (match_operand 0 "register_operand" ""))
11176 (match_operand 2 "const1_operand" ""))
11177 (const_string "alu")
11178 ]
11179 (const_string "ishift")))
11180 (set_attr "mode" "QI,SI,SI")])
11181
11182 (define_insn "*ashlqi3_1"
11183 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11184 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11185 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11186 (clobber (reg:CC 17))]
11187 "TARGET_PARTIAL_REG_STALL
11188 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11189 {
11190 switch (get_attr_type (insn))
11191 {
11192 case TYPE_ALU:
11193 if (operands[2] != const1_rtx)
11194 abort ();
11195 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11196 return "add{l}\t{%k0, %k0|%k0, %k0}";
11197 else
11198 return "add{b}\t{%0, %0|%0, %0}";
11199
11200 default:
11201 if (REG_P (operands[2]))
11202 {
11203 if (get_attr_mode (insn) == MODE_SI)
11204 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11205 else
11206 return "sal{b}\t{%b2, %0|%0, %b2}";
11207 }
11208 else if (operands[2] == const1_rtx
11209 && (TARGET_SHIFT1 || optimize_size))
11210 {
11211 if (get_attr_mode (insn) == MODE_SI)
11212 return "sal{l}\t%0";
11213 else
11214 return "sal{b}\t%0";
11215 }
11216 else
11217 {
11218 if (get_attr_mode (insn) == MODE_SI)
11219 return "sal{l}\t{%2, %k0|%k0, %2}";
11220 else
11221 return "sal{b}\t{%2, %0|%0, %2}";
11222 }
11223 }
11224 }
11225 [(set (attr "type")
11226 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11227 (const_int 0))
11228 (match_operand 0 "register_operand" ""))
11229 (match_operand 2 "const1_operand" ""))
11230 (const_string "alu")
11231 ]
11232 (const_string "ishift")))
11233 (set_attr "mode" "QI,SI")])
11234
11235 ;; This pattern can't accept a variable shift count, since shifts by
11236 ;; zero don't affect the flags. We assume that shifts by constant
11237 ;; zero are optimized away.
11238 (define_insn "*ashlqi3_cmp"
11239 [(set (reg 17)
11240 (compare
11241 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11242 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11243 (const_int 0)))
11244 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11245 (ashift:QI (match_dup 1) (match_dup 2)))]
11246 "ix86_match_ccmode (insn, CCGOCmode)
11247 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11248 {
11249 switch (get_attr_type (insn))
11250 {
11251 case TYPE_ALU:
11252 if (operands[2] != const1_rtx)
11253 abort ();
11254 return "add{b}\t{%0, %0|%0, %0}";
11255
11256 default:
11257 if (REG_P (operands[2]))
11258 return "sal{b}\t{%b2, %0|%0, %b2}";
11259 else if (operands[2] == const1_rtx
11260 && (TARGET_SHIFT1 || optimize_size))
11261 return "sal{b}\t%0";
11262 else
11263 return "sal{b}\t{%2, %0|%0, %2}";
11264 }
11265 }
11266 [(set (attr "type")
11267 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11268 (const_int 0))
11269 (match_operand 0 "register_operand" ""))
11270 (match_operand 2 "const1_operand" ""))
11271 (const_string "alu")
11272 ]
11273 (const_string "ishift")))
11274 (set_attr "mode" "QI")])
11275
11276 ;; See comment above `ashldi3' about how this works.
11277
11278 (define_expand "ashrdi3"
11279 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11280 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11281 (match_operand:QI 2 "nonmemory_operand" "")))
11282 (clobber (reg:CC 17))])]
11283 ""
11284 {
11285 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11286 {
11287 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11288 DONE;
11289 }
11290 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11291 DONE;
11292 })
11293
11294 (define_insn "ashrdi3_63_rex64"
11295 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11296 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11297 (match_operand:DI 2 "const_int_operand" "i,i")))
11298 (clobber (reg:CC 17))]
11299 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11300 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11301 "@
11302 {cqto|cqo}
11303 sar{q}\t{%2, %0|%0, %2}"
11304 [(set_attr "type" "imovx,ishift")
11305 (set_attr "prefix_0f" "0,*")
11306 (set_attr "length_immediate" "0,*")
11307 (set_attr "modrm" "0,1")
11308 (set_attr "mode" "DI")])
11309
11310 (define_insn "*ashrdi3_1_one_bit_rex64"
11311 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11312 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11313 (match_operand:QI 2 "const1_operand" "")))
11314 (clobber (reg:CC 17))]
11315 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11316 && (TARGET_SHIFT1 || optimize_size)"
11317 "sar{q}\t%0"
11318 [(set_attr "type" "ishift")
11319 (set (attr "length")
11320 (if_then_else (match_operand:DI 0 "register_operand" "")
11321 (const_string "2")
11322 (const_string "*")))])
11323
11324 (define_insn "*ashrdi3_1_rex64"
11325 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11326 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11327 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11328 (clobber (reg:CC 17))]
11329 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11330 "@
11331 sar{q}\t{%2, %0|%0, %2}
11332 sar{q}\t{%b2, %0|%0, %b2}"
11333 [(set_attr "type" "ishift")
11334 (set_attr "mode" "DI")])
11335
11336 ;; This pattern can't accept a variable shift count, since shifts by
11337 ;; zero don't affect the flags. We assume that shifts by constant
11338 ;; zero are optimized away.
11339 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11340 [(set (reg 17)
11341 (compare
11342 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11343 (match_operand:QI 2 "const1_operand" ""))
11344 (const_int 0)))
11345 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11346 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11347 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11348 && (TARGET_SHIFT1 || optimize_size)
11349 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11350 "sar{q}\t%0"
11351 [(set_attr "type" "ishift")
11352 (set (attr "length")
11353 (if_then_else (match_operand:DI 0 "register_operand" "")
11354 (const_string "2")
11355 (const_string "*")))])
11356
11357 ;; This pattern can't accept a variable shift count, since shifts by
11358 ;; zero don't affect the flags. We assume that shifts by constant
11359 ;; zero are optimized away.
11360 (define_insn "*ashrdi3_cmp_rex64"
11361 [(set (reg 17)
11362 (compare
11363 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11364 (match_operand:QI 2 "const_int_operand" "n"))
11365 (const_int 0)))
11366 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11367 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11368 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11369 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11370 "sar{q}\t{%2, %0|%0, %2}"
11371 [(set_attr "type" "ishift")
11372 (set_attr "mode" "DI")])
11373
11374
11375 (define_insn "ashrdi3_1"
11376 [(set (match_operand:DI 0 "register_operand" "=r")
11377 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11378 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11379 (clobber (match_scratch:SI 3 "=&r"))
11380 (clobber (reg:CC 17))]
11381 "!TARGET_64BIT && TARGET_CMOVE"
11382 "#"
11383 [(set_attr "type" "multi")])
11384
11385 (define_insn "*ashrdi3_2"
11386 [(set (match_operand:DI 0 "register_operand" "=r")
11387 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11388 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11389 (clobber (reg:CC 17))]
11390 "!TARGET_64BIT"
11391 "#"
11392 [(set_attr "type" "multi")])
11393
11394 (define_split
11395 [(set (match_operand:DI 0 "register_operand" "")
11396 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11397 (match_operand:QI 2 "nonmemory_operand" "")))
11398 (clobber (match_scratch:SI 3 ""))
11399 (clobber (reg:CC 17))]
11400 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11401 [(const_int 0)]
11402 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11403
11404 (define_split
11405 [(set (match_operand:DI 0 "register_operand" "")
11406 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11407 (match_operand:QI 2 "nonmemory_operand" "")))
11408 (clobber (reg:CC 17))]
11409 "!TARGET_64BIT && reload_completed"
11410 [(const_int 0)]
11411 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11412
11413 (define_insn "x86_shrd_1"
11414 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11415 (ior:SI (ashiftrt:SI (match_dup 0)
11416 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11417 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11418 (minus:QI (const_int 32) (match_dup 2)))))
11419 (clobber (reg:CC 17))]
11420 ""
11421 "@
11422 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11423 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11424 [(set_attr "type" "ishift")
11425 (set_attr "prefix_0f" "1")
11426 (set_attr "pent_pair" "np")
11427 (set_attr "mode" "SI")])
11428
11429 (define_expand "x86_shift_adj_3"
11430 [(use (match_operand:SI 0 "register_operand" ""))
11431 (use (match_operand:SI 1 "register_operand" ""))
11432 (use (match_operand:QI 2 "register_operand" ""))]
11433 ""
11434 {
11435 rtx label = gen_label_rtx ();
11436 rtx tmp;
11437
11438 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11439
11440 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11441 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11442 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11443 gen_rtx_LABEL_REF (VOIDmode, label),
11444 pc_rtx);
11445 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11446 JUMP_LABEL (tmp) = label;
11447
11448 emit_move_insn (operands[0], operands[1]);
11449 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11450
11451 emit_label (label);
11452 LABEL_NUSES (label) = 1;
11453
11454 DONE;
11455 })
11456
11457 (define_insn "ashrsi3_31"
11458 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11459 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11460 (match_operand:SI 2 "const_int_operand" "i,i")))
11461 (clobber (reg:CC 17))]
11462 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11463 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11464 "@
11465 {cltd|cdq}
11466 sar{l}\t{%2, %0|%0, %2}"
11467 [(set_attr "type" "imovx,ishift")
11468 (set_attr "prefix_0f" "0,*")
11469 (set_attr "length_immediate" "0,*")
11470 (set_attr "modrm" "0,1")
11471 (set_attr "mode" "SI")])
11472
11473 (define_insn "*ashrsi3_31_zext"
11474 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11475 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11476 (match_operand:SI 2 "const_int_operand" "i,i"))))
11477 (clobber (reg:CC 17))]
11478 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11479 && INTVAL (operands[2]) == 31
11480 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11481 "@
11482 {cltd|cdq}
11483 sar{l}\t{%2, %k0|%k0, %2}"
11484 [(set_attr "type" "imovx,ishift")
11485 (set_attr "prefix_0f" "0,*")
11486 (set_attr "length_immediate" "0,*")
11487 (set_attr "modrm" "0,1")
11488 (set_attr "mode" "SI")])
11489
11490 (define_expand "ashrsi3"
11491 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11492 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11493 (match_operand:QI 2 "nonmemory_operand" "")))
11494 (clobber (reg:CC 17))]
11495 ""
11496 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11497
11498 (define_insn "*ashrsi3_1_one_bit"
11499 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11500 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11501 (match_operand:QI 2 "const1_operand" "")))
11502 (clobber (reg:CC 17))]
11503 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11504 && (TARGET_SHIFT1 || optimize_size)"
11505 "sar{l}\t%0"
11506 [(set_attr "type" "ishift")
11507 (set (attr "length")
11508 (if_then_else (match_operand:SI 0 "register_operand" "")
11509 (const_string "2")
11510 (const_string "*")))])
11511
11512 (define_insn "*ashrsi3_1_one_bit_zext"
11513 [(set (match_operand:DI 0 "register_operand" "=r")
11514 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11515 (match_operand:QI 2 "const1_operand" ""))))
11516 (clobber (reg:CC 17))]
11517 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11518 && (TARGET_SHIFT1 || optimize_size)"
11519 "sar{l}\t%k0"
11520 [(set_attr "type" "ishift")
11521 (set_attr "length" "2")])
11522
11523 (define_insn "*ashrsi3_1"
11524 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11525 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11526 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11527 (clobber (reg:CC 17))]
11528 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11529 "@
11530 sar{l}\t{%2, %0|%0, %2}
11531 sar{l}\t{%b2, %0|%0, %b2}"
11532 [(set_attr "type" "ishift")
11533 (set_attr "mode" "SI")])
11534
11535 (define_insn "*ashrsi3_1_zext"
11536 [(set (match_operand:DI 0 "register_operand" "=r,r")
11537 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11538 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11539 (clobber (reg:CC 17))]
11540 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11541 "@
11542 sar{l}\t{%2, %k0|%k0, %2}
11543 sar{l}\t{%b2, %k0|%k0, %b2}"
11544 [(set_attr "type" "ishift")
11545 (set_attr "mode" "SI")])
11546
11547 ;; This pattern can't accept a variable shift count, since shifts by
11548 ;; zero don't affect the flags. We assume that shifts by constant
11549 ;; zero are optimized away.
11550 (define_insn "*ashrsi3_one_bit_cmp"
11551 [(set (reg 17)
11552 (compare
11553 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11554 (match_operand:QI 2 "const1_operand" ""))
11555 (const_int 0)))
11556 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11557 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11558 "ix86_match_ccmode (insn, CCGOCmode)
11559 && (TARGET_SHIFT1 || optimize_size)
11560 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11561 "sar{l}\t%0"
11562 [(set_attr "type" "ishift")
11563 (set (attr "length")
11564 (if_then_else (match_operand:SI 0 "register_operand" "")
11565 (const_string "2")
11566 (const_string "*")))])
11567
11568 (define_insn "*ashrsi3_one_bit_cmp_zext"
11569 [(set (reg 17)
11570 (compare
11571 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11572 (match_operand:QI 2 "const1_operand" ""))
11573 (const_int 0)))
11574 (set (match_operand:DI 0 "register_operand" "=r")
11575 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11576 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11577 && (TARGET_SHIFT1 || optimize_size)
11578 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11579 "sar{l}\t%k0"
11580 [(set_attr "type" "ishift")
11581 (set_attr "length" "2")])
11582
11583 ;; This pattern can't accept a variable shift count, since shifts by
11584 ;; zero don't affect the flags. We assume that shifts by constant
11585 ;; zero are optimized away.
11586 (define_insn "*ashrsi3_cmp"
11587 [(set (reg 17)
11588 (compare
11589 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11590 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11591 (const_int 0)))
11592 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11593 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11594 "ix86_match_ccmode (insn, CCGOCmode)
11595 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11596 "sar{l}\t{%2, %0|%0, %2}"
11597 [(set_attr "type" "ishift")
11598 (set_attr "mode" "SI")])
11599
11600 (define_insn "*ashrsi3_cmp_zext"
11601 [(set (reg 17)
11602 (compare
11603 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11604 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11605 (const_int 0)))
11606 (set (match_operand:DI 0 "register_operand" "=r")
11607 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11608 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11609 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11610 "sar{l}\t{%2, %k0|%k0, %2}"
11611 [(set_attr "type" "ishift")
11612 (set_attr "mode" "SI")])
11613
11614 (define_expand "ashrhi3"
11615 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11616 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11617 (match_operand:QI 2 "nonmemory_operand" "")))
11618 (clobber (reg:CC 17))]
11619 "TARGET_HIMODE_MATH"
11620 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11621
11622 (define_insn "*ashrhi3_1_one_bit"
11623 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11624 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11625 (match_operand:QI 2 "const1_operand" "")))
11626 (clobber (reg:CC 17))]
11627 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11628 && (TARGET_SHIFT1 || optimize_size)"
11629 "sar{w}\t%0"
11630 [(set_attr "type" "ishift")
11631 (set (attr "length")
11632 (if_then_else (match_operand 0 "register_operand" "")
11633 (const_string "2")
11634 (const_string "*")))])
11635
11636 (define_insn "*ashrhi3_1"
11637 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11638 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11639 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11640 (clobber (reg:CC 17))]
11641 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11642 "@
11643 sar{w}\t{%2, %0|%0, %2}
11644 sar{w}\t{%b2, %0|%0, %b2}"
11645 [(set_attr "type" "ishift")
11646 (set_attr "mode" "HI")])
11647
11648 ;; This pattern can't accept a variable shift count, since shifts by
11649 ;; zero don't affect the flags. We assume that shifts by constant
11650 ;; zero are optimized away.
11651 (define_insn "*ashrhi3_one_bit_cmp"
11652 [(set (reg 17)
11653 (compare
11654 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11655 (match_operand:QI 2 "const1_operand" ""))
11656 (const_int 0)))
11657 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11658 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11659 "ix86_match_ccmode (insn, CCGOCmode)
11660 && (TARGET_SHIFT1 || optimize_size)
11661 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11662 "sar{w}\t%0"
11663 [(set_attr "type" "ishift")
11664 (set (attr "length")
11665 (if_then_else (match_operand 0 "register_operand" "")
11666 (const_string "2")
11667 (const_string "*")))])
11668
11669 ;; This pattern can't accept a variable shift count, since shifts by
11670 ;; zero don't affect the flags. We assume that shifts by constant
11671 ;; zero are optimized away.
11672 (define_insn "*ashrhi3_cmp"
11673 [(set (reg 17)
11674 (compare
11675 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11676 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11677 (const_int 0)))
11678 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11679 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11680 "ix86_match_ccmode (insn, CCGOCmode)
11681 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11682 "sar{w}\t{%2, %0|%0, %2}"
11683 [(set_attr "type" "ishift")
11684 (set_attr "mode" "HI")])
11685
11686 (define_expand "ashrqi3"
11687 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11688 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11689 (match_operand:QI 2 "nonmemory_operand" "")))
11690 (clobber (reg:CC 17))]
11691 "TARGET_QIMODE_MATH"
11692 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11693
11694 (define_insn "*ashrqi3_1_one_bit"
11695 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11696 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11697 (match_operand:QI 2 "const1_operand" "")))
11698 (clobber (reg:CC 17))]
11699 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11700 && (TARGET_SHIFT1 || optimize_size)"
11701 "sar{b}\t%0"
11702 [(set_attr "type" "ishift")
11703 (set (attr "length")
11704 (if_then_else (match_operand 0 "register_operand" "")
11705 (const_string "2")
11706 (const_string "*")))])
11707
11708 (define_insn "*ashrqi3_1_one_bit_slp"
11709 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11710 (ashiftrt:QI (match_dup 0)
11711 (match_operand:QI 1 "const1_operand" "")))
11712 (clobber (reg:CC 17))]
11713 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11714 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11715 && (TARGET_SHIFT1 || optimize_size)"
11716 "sar{b}\t%0"
11717 [(set_attr "type" "ishift1")
11718 (set (attr "length")
11719 (if_then_else (match_operand 0 "register_operand" "")
11720 (const_string "2")
11721 (const_string "*")))])
11722
11723 (define_insn "*ashrqi3_1"
11724 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11725 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11726 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11727 (clobber (reg:CC 17))]
11728 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11729 "@
11730 sar{b}\t{%2, %0|%0, %2}
11731 sar{b}\t{%b2, %0|%0, %b2}"
11732 [(set_attr "type" "ishift")
11733 (set_attr "mode" "QI")])
11734
11735 (define_insn "*ashrqi3_1_slp"
11736 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11737 (ashiftrt:QI (match_dup 0)
11738 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11739 (clobber (reg:CC 17))]
11740 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11741 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11742 "@
11743 sar{b}\t{%1, %0|%0, %1}
11744 sar{b}\t{%b1, %0|%0, %b1}"
11745 [(set_attr "type" "ishift1")
11746 (set_attr "mode" "QI")])
11747
11748 ;; This pattern can't accept a variable shift count, since shifts by
11749 ;; zero don't affect the flags. We assume that shifts by constant
11750 ;; zero are optimized away.
11751 (define_insn "*ashrqi3_one_bit_cmp"
11752 [(set (reg 17)
11753 (compare
11754 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11755 (match_operand:QI 2 "const1_operand" "I"))
11756 (const_int 0)))
11757 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11758 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11759 "ix86_match_ccmode (insn, CCGOCmode)
11760 && (TARGET_SHIFT1 || optimize_size)
11761 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11762 "sar{b}\t%0"
11763 [(set_attr "type" "ishift")
11764 (set (attr "length")
11765 (if_then_else (match_operand 0 "register_operand" "")
11766 (const_string "2")
11767 (const_string "*")))])
11768
11769 ;; This pattern can't accept a variable shift count, since shifts by
11770 ;; zero don't affect the flags. We assume that shifts by constant
11771 ;; zero are optimized away.
11772 (define_insn "*ashrqi3_cmp"
11773 [(set (reg 17)
11774 (compare
11775 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11776 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11777 (const_int 0)))
11778 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11779 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11780 "ix86_match_ccmode (insn, CCGOCmode)
11781 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11782 "sar{b}\t{%2, %0|%0, %2}"
11783 [(set_attr "type" "ishift")
11784 (set_attr "mode" "QI")])
11785 \f
11786 ;; Logical shift instructions
11787
11788 ;; See comment above `ashldi3' about how this works.
11789
11790 (define_expand "lshrdi3"
11791 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11792 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11793 (match_operand:QI 2 "nonmemory_operand" "")))
11794 (clobber (reg:CC 17))])]
11795 ""
11796 {
11797 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11798 {
11799 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11800 DONE;
11801 }
11802 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11803 DONE;
11804 })
11805
11806 (define_insn "*lshrdi3_1_one_bit_rex64"
11807 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11808 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11809 (match_operand:QI 2 "const1_operand" "")))
11810 (clobber (reg:CC 17))]
11811 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11812 && (TARGET_SHIFT1 || optimize_size)"
11813 "shr{q}\t%0"
11814 [(set_attr "type" "ishift")
11815 (set (attr "length")
11816 (if_then_else (match_operand:DI 0 "register_operand" "")
11817 (const_string "2")
11818 (const_string "*")))])
11819
11820 (define_insn "*lshrdi3_1_rex64"
11821 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11822 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11823 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11824 (clobber (reg:CC 17))]
11825 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11826 "@
11827 shr{q}\t{%2, %0|%0, %2}
11828 shr{q}\t{%b2, %0|%0, %b2}"
11829 [(set_attr "type" "ishift")
11830 (set_attr "mode" "DI")])
11831
11832 ;; This pattern can't accept a variable shift count, since shifts by
11833 ;; zero don't affect the flags. We assume that shifts by constant
11834 ;; zero are optimized away.
11835 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11836 [(set (reg 17)
11837 (compare
11838 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11839 (match_operand:QI 2 "const1_operand" ""))
11840 (const_int 0)))
11841 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11842 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11843 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11844 && (TARGET_SHIFT1 || optimize_size)
11845 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11846 "shr{q}\t%0"
11847 [(set_attr "type" "ishift")
11848 (set (attr "length")
11849 (if_then_else (match_operand:DI 0 "register_operand" "")
11850 (const_string "2")
11851 (const_string "*")))])
11852
11853 ;; This pattern can't accept a variable shift count, since shifts by
11854 ;; zero don't affect the flags. We assume that shifts by constant
11855 ;; zero are optimized away.
11856 (define_insn "*lshrdi3_cmp_rex64"
11857 [(set (reg 17)
11858 (compare
11859 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11860 (match_operand:QI 2 "const_int_operand" "e"))
11861 (const_int 0)))
11862 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11863 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11864 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11865 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11866 "shr{q}\t{%2, %0|%0, %2}"
11867 [(set_attr "type" "ishift")
11868 (set_attr "mode" "DI")])
11869
11870 (define_insn "lshrdi3_1"
11871 [(set (match_operand:DI 0 "register_operand" "=r")
11872 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11873 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11874 (clobber (match_scratch:SI 3 "=&r"))
11875 (clobber (reg:CC 17))]
11876 "!TARGET_64BIT && TARGET_CMOVE"
11877 "#"
11878 [(set_attr "type" "multi")])
11879
11880 (define_insn "*lshrdi3_2"
11881 [(set (match_operand:DI 0 "register_operand" "=r")
11882 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11883 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11884 (clobber (reg:CC 17))]
11885 "!TARGET_64BIT"
11886 "#"
11887 [(set_attr "type" "multi")])
11888
11889 (define_split
11890 [(set (match_operand:DI 0 "register_operand" "")
11891 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11892 (match_operand:QI 2 "nonmemory_operand" "")))
11893 (clobber (match_scratch:SI 3 ""))
11894 (clobber (reg:CC 17))]
11895 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11896 [(const_int 0)]
11897 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11898
11899 (define_split
11900 [(set (match_operand:DI 0 "register_operand" "")
11901 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11902 (match_operand:QI 2 "nonmemory_operand" "")))
11903 (clobber (reg:CC 17))]
11904 "!TARGET_64BIT && reload_completed"
11905 [(const_int 0)]
11906 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11907
11908 (define_expand "lshrsi3"
11909 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11910 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11911 (match_operand:QI 2 "nonmemory_operand" "")))
11912 (clobber (reg:CC 17))]
11913 ""
11914 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11915
11916 (define_insn "*lshrsi3_1_one_bit"
11917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11918 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11919 (match_operand:QI 2 "const1_operand" "")))
11920 (clobber (reg:CC 17))]
11921 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11922 && (TARGET_SHIFT1 || optimize_size)"
11923 "shr{l}\t%0"
11924 [(set_attr "type" "ishift")
11925 (set (attr "length")
11926 (if_then_else (match_operand:SI 0 "register_operand" "")
11927 (const_string "2")
11928 (const_string "*")))])
11929
11930 (define_insn "*lshrsi3_1_one_bit_zext"
11931 [(set (match_operand:DI 0 "register_operand" "=r")
11932 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11933 (match_operand:QI 2 "const1_operand" "")))
11934 (clobber (reg:CC 17))]
11935 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11936 && (TARGET_SHIFT1 || optimize_size)"
11937 "shr{l}\t%k0"
11938 [(set_attr "type" "ishift")
11939 (set_attr "length" "2")])
11940
11941 (define_insn "*lshrsi3_1"
11942 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11943 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11944 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11945 (clobber (reg:CC 17))]
11946 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11947 "@
11948 shr{l}\t{%2, %0|%0, %2}
11949 shr{l}\t{%b2, %0|%0, %b2}"
11950 [(set_attr "type" "ishift")
11951 (set_attr "mode" "SI")])
11952
11953 (define_insn "*lshrsi3_1_zext"
11954 [(set (match_operand:DI 0 "register_operand" "=r,r")
11955 (zero_extend:DI
11956 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11957 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11958 (clobber (reg:CC 17))]
11959 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11960 "@
11961 shr{l}\t{%2, %k0|%k0, %2}
11962 shr{l}\t{%b2, %k0|%k0, %b2}"
11963 [(set_attr "type" "ishift")
11964 (set_attr "mode" "SI")])
11965
11966 ;; This pattern can't accept a variable shift count, since shifts by
11967 ;; zero don't affect the flags. We assume that shifts by constant
11968 ;; zero are optimized away.
11969 (define_insn "*lshrsi3_one_bit_cmp"
11970 [(set (reg 17)
11971 (compare
11972 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11973 (match_operand:QI 2 "const1_operand" ""))
11974 (const_int 0)))
11975 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11976 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11977 "ix86_match_ccmode (insn, CCGOCmode)
11978 && (TARGET_SHIFT1 || optimize_size)
11979 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11980 "shr{l}\t%0"
11981 [(set_attr "type" "ishift")
11982 (set (attr "length")
11983 (if_then_else (match_operand:SI 0 "register_operand" "")
11984 (const_string "2")
11985 (const_string "*")))])
11986
11987 (define_insn "*lshrsi3_cmp_one_bit_zext"
11988 [(set (reg 17)
11989 (compare
11990 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11991 (match_operand:QI 2 "const1_operand" ""))
11992 (const_int 0)))
11993 (set (match_operand:DI 0 "register_operand" "=r")
11994 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11995 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11996 && (TARGET_SHIFT1 || optimize_size)
11997 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11998 "shr{l}\t%k0"
11999 [(set_attr "type" "ishift")
12000 (set_attr "length" "2")])
12001
12002 ;; This pattern can't accept a variable shift count, since shifts by
12003 ;; zero don't affect the flags. We assume that shifts by constant
12004 ;; zero are optimized away.
12005 (define_insn "*lshrsi3_cmp"
12006 [(set (reg 17)
12007 (compare
12008 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12009 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12010 (const_int 0)))
12011 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12012 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12013 "ix86_match_ccmode (insn, CCGOCmode)
12014 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12015 "shr{l}\t{%2, %0|%0, %2}"
12016 [(set_attr "type" "ishift")
12017 (set_attr "mode" "SI")])
12018
12019 (define_insn "*lshrsi3_cmp_zext"
12020 [(set (reg 17)
12021 (compare
12022 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12023 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12024 (const_int 0)))
12025 (set (match_operand:DI 0 "register_operand" "=r")
12026 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12027 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12028 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12029 "shr{l}\t{%2, %k0|%k0, %2}"
12030 [(set_attr "type" "ishift")
12031 (set_attr "mode" "SI")])
12032
12033 (define_expand "lshrhi3"
12034 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12035 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12036 (match_operand:QI 2 "nonmemory_operand" "")))
12037 (clobber (reg:CC 17))]
12038 "TARGET_HIMODE_MATH"
12039 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12040
12041 (define_insn "*lshrhi3_1_one_bit"
12042 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12043 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12044 (match_operand:QI 2 "const1_operand" "")))
12045 (clobber (reg:CC 17))]
12046 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12047 && (TARGET_SHIFT1 || optimize_size)"
12048 "shr{w}\t%0"
12049 [(set_attr "type" "ishift")
12050 (set (attr "length")
12051 (if_then_else (match_operand 0 "register_operand" "")
12052 (const_string "2")
12053 (const_string "*")))])
12054
12055 (define_insn "*lshrhi3_1"
12056 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12057 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12058 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12059 (clobber (reg:CC 17))]
12060 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12061 "@
12062 shr{w}\t{%2, %0|%0, %2}
12063 shr{w}\t{%b2, %0|%0, %b2}"
12064 [(set_attr "type" "ishift")
12065 (set_attr "mode" "HI")])
12066
12067 ;; This pattern can't accept a variable shift count, since shifts by
12068 ;; zero don't affect the flags. We assume that shifts by constant
12069 ;; zero are optimized away.
12070 (define_insn "*lshrhi3_one_bit_cmp"
12071 [(set (reg 17)
12072 (compare
12073 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const1_operand" ""))
12075 (const_int 0)))
12076 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12077 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12078 "ix86_match_ccmode (insn, CCGOCmode)
12079 && (TARGET_SHIFT1 || optimize_size)
12080 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12081 "shr{w}\t%0"
12082 [(set_attr "type" "ishift")
12083 (set (attr "length")
12084 (if_then_else (match_operand:SI 0 "register_operand" "")
12085 (const_string "2")
12086 (const_string "*")))])
12087
12088 ;; This pattern can't accept a variable shift count, since shifts by
12089 ;; zero don't affect the flags. We assume that shifts by constant
12090 ;; zero are optimized away.
12091 (define_insn "*lshrhi3_cmp"
12092 [(set (reg 17)
12093 (compare
12094 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12095 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12096 (const_int 0)))
12097 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12098 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12099 "ix86_match_ccmode (insn, CCGOCmode)
12100 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12101 "shr{w}\t{%2, %0|%0, %2}"
12102 [(set_attr "type" "ishift")
12103 (set_attr "mode" "HI")])
12104
12105 (define_expand "lshrqi3"
12106 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12107 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12108 (match_operand:QI 2 "nonmemory_operand" "")))
12109 (clobber (reg:CC 17))]
12110 "TARGET_QIMODE_MATH"
12111 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12112
12113 (define_insn "*lshrqi3_1_one_bit"
12114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12115 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12116 (match_operand:QI 2 "const1_operand" "")))
12117 (clobber (reg:CC 17))]
12118 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12119 && (TARGET_SHIFT1 || optimize_size)"
12120 "shr{b}\t%0"
12121 [(set_attr "type" "ishift")
12122 (set (attr "length")
12123 (if_then_else (match_operand 0 "register_operand" "")
12124 (const_string "2")
12125 (const_string "*")))])
12126
12127 (define_insn "*lshrqi3_1_one_bit_slp"
12128 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12129 (lshiftrt:QI (match_dup 0)
12130 (match_operand:QI 1 "const1_operand" "")))
12131 (clobber (reg:CC 17))]
12132 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12133 && (TARGET_SHIFT1 || optimize_size)"
12134 "shr{b}\t%0"
12135 [(set_attr "type" "ishift1")
12136 (set (attr "length")
12137 (if_then_else (match_operand 0 "register_operand" "")
12138 (const_string "2")
12139 (const_string "*")))])
12140
12141 (define_insn "*lshrqi3_1"
12142 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12143 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12144 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12145 (clobber (reg:CC 17))]
12146 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12147 "@
12148 shr{b}\t{%2, %0|%0, %2}
12149 shr{b}\t{%b2, %0|%0, %b2}"
12150 [(set_attr "type" "ishift")
12151 (set_attr "mode" "QI")])
12152
12153 (define_insn "*lshrqi3_1_slp"
12154 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12155 (lshiftrt:QI (match_dup 0)
12156 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12157 (clobber (reg:CC 17))]
12158 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12159 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12160 "@
12161 shr{b}\t{%1, %0|%0, %1}
12162 shr{b}\t{%b1, %0|%0, %b1}"
12163 [(set_attr "type" "ishift1")
12164 (set_attr "mode" "QI")])
12165
12166 ;; This pattern can't accept a variable shift count, since shifts by
12167 ;; zero don't affect the flags. We assume that shifts by constant
12168 ;; zero are optimized away.
12169 (define_insn "*lshrqi2_one_bit_cmp"
12170 [(set (reg 17)
12171 (compare
12172 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12173 (match_operand:QI 2 "const1_operand" ""))
12174 (const_int 0)))
12175 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12176 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12177 "ix86_match_ccmode (insn, CCGOCmode)
12178 && (TARGET_SHIFT1 || optimize_size)
12179 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12180 "shr{b}\t%0"
12181 [(set_attr "type" "ishift")
12182 (set (attr "length")
12183 (if_then_else (match_operand:SI 0 "register_operand" "")
12184 (const_string "2")
12185 (const_string "*")))])
12186
12187 ;; This pattern can't accept a variable shift count, since shifts by
12188 ;; zero don't affect the flags. We assume that shifts by constant
12189 ;; zero are optimized away.
12190 (define_insn "*lshrqi2_cmp"
12191 [(set (reg 17)
12192 (compare
12193 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12194 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12195 (const_int 0)))
12196 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12197 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12198 "ix86_match_ccmode (insn, CCGOCmode)
12199 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12200 "shr{b}\t{%2, %0|%0, %2}"
12201 [(set_attr "type" "ishift")
12202 (set_attr "mode" "QI")])
12203 \f
12204 ;; Rotate instructions
12205
12206 (define_expand "rotldi3"
12207 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12208 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12209 (match_operand:QI 2 "nonmemory_operand" "")))
12210 (clobber (reg:CC 17))]
12211 "TARGET_64BIT"
12212 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12213
12214 (define_insn "*rotlsi3_1_one_bit_rex64"
12215 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12216 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12217 (match_operand:QI 2 "const1_operand" "")))
12218 (clobber (reg:CC 17))]
12219 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12220 && (TARGET_SHIFT1 || optimize_size)"
12221 "rol{q}\t%0"
12222 [(set_attr "type" "rotate")
12223 (set (attr "length")
12224 (if_then_else (match_operand:DI 0 "register_operand" "")
12225 (const_string "2")
12226 (const_string "*")))])
12227
12228 (define_insn "*rotldi3_1_rex64"
12229 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12230 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12231 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12232 (clobber (reg:CC 17))]
12233 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12234 "@
12235 rol{q}\t{%2, %0|%0, %2}
12236 rol{q}\t{%b2, %0|%0, %b2}"
12237 [(set_attr "type" "rotate")
12238 (set_attr "mode" "DI")])
12239
12240 (define_expand "rotlsi3"
12241 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12242 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12243 (match_operand:QI 2 "nonmemory_operand" "")))
12244 (clobber (reg:CC 17))]
12245 ""
12246 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12247
12248 (define_insn "*rotlsi3_1_one_bit"
12249 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12250 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12251 (match_operand:QI 2 "const1_operand" "")))
12252 (clobber (reg:CC 17))]
12253 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12254 && (TARGET_SHIFT1 || optimize_size)"
12255 "rol{l}\t%0"
12256 [(set_attr "type" "rotate")
12257 (set (attr "length")
12258 (if_then_else (match_operand:SI 0 "register_operand" "")
12259 (const_string "2")
12260 (const_string "*")))])
12261
12262 (define_insn "*rotlsi3_1_one_bit_zext"
12263 [(set (match_operand:DI 0 "register_operand" "=r")
12264 (zero_extend:DI
12265 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12266 (match_operand:QI 2 "const1_operand" ""))))
12267 (clobber (reg:CC 17))]
12268 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12269 && (TARGET_SHIFT1 || optimize_size)"
12270 "rol{l}\t%k0"
12271 [(set_attr "type" "rotate")
12272 (set_attr "length" "2")])
12273
12274 (define_insn "*rotlsi3_1"
12275 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12276 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12277 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12278 (clobber (reg:CC 17))]
12279 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12280 "@
12281 rol{l}\t{%2, %0|%0, %2}
12282 rol{l}\t{%b2, %0|%0, %b2}"
12283 [(set_attr "type" "rotate")
12284 (set_attr "mode" "SI")])
12285
12286 (define_insn "*rotlsi3_1_zext"
12287 [(set (match_operand:DI 0 "register_operand" "=r,r")
12288 (zero_extend:DI
12289 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12290 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12291 (clobber (reg:CC 17))]
12292 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12293 "@
12294 rol{l}\t{%2, %k0|%k0, %2}
12295 rol{l}\t{%b2, %k0|%k0, %b2}"
12296 [(set_attr "type" "rotate")
12297 (set_attr "mode" "SI")])
12298
12299 (define_expand "rotlhi3"
12300 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12301 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12302 (match_operand:QI 2 "nonmemory_operand" "")))
12303 (clobber (reg:CC 17))]
12304 "TARGET_HIMODE_MATH"
12305 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12306
12307 (define_insn "*rotlhi3_1_one_bit"
12308 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12309 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12310 (match_operand:QI 2 "const1_operand" "")))
12311 (clobber (reg:CC 17))]
12312 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12313 && (TARGET_SHIFT1 || optimize_size)"
12314 "rol{w}\t%0"
12315 [(set_attr "type" "rotate")
12316 (set (attr "length")
12317 (if_then_else (match_operand 0 "register_operand" "")
12318 (const_string "2")
12319 (const_string "*")))])
12320
12321 (define_insn "*rotlhi3_1"
12322 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12323 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12324 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12325 (clobber (reg:CC 17))]
12326 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12327 "@
12328 rol{w}\t{%2, %0|%0, %2}
12329 rol{w}\t{%b2, %0|%0, %b2}"
12330 [(set_attr "type" "rotate")
12331 (set_attr "mode" "HI")])
12332
12333 (define_expand "rotlqi3"
12334 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12335 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12336 (match_operand:QI 2 "nonmemory_operand" "")))
12337 (clobber (reg:CC 17))]
12338 "TARGET_QIMODE_MATH"
12339 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12340
12341 (define_insn "*rotlqi3_1_one_bit_slp"
12342 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12343 (rotate:QI (match_dup 0)
12344 (match_operand:QI 1 "const1_operand" "")))
12345 (clobber (reg:CC 17))]
12346 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12347 && (TARGET_SHIFT1 || optimize_size)"
12348 "rol{b}\t%0"
12349 [(set_attr "type" "rotate1")
12350 (set (attr "length")
12351 (if_then_else (match_operand 0 "register_operand" "")
12352 (const_string "2")
12353 (const_string "*")))])
12354
12355 (define_insn "*rotlqi3_1_one_bit"
12356 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12357 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12358 (match_operand:QI 2 "const1_operand" "")))
12359 (clobber (reg:CC 17))]
12360 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12361 && (TARGET_SHIFT1 || optimize_size)"
12362 "rol{b}\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 "*rotlqi3_1_slp"
12370 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12371 (rotate:QI (match_dup 0)
12372 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12373 (clobber (reg:CC 17))]
12374 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12375 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12376 "@
12377 rol{b}\t{%1, %0|%0, %1}
12378 rol{b}\t{%b1, %0|%0, %b1}"
12379 [(set_attr "type" "rotate1")
12380 (set_attr "mode" "QI")])
12381
12382 (define_insn "*rotlqi3_1"
12383 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12384 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12385 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12386 (clobber (reg:CC 17))]
12387 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12388 "@
12389 rol{b}\t{%2, %0|%0, %2}
12390 rol{b}\t{%b2, %0|%0, %b2}"
12391 [(set_attr "type" "rotate")
12392 (set_attr "mode" "QI")])
12393
12394 (define_expand "rotrdi3"
12395 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12396 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12397 (match_operand:QI 2 "nonmemory_operand" "")))
12398 (clobber (reg:CC 17))]
12399 "TARGET_64BIT"
12400 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12401
12402 (define_insn "*rotrdi3_1_one_bit_rex64"
12403 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12404 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12405 (match_operand:QI 2 "const1_operand" "")))
12406 (clobber (reg:CC 17))]
12407 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12408 && (TARGET_SHIFT1 || optimize_size)"
12409 "ror{q}\t%0"
12410 [(set_attr "type" "rotate")
12411 (set (attr "length")
12412 (if_then_else (match_operand:DI 0 "register_operand" "")
12413 (const_string "2")
12414 (const_string "*")))])
12415
12416 (define_insn "*rotrdi3_1_rex64"
12417 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12418 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12419 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12420 (clobber (reg:CC 17))]
12421 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12422 "@
12423 ror{q}\t{%2, %0|%0, %2}
12424 ror{q}\t{%b2, %0|%0, %b2}"
12425 [(set_attr "type" "rotate")
12426 (set_attr "mode" "DI")])
12427
12428 (define_expand "rotrsi3"
12429 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12430 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12431 (match_operand:QI 2 "nonmemory_operand" "")))
12432 (clobber (reg:CC 17))]
12433 ""
12434 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12435
12436 (define_insn "*rotrsi3_1_one_bit"
12437 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12438 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12439 (match_operand:QI 2 "const1_operand" "")))
12440 (clobber (reg:CC 17))]
12441 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12442 && (TARGET_SHIFT1 || optimize_size)"
12443 "ror{l}\t%0"
12444 [(set_attr "type" "rotate")
12445 (set (attr "length")
12446 (if_then_else (match_operand:SI 0 "register_operand" "")
12447 (const_string "2")
12448 (const_string "*")))])
12449
12450 (define_insn "*rotrsi3_1_one_bit_zext"
12451 [(set (match_operand:DI 0 "register_operand" "=r")
12452 (zero_extend:DI
12453 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12454 (match_operand:QI 2 "const1_operand" ""))))
12455 (clobber (reg:CC 17))]
12456 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12457 && (TARGET_SHIFT1 || optimize_size)"
12458 "ror{l}\t%k0"
12459 [(set_attr "type" "rotate")
12460 (set (attr "length")
12461 (if_then_else (match_operand:SI 0 "register_operand" "")
12462 (const_string "2")
12463 (const_string "*")))])
12464
12465 (define_insn "*rotrsi3_1"
12466 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12467 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12468 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12469 (clobber (reg:CC 17))]
12470 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12471 "@
12472 ror{l}\t{%2, %0|%0, %2}
12473 ror{l}\t{%b2, %0|%0, %b2}"
12474 [(set_attr "type" "rotate")
12475 (set_attr "mode" "SI")])
12476
12477 (define_insn "*rotrsi3_1_zext"
12478 [(set (match_operand:DI 0 "register_operand" "=r,r")
12479 (zero_extend:DI
12480 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12481 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12482 (clobber (reg:CC 17))]
12483 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12484 "@
12485 ror{l}\t{%2, %k0|%k0, %2}
12486 ror{l}\t{%b2, %k0|%k0, %b2}"
12487 [(set_attr "type" "rotate")
12488 (set_attr "mode" "SI")])
12489
12490 (define_expand "rotrhi3"
12491 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12492 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12493 (match_operand:QI 2 "nonmemory_operand" "")))
12494 (clobber (reg:CC 17))]
12495 "TARGET_HIMODE_MATH"
12496 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12497
12498 (define_insn "*rotrhi3_one_bit"
12499 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12500 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12501 (match_operand:QI 2 "const1_operand" "")))
12502 (clobber (reg:CC 17))]
12503 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12504 && (TARGET_SHIFT1 || optimize_size)"
12505 "ror{w}\t%0"
12506 [(set_attr "type" "rotate")
12507 (set (attr "length")
12508 (if_then_else (match_operand 0 "register_operand" "")
12509 (const_string "2")
12510 (const_string "*")))])
12511
12512 (define_insn "*rotrhi3"
12513 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12514 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12515 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12516 (clobber (reg:CC 17))]
12517 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12518 "@
12519 ror{w}\t{%2, %0|%0, %2}
12520 ror{w}\t{%b2, %0|%0, %b2}"
12521 [(set_attr "type" "rotate")
12522 (set_attr "mode" "HI")])
12523
12524 (define_expand "rotrqi3"
12525 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12526 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12527 (match_operand:QI 2 "nonmemory_operand" "")))
12528 (clobber (reg:CC 17))]
12529 "TARGET_QIMODE_MATH"
12530 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12531
12532 (define_insn "*rotrqi3_1_one_bit"
12533 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12534 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12535 (match_operand:QI 2 "const1_operand" "")))
12536 (clobber (reg:CC 17))]
12537 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12538 && (TARGET_SHIFT1 || optimize_size)"
12539 "ror{b}\t%0"
12540 [(set_attr "type" "rotate")
12541 (set (attr "length")
12542 (if_then_else (match_operand 0 "register_operand" "")
12543 (const_string "2")
12544 (const_string "*")))])
12545
12546 (define_insn "*rotrqi3_1_one_bit_slp"
12547 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12548 (rotatert:QI (match_dup 0)
12549 (match_operand:QI 1 "const1_operand" "")))
12550 (clobber (reg:CC 17))]
12551 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12552 && (TARGET_SHIFT1 || optimize_size)"
12553 "ror{b}\t%0"
12554 [(set_attr "type" "rotate1")
12555 (set (attr "length")
12556 (if_then_else (match_operand 0 "register_operand" "")
12557 (const_string "2")
12558 (const_string "*")))])
12559
12560 (define_insn "*rotrqi3_1"
12561 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12562 (rotatert:QI (match_operand:QI 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, QImode, operands)"
12566 "@
12567 ror{b}\t{%2, %0|%0, %2}
12568 ror{b}\t{%b2, %0|%0, %b2}"
12569 [(set_attr "type" "rotate")
12570 (set_attr "mode" "QI")])
12571
12572 (define_insn "*rotrqi3_1_slp"
12573 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12574 (rotatert:QI (match_dup 0)
12575 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12576 (clobber (reg:CC 17))]
12577 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12578 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12579 "@
12580 ror{b}\t{%1, %0|%0, %1}
12581 ror{b}\t{%b1, %0|%0, %b1}"
12582 [(set_attr "type" "rotate1")
12583 (set_attr "mode" "QI")])
12584 \f
12585 ;; Bit set / bit test instructions
12586
12587 (define_expand "extv"
12588 [(set (match_operand:SI 0 "register_operand" "")
12589 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12590 (match_operand:SI 2 "immediate_operand" "")
12591 (match_operand:SI 3 "immediate_operand" "")))]
12592 ""
12593 {
12594 /* Handle extractions from %ah et al. */
12595 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12596 FAIL;
12597
12598 /* From mips.md: extract_bit_field doesn't verify that our source
12599 matches the predicate, so check it again here. */
12600 if (! register_operand (operands[1], VOIDmode))
12601 FAIL;
12602 })
12603
12604 (define_expand "extzv"
12605 [(set (match_operand:SI 0 "register_operand" "")
12606 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12607 (match_operand:SI 2 "immediate_operand" "")
12608 (match_operand:SI 3 "immediate_operand" "")))]
12609 ""
12610 {
12611 /* Handle extractions from %ah et al. */
12612 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12613 FAIL;
12614
12615 /* From mips.md: extract_bit_field doesn't verify that our source
12616 matches the predicate, so check it again here. */
12617 if (! register_operand (operands[1], VOIDmode))
12618 FAIL;
12619 })
12620
12621 (define_expand "insv"
12622 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12623 (match_operand:SI 1 "immediate_operand" "")
12624 (match_operand:SI 2 "immediate_operand" ""))
12625 (match_operand:SI 3 "register_operand" ""))]
12626 ""
12627 {
12628 /* Handle extractions from %ah et al. */
12629 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12630 FAIL;
12631
12632 /* From mips.md: insert_bit_field doesn't verify that our source
12633 matches the predicate, so check it again here. */
12634 if (! register_operand (operands[0], VOIDmode))
12635 FAIL;
12636 })
12637
12638 ;; %%% bts, btr, btc, bt.
12639 \f
12640 ;; Store-flag instructions.
12641
12642 ;; For all sCOND expanders, also expand the compare or test insn that
12643 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12644
12645 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12646 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12647 ;; way, which can later delete the movzx if only QImode is needed.
12648
12649 (define_expand "seq"
12650 [(set (match_operand:QI 0 "register_operand" "")
12651 (eq:QI (reg:CC 17) (const_int 0)))]
12652 ""
12653 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12654
12655 (define_expand "sne"
12656 [(set (match_operand:QI 0 "register_operand" "")
12657 (ne:QI (reg:CC 17) (const_int 0)))]
12658 ""
12659 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12660
12661 (define_expand "sgt"
12662 [(set (match_operand:QI 0 "register_operand" "")
12663 (gt:QI (reg:CC 17) (const_int 0)))]
12664 ""
12665 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12666
12667 (define_expand "sgtu"
12668 [(set (match_operand:QI 0 "register_operand" "")
12669 (gtu:QI (reg:CC 17) (const_int 0)))]
12670 ""
12671 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12672
12673 (define_expand "slt"
12674 [(set (match_operand:QI 0 "register_operand" "")
12675 (lt:QI (reg:CC 17) (const_int 0)))]
12676 ""
12677 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12678
12679 (define_expand "sltu"
12680 [(set (match_operand:QI 0 "register_operand" "")
12681 (ltu:QI (reg:CC 17) (const_int 0)))]
12682 ""
12683 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12684
12685 (define_expand "sge"
12686 [(set (match_operand:QI 0 "register_operand" "")
12687 (ge:QI (reg:CC 17) (const_int 0)))]
12688 ""
12689 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12690
12691 (define_expand "sgeu"
12692 [(set (match_operand:QI 0 "register_operand" "")
12693 (geu:QI (reg:CC 17) (const_int 0)))]
12694 ""
12695 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12696
12697 (define_expand "sle"
12698 [(set (match_operand:QI 0 "register_operand" "")
12699 (le:QI (reg:CC 17) (const_int 0)))]
12700 ""
12701 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12702
12703 (define_expand "sleu"
12704 [(set (match_operand:QI 0 "register_operand" "")
12705 (leu:QI (reg:CC 17) (const_int 0)))]
12706 ""
12707 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12708
12709 (define_expand "sunordered"
12710 [(set (match_operand:QI 0 "register_operand" "")
12711 (unordered:QI (reg:CC 17) (const_int 0)))]
12712 "TARGET_80387 || TARGET_SSE"
12713 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12714
12715 (define_expand "sordered"
12716 [(set (match_operand:QI 0 "register_operand" "")
12717 (ordered:QI (reg:CC 17) (const_int 0)))]
12718 "TARGET_80387"
12719 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12720
12721 (define_expand "suneq"
12722 [(set (match_operand:QI 0 "register_operand" "")
12723 (uneq:QI (reg:CC 17) (const_int 0)))]
12724 "TARGET_80387 || TARGET_SSE"
12725 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12726
12727 (define_expand "sunge"
12728 [(set (match_operand:QI 0 "register_operand" "")
12729 (unge:QI (reg:CC 17) (const_int 0)))]
12730 "TARGET_80387 || TARGET_SSE"
12731 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12732
12733 (define_expand "sungt"
12734 [(set (match_operand:QI 0 "register_operand" "")
12735 (ungt:QI (reg:CC 17) (const_int 0)))]
12736 "TARGET_80387 || TARGET_SSE"
12737 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12738
12739 (define_expand "sunle"
12740 [(set (match_operand:QI 0 "register_operand" "")
12741 (unle:QI (reg:CC 17) (const_int 0)))]
12742 "TARGET_80387 || TARGET_SSE"
12743 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12744
12745 (define_expand "sunlt"
12746 [(set (match_operand:QI 0 "register_operand" "")
12747 (unlt:QI (reg:CC 17) (const_int 0)))]
12748 "TARGET_80387 || TARGET_SSE"
12749 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12750
12751 (define_expand "sltgt"
12752 [(set (match_operand:QI 0 "register_operand" "")
12753 (ltgt:QI (reg:CC 17) (const_int 0)))]
12754 "TARGET_80387 || TARGET_SSE"
12755 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12756
12757 (define_insn "*setcc_1"
12758 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12759 (match_operator:QI 1 "ix86_comparison_operator"
12760 [(reg 17) (const_int 0)]))]
12761 ""
12762 "set%C1\t%0"
12763 [(set_attr "type" "setcc")
12764 (set_attr "mode" "QI")])
12765
12766 (define_insn "setcc_2"
12767 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12768 (match_operator:QI 1 "ix86_comparison_operator"
12769 [(reg 17) (const_int 0)]))]
12770 ""
12771 "set%C1\t%0"
12772 [(set_attr "type" "setcc")
12773 (set_attr "mode" "QI")])
12774
12775 ;; In general it is not safe to assume too much about CCmode registers,
12776 ;; so simplify-rtx stops when it sees a second one. Under certain
12777 ;; conditions this is safe on x86, so help combine not create
12778 ;;
12779 ;; seta %al
12780 ;; testb %al, %al
12781 ;; sete %al
12782
12783 (define_split
12784 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12785 (ne:QI (match_operator 1 "ix86_comparison_operator"
12786 [(reg 17) (const_int 0)])
12787 (const_int 0)))]
12788 ""
12789 [(set (match_dup 0) (match_dup 1))]
12790 {
12791 PUT_MODE (operands[1], QImode);
12792 })
12793
12794 (define_split
12795 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12796 (ne:QI (match_operator 1 "ix86_comparison_operator"
12797 [(reg 17) (const_int 0)])
12798 (const_int 0)))]
12799 ""
12800 [(set (match_dup 0) (match_dup 1))]
12801 {
12802 PUT_MODE (operands[1], QImode);
12803 })
12804
12805 (define_split
12806 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12807 (eq:QI (match_operator 1 "ix86_comparison_operator"
12808 [(reg 17) (const_int 0)])
12809 (const_int 0)))]
12810 ""
12811 [(set (match_dup 0) (match_dup 1))]
12812 {
12813 rtx new_op1 = copy_rtx (operands[1]);
12814 operands[1] = new_op1;
12815 PUT_MODE (new_op1, QImode);
12816 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12817 GET_MODE (XEXP (new_op1, 0))));
12818
12819 /* Make sure that (a) the CCmode we have for the flags is strong
12820 enough for the reversed compare or (b) we have a valid FP compare. */
12821 if (! ix86_comparison_operator (new_op1, VOIDmode))
12822 FAIL;
12823 })
12824
12825 (define_split
12826 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12827 (eq:QI (match_operator 1 "ix86_comparison_operator"
12828 [(reg 17) (const_int 0)])
12829 (const_int 0)))]
12830 ""
12831 [(set (match_dup 0) (match_dup 1))]
12832 {
12833 rtx new_op1 = copy_rtx (operands[1]);
12834 operands[1] = new_op1;
12835 PUT_MODE (new_op1, QImode);
12836 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12837 GET_MODE (XEXP (new_op1, 0))));
12838
12839 /* Make sure that (a) the CCmode we have for the flags is strong
12840 enough for the reversed compare or (b) we have a valid FP compare. */
12841 if (! ix86_comparison_operator (new_op1, VOIDmode))
12842 FAIL;
12843 })
12844
12845 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12846 ;; subsequent logical operations are used to imitate conditional moves.
12847 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12848 ;; it directly. Further holding this value in pseudo register might bring
12849 ;; problem in implicit normalization in spill code.
12850 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12851 ;; instructions after reload by splitting the conditional move patterns.
12852
12853 (define_insn "*sse_setccsf"
12854 [(set (match_operand:SF 0 "register_operand" "=x")
12855 (match_operator:SF 1 "sse_comparison_operator"
12856 [(match_operand:SF 2 "register_operand" "0")
12857 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12858 "TARGET_SSE && reload_completed"
12859 "cmp%D1ss\t{%3, %0|%0, %3}"
12860 [(set_attr "type" "ssecmp")
12861 (set_attr "mode" "SF")])
12862
12863 (define_insn "*sse_setccdf"
12864 [(set (match_operand:DF 0 "register_operand" "=Y")
12865 (match_operator:DF 1 "sse_comparison_operator"
12866 [(match_operand:DF 2 "register_operand" "0")
12867 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12868 "TARGET_SSE2 && reload_completed"
12869 "cmp%D1sd\t{%3, %0|%0, %3}"
12870 [(set_attr "type" "ssecmp")
12871 (set_attr "mode" "DF")])
12872 \f
12873 ;; Basic conditional jump instructions.
12874 ;; We ignore the overflow flag for signed branch instructions.
12875
12876 ;; For all bCOND expanders, also expand the compare or test insn that
12877 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12878
12879 (define_expand "beq"
12880 [(set (pc)
12881 (if_then_else (match_dup 1)
12882 (label_ref (match_operand 0 "" ""))
12883 (pc)))]
12884 ""
12885 "ix86_expand_branch (EQ, operands[0]); DONE;")
12886
12887 (define_expand "bne"
12888 [(set (pc)
12889 (if_then_else (match_dup 1)
12890 (label_ref (match_operand 0 "" ""))
12891 (pc)))]
12892 ""
12893 "ix86_expand_branch (NE, operands[0]); DONE;")
12894
12895 (define_expand "bgt"
12896 [(set (pc)
12897 (if_then_else (match_dup 1)
12898 (label_ref (match_operand 0 "" ""))
12899 (pc)))]
12900 ""
12901 "ix86_expand_branch (GT, operands[0]); DONE;")
12902
12903 (define_expand "bgtu"
12904 [(set (pc)
12905 (if_then_else (match_dup 1)
12906 (label_ref (match_operand 0 "" ""))
12907 (pc)))]
12908 ""
12909 "ix86_expand_branch (GTU, operands[0]); DONE;")
12910
12911 (define_expand "blt"
12912 [(set (pc)
12913 (if_then_else (match_dup 1)
12914 (label_ref (match_operand 0 "" ""))
12915 (pc)))]
12916 ""
12917 "ix86_expand_branch (LT, operands[0]); DONE;")
12918
12919 (define_expand "bltu"
12920 [(set (pc)
12921 (if_then_else (match_dup 1)
12922 (label_ref (match_operand 0 "" ""))
12923 (pc)))]
12924 ""
12925 "ix86_expand_branch (LTU, operands[0]); DONE;")
12926
12927 (define_expand "bge"
12928 [(set (pc)
12929 (if_then_else (match_dup 1)
12930 (label_ref (match_operand 0 "" ""))
12931 (pc)))]
12932 ""
12933 "ix86_expand_branch (GE, operands[0]); DONE;")
12934
12935 (define_expand "bgeu"
12936 [(set (pc)
12937 (if_then_else (match_dup 1)
12938 (label_ref (match_operand 0 "" ""))
12939 (pc)))]
12940 ""
12941 "ix86_expand_branch (GEU, operands[0]); DONE;")
12942
12943 (define_expand "ble"
12944 [(set (pc)
12945 (if_then_else (match_dup 1)
12946 (label_ref (match_operand 0 "" ""))
12947 (pc)))]
12948 ""
12949 "ix86_expand_branch (LE, operands[0]); DONE;")
12950
12951 (define_expand "bleu"
12952 [(set (pc)
12953 (if_then_else (match_dup 1)
12954 (label_ref (match_operand 0 "" ""))
12955 (pc)))]
12956 ""
12957 "ix86_expand_branch (LEU, operands[0]); DONE;")
12958
12959 (define_expand "bunordered"
12960 [(set (pc)
12961 (if_then_else (match_dup 1)
12962 (label_ref (match_operand 0 "" ""))
12963 (pc)))]
12964 "TARGET_80387 || TARGET_SSE"
12965 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12966
12967 (define_expand "bordered"
12968 [(set (pc)
12969 (if_then_else (match_dup 1)
12970 (label_ref (match_operand 0 "" ""))
12971 (pc)))]
12972 "TARGET_80387 || TARGET_SSE"
12973 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12974
12975 (define_expand "buneq"
12976 [(set (pc)
12977 (if_then_else (match_dup 1)
12978 (label_ref (match_operand 0 "" ""))
12979 (pc)))]
12980 "TARGET_80387 || TARGET_SSE"
12981 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12982
12983 (define_expand "bunge"
12984 [(set (pc)
12985 (if_then_else (match_dup 1)
12986 (label_ref (match_operand 0 "" ""))
12987 (pc)))]
12988 "TARGET_80387 || TARGET_SSE"
12989 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12990
12991 (define_expand "bungt"
12992 [(set (pc)
12993 (if_then_else (match_dup 1)
12994 (label_ref (match_operand 0 "" ""))
12995 (pc)))]
12996 "TARGET_80387 || TARGET_SSE"
12997 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12998
12999 (define_expand "bunle"
13000 [(set (pc)
13001 (if_then_else (match_dup 1)
13002 (label_ref (match_operand 0 "" ""))
13003 (pc)))]
13004 "TARGET_80387 || TARGET_SSE"
13005 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13006
13007 (define_expand "bunlt"
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 (UNLT, operands[0]); DONE;")
13014
13015 (define_expand "bltgt"
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 (LTGT, operands[0]); DONE;")
13022
13023 (define_insn "*jcc_1"
13024 [(set (pc)
13025 (if_then_else (match_operator 1 "ix86_comparison_operator"
13026 [(reg 17) (const_int 0)])
13027 (label_ref (match_operand 0 "" ""))
13028 (pc)))]
13029 ""
13030 "%+j%C1\t%l0"
13031 [(set_attr "type" "ibr")
13032 (set_attr "modrm" "0")
13033 (set (attr "length")
13034 (if_then_else (and (ge (minus (match_dup 0) (pc))
13035 (const_int -126))
13036 (lt (minus (match_dup 0) (pc))
13037 (const_int 128)))
13038 (const_int 2)
13039 (const_int 6)))])
13040
13041 (define_insn "*jcc_2"
13042 [(set (pc)
13043 (if_then_else (match_operator 1 "ix86_comparison_operator"
13044 [(reg 17) (const_int 0)])
13045 (pc)
13046 (label_ref (match_operand 0 "" ""))))]
13047 ""
13048 "%+j%c1\t%l0"
13049 [(set_attr "type" "ibr")
13050 (set_attr "modrm" "0")
13051 (set (attr "length")
13052 (if_then_else (and (ge (minus (match_dup 0) (pc))
13053 (const_int -126))
13054 (lt (minus (match_dup 0) (pc))
13055 (const_int 128)))
13056 (const_int 2)
13057 (const_int 6)))])
13058
13059 ;; In general it is not safe to assume too much about CCmode registers,
13060 ;; so simplify-rtx stops when it sees a second one. Under certain
13061 ;; conditions this is safe on x86, so help combine not create
13062 ;;
13063 ;; seta %al
13064 ;; testb %al, %al
13065 ;; je Lfoo
13066
13067 (define_split
13068 [(set (pc)
13069 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13070 [(reg 17) (const_int 0)])
13071 (const_int 0))
13072 (label_ref (match_operand 1 "" ""))
13073 (pc)))]
13074 ""
13075 [(set (pc)
13076 (if_then_else (match_dup 0)
13077 (label_ref (match_dup 1))
13078 (pc)))]
13079 {
13080 PUT_MODE (operands[0], VOIDmode);
13081 })
13082
13083 (define_split
13084 [(set (pc)
13085 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13086 [(reg 17) (const_int 0)])
13087 (const_int 0))
13088 (label_ref (match_operand 1 "" ""))
13089 (pc)))]
13090 ""
13091 [(set (pc)
13092 (if_then_else (match_dup 0)
13093 (label_ref (match_dup 1))
13094 (pc)))]
13095 {
13096 rtx new_op0 = copy_rtx (operands[0]);
13097 operands[0] = new_op0;
13098 PUT_MODE (new_op0, VOIDmode);
13099 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13100 GET_MODE (XEXP (new_op0, 0))));
13101
13102 /* Make sure that (a) the CCmode we have for the flags is strong
13103 enough for the reversed compare or (b) we have a valid FP compare. */
13104 if (! ix86_comparison_operator (new_op0, VOIDmode))
13105 FAIL;
13106 })
13107
13108 ;; Define combination compare-and-branch fp compare instructions to use
13109 ;; during early optimization. Splitting the operation apart early makes
13110 ;; for bad code when we want to reverse the operation.
13111
13112 (define_insn "*fp_jcc_1"
13113 [(set (pc)
13114 (if_then_else (match_operator 0 "comparison_operator"
13115 [(match_operand 1 "register_operand" "f")
13116 (match_operand 2 "register_operand" "f")])
13117 (label_ref (match_operand 3 "" ""))
13118 (pc)))
13119 (clobber (reg:CCFP 18))
13120 (clobber (reg:CCFP 17))]
13121 "TARGET_CMOVE && TARGET_80387
13122 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13123 && FLOAT_MODE_P (GET_MODE (operands[1]))
13124 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13125 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13126 "#")
13127
13128 (define_insn "*fp_jcc_1_sse"
13129 [(set (pc)
13130 (if_then_else (match_operator 0 "comparison_operator"
13131 [(match_operand 1 "register_operand" "f#x,x#f")
13132 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13133 (label_ref (match_operand 3 "" ""))
13134 (pc)))
13135 (clobber (reg:CCFP 18))
13136 (clobber (reg:CCFP 17))]
13137 "TARGET_80387
13138 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13139 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13140 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13141 "#")
13142
13143 (define_insn "*fp_jcc_1_sse_only"
13144 [(set (pc)
13145 (if_then_else (match_operator 0 "comparison_operator"
13146 [(match_operand 1 "register_operand" "x")
13147 (match_operand 2 "nonimmediate_operand" "xm")])
13148 (label_ref (match_operand 3 "" ""))
13149 (pc)))
13150 (clobber (reg:CCFP 18))
13151 (clobber (reg:CCFP 17))]
13152 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13153 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13154 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13155 "#")
13156
13157 (define_insn "*fp_jcc_2"
13158 [(set (pc)
13159 (if_then_else (match_operator 0 "comparison_operator"
13160 [(match_operand 1 "register_operand" "f")
13161 (match_operand 2 "register_operand" "f")])
13162 (pc)
13163 (label_ref (match_operand 3 "" ""))))
13164 (clobber (reg:CCFP 18))
13165 (clobber (reg:CCFP 17))]
13166 "TARGET_CMOVE && TARGET_80387
13167 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13168 && FLOAT_MODE_P (GET_MODE (operands[1]))
13169 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13170 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13171 "#")
13172
13173 (define_insn "*fp_jcc_2_sse"
13174 [(set (pc)
13175 (if_then_else (match_operator 0 "comparison_operator"
13176 [(match_operand 1 "register_operand" "f#x,x#f")
13177 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13178 (pc)
13179 (label_ref (match_operand 3 "" ""))))
13180 (clobber (reg:CCFP 18))
13181 (clobber (reg:CCFP 17))]
13182 "TARGET_80387
13183 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13184 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13185 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13186 "#")
13187
13188 (define_insn "*fp_jcc_2_sse_only"
13189 [(set (pc)
13190 (if_then_else (match_operator 0 "comparison_operator"
13191 [(match_operand 1 "register_operand" "x")
13192 (match_operand 2 "nonimmediate_operand" "xm")])
13193 (pc)
13194 (label_ref (match_operand 3 "" ""))))
13195 (clobber (reg:CCFP 18))
13196 (clobber (reg:CCFP 17))]
13197 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13198 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13199 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13200 "#")
13201
13202 (define_insn "*fp_jcc_3"
13203 [(set (pc)
13204 (if_then_else (match_operator 0 "comparison_operator"
13205 [(match_operand 1 "register_operand" "f")
13206 (match_operand 2 "nonimmediate_operand" "fm")])
13207 (label_ref (match_operand 3 "" ""))
13208 (pc)))
13209 (clobber (reg:CCFP 18))
13210 (clobber (reg:CCFP 17))
13211 (clobber (match_scratch:HI 4 "=a"))]
13212 "TARGET_80387
13213 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13214 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13215 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13216 && SELECT_CC_MODE (GET_CODE (operands[0]),
13217 operands[1], operands[2]) == CCFPmode
13218 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13219 "#")
13220
13221 (define_insn "*fp_jcc_4"
13222 [(set (pc)
13223 (if_then_else (match_operator 0 "comparison_operator"
13224 [(match_operand 1 "register_operand" "f")
13225 (match_operand 2 "nonimmediate_operand" "fm")])
13226 (pc)
13227 (label_ref (match_operand 3 "" ""))))
13228 (clobber (reg:CCFP 18))
13229 (clobber (reg:CCFP 17))
13230 (clobber (match_scratch:HI 4 "=a"))]
13231 "TARGET_80387
13232 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13233 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13234 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13235 && SELECT_CC_MODE (GET_CODE (operands[0]),
13236 operands[1], operands[2]) == CCFPmode
13237 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13238 "#")
13239
13240 (define_insn "*fp_jcc_5"
13241 [(set (pc)
13242 (if_then_else (match_operator 0 "comparison_operator"
13243 [(match_operand 1 "register_operand" "f")
13244 (match_operand 2 "register_operand" "f")])
13245 (label_ref (match_operand 3 "" ""))
13246 (pc)))
13247 (clobber (reg:CCFP 18))
13248 (clobber (reg:CCFP 17))
13249 (clobber (match_scratch:HI 4 "=a"))]
13250 "TARGET_80387
13251 && FLOAT_MODE_P (GET_MODE (operands[1]))
13252 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13253 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13254 "#")
13255
13256 (define_insn "*fp_jcc_6"
13257 [(set (pc)
13258 (if_then_else (match_operator 0 "comparison_operator"
13259 [(match_operand 1 "register_operand" "f")
13260 (match_operand 2 "register_operand" "f")])
13261 (pc)
13262 (label_ref (match_operand 3 "" ""))))
13263 (clobber (reg:CCFP 18))
13264 (clobber (reg:CCFP 17))
13265 (clobber (match_scratch:HI 4 "=a"))]
13266 "TARGET_80387
13267 && FLOAT_MODE_P (GET_MODE (operands[1]))
13268 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13269 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13270 "#")
13271
13272 (define_split
13273 [(set (pc)
13274 (if_then_else (match_operator 0 "comparison_operator"
13275 [(match_operand 1 "register_operand" "")
13276 (match_operand 2 "nonimmediate_operand" "")])
13277 (match_operand 3 "" "")
13278 (match_operand 4 "" "")))
13279 (clobber (reg:CCFP 18))
13280 (clobber (reg:CCFP 17))]
13281 "reload_completed"
13282 [(const_int 0)]
13283 {
13284 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13285 operands[3], operands[4], NULL_RTX);
13286 DONE;
13287 })
13288
13289 (define_split
13290 [(set (pc)
13291 (if_then_else (match_operator 0 "comparison_operator"
13292 [(match_operand 1 "register_operand" "")
13293 (match_operand 2 "nonimmediate_operand" "")])
13294 (match_operand 3 "" "")
13295 (match_operand 4 "" "")))
13296 (clobber (reg:CCFP 18))
13297 (clobber (reg:CCFP 17))
13298 (clobber (match_scratch:HI 5 "=a"))]
13299 "reload_completed"
13300 [(set (pc)
13301 (if_then_else (match_dup 6)
13302 (match_dup 3)
13303 (match_dup 4)))]
13304 {
13305 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13306 operands[3], operands[4], operands[5]);
13307 DONE;
13308 })
13309 \f
13310 ;; Unconditional and other jump instructions
13311
13312 (define_insn "jump"
13313 [(set (pc)
13314 (label_ref (match_operand 0 "" "")))]
13315 ""
13316 "jmp\t%l0"
13317 [(set_attr "type" "ibr")
13318 (set (attr "length")
13319 (if_then_else (and (ge (minus (match_dup 0) (pc))
13320 (const_int -126))
13321 (lt (minus (match_dup 0) (pc))
13322 (const_int 128)))
13323 (const_int 2)
13324 (const_int 5)))
13325 (set_attr "modrm" "0")])
13326
13327 (define_expand "indirect_jump"
13328 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13329 ""
13330 "")
13331
13332 (define_insn "*indirect_jump"
13333 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13334 "!TARGET_64BIT"
13335 "jmp\t%A0"
13336 [(set_attr "type" "ibr")
13337 (set_attr "length_immediate" "0")])
13338
13339 (define_insn "*indirect_jump_rtx64"
13340 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13341 "TARGET_64BIT"
13342 "jmp\t%A0"
13343 [(set_attr "type" "ibr")
13344 (set_attr "length_immediate" "0")])
13345
13346 (define_expand "tablejump"
13347 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13348 (use (label_ref (match_operand 1 "" "")))])]
13349 ""
13350 {
13351 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13352 relative. Convert the relative address to an absolute address. */
13353 if (flag_pic)
13354 {
13355 rtx op0, op1;
13356 enum rtx_code code;
13357
13358 if (TARGET_64BIT)
13359 {
13360 code = PLUS;
13361 op0 = operands[0];
13362 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13363 }
13364 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13365 {
13366 code = PLUS;
13367 op0 = operands[0];
13368 op1 = pic_offset_table_rtx;
13369 }
13370 else
13371 {
13372 code = MINUS;
13373 op0 = pic_offset_table_rtx;
13374 op1 = operands[0];
13375 }
13376
13377 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13378 OPTAB_DIRECT);
13379 }
13380 })
13381
13382 (define_insn "*tablejump_1"
13383 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13384 (use (label_ref (match_operand 1 "" "")))]
13385 "!TARGET_64BIT"
13386 "jmp\t%A0"
13387 [(set_attr "type" "ibr")
13388 (set_attr "length_immediate" "0")])
13389
13390 (define_insn "*tablejump_1_rtx64"
13391 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13392 (use (label_ref (match_operand 1 "" "")))]
13393 "TARGET_64BIT"
13394 "jmp\t%A0"
13395 [(set_attr "type" "ibr")
13396 (set_attr "length_immediate" "0")])
13397 \f
13398 ;; Loop instruction
13399 ;;
13400 ;; This is all complicated by the fact that since this is a jump insn
13401 ;; we must handle our own reloads.
13402
13403 (define_expand "doloop_end"
13404 [(use (match_operand 0 "" "")) ; loop pseudo
13405 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13406 (use (match_operand 2 "" "")) ; max iterations
13407 (use (match_operand 3 "" "")) ; loop level
13408 (use (match_operand 4 "" ""))] ; label
13409 "!TARGET_64BIT && TARGET_USE_LOOP"
13410 "
13411 {
13412 /* Only use cloop on innermost loops. */
13413 if (INTVAL (operands[3]) > 1)
13414 FAIL;
13415 if (GET_MODE (operands[0]) != SImode)
13416 FAIL;
13417 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13418 operands[0]));
13419 DONE;
13420 }")
13421
13422 (define_insn "doloop_end_internal"
13423 [(set (pc)
13424 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13425 (const_int 1))
13426 (label_ref (match_operand 0 "" ""))
13427 (pc)))
13428 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13429 (plus:SI (match_dup 1)
13430 (const_int -1)))
13431 (clobber (match_scratch:SI 3 "=X,X,r"))
13432 (clobber (reg:CC 17))]
13433 "!TARGET_64BIT && TARGET_USE_LOOP
13434 && (reload_in_progress || reload_completed
13435 || register_operand (operands[2], VOIDmode))"
13436 {
13437 if (which_alternative != 0)
13438 return "#";
13439 if (get_attr_length (insn) == 2)
13440 return "%+loop\t%l0";
13441 else
13442 return "dec{l}\t%1\;%+jne\t%l0";
13443 }
13444 [(set (attr "length")
13445 (if_then_else (and (eq_attr "alternative" "0")
13446 (and (ge (minus (match_dup 0) (pc))
13447 (const_int -126))
13448 (lt (minus (match_dup 0) (pc))
13449 (const_int 128))))
13450 (const_int 2)
13451 (const_int 16)))
13452 ;; We don't know the type before shorten branches. Optimistically expect
13453 ;; the loop instruction to match.
13454 (set (attr "type") (const_string "ibr"))])
13455
13456 (define_split
13457 [(set (pc)
13458 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13459 (const_int 1))
13460 (match_operand 0 "" "")
13461 (pc)))
13462 (set (match_dup 1)
13463 (plus:SI (match_dup 1)
13464 (const_int -1)))
13465 (clobber (match_scratch:SI 2 ""))
13466 (clobber (reg:CC 17))]
13467 "!TARGET_64BIT && TARGET_USE_LOOP
13468 && reload_completed
13469 && REGNO (operands[1]) != 2"
13470 [(parallel [(set (reg:CCZ 17)
13471 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13472 (const_int 0)))
13473 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13474 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13475 (match_dup 0)
13476 (pc)))]
13477 "")
13478
13479 (define_split
13480 [(set (pc)
13481 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13482 (const_int 1))
13483 (match_operand 0 "" "")
13484 (pc)))
13485 (set (match_operand:SI 2 "nonimmediate_operand" "")
13486 (plus:SI (match_dup 1)
13487 (const_int -1)))
13488 (clobber (match_scratch:SI 3 ""))
13489 (clobber (reg:CC 17))]
13490 "!TARGET_64BIT && TARGET_USE_LOOP
13491 && reload_completed
13492 && (! REG_P (operands[2])
13493 || ! rtx_equal_p (operands[1], operands[2]))"
13494 [(set (match_dup 3) (match_dup 1))
13495 (parallel [(set (reg:CCZ 17)
13496 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13497 (const_int 0)))
13498 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13499 (set (match_dup 2) (match_dup 3))
13500 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13501 (match_dup 0)
13502 (pc)))]
13503 "")
13504
13505 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13506
13507 (define_peephole2
13508 [(set (reg 17) (match_operand 0 "" ""))
13509 (set (match_operand:QI 1 "register_operand" "")
13510 (match_operator:QI 2 "ix86_comparison_operator"
13511 [(reg 17) (const_int 0)]))
13512 (set (match_operand 3 "q_regs_operand" "")
13513 (zero_extend (match_dup 1)))]
13514 "(peep2_reg_dead_p (3, operands[1])
13515 || operands_match_p (operands[1], operands[3]))
13516 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13517 [(set (match_dup 4) (match_dup 0))
13518 (set (strict_low_part (match_dup 5))
13519 (match_dup 2))]
13520 {
13521 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13522 operands[5] = gen_lowpart (QImode, operands[3]);
13523 ix86_expand_clear (operands[3]);
13524 })
13525
13526 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13527
13528 (define_peephole2
13529 [(set (reg 17) (match_operand 0 "" ""))
13530 (set (match_operand:QI 1 "register_operand" "")
13531 (match_operator:QI 2 "ix86_comparison_operator"
13532 [(reg 17) (const_int 0)]))
13533 (parallel [(set (match_operand 3 "q_regs_operand" "")
13534 (zero_extend (match_dup 1)))
13535 (clobber (reg:CC 17))])]
13536 "(peep2_reg_dead_p (3, operands[1])
13537 || operands_match_p (operands[1], operands[3]))
13538 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13539 [(set (match_dup 4) (match_dup 0))
13540 (set (strict_low_part (match_dup 5))
13541 (match_dup 2))]
13542 {
13543 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13544 operands[5] = gen_lowpart (QImode, operands[3]);
13545 ix86_expand_clear (operands[3]);
13546 })
13547 \f
13548 ;; Call instructions.
13549
13550 ;; The predicates normally associated with named expanders are not properly
13551 ;; checked for calls. This is a bug in the generic code, but it isn't that
13552 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13553
13554 ;; Call subroutine returning no value.
13555
13556 (define_expand "call_pop"
13557 [(parallel [(call (match_operand:QI 0 "" "")
13558 (match_operand:SI 1 "" ""))
13559 (set (reg:SI 7)
13560 (plus:SI (reg:SI 7)
13561 (match_operand:SI 3 "" "")))])]
13562 "!TARGET_64BIT"
13563 {
13564 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13565 DONE;
13566 })
13567
13568 (define_insn "*call_pop_0"
13569 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13570 (match_operand:SI 1 "" ""))
13571 (set (reg:SI 7) (plus:SI (reg:SI 7)
13572 (match_operand:SI 2 "immediate_operand" "")))]
13573 "!TARGET_64BIT"
13574 {
13575 if (SIBLING_CALL_P (insn))
13576 return "jmp\t%P0";
13577 else
13578 return "call\t%P0";
13579 }
13580 [(set_attr "type" "call")])
13581
13582 (define_insn "*call_pop_1"
13583 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13584 (match_operand:SI 1 "" ""))
13585 (set (reg:SI 7) (plus:SI (reg:SI 7)
13586 (match_operand:SI 2 "immediate_operand" "i")))]
13587 "!TARGET_64BIT"
13588 {
13589 if (constant_call_address_operand (operands[0], Pmode))
13590 {
13591 if (SIBLING_CALL_P (insn))
13592 return "jmp\t%P0";
13593 else
13594 return "call\t%P0";
13595 }
13596 if (SIBLING_CALL_P (insn))
13597 return "jmp\t%A0";
13598 else
13599 return "call\t%A0";
13600 }
13601 [(set_attr "type" "call")])
13602
13603 (define_expand "call"
13604 [(call (match_operand:QI 0 "" "")
13605 (match_operand 1 "" ""))
13606 (use (match_operand 2 "" ""))]
13607 ""
13608 {
13609 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13610 DONE;
13611 })
13612
13613 (define_expand "sibcall"
13614 [(call (match_operand:QI 0 "" "")
13615 (match_operand 1 "" ""))
13616 (use (match_operand 2 "" ""))]
13617 ""
13618 {
13619 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13620 DONE;
13621 })
13622
13623 (define_insn "*call_0"
13624 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13625 (match_operand 1 "" ""))]
13626 ""
13627 {
13628 if (SIBLING_CALL_P (insn))
13629 return "jmp\t%P0";
13630 else
13631 return "call\t%P0";
13632 }
13633 [(set_attr "type" "call")])
13634
13635 (define_insn "*call_1"
13636 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13637 (match_operand 1 "" ""))]
13638 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13639 {
13640 if (constant_call_address_operand (operands[0], QImode))
13641 return "call\t%P0";
13642 return "call\t%A0";
13643 }
13644 [(set_attr "type" "call")])
13645
13646 (define_insn "*sibcall_1"
13647 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13648 (match_operand 1 "" ""))]
13649 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13650 {
13651 if (constant_call_address_operand (operands[0], QImode))
13652 return "jmp\t%P0";
13653 return "jmp\t%A0";
13654 }
13655 [(set_attr "type" "call")])
13656
13657 (define_insn "*call_1_rex64"
13658 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13659 (match_operand 1 "" ""))]
13660 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13661 {
13662 if (constant_call_address_operand (operands[0], QImode))
13663 return "call\t%P0";
13664 return "call\t%A0";
13665 }
13666 [(set_attr "type" "call")])
13667
13668 (define_insn "*sibcall_1_rex64"
13669 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13670 (match_operand 1 "" ""))]
13671 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13672 "jmp\t%P0"
13673 [(set_attr "type" "call")])
13674
13675 (define_insn "*sibcall_1_rex64_v"
13676 [(call (mem:QI (reg:DI 40))
13677 (match_operand 0 "" ""))]
13678 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13679 "jmp\t*%%r11"
13680 [(set_attr "type" "call")])
13681
13682
13683 ;; Call subroutine, returning value in operand 0
13684
13685 (define_expand "call_value_pop"
13686 [(parallel [(set (match_operand 0 "" "")
13687 (call (match_operand:QI 1 "" "")
13688 (match_operand:SI 2 "" "")))
13689 (set (reg:SI 7)
13690 (plus:SI (reg:SI 7)
13691 (match_operand:SI 4 "" "")))])]
13692 "!TARGET_64BIT"
13693 {
13694 ix86_expand_call (operands[0], operands[1], operands[2],
13695 operands[3], operands[4], 0);
13696 DONE;
13697 })
13698
13699 (define_expand "call_value"
13700 [(set (match_operand 0 "" "")
13701 (call (match_operand:QI 1 "" "")
13702 (match_operand:SI 2 "" "")))
13703 (use (match_operand:SI 3 "" ""))]
13704 ;; Operand 2 not used on the i386.
13705 ""
13706 {
13707 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13708 DONE;
13709 })
13710
13711 (define_expand "sibcall_value"
13712 [(set (match_operand 0 "" "")
13713 (call (match_operand:QI 1 "" "")
13714 (match_operand:SI 2 "" "")))
13715 (use (match_operand:SI 3 "" ""))]
13716 ;; Operand 2 not used on the i386.
13717 ""
13718 {
13719 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13720 DONE;
13721 })
13722
13723 ;; Call subroutine returning any type.
13724
13725 (define_expand "untyped_call"
13726 [(parallel [(call (match_operand 0 "" "")
13727 (const_int 0))
13728 (match_operand 1 "" "")
13729 (match_operand 2 "" "")])]
13730 ""
13731 {
13732 int i;
13733
13734 /* In order to give reg-stack an easier job in validating two
13735 coprocessor registers as containing a possible return value,
13736 simply pretend the untyped call returns a complex long double
13737 value. */
13738
13739 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13740 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13741 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13742 NULL, 0);
13743
13744 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13745 {
13746 rtx set = XVECEXP (operands[2], 0, i);
13747 emit_move_insn (SET_DEST (set), SET_SRC (set));
13748 }
13749
13750 /* The optimizer does not know that the call sets the function value
13751 registers we stored in the result block. We avoid problems by
13752 claiming that all hard registers are used and clobbered at this
13753 point. */
13754 emit_insn (gen_blockage (const0_rtx));
13755
13756 DONE;
13757 })
13758 \f
13759 ;; Prologue and epilogue instructions
13760
13761 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13762 ;; all of memory. This blocks insns from being moved across this point.
13763
13764 (define_insn "blockage"
13765 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13766 ""
13767 ""
13768 [(set_attr "length" "0")])
13769
13770 ;; Insn emitted into the body of a function to return from a function.
13771 ;; This is only done if the function's epilogue is known to be simple.
13772 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13773
13774 (define_expand "return"
13775 [(return)]
13776 "ix86_can_use_return_insn_p ()"
13777 {
13778 if (current_function_pops_args)
13779 {
13780 rtx popc = GEN_INT (current_function_pops_args);
13781 emit_jump_insn (gen_return_pop_internal (popc));
13782 DONE;
13783 }
13784 })
13785
13786 (define_insn "return_internal"
13787 [(return)]
13788 "reload_completed"
13789 "ret"
13790 [(set_attr "length" "1")
13791 (set_attr "length_immediate" "0")
13792 (set_attr "modrm" "0")])
13793
13794 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13795 ;; instruction Athlon and K8 have.
13796
13797 (define_insn "return_internal_long"
13798 [(return)
13799 (unspec [(const_int 0)] UNSPEC_REP)]
13800 "reload_completed"
13801 "rep {;} ret"
13802 [(set_attr "length" "1")
13803 (set_attr "length_immediate" "0")
13804 (set_attr "prefix_rep" "1")
13805 (set_attr "modrm" "0")])
13806
13807 (define_insn "return_pop_internal"
13808 [(return)
13809 (use (match_operand:SI 0 "const_int_operand" ""))]
13810 "reload_completed"
13811 "ret\t%0"
13812 [(set_attr "length" "3")
13813 (set_attr "length_immediate" "2")
13814 (set_attr "modrm" "0")])
13815
13816 (define_insn "return_indirect_internal"
13817 [(return)
13818 (use (match_operand:SI 0 "register_operand" "r"))]
13819 "reload_completed"
13820 "jmp\t%A0"
13821 [(set_attr "type" "ibr")
13822 (set_attr "length_immediate" "0")])
13823
13824 (define_insn "nop"
13825 [(const_int 0)]
13826 ""
13827 "nop"
13828 [(set_attr "length" "1")
13829 (set_attr "length_immediate" "0")
13830 (set_attr "modrm" "0")])
13831
13832 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13833 ;; branch prediction penalty for the third jump in a 16-byte
13834 ;; block on K8.
13835
13836 (define_insn "align"
13837 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13838 ""
13839 {
13840 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13841 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13842 #else
13843 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13844 The align insn is used to avoid 3 jump instructions in the row to improve
13845 branch prediction and the benefits hardly outweight the cost of extra 8
13846 nops on the average inserted by full alignment pseudo operation. */
13847 #endif
13848 return "";
13849 }
13850 [(set_attr "length" "16")])
13851
13852 (define_expand "prologue"
13853 [(const_int 1)]
13854 ""
13855 "ix86_expand_prologue (); DONE;")
13856
13857 (define_insn "set_got"
13858 [(set (match_operand:SI 0 "register_operand" "=r")
13859 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13860 (clobber (reg:CC 17))]
13861 "!TARGET_64BIT"
13862 { return output_set_got (operands[0]); }
13863 [(set_attr "type" "multi")
13864 (set_attr "length" "12")])
13865
13866 (define_expand "epilogue"
13867 [(const_int 1)]
13868 ""
13869 "ix86_expand_epilogue (1); DONE;")
13870
13871 (define_expand "sibcall_epilogue"
13872 [(const_int 1)]
13873 ""
13874 "ix86_expand_epilogue (0); DONE;")
13875
13876 (define_expand "eh_return"
13877 [(use (match_operand 0 "register_operand" ""))]
13878 ""
13879 {
13880 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13881
13882 /* Tricky bit: we write the address of the handler to which we will
13883 be returning into someone else's stack frame, one word below the
13884 stack address we wish to restore. */
13885 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13886 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13887 tmp = gen_rtx_MEM (Pmode, tmp);
13888 emit_move_insn (tmp, ra);
13889
13890 if (Pmode == SImode)
13891 emit_insn (gen_eh_return_si (sa));
13892 else
13893 emit_insn (gen_eh_return_di (sa));
13894 emit_barrier ();
13895 DONE;
13896 })
13897
13898 (define_insn_and_split "eh_return_si"
13899 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13900 UNSPECV_EH_RETURN)]
13901 "!TARGET_64BIT"
13902 "#"
13903 "reload_completed"
13904 [(const_int 1)]
13905 "ix86_expand_epilogue (2); DONE;")
13906
13907 (define_insn_and_split "eh_return_di"
13908 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13909 UNSPECV_EH_RETURN)]
13910 "TARGET_64BIT"
13911 "#"
13912 "reload_completed"
13913 [(const_int 1)]
13914 "ix86_expand_epilogue (2); DONE;")
13915
13916 (define_insn "leave"
13917 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13918 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13919 (clobber (mem:BLK (scratch)))]
13920 "!TARGET_64BIT"
13921 "leave"
13922 [(set_attr "type" "leave")])
13923
13924 (define_insn "leave_rex64"
13925 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13926 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13927 (clobber (mem:BLK (scratch)))]
13928 "TARGET_64BIT"
13929 "leave"
13930 [(set_attr "type" "leave")])
13931 \f
13932 (define_expand "ffssi2"
13933 [(parallel
13934 [(set (match_operand:SI 0 "register_operand" "")
13935 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13936 (clobber (match_scratch:SI 2 ""))
13937 (clobber (reg:CC 17))])]
13938 ""
13939 "")
13940
13941 (define_insn_and_split "*ffs_cmove"
13942 [(set (match_operand:SI 0 "register_operand" "=r")
13943 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13944 (clobber (match_scratch:SI 2 "=&r"))
13945 (clobber (reg:CC 17))]
13946 "TARGET_CMOVE"
13947 "#"
13948 "&& reload_completed"
13949 [(set (match_dup 2) (const_int -1))
13950 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13951 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13952 (set (match_dup 0) (if_then_else:SI
13953 (eq (reg:CCZ 17) (const_int 0))
13954 (match_dup 2)
13955 (match_dup 0)))
13956 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13957 (clobber (reg:CC 17))])]
13958 "")
13959
13960 (define_insn_and_split "*ffs_no_cmove"
13961 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13962 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13963 (clobber (match_scratch:SI 2 "=&q"))
13964 (clobber (reg:CC 17))]
13965 ""
13966 "#"
13967 "reload_completed"
13968 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13969 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13970 (set (strict_low_part (match_dup 3))
13971 (eq:QI (reg:CCZ 17) (const_int 0)))
13972 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13973 (clobber (reg:CC 17))])
13974 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13975 (clobber (reg:CC 17))])
13976 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13977 (clobber (reg:CC 17))])]
13978 {
13979 operands[3] = gen_lowpart (QImode, operands[2]);
13980 ix86_expand_clear (operands[2]);
13981 })
13982
13983 (define_insn "*ffssi_1"
13984 [(set (reg:CCZ 17)
13985 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13986 (const_int 0)))
13987 (set (match_operand:SI 0 "register_operand" "=r")
13988 (ctz:SI (match_dup 1)))]
13989 ""
13990 "bsf{l}\t{%1, %0|%0, %1}"
13991 [(set_attr "prefix_0f" "1")])
13992
13993 (define_insn "ctzsi2"
13994 [(set (match_operand:SI 0 "register_operand" "=r")
13995 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13996 (clobber (reg:CC 17))]
13997 ""
13998 "bsf{l}\t{%1, %0|%0, %1}"
13999 [(set_attr "prefix_0f" "1")])
14000
14001 (define_expand "clzsi2"
14002 [(parallel
14003 [(set (match_operand:SI 0 "register_operand" "")
14004 (minus:SI (const_int 31)
14005 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14006 (clobber (reg:CC 17))])
14007 (parallel
14008 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14009 (clobber (reg:CC 17))])]
14010 ""
14011 "")
14012
14013 (define_insn "*bsr"
14014 [(set (match_operand:SI 0 "register_operand" "=r")
14015 (minus:SI (const_int 31)
14016 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14017 (clobber (reg:CC 17))]
14018 ""
14019 "bsr{l}\t{%1, %0|%0, %1}"
14020 [(set_attr "prefix_0f" "1")])
14021 \f
14022 ;; Thread-local storage patterns for ELF.
14023 ;;
14024 ;; Note that these code sequences must appear exactly as shown
14025 ;; in order to allow linker relaxation.
14026
14027 (define_insn "*tls_global_dynamic_32_gnu"
14028 [(set (match_operand:SI 0 "register_operand" "=a")
14029 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14030 (match_operand:SI 2 "tls_symbolic_operand" "")
14031 (match_operand:SI 3 "call_insn_operand" "")]
14032 UNSPEC_TLS_GD))
14033 (clobber (match_scratch:SI 4 "=d"))
14034 (clobber (match_scratch:SI 5 "=c"))
14035 (clobber (reg:CC 17))]
14036 "!TARGET_64BIT && TARGET_GNU_TLS"
14037 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14038 [(set_attr "type" "multi")
14039 (set_attr "length" "12")])
14040
14041 (define_insn "*tls_global_dynamic_32_sun"
14042 [(set (match_operand:SI 0 "register_operand" "=a")
14043 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14044 (match_operand:SI 2 "tls_symbolic_operand" "")
14045 (match_operand:SI 3 "call_insn_operand" "")]
14046 UNSPEC_TLS_GD))
14047 (clobber (match_scratch:SI 4 "=d"))
14048 (clobber (match_scratch:SI 5 "=c"))
14049 (clobber (reg:CC 17))]
14050 "!TARGET_64BIT && TARGET_SUN_TLS"
14051 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14052 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14053 [(set_attr "type" "multi")
14054 (set_attr "length" "14")])
14055
14056 (define_expand "tls_global_dynamic_32"
14057 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14058 (unspec:SI
14059 [(match_dup 2)
14060 (match_operand:SI 1 "tls_symbolic_operand" "")
14061 (match_dup 3)]
14062 UNSPEC_TLS_GD))
14063 (clobber (match_scratch:SI 4 ""))
14064 (clobber (match_scratch:SI 5 ""))
14065 (clobber (reg:CC 17))])]
14066 ""
14067 {
14068 if (flag_pic)
14069 operands[2] = pic_offset_table_rtx;
14070 else
14071 {
14072 operands[2] = gen_reg_rtx (Pmode);
14073 emit_insn (gen_set_got (operands[2]));
14074 }
14075 operands[3] = ix86_tls_get_addr ();
14076 })
14077
14078 (define_insn "*tls_global_dynamic_64"
14079 [(set (match_operand:DI 0 "register_operand" "=a")
14080 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14081 (match_operand:DI 3 "" "")))
14082 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14083 UNSPEC_TLS_GD)]
14084 "TARGET_64BIT"
14085 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14086 [(set_attr "type" "multi")
14087 (set_attr "length" "16")])
14088
14089 (define_expand "tls_global_dynamic_64"
14090 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14091 (call (mem:QI (match_dup 2)) (const_int 0)))
14092 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14093 UNSPEC_TLS_GD)])]
14094 ""
14095 {
14096 operands[2] = ix86_tls_get_addr ();
14097 })
14098
14099 (define_insn "*tls_local_dynamic_base_32_gnu"
14100 [(set (match_operand:SI 0 "register_operand" "=a")
14101 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14102 (match_operand:SI 2 "call_insn_operand" "")]
14103 UNSPEC_TLS_LD_BASE))
14104 (clobber (match_scratch:SI 3 "=d"))
14105 (clobber (match_scratch:SI 4 "=c"))
14106 (clobber (reg:CC 17))]
14107 "!TARGET_64BIT && TARGET_GNU_TLS"
14108 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14109 [(set_attr "type" "multi")
14110 (set_attr "length" "11")])
14111
14112 (define_insn "*tls_local_dynamic_base_32_sun"
14113 [(set (match_operand:SI 0 "register_operand" "=a")
14114 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14115 (match_operand:SI 2 "call_insn_operand" "")]
14116 UNSPEC_TLS_LD_BASE))
14117 (clobber (match_scratch:SI 3 "=d"))
14118 (clobber (match_scratch:SI 4 "=c"))
14119 (clobber (reg:CC 17))]
14120 "!TARGET_64BIT && TARGET_SUN_TLS"
14121 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14122 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14123 [(set_attr "type" "multi")
14124 (set_attr "length" "13")])
14125
14126 (define_expand "tls_local_dynamic_base_32"
14127 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14128 (unspec:SI [(match_dup 1) (match_dup 2)]
14129 UNSPEC_TLS_LD_BASE))
14130 (clobber (match_scratch:SI 3 ""))
14131 (clobber (match_scratch:SI 4 ""))
14132 (clobber (reg:CC 17))])]
14133 ""
14134 {
14135 if (flag_pic)
14136 operands[1] = pic_offset_table_rtx;
14137 else
14138 {
14139 operands[1] = gen_reg_rtx (Pmode);
14140 emit_insn (gen_set_got (operands[1]));
14141 }
14142 operands[2] = ix86_tls_get_addr ();
14143 })
14144
14145 (define_insn "*tls_local_dynamic_base_64"
14146 [(set (match_operand:DI 0 "register_operand" "=a")
14147 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14148 (match_operand:DI 2 "" "")))
14149 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14150 "TARGET_64BIT"
14151 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14152 [(set_attr "type" "multi")
14153 (set_attr "length" "12")])
14154
14155 (define_expand "tls_local_dynamic_base_64"
14156 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14157 (call (mem:QI (match_dup 1)) (const_int 0)))
14158 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14159 ""
14160 {
14161 operands[1] = ix86_tls_get_addr ();
14162 })
14163
14164 ;; Local dynamic of a single variable is a lose. Show combine how
14165 ;; to convert that back to global dynamic.
14166
14167 (define_insn_and_split "*tls_local_dynamic_32_once"
14168 [(set (match_operand:SI 0 "register_operand" "=a")
14169 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14170 (match_operand:SI 2 "call_insn_operand" "")]
14171 UNSPEC_TLS_LD_BASE)
14172 (const:SI (unspec:SI
14173 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14174 UNSPEC_DTPOFF))))
14175 (clobber (match_scratch:SI 4 "=d"))
14176 (clobber (match_scratch:SI 5 "=c"))
14177 (clobber (reg:CC 17))]
14178 ""
14179 "#"
14180 ""
14181 [(parallel [(set (match_dup 0)
14182 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14183 UNSPEC_TLS_GD))
14184 (clobber (match_dup 4))
14185 (clobber (match_dup 5))
14186 (clobber (reg:CC 17))])]
14187 "")
14188
14189 ;; Load and add the thread base pointer from %gs:0.
14190
14191 (define_insn "*load_tp_si"
14192 [(set (match_operand:SI 0 "register_operand" "=r")
14193 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14194 "!TARGET_64BIT"
14195 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14196 [(set_attr "type" "imov")
14197 (set_attr "modrm" "0")
14198 (set_attr "length" "7")
14199 (set_attr "memory" "load")
14200 (set_attr "imm_disp" "false")])
14201
14202 (define_insn "*add_tp_si"
14203 [(set (match_operand:SI 0 "register_operand" "=r")
14204 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14205 (match_operand:SI 1 "register_operand" "0")))
14206 (clobber (reg:CC 17))]
14207 "!TARGET_64BIT"
14208 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14209 [(set_attr "type" "alu")
14210 (set_attr "modrm" "0")
14211 (set_attr "length" "7")
14212 (set_attr "memory" "load")
14213 (set_attr "imm_disp" "false")])
14214
14215 (define_insn "*load_tp_di"
14216 [(set (match_operand:DI 0 "register_operand" "=r")
14217 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14218 "TARGET_64BIT"
14219 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14220 [(set_attr "type" "imov")
14221 (set_attr "modrm" "0")
14222 (set_attr "length" "7")
14223 (set_attr "memory" "load")
14224 (set_attr "imm_disp" "false")])
14225
14226 (define_insn "*add_tp_di"
14227 [(set (match_operand:DI 0 "register_operand" "=r")
14228 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14229 (match_operand:DI 1 "register_operand" "0")))
14230 (clobber (reg:CC 17))]
14231 "TARGET_64BIT"
14232 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14233 [(set_attr "type" "alu")
14234 (set_attr "modrm" "0")
14235 (set_attr "length" "7")
14236 (set_attr "memory" "load")
14237 (set_attr "imm_disp" "false")])
14238 \f
14239 ;; These patterns match the binary 387 instructions for addM3, subM3,
14240 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14241 ;; SFmode. The first is the normal insn, the second the same insn but
14242 ;; with one operand a conversion, and the third the same insn but with
14243 ;; the other operand a conversion. The conversion may be SFmode or
14244 ;; SImode if the target mode DFmode, but only SImode if the target mode
14245 ;; is SFmode.
14246
14247 ;; Gcc is slightly more smart about handling normal two address instructions
14248 ;; so use special patterns for add and mull.
14249 (define_insn "*fop_sf_comm_nosse"
14250 [(set (match_operand:SF 0 "register_operand" "=f")
14251 (match_operator:SF 3 "binary_fp_operator"
14252 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14253 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14254 "TARGET_80387 && !TARGET_SSE_MATH
14255 && COMMUTATIVE_ARITH_P (operands[3])
14256 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14257 "* return output_387_binary_op (insn, operands);"
14258 [(set (attr "type")
14259 (if_then_else (match_operand:SF 3 "mult_operator" "")
14260 (const_string "fmul")
14261 (const_string "fop")))
14262 (set_attr "mode" "SF")])
14263
14264 (define_insn "*fop_sf_comm"
14265 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14266 (match_operator:SF 3 "binary_fp_operator"
14267 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14268 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14269 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14270 && COMMUTATIVE_ARITH_P (operands[3])
14271 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14272 "* return output_387_binary_op (insn, operands);"
14273 [(set (attr "type")
14274 (if_then_else (eq_attr "alternative" "1")
14275 (if_then_else (match_operand:SF 3 "mult_operator" "")
14276 (const_string "ssemul")
14277 (const_string "sseadd"))
14278 (if_then_else (match_operand:SF 3 "mult_operator" "")
14279 (const_string "fmul")
14280 (const_string "fop"))))
14281 (set_attr "mode" "SF")])
14282
14283 (define_insn "*fop_sf_comm_sse"
14284 [(set (match_operand:SF 0 "register_operand" "=x")
14285 (match_operator:SF 3 "binary_fp_operator"
14286 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14287 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14288 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14290 "* return output_387_binary_op (insn, operands);"
14291 [(set (attr "type")
14292 (if_then_else (match_operand:SF 3 "mult_operator" "")
14293 (const_string "ssemul")
14294 (const_string "sseadd")))
14295 (set_attr "mode" "SF")])
14296
14297 (define_insn "*fop_df_comm_nosse"
14298 [(set (match_operand:DF 0 "register_operand" "=f")
14299 (match_operator:DF 3 "binary_fp_operator"
14300 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14301 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14302 "TARGET_80387 && (!TARGET_SSE2 || !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" "DF")])
14311
14312 (define_insn "*fop_df_comm"
14313 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14314 (match_operator:DF 3 "binary_fp_operator"
14315 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14316 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14317 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && 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" "DF")])
14330
14331 (define_insn "*fop_df_comm_sse"
14332 [(set (match_operand:DF 0 "register_operand" "=Y")
14333 (match_operator:DF 3 "binary_fp_operator"
14334 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14335 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14336 "TARGET_SSE2 && TARGET_SSE_MATH
14337 && COMMUTATIVE_ARITH_P (operands[3])
14338 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14339 "* return output_387_binary_op (insn, operands);"
14340 [(set (attr "type")
14341 (if_then_else (match_operand:SF 3 "mult_operator" "")
14342 (const_string "ssemul")
14343 (const_string "sseadd")))
14344 (set_attr "mode" "DF")])
14345
14346 (define_insn "*fop_xf_comm"
14347 [(set (match_operand:XF 0 "register_operand" "=f")
14348 (match_operator:XF 3 "binary_fp_operator"
14349 [(match_operand:XF 1 "register_operand" "%0")
14350 (match_operand:XF 2 "register_operand" "f")]))]
14351 "TARGET_80387
14352 && COMMUTATIVE_ARITH_P (operands[3])"
14353 "* return output_387_binary_op (insn, operands);"
14354 [(set (attr "type")
14355 (if_then_else (match_operand:XF 3 "mult_operator" "")
14356 (const_string "fmul")
14357 (const_string "fop")))
14358 (set_attr "mode" "XF")])
14359
14360 (define_insn "*fop_sf_1_nosse"
14361 [(set (match_operand:SF 0 "register_operand" "=f,f")
14362 (match_operator:SF 3 "binary_fp_operator"
14363 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14364 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14365 "TARGET_80387 && !TARGET_SSE_MATH
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 (cond [(match_operand:SF 3 "mult_operator" "")
14371 (const_string "fmul")
14372 (match_operand:SF 3 "div_operator" "")
14373 (const_string "fdiv")
14374 ]
14375 (const_string "fop")))
14376 (set_attr "mode" "SF")])
14377
14378 (define_insn "*fop_sf_1"
14379 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14380 (match_operator:SF 3 "binary_fp_operator"
14381 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14382 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14383 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14384 && !COMMUTATIVE_ARITH_P (operands[3])
14385 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14386 "* return output_387_binary_op (insn, operands);"
14387 [(set (attr "type")
14388 (cond [(and (eq_attr "alternative" "2")
14389 (match_operand:SF 3 "mult_operator" ""))
14390 (const_string "ssemul")
14391 (and (eq_attr "alternative" "2")
14392 (match_operand:SF 3 "div_operator" ""))
14393 (const_string "ssediv")
14394 (eq_attr "alternative" "2")
14395 (const_string "sseadd")
14396 (match_operand:SF 3 "mult_operator" "")
14397 (const_string "fmul")
14398 (match_operand:SF 3 "div_operator" "")
14399 (const_string "fdiv")
14400 ]
14401 (const_string "fop")))
14402 (set_attr "mode" "SF")])
14403
14404 (define_insn "*fop_sf_1_sse"
14405 [(set (match_operand:SF 0 "register_operand" "=x")
14406 (match_operator:SF 3 "binary_fp_operator"
14407 [(match_operand:SF 1 "register_operand" "0")
14408 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14409 "TARGET_SSE_MATH
14410 && !COMMUTATIVE_ARITH_P (operands[3])"
14411 "* return output_387_binary_op (insn, operands);"
14412 [(set (attr "type")
14413 (cond [(match_operand:SF 3 "mult_operator" "")
14414 (const_string "ssemul")
14415 (match_operand:SF 3 "div_operator" "")
14416 (const_string "ssediv")
14417 ]
14418 (const_string "sseadd")))
14419 (set_attr "mode" "SF")])
14420
14421 ;; ??? Add SSE splitters for these!
14422 (define_insn "*fop_sf_2"
14423 [(set (match_operand:SF 0 "register_operand" "=f,f")
14424 (match_operator:SF 3 "binary_fp_operator"
14425 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14426 (match_operand:SF 2 "register_operand" "0,0")]))]
14427 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14428 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14429 [(set (attr "type")
14430 (cond [(match_operand:SF 3 "mult_operator" "")
14431 (const_string "fmul")
14432 (match_operand:SF 3 "div_operator" "")
14433 (const_string "fdiv")
14434 ]
14435 (const_string "fop")))
14436 (set_attr "fp_int_src" "true")
14437 (set_attr "mode" "SI")])
14438
14439 (define_insn "*fop_sf_3"
14440 [(set (match_operand:SF 0 "register_operand" "=f,f")
14441 (match_operator:SF 3 "binary_fp_operator"
14442 [(match_operand:SF 1 "register_operand" "0,0")
14443 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14444 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14445 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14446 [(set (attr "type")
14447 (cond [(match_operand:SF 3 "mult_operator" "")
14448 (const_string "fmul")
14449 (match_operand:SF 3 "div_operator" "")
14450 (const_string "fdiv")
14451 ]
14452 (const_string "fop")))
14453 (set_attr "fp_int_src" "true")
14454 (set_attr "mode" "SI")])
14455
14456 (define_insn "*fop_df_1_nosse"
14457 [(set (match_operand:DF 0 "register_operand" "=f,f")
14458 (match_operator:DF 3 "binary_fp_operator"
14459 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14460 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14461 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14462 && !COMMUTATIVE_ARITH_P (operands[3])
14463 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14464 "* return output_387_binary_op (insn, operands);"
14465 [(set (attr "type")
14466 (cond [(match_operand:DF 3 "mult_operator" "")
14467 (const_string "fmul")
14468 (match_operand:DF 3 "div_operator" "")
14469 (const_string "fdiv")
14470 ]
14471 (const_string "fop")))
14472 (set_attr "mode" "DF")])
14473
14474
14475 (define_insn "*fop_df_1"
14476 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14477 (match_operator:DF 3 "binary_fp_operator"
14478 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14479 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14480 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14481 && !COMMUTATIVE_ARITH_P (operands[3])
14482 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14483 "* return output_387_binary_op (insn, operands);"
14484 [(set (attr "type")
14485 (cond [(and (eq_attr "alternative" "2")
14486 (match_operand:SF 3 "mult_operator" ""))
14487 (const_string "ssemul")
14488 (and (eq_attr "alternative" "2")
14489 (match_operand:SF 3 "div_operator" ""))
14490 (const_string "ssediv")
14491 (eq_attr "alternative" "2")
14492 (const_string "sseadd")
14493 (match_operand:DF 3 "mult_operator" "")
14494 (const_string "fmul")
14495 (match_operand:DF 3 "div_operator" "")
14496 (const_string "fdiv")
14497 ]
14498 (const_string "fop")))
14499 (set_attr "mode" "DF")])
14500
14501 (define_insn "*fop_df_1_sse"
14502 [(set (match_operand:DF 0 "register_operand" "=Y")
14503 (match_operator:DF 3 "binary_fp_operator"
14504 [(match_operand:DF 1 "register_operand" "0")
14505 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14506 "TARGET_SSE2 && TARGET_SSE_MATH
14507 && !COMMUTATIVE_ARITH_P (operands[3])"
14508 "* return output_387_binary_op (insn, operands);"
14509 [(set_attr "mode" "DF")
14510 (set (attr "type")
14511 (cond [(match_operand:SF 3 "mult_operator" "")
14512 (const_string "ssemul")
14513 (match_operand:SF 3 "div_operator" "")
14514 (const_string "ssediv")
14515 ]
14516 (const_string "sseadd")))])
14517
14518 ;; ??? Add SSE splitters for these!
14519 (define_insn "*fop_df_2"
14520 [(set (match_operand:DF 0 "register_operand" "=f,f")
14521 (match_operator:DF 3 "binary_fp_operator"
14522 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14523 (match_operand:DF 2 "register_operand" "0,0")]))]
14524 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14525 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14526 [(set (attr "type")
14527 (cond [(match_operand:DF 3 "mult_operator" "")
14528 (const_string "fmul")
14529 (match_operand:DF 3 "div_operator" "")
14530 (const_string "fdiv")
14531 ]
14532 (const_string "fop")))
14533 (set_attr "fp_int_src" "true")
14534 (set_attr "mode" "SI")])
14535
14536 (define_insn "*fop_df_3"
14537 [(set (match_operand:DF 0 "register_operand" "=f,f")
14538 (match_operator:DF 3 "binary_fp_operator"
14539 [(match_operand:DF 1 "register_operand" "0,0")
14540 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14541 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14542 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14543 [(set (attr "type")
14544 (cond [(match_operand:DF 3 "mult_operator" "")
14545 (const_string "fmul")
14546 (match_operand:DF 3 "div_operator" "")
14547 (const_string "fdiv")
14548 ]
14549 (const_string "fop")))
14550 (set_attr "fp_int_src" "true")
14551 (set_attr "mode" "SI")])
14552
14553 (define_insn "*fop_df_4"
14554 [(set (match_operand:DF 0 "register_operand" "=f,f")
14555 (match_operator:DF 3 "binary_fp_operator"
14556 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14557 (match_operand:DF 2 "register_operand" "0,f")]))]
14558 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14559 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14560 "* return output_387_binary_op (insn, operands);"
14561 [(set (attr "type")
14562 (cond [(match_operand:DF 3 "mult_operator" "")
14563 (const_string "fmul")
14564 (match_operand:DF 3 "div_operator" "")
14565 (const_string "fdiv")
14566 ]
14567 (const_string "fop")))
14568 (set_attr "mode" "SF")])
14569
14570 (define_insn "*fop_df_5"
14571 [(set (match_operand:DF 0 "register_operand" "=f,f")
14572 (match_operator:DF 3 "binary_fp_operator"
14573 [(match_operand:DF 1 "register_operand" "0,f")
14574 (float_extend:DF
14575 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14576 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14577 "* return output_387_binary_op (insn, operands);"
14578 [(set (attr "type")
14579 (cond [(match_operand:DF 3 "mult_operator" "")
14580 (const_string "fmul")
14581 (match_operand:DF 3 "div_operator" "")
14582 (const_string "fdiv")
14583 ]
14584 (const_string "fop")))
14585 (set_attr "mode" "SF")])
14586
14587 (define_insn "*fop_df_6"
14588 [(set (match_operand:DF 0 "register_operand" "=f,f")
14589 (match_operator:DF 3 "binary_fp_operator"
14590 [(float_extend:DF
14591 (match_operand:SF 1 "register_operand" "0,f"))
14592 (float_extend:DF
14593 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14594 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14595 "* return output_387_binary_op (insn, operands);"
14596 [(set (attr "type")
14597 (cond [(match_operand:DF 3 "mult_operator" "")
14598 (const_string "fmul")
14599 (match_operand:DF 3 "div_operator" "")
14600 (const_string "fdiv")
14601 ]
14602 (const_string "fop")))
14603 (set_attr "mode" "SF")])
14604
14605 (define_insn "*fop_xf_1"
14606 [(set (match_operand:XF 0 "register_operand" "=f,f")
14607 (match_operator:XF 3 "binary_fp_operator"
14608 [(match_operand:XF 1 "register_operand" "0,f")
14609 (match_operand:XF 2 "register_operand" "f,0")]))]
14610 "TARGET_80387
14611 && !COMMUTATIVE_ARITH_P (operands[3])"
14612 "* return output_387_binary_op (insn, operands);"
14613 [(set (attr "type")
14614 (cond [(match_operand:XF 3 "mult_operator" "")
14615 (const_string "fmul")
14616 (match_operand:XF 3 "div_operator" "")
14617 (const_string "fdiv")
14618 ]
14619 (const_string "fop")))
14620 (set_attr "mode" "XF")])
14621
14622 (define_insn "*fop_xf_2"
14623 [(set (match_operand:XF 0 "register_operand" "=f,f")
14624 (match_operator:XF 3 "binary_fp_operator"
14625 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14626 (match_operand:XF 2 "register_operand" "0,0")]))]
14627 "TARGET_80387 && TARGET_USE_FIOP"
14628 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14629 [(set (attr "type")
14630 (cond [(match_operand:XF 3 "mult_operator" "")
14631 (const_string "fmul")
14632 (match_operand:XF 3 "div_operator" "")
14633 (const_string "fdiv")
14634 ]
14635 (const_string "fop")))
14636 (set_attr "fp_int_src" "true")
14637 (set_attr "mode" "SI")])
14638
14639 (define_insn "*fop_xf_3"
14640 [(set (match_operand:XF 0 "register_operand" "=f,f")
14641 (match_operator:XF 3 "binary_fp_operator"
14642 [(match_operand:XF 1 "register_operand" "0,0")
14643 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14644 "TARGET_80387 && TARGET_USE_FIOP"
14645 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14646 [(set (attr "type")
14647 (cond [(match_operand:XF 3 "mult_operator" "")
14648 (const_string "fmul")
14649 (match_operand:XF 3 "div_operator" "")
14650 (const_string "fdiv")
14651 ]
14652 (const_string "fop")))
14653 (set_attr "fp_int_src" "true")
14654 (set_attr "mode" "SI")])
14655
14656 (define_insn "*fop_xf_4"
14657 [(set (match_operand:XF 0 "register_operand" "=f,f")
14658 (match_operator:XF 3 "binary_fp_operator"
14659 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14660 (match_operand:XF 2 "register_operand" "0,f")]))]
14661 "TARGET_80387"
14662 "* return output_387_binary_op (insn, operands);"
14663 [(set (attr "type")
14664 (cond [(match_operand:XF 3 "mult_operator" "")
14665 (const_string "fmul")
14666 (match_operand:XF 3 "div_operator" "")
14667 (const_string "fdiv")
14668 ]
14669 (const_string "fop")))
14670 (set_attr "mode" "SF")])
14671
14672 (define_insn "*fop_xf_5"
14673 [(set (match_operand:XF 0 "register_operand" "=f,f")
14674 (match_operator:XF 3 "binary_fp_operator"
14675 [(match_operand:XF 1 "register_operand" "0,f")
14676 (float_extend:XF
14677 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14678 "TARGET_80387"
14679 "* return output_387_binary_op (insn, operands);"
14680 [(set (attr "type")
14681 (cond [(match_operand:XF 3 "mult_operator" "")
14682 (const_string "fmul")
14683 (match_operand:XF 3 "div_operator" "")
14684 (const_string "fdiv")
14685 ]
14686 (const_string "fop")))
14687 (set_attr "mode" "SF")])
14688
14689 (define_insn "*fop_xf_6"
14690 [(set (match_operand:XF 0 "register_operand" "=f,f")
14691 (match_operator:XF 3 "binary_fp_operator"
14692 [(float_extend:XF
14693 (match_operand 1 "register_operand" "0,f"))
14694 (float_extend:XF
14695 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14696 "TARGET_80387"
14697 "* return output_387_binary_op (insn, operands);"
14698 [(set (attr "type")
14699 (cond [(match_operand:XF 3 "mult_operator" "")
14700 (const_string "fmul")
14701 (match_operand:XF 3 "div_operator" "")
14702 (const_string "fdiv")
14703 ]
14704 (const_string "fop")))
14705 (set_attr "mode" "SF")])
14706
14707 (define_split
14708 [(set (match_operand 0 "register_operand" "")
14709 (match_operator 3 "binary_fp_operator"
14710 [(float (match_operand:SI 1 "register_operand" ""))
14711 (match_operand 2 "register_operand" "")]))]
14712 "TARGET_80387 && reload_completed
14713 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14714 [(const_int 0)]
14715 {
14716 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14717 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14718 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14719 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14720 GET_MODE (operands[3]),
14721 operands[4],
14722 operands[2])));
14723 ix86_free_from_memory (GET_MODE (operands[1]));
14724 DONE;
14725 })
14726
14727 (define_split
14728 [(set (match_operand 0 "register_operand" "")
14729 (match_operator 3 "binary_fp_operator"
14730 [(match_operand 1 "register_operand" "")
14731 (float (match_operand:SI 2 "register_operand" ""))]))]
14732 "TARGET_80387 && reload_completed
14733 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14734 [(const_int 0)]
14735 {
14736 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14737 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14738 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14739 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14740 GET_MODE (operands[3]),
14741 operands[1],
14742 operands[4])));
14743 ix86_free_from_memory (GET_MODE (operands[2]));
14744 DONE;
14745 })
14746 \f
14747 ;; FPU special functions.
14748
14749 (define_expand "sqrtsf2"
14750 [(set (match_operand:SF 0 "register_operand" "")
14751 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14752 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14753 {
14754 if (!TARGET_SSE_MATH)
14755 operands[1] = force_reg (SFmode, operands[1]);
14756 })
14757
14758 (define_insn "sqrtsf2_1"
14759 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14760 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14761 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14762 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14763 "@
14764 fsqrt
14765 sqrtss\t{%1, %0|%0, %1}"
14766 [(set_attr "type" "fpspc,sse")
14767 (set_attr "mode" "SF,SF")
14768 (set_attr "athlon_decode" "direct,*")])
14769
14770 (define_insn "sqrtsf2_1_sse_only"
14771 [(set (match_operand:SF 0 "register_operand" "=x")
14772 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14773 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14774 "sqrtss\t{%1, %0|%0, %1}"
14775 [(set_attr "type" "sse")
14776 (set_attr "mode" "SF")
14777 (set_attr "athlon_decode" "*")])
14778
14779 (define_insn "sqrtsf2_i387"
14780 [(set (match_operand:SF 0 "register_operand" "=f")
14781 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14782 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14783 && !TARGET_SSE_MATH"
14784 "fsqrt"
14785 [(set_attr "type" "fpspc")
14786 (set_attr "mode" "SF")
14787 (set_attr "athlon_decode" "direct")])
14788
14789 (define_expand "sqrtdf2"
14790 [(set (match_operand:DF 0 "register_operand" "")
14791 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14792 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14793 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14794 {
14795 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14796 operands[1] = force_reg (DFmode, operands[1]);
14797 })
14798
14799 (define_insn "sqrtdf2_1"
14800 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14801 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14802 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14803 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14804 "@
14805 fsqrt
14806 sqrtsd\t{%1, %0|%0, %1}"
14807 [(set_attr "type" "fpspc,sse")
14808 (set_attr "mode" "DF,DF")
14809 (set_attr "athlon_decode" "direct,*")])
14810
14811 (define_insn "sqrtdf2_1_sse_only"
14812 [(set (match_operand:DF 0 "register_operand" "=Y")
14813 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14814 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14815 "sqrtsd\t{%1, %0|%0, %1}"
14816 [(set_attr "type" "sse")
14817 (set_attr "mode" "DF")
14818 (set_attr "athlon_decode" "*")])
14819
14820 (define_insn "sqrtdf2_i387"
14821 [(set (match_operand:DF 0 "register_operand" "=f")
14822 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14823 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14824 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14825 "fsqrt"
14826 [(set_attr "type" "fpspc")
14827 (set_attr "mode" "DF")
14828 (set_attr "athlon_decode" "direct")])
14829
14830 (define_insn "*sqrtextendsfdf2"
14831 [(set (match_operand:DF 0 "register_operand" "=f")
14832 (sqrt:DF (float_extend:DF
14833 (match_operand:SF 1 "register_operand" "0"))))]
14834 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14835 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14836 "fsqrt"
14837 [(set_attr "type" "fpspc")
14838 (set_attr "mode" "DF")
14839 (set_attr "athlon_decode" "direct")])
14840
14841 (define_insn "sqrtxf2"
14842 [(set (match_operand:XF 0 "register_operand" "=f")
14843 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14844 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14845 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14846 "fsqrt"
14847 [(set_attr "type" "fpspc")
14848 (set_attr "mode" "XF")
14849 (set_attr "athlon_decode" "direct")])
14850
14851 (define_insn "*sqrtextenddfxf2"
14852 [(set (match_operand:XF 0 "register_operand" "=f")
14853 (sqrt:XF (float_extend:XF
14854 (match_operand:DF 1 "register_operand" "0"))))]
14855 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14856 "fsqrt"
14857 [(set_attr "type" "fpspc")
14858 (set_attr "mode" "XF")
14859 (set_attr "athlon_decode" "direct")])
14860
14861 (define_insn "*sqrtextendsfxf2"
14862 [(set (match_operand:XF 0 "register_operand" "=f")
14863 (sqrt:XF (float_extend:XF
14864 (match_operand:SF 1 "register_operand" "0"))))]
14865 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14866 "fsqrt"
14867 [(set_attr "type" "fpspc")
14868 (set_attr "mode" "XF")
14869 (set_attr "athlon_decode" "direct")])
14870
14871 (define_insn "sindf2"
14872 [(set (match_operand:DF 0 "register_operand" "=f")
14873 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14874 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14875 && flag_unsafe_math_optimizations"
14876 "fsin"
14877 [(set_attr "type" "fpspc")
14878 (set_attr "mode" "DF")])
14879
14880 (define_insn "sinsf2"
14881 [(set (match_operand:SF 0 "register_operand" "=f")
14882 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14883 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14884 && flag_unsafe_math_optimizations"
14885 "fsin"
14886 [(set_attr "type" "fpspc")
14887 (set_attr "mode" "SF")])
14888
14889 (define_insn "*sinextendsfdf2"
14890 [(set (match_operand:DF 0 "register_operand" "=f")
14891 (unspec:DF [(float_extend:DF
14892 (match_operand:SF 1 "register_operand" "0"))]
14893 UNSPEC_SIN))]
14894 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14895 && flag_unsafe_math_optimizations"
14896 "fsin"
14897 [(set_attr "type" "fpspc")
14898 (set_attr "mode" "DF")])
14899
14900 (define_insn "sinxf2"
14901 [(set (match_operand:XF 0 "register_operand" "=f")
14902 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14903 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14904 && flag_unsafe_math_optimizations"
14905 "fsin"
14906 [(set_attr "type" "fpspc")
14907 (set_attr "mode" "XF")])
14908
14909 (define_insn "cosdf2"
14910 [(set (match_operand:DF 0 "register_operand" "=f")
14911 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14912 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14913 && flag_unsafe_math_optimizations"
14914 "fcos"
14915 [(set_attr "type" "fpspc")
14916 (set_attr "mode" "DF")])
14917
14918 (define_insn "cossf2"
14919 [(set (match_operand:SF 0 "register_operand" "=f")
14920 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14921 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14922 && flag_unsafe_math_optimizations"
14923 "fcos"
14924 [(set_attr "type" "fpspc")
14925 (set_attr "mode" "SF")])
14926
14927 (define_insn "*cosextendsfdf2"
14928 [(set (match_operand:DF 0 "register_operand" "=f")
14929 (unspec:DF [(float_extend:DF
14930 (match_operand:SF 1 "register_operand" "0"))]
14931 UNSPEC_COS))]
14932 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14933 && flag_unsafe_math_optimizations"
14934 "fcos"
14935 [(set_attr "type" "fpspc")
14936 (set_attr "mode" "DF")])
14937
14938 (define_insn "cosxf2"
14939 [(set (match_operand:XF 0 "register_operand" "=f")
14940 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14941 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14942 && flag_unsafe_math_optimizations"
14943 "fcos"
14944 [(set_attr "type" "fpspc")
14945 (set_attr "mode" "XF")])
14946
14947 (define_insn "atan2df3_1"
14948 [(set (match_operand:DF 0 "register_operand" "=f")
14949 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
14950 (match_operand:DF 1 "register_operand" "u")]
14951 UNSPEC_FPATAN))
14952 (clobber (match_scratch:DF 3 "=1"))]
14953 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14954 && flag_unsafe_math_optimizations"
14955 "fpatan"
14956 [(set_attr "type" "fpspc")
14957 (set_attr "mode" "DF")])
14958
14959 (define_expand "atan2df3"
14960 [(use (match_operand:DF 0 "register_operand" "=f"))
14961 (use (match_operand:DF 2 "register_operand" "0"))
14962 (use (match_operand:DF 1 "register_operand" "u"))]
14963 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14964 && flag_unsafe_math_optimizations"
14965 {
14966 rtx copy = gen_reg_rtx (DFmode);
14967 emit_move_insn (copy, operands[1]);
14968 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
14969 DONE;
14970 })
14971
14972 (define_insn "atan2sf3_1"
14973 [(set (match_operand:SF 0 "register_operand" "=f")
14974 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
14975 (match_operand:SF 1 "register_operand" "u")]
14976 UNSPEC_FPATAN))
14977 (clobber (match_scratch:SF 3 "=1"))]
14978 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14979 && flag_unsafe_math_optimizations"
14980 "fpatan"
14981 [(set_attr "type" "fpspc")
14982 (set_attr "mode" "SF")])
14983
14984 (define_expand "atan2sf3"
14985 [(use (match_operand:SF 0 "register_operand" "=f"))
14986 (use (match_operand:SF 2 "register_operand" "0"))
14987 (use (match_operand:SF 1 "register_operand" "u"))]
14988 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14989 && flag_unsafe_math_optimizations"
14990 {
14991 rtx copy = gen_reg_rtx (SFmode);
14992 emit_move_insn (copy, operands[1]);
14993 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
14994 DONE;
14995 })
14996
14997 (define_insn "atan2xf3_1"
14998 [(set (match_operand:XF 0 "register_operand" "=f")
14999 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15000 (match_operand:XF 1 "register_operand" "u")]
15001 UNSPEC_FPATAN))
15002 (clobber (match_scratch:XF 3 "=1"))]
15003 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15004 && flag_unsafe_math_optimizations"
15005 "fpatan"
15006 [(set_attr "type" "fpspc")
15007 (set_attr "mode" "XF")])
15008
15009 (define_expand "atan2xf3"
15010 [(use (match_operand:XF 0 "register_operand" "=f"))
15011 (use (match_operand:XF 2 "register_operand" "0"))
15012 (use (match_operand:XF 1 "register_operand" "u"))]
15013 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15014 && flag_unsafe_math_optimizations"
15015 {
15016 rtx copy = gen_reg_rtx (XFmode);
15017 emit_move_insn (copy, operands[1]);
15018 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15019 DONE;
15020 })
15021
15022 (define_insn "*fyl2x_sfxf3"
15023 [(set (match_operand:SF 0 "register_operand" "=f")
15024 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15025 (match_operand:XF 1 "register_operand" "u")]
15026 UNSPEC_FYL2X))
15027 (clobber (match_scratch:SF 3 "=1"))]
15028 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15029 && flag_unsafe_math_optimizations"
15030 "fyl2x"
15031 [(set_attr "type" "fpspc")
15032 (set_attr "mode" "SF")])
15033
15034 (define_insn "*fyl2x_dfxf3"
15035 [(set (match_operand:DF 0 "register_operand" "=f")
15036 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15037 (match_operand:XF 1 "register_operand" "u")]
15038 UNSPEC_FYL2X))
15039 (clobber (match_scratch:DF 3 "=1"))]
15040 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15041 && flag_unsafe_math_optimizations"
15042 "fyl2x"
15043 [(set_attr "type" "fpspc")
15044 (set_attr "mode" "DF")])
15045
15046 (define_insn "*fyl2x_xf3"
15047 [(set (match_operand:XF 0 "register_operand" "=f")
15048 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15049 (match_operand:XF 1 "register_operand" "u")]
15050 UNSPEC_FYL2X))
15051 (clobber (match_scratch:XF 3 "=1"))]
15052 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15053 && flag_unsafe_math_optimizations"
15054 "fyl2x"
15055 [(set_attr "type" "fpspc")
15056 (set_attr "mode" "XF")])
15057
15058 (define_expand "logsf2"
15059 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15060 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15061 (match_dup 2)] UNSPEC_FYL2X))
15062 (clobber (match_scratch:SF 3 ""))])]
15063 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15064 && flag_unsafe_math_optimizations"
15065 {
15066 rtx temp;
15067
15068 operands[2] = gen_reg_rtx (XFmode);
15069 temp = standard_80387_constant_rtx (4); /* fldln2 */
15070 emit_move_insn (operands[2], temp);
15071 })
15072
15073 (define_expand "logdf2"
15074 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15075 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15076 (match_dup 2)] UNSPEC_FYL2X))
15077 (clobber (match_scratch:DF 3 ""))])]
15078 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15079 && flag_unsafe_math_optimizations"
15080 {
15081 rtx temp;
15082
15083 operands[2] = gen_reg_rtx (XFmode);
15084 temp = standard_80387_constant_rtx (4); /* fldln2 */
15085 emit_move_insn (operands[2], temp);
15086 })
15087
15088 (define_expand "logxf2"
15089 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15090 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15091 (match_dup 2)] UNSPEC_FYL2X))
15092 (clobber (match_scratch:XF 3 ""))])]
15093 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15094 && flag_unsafe_math_optimizations"
15095 {
15096 rtx temp;
15097
15098 operands[2] = gen_reg_rtx (XFmode);
15099 temp = standard_80387_constant_rtx (4); /* fldln2 */
15100 emit_move_insn (operands[2], temp);
15101 })
15102
15103 (define_expand "log10sf2"
15104 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15105 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15106 (match_dup 2)] UNSPEC_FYL2X))
15107 (clobber (match_scratch:SF 3 ""))])]
15108 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15109 && flag_unsafe_math_optimizations"
15110 {
15111 rtx temp;
15112
15113 operands[2] = gen_reg_rtx (XFmode);
15114 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15115 emit_move_insn (operands[2], temp);
15116 })
15117
15118 (define_expand "log10df2"
15119 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15120 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15121 (match_dup 2)] UNSPEC_FYL2X))
15122 (clobber (match_scratch:DF 3 ""))])]
15123 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15124 && flag_unsafe_math_optimizations"
15125 {
15126 rtx temp;
15127
15128 operands[2] = gen_reg_rtx (XFmode);
15129 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15130 emit_move_insn (operands[2], temp);
15131 })
15132
15133 (define_expand "log10xf2"
15134 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15135 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15136 (match_dup 2)] UNSPEC_FYL2X))
15137 (clobber (match_scratch:XF 3 ""))])]
15138 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15139 && flag_unsafe_math_optimizations"
15140 {
15141 rtx temp;
15142
15143 operands[2] = gen_reg_rtx (XFmode);
15144 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15145 emit_move_insn (operands[2], temp);
15146 })
15147
15148 (define_expand "log2sf2"
15149 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15150 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15151 (match_dup 2)] UNSPEC_FYL2X))
15152 (clobber (match_scratch:SF 3 ""))])]
15153 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15154 && flag_unsafe_math_optimizations"
15155 {
15156 operands[2] = gen_reg_rtx (XFmode);
15157 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15158
15159 })
15160
15161 (define_expand "log2df2"
15162 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15163 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15164 (match_dup 2)] UNSPEC_FYL2X))
15165 (clobber (match_scratch:DF 3 ""))])]
15166 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15167 && flag_unsafe_math_optimizations"
15168 {
15169 operands[2] = gen_reg_rtx (XFmode);
15170 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15171 })
15172
15173 (define_expand "log2xf2"
15174 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15175 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15176 (match_dup 2)] UNSPEC_FYL2X))
15177 (clobber (match_scratch:XF 3 ""))])]
15178 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15179 && flag_unsafe_math_optimizations"
15180 {
15181 operands[2] = gen_reg_rtx (XFmode);
15182 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15183 })
15184
15185 (define_insn "*fscale_sfxf3"
15186 [(set (match_operand:SF 0 "register_operand" "=f")
15187 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15188 (match_operand:XF 1 "register_operand" "u")]
15189 UNSPEC_FSCALE))
15190 (clobber (match_scratch:SF 3 "=1"))]
15191 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15192 && flag_unsafe_math_optimizations"
15193 "fscale\;fstp\t%y1"
15194 [(set_attr "type" "fpspc")
15195 (set_attr "mode" "SF")])
15196
15197 (define_insn "*fscale_dfxf3"
15198 [(set (match_operand:DF 0 "register_operand" "=f")
15199 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15200 (match_operand:XF 1 "register_operand" "u")]
15201 UNSPEC_FSCALE))
15202 (clobber (match_scratch:DF 3 "=1"))]
15203 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15204 && flag_unsafe_math_optimizations"
15205 "fscale\;fstp\t%y1"
15206 [(set_attr "type" "fpspc")
15207 (set_attr "mode" "DF")])
15208
15209 (define_insn "*fscale_xf3"
15210 [(set (match_operand:XF 0 "register_operand" "=f")
15211 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15212 (match_operand:XF 1 "register_operand" "u")]
15213 UNSPEC_FSCALE))
15214 (clobber (match_scratch:XF 3 "=1"))]
15215 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15216 && flag_unsafe_math_optimizations"
15217 "fscale\;fstp\t%y1"
15218 [(set_attr "type" "fpspc")
15219 (set_attr "mode" "XF")])
15220
15221 (define_insn "*frndintxf2"
15222 [(set (match_operand:XF 0 "register_operand" "=f")
15223 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15224 UNSPEC_FRNDINT))]
15225 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15226 && flag_unsafe_math_optimizations"
15227 "frndint"
15228 [(set_attr "type" "fpspc")
15229 (set_attr "mode" "XF")])
15230
15231 (define_insn "*f2xm1xf2"
15232 [(set (match_operand:XF 0 "register_operand" "=f")
15233 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15234 UNSPEC_F2XM1))]
15235 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15236 && flag_unsafe_math_optimizations"
15237 "f2xm1"
15238 [(set_attr "type" "fpspc")
15239 (set_attr "mode" "XF")])
15240
15241 (define_expand "expsf2"
15242 [(set (match_dup 2)
15243 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15244 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15245 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15246 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15247 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15248 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15249 (parallel [(set (match_operand:SF 0 "register_operand" "")
15250 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15251 (clobber (match_scratch:SF 5 ""))])]
15252 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15253 && flag_unsafe_math_optimizations"
15254 {
15255 rtx temp;
15256 int i;
15257
15258 for (i=2; i<10; i++)
15259 operands[i] = gen_reg_rtx (XFmode);
15260 temp = standard_80387_constant_rtx (5); /* fldl2e */
15261 emit_move_insn (operands[3], temp);
15262 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15263 })
15264
15265 (define_expand "expdf2"
15266 [(set (match_dup 2)
15267 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15268 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15269 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15270 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15271
15272 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15273 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15274 (parallel [(set (match_operand:DF 0 "register_operand" "")
15275 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15276 (clobber (match_scratch:DF 5 ""))])]
15277 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15278 && flag_unsafe_math_optimizations"
15279 {
15280 rtx temp;
15281 int i;
15282
15283 for (i=2; i<10; i++)
15284 operands[i] = gen_reg_rtx (XFmode);
15285 temp = standard_80387_constant_rtx (5); /* fldl2e */
15286 emit_move_insn (operands[3], temp);
15287 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15288 })
15289
15290 (define_expand "expxf2"
15291 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15292 (match_dup 2)))
15293 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15294 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15295 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15296 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15297 (parallel [(set (match_operand:XF 0 "register_operand" "")
15298 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15299 (clobber (match_scratch:XF 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<9; i++)
15307 operands[i] = gen_reg_rtx (XFmode);
15308 temp = standard_80387_constant_rtx (5); /* fldl2e */
15309 emit_move_insn (operands[2], temp);
15310 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15311 })
15312
15313 (define_expand "exp10sf2"
15314 [(set (match_dup 2)
15315 (float_extend:XF (match_operand:SF 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 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15320 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15321 (parallel [(set (match_operand:SF 0 "register_operand" "")
15322 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15323 (clobber (match_scratch:SF 5 ""))])]
15324 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15325 && flag_unsafe_math_optimizations"
15326 {
15327 rtx temp;
15328 int i;
15329
15330 for (i=2; i<10; i++)
15331 operands[i] = gen_reg_rtx (XFmode);
15332 temp = standard_80387_constant_rtx (6); /* fldl2t */
15333 emit_move_insn (operands[3], temp);
15334 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15335 })
15336
15337 (define_expand "exp10df2"
15338 [(set (match_dup 2)
15339 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15340 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15341 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15342 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15343 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15344 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15345 (parallel [(set (match_operand:DF 0 "register_operand" "")
15346 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15347 (clobber (match_scratch:DF 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<10; i++)
15355 operands[i] = gen_reg_rtx (XFmode);
15356 temp = standard_80387_constant_rtx (6); /* fldl2t */
15357 emit_move_insn (operands[3], temp);
15358 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15359 })
15360
15361 (define_expand "exp10xf2"
15362 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15363 (match_dup 2)))
15364 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15365 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15366 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15367 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15368 (parallel [(set (match_operand:XF 0 "register_operand" "")
15369 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15370 (clobber (match_scratch:XF 5 ""))])]
15371 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15372 && flag_unsafe_math_optimizations"
15373 {
15374 rtx temp;
15375 int i;
15376
15377 for (i=2; i<9; i++)
15378 operands[i] = gen_reg_rtx (XFmode);
15379 temp = standard_80387_constant_rtx (6); /* fldl2t */
15380 emit_move_insn (operands[2], temp);
15381 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15382 })
15383
15384 (define_expand "exp2sf2"
15385 [(set (match_dup 2)
15386 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15387 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15388 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15389 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15390 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15391 (parallel [(set (match_operand:SF 0 "register_operand" "")
15392 (unspec:SF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15393 (clobber (match_scratch:SF 3 ""))])]
15394 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15395 && flag_unsafe_math_optimizations"
15396 {
15397 int i;
15398
15399 for (i=2; i<8; i++)
15400 operands[i] = gen_reg_rtx (XFmode);
15401 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15402 })
15403
15404 (define_expand "exp2df2"
15405 [(set (match_dup 2)
15406 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15407 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15408 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15409 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15410 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15411 (parallel [(set (match_operand:DF 0 "register_operand" "")
15412 (unspec:DF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15413 (clobber (match_scratch:DF 3 ""))])]
15414 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15415 && flag_unsafe_math_optimizations"
15416 {
15417 int i;
15418
15419 for (i=2; i<8; i++)
15420 operands[i] = gen_reg_rtx (XFmode);
15421 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15422 })
15423
15424 (define_expand "exp2xf2"
15425 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15426 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15427 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15428 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15429 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15430 (parallel [(set (match_operand:XF 0 "register_operand" "")
15431 (unspec:XF [(match_dup 7) (match_dup 3)] UNSPEC_FSCALE))
15432 (clobber (match_scratch:XF 3 ""))])]
15433 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15434 && flag_unsafe_math_optimizations"
15435 {
15436 int i;
15437
15438 for (i=2; i<8; i++)
15439 operands[i] = gen_reg_rtx (XFmode);
15440 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15441 })
15442
15443 (define_expand "atansf2"
15444 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15445 (unspec:SF [(match_dup 2)
15446 (match_operand:SF 1 "register_operand" "")]
15447 UNSPEC_FPATAN))
15448 (clobber (match_scratch:SF 3 ""))])]
15449 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15450 && flag_unsafe_math_optimizations"
15451 {
15452 operands[2] = gen_reg_rtx (SFmode);
15453 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15454 })
15455
15456 (define_expand "atandf2"
15457 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15458 (unspec:DF [(match_dup 2)
15459 (match_operand:DF 1 "register_operand" "")]
15460 UNSPEC_FPATAN))
15461 (clobber (match_scratch:DF 3 ""))])]
15462 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15463 && flag_unsafe_math_optimizations"
15464 {
15465 operands[2] = gen_reg_rtx (DFmode);
15466 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15467 })
15468
15469 (define_expand "atanxf2"
15470 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15471 (unspec:XF [(match_dup 2)
15472 (match_operand:XF 1 "register_operand" "")]
15473 UNSPEC_FPATAN))
15474 (clobber (match_scratch:XF 3 ""))])]
15475 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15476 && flag_unsafe_math_optimizations"
15477 {
15478 operands[2] = gen_reg_rtx (XFmode);
15479 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15480 })
15481 \f
15482 ;; Block operation instructions
15483
15484 (define_insn "cld"
15485 [(set (reg:SI 19) (const_int 0))]
15486 ""
15487 "cld"
15488 [(set_attr "type" "cld")])
15489
15490 (define_expand "movstrsi"
15491 [(use (match_operand:BLK 0 "memory_operand" ""))
15492 (use (match_operand:BLK 1 "memory_operand" ""))
15493 (use (match_operand:SI 2 "nonmemory_operand" ""))
15494 (use (match_operand:SI 3 "const_int_operand" ""))]
15495 "! optimize_size"
15496 {
15497 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15498 DONE;
15499 else
15500 FAIL;
15501 })
15502
15503 (define_expand "movstrdi"
15504 [(use (match_operand:BLK 0 "memory_operand" ""))
15505 (use (match_operand:BLK 1 "memory_operand" ""))
15506 (use (match_operand:DI 2 "nonmemory_operand" ""))
15507 (use (match_operand:DI 3 "const_int_operand" ""))]
15508 "TARGET_64BIT"
15509 {
15510 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15511 DONE;
15512 else
15513 FAIL;
15514 })
15515
15516 ;; Most CPUs don't like single string operations
15517 ;; Handle this case here to simplify previous expander.
15518
15519 (define_expand "strmov"
15520 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15521 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15522 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15523 (clobber (reg:CC 17))])
15524 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15525 (clobber (reg:CC 17))])]
15526 ""
15527 {
15528 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15529
15530 /* If .md ever supports :P for Pmode, these can be directly
15531 in the pattern above. */
15532 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15533 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15534
15535 if (TARGET_SINGLE_STRINGOP || optimize_size)
15536 {
15537 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15538 operands[2], operands[3],
15539 operands[5], operands[6]));
15540 DONE;
15541 }
15542
15543 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15544 })
15545
15546 (define_expand "strmov_singleop"
15547 [(parallel [(set (match_operand 1 "memory_operand" "")
15548 (match_operand 3 "memory_operand" ""))
15549 (set (match_operand 0 "register_operand" "")
15550 (match_operand 4 "" ""))
15551 (set (match_operand 2 "register_operand" "")
15552 (match_operand 5 "" ""))
15553 (use (reg:SI 19))])]
15554 "TARGET_SINGLE_STRINGOP || optimize_size"
15555 "")
15556
15557 (define_insn "*strmovdi_rex_1"
15558 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15559 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15560 (set (match_operand:DI 0 "register_operand" "=D")
15561 (plus:DI (match_dup 2)
15562 (const_int 8)))
15563 (set (match_operand:DI 1 "register_operand" "=S")
15564 (plus:DI (match_dup 3)
15565 (const_int 8)))
15566 (use (reg:SI 19))]
15567 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15568 "movsq"
15569 [(set_attr "type" "str")
15570 (set_attr "mode" "DI")
15571 (set_attr "memory" "both")])
15572
15573 (define_insn "*strmovsi_1"
15574 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15575 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15576 (set (match_operand:SI 0 "register_operand" "=D")
15577 (plus:SI (match_dup 2)
15578 (const_int 4)))
15579 (set (match_operand:SI 1 "register_operand" "=S")
15580 (plus:SI (match_dup 3)
15581 (const_int 4)))
15582 (use (reg:SI 19))]
15583 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15584 "{movsl|movsd}"
15585 [(set_attr "type" "str")
15586 (set_attr "mode" "SI")
15587 (set_attr "memory" "both")])
15588
15589 (define_insn "*strmovsi_rex_1"
15590 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15591 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15592 (set (match_operand:DI 0 "register_operand" "=D")
15593 (plus:DI (match_dup 2)
15594 (const_int 4)))
15595 (set (match_operand:DI 1 "register_operand" "=S")
15596 (plus:DI (match_dup 3)
15597 (const_int 4)))
15598 (use (reg:SI 19))]
15599 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15600 "{movsl|movsd}"
15601 [(set_attr "type" "str")
15602 (set_attr "mode" "SI")
15603 (set_attr "memory" "both")])
15604
15605 (define_insn "*strmovhi_1"
15606 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15607 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15608 (set (match_operand:SI 0 "register_operand" "=D")
15609 (plus:SI (match_dup 2)
15610 (const_int 2)))
15611 (set (match_operand:SI 1 "register_operand" "=S")
15612 (plus:SI (match_dup 3)
15613 (const_int 2)))
15614 (use (reg:SI 19))]
15615 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15616 "movsw"
15617 [(set_attr "type" "str")
15618 (set_attr "memory" "both")
15619 (set_attr "mode" "HI")])
15620
15621 (define_insn "*strmovhi_rex_1"
15622 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15623 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15624 (set (match_operand:DI 0 "register_operand" "=D")
15625 (plus:DI (match_dup 2)
15626 (const_int 2)))
15627 (set (match_operand:DI 1 "register_operand" "=S")
15628 (plus:DI (match_dup 3)
15629 (const_int 2)))
15630 (use (reg:SI 19))]
15631 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15632 "movsw"
15633 [(set_attr "type" "str")
15634 (set_attr "memory" "both")
15635 (set_attr "mode" "HI")])
15636
15637 (define_insn "*strmovqi_1"
15638 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15639 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15640 (set (match_operand:SI 0 "register_operand" "=D")
15641 (plus:SI (match_dup 2)
15642 (const_int 1)))
15643 (set (match_operand:SI 1 "register_operand" "=S")
15644 (plus:SI (match_dup 3)
15645 (const_int 1)))
15646 (use (reg:SI 19))]
15647 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15648 "movsb"
15649 [(set_attr "type" "str")
15650 (set_attr "memory" "both")
15651 (set_attr "mode" "QI")])
15652
15653 (define_insn "*strmovqi_rex_1"
15654 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15655 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15656 (set (match_operand:DI 0 "register_operand" "=D")
15657 (plus:DI (match_dup 2)
15658 (const_int 1)))
15659 (set (match_operand:DI 1 "register_operand" "=S")
15660 (plus:DI (match_dup 3)
15661 (const_int 1)))
15662 (use (reg:SI 19))]
15663 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15664 "movsb"
15665 [(set_attr "type" "str")
15666 (set_attr "memory" "both")
15667 (set_attr "mode" "QI")])
15668
15669 (define_expand "rep_mov"
15670 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15671 (set (match_operand 0 "register_operand" "")
15672 (match_operand 5 "" ""))
15673 (set (match_operand 2 "register_operand" "")
15674 (match_operand 6 "" ""))
15675 (set (match_operand 1 "memory_operand" "")
15676 (match_operand 3 "memory_operand" ""))
15677 (use (match_dup 4))
15678 (use (reg:SI 19))])]
15679 ""
15680 "")
15681
15682 (define_insn "*rep_movdi_rex64"
15683 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15684 (set (match_operand:DI 0 "register_operand" "=D")
15685 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15686 (const_int 3))
15687 (match_operand:DI 3 "register_operand" "0")))
15688 (set (match_operand:DI 1 "register_operand" "=S")
15689 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15690 (match_operand:DI 4 "register_operand" "1")))
15691 (set (mem:BLK (match_dup 3))
15692 (mem:BLK (match_dup 4)))
15693 (use (match_dup 5))
15694 (use (reg:SI 19))]
15695 "TARGET_64BIT"
15696 "{rep\;movsq|rep movsq}"
15697 [(set_attr "type" "str")
15698 (set_attr "prefix_rep" "1")
15699 (set_attr "memory" "both")
15700 (set_attr "mode" "DI")])
15701
15702 (define_insn "*rep_movsi"
15703 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15704 (set (match_operand:SI 0 "register_operand" "=D")
15705 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15706 (const_int 2))
15707 (match_operand:SI 3 "register_operand" "0")))
15708 (set (match_operand:SI 1 "register_operand" "=S")
15709 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15710 (match_operand:SI 4 "register_operand" "1")))
15711 (set (mem:BLK (match_dup 3))
15712 (mem:BLK (match_dup 4)))
15713 (use (match_dup 5))
15714 (use (reg:SI 19))]
15715 "!TARGET_64BIT"
15716 "{rep\;movsl|rep movsd}"
15717 [(set_attr "type" "str")
15718 (set_attr "prefix_rep" "1")
15719 (set_attr "memory" "both")
15720 (set_attr "mode" "SI")])
15721
15722 (define_insn "*rep_movsi_rex64"
15723 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15724 (set (match_operand:DI 0 "register_operand" "=D")
15725 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15726 (const_int 2))
15727 (match_operand:DI 3 "register_operand" "0")))
15728 (set (match_operand:DI 1 "register_operand" "=S")
15729 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15730 (match_operand:DI 4 "register_operand" "1")))
15731 (set (mem:BLK (match_dup 3))
15732 (mem:BLK (match_dup 4)))
15733 (use (match_dup 5))
15734 (use (reg:SI 19))]
15735 "TARGET_64BIT"
15736 "{rep\;movsl|rep movsd}"
15737 [(set_attr "type" "str")
15738 (set_attr "prefix_rep" "1")
15739 (set_attr "memory" "both")
15740 (set_attr "mode" "SI")])
15741
15742 (define_insn "*rep_movqi"
15743 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15744 (set (match_operand:SI 0 "register_operand" "=D")
15745 (plus:SI (match_operand:SI 3 "register_operand" "0")
15746 (match_operand:SI 5 "register_operand" "2")))
15747 (set (match_operand:SI 1 "register_operand" "=S")
15748 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15749 (set (mem:BLK (match_dup 3))
15750 (mem:BLK (match_dup 4)))
15751 (use (match_dup 5))
15752 (use (reg:SI 19))]
15753 "!TARGET_64BIT"
15754 "{rep\;movsb|rep movsb}"
15755 [(set_attr "type" "str")
15756 (set_attr "prefix_rep" "1")
15757 (set_attr "memory" "both")
15758 (set_attr "mode" "SI")])
15759
15760 (define_insn "*rep_movqi_rex64"
15761 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15762 (set (match_operand:DI 0 "register_operand" "=D")
15763 (plus:DI (match_operand:DI 3 "register_operand" "0")
15764 (match_operand:DI 5 "register_operand" "2")))
15765 (set (match_operand:DI 1 "register_operand" "=S")
15766 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15767 (set (mem:BLK (match_dup 3))
15768 (mem:BLK (match_dup 4)))
15769 (use (match_dup 5))
15770 (use (reg:SI 19))]
15771 "TARGET_64BIT"
15772 "{rep\;movsb|rep movsb}"
15773 [(set_attr "type" "str")
15774 (set_attr "prefix_rep" "1")
15775 (set_attr "memory" "both")
15776 (set_attr "mode" "SI")])
15777
15778 (define_expand "clrstrsi"
15779 [(use (match_operand:BLK 0 "memory_operand" ""))
15780 (use (match_operand:SI 1 "nonmemory_operand" ""))
15781 (use (match_operand 2 "const_int_operand" ""))]
15782 ""
15783 {
15784 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15785 DONE;
15786 else
15787 FAIL;
15788 })
15789
15790 (define_expand "clrstrdi"
15791 [(use (match_operand:BLK 0 "memory_operand" ""))
15792 (use (match_operand:DI 1 "nonmemory_operand" ""))
15793 (use (match_operand 2 "const_int_operand" ""))]
15794 "TARGET_64BIT"
15795 {
15796 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15797 DONE;
15798 else
15799 FAIL;
15800 })
15801
15802 ;; Most CPUs don't like single string operations
15803 ;; Handle this case here to simplify previous expander.
15804
15805 (define_expand "strset"
15806 [(set (match_operand 1 "memory_operand" "")
15807 (match_operand 2 "register_operand" ""))
15808 (parallel [(set (match_operand 0 "register_operand" "")
15809 (match_dup 3))
15810 (clobber (reg:CC 17))])]
15811 ""
15812 {
15813 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15814 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15815
15816 /* If .md ever supports :P for Pmode, this can be directly
15817 in the pattern above. */
15818 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15819 GEN_INT (GET_MODE_SIZE (GET_MODE
15820 (operands[2]))));
15821 if (TARGET_SINGLE_STRINGOP || optimize_size)
15822 {
15823 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15824 operands[3]));
15825 DONE;
15826 }
15827 })
15828
15829 (define_expand "strset_singleop"
15830 [(parallel [(set (match_operand 1 "memory_operand" "")
15831 (match_operand 2 "register_operand" ""))
15832 (set (match_operand 0 "register_operand" "")
15833 (match_operand 3 "" ""))
15834 (use (reg:SI 19))])]
15835 "TARGET_SINGLE_STRINGOP || optimize_size"
15836 "")
15837
15838 (define_insn "*strsetdi_rex_1"
15839 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15840 (match_operand:SI 2 "register_operand" "a"))
15841 (set (match_operand:DI 0 "register_operand" "=D")
15842 (plus:DI (match_dup 1)
15843 (const_int 8)))
15844 (use (reg:SI 19))]
15845 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15846 "stosq"
15847 [(set_attr "type" "str")
15848 (set_attr "memory" "store")
15849 (set_attr "mode" "DI")])
15850
15851 (define_insn "*strsetsi_1"
15852 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15853 (match_operand:SI 2 "register_operand" "a"))
15854 (set (match_operand:SI 0 "register_operand" "=D")
15855 (plus:SI (match_dup 1)
15856 (const_int 4)))
15857 (use (reg:SI 19))]
15858 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15859 "{stosl|stosd}"
15860 [(set_attr "type" "str")
15861 (set_attr "memory" "store")
15862 (set_attr "mode" "SI")])
15863
15864 (define_insn "*strsetsi_rex_1"
15865 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15866 (match_operand:SI 2 "register_operand" "a"))
15867 (set (match_operand:DI 0 "register_operand" "=D")
15868 (plus:DI (match_dup 1)
15869 (const_int 4)))
15870 (use (reg:SI 19))]
15871 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15872 "{stosl|stosd}"
15873 [(set_attr "type" "str")
15874 (set_attr "memory" "store")
15875 (set_attr "mode" "SI")])
15876
15877 (define_insn "*strsethi_1"
15878 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15879 (match_operand:HI 2 "register_operand" "a"))
15880 (set (match_operand:SI 0 "register_operand" "=D")
15881 (plus:SI (match_dup 1)
15882 (const_int 2)))
15883 (use (reg:SI 19))]
15884 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15885 "stosw"
15886 [(set_attr "type" "str")
15887 (set_attr "memory" "store")
15888 (set_attr "mode" "HI")])
15889
15890 (define_insn "*strsethi_rex_1"
15891 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15892 (match_operand:HI 2 "register_operand" "a"))
15893 (set (match_operand:DI 0 "register_operand" "=D")
15894 (plus:DI (match_dup 1)
15895 (const_int 2)))
15896 (use (reg:SI 19))]
15897 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15898 "stosw"
15899 [(set_attr "type" "str")
15900 (set_attr "memory" "store")
15901 (set_attr "mode" "HI")])
15902
15903 (define_insn "*strsetqi_1"
15904 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15905 (match_operand:QI 2 "register_operand" "a"))
15906 (set (match_operand:SI 0 "register_operand" "=D")
15907 (plus:SI (match_dup 1)
15908 (const_int 1)))
15909 (use (reg:SI 19))]
15910 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15911 "stosb"
15912 [(set_attr "type" "str")
15913 (set_attr "memory" "store")
15914 (set_attr "mode" "QI")])
15915
15916 (define_insn "*strsetqi_rex_1"
15917 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15918 (match_operand:QI 2 "register_operand" "a"))
15919 (set (match_operand:DI 0 "register_operand" "=D")
15920 (plus:DI (match_dup 1)
15921 (const_int 1)))
15922 (use (reg:SI 19))]
15923 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15924 "stosb"
15925 [(set_attr "type" "str")
15926 (set_attr "memory" "store")
15927 (set_attr "mode" "QI")])
15928
15929 (define_expand "rep_stos"
15930 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15931 (set (match_operand 0 "register_operand" "")
15932 (match_operand 4 "" ""))
15933 (set (match_operand 2 "memory_operand" "") (const_int 0))
15934 (use (match_operand 3 "register_operand" ""))
15935 (use (match_dup 1))
15936 (use (reg:SI 19))])]
15937 ""
15938 "")
15939
15940 (define_insn "*rep_stosdi_rex64"
15941 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15942 (set (match_operand:DI 0 "register_operand" "=D")
15943 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15944 (const_int 3))
15945 (match_operand:DI 3 "register_operand" "0")))
15946 (set (mem:BLK (match_dup 3))
15947 (const_int 0))
15948 (use (match_operand:DI 2 "register_operand" "a"))
15949 (use (match_dup 4))
15950 (use (reg:SI 19))]
15951 "TARGET_64BIT"
15952 "{rep\;stosq|rep stosq}"
15953 [(set_attr "type" "str")
15954 (set_attr "prefix_rep" "1")
15955 (set_attr "memory" "store")
15956 (set_attr "mode" "DI")])
15957
15958 (define_insn "*rep_stossi"
15959 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15960 (set (match_operand:SI 0 "register_operand" "=D")
15961 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15962 (const_int 2))
15963 (match_operand:SI 3 "register_operand" "0")))
15964 (set (mem:BLK (match_dup 3))
15965 (const_int 0))
15966 (use (match_operand:SI 2 "register_operand" "a"))
15967 (use (match_dup 4))
15968 (use (reg:SI 19))]
15969 "!TARGET_64BIT"
15970 "{rep\;stosl|rep stosd}"
15971 [(set_attr "type" "str")
15972 (set_attr "prefix_rep" "1")
15973 (set_attr "memory" "store")
15974 (set_attr "mode" "SI")])
15975
15976 (define_insn "*rep_stossi_rex64"
15977 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15978 (set (match_operand:DI 0 "register_operand" "=D")
15979 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15980 (const_int 2))
15981 (match_operand:DI 3 "register_operand" "0")))
15982 (set (mem:BLK (match_dup 3))
15983 (const_int 0))
15984 (use (match_operand:SI 2 "register_operand" "a"))
15985 (use (match_dup 4))
15986 (use (reg:SI 19))]
15987 "TARGET_64BIT"
15988 "{rep\;stosl|rep stosd}"
15989 [(set_attr "type" "str")
15990 (set_attr "prefix_rep" "1")
15991 (set_attr "memory" "store")
15992 (set_attr "mode" "SI")])
15993
15994 (define_insn "*rep_stosqi"
15995 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15996 (set (match_operand:SI 0 "register_operand" "=D")
15997 (plus:SI (match_operand:SI 3 "register_operand" "0")
15998 (match_operand:SI 4 "register_operand" "1")))
15999 (set (mem:BLK (match_dup 3))
16000 (const_int 0))
16001 (use (match_operand:QI 2 "register_operand" "a"))
16002 (use (match_dup 4))
16003 (use (reg:SI 19))]
16004 "!TARGET_64BIT"
16005 "{rep\;stosb|rep stosb}"
16006 [(set_attr "type" "str")
16007 (set_attr "prefix_rep" "1")
16008 (set_attr "memory" "store")
16009 (set_attr "mode" "QI")])
16010
16011 (define_insn "*rep_stosqi_rex64"
16012 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16013 (set (match_operand:DI 0 "register_operand" "=D")
16014 (plus:DI (match_operand:DI 3 "register_operand" "0")
16015 (match_operand:DI 4 "register_operand" "1")))
16016 (set (mem:BLK (match_dup 3))
16017 (const_int 0))
16018 (use (match_operand:QI 2 "register_operand" "a"))
16019 (use (match_dup 4))
16020 (use (reg:SI 19))]
16021 "TARGET_64BIT"
16022 "{rep\;stosb|rep stosb}"
16023 [(set_attr "type" "str")
16024 (set_attr "prefix_rep" "1")
16025 (set_attr "memory" "store")
16026 (set_attr "mode" "QI")])
16027
16028 (define_expand "cmpstrsi"
16029 [(set (match_operand:SI 0 "register_operand" "")
16030 (compare:SI (match_operand:BLK 1 "general_operand" "")
16031 (match_operand:BLK 2 "general_operand" "")))
16032 (use (match_operand 3 "general_operand" ""))
16033 (use (match_operand 4 "immediate_operand" ""))]
16034 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16035 {
16036 rtx addr1, addr2, out, outlow, count, countreg, align;
16037
16038 /* Can't use this if the user has appropriated esi or edi. */
16039 if (global_regs[4] || global_regs[5])
16040 FAIL;
16041
16042 out = operands[0];
16043 if (GET_CODE (out) != REG)
16044 out = gen_reg_rtx (SImode);
16045
16046 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16047 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16048 if (addr1 != XEXP (operands[1], 0))
16049 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16050 if (addr2 != XEXP (operands[2], 0))
16051 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16052
16053 count = operands[3];
16054 countreg = ix86_zero_extend_to_Pmode (count);
16055
16056 /* %%% Iff we are testing strict equality, we can use known alignment
16057 to good advantage. This may be possible with combine, particularly
16058 once cc0 is dead. */
16059 align = operands[4];
16060
16061 emit_insn (gen_cld ());
16062 if (GET_CODE (count) == CONST_INT)
16063 {
16064 if (INTVAL (count) == 0)
16065 {
16066 emit_move_insn (operands[0], const0_rtx);
16067 DONE;
16068 }
16069 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16070 operands[1], operands[2]));
16071 }
16072 else
16073 {
16074 if (TARGET_64BIT)
16075 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16076 else
16077 emit_insn (gen_cmpsi_1 (countreg, countreg));
16078 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16079 operands[1], operands[2]));
16080 }
16081
16082 outlow = gen_lowpart (QImode, out);
16083 emit_insn (gen_cmpintqi (outlow));
16084 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16085
16086 if (operands[0] != out)
16087 emit_move_insn (operands[0], out);
16088
16089 DONE;
16090 })
16091
16092 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16093
16094 (define_expand "cmpintqi"
16095 [(set (match_dup 1)
16096 (gtu:QI (reg:CC 17) (const_int 0)))
16097 (set (match_dup 2)
16098 (ltu:QI (reg:CC 17) (const_int 0)))
16099 (parallel [(set (match_operand:QI 0 "register_operand" "")
16100 (minus:QI (match_dup 1)
16101 (match_dup 2)))
16102 (clobber (reg:CC 17))])]
16103 ""
16104 "operands[1] = gen_reg_rtx (QImode);
16105 operands[2] = gen_reg_rtx (QImode);")
16106
16107 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16108 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16109
16110 (define_expand "cmpstrqi_nz_1"
16111 [(parallel [(set (reg:CC 17)
16112 (compare:CC (match_operand 4 "memory_operand" "")
16113 (match_operand 5 "memory_operand" "")))
16114 (use (match_operand 2 "register_operand" ""))
16115 (use (match_operand:SI 3 "immediate_operand" ""))
16116 (use (reg:SI 19))
16117 (clobber (match_operand 0 "register_operand" ""))
16118 (clobber (match_operand 1 "register_operand" ""))
16119 (clobber (match_dup 2))])]
16120 ""
16121 "")
16122
16123 (define_insn "*cmpstrqi_nz_1"
16124 [(set (reg:CC 17)
16125 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16126 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16127 (use (match_operand:SI 6 "register_operand" "2"))
16128 (use (match_operand:SI 3 "immediate_operand" "i"))
16129 (use (reg:SI 19))
16130 (clobber (match_operand:SI 0 "register_operand" "=S"))
16131 (clobber (match_operand:SI 1 "register_operand" "=D"))
16132 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16133 "!TARGET_64BIT"
16134 "repz{\;| }cmpsb"
16135 [(set_attr "type" "str")
16136 (set_attr "mode" "QI")
16137 (set_attr "prefix_rep" "1")])
16138
16139 (define_insn "*cmpstrqi_nz_rex_1"
16140 [(set (reg:CC 17)
16141 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16142 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16143 (use (match_operand:DI 6 "register_operand" "2"))
16144 (use (match_operand:SI 3 "immediate_operand" "i"))
16145 (use (reg:SI 19))
16146 (clobber (match_operand:DI 0 "register_operand" "=S"))
16147 (clobber (match_operand:DI 1 "register_operand" "=D"))
16148 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16149 "TARGET_64BIT"
16150 "repz{\;| }cmpsb"
16151 [(set_attr "type" "str")
16152 (set_attr "mode" "QI")
16153 (set_attr "prefix_rep" "1")])
16154
16155 ;; The same, but the count is not known to not be zero.
16156
16157 (define_expand "cmpstrqi_1"
16158 [(parallel [(set (reg:CC 17)
16159 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16160 (const_int 0))
16161 (compare:CC (match_operand 4 "memory_operand" "")
16162 (match_operand 5 "memory_operand" ""))
16163 (const_int 0)))
16164 (use (match_operand:SI 3 "immediate_operand" ""))
16165 (use (reg:CC 17))
16166 (use (reg:SI 19))
16167 (clobber (match_operand 0 "register_operand" ""))
16168 (clobber (match_operand 1 "register_operand" ""))
16169 (clobber (match_dup 2))])]
16170 ""
16171 "")
16172
16173 (define_insn "*cmpstrqi_1"
16174 [(set (reg:CC 17)
16175 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16176 (const_int 0))
16177 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16178 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16179 (const_int 0)))
16180 (use (match_operand:SI 3 "immediate_operand" "i"))
16181 (use (reg:CC 17))
16182 (use (reg:SI 19))
16183 (clobber (match_operand:SI 0 "register_operand" "=S"))
16184 (clobber (match_operand:SI 1 "register_operand" "=D"))
16185 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16186 "!TARGET_64BIT"
16187 "repz{\;| }cmpsb"
16188 [(set_attr "type" "str")
16189 (set_attr "mode" "QI")
16190 (set_attr "prefix_rep" "1")])
16191
16192 (define_insn "*cmpstrqi_rex_1"
16193 [(set (reg:CC 17)
16194 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16195 (const_int 0))
16196 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16197 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16198 (const_int 0)))
16199 (use (match_operand:SI 3 "immediate_operand" "i"))
16200 (use (reg:CC 17))
16201 (use (reg:SI 19))
16202 (clobber (match_operand:DI 0 "register_operand" "=S"))
16203 (clobber (match_operand:DI 1 "register_operand" "=D"))
16204 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16205 "TARGET_64BIT"
16206 "repz{\;| }cmpsb"
16207 [(set_attr "type" "str")
16208 (set_attr "mode" "QI")
16209 (set_attr "prefix_rep" "1")])
16210
16211 (define_expand "strlensi"
16212 [(set (match_operand:SI 0 "register_operand" "")
16213 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16214 (match_operand:QI 2 "immediate_operand" "")
16215 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16216 ""
16217 {
16218 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16219 DONE;
16220 else
16221 FAIL;
16222 })
16223
16224 (define_expand "strlendi"
16225 [(set (match_operand:DI 0 "register_operand" "")
16226 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16227 (match_operand:QI 2 "immediate_operand" "")
16228 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16229 ""
16230 {
16231 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16232 DONE;
16233 else
16234 FAIL;
16235 })
16236
16237 (define_expand "strlenqi_1"
16238 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16239 (use (reg:SI 19))
16240 (clobber (match_operand 1 "register_operand" ""))
16241 (clobber (reg:CC 17))])]
16242 ""
16243 "")
16244
16245 (define_insn "*strlenqi_1"
16246 [(set (match_operand:SI 0 "register_operand" "=&c")
16247 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16248 (match_operand:QI 2 "register_operand" "a")
16249 (match_operand:SI 3 "immediate_operand" "i")
16250 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16251 (use (reg:SI 19))
16252 (clobber (match_operand:SI 1 "register_operand" "=D"))
16253 (clobber (reg:CC 17))]
16254 "!TARGET_64BIT"
16255 "repnz{\;| }scasb"
16256 [(set_attr "type" "str")
16257 (set_attr "mode" "QI")
16258 (set_attr "prefix_rep" "1")])
16259
16260 (define_insn "*strlenqi_rex_1"
16261 [(set (match_operand:DI 0 "register_operand" "=&c")
16262 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16263 (match_operand:QI 2 "register_operand" "a")
16264 (match_operand:DI 3 "immediate_operand" "i")
16265 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16266 (use (reg:SI 19))
16267 (clobber (match_operand:DI 1 "register_operand" "=D"))
16268 (clobber (reg:CC 17))]
16269 "TARGET_64BIT"
16270 "repnz{\;| }scasb"
16271 [(set_attr "type" "str")
16272 (set_attr "mode" "QI")
16273 (set_attr "prefix_rep" "1")])
16274
16275 ;; Peephole optimizations to clean up after cmpstr*. This should be
16276 ;; handled in combine, but it is not currently up to the task.
16277 ;; When used for their truth value, the cmpstr* expanders generate
16278 ;; code like this:
16279 ;;
16280 ;; repz cmpsb
16281 ;; seta %al
16282 ;; setb %dl
16283 ;; cmpb %al, %dl
16284 ;; jcc label
16285 ;;
16286 ;; The intermediate three instructions are unnecessary.
16287
16288 ;; This one handles cmpstr*_nz_1...
16289 (define_peephole2
16290 [(parallel[
16291 (set (reg:CC 17)
16292 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16293 (mem:BLK (match_operand 5 "register_operand" ""))))
16294 (use (match_operand 6 "register_operand" ""))
16295 (use (match_operand:SI 3 "immediate_operand" ""))
16296 (use (reg:SI 19))
16297 (clobber (match_operand 0 "register_operand" ""))
16298 (clobber (match_operand 1 "register_operand" ""))
16299 (clobber (match_operand 2 "register_operand" ""))])
16300 (set (match_operand:QI 7 "register_operand" "")
16301 (gtu:QI (reg:CC 17) (const_int 0)))
16302 (set (match_operand:QI 8 "register_operand" "")
16303 (ltu:QI (reg:CC 17) (const_int 0)))
16304 (set (reg 17)
16305 (compare (match_dup 7) (match_dup 8)))
16306 ]
16307 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16308 [(parallel[
16309 (set (reg:CC 17)
16310 (compare:CC (mem:BLK (match_dup 4))
16311 (mem:BLK (match_dup 5))))
16312 (use (match_dup 6))
16313 (use (match_dup 3))
16314 (use (reg:SI 19))
16315 (clobber (match_dup 0))
16316 (clobber (match_dup 1))
16317 (clobber (match_dup 2))])]
16318 "")
16319
16320 ;; ...and this one handles cmpstr*_1.
16321 (define_peephole2
16322 [(parallel[
16323 (set (reg:CC 17)
16324 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16325 (const_int 0))
16326 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16327 (mem:BLK (match_operand 5 "register_operand" "")))
16328 (const_int 0)))
16329 (use (match_operand:SI 3 "immediate_operand" ""))
16330 (use (reg:CC 17))
16331 (use (reg:SI 19))
16332 (clobber (match_operand 0 "register_operand" ""))
16333 (clobber (match_operand 1 "register_operand" ""))
16334 (clobber (match_operand 2 "register_operand" ""))])
16335 (set (match_operand:QI 7 "register_operand" "")
16336 (gtu:QI (reg:CC 17) (const_int 0)))
16337 (set (match_operand:QI 8 "register_operand" "")
16338 (ltu:QI (reg:CC 17) (const_int 0)))
16339 (set (reg 17)
16340 (compare (match_dup 7) (match_dup 8)))
16341 ]
16342 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16343 [(parallel[
16344 (set (reg:CC 17)
16345 (if_then_else:CC (ne (match_dup 6)
16346 (const_int 0))
16347 (compare:CC (mem:BLK (match_dup 4))
16348 (mem:BLK (match_dup 5)))
16349 (const_int 0)))
16350 (use (match_dup 3))
16351 (use (reg:CC 17))
16352 (use (reg:SI 19))
16353 (clobber (match_dup 0))
16354 (clobber (match_dup 1))
16355 (clobber (match_dup 2))])]
16356 "")
16357
16358
16359 \f
16360 ;; Conditional move instructions.
16361
16362 (define_expand "movdicc"
16363 [(set (match_operand:DI 0 "register_operand" "")
16364 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16365 (match_operand:DI 2 "general_operand" "")
16366 (match_operand:DI 3 "general_operand" "")))]
16367 "TARGET_64BIT"
16368 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16369
16370 (define_insn "x86_movdicc_0_m1_rex64"
16371 [(set (match_operand:DI 0 "register_operand" "=r")
16372 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16373 (const_int -1)
16374 (const_int 0)))
16375 (clobber (reg:CC 17))]
16376 "TARGET_64BIT"
16377 "sbb{q}\t%0, %0"
16378 ; Since we don't have the proper number of operands for an alu insn,
16379 ; fill in all the blanks.
16380 [(set_attr "type" "alu")
16381 (set_attr "pent_pair" "pu")
16382 (set_attr "memory" "none")
16383 (set_attr "imm_disp" "false")
16384 (set_attr "mode" "DI")
16385 (set_attr "length_immediate" "0")])
16386
16387 (define_insn "movdicc_c_rex64"
16388 [(set (match_operand:DI 0 "register_operand" "=r,r")
16389 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16390 [(reg 17) (const_int 0)])
16391 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16392 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16393 "TARGET_64BIT && TARGET_CMOVE
16394 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16395 "@
16396 cmov%O2%C1\t{%2, %0|%0, %2}
16397 cmov%O2%c1\t{%3, %0|%0, %3}"
16398 [(set_attr "type" "icmov")
16399 (set_attr "mode" "DI")])
16400
16401 (define_expand "movsicc"
16402 [(set (match_operand:SI 0 "register_operand" "")
16403 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16404 (match_operand:SI 2 "general_operand" "")
16405 (match_operand:SI 3 "general_operand" "")))]
16406 ""
16407 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16408
16409 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16410 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16411 ;; So just document what we're doing explicitly.
16412
16413 (define_insn "x86_movsicc_0_m1"
16414 [(set (match_operand:SI 0 "register_operand" "=r")
16415 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16416 (const_int -1)
16417 (const_int 0)))
16418 (clobber (reg:CC 17))]
16419 ""
16420 "sbb{l}\t%0, %0"
16421 ; Since we don't have the proper number of operands for an alu insn,
16422 ; fill in all the blanks.
16423 [(set_attr "type" "alu")
16424 (set_attr "pent_pair" "pu")
16425 (set_attr "memory" "none")
16426 (set_attr "imm_disp" "false")
16427 (set_attr "mode" "SI")
16428 (set_attr "length_immediate" "0")])
16429
16430 (define_insn "*movsicc_noc"
16431 [(set (match_operand:SI 0 "register_operand" "=r,r")
16432 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16433 [(reg 17) (const_int 0)])
16434 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16435 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16436 "TARGET_CMOVE
16437 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16438 "@
16439 cmov%O2%C1\t{%2, %0|%0, %2}
16440 cmov%O2%c1\t{%3, %0|%0, %3}"
16441 [(set_attr "type" "icmov")
16442 (set_attr "mode" "SI")])
16443
16444 (define_expand "movhicc"
16445 [(set (match_operand:HI 0 "register_operand" "")
16446 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16447 (match_operand:HI 2 "general_operand" "")
16448 (match_operand:HI 3 "general_operand" "")))]
16449 "TARGET_HIMODE_MATH"
16450 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16451
16452 (define_insn "*movhicc_noc"
16453 [(set (match_operand:HI 0 "register_operand" "=r,r")
16454 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16455 [(reg 17) (const_int 0)])
16456 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16457 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16458 "TARGET_CMOVE
16459 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16460 "@
16461 cmov%O2%C1\t{%2, %0|%0, %2}
16462 cmov%O2%c1\t{%3, %0|%0, %3}"
16463 [(set_attr "type" "icmov")
16464 (set_attr "mode" "HI")])
16465
16466 (define_expand "movqicc"
16467 [(set (match_operand:QI 0 "register_operand" "")
16468 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16469 (match_operand:QI 2 "general_operand" "")
16470 (match_operand:QI 3 "general_operand" "")))]
16471 "TARGET_QIMODE_MATH"
16472 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16473
16474 (define_insn_and_split "*movqicc_noc"
16475 [(set (match_operand:QI 0 "register_operand" "=r,r")
16476 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16477 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16478 (match_operand:QI 2 "register_operand" "r,0")
16479 (match_operand:QI 3 "register_operand" "0,r")))]
16480 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16481 "#"
16482 "&& reload_completed"
16483 [(set (match_dup 0)
16484 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16485 (match_dup 2)
16486 (match_dup 3)))]
16487 "operands[0] = gen_lowpart (SImode, operands[0]);
16488 operands[2] = gen_lowpart (SImode, operands[2]);
16489 operands[3] = gen_lowpart (SImode, operands[3]);"
16490 [(set_attr "type" "icmov")
16491 (set_attr "mode" "SI")])
16492
16493 (define_expand "movsfcc"
16494 [(set (match_operand:SF 0 "register_operand" "")
16495 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16496 (match_operand:SF 2 "register_operand" "")
16497 (match_operand:SF 3 "register_operand" "")))]
16498 "TARGET_CMOVE"
16499 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16500
16501 (define_insn "*movsfcc_1"
16502 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16503 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16504 [(reg 17) (const_int 0)])
16505 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16506 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16507 "TARGET_CMOVE
16508 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16509 "@
16510 fcmov%F1\t{%2, %0|%0, %2}
16511 fcmov%f1\t{%3, %0|%0, %3}
16512 cmov%O2%C1\t{%2, %0|%0, %2}
16513 cmov%O2%c1\t{%3, %0|%0, %3}"
16514 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16515 (set_attr "mode" "SF,SF,SI,SI")])
16516
16517 (define_expand "movdfcc"
16518 [(set (match_operand:DF 0 "register_operand" "")
16519 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16520 (match_operand:DF 2 "register_operand" "")
16521 (match_operand:DF 3 "register_operand" "")))]
16522 "TARGET_CMOVE"
16523 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16524
16525 (define_insn "*movdfcc_1"
16526 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16527 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16528 [(reg 17) (const_int 0)])
16529 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16530 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16531 "!TARGET_64BIT && TARGET_CMOVE
16532 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16533 "@
16534 fcmov%F1\t{%2, %0|%0, %2}
16535 fcmov%f1\t{%3, %0|%0, %3}
16536 #
16537 #"
16538 [(set_attr "type" "fcmov,fcmov,multi,multi")
16539 (set_attr "mode" "DF")])
16540
16541 (define_insn "*movdfcc_1_rex64"
16542 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16543 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16544 [(reg 17) (const_int 0)])
16545 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16546 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16547 "TARGET_64BIT && TARGET_CMOVE
16548 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16549 "@
16550 fcmov%F1\t{%2, %0|%0, %2}
16551 fcmov%f1\t{%3, %0|%0, %3}
16552 cmov%O2%C1\t{%2, %0|%0, %2}
16553 cmov%O2%c1\t{%3, %0|%0, %3}"
16554 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16555 (set_attr "mode" "DF")])
16556
16557 (define_split
16558 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16559 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16560 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16561 (match_operand:DF 2 "nonimmediate_operand" "")
16562 (match_operand:DF 3 "nonimmediate_operand" "")))]
16563 "!TARGET_64BIT && reload_completed"
16564 [(set (match_dup 2)
16565 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16566 (match_dup 5)
16567 (match_dup 7)))
16568 (set (match_dup 3)
16569 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16570 (match_dup 6)
16571 (match_dup 8)))]
16572 "split_di (operands+2, 1, operands+5, operands+6);
16573 split_di (operands+3, 1, operands+7, operands+8);
16574 split_di (operands, 1, operands+2, operands+3);")
16575
16576 (define_expand "movxfcc"
16577 [(set (match_operand:XF 0 "register_operand" "")
16578 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16579 (match_operand:XF 2 "register_operand" "")
16580 (match_operand:XF 3 "register_operand" "")))]
16581 "TARGET_CMOVE"
16582 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16583
16584 (define_insn "*movxfcc_1"
16585 [(set (match_operand:XF 0 "register_operand" "=f,f")
16586 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16587 [(reg 17) (const_int 0)])
16588 (match_operand:XF 2 "register_operand" "f,0")
16589 (match_operand:XF 3 "register_operand" "0,f")))]
16590 "TARGET_CMOVE"
16591 "@
16592 fcmov%F1\t{%2, %0|%0, %2}
16593 fcmov%f1\t{%3, %0|%0, %3}"
16594 [(set_attr "type" "fcmov")
16595 (set_attr "mode" "XF")])
16596
16597 (define_expand "minsf3"
16598 [(parallel [
16599 (set (match_operand:SF 0 "register_operand" "")
16600 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16601 (match_operand:SF 2 "nonimmediate_operand" ""))
16602 (match_dup 1)
16603 (match_dup 2)))
16604 (clobber (reg:CC 17))])]
16605 "TARGET_SSE"
16606 "")
16607
16608 (define_insn "*minsf"
16609 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16610 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16611 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16612 (match_dup 1)
16613 (match_dup 2)))
16614 (clobber (reg:CC 17))]
16615 "TARGET_SSE && TARGET_IEEE_FP"
16616 "#")
16617
16618 (define_insn "*minsf_nonieee"
16619 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16620 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16621 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16622 (match_dup 1)
16623 (match_dup 2)))
16624 (clobber (reg:CC 17))]
16625 "TARGET_SSE && !TARGET_IEEE_FP
16626 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16627 "#")
16628
16629 (define_split
16630 [(set (match_operand:SF 0 "register_operand" "")
16631 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16632 (match_operand:SF 2 "nonimmediate_operand" ""))
16633 (match_operand:SF 3 "register_operand" "")
16634 (match_operand:SF 4 "nonimmediate_operand" "")))
16635 (clobber (reg:CC 17))]
16636 "SSE_REG_P (operands[0]) && reload_completed
16637 && ((operands_match_p (operands[1], operands[3])
16638 && operands_match_p (operands[2], operands[4]))
16639 || (operands_match_p (operands[1], operands[4])
16640 && operands_match_p (operands[2], operands[3])))"
16641 [(set (match_dup 0)
16642 (if_then_else:SF (lt (match_dup 1)
16643 (match_dup 2))
16644 (match_dup 1)
16645 (match_dup 2)))])
16646
16647 ;; Conditional addition patterns
16648 (define_expand "addqicc"
16649 [(match_operand:QI 0 "register_operand" "")
16650 (match_operand 1 "comparison_operator" "")
16651 (match_operand:QI 2 "register_operand" "")
16652 (match_operand:QI 3 "const_int_operand" "")]
16653 ""
16654 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16655
16656 (define_expand "addhicc"
16657 [(match_operand:HI 0 "register_operand" "")
16658 (match_operand 1 "comparison_operator" "")
16659 (match_operand:HI 2 "register_operand" "")
16660 (match_operand:HI 3 "const_int_operand" "")]
16661 ""
16662 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16663
16664 (define_expand "addsicc"
16665 [(match_operand:SI 0 "register_operand" "")
16666 (match_operand 1 "comparison_operator" "")
16667 (match_operand:SI 2 "register_operand" "")
16668 (match_operand:SI 3 "const_int_operand" "")]
16669 ""
16670 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16671
16672 (define_expand "adddicc"
16673 [(match_operand:DI 0 "register_operand" "")
16674 (match_operand 1 "comparison_operator" "")
16675 (match_operand:DI 2 "register_operand" "")
16676 (match_operand:DI 3 "const_int_operand" "")]
16677 "TARGET_64BIT"
16678 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16679
16680 ;; We can't represent the LT test directly. Do this by swapping the operands.
16681
16682 (define_split
16683 [(set (match_operand:SF 0 "fp_register_operand" "")
16684 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16685 (match_operand:SF 2 "register_operand" ""))
16686 (match_operand:SF 3 "register_operand" "")
16687 (match_operand:SF 4 "register_operand" "")))
16688 (clobber (reg:CC 17))]
16689 "reload_completed
16690 && ((operands_match_p (operands[1], operands[3])
16691 && operands_match_p (operands[2], operands[4]))
16692 || (operands_match_p (operands[1], operands[4])
16693 && operands_match_p (operands[2], operands[3])))"
16694 [(set (reg:CCFP 17)
16695 (compare:CCFP (match_dup 2)
16696 (match_dup 1)))
16697 (set (match_dup 0)
16698 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16699 (match_dup 1)
16700 (match_dup 2)))])
16701
16702 (define_insn "*minsf_sse"
16703 [(set (match_operand:SF 0 "register_operand" "=x")
16704 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16705 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16706 (match_dup 1)
16707 (match_dup 2)))]
16708 "TARGET_SSE && reload_completed"
16709 "minss\t{%2, %0|%0, %2}"
16710 [(set_attr "type" "sse")
16711 (set_attr "mode" "SF")])
16712
16713 (define_expand "mindf3"
16714 [(parallel [
16715 (set (match_operand:DF 0 "register_operand" "")
16716 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16717 (match_operand:DF 2 "nonimmediate_operand" ""))
16718 (match_dup 1)
16719 (match_dup 2)))
16720 (clobber (reg:CC 17))])]
16721 "TARGET_SSE2 && TARGET_SSE_MATH"
16722 "#")
16723
16724 (define_insn "*mindf"
16725 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16726 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16727 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16728 (match_dup 1)
16729 (match_dup 2)))
16730 (clobber (reg:CC 17))]
16731 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16732 "#")
16733
16734 (define_insn "*mindf_nonieee"
16735 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16736 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16737 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16738 (match_dup 1)
16739 (match_dup 2)))
16740 (clobber (reg:CC 17))]
16741 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16742 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16743 "#")
16744
16745 (define_split
16746 [(set (match_operand:DF 0 "register_operand" "")
16747 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16748 (match_operand:DF 2 "nonimmediate_operand" ""))
16749 (match_operand:DF 3 "register_operand" "")
16750 (match_operand:DF 4 "nonimmediate_operand" "")))
16751 (clobber (reg:CC 17))]
16752 "SSE_REG_P (operands[0]) && reload_completed
16753 && ((operands_match_p (operands[1], operands[3])
16754 && operands_match_p (operands[2], operands[4]))
16755 || (operands_match_p (operands[1], operands[4])
16756 && operands_match_p (operands[2], operands[3])))"
16757 [(set (match_dup 0)
16758 (if_then_else:DF (lt (match_dup 1)
16759 (match_dup 2))
16760 (match_dup 1)
16761 (match_dup 2)))])
16762
16763 ;; We can't represent the LT test directly. Do this by swapping the operands.
16764 (define_split
16765 [(set (match_operand:DF 0 "fp_register_operand" "")
16766 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16767 (match_operand:DF 2 "register_operand" ""))
16768 (match_operand:DF 3 "register_operand" "")
16769 (match_operand:DF 4 "register_operand" "")))
16770 (clobber (reg:CC 17))]
16771 "reload_completed
16772 && ((operands_match_p (operands[1], operands[3])
16773 && operands_match_p (operands[2], operands[4]))
16774 || (operands_match_p (operands[1], operands[4])
16775 && operands_match_p (operands[2], operands[3])))"
16776 [(set (reg:CCFP 17)
16777 (compare:CCFP (match_dup 2)
16778 (match_dup 1)))
16779 (set (match_dup 0)
16780 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16781 (match_dup 1)
16782 (match_dup 2)))])
16783
16784 (define_insn "*mindf_sse"
16785 [(set (match_operand:DF 0 "register_operand" "=Y")
16786 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16787 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16788 (match_dup 1)
16789 (match_dup 2)))]
16790 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16791 "minsd\t{%2, %0|%0, %2}"
16792 [(set_attr "type" "sse")
16793 (set_attr "mode" "DF")])
16794
16795 (define_expand "maxsf3"
16796 [(parallel [
16797 (set (match_operand:SF 0 "register_operand" "")
16798 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16799 (match_operand:SF 2 "nonimmediate_operand" ""))
16800 (match_dup 1)
16801 (match_dup 2)))
16802 (clobber (reg:CC 17))])]
16803 "TARGET_SSE"
16804 "#")
16805
16806 (define_insn "*maxsf"
16807 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16808 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16809 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16810 (match_dup 1)
16811 (match_dup 2)))
16812 (clobber (reg:CC 17))]
16813 "TARGET_SSE && TARGET_IEEE_FP"
16814 "#")
16815
16816 (define_insn "*maxsf_nonieee"
16817 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16818 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16819 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16820 (match_dup 1)
16821 (match_dup 2)))
16822 (clobber (reg:CC 17))]
16823 "TARGET_SSE && !TARGET_IEEE_FP
16824 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16825 "#")
16826
16827 (define_split
16828 [(set (match_operand:SF 0 "register_operand" "")
16829 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16830 (match_operand:SF 2 "nonimmediate_operand" ""))
16831 (match_operand:SF 3 "register_operand" "")
16832 (match_operand:SF 4 "nonimmediate_operand" "")))
16833 (clobber (reg:CC 17))]
16834 "SSE_REG_P (operands[0]) && reload_completed
16835 && ((operands_match_p (operands[1], operands[3])
16836 && operands_match_p (operands[2], operands[4]))
16837 || (operands_match_p (operands[1], operands[4])
16838 && operands_match_p (operands[2], operands[3])))"
16839 [(set (match_dup 0)
16840 (if_then_else:SF (gt (match_dup 1)
16841 (match_dup 2))
16842 (match_dup 1)
16843 (match_dup 2)))])
16844
16845 (define_split
16846 [(set (match_operand:SF 0 "fp_register_operand" "")
16847 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16848 (match_operand:SF 2 "register_operand" ""))
16849 (match_operand:SF 3 "register_operand" "")
16850 (match_operand:SF 4 "register_operand" "")))
16851 (clobber (reg:CC 17))]
16852 "reload_completed
16853 && ((operands_match_p (operands[1], operands[3])
16854 && operands_match_p (operands[2], operands[4]))
16855 || (operands_match_p (operands[1], operands[4])
16856 && operands_match_p (operands[2], operands[3])))"
16857 [(set (reg:CCFP 17)
16858 (compare:CCFP (match_dup 1)
16859 (match_dup 2)))
16860 (set (match_dup 0)
16861 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16862 (match_dup 1)
16863 (match_dup 2)))])
16864
16865 (define_insn "*maxsf_sse"
16866 [(set (match_operand:SF 0 "register_operand" "=x")
16867 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16868 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16869 (match_dup 1)
16870 (match_dup 2)))]
16871 "TARGET_SSE && reload_completed"
16872 "maxss\t{%2, %0|%0, %2}"
16873 [(set_attr "type" "sse")
16874 (set_attr "mode" "SF")])
16875
16876 (define_expand "maxdf3"
16877 [(parallel [
16878 (set (match_operand:DF 0 "register_operand" "")
16879 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16880 (match_operand:DF 2 "nonimmediate_operand" ""))
16881 (match_dup 1)
16882 (match_dup 2)))
16883 (clobber (reg:CC 17))])]
16884 "TARGET_SSE2 && TARGET_SSE_MATH"
16885 "#")
16886
16887 (define_insn "*maxdf"
16888 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16889 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16890 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16891 (match_dup 1)
16892 (match_dup 2)))
16893 (clobber (reg:CC 17))]
16894 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16895 "#")
16896
16897 (define_insn "*maxdf_nonieee"
16898 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16899 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16900 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16901 (match_dup 1)
16902 (match_dup 2)))
16903 (clobber (reg:CC 17))]
16904 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16905 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16906 "#")
16907
16908 (define_split
16909 [(set (match_operand:DF 0 "register_operand" "")
16910 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16911 (match_operand:DF 2 "nonimmediate_operand" ""))
16912 (match_operand:DF 3 "register_operand" "")
16913 (match_operand:DF 4 "nonimmediate_operand" "")))
16914 (clobber (reg:CC 17))]
16915 "SSE_REG_P (operands[0]) && reload_completed
16916 && ((operands_match_p (operands[1], operands[3])
16917 && operands_match_p (operands[2], operands[4]))
16918 || (operands_match_p (operands[1], operands[4])
16919 && operands_match_p (operands[2], operands[3])))"
16920 [(set (match_dup 0)
16921 (if_then_else:DF (gt (match_dup 1)
16922 (match_dup 2))
16923 (match_dup 1)
16924 (match_dup 2)))])
16925
16926 (define_split
16927 [(set (match_operand:DF 0 "fp_register_operand" "")
16928 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16929 (match_operand:DF 2 "register_operand" ""))
16930 (match_operand:DF 3 "register_operand" "")
16931 (match_operand:DF 4 "register_operand" "")))
16932 (clobber (reg:CC 17))]
16933 "reload_completed
16934 && ((operands_match_p (operands[1], operands[3])
16935 && operands_match_p (operands[2], operands[4]))
16936 || (operands_match_p (operands[1], operands[4])
16937 && operands_match_p (operands[2], operands[3])))"
16938 [(set (reg:CCFP 17)
16939 (compare:CCFP (match_dup 1)
16940 (match_dup 2)))
16941 (set (match_dup 0)
16942 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16943 (match_dup 1)
16944 (match_dup 2)))])
16945
16946 (define_insn "*maxdf_sse"
16947 [(set (match_operand:DF 0 "register_operand" "=Y")
16948 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16949 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16950 (match_dup 1)
16951 (match_dup 2)))]
16952 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16953 "maxsd\t{%2, %0|%0, %2}"
16954 [(set_attr "type" "sse")
16955 (set_attr "mode" "DF")])
16956 \f
16957 ;; Misc patterns (?)
16958
16959 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16960 ;; Otherwise there will be nothing to keep
16961 ;;
16962 ;; [(set (reg ebp) (reg esp))]
16963 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16964 ;; (clobber (eflags)]
16965 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16966 ;;
16967 ;; in proper program order.
16968 (define_insn "pro_epilogue_adjust_stack_1"
16969 [(set (match_operand:SI 0 "register_operand" "=r,r")
16970 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16971 (match_operand:SI 2 "immediate_operand" "i,i")))
16972 (clobber (reg:CC 17))
16973 (clobber (mem:BLK (scratch)))]
16974 "!TARGET_64BIT"
16975 {
16976 switch (get_attr_type (insn))
16977 {
16978 case TYPE_IMOV:
16979 return "mov{l}\t{%1, %0|%0, %1}";
16980
16981 case TYPE_ALU:
16982 if (GET_CODE (operands[2]) == CONST_INT
16983 && (INTVAL (operands[2]) == 128
16984 || (INTVAL (operands[2]) < 0
16985 && INTVAL (operands[2]) != -128)))
16986 {
16987 operands[2] = GEN_INT (-INTVAL (operands[2]));
16988 return "sub{l}\t{%2, %0|%0, %2}";
16989 }
16990 return "add{l}\t{%2, %0|%0, %2}";
16991
16992 case TYPE_LEA:
16993 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16994 return "lea{l}\t{%a2, %0|%0, %a2}";
16995
16996 default:
16997 abort ();
16998 }
16999 }
17000 [(set (attr "type")
17001 (cond [(eq_attr "alternative" "0")
17002 (const_string "alu")
17003 (match_operand:SI 2 "const0_operand" "")
17004 (const_string "imov")
17005 ]
17006 (const_string "lea")))
17007 (set_attr "mode" "SI")])
17008
17009 (define_insn "pro_epilogue_adjust_stack_rex64"
17010 [(set (match_operand:DI 0 "register_operand" "=r,r")
17011 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17012 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17013 (clobber (reg:CC 17))
17014 (clobber (mem:BLK (scratch)))]
17015 "TARGET_64BIT"
17016 {
17017 switch (get_attr_type (insn))
17018 {
17019 case TYPE_IMOV:
17020 return "mov{q}\t{%1, %0|%0, %1}";
17021
17022 case TYPE_ALU:
17023 if (GET_CODE (operands[2]) == CONST_INT
17024 /* Avoid overflows. */
17025 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17026 && (INTVAL (operands[2]) == 128
17027 || (INTVAL (operands[2]) < 0
17028 && INTVAL (operands[2]) != -128)))
17029 {
17030 operands[2] = GEN_INT (-INTVAL (operands[2]));
17031 return "sub{q}\t{%2, %0|%0, %2}";
17032 }
17033 return "add{q}\t{%2, %0|%0, %2}";
17034
17035 case TYPE_LEA:
17036 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17037 return "lea{q}\t{%a2, %0|%0, %a2}";
17038
17039 default:
17040 abort ();
17041 }
17042 }
17043 [(set (attr "type")
17044 (cond [(eq_attr "alternative" "0")
17045 (const_string "alu")
17046 (match_operand:DI 2 "const0_operand" "")
17047 (const_string "imov")
17048 ]
17049 (const_string "lea")))
17050 (set_attr "mode" "DI")])
17051
17052 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17053 [(set (match_operand:DI 0 "register_operand" "=r,r")
17054 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17055 (match_operand:DI 3 "immediate_operand" "i,i")))
17056 (use (match_operand:DI 2 "register_operand" "r,r"))
17057 (clobber (reg:CC 17))
17058 (clobber (mem:BLK (scratch)))]
17059 "TARGET_64BIT"
17060 {
17061 switch (get_attr_type (insn))
17062 {
17063 case TYPE_ALU:
17064 return "add{q}\t{%2, %0|%0, %2}";
17065
17066 case TYPE_LEA:
17067 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17068 return "lea{q}\t{%a2, %0|%0, %a2}";
17069
17070 default:
17071 abort ();
17072 }
17073 }
17074 [(set_attr "type" "alu,lea")
17075 (set_attr "mode" "DI")])
17076
17077 ;; Placeholder for the conditional moves. This one is split either to SSE
17078 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17079 ;; fact is that compares supported by the cmp??ss instructions are exactly
17080 ;; swapped of those supported by cmove sequence.
17081 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17082 ;; supported by i387 comparisons and we do need to emit two conditional moves
17083 ;; in tandem.
17084
17085 (define_insn "sse_movsfcc"
17086 [(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")
17087 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17088 [(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")
17089 (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")])
17090 (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")
17091 (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")))
17092 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17093 (clobber (reg:CC 17))]
17094 "TARGET_SSE
17095 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17096 /* Avoid combine from being smart and converting min/max
17097 instruction patterns into conditional moves. */
17098 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17099 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17100 || !rtx_equal_p (operands[4], operands[2])
17101 || !rtx_equal_p (operands[5], operands[3]))
17102 && (!TARGET_IEEE_FP
17103 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17104 "#")
17105
17106 (define_insn "sse_movsfcc_eq"
17107 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17108 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17109 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17110 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17111 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17112 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17113 (clobber (reg:CC 17))]
17114 "TARGET_SSE
17115 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17116 "#")
17117
17118 (define_insn "sse_movdfcc"
17119 [(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")
17120 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17121 [(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")
17122 (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")])
17123 (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")
17124 (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")))
17125 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17126 (clobber (reg:CC 17))]
17127 "TARGET_SSE2
17128 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17129 /* Avoid combine from being smart and converting min/max
17130 instruction patterns into conditional moves. */
17131 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17132 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17133 || !rtx_equal_p (operands[4], operands[2])
17134 || !rtx_equal_p (operands[5], operands[3]))
17135 && (!TARGET_IEEE_FP
17136 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17137 "#")
17138
17139 (define_insn "sse_movdfcc_eq"
17140 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17141 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17142 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17143 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17144 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17145 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17146 (clobber (reg:CC 17))]
17147 "TARGET_SSE
17148 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17149 "#")
17150
17151 ;; For non-sse moves just expand the usual cmove sequence.
17152 (define_split
17153 [(set (match_operand 0 "register_operand" "")
17154 (if_then_else (match_operator 1 "comparison_operator"
17155 [(match_operand 4 "nonimmediate_operand" "")
17156 (match_operand 5 "register_operand" "")])
17157 (match_operand 2 "nonimmediate_operand" "")
17158 (match_operand 3 "nonimmediate_operand" "")))
17159 (clobber (match_operand 6 "" ""))
17160 (clobber (reg:CC 17))]
17161 "!SSE_REG_P (operands[0]) && reload_completed
17162 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17163 [(const_int 0)]
17164 {
17165 ix86_compare_op0 = operands[5];
17166 ix86_compare_op1 = operands[4];
17167 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17168 VOIDmode, operands[5], operands[4]);
17169 ix86_expand_fp_movcc (operands);
17170 DONE;
17171 })
17172
17173 ;; Split SSE based conditional move into sequence:
17174 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17175 ;; and op2, op0 - zero op2 if comparison was false
17176 ;; nand op0, op3 - load op3 to op0 if comparison was false
17177 ;; or op2, op0 - get the nonzero one into the result.
17178 (define_split
17179 [(set (match_operand:SF 0 "register_operand" "")
17180 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
17181 [(match_operand:SF 4 "register_operand" "")
17182 (match_operand:SF 5 "nonimmediate_operand" "")])
17183 (match_operand:SF 2 "register_operand" "")
17184 (match_operand:SF 3 "register_operand" "")))
17185 (clobber (match_operand 6 "" ""))
17186 (clobber (reg:CC 17))]
17187 "SSE_REG_P (operands[0]) && reload_completed"
17188 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17189 (set (match_dup 2) (and:V4SF (match_dup 2)
17190 (match_dup 8)))
17191 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17192 (match_dup 3)))
17193 (set (match_dup 0) (ior:V4SF (match_dup 6)
17194 (match_dup 7)))]
17195 {
17196 /* If op2 == op3, op3 would be clobbered before it is used. */
17197 if (operands_match_p (operands[2], operands[3]))
17198 {
17199 emit_move_insn (operands[0], operands[2]);
17200 DONE;
17201 }
17202
17203 PUT_MODE (operands[1], GET_MODE (operands[0]));
17204 if (operands_match_p (operands[0], operands[4]))
17205 operands[6] = operands[4], operands[7] = operands[2];
17206 else
17207 operands[6] = operands[2], operands[7] = operands[4];
17208 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17209 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17210 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17211 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17212 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17213 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17214 })
17215
17216 (define_split
17217 [(set (match_operand:DF 0 "register_operand" "")
17218 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
17219 [(match_operand:DF 4 "register_operand" "")
17220 (match_operand:DF 5 "nonimmediate_operand" "")])
17221 (match_operand:DF 2 "register_operand" "")
17222 (match_operand:DF 3 "register_operand" "")))
17223 (clobber (match_operand 6 "" ""))
17224 (clobber (reg:CC 17))]
17225 "SSE_REG_P (operands[0]) && reload_completed"
17226 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17227 (set (match_dup 2) (and:V2DF (match_dup 2)
17228 (match_dup 8)))
17229 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17230 (match_dup 3)))
17231 (set (match_dup 0) (ior:V2DF (match_dup 6)
17232 (match_dup 7)))]
17233 {
17234 if (GET_MODE (operands[2]) == DFmode
17235 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17236 {
17237 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17238 emit_insn (gen_sse2_unpcklpd (op, op, op));
17239 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17240 emit_insn (gen_sse2_unpcklpd (op, op, op));
17241 }
17242
17243 /* If op2 == op3, op3 would be clobbered before it is used. */
17244 if (operands_match_p (operands[2], operands[3]))
17245 {
17246 emit_move_insn (operands[0], operands[2]);
17247 DONE;
17248 }
17249
17250 PUT_MODE (operands[1], GET_MODE (operands[0]));
17251 if (operands_match_p (operands[0], operands[4]))
17252 operands[6] = operands[4], operands[7] = operands[2];
17253 else
17254 operands[6] = operands[2], operands[7] = operands[4];
17255 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17256 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17257 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17258 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17259 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17260 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17261 })
17262
17263 ;; Special case of conditional move we can handle effectively.
17264 ;; Do not brother with the integer/floating point case, since these are
17265 ;; bot considerably slower, unlike in the generic case.
17266 (define_insn "*sse_movsfcc_const0_1"
17267 [(set (match_operand:SF 0 "register_operand" "=&x")
17268 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17269 [(match_operand:SF 4 "register_operand" "0")
17270 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17271 (match_operand:SF 2 "register_operand" "x")
17272 (match_operand:SF 3 "const0_operand" "X")))]
17273 "TARGET_SSE"
17274 "#")
17275
17276 (define_insn "*sse_movsfcc_const0_2"
17277 [(set (match_operand:SF 0 "register_operand" "=&x")
17278 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17279 [(match_operand:SF 4 "register_operand" "0")
17280 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17281 (match_operand:SF 2 "const0_operand" "X")
17282 (match_operand:SF 3 "register_operand" "x")))]
17283 "TARGET_SSE"
17284 "#")
17285
17286 (define_insn "*sse_movsfcc_const0_3"
17287 [(set (match_operand:SF 0 "register_operand" "=&x")
17288 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17289 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17290 (match_operand:SF 5 "register_operand" "0")])
17291 (match_operand:SF 2 "register_operand" "x")
17292 (match_operand:SF 3 "const0_operand" "X")))]
17293 "TARGET_SSE"
17294 "#")
17295
17296 (define_insn "*sse_movsfcc_const0_4"
17297 [(set (match_operand:SF 0 "register_operand" "=&x")
17298 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17299 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17300 (match_operand:SF 5 "register_operand" "0")])
17301 (match_operand:SF 2 "const0_operand" "X")
17302 (match_operand:SF 3 "register_operand" "x")))]
17303 "TARGET_SSE"
17304 "#")
17305
17306 (define_insn "*sse_movdfcc_const0_1"
17307 [(set (match_operand:DF 0 "register_operand" "=&Y")
17308 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17309 [(match_operand:DF 4 "register_operand" "0")
17310 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17311 (match_operand:DF 2 "register_operand" "Y")
17312 (match_operand:DF 3 "const0_operand" "X")))]
17313 "TARGET_SSE2"
17314 "#")
17315
17316 (define_insn "*sse_movdfcc_const0_2"
17317 [(set (match_operand:DF 0 "register_operand" "=&Y")
17318 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17319 [(match_operand:DF 4 "register_operand" "0")
17320 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17321 (match_operand:DF 2 "const0_operand" "X")
17322 (match_operand:DF 3 "register_operand" "Y")))]
17323 "TARGET_SSE2"
17324 "#")
17325
17326 (define_insn "*sse_movdfcc_const0_3"
17327 [(set (match_operand:DF 0 "register_operand" "=&Y")
17328 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17329 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17330 (match_operand:DF 5 "register_operand" "0")])
17331 (match_operand:DF 2 "register_operand" "Y")
17332 (match_operand:DF 3 "const0_operand" "X")))]
17333 "TARGET_SSE2"
17334 "#")
17335
17336 (define_insn "*sse_movdfcc_const0_4"
17337 [(set (match_operand:DF 0 "register_operand" "=&Y")
17338 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17339 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17340 (match_operand:DF 5 "register_operand" "0")])
17341 (match_operand:DF 2 "const0_operand" "X")
17342 (match_operand:DF 3 "register_operand" "Y")))]
17343 "TARGET_SSE2"
17344 "#")
17345
17346 (define_split
17347 [(set (match_operand:SF 0 "register_operand" "")
17348 (if_then_else (match_operator:SF 1 "comparison_operator"
17349 [(match_operand:SF 4 "nonimmediate_operand" "")
17350 (match_operand:SF 5 "nonimmediate_operand" "")])
17351 (match_operand:SF 2 "nonmemory_operand" "")
17352 (match_operand:SF 3 "nonmemory_operand" "")))]
17353 "SSE_REG_P (operands[0]) && reload_completed
17354 && (const0_operand (operands[2], GET_MODE (operands[0]))
17355 || const0_operand (operands[3], GET_MODE (operands[0])))"
17356 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17357 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17358 {
17359 PUT_MODE (operands[1], GET_MODE (operands[0]));
17360 if (!sse_comparison_operator (operands[1], VOIDmode)
17361 || !rtx_equal_p (operands[0], operands[4]))
17362 {
17363 rtx tmp = operands[5];
17364 operands[5] = operands[4];
17365 operands[4] = tmp;
17366 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17367 }
17368 if (!rtx_equal_p (operands[0], operands[4]))
17369 abort ();
17370 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17371 if (const0_operand (operands[2], GET_MODE (operands[2])))
17372 {
17373 operands[7] = operands[3];
17374 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17375 }
17376 else
17377 {
17378 operands[7] = operands[2];
17379 operands[6] = operands[0];
17380 }
17381 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17382 })
17383
17384 (define_split
17385 [(set (match_operand:DF 0 "register_operand" "")
17386 (if_then_else (match_operator:DF 1 "comparison_operator"
17387 [(match_operand:DF 4 "nonimmediate_operand" "")
17388 (match_operand:DF 5 "nonimmediate_operand" "")])
17389 (match_operand:DF 2 "nonmemory_operand" "")
17390 (match_operand:DF 3 "nonmemory_operand" "")))]
17391 "SSE_REG_P (operands[0]) && reload_completed
17392 && (const0_operand (operands[2], GET_MODE (operands[0]))
17393 || const0_operand (operands[3], GET_MODE (operands[0])))"
17394 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17395 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17396 {
17397 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17398 && GET_MODE (operands[2]) == DFmode)
17399 {
17400 if (REG_P (operands[2]))
17401 {
17402 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17403 emit_insn (gen_sse2_unpcklpd (op, op, op));
17404 }
17405 if (REG_P (operands[3]))
17406 {
17407 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17408 emit_insn (gen_sse2_unpcklpd (op, op, op));
17409 }
17410 }
17411 PUT_MODE (operands[1], GET_MODE (operands[0]));
17412 if (!sse_comparison_operator (operands[1], VOIDmode)
17413 || !rtx_equal_p (operands[0], operands[4]))
17414 {
17415 rtx tmp = operands[5];
17416 operands[5] = operands[4];
17417 operands[4] = tmp;
17418 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17419 }
17420 if (!rtx_equal_p (operands[0], operands[4]))
17421 abort ();
17422 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17423 if (const0_operand (operands[2], GET_MODE (operands[2])))
17424 {
17425 operands[7] = operands[3];
17426 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
17427 }
17428 else
17429 {
17430 operands[7] = operands[2];
17431 operands[6] = operands[8];
17432 }
17433 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17434 })
17435
17436 (define_expand "allocate_stack_worker"
17437 [(match_operand:SI 0 "register_operand" "")]
17438 "TARGET_STACK_PROBE"
17439 {
17440 if (reload_completed)
17441 {
17442 if (TARGET_64BIT)
17443 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17444 else
17445 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17446 }
17447 else
17448 {
17449 if (TARGET_64BIT)
17450 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17451 else
17452 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17453 }
17454 DONE;
17455 })
17456
17457 (define_insn "allocate_stack_worker_1"
17458 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17459 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17460 (clobber (match_scratch:SI 1 "=0"))
17461 (clobber (reg:CC 17))]
17462 "!TARGET_64BIT && TARGET_STACK_PROBE"
17463 "call\t__alloca"
17464 [(set_attr "type" "multi")
17465 (set_attr "length" "5")])
17466
17467 (define_expand "allocate_stack_worker_postreload"
17468 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17469 UNSPEC_STACK_PROBE)
17470 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17471 (clobber (match_dup 0))
17472 (clobber (reg:CC 17))])]
17473 ""
17474 "")
17475
17476 (define_insn "allocate_stack_worker_rex64"
17477 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17478 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17479 (clobber (match_scratch:DI 1 "=0"))
17480 (clobber (reg:CC 17))]
17481 "TARGET_64BIT && TARGET_STACK_PROBE"
17482 "call\t__alloca"
17483 [(set_attr "type" "multi")
17484 (set_attr "length" "5")])
17485
17486 (define_expand "allocate_stack_worker_rex64_postreload"
17487 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17488 UNSPEC_STACK_PROBE)
17489 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17490 (clobber (match_dup 0))
17491 (clobber (reg:CC 17))])]
17492 ""
17493 "")
17494
17495 (define_expand "allocate_stack"
17496 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17497 (minus:SI (reg:SI 7)
17498 (match_operand:SI 1 "general_operand" "")))
17499 (clobber (reg:CC 17))])
17500 (parallel [(set (reg:SI 7)
17501 (minus:SI (reg:SI 7) (match_dup 1)))
17502 (clobber (reg:CC 17))])]
17503 "TARGET_STACK_PROBE"
17504 {
17505 #ifdef CHECK_STACK_LIMIT
17506 if (GET_CODE (operands[1]) == CONST_INT
17507 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17508 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17509 operands[1]));
17510 else
17511 #endif
17512 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17513 operands[1])));
17514
17515 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17516 DONE;
17517 })
17518
17519 (define_expand "builtin_setjmp_receiver"
17520 [(label_ref (match_operand 0 "" ""))]
17521 "!TARGET_64BIT && flag_pic"
17522 {
17523 emit_insn (gen_set_got (pic_offset_table_rtx));
17524 DONE;
17525 })
17526 \f
17527 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17528
17529 (define_split
17530 [(set (match_operand 0 "register_operand" "")
17531 (match_operator 3 "promotable_binary_operator"
17532 [(match_operand 1 "register_operand" "")
17533 (match_operand 2 "aligned_operand" "")]))
17534 (clobber (reg:CC 17))]
17535 "! TARGET_PARTIAL_REG_STALL && reload_completed
17536 && ((GET_MODE (operands[0]) == HImode
17537 && ((!optimize_size && !TARGET_FAST_PREFIX)
17538 || GET_CODE (operands[2]) != CONST_INT
17539 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17540 || (GET_MODE (operands[0]) == QImode
17541 && (TARGET_PROMOTE_QImode || optimize_size)))"
17542 [(parallel [(set (match_dup 0)
17543 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17544 (clobber (reg:CC 17))])]
17545 "operands[0] = gen_lowpart (SImode, operands[0]);
17546 operands[1] = gen_lowpart (SImode, operands[1]);
17547 if (GET_CODE (operands[3]) != ASHIFT)
17548 operands[2] = gen_lowpart (SImode, operands[2]);
17549 PUT_MODE (operands[3], SImode);")
17550
17551 ; Promote the QImode tests, as i386 has encoding of the AND
17552 ; instruction with 32-bit sign-extended immediate and thus the
17553 ; instruction size is unchanged, except in the %eax case for
17554 ; which it is increased by one byte, hence the ! optimize_size.
17555 (define_split
17556 [(set (reg 17)
17557 (compare (and (match_operand 1 "aligned_operand" "")
17558 (match_operand 2 "const_int_operand" ""))
17559 (const_int 0)))
17560 (set (match_operand 0 "register_operand" "")
17561 (and (match_dup 1) (match_dup 2)))]
17562 "! TARGET_PARTIAL_REG_STALL && reload_completed
17563 /* Ensure that the operand will remain sign-extended immediate. */
17564 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17565 && ! optimize_size
17566 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17567 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17568 [(parallel [(set (reg:CCNO 17)
17569 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17570 (const_int 0)))
17571 (set (match_dup 0)
17572 (and:SI (match_dup 1) (match_dup 2)))])]
17573 "operands[2]
17574 = gen_int_mode (INTVAL (operands[2])
17575 & GET_MODE_MASK (GET_MODE (operands[0])),
17576 SImode);
17577 operands[0] = gen_lowpart (SImode, operands[0]);
17578 operands[1] = gen_lowpart (SImode, operands[1]);")
17579
17580 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17581 ; the TEST instruction with 32-bit sign-extended immediate and thus
17582 ; the instruction size would at least double, which is not what we
17583 ; want even with ! optimize_size.
17584 (define_split
17585 [(set (reg 17)
17586 (compare (and (match_operand:HI 0 "aligned_operand" "")
17587 (match_operand:HI 1 "const_int_operand" ""))
17588 (const_int 0)))]
17589 "! TARGET_PARTIAL_REG_STALL && reload_completed
17590 /* Ensure that the operand will remain sign-extended immediate. */
17591 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17592 && ! TARGET_FAST_PREFIX
17593 && ! optimize_size"
17594 [(set (reg:CCNO 17)
17595 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17596 (const_int 0)))]
17597 "operands[1]
17598 = gen_int_mode (INTVAL (operands[1])
17599 & GET_MODE_MASK (GET_MODE (operands[0])),
17600 SImode);
17601 operands[0] = gen_lowpart (SImode, operands[0]);")
17602
17603 (define_split
17604 [(set (match_operand 0 "register_operand" "")
17605 (neg (match_operand 1 "register_operand" "")))
17606 (clobber (reg:CC 17))]
17607 "! TARGET_PARTIAL_REG_STALL && reload_completed
17608 && (GET_MODE (operands[0]) == HImode
17609 || (GET_MODE (operands[0]) == QImode
17610 && (TARGET_PROMOTE_QImode || optimize_size)))"
17611 [(parallel [(set (match_dup 0)
17612 (neg:SI (match_dup 1)))
17613 (clobber (reg:CC 17))])]
17614 "operands[0] = gen_lowpart (SImode, operands[0]);
17615 operands[1] = gen_lowpart (SImode, operands[1]);")
17616
17617 (define_split
17618 [(set (match_operand 0 "register_operand" "")
17619 (not (match_operand 1 "register_operand" "")))]
17620 "! TARGET_PARTIAL_REG_STALL && reload_completed
17621 && (GET_MODE (operands[0]) == HImode
17622 || (GET_MODE (operands[0]) == QImode
17623 && (TARGET_PROMOTE_QImode || optimize_size)))"
17624 [(set (match_dup 0)
17625 (not:SI (match_dup 1)))]
17626 "operands[0] = gen_lowpart (SImode, operands[0]);
17627 operands[1] = gen_lowpart (SImode, operands[1]);")
17628
17629 (define_split
17630 [(set (match_operand 0 "register_operand" "")
17631 (if_then_else (match_operator 1 "comparison_operator"
17632 [(reg 17) (const_int 0)])
17633 (match_operand 2 "register_operand" "")
17634 (match_operand 3 "register_operand" "")))]
17635 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17636 && (GET_MODE (operands[0]) == HImode
17637 || (GET_MODE (operands[0]) == QImode
17638 && (TARGET_PROMOTE_QImode || optimize_size)))"
17639 [(set (match_dup 0)
17640 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17641 "operands[0] = gen_lowpart (SImode, operands[0]);
17642 operands[2] = gen_lowpart (SImode, operands[2]);
17643 operands[3] = gen_lowpart (SImode, operands[3]);")
17644
17645 \f
17646 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17647 ;; transform a complex memory operation into two memory to register operations.
17648
17649 ;; Don't push memory operands
17650 (define_peephole2
17651 [(set (match_operand:SI 0 "push_operand" "")
17652 (match_operand:SI 1 "memory_operand" ""))
17653 (match_scratch:SI 2 "r")]
17654 "! optimize_size && ! TARGET_PUSH_MEMORY"
17655 [(set (match_dup 2) (match_dup 1))
17656 (set (match_dup 0) (match_dup 2))]
17657 "")
17658
17659 (define_peephole2
17660 [(set (match_operand:DI 0 "push_operand" "")
17661 (match_operand:DI 1 "memory_operand" ""))
17662 (match_scratch:DI 2 "r")]
17663 "! optimize_size && ! TARGET_PUSH_MEMORY"
17664 [(set (match_dup 2) (match_dup 1))
17665 (set (match_dup 0) (match_dup 2))]
17666 "")
17667
17668 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17669 ;; SImode pushes.
17670 (define_peephole2
17671 [(set (match_operand:SF 0 "push_operand" "")
17672 (match_operand:SF 1 "memory_operand" ""))
17673 (match_scratch:SF 2 "r")]
17674 "! optimize_size && ! TARGET_PUSH_MEMORY"
17675 [(set (match_dup 2) (match_dup 1))
17676 (set (match_dup 0) (match_dup 2))]
17677 "")
17678
17679 (define_peephole2
17680 [(set (match_operand:HI 0 "push_operand" "")
17681 (match_operand:HI 1 "memory_operand" ""))
17682 (match_scratch:HI 2 "r")]
17683 "! optimize_size && ! TARGET_PUSH_MEMORY"
17684 [(set (match_dup 2) (match_dup 1))
17685 (set (match_dup 0) (match_dup 2))]
17686 "")
17687
17688 (define_peephole2
17689 [(set (match_operand:QI 0 "push_operand" "")
17690 (match_operand:QI 1 "memory_operand" ""))
17691 (match_scratch:QI 2 "q")]
17692 "! optimize_size && ! TARGET_PUSH_MEMORY"
17693 [(set (match_dup 2) (match_dup 1))
17694 (set (match_dup 0) (match_dup 2))]
17695 "")
17696
17697 ;; Don't move an immediate directly to memory when the instruction
17698 ;; gets too big.
17699 (define_peephole2
17700 [(match_scratch:SI 1 "r")
17701 (set (match_operand:SI 0 "memory_operand" "")
17702 (const_int 0))]
17703 "! optimize_size
17704 && ! TARGET_USE_MOV0
17705 && TARGET_SPLIT_LONG_MOVES
17706 && get_attr_length (insn) >= ix86_cost->large_insn
17707 && peep2_regno_dead_p (0, FLAGS_REG)"
17708 [(parallel [(set (match_dup 1) (const_int 0))
17709 (clobber (reg:CC 17))])
17710 (set (match_dup 0) (match_dup 1))]
17711 "")
17712
17713 (define_peephole2
17714 [(match_scratch:HI 1 "r")
17715 (set (match_operand:HI 0 "memory_operand" "")
17716 (const_int 0))]
17717 "! optimize_size
17718 && ! TARGET_USE_MOV0
17719 && TARGET_SPLIT_LONG_MOVES
17720 && get_attr_length (insn) >= ix86_cost->large_insn
17721 && peep2_regno_dead_p (0, FLAGS_REG)"
17722 [(parallel [(set (match_dup 2) (const_int 0))
17723 (clobber (reg:CC 17))])
17724 (set (match_dup 0) (match_dup 1))]
17725 "operands[2] = gen_lowpart (SImode, operands[1]);")
17726
17727 (define_peephole2
17728 [(match_scratch:QI 1 "q")
17729 (set (match_operand:QI 0 "memory_operand" "")
17730 (const_int 0))]
17731 "! optimize_size
17732 && ! TARGET_USE_MOV0
17733 && TARGET_SPLIT_LONG_MOVES
17734 && get_attr_length (insn) >= ix86_cost->large_insn
17735 && peep2_regno_dead_p (0, FLAGS_REG)"
17736 [(parallel [(set (match_dup 2) (const_int 0))
17737 (clobber (reg:CC 17))])
17738 (set (match_dup 0) (match_dup 1))]
17739 "operands[2] = gen_lowpart (SImode, operands[1]);")
17740
17741 (define_peephole2
17742 [(match_scratch:SI 2 "r")
17743 (set (match_operand:SI 0 "memory_operand" "")
17744 (match_operand:SI 1 "immediate_operand" ""))]
17745 "! optimize_size
17746 && get_attr_length (insn) >= ix86_cost->large_insn
17747 && TARGET_SPLIT_LONG_MOVES"
17748 [(set (match_dup 2) (match_dup 1))
17749 (set (match_dup 0) (match_dup 2))]
17750 "")
17751
17752 (define_peephole2
17753 [(match_scratch:HI 2 "r")
17754 (set (match_operand:HI 0 "memory_operand" "")
17755 (match_operand:HI 1 "immediate_operand" ""))]
17756 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17757 && TARGET_SPLIT_LONG_MOVES"
17758 [(set (match_dup 2) (match_dup 1))
17759 (set (match_dup 0) (match_dup 2))]
17760 "")
17761
17762 (define_peephole2
17763 [(match_scratch:QI 2 "q")
17764 (set (match_operand:QI 0 "memory_operand" "")
17765 (match_operand:QI 1 "immediate_operand" ""))]
17766 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17767 && TARGET_SPLIT_LONG_MOVES"
17768 [(set (match_dup 2) (match_dup 1))
17769 (set (match_dup 0) (match_dup 2))]
17770 "")
17771
17772 ;; Don't compare memory with zero, load and use a test instead.
17773 (define_peephole2
17774 [(set (reg 17)
17775 (compare (match_operand:SI 0 "memory_operand" "")
17776 (const_int 0)))
17777 (match_scratch:SI 3 "r")]
17778 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17779 [(set (match_dup 3) (match_dup 0))
17780 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17781 "")
17782
17783 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17784 ;; Don't split NOTs with a displacement operand, because resulting XOR
17785 ;; will not be pairable anyway.
17786 ;;
17787 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17788 ;; represented using a modRM byte. The XOR replacement is long decoded,
17789 ;; so this split helps here as well.
17790 ;;
17791 ;; Note: Can't do this as a regular split because we can't get proper
17792 ;; lifetime information then.
17793
17794 (define_peephole2
17795 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17796 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17797 "!optimize_size
17798 && peep2_regno_dead_p (0, FLAGS_REG)
17799 && ((TARGET_PENTIUM
17800 && (GET_CODE (operands[0]) != MEM
17801 || !memory_displacement_operand (operands[0], SImode)))
17802 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17803 [(parallel [(set (match_dup 0)
17804 (xor:SI (match_dup 1) (const_int -1)))
17805 (clobber (reg:CC 17))])]
17806 "")
17807
17808 (define_peephole2
17809 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17810 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17811 "!optimize_size
17812 && peep2_regno_dead_p (0, FLAGS_REG)
17813 && ((TARGET_PENTIUM
17814 && (GET_CODE (operands[0]) != MEM
17815 || !memory_displacement_operand (operands[0], HImode)))
17816 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17817 [(parallel [(set (match_dup 0)
17818 (xor:HI (match_dup 1) (const_int -1)))
17819 (clobber (reg:CC 17))])]
17820 "")
17821
17822 (define_peephole2
17823 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17824 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17825 "!optimize_size
17826 && peep2_regno_dead_p (0, FLAGS_REG)
17827 && ((TARGET_PENTIUM
17828 && (GET_CODE (operands[0]) != MEM
17829 || !memory_displacement_operand (operands[0], QImode)))
17830 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17831 [(parallel [(set (match_dup 0)
17832 (xor:QI (match_dup 1) (const_int -1)))
17833 (clobber (reg:CC 17))])]
17834 "")
17835
17836 ;; Non pairable "test imm, reg" instructions can be translated to
17837 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17838 ;; byte opcode instead of two, have a short form for byte operands),
17839 ;; so do it for other CPUs as well. Given that the value was dead,
17840 ;; this should not create any new dependencies. Pass on the sub-word
17841 ;; versions if we're concerned about partial register stalls.
17842
17843 (define_peephole2
17844 [(set (reg 17)
17845 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17846 (match_operand:SI 1 "immediate_operand" ""))
17847 (const_int 0)))]
17848 "ix86_match_ccmode (insn, CCNOmode)
17849 && (true_regnum (operands[0]) != 0
17850 || (GET_CODE (operands[1]) == CONST_INT
17851 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17852 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17853 [(parallel
17854 [(set (reg:CCNO 17)
17855 (compare:CCNO (and:SI (match_dup 0)
17856 (match_dup 1))
17857 (const_int 0)))
17858 (set (match_dup 0)
17859 (and:SI (match_dup 0) (match_dup 1)))])]
17860 "")
17861
17862 ;; We don't need to handle HImode case, because it will be promoted to SImode
17863 ;; on ! TARGET_PARTIAL_REG_STALL
17864
17865 (define_peephole2
17866 [(set (reg 17)
17867 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17868 (match_operand:QI 1 "immediate_operand" ""))
17869 (const_int 0)))]
17870 "! TARGET_PARTIAL_REG_STALL
17871 && ix86_match_ccmode (insn, CCNOmode)
17872 && true_regnum (operands[0]) != 0
17873 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17874 [(parallel
17875 [(set (reg:CCNO 17)
17876 (compare:CCNO (and:QI (match_dup 0)
17877 (match_dup 1))
17878 (const_int 0)))
17879 (set (match_dup 0)
17880 (and:QI (match_dup 0) (match_dup 1)))])]
17881 "")
17882
17883 (define_peephole2
17884 [(set (reg 17)
17885 (compare
17886 (and:SI
17887 (zero_extract:SI
17888 (match_operand 0 "ext_register_operand" "")
17889 (const_int 8)
17890 (const_int 8))
17891 (match_operand 1 "const_int_operand" ""))
17892 (const_int 0)))]
17893 "! TARGET_PARTIAL_REG_STALL
17894 && ix86_match_ccmode (insn, CCNOmode)
17895 && true_regnum (operands[0]) != 0
17896 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17897 [(parallel [(set (reg:CCNO 17)
17898 (compare:CCNO
17899 (and:SI
17900 (zero_extract:SI
17901 (match_dup 0)
17902 (const_int 8)
17903 (const_int 8))
17904 (match_dup 1))
17905 (const_int 0)))
17906 (set (zero_extract:SI (match_dup 0)
17907 (const_int 8)
17908 (const_int 8))
17909 (and:SI
17910 (zero_extract:SI
17911 (match_dup 0)
17912 (const_int 8)
17913 (const_int 8))
17914 (match_dup 1)))])]
17915 "")
17916
17917 ;; Don't do logical operations with memory inputs.
17918 (define_peephole2
17919 [(match_scratch:SI 2 "r")
17920 (parallel [(set (match_operand:SI 0 "register_operand" "")
17921 (match_operator:SI 3 "arith_or_logical_operator"
17922 [(match_dup 0)
17923 (match_operand:SI 1 "memory_operand" "")]))
17924 (clobber (reg:CC 17))])]
17925 "! optimize_size && ! TARGET_READ_MODIFY"
17926 [(set (match_dup 2) (match_dup 1))
17927 (parallel [(set (match_dup 0)
17928 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17929 (clobber (reg:CC 17))])]
17930 "")
17931
17932 (define_peephole2
17933 [(match_scratch:SI 2 "r")
17934 (parallel [(set (match_operand:SI 0 "register_operand" "")
17935 (match_operator:SI 3 "arith_or_logical_operator"
17936 [(match_operand:SI 1 "memory_operand" "")
17937 (match_dup 0)]))
17938 (clobber (reg:CC 17))])]
17939 "! optimize_size && ! TARGET_READ_MODIFY"
17940 [(set (match_dup 2) (match_dup 1))
17941 (parallel [(set (match_dup 0)
17942 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17943 (clobber (reg:CC 17))])]
17944 "")
17945
17946 ; Don't do logical operations with memory outputs
17947 ;
17948 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17949 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17950 ; the same decoder scheduling characteristics as the original.
17951
17952 (define_peephole2
17953 [(match_scratch:SI 2 "r")
17954 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17955 (match_operator:SI 3 "arith_or_logical_operator"
17956 [(match_dup 0)
17957 (match_operand:SI 1 "nonmemory_operand" "")]))
17958 (clobber (reg:CC 17))])]
17959 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17960 [(set (match_dup 2) (match_dup 0))
17961 (parallel [(set (match_dup 2)
17962 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17963 (clobber (reg:CC 17))])
17964 (set (match_dup 0) (match_dup 2))]
17965 "")
17966
17967 (define_peephole2
17968 [(match_scratch:SI 2 "r")
17969 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17970 (match_operator:SI 3 "arith_or_logical_operator"
17971 [(match_operand:SI 1 "nonmemory_operand" "")
17972 (match_dup 0)]))
17973 (clobber (reg:CC 17))])]
17974 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17975 [(set (match_dup 2) (match_dup 0))
17976 (parallel [(set (match_dup 2)
17977 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17978 (clobber (reg:CC 17))])
17979 (set (match_dup 0) (match_dup 2))]
17980 "")
17981
17982 ;; Attempt to always use XOR for zeroing registers.
17983 (define_peephole2
17984 [(set (match_operand 0 "register_operand" "")
17985 (const_int 0))]
17986 "(GET_MODE (operands[0]) == QImode
17987 || GET_MODE (operands[0]) == HImode
17988 || GET_MODE (operands[0]) == SImode
17989 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17990 && (! TARGET_USE_MOV0 || optimize_size)
17991 && peep2_regno_dead_p (0, FLAGS_REG)"
17992 [(parallel [(set (match_dup 0) (const_int 0))
17993 (clobber (reg:CC 17))])]
17994 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17995 operands[0]);")
17996
17997 (define_peephole2
17998 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17999 (const_int 0))]
18000 "(GET_MODE (operands[0]) == QImode
18001 || GET_MODE (operands[0]) == HImode)
18002 && (! TARGET_USE_MOV0 || optimize_size)
18003 && peep2_regno_dead_p (0, FLAGS_REG)"
18004 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18005 (clobber (reg:CC 17))])])
18006
18007 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18008 (define_peephole2
18009 [(set (match_operand 0 "register_operand" "")
18010 (const_int -1))]
18011 "(GET_MODE (operands[0]) == HImode
18012 || GET_MODE (operands[0]) == SImode
18013 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18014 && (optimize_size || TARGET_PENTIUM)
18015 && peep2_regno_dead_p (0, FLAGS_REG)"
18016 [(parallel [(set (match_dup 0) (const_int -1))
18017 (clobber (reg:CC 17))])]
18018 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18019 operands[0]);")
18020
18021 ;; Attempt to convert simple leas to adds. These can be created by
18022 ;; move expanders.
18023 (define_peephole2
18024 [(set (match_operand:SI 0 "register_operand" "")
18025 (plus:SI (match_dup 0)
18026 (match_operand:SI 1 "nonmemory_operand" "")))]
18027 "peep2_regno_dead_p (0, FLAGS_REG)"
18028 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18029 (clobber (reg:CC 17))])]
18030 "")
18031
18032 (define_peephole2
18033 [(set (match_operand:SI 0 "register_operand" "")
18034 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18035 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18036 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18037 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18038 (clobber (reg:CC 17))])]
18039 "operands[2] = gen_lowpart (SImode, operands[2]);")
18040
18041 (define_peephole2
18042 [(set (match_operand:DI 0 "register_operand" "")
18043 (plus:DI (match_dup 0)
18044 (match_operand:DI 1 "x86_64_general_operand" "")))]
18045 "peep2_regno_dead_p (0, FLAGS_REG)"
18046 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18047 (clobber (reg:CC 17))])]
18048 "")
18049
18050 (define_peephole2
18051 [(set (match_operand:SI 0 "register_operand" "")
18052 (mult:SI (match_dup 0)
18053 (match_operand:SI 1 "const_int_operand" "")))]
18054 "exact_log2 (INTVAL (operands[1])) >= 0
18055 && peep2_regno_dead_p (0, FLAGS_REG)"
18056 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18057 (clobber (reg:CC 17))])]
18058 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18059
18060 (define_peephole2
18061 [(set (match_operand:DI 0 "register_operand" "")
18062 (mult:DI (match_dup 0)
18063 (match_operand:DI 1 "const_int_operand" "")))]
18064 "exact_log2 (INTVAL (operands[1])) >= 0
18065 && peep2_regno_dead_p (0, FLAGS_REG)"
18066 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18067 (clobber (reg:CC 17))])]
18068 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18069
18070 (define_peephole2
18071 [(set (match_operand:SI 0 "register_operand" "")
18072 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18073 (match_operand:DI 2 "const_int_operand" "")) 0))]
18074 "exact_log2 (INTVAL (operands[2])) >= 0
18075 && REGNO (operands[0]) == REGNO (operands[1])
18076 && peep2_regno_dead_p (0, FLAGS_REG)"
18077 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18078 (clobber (reg:CC 17))])]
18079 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18080
18081 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18082 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18083 ;; many CPUs it is also faster, since special hardware to avoid esp
18084 ;; dependencies is present.
18085
18086 ;; While some of these conversions may be done using splitters, we use peepholes
18087 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18088
18089 ;; Convert prologue esp subtractions to push.
18090 ;; We need register to push. In order to keep verify_flow_info happy we have
18091 ;; two choices
18092 ;; - use scratch and clobber it in order to avoid dependencies
18093 ;; - use already live register
18094 ;; We can't use the second way right now, since there is no reliable way how to
18095 ;; verify that given register is live. First choice will also most likely in
18096 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18097 ;; call clobbered registers are dead. We may want to use base pointer as an
18098 ;; alternative when no register is available later.
18099
18100 (define_peephole2
18101 [(match_scratch:SI 0 "r")
18102 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18103 (clobber (reg:CC 17))
18104 (clobber (mem:BLK (scratch)))])]
18105 "optimize_size || !TARGET_SUB_ESP_4"
18106 [(clobber (match_dup 0))
18107 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18108 (clobber (mem:BLK (scratch)))])])
18109
18110 (define_peephole2
18111 [(match_scratch:SI 0 "r")
18112 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18113 (clobber (reg:CC 17))
18114 (clobber (mem:BLK (scratch)))])]
18115 "optimize_size || !TARGET_SUB_ESP_8"
18116 [(clobber (match_dup 0))
18117 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18118 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18119 (clobber (mem:BLK (scratch)))])])
18120
18121 ;; Convert esp subtractions to push.
18122 (define_peephole2
18123 [(match_scratch:SI 0 "r")
18124 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18125 (clobber (reg:CC 17))])]
18126 "optimize_size || !TARGET_SUB_ESP_4"
18127 [(clobber (match_dup 0))
18128 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18129
18130 (define_peephole2
18131 [(match_scratch:SI 0 "r")
18132 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18133 (clobber (reg:CC 17))])]
18134 "optimize_size || !TARGET_SUB_ESP_8"
18135 [(clobber (match_dup 0))
18136 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18137 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18138
18139 ;; Convert epilogue deallocator to pop.
18140 (define_peephole2
18141 [(match_scratch:SI 0 "r")
18142 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18143 (clobber (reg:CC 17))
18144 (clobber (mem:BLK (scratch)))])]
18145 "optimize_size || !TARGET_ADD_ESP_4"
18146 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18147 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18148 (clobber (mem:BLK (scratch)))])]
18149 "")
18150
18151 ;; Two pops case is tricky, since pop causes dependency on destination register.
18152 ;; We use two registers if available.
18153 (define_peephole2
18154 [(match_scratch:SI 0 "r")
18155 (match_scratch:SI 1 "r")
18156 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18157 (clobber (reg:CC 17))
18158 (clobber (mem:BLK (scratch)))])]
18159 "optimize_size || !TARGET_ADD_ESP_8"
18160 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18161 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18162 (clobber (mem:BLK (scratch)))])
18163 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18164 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18165 "")
18166
18167 (define_peephole2
18168 [(match_scratch:SI 0 "r")
18169 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18170 (clobber (reg:CC 17))
18171 (clobber (mem:BLK (scratch)))])]
18172 "optimize_size"
18173 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18174 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18175 (clobber (mem:BLK (scratch)))])
18176 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18177 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18178 "")
18179
18180 ;; Convert esp additions to pop.
18181 (define_peephole2
18182 [(match_scratch:SI 0 "r")
18183 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18184 (clobber (reg:CC 17))])]
18185 ""
18186 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18187 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18188 "")
18189
18190 ;; Two pops case is tricky, since pop causes dependency on destination register.
18191 ;; We use two registers if available.
18192 (define_peephole2
18193 [(match_scratch:SI 0 "r")
18194 (match_scratch:SI 1 "r")
18195 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18196 (clobber (reg:CC 17))])]
18197 ""
18198 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18199 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18200 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18201 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18202 "")
18203
18204 (define_peephole2
18205 [(match_scratch:SI 0 "r")
18206 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18207 (clobber (reg:CC 17))])]
18208 "optimize_size"
18209 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18210 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18211 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18212 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18213 "")
18214 \f
18215 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18216 ;; required and register dies.
18217 (define_peephole2
18218 [(set (reg 17)
18219 (compare (match_operand:SI 0 "register_operand" "")
18220 (match_operand:SI 1 "incdec_operand" "")))]
18221 "ix86_match_ccmode (insn, CCGCmode)
18222 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18223 [(parallel [(set (reg:CCGC 17)
18224 (compare:CCGC (match_dup 0)
18225 (match_dup 1)))
18226 (clobber (match_dup 0))])]
18227 "")
18228
18229 (define_peephole2
18230 [(set (reg 17)
18231 (compare (match_operand:HI 0 "register_operand" "")
18232 (match_operand:HI 1 "incdec_operand" "")))]
18233 "ix86_match_ccmode (insn, CCGCmode)
18234 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18235 [(parallel [(set (reg:CCGC 17)
18236 (compare:CCGC (match_dup 0)
18237 (match_dup 1)))
18238 (clobber (match_dup 0))])]
18239 "")
18240
18241 (define_peephole2
18242 [(set (reg 17)
18243 (compare (match_operand:QI 0 "register_operand" "")
18244 (match_operand:QI 1 "incdec_operand" "")))]
18245 "ix86_match_ccmode (insn, CCGCmode)
18246 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18247 [(parallel [(set (reg:CCGC 17)
18248 (compare:CCGC (match_dup 0)
18249 (match_dup 1)))
18250 (clobber (match_dup 0))])]
18251 "")
18252
18253 ;; Convert compares with 128 to shorter add -128
18254 (define_peephole2
18255 [(set (reg 17)
18256 (compare (match_operand:SI 0 "register_operand" "")
18257 (const_int 128)))]
18258 "ix86_match_ccmode (insn, CCGCmode)
18259 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18260 [(parallel [(set (reg:CCGC 17)
18261 (compare:CCGC (match_dup 0)
18262 (const_int 128)))
18263 (clobber (match_dup 0))])]
18264 "")
18265
18266 (define_peephole2
18267 [(set (reg 17)
18268 (compare (match_operand:HI 0 "register_operand" "")
18269 (const_int 128)))]
18270 "ix86_match_ccmode (insn, CCGCmode)
18271 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18272 [(parallel [(set (reg:CCGC 17)
18273 (compare:CCGC (match_dup 0)
18274 (const_int 128)))
18275 (clobber (match_dup 0))])]
18276 "")
18277 \f
18278 (define_peephole2
18279 [(match_scratch:DI 0 "r")
18280 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18281 (clobber (reg:CC 17))
18282 (clobber (mem:BLK (scratch)))])]
18283 "optimize_size || !TARGET_SUB_ESP_4"
18284 [(clobber (match_dup 0))
18285 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18286 (clobber (mem:BLK (scratch)))])])
18287
18288 (define_peephole2
18289 [(match_scratch:DI 0 "r")
18290 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18291 (clobber (reg:CC 17))
18292 (clobber (mem:BLK (scratch)))])]
18293 "optimize_size || !TARGET_SUB_ESP_8"
18294 [(clobber (match_dup 0))
18295 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18296 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18297 (clobber (mem:BLK (scratch)))])])
18298
18299 ;; Convert esp subtractions to push.
18300 (define_peephole2
18301 [(match_scratch:DI 0 "r")
18302 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18303 (clobber (reg:CC 17))])]
18304 "optimize_size || !TARGET_SUB_ESP_4"
18305 [(clobber (match_dup 0))
18306 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18307
18308 (define_peephole2
18309 [(match_scratch:DI 0 "r")
18310 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18311 (clobber (reg:CC 17))])]
18312 "optimize_size || !TARGET_SUB_ESP_8"
18313 [(clobber (match_dup 0))
18314 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18315 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18316
18317 ;; Convert epilogue deallocator to pop.
18318 (define_peephole2
18319 [(match_scratch:DI 0 "r")
18320 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18321 (clobber (reg:CC 17))
18322 (clobber (mem:BLK (scratch)))])]
18323 "optimize_size || !TARGET_ADD_ESP_4"
18324 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18325 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18326 (clobber (mem:BLK (scratch)))])]
18327 "")
18328
18329 ;; Two pops case is tricky, since pop causes dependency on destination register.
18330 ;; We use two registers if available.
18331 (define_peephole2
18332 [(match_scratch:DI 0 "r")
18333 (match_scratch:DI 1 "r")
18334 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18335 (clobber (reg:CC 17))
18336 (clobber (mem:BLK (scratch)))])]
18337 "optimize_size || !TARGET_ADD_ESP_8"
18338 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18339 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18340 (clobber (mem:BLK (scratch)))])
18341 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18342 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18343 "")
18344
18345 (define_peephole2
18346 [(match_scratch:DI 0 "r")
18347 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18348 (clobber (reg:CC 17))
18349 (clobber (mem:BLK (scratch)))])]
18350 "optimize_size"
18351 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18352 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18353 (clobber (mem:BLK (scratch)))])
18354 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18355 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18356 "")
18357
18358 ;; Convert esp additions to pop.
18359 (define_peephole2
18360 [(match_scratch:DI 0 "r")
18361 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18362 (clobber (reg:CC 17))])]
18363 ""
18364 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18365 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18366 "")
18367
18368 ;; Two pops case is tricky, since pop causes dependency on destination register.
18369 ;; We use two registers if available.
18370 (define_peephole2
18371 [(match_scratch:DI 0 "r")
18372 (match_scratch:DI 1 "r")
18373 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18374 (clobber (reg:CC 17))])]
18375 ""
18376 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18377 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18378 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18379 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18380 "")
18381
18382 (define_peephole2
18383 [(match_scratch:DI 0 "r")
18384 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18385 (clobber (reg:CC 17))])]
18386 "optimize_size"
18387 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18388 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18389 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18390 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18391 "")
18392 \f
18393 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18394 ;; imul $32bit_imm, reg, reg is direct decoded.
18395 (define_peephole2
18396 [(match_scratch:DI 3 "r")
18397 (parallel [(set (match_operand:DI 0 "register_operand" "")
18398 (mult:DI (match_operand:DI 1 "memory_operand" "")
18399 (match_operand:DI 2 "immediate_operand" "")))
18400 (clobber (reg:CC 17))])]
18401 "TARGET_K8 && !optimize_size
18402 && (GET_CODE (operands[2]) != CONST_INT
18403 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18404 [(set (match_dup 3) (match_dup 1))
18405 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18406 (clobber (reg:CC 17))])]
18407 "")
18408
18409 (define_peephole2
18410 [(match_scratch:SI 3 "r")
18411 (parallel [(set (match_operand:SI 0 "register_operand" "")
18412 (mult:SI (match_operand:SI 1 "memory_operand" "")
18413 (match_operand:SI 2 "immediate_operand" "")))
18414 (clobber (reg:CC 17))])]
18415 "TARGET_K8 && !optimize_size
18416 && (GET_CODE (operands[2]) != CONST_INT
18417 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18418 [(set (match_dup 3) (match_dup 1))
18419 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18420 (clobber (reg:CC 17))])]
18421 "")
18422
18423 (define_peephole2
18424 [(match_scratch:SI 3 "r")
18425 (parallel [(set (match_operand:DI 0 "register_operand" "")
18426 (zero_extend:DI
18427 (mult:SI (match_operand:SI 1 "memory_operand" "")
18428 (match_operand:SI 2 "immediate_operand" ""))))
18429 (clobber (reg:CC 17))])]
18430 "TARGET_K8 && !optimize_size
18431 && (GET_CODE (operands[2]) != CONST_INT
18432 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18433 [(set (match_dup 3) (match_dup 1))
18434 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18435 (clobber (reg:CC 17))])]
18436 "")
18437
18438 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18439 ;; Convert it into imul reg, reg
18440 ;; It would be better to force assembler to encode instruction using long
18441 ;; immediate, but there is apparently no way to do so.
18442 (define_peephole2
18443 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18444 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18445 (match_operand:DI 2 "const_int_operand" "")))
18446 (clobber (reg:CC 17))])
18447 (match_scratch:DI 3 "r")]
18448 "TARGET_K8 && !optimize_size
18449 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18450 [(set (match_dup 3) (match_dup 2))
18451 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18452 (clobber (reg:CC 17))])]
18453 {
18454 if (!rtx_equal_p (operands[0], operands[1]))
18455 emit_move_insn (operands[0], operands[1]);
18456 })
18457
18458 (define_peephole2
18459 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18460 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18461 (match_operand:SI 2 "const_int_operand" "")))
18462 (clobber (reg:CC 17))])
18463 (match_scratch:SI 3 "r")]
18464 "TARGET_K8 && !optimize_size
18465 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18466 [(set (match_dup 3) (match_dup 2))
18467 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18468 (clobber (reg:CC 17))])]
18469 {
18470 if (!rtx_equal_p (operands[0], operands[1]))
18471 emit_move_insn (operands[0], operands[1]);
18472 })
18473
18474 (define_peephole2
18475 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18476 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18477 (match_operand:HI 2 "immediate_operand" "")))
18478 (clobber (reg:CC 17))])
18479 (match_scratch:HI 3 "r")]
18480 "TARGET_K8 && !optimize_size"
18481 [(set (match_dup 3) (match_dup 2))
18482 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18483 (clobber (reg:CC 17))])]
18484 {
18485 if (!rtx_equal_p (operands[0], operands[1]))
18486 emit_move_insn (operands[0], operands[1]);
18487 })
18488 \f
18489 ;; Call-value patterns last so that the wildcard operand does not
18490 ;; disrupt insn-recog's switch tables.
18491
18492 (define_insn "*call_value_pop_0"
18493 [(set (match_operand 0 "" "")
18494 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18495 (match_operand:SI 2 "" "")))
18496 (set (reg:SI 7) (plus:SI (reg:SI 7)
18497 (match_operand:SI 3 "immediate_operand" "")))]
18498 "!TARGET_64BIT"
18499 {
18500 if (SIBLING_CALL_P (insn))
18501 return "jmp\t%P1";
18502 else
18503 return "call\t%P1";
18504 }
18505 [(set_attr "type" "callv")])
18506
18507 (define_insn "*call_value_pop_1"
18508 [(set (match_operand 0 "" "")
18509 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18510 (match_operand:SI 2 "" "")))
18511 (set (reg:SI 7) (plus:SI (reg:SI 7)
18512 (match_operand:SI 3 "immediate_operand" "i")))]
18513 "!TARGET_64BIT"
18514 {
18515 if (constant_call_address_operand (operands[1], QImode))
18516 {
18517 if (SIBLING_CALL_P (insn))
18518 return "jmp\t%P1";
18519 else
18520 return "call\t%P1";
18521 }
18522 if (SIBLING_CALL_P (insn))
18523 return "jmp\t%A1";
18524 else
18525 return "call\t%A1";
18526 }
18527 [(set_attr "type" "callv")])
18528
18529 (define_insn "*call_value_0"
18530 [(set (match_operand 0 "" "")
18531 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18532 (match_operand:SI 2 "" "")))]
18533 "!TARGET_64BIT"
18534 {
18535 if (SIBLING_CALL_P (insn))
18536 return "jmp\t%P1";
18537 else
18538 return "call\t%P1";
18539 }
18540 [(set_attr "type" "callv")])
18541
18542 (define_insn "*call_value_0_rex64"
18543 [(set (match_operand 0 "" "")
18544 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18545 (match_operand:DI 2 "const_int_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_1"
18556 [(set (match_operand 0 "" "")
18557 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18558 (match_operand:SI 2 "" "")))]
18559 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18560 {
18561 if (constant_call_address_operand (operands[1], QImode))
18562 return "call\t%P1";
18563 return "call\t%*%1";
18564 }
18565 [(set_attr "type" "callv")])
18566
18567 (define_insn "*sibcall_value_1"
18568 [(set (match_operand 0 "" "")
18569 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18570 (match_operand:SI 2 "" "")))]
18571 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18572 {
18573 if (constant_call_address_operand (operands[1], QImode))
18574 return "jmp\t%P1";
18575 return "jmp\t%*%1";
18576 }
18577 [(set_attr "type" "callv")])
18578
18579 (define_insn "*call_value_1_rex64"
18580 [(set (match_operand 0 "" "")
18581 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18582 (match_operand:DI 2 "" "")))]
18583 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18584 {
18585 if (constant_call_address_operand (operands[1], QImode))
18586 return "call\t%P1";
18587 return "call\t%A1";
18588 }
18589 [(set_attr "type" "callv")])
18590
18591 (define_insn "*sibcall_value_1_rex64"
18592 [(set (match_operand 0 "" "")
18593 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18594 (match_operand:DI 2 "" "")))]
18595 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18596 "jmp\t%P1"
18597 [(set_attr "type" "callv")])
18598
18599 (define_insn "*sibcall_value_1_rex64_v"
18600 [(set (match_operand 0 "" "")
18601 (call (mem:QI (reg:DI 40))
18602 (match_operand:DI 1 "" "")))]
18603 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18604 "jmp\t*%%r11"
18605 [(set_attr "type" "callv")])
18606 \f
18607 (define_insn "trap"
18608 [(trap_if (const_int 1) (const_int 5))]
18609 ""
18610 "int\t$5")
18611
18612 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18613 ;;; for the sake of bounds checking. By emitting bounds checks as
18614 ;;; conditional traps rather than as conditional jumps around
18615 ;;; unconditional traps we avoid introducing spurious basic-block
18616 ;;; boundaries and facilitate elimination of redundant checks. In
18617 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18618 ;;; interrupt 5.
18619 ;;;
18620 ;;; FIXME: Static branch prediction rules for ix86 are such that
18621 ;;; forward conditional branches predict as untaken. As implemented
18622 ;;; below, pseudo conditional traps violate that rule. We should use
18623 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18624 ;;; section loaded at the end of the text segment and branch forward
18625 ;;; there on bounds-failure, and then jump back immediately (in case
18626 ;;; the system chooses to ignore bounds violations, or to report
18627 ;;; violations and continue execution).
18628
18629 (define_expand "conditional_trap"
18630 [(trap_if (match_operator 0 "comparison_operator"
18631 [(match_dup 2) (const_int 0)])
18632 (match_operand 1 "const_int_operand" ""))]
18633 ""
18634 {
18635 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18636 ix86_expand_compare (GET_CODE (operands[0]),
18637 NULL, NULL),
18638 operands[1]));
18639 DONE;
18640 })
18641
18642 (define_insn "*conditional_trap_1"
18643 [(trap_if (match_operator 0 "comparison_operator"
18644 [(reg 17) (const_int 0)])
18645 (match_operand 1 "const_int_operand" ""))]
18646 ""
18647 {
18648 operands[2] = gen_label_rtx ();
18649 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18650 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18651 CODE_LABEL_NUMBER (operands[2]));
18652 RET;
18653 })
18654
18655 ;; Pentium III SIMD instructions.
18656
18657 ;; Moves for SSE/MMX regs.
18658
18659 (define_insn "movv4sf_internal"
18660 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18661 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18662 "TARGET_SSE"
18663 "@
18664 xorps\t%0, %0
18665 movaps\t{%1, %0|%0, %1}
18666 movaps\t{%1, %0|%0, %1}"
18667 [(set_attr "type" "ssemov")
18668 (set_attr "mode" "V4SF")])
18669
18670 (define_split
18671 [(set (match_operand:V4SF 0 "register_operand" "")
18672 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18673 "TARGET_SSE"
18674 [(set (match_dup 0)
18675 (vec_merge:V4SF
18676 (vec_duplicate:V4SF (match_dup 1))
18677 (match_dup 2)
18678 (const_int 1)))]
18679 {
18680 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18681 operands[2] = CONST0_RTX (V4SFmode);
18682 })
18683
18684 (define_insn "movv4si_internal"
18685 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18686 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18687 "TARGET_SSE"
18688 {
18689 switch (which_alternative)
18690 {
18691 case 0:
18692 if (get_attr_mode (insn) == MODE_V4SF)
18693 return "xorps\t%0, %0";
18694 else
18695 return "pxor\t%0, %0";
18696 case 1:
18697 case 2:
18698 if (get_attr_mode (insn) == MODE_V4SF)
18699 return "movaps\t{%1, %0|%0, %1}";
18700 else
18701 return "movdqa\t{%1, %0|%0, %1}";
18702 default:
18703 abort ();
18704 }
18705 }
18706 [(set_attr "type" "ssemov")
18707 (set (attr "mode")
18708 (cond [(eq_attr "alternative" "0,1")
18709 (if_then_else
18710 (ne (symbol_ref "optimize_size")
18711 (const_int 0))
18712 (const_string "V4SF")
18713 (const_string "TI"))
18714 (eq_attr "alternative" "2")
18715 (if_then_else
18716 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18717 (const_int 0))
18718 (ne (symbol_ref "optimize_size")
18719 (const_int 0)))
18720 (const_string "V4SF")
18721 (const_string "TI"))]
18722 (const_string "TI")))])
18723
18724 (define_insn "movv2di_internal"
18725 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18726 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18727 "TARGET_SSE"
18728 {
18729 switch (which_alternative)
18730 {
18731 case 0:
18732 if (get_attr_mode (insn) == MODE_V4SF)
18733 return "xorps\t%0, %0";
18734 else
18735 return "pxor\t%0, %0";
18736 case 1:
18737 case 2:
18738 if (get_attr_mode (insn) == MODE_V4SF)
18739 return "movaps\t{%1, %0|%0, %1}";
18740 else
18741 return "movdqa\t{%1, %0|%0, %1}";
18742 default:
18743 abort ();
18744 }
18745 }
18746 [(set_attr "type" "ssemov")
18747 (set (attr "mode")
18748 (cond [(eq_attr "alternative" "0,1")
18749 (if_then_else
18750 (ne (symbol_ref "optimize_size")
18751 (const_int 0))
18752 (const_string "V4SF")
18753 (const_string "TI"))
18754 (eq_attr "alternative" "2")
18755 (if_then_else
18756 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18757 (const_int 0))
18758 (ne (symbol_ref "optimize_size")
18759 (const_int 0)))
18760 (const_string "V4SF")
18761 (const_string "TI"))]
18762 (const_string "TI")))])
18763
18764 (define_split
18765 [(set (match_operand:V2DF 0 "register_operand" "")
18766 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18767 "TARGET_SSE2"
18768 [(set (match_dup 0)
18769 (vec_merge:V2DF
18770 (vec_duplicate:V2DF (match_dup 1))
18771 (match_dup 2)
18772 (const_int 1)))]
18773 {
18774 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18775 operands[2] = CONST0_RTX (V2DFmode);
18776 })
18777
18778 (define_insn "movv8qi_internal"
18779 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18780 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18781 "TARGET_MMX
18782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18783 "@
18784 pxor\t%0, %0
18785 movq\t{%1, %0|%0, %1}
18786 movq\t{%1, %0|%0, %1}"
18787 [(set_attr "type" "mmxmov")
18788 (set_attr "mode" "DI")])
18789
18790 (define_insn "movv4hi_internal"
18791 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18792 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18793 "TARGET_MMX
18794 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18795 "@
18796 pxor\t%0, %0
18797 movq\t{%1, %0|%0, %1}
18798 movq\t{%1, %0|%0, %1}"
18799 [(set_attr "type" "mmxmov")
18800 (set_attr "mode" "DI")])
18801
18802 (define_insn "movv2si_internal"
18803 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18804 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18805 "TARGET_MMX
18806 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18807 "@
18808 pxor\t%0, %0
18809 movq\t{%1, %0|%0, %1}
18810 movq\t{%1, %0|%0, %1}"
18811 [(set_attr "type" "mmxcvt")
18812 (set_attr "mode" "DI")])
18813
18814 (define_insn "movv2sf_internal"
18815 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18816 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18817 "TARGET_3DNOW
18818 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18819 "@
18820 pxor\t%0, %0
18821 movq\t{%1, %0|%0, %1}
18822 movq\t{%1, %0|%0, %1}"
18823 [(set_attr "type" "mmxcvt")
18824 (set_attr "mode" "DI")])
18825
18826 (define_expand "movti"
18827 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18828 (match_operand:TI 1 "nonimmediate_operand" ""))]
18829 "TARGET_SSE || TARGET_64BIT"
18830 {
18831 if (TARGET_64BIT)
18832 ix86_expand_move (TImode, operands);
18833 else
18834 ix86_expand_vector_move (TImode, operands);
18835 DONE;
18836 })
18837
18838 (define_expand "movtf"
18839 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18840 (match_operand:TF 1 "nonimmediate_operand" ""))]
18841 "TARGET_64BIT"
18842 {
18843 if (TARGET_64BIT)
18844 ix86_expand_move (TFmode, operands);
18845 else
18846 ix86_expand_vector_move (TFmode, operands);
18847 DONE;
18848 })
18849
18850 (define_insn "movv2df_internal"
18851 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18852 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18853 "TARGET_SSE2
18854 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18855 {
18856 switch (which_alternative)
18857 {
18858 case 0:
18859 if (get_attr_mode (insn) == MODE_V4SF)
18860 return "xorps\t%0, %0";
18861 else
18862 return "xorpd\t%0, %0";
18863 case 1:
18864 case 2:
18865 if (get_attr_mode (insn) == MODE_V4SF)
18866 return "movaps\t{%1, %0|%0, %1}";
18867 else
18868 return "movapd\t{%1, %0|%0, %1}";
18869 default:
18870 abort ();
18871 }
18872 }
18873 [(set_attr "type" "ssemov")
18874 (set (attr "mode")
18875 (cond [(eq_attr "alternative" "0,1")
18876 (if_then_else
18877 (ne (symbol_ref "optimize_size")
18878 (const_int 0))
18879 (const_string "V4SF")
18880 (const_string "V2DF"))
18881 (eq_attr "alternative" "2")
18882 (if_then_else
18883 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18884 (const_int 0))
18885 (ne (symbol_ref "optimize_size")
18886 (const_int 0)))
18887 (const_string "V4SF")
18888 (const_string "V2DF"))]
18889 (const_string "V2DF")))])
18890
18891 (define_insn "movv8hi_internal"
18892 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18893 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18894 "TARGET_SSE2
18895 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18896 {
18897 switch (which_alternative)
18898 {
18899 case 0:
18900 if (get_attr_mode (insn) == MODE_V4SF)
18901 return "xorps\t%0, %0";
18902 else
18903 return "pxor\t%0, %0";
18904 case 1:
18905 case 2:
18906 if (get_attr_mode (insn) == MODE_V4SF)
18907 return "movaps\t{%1, %0|%0, %1}";
18908 else
18909 return "movdqa\t{%1, %0|%0, %1}";
18910 default:
18911 abort ();
18912 }
18913 }
18914 [(set_attr "type" "ssemov")
18915 (set (attr "mode")
18916 (cond [(eq_attr "alternative" "0,1")
18917 (if_then_else
18918 (ne (symbol_ref "optimize_size")
18919 (const_int 0))
18920 (const_string "V4SF")
18921 (const_string "TI"))
18922 (eq_attr "alternative" "2")
18923 (if_then_else
18924 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18925 (const_int 0))
18926 (ne (symbol_ref "optimize_size")
18927 (const_int 0)))
18928 (const_string "V4SF")
18929 (const_string "TI"))]
18930 (const_string "TI")))])
18931
18932 (define_insn "movv16qi_internal"
18933 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18934 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18935 "TARGET_SSE2
18936 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18937 {
18938 switch (which_alternative)
18939 {
18940 case 0:
18941 if (get_attr_mode (insn) == MODE_V4SF)
18942 return "xorps\t%0, %0";
18943 else
18944 return "pxor\t%0, %0";
18945 case 1:
18946 case 2:
18947 if (get_attr_mode (insn) == MODE_V4SF)
18948 return "movaps\t{%1, %0|%0, %1}";
18949 else
18950 return "movdqa\t{%1, %0|%0, %1}";
18951 default:
18952 abort ();
18953 }
18954 }
18955 [(set_attr "type" "ssemov")
18956 (set (attr "mode")
18957 (cond [(eq_attr "alternative" "0,1")
18958 (if_then_else
18959 (ne (symbol_ref "optimize_size")
18960 (const_int 0))
18961 (const_string "V4SF")
18962 (const_string "TI"))
18963 (eq_attr "alternative" "2")
18964 (if_then_else
18965 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18966 (const_int 0))
18967 (ne (symbol_ref "optimize_size")
18968 (const_int 0)))
18969 (const_string "V4SF")
18970 (const_string "TI"))]
18971 (const_string "TI")))])
18972
18973 (define_expand "movv2df"
18974 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18975 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18976 "TARGET_SSE2"
18977 {
18978 ix86_expand_vector_move (V2DFmode, operands);
18979 DONE;
18980 })
18981
18982 (define_expand "movv8hi"
18983 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18984 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18985 "TARGET_SSE2"
18986 {
18987 ix86_expand_vector_move (V8HImode, operands);
18988 DONE;
18989 })
18990
18991 (define_expand "movv16qi"
18992 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18993 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18994 "TARGET_SSE2"
18995 {
18996 ix86_expand_vector_move (V16QImode, operands);
18997 DONE;
18998 })
18999
19000 (define_expand "movv4sf"
19001 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19002 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19003 "TARGET_SSE"
19004 {
19005 ix86_expand_vector_move (V4SFmode, operands);
19006 DONE;
19007 })
19008
19009 (define_expand "movv4si"
19010 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19011 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19012 "TARGET_SSE"
19013 {
19014 ix86_expand_vector_move (V4SImode, operands);
19015 DONE;
19016 })
19017
19018 (define_expand "movv2di"
19019 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19020 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19021 "TARGET_SSE"
19022 {
19023 ix86_expand_vector_move (V2DImode, operands);
19024 DONE;
19025 })
19026
19027 (define_expand "movv2si"
19028 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19029 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19030 "TARGET_MMX"
19031 {
19032 ix86_expand_vector_move (V2SImode, operands);
19033 DONE;
19034 })
19035
19036 (define_expand "movv4hi"
19037 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19038 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19039 "TARGET_MMX"
19040 {
19041 ix86_expand_vector_move (V4HImode, operands);
19042 DONE;
19043 })
19044
19045 (define_expand "movv8qi"
19046 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19047 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19048 "TARGET_MMX"
19049 {
19050 ix86_expand_vector_move (V8QImode, operands);
19051 DONE;
19052 })
19053
19054 (define_expand "movv2sf"
19055 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19056 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19057 "TARGET_3DNOW"
19058 {
19059 ix86_expand_vector_move (V2SFmode, operands);
19060 DONE;
19061 })
19062
19063 (define_insn "*pushti"
19064 [(set (match_operand:TI 0 "push_operand" "=<")
19065 (match_operand:TI 1 "register_operand" "x"))]
19066 "TARGET_SSE"
19067 "#")
19068
19069 (define_insn "*pushv2df"
19070 [(set (match_operand:V2DF 0 "push_operand" "=<")
19071 (match_operand:V2DF 1 "register_operand" "x"))]
19072 "TARGET_SSE"
19073 "#")
19074
19075 (define_insn "*pushv2di"
19076 [(set (match_operand:V2DI 0 "push_operand" "=<")
19077 (match_operand:V2DI 1 "register_operand" "x"))]
19078 "TARGET_SSE2"
19079 "#")
19080
19081 (define_insn "*pushv8hi"
19082 [(set (match_operand:V8HI 0 "push_operand" "=<")
19083 (match_operand:V8HI 1 "register_operand" "x"))]
19084 "TARGET_SSE2"
19085 "#")
19086
19087 (define_insn "*pushv16qi"
19088 [(set (match_operand:V16QI 0 "push_operand" "=<")
19089 (match_operand:V16QI 1 "register_operand" "x"))]
19090 "TARGET_SSE2"
19091 "#")
19092
19093 (define_insn "*pushv4sf"
19094 [(set (match_operand:V4SF 0 "push_operand" "=<")
19095 (match_operand:V4SF 1 "register_operand" "x"))]
19096 "TARGET_SSE"
19097 "#")
19098
19099 (define_insn "*pushv4si"
19100 [(set (match_operand:V4SI 0 "push_operand" "=<")
19101 (match_operand:V4SI 1 "register_operand" "x"))]
19102 "TARGET_SSE2"
19103 "#")
19104
19105 (define_insn "*pushv2si"
19106 [(set (match_operand:V2SI 0 "push_operand" "=<")
19107 (match_operand:V2SI 1 "register_operand" "y"))]
19108 "TARGET_MMX"
19109 "#")
19110
19111 (define_insn "*pushv4hi"
19112 [(set (match_operand:V4HI 0 "push_operand" "=<")
19113 (match_operand:V4HI 1 "register_operand" "y"))]
19114 "TARGET_MMX"
19115 "#")
19116
19117 (define_insn "*pushv8qi"
19118 [(set (match_operand:V8QI 0 "push_operand" "=<")
19119 (match_operand:V8QI 1 "register_operand" "y"))]
19120 "TARGET_MMX"
19121 "#")
19122
19123 (define_insn "*pushv2sf"
19124 [(set (match_operand:V2SF 0 "push_operand" "=<")
19125 (match_operand:V2SF 1 "register_operand" "y"))]
19126 "TARGET_3DNOW"
19127 "#")
19128
19129 (define_split
19130 [(set (match_operand 0 "push_operand" "")
19131 (match_operand 1 "register_operand" ""))]
19132 "!TARGET_64BIT && reload_completed
19133 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19134 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19135 (set (match_dup 2) (match_dup 1))]
19136 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19137 stack_pointer_rtx);
19138 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19139
19140 (define_split
19141 [(set (match_operand 0 "push_operand" "")
19142 (match_operand 1 "register_operand" ""))]
19143 "TARGET_64BIT && reload_completed
19144 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19145 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19146 (set (match_dup 2) (match_dup 1))]
19147 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19148 stack_pointer_rtx);
19149 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19150
19151
19152 (define_insn "movti_internal"
19153 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19154 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19155 "TARGET_SSE && !TARGET_64BIT
19156 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19157 {
19158 switch (which_alternative)
19159 {
19160 case 0:
19161 if (get_attr_mode (insn) == MODE_V4SF)
19162 return "xorps\t%0, %0";
19163 else
19164 return "pxor\t%0, %0";
19165 case 1:
19166 case 2:
19167 if (get_attr_mode (insn) == MODE_V4SF)
19168 return "movaps\t{%1, %0|%0, %1}";
19169 else
19170 return "movdqa\t{%1, %0|%0, %1}";
19171 default:
19172 abort ();
19173 }
19174 }
19175 [(set_attr "type" "ssemov,ssemov,ssemov")
19176 (set (attr "mode")
19177 (cond [(eq_attr "alternative" "0,1")
19178 (if_then_else
19179 (ne (symbol_ref "optimize_size")
19180 (const_int 0))
19181 (const_string "V4SF")
19182 (const_string "TI"))
19183 (eq_attr "alternative" "2")
19184 (if_then_else
19185 (ne (symbol_ref "optimize_size")
19186 (const_int 0))
19187 (const_string "V4SF")
19188 (const_string "TI"))]
19189 (const_string "TI")))])
19190
19191 (define_insn "*movti_rex64"
19192 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19193 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19194 "TARGET_64BIT
19195 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19196 {
19197 switch (which_alternative)
19198 {
19199 case 0:
19200 case 1:
19201 return "#";
19202 case 2:
19203 if (get_attr_mode (insn) == MODE_V4SF)
19204 return "xorps\t%0, %0";
19205 else
19206 return "pxor\t%0, %0";
19207 case 3:
19208 case 4:
19209 if (get_attr_mode (insn) == MODE_V4SF)
19210 return "movaps\t{%1, %0|%0, %1}";
19211 else
19212 return "movdqa\t{%1, %0|%0, %1}";
19213 default:
19214 abort ();
19215 }
19216 }
19217 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19218 (set (attr "mode")
19219 (cond [(eq_attr "alternative" "2,3")
19220 (if_then_else
19221 (ne (symbol_ref "optimize_size")
19222 (const_int 0))
19223 (const_string "V4SF")
19224 (const_string "TI"))
19225 (eq_attr "alternative" "4")
19226 (if_then_else
19227 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19228 (const_int 0))
19229 (ne (symbol_ref "optimize_size")
19230 (const_int 0)))
19231 (const_string "V4SF")
19232 (const_string "TI"))]
19233 (const_string "DI")))])
19234
19235 (define_insn "*movtf_rex64"
19236 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19237 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19238 "TARGET_64BIT
19239 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19240 {
19241 switch (which_alternative)
19242 {
19243 case 0:
19244 case 1:
19245 return "#";
19246 case 2:
19247 if (get_attr_mode (insn) == MODE_V4SF)
19248 return "xorps\t%0, %0";
19249 else
19250 return "pxor\t%0, %0";
19251 case 3:
19252 case 4:
19253 if (get_attr_mode (insn) == MODE_V4SF)
19254 return "movaps\t{%1, %0|%0, %1}";
19255 else
19256 return "movdqa\t{%1, %0|%0, %1}";
19257 default:
19258 abort ();
19259 }
19260 }
19261 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19262 (set (attr "mode")
19263 (cond [(eq_attr "alternative" "2,3")
19264 (if_then_else
19265 (ne (symbol_ref "optimize_size")
19266 (const_int 0))
19267 (const_string "V4SF")
19268 (const_string "TI"))
19269 (eq_attr "alternative" "4")
19270 (if_then_else
19271 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19272 (const_int 0))
19273 (ne (symbol_ref "optimize_size")
19274 (const_int 0)))
19275 (const_string "V4SF")
19276 (const_string "TI"))]
19277 (const_string "DI")))])
19278
19279 (define_split
19280 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19281 (match_operand:TI 1 "general_operand" ""))]
19282 "reload_completed && !SSE_REG_P (operands[0])
19283 && !SSE_REG_P (operands[1])"
19284 [(const_int 0)]
19285 "ix86_split_long_move (operands); DONE;")
19286
19287 (define_split
19288 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19289 (match_operand:TF 1 "general_operand" ""))]
19290 "reload_completed && !SSE_REG_P (operands[0])
19291 && !SSE_REG_P (operands[1])"
19292 [(const_int 0)]
19293 "ix86_split_long_move (operands); DONE;")
19294
19295 ;; These two patterns are useful for specifying exactly whether to use
19296 ;; movaps or movups
19297 (define_expand "sse_movaps"
19298 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19299 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19300 UNSPEC_MOVA))]
19301 "TARGET_SSE"
19302 {
19303 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19304 {
19305 rtx tmp = gen_reg_rtx (V4SFmode);
19306 emit_insn (gen_sse_movaps (tmp, operands[1]));
19307 emit_move_insn (operands[0], tmp);
19308 DONE;
19309 }
19310 })
19311
19312 (define_insn "*sse_movaps_1"
19313 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19314 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19315 UNSPEC_MOVA))]
19316 "TARGET_SSE
19317 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19318 "movaps\t{%1, %0|%0, %1}"
19319 [(set_attr "type" "ssemov,ssemov")
19320 (set_attr "mode" "V4SF")])
19321
19322 (define_expand "sse_movups"
19323 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19324 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19325 UNSPEC_MOVU))]
19326 "TARGET_SSE"
19327 {
19328 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19329 {
19330 rtx tmp = gen_reg_rtx (V4SFmode);
19331 emit_insn (gen_sse_movups (tmp, operands[1]));
19332 emit_move_insn (operands[0], tmp);
19333 DONE;
19334 }
19335 })
19336
19337 (define_insn "*sse_movups_1"
19338 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19339 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19340 UNSPEC_MOVU))]
19341 "TARGET_SSE
19342 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19343 "movups\t{%1, %0|%0, %1}"
19344 [(set_attr "type" "ssecvt,ssecvt")
19345 (set_attr "mode" "V4SF")])
19346
19347 ;; SSE Strange Moves.
19348
19349 (define_insn "sse_movmskps"
19350 [(set (match_operand:SI 0 "register_operand" "=r")
19351 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19352 UNSPEC_MOVMSK))]
19353 "TARGET_SSE"
19354 "movmskps\t{%1, %0|%0, %1}"
19355 [(set_attr "type" "ssecvt")
19356 (set_attr "mode" "V4SF")])
19357
19358 (define_insn "mmx_pmovmskb"
19359 [(set (match_operand:SI 0 "register_operand" "=r")
19360 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19361 UNSPEC_MOVMSK))]
19362 "TARGET_SSE || TARGET_3DNOW_A"
19363 "pmovmskb\t{%1, %0|%0, %1}"
19364 [(set_attr "type" "ssecvt")
19365 (set_attr "mode" "V4SF")])
19366
19367
19368 (define_insn "mmx_maskmovq"
19369 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19370 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19371 (match_operand:V8QI 2 "register_operand" "y")]
19372 UNSPEC_MASKMOV))]
19373 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19374 ;; @@@ check ordering of operands in intel/nonintel syntax
19375 "maskmovq\t{%2, %1|%1, %2}"
19376 [(set_attr "type" "mmxcvt")
19377 (set_attr "mode" "DI")])
19378
19379 (define_insn "mmx_maskmovq_rex"
19380 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19381 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19382 (match_operand:V8QI 2 "register_operand" "y")]
19383 UNSPEC_MASKMOV))]
19384 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19385 ;; @@@ check ordering of operands in intel/nonintel syntax
19386 "maskmovq\t{%2, %1|%1, %2}"
19387 [(set_attr "type" "mmxcvt")
19388 (set_attr "mode" "DI")])
19389
19390 (define_insn "sse_movntv4sf"
19391 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19392 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19393 UNSPEC_MOVNT))]
19394 "TARGET_SSE"
19395 "movntps\t{%1, %0|%0, %1}"
19396 [(set_attr "type" "ssemov")
19397 (set_attr "mode" "V4SF")])
19398
19399 (define_insn "sse_movntdi"
19400 [(set (match_operand:DI 0 "memory_operand" "=m")
19401 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19402 UNSPEC_MOVNT))]
19403 "TARGET_SSE || TARGET_3DNOW_A"
19404 "movntq\t{%1, %0|%0, %1}"
19405 [(set_attr "type" "mmxmov")
19406 (set_attr "mode" "DI")])
19407
19408 (define_insn "sse_movhlps"
19409 [(set (match_operand:V4SF 0 "register_operand" "=x")
19410 (vec_merge:V4SF
19411 (match_operand:V4SF 1 "register_operand" "0")
19412 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19413 (parallel [(const_int 2)
19414 (const_int 3)
19415 (const_int 0)
19416 (const_int 1)]))
19417 (const_int 3)))]
19418 "TARGET_SSE"
19419 "movhlps\t{%2, %0|%0, %2}"
19420 [(set_attr "type" "ssecvt")
19421 (set_attr "mode" "V4SF")])
19422
19423 (define_insn "sse_movlhps"
19424 [(set (match_operand:V4SF 0 "register_operand" "=x")
19425 (vec_merge:V4SF
19426 (match_operand:V4SF 1 "register_operand" "0")
19427 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19428 (parallel [(const_int 2)
19429 (const_int 3)
19430 (const_int 0)
19431 (const_int 1)]))
19432 (const_int 12)))]
19433 "TARGET_SSE"
19434 "movlhps\t{%2, %0|%0, %2}"
19435 [(set_attr "type" "ssecvt")
19436 (set_attr "mode" "V4SF")])
19437
19438 (define_insn "sse_movhps"
19439 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19440 (vec_merge:V4SF
19441 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19442 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19443 (const_int 12)))]
19444 "TARGET_SSE
19445 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19446 "movhps\t{%2, %0|%0, %2}"
19447 [(set_attr "type" "ssecvt")
19448 (set_attr "mode" "V4SF")])
19449
19450 (define_insn "sse_movlps"
19451 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19452 (vec_merge:V4SF
19453 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19454 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19455 (const_int 3)))]
19456 "TARGET_SSE
19457 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19458 "movlps\t{%2, %0|%0, %2}"
19459 [(set_attr "type" "ssecvt")
19460 (set_attr "mode" "V4SF")])
19461
19462 (define_expand "sse_loadss"
19463 [(match_operand:V4SF 0 "register_operand" "")
19464 (match_operand:SF 1 "memory_operand" "")]
19465 "TARGET_SSE"
19466 {
19467 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19468 CONST0_RTX (V4SFmode)));
19469 DONE;
19470 })
19471
19472 (define_insn "sse_loadss_1"
19473 [(set (match_operand:V4SF 0 "register_operand" "=x")
19474 (vec_merge:V4SF
19475 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19476 (match_operand:V4SF 2 "const0_operand" "X")
19477 (const_int 1)))]
19478 "TARGET_SSE"
19479 "movss\t{%1, %0|%0, %1}"
19480 [(set_attr "type" "ssemov")
19481 (set_attr "mode" "SF")])
19482
19483 (define_insn "sse_movss"
19484 [(set (match_operand:V4SF 0 "register_operand" "=x")
19485 (vec_merge:V4SF
19486 (match_operand:V4SF 1 "register_operand" "0")
19487 (match_operand:V4SF 2 "register_operand" "x")
19488 (const_int 1)))]
19489 "TARGET_SSE"
19490 "movss\t{%2, %0|%0, %2}"
19491 [(set_attr "type" "ssemov")
19492 (set_attr "mode" "SF")])
19493
19494 (define_insn "sse_storess"
19495 [(set (match_operand:SF 0 "memory_operand" "=m")
19496 (vec_select:SF
19497 (match_operand:V4SF 1 "register_operand" "x")
19498 (parallel [(const_int 0)])))]
19499 "TARGET_SSE"
19500 "movss\t{%1, %0|%0, %1}"
19501 [(set_attr "type" "ssemov")
19502 (set_attr "mode" "SF")])
19503
19504 (define_insn "sse_shufps"
19505 [(set (match_operand:V4SF 0 "register_operand" "=x")
19506 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19507 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19508 (match_operand:SI 3 "immediate_operand" "i")]
19509 UNSPEC_SHUFFLE))]
19510 "TARGET_SSE"
19511 ;; @@@ check operand order for intel/nonintel syntax
19512 "shufps\t{%3, %2, %0|%0, %2, %3}"
19513 [(set_attr "type" "ssecvt")
19514 (set_attr "mode" "V4SF")])
19515
19516
19517 ;; SSE arithmetic
19518
19519 (define_insn "addv4sf3"
19520 [(set (match_operand:V4SF 0 "register_operand" "=x")
19521 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19522 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19523 "TARGET_SSE"
19524 "addps\t{%2, %0|%0, %2}"
19525 [(set_attr "type" "sseadd")
19526 (set_attr "mode" "V4SF")])
19527
19528 (define_insn "vmaddv4sf3"
19529 [(set (match_operand:V4SF 0 "register_operand" "=x")
19530 (vec_merge:V4SF
19531 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19532 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19533 (match_dup 1)
19534 (const_int 1)))]
19535 "TARGET_SSE"
19536 "addss\t{%2, %0|%0, %2}"
19537 [(set_attr "type" "sseadd")
19538 (set_attr "mode" "SF")])
19539
19540 (define_insn "subv4sf3"
19541 [(set (match_operand:V4SF 0 "register_operand" "=x")
19542 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19543 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19544 "TARGET_SSE"
19545 "subps\t{%2, %0|%0, %2}"
19546 [(set_attr "type" "sseadd")
19547 (set_attr "mode" "V4SF")])
19548
19549 (define_insn "vmsubv4sf3"
19550 [(set (match_operand:V4SF 0 "register_operand" "=x")
19551 (vec_merge:V4SF
19552 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19553 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19554 (match_dup 1)
19555 (const_int 1)))]
19556 "TARGET_SSE"
19557 "subss\t{%2, %0|%0, %2}"
19558 [(set_attr "type" "sseadd")
19559 (set_attr "mode" "SF")])
19560
19561 (define_insn "mulv4sf3"
19562 [(set (match_operand:V4SF 0 "register_operand" "=x")
19563 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19564 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19565 "TARGET_SSE"
19566 "mulps\t{%2, %0|%0, %2}"
19567 [(set_attr "type" "ssemul")
19568 (set_attr "mode" "V4SF")])
19569
19570 (define_insn "vmmulv4sf3"
19571 [(set (match_operand:V4SF 0 "register_operand" "=x")
19572 (vec_merge:V4SF
19573 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19574 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19575 (match_dup 1)
19576 (const_int 1)))]
19577 "TARGET_SSE"
19578 "mulss\t{%2, %0|%0, %2}"
19579 [(set_attr "type" "ssemul")
19580 (set_attr "mode" "SF")])
19581
19582 (define_insn "divv4sf3"
19583 [(set (match_operand:V4SF 0 "register_operand" "=x")
19584 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19585 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19586 "TARGET_SSE"
19587 "divps\t{%2, %0|%0, %2}"
19588 [(set_attr "type" "ssediv")
19589 (set_attr "mode" "V4SF")])
19590
19591 (define_insn "vmdivv4sf3"
19592 [(set (match_operand:V4SF 0 "register_operand" "=x")
19593 (vec_merge:V4SF
19594 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19595 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19596 (match_dup 1)
19597 (const_int 1)))]
19598 "TARGET_SSE"
19599 "divss\t{%2, %0|%0, %2}"
19600 [(set_attr "type" "ssediv")
19601 (set_attr "mode" "SF")])
19602
19603
19604 ;; SSE square root/reciprocal
19605
19606 (define_insn "rcpv4sf2"
19607 [(set (match_operand:V4SF 0 "register_operand" "=x")
19608 (unspec:V4SF
19609 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19610 "TARGET_SSE"
19611 "rcpps\t{%1, %0|%0, %1}"
19612 [(set_attr "type" "sse")
19613 (set_attr "mode" "V4SF")])
19614
19615 (define_insn "vmrcpv4sf2"
19616 [(set (match_operand:V4SF 0 "register_operand" "=x")
19617 (vec_merge:V4SF
19618 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19619 UNSPEC_RCP)
19620 (match_operand:V4SF 2 "register_operand" "0")
19621 (const_int 1)))]
19622 "TARGET_SSE"
19623 "rcpss\t{%1, %0|%0, %1}"
19624 [(set_attr "type" "sse")
19625 (set_attr "mode" "SF")])
19626
19627 (define_insn "rsqrtv4sf2"
19628 [(set (match_operand:V4SF 0 "register_operand" "=x")
19629 (unspec:V4SF
19630 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19631 "TARGET_SSE"
19632 "rsqrtps\t{%1, %0|%0, %1}"
19633 [(set_attr "type" "sse")
19634 (set_attr "mode" "V4SF")])
19635
19636 (define_insn "vmrsqrtv4sf2"
19637 [(set (match_operand:V4SF 0 "register_operand" "=x")
19638 (vec_merge:V4SF
19639 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19640 UNSPEC_RSQRT)
19641 (match_operand:V4SF 2 "register_operand" "0")
19642 (const_int 1)))]
19643 "TARGET_SSE"
19644 "rsqrtss\t{%1, %0|%0, %1}"
19645 [(set_attr "type" "sse")
19646 (set_attr "mode" "SF")])
19647
19648 (define_insn "sqrtv4sf2"
19649 [(set (match_operand:V4SF 0 "register_operand" "=x")
19650 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19651 "TARGET_SSE"
19652 "sqrtps\t{%1, %0|%0, %1}"
19653 [(set_attr "type" "sse")
19654 (set_attr "mode" "V4SF")])
19655
19656 (define_insn "vmsqrtv4sf2"
19657 [(set (match_operand:V4SF 0 "register_operand" "=x")
19658 (vec_merge:V4SF
19659 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19660 (match_operand:V4SF 2 "register_operand" "0")
19661 (const_int 1)))]
19662 "TARGET_SSE"
19663 "sqrtss\t{%1, %0|%0, %1}"
19664 [(set_attr "type" "sse")
19665 (set_attr "mode" "SF")])
19666
19667 ;; SSE logical operations.
19668
19669 ;; SSE defines logical operations on floating point values. This brings
19670 ;; interesting challenge to RTL representation where logicals are only valid
19671 ;; on integral types. We deal with this by representing the floating point
19672 ;; logical as logical on arguments casted to TImode as this is what hardware
19673 ;; really does. Unfortunately hardware requires the type information to be
19674 ;; present and thus we must avoid subregs from being simplified and eliminated
19675 ;; in later compilation phases.
19676 ;;
19677 ;; We have following variants from each instruction:
19678 ;; sse_andsf3 - the operation taking V4SF vector operands
19679 ;; and doing TImode cast on them
19680 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19681 ;; TImode, since backend insist on eliminating casts
19682 ;; on memory operands
19683 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19684 ;; We can not accept memory operand here as instruction reads
19685 ;; whole scalar. This is generated only post reload by GCC
19686 ;; scalar float operations that expands to logicals (fabs)
19687 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19688 ;; memory operand. Eventually combine can be able
19689 ;; to synthesize these using splitter.
19690 ;; sse2_anddf3, *sse2_anddf3_memory
19691 ;;
19692 ;;
19693 ;; These are not called andti3 etc. because we really really don't want
19694 ;; the compiler to widen DImode ands to TImode ands and then try to move
19695 ;; into DImode subregs of SSE registers, and them together, and move out
19696 ;; of DImode subregs again!
19697 ;; SSE1 single precision floating point logical operation
19698 (define_expand "sse_andv4sf3"
19699 [(set (match_operand:V4SF 0 "register_operand" "")
19700 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
19701 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19702 "TARGET_SSE"
19703 "")
19704
19705 (define_insn "*sse_andv4sf3"
19706 [(set (match_operand:V4SF 0 "register_operand" "=x")
19707 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19708 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19709 "TARGET_SSE
19710 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19711 "andps\t{%2, %0|%0, %2}"
19712 [(set_attr "type" "sselog")
19713 (set_attr "mode" "V4SF")])
19714
19715 (define_expand "sse_nandv4sf3"
19716 [(set (match_operand:V4SF 0 "register_operand" "")
19717 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
19718 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19719 "TARGET_SSE"
19720 "")
19721
19722 (define_insn "*sse_nandv4sf3"
19723 [(set (match_operand:V4SF 0 "register_operand" "=x")
19724 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
19725 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19726 "TARGET_SSE"
19727 "andnps\t{%2, %0|%0, %2}"
19728 [(set_attr "type" "sselog")
19729 (set_attr "mode" "V4SF")])
19730
19731 (define_expand "sse_iorv4sf3"
19732 [(set (match_operand:V4SF 0 "register_operand" "")
19733 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
19734 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19735 "TARGET_SSE"
19736 "")
19737
19738 (define_insn "*sse_iorv4sf3"
19739 [(set (match_operand:V4SF 0 "register_operand" "=x")
19740 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19741 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19742 "TARGET_SSE
19743 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19744 "orps\t{%2, %0|%0, %2}"
19745 [(set_attr "type" "sselog")
19746 (set_attr "mode" "V4SF")])
19747
19748 (define_expand "sse_xorv4sf3"
19749 [(set (match_operand:V4SF 0 "register_operand" "")
19750 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
19751 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19752 "TARGET_SSE"
19753 "")
19754
19755 (define_insn "*sse_xorv4sf3"
19756 [(set (match_operand:V4SF 0 "register_operand" "=x")
19757 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19758 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19759 "TARGET_SSE
19760 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19761 "xorps\t{%2, %0|%0, %2}"
19762 [(set_attr "type" "sselog")
19763 (set_attr "mode" "V4SF")])
19764
19765 ;; SSE2 double precision floating point logical operation
19766
19767 (define_expand "sse2_andv2df3"
19768 [(set (match_operand:V2DF 0 "register_operand" "")
19769 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
19770 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19771 "TARGET_SSE2"
19772 "")
19773
19774 (define_insn "*sse2_andv2df3"
19775 [(set (match_operand:V2DF 0 "register_operand" "=x")
19776 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19777 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19778 "TARGET_SSE2
19779 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19780 "andpd\t{%2, %0|%0, %2}"
19781 [(set_attr "type" "sselog")
19782 (set_attr "mode" "V2DF")])
19783
19784 (define_expand "sse2_nandv2df3"
19785 [(set (match_operand:V2DF 0 "register_operand" "")
19786 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
19787 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19788 "TARGET_SSE2"
19789 "")
19790
19791 (define_insn "*sse2_nandv2df3"
19792 [(set (match_operand:V2DF 0 "register_operand" "=x")
19793 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
19794 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19795 "TARGET_SSE2"
19796 "andnpd\t{%2, %0|%0, %2}"
19797 [(set_attr "type" "sselog")
19798 (set_attr "mode" "V2DF")])
19799
19800 (define_expand "sse2_iorv2df3"
19801 [(set (match_operand:V2DF 0 "register_operand" "")
19802 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
19803 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19804 "TARGET_SSE2"
19805 "")
19806
19807 (define_insn "*sse2_iorv2df3"
19808 [(set (match_operand:V2DF 0 "register_operand" "=x")
19809 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19810 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19811 "TARGET_SSE2
19812 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19813 "orpd\t{%2, %0|%0, %2}"
19814 [(set_attr "type" "sselog")
19815 (set_attr "mode" "V2DF")])
19816
19817 (define_expand "sse2_xorv2df3"
19818 [(set (match_operand:V2DF 0 "register_operand" "")
19819 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
19820 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19821 "TARGET_SSE2"
19822 "")
19823
19824 (define_insn "*sse2_xorv2df3"
19825 [(set (match_operand:V2DF 0 "register_operand" "=x")
19826 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19827 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19828 "TARGET_SSE2
19829 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19830 "xorpd\t{%2, %0|%0, %2}"
19831 [(set_attr "type" "sselog")
19832 (set_attr "mode" "V2DF")])
19833
19834 ;; SSE2 integral logicals. These patterns must always come after floating
19835 ;; point ones since we don't want compiler to use integer opcodes on floating
19836 ;; point SSE values to avoid matching of subregs in the match_operand.
19837 (define_insn "*sse2_andti3"
19838 [(set (match_operand:TI 0 "register_operand" "=x")
19839 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19840 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19841 "TARGET_SSE2
19842 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19843 "pand\t{%2, %0|%0, %2}"
19844 [(set_attr "type" "sselog")
19845 (set_attr "mode" "TI")])
19846
19847 (define_insn "sse2_andv2di3"
19848 [(set (match_operand:V2DI 0 "register_operand" "=x")
19849 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19850 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19851 "TARGET_SSE2
19852 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19853 "pand\t{%2, %0|%0, %2}"
19854 [(set_attr "type" "sselog")
19855 (set_attr "mode" "TI")])
19856
19857 (define_insn "*sse2_nandti3"
19858 [(set (match_operand:TI 0 "register_operand" "=x")
19859 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19860 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19861 "TARGET_SSE2"
19862 "pandn\t{%2, %0|%0, %2}"
19863 [(set_attr "type" "sselog")
19864 (set_attr "mode" "TI")])
19865
19866 (define_insn "sse2_nandv2di3"
19867 [(set (match_operand:V2DI 0 "register_operand" "=x")
19868 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19869 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19870 "TARGET_SSE2
19871 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19872 "pandn\t{%2, %0|%0, %2}"
19873 [(set_attr "type" "sselog")
19874 (set_attr "mode" "TI")])
19875
19876 (define_insn "*sse2_iorti3"
19877 [(set (match_operand:TI 0 "register_operand" "=x")
19878 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19879 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19880 "TARGET_SSE2
19881 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19882 "por\t{%2, %0|%0, %2}"
19883 [(set_attr "type" "sselog")
19884 (set_attr "mode" "TI")])
19885
19886 (define_insn "sse2_iorv2di3"
19887 [(set (match_operand:V2DI 0 "register_operand" "=x")
19888 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19889 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19890 "TARGET_SSE2
19891 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19892 "por\t{%2, %0|%0, %2}"
19893 [(set_attr "type" "sselog")
19894 (set_attr "mode" "TI")])
19895
19896 (define_insn "*sse2_xorti3"
19897 [(set (match_operand:TI 0 "register_operand" "=x")
19898 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19899 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19900 "TARGET_SSE2
19901 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19902 "pxor\t{%2, %0|%0, %2}"
19903 [(set_attr "type" "sselog")
19904 (set_attr "mode" "TI")])
19905
19906 (define_insn "sse2_xorv2di3"
19907 [(set (match_operand:V2DI 0 "register_operand" "=x")
19908 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19909 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19910 "TARGET_SSE2
19911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19912 "pxor\t{%2, %0|%0, %2}"
19913 [(set_attr "type" "sselog")
19914 (set_attr "mode" "TI")])
19915
19916 ;; Use xor, but don't show input operands so they aren't live before
19917 ;; this insn.
19918 (define_insn "sse_clrv4sf"
19919 [(set (match_operand:V4SF 0 "register_operand" "=x")
19920 (match_operand:V4SF 1 "const0_operand" "X"))]
19921 "TARGET_SSE"
19922 {
19923 if (get_attr_mode (insn) == MODE_TI)
19924 return "pxor\t{%0, %0|%0, %0}";
19925 else
19926 return "xorps\t{%0, %0|%0, %0}";
19927 }
19928 [(set_attr "type" "sselog")
19929 (set_attr "memory" "none")
19930 (set (attr "mode")
19931 (if_then_else
19932 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19933 (const_int 0))
19934 (ne (symbol_ref "TARGET_SSE2")
19935 (const_int 0)))
19936 (eq (symbol_ref "optimize_size")
19937 (const_int 0)))
19938 (const_string "TI")
19939 (const_string "V4SF")))])
19940
19941 ;; Use xor, but don't show input operands so they aren't live before
19942 ;; this insn.
19943 (define_insn "sse_clrv2df"
19944 [(set (match_operand:V2DF 0 "register_operand" "=x")
19945 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19946 "TARGET_SSE2"
19947 "xorpd\t{%0, %0|%0, %0}"
19948 [(set_attr "type" "sselog")
19949 (set_attr "memory" "none")
19950 (set_attr "mode" "V4SF")])
19951
19952 ;; SSE mask-generating compares
19953
19954 (define_insn "maskcmpv4sf3"
19955 [(set (match_operand:V4SI 0 "register_operand" "=x")
19956 (match_operator:V4SI 3 "sse_comparison_operator"
19957 [(match_operand:V4SF 1 "register_operand" "0")
19958 (match_operand:V4SF 2 "register_operand" "x")]))]
19959 "TARGET_SSE"
19960 "cmp%D3ps\t{%2, %0|%0, %2}"
19961 [(set_attr "type" "ssecmp")
19962 (set_attr "mode" "V4SF")])
19963
19964 (define_insn "maskncmpv4sf3"
19965 [(set (match_operand:V4SI 0 "register_operand" "=x")
19966 (not:V4SI
19967 (match_operator:V4SI 3 "sse_comparison_operator"
19968 [(match_operand:V4SF 1 "register_operand" "0")
19969 (match_operand:V4SF 2 "register_operand" "x")])))]
19970 "TARGET_SSE"
19971 {
19972 if (GET_CODE (operands[3]) == UNORDERED)
19973 return "cmpordps\t{%2, %0|%0, %2}";
19974 else
19975 return "cmpn%D3ps\t{%2, %0|%0, %2}";
19976 }
19977 [(set_attr "type" "ssecmp")
19978 (set_attr "mode" "V4SF")])
19979
19980 (define_insn "vmmaskcmpv4sf3"
19981 [(set (match_operand:V4SI 0 "register_operand" "=x")
19982 (vec_merge:V4SI
19983 (match_operator:V4SI 3 "sse_comparison_operator"
19984 [(match_operand:V4SF 1 "register_operand" "0")
19985 (match_operand:V4SF 2 "register_operand" "x")])
19986 (subreg:V4SI (match_dup 1) 0)
19987 (const_int 1)))]
19988 "TARGET_SSE"
19989 "cmp%D3ss\t{%2, %0|%0, %2}"
19990 [(set_attr "type" "ssecmp")
19991 (set_attr "mode" "SF")])
19992
19993 (define_insn "vmmaskncmpv4sf3"
19994 [(set (match_operand:V4SI 0 "register_operand" "=x")
19995 (vec_merge:V4SI
19996 (not:V4SI
19997 (match_operator:V4SI 3 "sse_comparison_operator"
19998 [(match_operand:V4SF 1 "register_operand" "0")
19999 (match_operand:V4SF 2 "register_operand" "x")]))
20000 (subreg:V4SI (match_dup 1) 0)
20001 (const_int 1)))]
20002 "TARGET_SSE"
20003 {
20004 if (GET_CODE (operands[3]) == UNORDERED)
20005 return "cmpordss\t{%2, %0|%0, %2}";
20006 else
20007 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20008 }
20009 [(set_attr "type" "ssecmp")
20010 (set_attr "mode" "SF")])
20011
20012 (define_insn "sse_comi"
20013 [(set (reg:CCFP 17)
20014 (compare:CCFP (vec_select:SF
20015 (match_operand:V4SF 0 "register_operand" "x")
20016 (parallel [(const_int 0)]))
20017 (vec_select:SF
20018 (match_operand:V4SF 1 "register_operand" "x")
20019 (parallel [(const_int 0)]))))]
20020 "TARGET_SSE"
20021 "comiss\t{%1, %0|%0, %1}"
20022 [(set_attr "type" "ssecomi")
20023 (set_attr "mode" "SF")])
20024
20025 (define_insn "sse_ucomi"
20026 [(set (reg:CCFPU 17)
20027 (compare:CCFPU (vec_select:SF
20028 (match_operand:V4SF 0 "register_operand" "x")
20029 (parallel [(const_int 0)]))
20030 (vec_select:SF
20031 (match_operand:V4SF 1 "register_operand" "x")
20032 (parallel [(const_int 0)]))))]
20033 "TARGET_SSE"
20034 "ucomiss\t{%1, %0|%0, %1}"
20035 [(set_attr "type" "ssecomi")
20036 (set_attr "mode" "SF")])
20037
20038
20039 ;; SSE unpack
20040
20041 (define_insn "sse_unpckhps"
20042 [(set (match_operand:V4SF 0 "register_operand" "=x")
20043 (vec_merge:V4SF
20044 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20045 (parallel [(const_int 2)
20046 (const_int 0)
20047 (const_int 3)
20048 (const_int 1)]))
20049 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20050 (parallel [(const_int 0)
20051 (const_int 2)
20052 (const_int 1)
20053 (const_int 3)]))
20054 (const_int 5)))]
20055 "TARGET_SSE"
20056 "unpckhps\t{%2, %0|%0, %2}"
20057 [(set_attr "type" "ssecvt")
20058 (set_attr "mode" "V4SF")])
20059
20060 (define_insn "sse_unpcklps"
20061 [(set (match_operand:V4SF 0 "register_operand" "=x")
20062 (vec_merge:V4SF
20063 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20064 (parallel [(const_int 0)
20065 (const_int 2)
20066 (const_int 1)
20067 (const_int 3)]))
20068 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20069 (parallel [(const_int 2)
20070 (const_int 0)
20071 (const_int 3)
20072 (const_int 1)]))
20073 (const_int 5)))]
20074 "TARGET_SSE"
20075 "unpcklps\t{%2, %0|%0, %2}"
20076 [(set_attr "type" "ssecvt")
20077 (set_attr "mode" "V4SF")])
20078
20079
20080 ;; SSE min/max
20081
20082 (define_insn "smaxv4sf3"
20083 [(set (match_operand:V4SF 0 "register_operand" "=x")
20084 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20085 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20086 "TARGET_SSE"
20087 "maxps\t{%2, %0|%0, %2}"
20088 [(set_attr "type" "sse")
20089 (set_attr "mode" "V4SF")])
20090
20091 (define_insn "vmsmaxv4sf3"
20092 [(set (match_operand:V4SF 0 "register_operand" "=x")
20093 (vec_merge:V4SF
20094 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20095 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20096 (match_dup 1)
20097 (const_int 1)))]
20098 "TARGET_SSE"
20099 "maxss\t{%2, %0|%0, %2}"
20100 [(set_attr "type" "sse")
20101 (set_attr "mode" "SF")])
20102
20103 (define_insn "sminv4sf3"
20104 [(set (match_operand:V4SF 0 "register_operand" "=x")
20105 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20106 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20107 "TARGET_SSE"
20108 "minps\t{%2, %0|%0, %2}"
20109 [(set_attr "type" "sse")
20110 (set_attr "mode" "V4SF")])
20111
20112 (define_insn "vmsminv4sf3"
20113 [(set (match_operand:V4SF 0 "register_operand" "=x")
20114 (vec_merge:V4SF
20115 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20116 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20117 (match_dup 1)
20118 (const_int 1)))]
20119 "TARGET_SSE"
20120 "minss\t{%2, %0|%0, %2}"
20121 [(set_attr "type" "sse")
20122 (set_attr "mode" "SF")])
20123
20124 ;; SSE <-> integer/MMX conversions
20125
20126 (define_insn "cvtpi2ps"
20127 [(set (match_operand:V4SF 0 "register_operand" "=x")
20128 (vec_merge:V4SF
20129 (match_operand:V4SF 1 "register_operand" "0")
20130 (vec_duplicate:V4SF
20131 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20132 (const_int 12)))]
20133 "TARGET_SSE"
20134 "cvtpi2ps\t{%2, %0|%0, %2}"
20135 [(set_attr "type" "ssecvt")
20136 (set_attr "mode" "V4SF")])
20137
20138 (define_insn "cvtps2pi"
20139 [(set (match_operand:V2SI 0 "register_operand" "=y")
20140 (vec_select:V2SI
20141 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20142 (parallel [(const_int 0) (const_int 1)])))]
20143 "TARGET_SSE"
20144 "cvtps2pi\t{%1, %0|%0, %1}"
20145 [(set_attr "type" "ssecvt")
20146 (set_attr "mode" "V4SF")])
20147
20148 (define_insn "cvttps2pi"
20149 [(set (match_operand:V2SI 0 "register_operand" "=y")
20150 (vec_select:V2SI
20151 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20152 UNSPEC_FIX)
20153 (parallel [(const_int 0) (const_int 1)])))]
20154 "TARGET_SSE"
20155 "cvttps2pi\t{%1, %0|%0, %1}"
20156 [(set_attr "type" "ssecvt")
20157 (set_attr "mode" "SF")])
20158
20159 (define_insn "cvtsi2ss"
20160 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20161 (vec_merge:V4SF
20162 (match_operand:V4SF 1 "register_operand" "0,0")
20163 (vec_duplicate:V4SF
20164 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20165 (const_int 14)))]
20166 "TARGET_SSE"
20167 "cvtsi2ss\t{%2, %0|%0, %2}"
20168 [(set_attr "type" "sseicvt")
20169 (set_attr "athlon_decode" "vector,double")
20170 (set_attr "mode" "SF")])
20171
20172 (define_insn "cvtsi2ssq"
20173 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20174 (vec_merge:V4SF
20175 (match_operand:V4SF 1 "register_operand" "0,0")
20176 (vec_duplicate:V4SF
20177 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20178 (const_int 14)))]
20179 "TARGET_SSE && TARGET_64BIT"
20180 "cvtsi2ssq\t{%2, %0|%0, %2}"
20181 [(set_attr "type" "sseicvt")
20182 (set_attr "athlon_decode" "vector,double")
20183 (set_attr "mode" "SF")])
20184
20185 (define_insn "cvtss2si"
20186 [(set (match_operand:SI 0 "register_operand" "=r,r")
20187 (vec_select:SI
20188 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20189 (parallel [(const_int 0)])))]
20190 "TARGET_SSE"
20191 "cvtss2si\t{%1, %0|%0, %1}"
20192 [(set_attr "type" "sseicvt")
20193 (set_attr "athlon_decode" "double,vector")
20194 (set_attr "mode" "SI")])
20195
20196 (define_insn "cvtss2siq"
20197 [(set (match_operand:DI 0 "register_operand" "=r,r")
20198 (vec_select:DI
20199 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20200 (parallel [(const_int 0)])))]
20201 "TARGET_SSE"
20202 "cvtss2siq\t{%1, %0|%0, %1}"
20203 [(set_attr "type" "sseicvt")
20204 (set_attr "athlon_decode" "double,vector")
20205 (set_attr "mode" "DI")])
20206
20207 (define_insn "cvttss2si"
20208 [(set (match_operand:SI 0 "register_operand" "=r,r")
20209 (vec_select:SI
20210 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20211 UNSPEC_FIX)
20212 (parallel [(const_int 0)])))]
20213 "TARGET_SSE"
20214 "cvttss2si\t{%1, %0|%0, %1}"
20215 [(set_attr "type" "sseicvt")
20216 (set_attr "mode" "SF")
20217 (set_attr "athlon_decode" "double,vector")])
20218
20219 (define_insn "cvttss2siq"
20220 [(set (match_operand:DI 0 "register_operand" "=r,r")
20221 (vec_select:DI
20222 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20223 UNSPEC_FIX)
20224 (parallel [(const_int 0)])))]
20225 "TARGET_SSE && TARGET_64BIT"
20226 "cvttss2siq\t{%1, %0|%0, %1}"
20227 [(set_attr "type" "sseicvt")
20228 (set_attr "mode" "SF")
20229 (set_attr "athlon_decode" "double,vector")])
20230
20231
20232 ;; MMX insns
20233
20234 ;; MMX arithmetic
20235
20236 (define_insn "addv8qi3"
20237 [(set (match_operand:V8QI 0 "register_operand" "=y")
20238 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20239 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20240 "TARGET_MMX"
20241 "paddb\t{%2, %0|%0, %2}"
20242 [(set_attr "type" "mmxadd")
20243 (set_attr "mode" "DI")])
20244
20245 (define_insn "addv4hi3"
20246 [(set (match_operand:V4HI 0 "register_operand" "=y")
20247 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20248 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20249 "TARGET_MMX"
20250 "paddw\t{%2, %0|%0, %2}"
20251 [(set_attr "type" "mmxadd")
20252 (set_attr "mode" "DI")])
20253
20254 (define_insn "addv2si3"
20255 [(set (match_operand:V2SI 0 "register_operand" "=y")
20256 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20257 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20258 "TARGET_MMX"
20259 "paddd\t{%2, %0|%0, %2}"
20260 [(set_attr "type" "mmxadd")
20261 (set_attr "mode" "DI")])
20262
20263 (define_insn "mmx_adddi3"
20264 [(set (match_operand:DI 0 "register_operand" "=y")
20265 (unspec:DI
20266 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20267 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20268 UNSPEC_NOP))]
20269 "TARGET_MMX"
20270 "paddq\t{%2, %0|%0, %2}"
20271 [(set_attr "type" "mmxadd")
20272 (set_attr "mode" "DI")])
20273
20274 (define_insn "ssaddv8qi3"
20275 [(set (match_operand:V8QI 0 "register_operand" "=y")
20276 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20277 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20278 "TARGET_MMX"
20279 "paddsb\t{%2, %0|%0, %2}"
20280 [(set_attr "type" "mmxadd")
20281 (set_attr "mode" "DI")])
20282
20283 (define_insn "ssaddv4hi3"
20284 [(set (match_operand:V4HI 0 "register_operand" "=y")
20285 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20286 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20287 "TARGET_MMX"
20288 "paddsw\t{%2, %0|%0, %2}"
20289 [(set_attr "type" "mmxadd")
20290 (set_attr "mode" "DI")])
20291
20292 (define_insn "usaddv8qi3"
20293 [(set (match_operand:V8QI 0 "register_operand" "=y")
20294 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20295 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20296 "TARGET_MMX"
20297 "paddusb\t{%2, %0|%0, %2}"
20298 [(set_attr "type" "mmxadd")
20299 (set_attr "mode" "DI")])
20300
20301 (define_insn "usaddv4hi3"
20302 [(set (match_operand:V4HI 0 "register_operand" "=y")
20303 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20304 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20305 "TARGET_MMX"
20306 "paddusw\t{%2, %0|%0, %2}"
20307 [(set_attr "type" "mmxadd")
20308 (set_attr "mode" "DI")])
20309
20310 (define_insn "subv8qi3"
20311 [(set (match_operand:V8QI 0 "register_operand" "=y")
20312 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20313 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20314 "TARGET_MMX"
20315 "psubb\t{%2, %0|%0, %2}"
20316 [(set_attr "type" "mmxadd")
20317 (set_attr "mode" "DI")])
20318
20319 (define_insn "subv4hi3"
20320 [(set (match_operand:V4HI 0 "register_operand" "=y")
20321 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20322 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20323 "TARGET_MMX"
20324 "psubw\t{%2, %0|%0, %2}"
20325 [(set_attr "type" "mmxadd")
20326 (set_attr "mode" "DI")])
20327
20328 (define_insn "subv2si3"
20329 [(set (match_operand:V2SI 0 "register_operand" "=y")
20330 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20331 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20332 "TARGET_MMX"
20333 "psubd\t{%2, %0|%0, %2}"
20334 [(set_attr "type" "mmxadd")
20335 (set_attr "mode" "DI")])
20336
20337 (define_insn "mmx_subdi3"
20338 [(set (match_operand:DI 0 "register_operand" "=y")
20339 (unspec:DI
20340 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20341 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20342 UNSPEC_NOP))]
20343 "TARGET_MMX"
20344 "psubq\t{%2, %0|%0, %2}"
20345 [(set_attr "type" "mmxadd")
20346 (set_attr "mode" "DI")])
20347
20348 (define_insn "sssubv8qi3"
20349 [(set (match_operand:V8QI 0 "register_operand" "=y")
20350 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20351 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20352 "TARGET_MMX"
20353 "psubsb\t{%2, %0|%0, %2}"
20354 [(set_attr "type" "mmxadd")
20355 (set_attr "mode" "DI")])
20356
20357 (define_insn "sssubv4hi3"
20358 [(set (match_operand:V4HI 0 "register_operand" "=y")
20359 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20360 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20361 "TARGET_MMX"
20362 "psubsw\t{%2, %0|%0, %2}"
20363 [(set_attr "type" "mmxadd")
20364 (set_attr "mode" "DI")])
20365
20366 (define_insn "ussubv8qi3"
20367 [(set (match_operand:V8QI 0 "register_operand" "=y")
20368 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20369 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20370 "TARGET_MMX"
20371 "psubusb\t{%2, %0|%0, %2}"
20372 [(set_attr "type" "mmxadd")
20373 (set_attr "mode" "DI")])
20374
20375 (define_insn "ussubv4hi3"
20376 [(set (match_operand:V4HI 0 "register_operand" "=y")
20377 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20378 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20379 "TARGET_MMX"
20380 "psubusw\t{%2, %0|%0, %2}"
20381 [(set_attr "type" "mmxadd")
20382 (set_attr "mode" "DI")])
20383
20384 (define_insn "mulv4hi3"
20385 [(set (match_operand:V4HI 0 "register_operand" "=y")
20386 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20387 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20388 "TARGET_MMX"
20389 "pmullw\t{%2, %0|%0, %2}"
20390 [(set_attr "type" "mmxmul")
20391 (set_attr "mode" "DI")])
20392
20393 (define_insn "smulv4hi3_highpart"
20394 [(set (match_operand:V4HI 0 "register_operand" "=y")
20395 (truncate:V4HI
20396 (lshiftrt:V4SI
20397 (mult:V4SI (sign_extend:V4SI
20398 (match_operand:V4HI 1 "register_operand" "0"))
20399 (sign_extend:V4SI
20400 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20401 (const_int 16))))]
20402 "TARGET_MMX"
20403 "pmulhw\t{%2, %0|%0, %2}"
20404 [(set_attr "type" "mmxmul")
20405 (set_attr "mode" "DI")])
20406
20407 (define_insn "umulv4hi3_highpart"
20408 [(set (match_operand:V4HI 0 "register_operand" "=y")
20409 (truncate:V4HI
20410 (lshiftrt:V4SI
20411 (mult:V4SI (zero_extend:V4SI
20412 (match_operand:V4HI 1 "register_operand" "0"))
20413 (zero_extend:V4SI
20414 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20415 (const_int 16))))]
20416 "TARGET_SSE || TARGET_3DNOW_A"
20417 "pmulhuw\t{%2, %0|%0, %2}"
20418 [(set_attr "type" "mmxmul")
20419 (set_attr "mode" "DI")])
20420
20421 (define_insn "mmx_pmaddwd"
20422 [(set (match_operand:V2SI 0 "register_operand" "=y")
20423 (plus:V2SI
20424 (mult:V2SI
20425 (sign_extend:V2SI
20426 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20427 (parallel [(const_int 0) (const_int 2)])))
20428 (sign_extend:V2SI
20429 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20430 (parallel [(const_int 0) (const_int 2)]))))
20431 (mult:V2SI
20432 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20433 (parallel [(const_int 1)
20434 (const_int 3)])))
20435 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20436 (parallel [(const_int 1)
20437 (const_int 3)]))))))]
20438 "TARGET_MMX"
20439 "pmaddwd\t{%2, %0|%0, %2}"
20440 [(set_attr "type" "mmxmul")
20441 (set_attr "mode" "DI")])
20442
20443
20444 ;; MMX logical operations
20445 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20446 ;; normal code that also wants to use the FPU from getting broken.
20447 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20448 (define_insn "mmx_iordi3"
20449 [(set (match_operand:DI 0 "register_operand" "=y")
20450 (unspec:DI
20451 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20452 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20453 UNSPEC_NOP))]
20454 "TARGET_MMX"
20455 "por\t{%2, %0|%0, %2}"
20456 [(set_attr "type" "mmxadd")
20457 (set_attr "mode" "DI")])
20458
20459 (define_insn "mmx_xordi3"
20460 [(set (match_operand:DI 0 "register_operand" "=y")
20461 (unspec:DI
20462 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20463 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20464 UNSPEC_NOP))]
20465 "TARGET_MMX"
20466 "pxor\t{%2, %0|%0, %2}"
20467 [(set_attr "type" "mmxadd")
20468 (set_attr "mode" "DI")
20469 (set_attr "memory" "none")])
20470
20471 ;; Same as pxor, but don't show input operands so that we don't think
20472 ;; they are live.
20473 (define_insn "mmx_clrdi"
20474 [(set (match_operand:DI 0 "register_operand" "=y")
20475 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20476 "TARGET_MMX"
20477 "pxor\t{%0, %0|%0, %0}"
20478 [(set_attr "type" "mmxadd")
20479 (set_attr "mode" "DI")
20480 (set_attr "memory" "none")])
20481
20482 (define_insn "mmx_anddi3"
20483 [(set (match_operand:DI 0 "register_operand" "=y")
20484 (unspec:DI
20485 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20486 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20487 UNSPEC_NOP))]
20488 "TARGET_MMX"
20489 "pand\t{%2, %0|%0, %2}"
20490 [(set_attr "type" "mmxadd")
20491 (set_attr "mode" "DI")])
20492
20493 (define_insn "mmx_nanddi3"
20494 [(set (match_operand:DI 0 "register_operand" "=y")
20495 (unspec:DI
20496 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20497 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20498 UNSPEC_NOP))]
20499 "TARGET_MMX"
20500 "pandn\t{%2, %0|%0, %2}"
20501 [(set_attr "type" "mmxadd")
20502 (set_attr "mode" "DI")])
20503
20504
20505 ;; MMX unsigned averages/sum of absolute differences
20506
20507 (define_insn "mmx_uavgv8qi3"
20508 [(set (match_operand:V8QI 0 "register_operand" "=y")
20509 (ashiftrt:V8QI
20510 (plus:V8QI (plus:V8QI
20511 (match_operand:V8QI 1 "register_operand" "0")
20512 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20513 (const_vector:V8QI [(const_int 1)
20514 (const_int 1)
20515 (const_int 1)
20516 (const_int 1)
20517 (const_int 1)
20518 (const_int 1)
20519 (const_int 1)
20520 (const_int 1)]))
20521 (const_int 1)))]
20522 "TARGET_SSE || TARGET_3DNOW_A"
20523 "pavgb\t{%2, %0|%0, %2}"
20524 [(set_attr "type" "mmxshft")
20525 (set_attr "mode" "DI")])
20526
20527 (define_insn "mmx_uavgv4hi3"
20528 [(set (match_operand:V4HI 0 "register_operand" "=y")
20529 (ashiftrt:V4HI
20530 (plus:V4HI (plus:V4HI
20531 (match_operand:V4HI 1 "register_operand" "0")
20532 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20533 (const_vector:V4HI [(const_int 1)
20534 (const_int 1)
20535 (const_int 1)
20536 (const_int 1)]))
20537 (const_int 1)))]
20538 "TARGET_SSE || TARGET_3DNOW_A"
20539 "pavgw\t{%2, %0|%0, %2}"
20540 [(set_attr "type" "mmxshft")
20541 (set_attr "mode" "DI")])
20542
20543 (define_insn "mmx_psadbw"
20544 [(set (match_operand:DI 0 "register_operand" "=y")
20545 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20546 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20547 UNSPEC_PSADBW))]
20548 "TARGET_SSE || TARGET_3DNOW_A"
20549 "psadbw\t{%2, %0|%0, %2}"
20550 [(set_attr "type" "mmxshft")
20551 (set_attr "mode" "DI")])
20552
20553
20554 ;; MMX insert/extract/shuffle
20555
20556 (define_insn "mmx_pinsrw"
20557 [(set (match_operand:V4HI 0 "register_operand" "=y")
20558 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20559 (vec_duplicate:V4HI
20560 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20561 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20562 "TARGET_SSE || TARGET_3DNOW_A"
20563 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20564 [(set_attr "type" "mmxcvt")
20565 (set_attr "mode" "DI")])
20566
20567 (define_insn "mmx_pextrw"
20568 [(set (match_operand:SI 0 "register_operand" "=r")
20569 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20570 (parallel
20571 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20572 "TARGET_SSE || TARGET_3DNOW_A"
20573 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20574 [(set_attr "type" "mmxcvt")
20575 (set_attr "mode" "DI")])
20576
20577 (define_insn "mmx_pshufw"
20578 [(set (match_operand:V4HI 0 "register_operand" "=y")
20579 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20580 (match_operand:SI 2 "immediate_operand" "i")]
20581 UNSPEC_SHUFFLE))]
20582 "TARGET_SSE || TARGET_3DNOW_A"
20583 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20584 [(set_attr "type" "mmxcvt")
20585 (set_attr "mode" "DI")])
20586
20587
20588 ;; MMX mask-generating comparisons
20589
20590 (define_insn "eqv8qi3"
20591 [(set (match_operand:V8QI 0 "register_operand" "=y")
20592 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20593 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20594 "TARGET_MMX"
20595 "pcmpeqb\t{%2, %0|%0, %2}"
20596 [(set_attr "type" "mmxcmp")
20597 (set_attr "mode" "DI")])
20598
20599 (define_insn "eqv4hi3"
20600 [(set (match_operand:V4HI 0 "register_operand" "=y")
20601 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20602 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20603 "TARGET_MMX"
20604 "pcmpeqw\t{%2, %0|%0, %2}"
20605 [(set_attr "type" "mmxcmp")
20606 (set_attr "mode" "DI")])
20607
20608 (define_insn "eqv2si3"
20609 [(set (match_operand:V2SI 0 "register_operand" "=y")
20610 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20611 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20612 "TARGET_MMX"
20613 "pcmpeqd\t{%2, %0|%0, %2}"
20614 [(set_attr "type" "mmxcmp")
20615 (set_attr "mode" "DI")])
20616
20617 (define_insn "gtv8qi3"
20618 [(set (match_operand:V8QI 0 "register_operand" "=y")
20619 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20620 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20621 "TARGET_MMX"
20622 "pcmpgtb\t{%2, %0|%0, %2}"
20623 [(set_attr "type" "mmxcmp")
20624 (set_attr "mode" "DI")])
20625
20626 (define_insn "gtv4hi3"
20627 [(set (match_operand:V4HI 0 "register_operand" "=y")
20628 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20629 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20630 "TARGET_MMX"
20631 "pcmpgtw\t{%2, %0|%0, %2}"
20632 [(set_attr "type" "mmxcmp")
20633 (set_attr "mode" "DI")])
20634
20635 (define_insn "gtv2si3"
20636 [(set (match_operand:V2SI 0 "register_operand" "=y")
20637 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20638 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20639 "TARGET_MMX"
20640 "pcmpgtd\t{%2, %0|%0, %2}"
20641 [(set_attr "type" "mmxcmp")
20642 (set_attr "mode" "DI")])
20643
20644
20645 ;; MMX max/min insns
20646
20647 (define_insn "umaxv8qi3"
20648 [(set (match_operand:V8QI 0 "register_operand" "=y")
20649 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20650 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20651 "TARGET_SSE || TARGET_3DNOW_A"
20652 "pmaxub\t{%2, %0|%0, %2}"
20653 [(set_attr "type" "mmxadd")
20654 (set_attr "mode" "DI")])
20655
20656 (define_insn "smaxv4hi3"
20657 [(set (match_operand:V4HI 0 "register_operand" "=y")
20658 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20659 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20660 "TARGET_SSE || TARGET_3DNOW_A"
20661 "pmaxsw\t{%2, %0|%0, %2}"
20662 [(set_attr "type" "mmxadd")
20663 (set_attr "mode" "DI")])
20664
20665 (define_insn "uminv8qi3"
20666 [(set (match_operand:V8QI 0 "register_operand" "=y")
20667 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20668 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20669 "TARGET_SSE || TARGET_3DNOW_A"
20670 "pminub\t{%2, %0|%0, %2}"
20671 [(set_attr "type" "mmxadd")
20672 (set_attr "mode" "DI")])
20673
20674 (define_insn "sminv4hi3"
20675 [(set (match_operand:V4HI 0 "register_operand" "=y")
20676 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20677 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20678 "TARGET_SSE || TARGET_3DNOW_A"
20679 "pminsw\t{%2, %0|%0, %2}"
20680 [(set_attr "type" "mmxadd")
20681 (set_attr "mode" "DI")])
20682
20683
20684 ;; MMX shifts
20685
20686 (define_insn "ashrv4hi3"
20687 [(set (match_operand:V4HI 0 "register_operand" "=y")
20688 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20689 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20690 "TARGET_MMX"
20691 "psraw\t{%2, %0|%0, %2}"
20692 [(set_attr "type" "mmxshft")
20693 (set_attr "mode" "DI")])
20694
20695 (define_insn "ashrv2si3"
20696 [(set (match_operand:V2SI 0 "register_operand" "=y")
20697 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20698 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20699 "TARGET_MMX"
20700 "psrad\t{%2, %0|%0, %2}"
20701 [(set_attr "type" "mmxshft")
20702 (set_attr "mode" "DI")])
20703
20704 (define_insn "lshrv4hi3"
20705 [(set (match_operand:V4HI 0 "register_operand" "=y")
20706 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20707 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20708 "TARGET_MMX"
20709 "psrlw\t{%2, %0|%0, %2}"
20710 [(set_attr "type" "mmxshft")
20711 (set_attr "mode" "DI")])
20712
20713 (define_insn "lshrv2si3"
20714 [(set (match_operand:V2SI 0 "register_operand" "=y")
20715 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20716 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20717 "TARGET_MMX"
20718 "psrld\t{%2, %0|%0, %2}"
20719 [(set_attr "type" "mmxshft")
20720 (set_attr "mode" "DI")])
20721
20722 ;; See logical MMX insns.
20723 (define_insn "mmx_lshrdi3"
20724 [(set (match_operand:DI 0 "register_operand" "=y")
20725 (unspec:DI
20726 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20727 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20728 UNSPEC_NOP))]
20729 "TARGET_MMX"
20730 "psrlq\t{%2, %0|%0, %2}"
20731 [(set_attr "type" "mmxshft")
20732 (set_attr "mode" "DI")])
20733
20734 (define_insn "ashlv4hi3"
20735 [(set (match_operand:V4HI 0 "register_operand" "=y")
20736 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20737 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20738 "TARGET_MMX"
20739 "psllw\t{%2, %0|%0, %2}"
20740 [(set_attr "type" "mmxshft")
20741 (set_attr "mode" "DI")])
20742
20743 (define_insn "ashlv2si3"
20744 [(set (match_operand:V2SI 0 "register_operand" "=y")
20745 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20746 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20747 "TARGET_MMX"
20748 "pslld\t{%2, %0|%0, %2}"
20749 [(set_attr "type" "mmxshft")
20750 (set_attr "mode" "DI")])
20751
20752 ;; See logical MMX insns.
20753 (define_insn "mmx_ashldi3"
20754 [(set (match_operand:DI 0 "register_operand" "=y")
20755 (unspec:DI
20756 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20757 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20758 UNSPEC_NOP))]
20759 "TARGET_MMX"
20760 "psllq\t{%2, %0|%0, %2}"
20761 [(set_attr "type" "mmxshft")
20762 (set_attr "mode" "DI")])
20763
20764
20765 ;; MMX pack/unpack insns.
20766
20767 (define_insn "mmx_packsswb"
20768 [(set (match_operand:V8QI 0 "register_operand" "=y")
20769 (vec_concat:V8QI
20770 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20771 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20772 "TARGET_MMX"
20773 "packsswb\t{%2, %0|%0, %2}"
20774 [(set_attr "type" "mmxshft")
20775 (set_attr "mode" "DI")])
20776
20777 (define_insn "mmx_packssdw"
20778 [(set (match_operand:V4HI 0 "register_operand" "=y")
20779 (vec_concat:V4HI
20780 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20781 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20782 "TARGET_MMX"
20783 "packssdw\t{%2, %0|%0, %2}"
20784 [(set_attr "type" "mmxshft")
20785 (set_attr "mode" "DI")])
20786
20787 (define_insn "mmx_packuswb"
20788 [(set (match_operand:V8QI 0 "register_operand" "=y")
20789 (vec_concat:V8QI
20790 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20791 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20792 "TARGET_MMX"
20793 "packuswb\t{%2, %0|%0, %2}"
20794 [(set_attr "type" "mmxshft")
20795 (set_attr "mode" "DI")])
20796
20797 (define_insn "mmx_punpckhbw"
20798 [(set (match_operand:V8QI 0 "register_operand" "=y")
20799 (vec_merge:V8QI
20800 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20801 (parallel [(const_int 4)
20802 (const_int 0)
20803 (const_int 5)
20804 (const_int 1)
20805 (const_int 6)
20806 (const_int 2)
20807 (const_int 7)
20808 (const_int 3)]))
20809 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20810 (parallel [(const_int 0)
20811 (const_int 4)
20812 (const_int 1)
20813 (const_int 5)
20814 (const_int 2)
20815 (const_int 6)
20816 (const_int 3)
20817 (const_int 7)]))
20818 (const_int 85)))]
20819 "TARGET_MMX"
20820 "punpckhbw\t{%2, %0|%0, %2}"
20821 [(set_attr "type" "mmxcvt")
20822 (set_attr "mode" "DI")])
20823
20824 (define_insn "mmx_punpckhwd"
20825 [(set (match_operand:V4HI 0 "register_operand" "=y")
20826 (vec_merge:V4HI
20827 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20828 (parallel [(const_int 0)
20829 (const_int 2)
20830 (const_int 1)
20831 (const_int 3)]))
20832 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20833 (parallel [(const_int 2)
20834 (const_int 0)
20835 (const_int 3)
20836 (const_int 1)]))
20837 (const_int 5)))]
20838 "TARGET_MMX"
20839 "punpckhwd\t{%2, %0|%0, %2}"
20840 [(set_attr "type" "mmxcvt")
20841 (set_attr "mode" "DI")])
20842
20843 (define_insn "mmx_punpckhdq"
20844 [(set (match_operand:V2SI 0 "register_operand" "=y")
20845 (vec_merge:V2SI
20846 (match_operand:V2SI 1 "register_operand" "0")
20847 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20848 (parallel [(const_int 1)
20849 (const_int 0)]))
20850 (const_int 1)))]
20851 "TARGET_MMX"
20852 "punpckhdq\t{%2, %0|%0, %2}"
20853 [(set_attr "type" "mmxcvt")
20854 (set_attr "mode" "DI")])
20855
20856 (define_insn "mmx_punpcklbw"
20857 [(set (match_operand:V8QI 0 "register_operand" "=y")
20858 (vec_merge:V8QI
20859 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20860 (parallel [(const_int 0)
20861 (const_int 4)
20862 (const_int 1)
20863 (const_int 5)
20864 (const_int 2)
20865 (const_int 6)
20866 (const_int 3)
20867 (const_int 7)]))
20868 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20869 (parallel [(const_int 4)
20870 (const_int 0)
20871 (const_int 5)
20872 (const_int 1)
20873 (const_int 6)
20874 (const_int 2)
20875 (const_int 7)
20876 (const_int 3)]))
20877 (const_int 85)))]
20878 "TARGET_MMX"
20879 "punpcklbw\t{%2, %0|%0, %2}"
20880 [(set_attr "type" "mmxcvt")
20881 (set_attr "mode" "DI")])
20882
20883 (define_insn "mmx_punpcklwd"
20884 [(set (match_operand:V4HI 0 "register_operand" "=y")
20885 (vec_merge:V4HI
20886 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20887 (parallel [(const_int 2)
20888 (const_int 0)
20889 (const_int 3)
20890 (const_int 1)]))
20891 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20892 (parallel [(const_int 0)
20893 (const_int 2)
20894 (const_int 1)
20895 (const_int 3)]))
20896 (const_int 5)))]
20897 "TARGET_MMX"
20898 "punpcklwd\t{%2, %0|%0, %2}"
20899 [(set_attr "type" "mmxcvt")
20900 (set_attr "mode" "DI")])
20901
20902 (define_insn "mmx_punpckldq"
20903 [(set (match_operand:V2SI 0 "register_operand" "=y")
20904 (vec_merge:V2SI
20905 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20906 (parallel [(const_int 1)
20907 (const_int 0)]))
20908 (match_operand:V2SI 2 "register_operand" "y")
20909 (const_int 1)))]
20910 "TARGET_MMX"
20911 "punpckldq\t{%2, %0|%0, %2}"
20912 [(set_attr "type" "mmxcvt")
20913 (set_attr "mode" "DI")])
20914
20915
20916 ;; Miscellaneous stuff
20917
20918 (define_insn "emms"
20919 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20920 (clobber (reg:XF 8))
20921 (clobber (reg:XF 9))
20922 (clobber (reg:XF 10))
20923 (clobber (reg:XF 11))
20924 (clobber (reg:XF 12))
20925 (clobber (reg:XF 13))
20926 (clobber (reg:XF 14))
20927 (clobber (reg:XF 15))
20928 (clobber (reg:DI 29))
20929 (clobber (reg:DI 30))
20930 (clobber (reg:DI 31))
20931 (clobber (reg:DI 32))
20932 (clobber (reg:DI 33))
20933 (clobber (reg:DI 34))
20934 (clobber (reg:DI 35))
20935 (clobber (reg:DI 36))]
20936 "TARGET_MMX"
20937 "emms"
20938 [(set_attr "type" "mmx")
20939 (set_attr "memory" "unknown")])
20940
20941 (define_insn "ldmxcsr"
20942 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20943 UNSPECV_LDMXCSR)]
20944 "TARGET_SSE"
20945 "ldmxcsr\t%0"
20946 [(set_attr "type" "sse")
20947 (set_attr "memory" "load")])
20948
20949 (define_insn "stmxcsr"
20950 [(set (match_operand:SI 0 "memory_operand" "=m")
20951 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20952 "TARGET_SSE"
20953 "stmxcsr\t%0"
20954 [(set_attr "type" "sse")
20955 (set_attr "memory" "store")])
20956
20957 (define_expand "sfence"
20958 [(set (match_dup 0)
20959 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20960 "TARGET_SSE || TARGET_3DNOW_A"
20961 {
20962 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20963 MEM_VOLATILE_P (operands[0]) = 1;
20964 })
20965
20966 (define_insn "*sfence_insn"
20967 [(set (match_operand:BLK 0 "" "")
20968 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20969 "TARGET_SSE || TARGET_3DNOW_A"
20970 "sfence"
20971 [(set_attr "type" "sse")
20972 (set_attr "memory" "unknown")])
20973
20974 (define_expand "sse_prologue_save"
20975 [(parallel [(set (match_operand:BLK 0 "" "")
20976 (unspec:BLK [(reg:DI 21)
20977 (reg:DI 22)
20978 (reg:DI 23)
20979 (reg:DI 24)
20980 (reg:DI 25)
20981 (reg:DI 26)
20982 (reg:DI 27)
20983 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20984 (use (match_operand:DI 1 "register_operand" ""))
20985 (use (match_operand:DI 2 "immediate_operand" ""))
20986 (use (label_ref:DI (match_operand 3 "" "")))])]
20987 "TARGET_64BIT"
20988 "")
20989
20990 (define_insn "*sse_prologue_save_insn"
20991 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20992 (match_operand:DI 4 "const_int_operand" "n")))
20993 (unspec:BLK [(reg:DI 21)
20994 (reg:DI 22)
20995 (reg:DI 23)
20996 (reg:DI 24)
20997 (reg:DI 25)
20998 (reg:DI 26)
20999 (reg:DI 27)
21000 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21001 (use (match_operand:DI 1 "register_operand" "r"))
21002 (use (match_operand:DI 2 "const_int_operand" "i"))
21003 (use (label_ref:DI (match_operand 3 "" "X")))]
21004 "TARGET_64BIT
21005 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21006 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21007 "*
21008 {
21009 int i;
21010 operands[0] = gen_rtx_MEM (Pmode,
21011 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21012 output_asm_insn (\"jmp\\t%A1\", operands);
21013 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21014 {
21015 operands[4] = adjust_address (operands[0], DImode, i*16);
21016 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21017 PUT_MODE (operands[4], TImode);
21018 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21019 output_asm_insn (\"rex\", operands);
21020 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21021 }
21022 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21023 CODE_LABEL_NUMBER (operands[3]));
21024 RET;
21025 }
21026 "
21027 [(set_attr "type" "other")
21028 (set_attr "length_immediate" "0")
21029 (set_attr "length_address" "0")
21030 (set_attr "length" "135")
21031 (set_attr "memory" "store")
21032 (set_attr "modrm" "0")
21033 (set_attr "mode" "DI")])
21034
21035 ;; 3Dnow! instructions
21036
21037 (define_insn "addv2sf3"
21038 [(set (match_operand:V2SF 0 "register_operand" "=y")
21039 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21040 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21041 "TARGET_3DNOW"
21042 "pfadd\\t{%2, %0|%0, %2}"
21043 [(set_attr "type" "mmxadd")
21044 (set_attr "mode" "V2SF")])
21045
21046 (define_insn "subv2sf3"
21047 [(set (match_operand:V2SF 0 "register_operand" "=y")
21048 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21049 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21050 "TARGET_3DNOW"
21051 "pfsub\\t{%2, %0|%0, %2}"
21052 [(set_attr "type" "mmxadd")
21053 (set_attr "mode" "V2SF")])
21054
21055 (define_insn "subrv2sf3"
21056 [(set (match_operand:V2SF 0 "register_operand" "=y")
21057 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21058 (match_operand:V2SF 1 "register_operand" "0")))]
21059 "TARGET_3DNOW"
21060 "pfsubr\\t{%2, %0|%0, %2}"
21061 [(set_attr "type" "mmxadd")
21062 (set_attr "mode" "V2SF")])
21063
21064 (define_insn "gtv2sf3"
21065 [(set (match_operand:V2SI 0 "register_operand" "=y")
21066 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21067 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21068 "TARGET_3DNOW"
21069 "pfcmpgt\\t{%2, %0|%0, %2}"
21070 [(set_attr "type" "mmxcmp")
21071 (set_attr "mode" "V2SF")])
21072
21073 (define_insn "gev2sf3"
21074 [(set (match_operand:V2SI 0 "register_operand" "=y")
21075 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21076 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21077 "TARGET_3DNOW"
21078 "pfcmpge\\t{%2, %0|%0, %2}"
21079 [(set_attr "type" "mmxcmp")
21080 (set_attr "mode" "V2SF")])
21081
21082 (define_insn "eqv2sf3"
21083 [(set (match_operand:V2SI 0 "register_operand" "=y")
21084 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21085 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21086 "TARGET_3DNOW"
21087 "pfcmpeq\\t{%2, %0|%0, %2}"
21088 [(set_attr "type" "mmxcmp")
21089 (set_attr "mode" "V2SF")])
21090
21091 (define_insn "pfmaxv2sf3"
21092 [(set (match_operand:V2SF 0 "register_operand" "=y")
21093 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21094 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21095 "TARGET_3DNOW"
21096 "pfmax\\t{%2, %0|%0, %2}"
21097 [(set_attr "type" "mmxadd")
21098 (set_attr "mode" "V2SF")])
21099
21100 (define_insn "pfminv2sf3"
21101 [(set (match_operand:V2SF 0 "register_operand" "=y")
21102 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21103 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21104 "TARGET_3DNOW"
21105 "pfmin\\t{%2, %0|%0, %2}"
21106 [(set_attr "type" "mmxadd")
21107 (set_attr "mode" "V2SF")])
21108
21109 (define_insn "mulv2sf3"
21110 [(set (match_operand:V2SF 0 "register_operand" "=y")
21111 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21112 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21113 "TARGET_3DNOW"
21114 "pfmul\\t{%2, %0|%0, %2}"
21115 [(set_attr "type" "mmxmul")
21116 (set_attr "mode" "V2SF")])
21117
21118 (define_insn "femms"
21119 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21120 (clobber (reg:XF 8))
21121 (clobber (reg:XF 9))
21122 (clobber (reg:XF 10))
21123 (clobber (reg:XF 11))
21124 (clobber (reg:XF 12))
21125 (clobber (reg:XF 13))
21126 (clobber (reg:XF 14))
21127 (clobber (reg:XF 15))
21128 (clobber (reg:DI 29))
21129 (clobber (reg:DI 30))
21130 (clobber (reg:DI 31))
21131 (clobber (reg:DI 32))
21132 (clobber (reg:DI 33))
21133 (clobber (reg:DI 34))
21134 (clobber (reg:DI 35))
21135 (clobber (reg:DI 36))]
21136 "TARGET_3DNOW"
21137 "femms"
21138 [(set_attr "type" "mmx")
21139 (set_attr "memory" "none")])
21140
21141 (define_insn "pf2id"
21142 [(set (match_operand:V2SI 0 "register_operand" "=y")
21143 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21144 "TARGET_3DNOW"
21145 "pf2id\\t{%1, %0|%0, %1}"
21146 [(set_attr "type" "mmxcvt")
21147 (set_attr "mode" "V2SF")])
21148
21149 (define_insn "pf2iw"
21150 [(set (match_operand:V2SI 0 "register_operand" "=y")
21151 (sign_extend:V2SI
21152 (ss_truncate:V2HI
21153 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21154 "TARGET_3DNOW_A"
21155 "pf2iw\\t{%1, %0|%0, %1}"
21156 [(set_attr "type" "mmxcvt")
21157 (set_attr "mode" "V2SF")])
21158
21159 (define_insn "pfacc"
21160 [(set (match_operand:V2SF 0 "register_operand" "=y")
21161 (vec_concat:V2SF
21162 (plus:SF
21163 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21164 (parallel [(const_int 0)]))
21165 (vec_select:SF (match_dup 1)
21166 (parallel [(const_int 1)])))
21167 (plus:SF
21168 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21169 (parallel [(const_int 0)]))
21170 (vec_select:SF (match_dup 2)
21171 (parallel [(const_int 1)])))))]
21172 "TARGET_3DNOW"
21173 "pfacc\\t{%2, %0|%0, %2}"
21174 [(set_attr "type" "mmxadd")
21175 (set_attr "mode" "V2SF")])
21176
21177 (define_insn "pfnacc"
21178 [(set (match_operand:V2SF 0 "register_operand" "=y")
21179 (vec_concat:V2SF
21180 (minus:SF
21181 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21182 (parallel [(const_int 0)]))
21183 (vec_select:SF (match_dup 1)
21184 (parallel [(const_int 1)])))
21185 (minus:SF
21186 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21187 (parallel [(const_int 0)]))
21188 (vec_select:SF (match_dup 2)
21189 (parallel [(const_int 1)])))))]
21190 "TARGET_3DNOW_A"
21191 "pfnacc\\t{%2, %0|%0, %2}"
21192 [(set_attr "type" "mmxadd")
21193 (set_attr "mode" "V2SF")])
21194
21195 (define_insn "pfpnacc"
21196 [(set (match_operand:V2SF 0 "register_operand" "=y")
21197 (vec_concat:V2SF
21198 (minus:SF
21199 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21200 (parallel [(const_int 0)]))
21201 (vec_select:SF (match_dup 1)
21202 (parallel [(const_int 1)])))
21203 (plus:SF
21204 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21205 (parallel [(const_int 0)]))
21206 (vec_select:SF (match_dup 2)
21207 (parallel [(const_int 1)])))))]
21208 "TARGET_3DNOW_A"
21209 "pfpnacc\\t{%2, %0|%0, %2}"
21210 [(set_attr "type" "mmxadd")
21211 (set_attr "mode" "V2SF")])
21212
21213 (define_insn "pi2fw"
21214 [(set (match_operand:V2SF 0 "register_operand" "=y")
21215 (float:V2SF
21216 (vec_concat:V2SI
21217 (sign_extend:SI
21218 (truncate:HI
21219 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21220 (parallel [(const_int 0)]))))
21221 (sign_extend:SI
21222 (truncate:HI
21223 (vec_select:SI (match_dup 1)
21224 (parallel [(const_int 1)])))))))]
21225 "TARGET_3DNOW_A"
21226 "pi2fw\\t{%1, %0|%0, %1}"
21227 [(set_attr "type" "mmxcvt")
21228 (set_attr "mode" "V2SF")])
21229
21230 (define_insn "floatv2si2"
21231 [(set (match_operand:V2SF 0 "register_operand" "=y")
21232 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21233 "TARGET_3DNOW"
21234 "pi2fd\\t{%1, %0|%0, %1}"
21235 [(set_attr "type" "mmxcvt")
21236 (set_attr "mode" "V2SF")])
21237
21238 ;; This insn is identical to pavgb in operation, but the opcode is
21239 ;; different. To avoid accidentally matching pavgb, use an unspec.
21240
21241 (define_insn "pavgusb"
21242 [(set (match_operand:V8QI 0 "register_operand" "=y")
21243 (unspec:V8QI
21244 [(match_operand:V8QI 1 "register_operand" "0")
21245 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21246 UNSPEC_PAVGUSB))]
21247 "TARGET_3DNOW"
21248 "pavgusb\\t{%2, %0|%0, %2}"
21249 [(set_attr "type" "mmxshft")
21250 (set_attr "mode" "TI")])
21251
21252 ;; 3DNow reciprocal and sqrt
21253
21254 (define_insn "pfrcpv2sf2"
21255 [(set (match_operand:V2SF 0 "register_operand" "=y")
21256 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21257 UNSPEC_PFRCP))]
21258 "TARGET_3DNOW"
21259 "pfrcp\\t{%1, %0|%0, %1}"
21260 [(set_attr "type" "mmx")
21261 (set_attr "mode" "TI")])
21262
21263 (define_insn "pfrcpit1v2sf3"
21264 [(set (match_operand:V2SF 0 "register_operand" "=y")
21265 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21266 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21267 UNSPEC_PFRCPIT1))]
21268 "TARGET_3DNOW"
21269 "pfrcpit1\\t{%2, %0|%0, %2}"
21270 [(set_attr "type" "mmx")
21271 (set_attr "mode" "TI")])
21272
21273 (define_insn "pfrcpit2v2sf3"
21274 [(set (match_operand:V2SF 0 "register_operand" "=y")
21275 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21276 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21277 UNSPEC_PFRCPIT2))]
21278 "TARGET_3DNOW"
21279 "pfrcpit2\\t{%2, %0|%0, %2}"
21280 [(set_attr "type" "mmx")
21281 (set_attr "mode" "TI")])
21282
21283 (define_insn "pfrsqrtv2sf2"
21284 [(set (match_operand:V2SF 0 "register_operand" "=y")
21285 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21286 UNSPEC_PFRSQRT))]
21287 "TARGET_3DNOW"
21288 "pfrsqrt\\t{%1, %0|%0, %1}"
21289 [(set_attr "type" "mmx")
21290 (set_attr "mode" "TI")])
21291
21292 (define_insn "pfrsqit1v2sf3"
21293 [(set (match_operand:V2SF 0 "register_operand" "=y")
21294 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21295 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21296 UNSPEC_PFRSQIT1))]
21297 "TARGET_3DNOW"
21298 "pfrsqit1\\t{%2, %0|%0, %2}"
21299 [(set_attr "type" "mmx")
21300 (set_attr "mode" "TI")])
21301
21302 (define_insn "pmulhrwv4hi3"
21303 [(set (match_operand:V4HI 0 "register_operand" "=y")
21304 (truncate:V4HI
21305 (lshiftrt:V4SI
21306 (plus:V4SI
21307 (mult:V4SI
21308 (sign_extend:V4SI
21309 (match_operand:V4HI 1 "register_operand" "0"))
21310 (sign_extend:V4SI
21311 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21312 (const_vector:V4SI [(const_int 32768)
21313 (const_int 32768)
21314 (const_int 32768)
21315 (const_int 32768)]))
21316 (const_int 16))))]
21317 "TARGET_3DNOW"
21318 "pmulhrw\\t{%2, %0|%0, %2}"
21319 [(set_attr "type" "mmxmul")
21320 (set_attr "mode" "TI")])
21321
21322 (define_insn "pswapdv2si2"
21323 [(set (match_operand:V2SI 0 "register_operand" "=y")
21324 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21325 (parallel [(const_int 1) (const_int 0)])))]
21326 "TARGET_3DNOW_A"
21327 "pswapd\\t{%1, %0|%0, %1}"
21328 [(set_attr "type" "mmxcvt")
21329 (set_attr "mode" "TI")])
21330
21331 (define_insn "pswapdv2sf2"
21332 [(set (match_operand:V2SF 0 "register_operand" "=y")
21333 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21334 (parallel [(const_int 1) (const_int 0)])))]
21335 "TARGET_3DNOW_A"
21336 "pswapd\\t{%1, %0|%0, %1}"
21337 [(set_attr "type" "mmxcvt")
21338 (set_attr "mode" "TI")])
21339
21340 (define_expand "prefetch"
21341 [(prefetch (match_operand 0 "address_operand" "")
21342 (match_operand:SI 1 "const_int_operand" "")
21343 (match_operand:SI 2 "const_int_operand" ""))]
21344 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21345 {
21346 int rw = INTVAL (operands[1]);
21347 int locality = INTVAL (operands[2]);
21348
21349 if (rw != 0 && rw != 1)
21350 abort ();
21351 if (locality < 0 || locality > 3)
21352 abort ();
21353 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21354 abort ();
21355
21356 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21357 suported by SSE counterpart or the SSE prefetch is not available
21358 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21359 of locality. */
21360 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21361 operands[2] = GEN_INT (3);
21362 else
21363 operands[1] = const0_rtx;
21364 })
21365
21366 (define_insn "*prefetch_sse"
21367 [(prefetch (match_operand:SI 0 "address_operand" "p")
21368 (const_int 0)
21369 (match_operand:SI 1 "const_int_operand" ""))]
21370 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21371 {
21372 static const char * const patterns[4] = {
21373 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21374 };
21375
21376 int locality = INTVAL (operands[1]);
21377 if (locality < 0 || locality > 3)
21378 abort ();
21379
21380 return patterns[locality];
21381 }
21382 [(set_attr "type" "sse")
21383 (set_attr "memory" "none")])
21384
21385 (define_insn "*prefetch_sse_rex"
21386 [(prefetch (match_operand:DI 0 "address_operand" "p")
21387 (const_int 0)
21388 (match_operand:SI 1 "const_int_operand" ""))]
21389 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21390 {
21391 static const char * const patterns[4] = {
21392 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21393 };
21394
21395 int locality = INTVAL (operands[1]);
21396 if (locality < 0 || locality > 3)
21397 abort ();
21398
21399 return patterns[locality];
21400 }
21401 [(set_attr "type" "sse")
21402 (set_attr "memory" "none")])
21403
21404 (define_insn "*prefetch_3dnow"
21405 [(prefetch (match_operand:SI 0 "address_operand" "p")
21406 (match_operand:SI 1 "const_int_operand" "n")
21407 (const_int 3))]
21408 "TARGET_3DNOW && !TARGET_64BIT"
21409 {
21410 if (INTVAL (operands[1]) == 0)
21411 return "prefetch\t%a0";
21412 else
21413 return "prefetchw\t%a0";
21414 }
21415 [(set_attr "type" "mmx")
21416 (set_attr "memory" "none")])
21417
21418 (define_insn "*prefetch_3dnow_rex"
21419 [(prefetch (match_operand:DI 0 "address_operand" "p")
21420 (match_operand:SI 1 "const_int_operand" "n")
21421 (const_int 3))]
21422 "TARGET_3DNOW && TARGET_64BIT"
21423 {
21424 if (INTVAL (operands[1]) == 0)
21425 return "prefetch\t%a0";
21426 else
21427 return "prefetchw\t%a0";
21428 }
21429 [(set_attr "type" "mmx")
21430 (set_attr "memory" "none")])
21431
21432 ;; SSE2 support
21433
21434 (define_insn "addv2df3"
21435 [(set (match_operand:V2DF 0 "register_operand" "=x")
21436 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21437 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21438 "TARGET_SSE2"
21439 "addpd\t{%2, %0|%0, %2}"
21440 [(set_attr "type" "sseadd")
21441 (set_attr "mode" "V2DF")])
21442
21443 (define_insn "vmaddv2df3"
21444 [(set (match_operand:V2DF 0 "register_operand" "=x")
21445 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21446 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21447 (match_dup 1)
21448 (const_int 1)))]
21449 "TARGET_SSE2"
21450 "addsd\t{%2, %0|%0, %2}"
21451 [(set_attr "type" "sseadd")
21452 (set_attr "mode" "DF")])
21453
21454 (define_insn "subv2df3"
21455 [(set (match_operand:V2DF 0 "register_operand" "=x")
21456 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21457 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21458 "TARGET_SSE2"
21459 "subpd\t{%2, %0|%0, %2}"
21460 [(set_attr "type" "sseadd")
21461 (set_attr "mode" "V2DF")])
21462
21463 (define_insn "vmsubv2df3"
21464 [(set (match_operand:V2DF 0 "register_operand" "=x")
21465 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21466 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21467 (match_dup 1)
21468 (const_int 1)))]
21469 "TARGET_SSE2"
21470 "subsd\t{%2, %0|%0, %2}"
21471 [(set_attr "type" "sseadd")
21472 (set_attr "mode" "DF")])
21473
21474 (define_insn "mulv2df3"
21475 [(set (match_operand:V2DF 0 "register_operand" "=x")
21476 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21477 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21478 "TARGET_SSE2"
21479 "mulpd\t{%2, %0|%0, %2}"
21480 [(set_attr "type" "ssemul")
21481 (set_attr "mode" "V2DF")])
21482
21483 (define_insn "vmmulv2df3"
21484 [(set (match_operand:V2DF 0 "register_operand" "=x")
21485 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21486 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21487 (match_dup 1)
21488 (const_int 1)))]
21489 "TARGET_SSE2"
21490 "mulsd\t{%2, %0|%0, %2}"
21491 [(set_attr "type" "ssemul")
21492 (set_attr "mode" "DF")])
21493
21494 (define_insn "divv2df3"
21495 [(set (match_operand:V2DF 0 "register_operand" "=x")
21496 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21497 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21498 "TARGET_SSE2"
21499 "divpd\t{%2, %0|%0, %2}"
21500 [(set_attr "type" "ssediv")
21501 (set_attr "mode" "V2DF")])
21502
21503 (define_insn "vmdivv2df3"
21504 [(set (match_operand:V2DF 0 "register_operand" "=x")
21505 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21506 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21507 (match_dup 1)
21508 (const_int 1)))]
21509 "TARGET_SSE2"
21510 "divsd\t{%2, %0|%0, %2}"
21511 [(set_attr "type" "ssediv")
21512 (set_attr "mode" "DF")])
21513
21514 ;; SSE min/max
21515
21516 (define_insn "smaxv2df3"
21517 [(set (match_operand:V2DF 0 "register_operand" "=x")
21518 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21519 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21520 "TARGET_SSE2"
21521 "maxpd\t{%2, %0|%0, %2}"
21522 [(set_attr "type" "sseadd")
21523 (set_attr "mode" "V2DF")])
21524
21525 (define_insn "vmsmaxv2df3"
21526 [(set (match_operand:V2DF 0 "register_operand" "=x")
21527 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21528 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21529 (match_dup 1)
21530 (const_int 1)))]
21531 "TARGET_SSE2"
21532 "maxsd\t{%2, %0|%0, %2}"
21533 [(set_attr "type" "sseadd")
21534 (set_attr "mode" "DF")])
21535
21536 (define_insn "sminv2df3"
21537 [(set (match_operand:V2DF 0 "register_operand" "=x")
21538 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21539 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21540 "TARGET_SSE2"
21541 "minpd\t{%2, %0|%0, %2}"
21542 [(set_attr "type" "sseadd")
21543 (set_attr "mode" "V2DF")])
21544
21545 (define_insn "vmsminv2df3"
21546 [(set (match_operand:V2DF 0 "register_operand" "=x")
21547 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21548 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21549 (match_dup 1)
21550 (const_int 1)))]
21551 "TARGET_SSE2"
21552 "minsd\t{%2, %0|%0, %2}"
21553 [(set_attr "type" "sseadd")
21554 (set_attr "mode" "DF")])
21555 ;; SSE2 square root. There doesn't appear to be an extension for the
21556 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21557
21558 (define_insn "sqrtv2df2"
21559 [(set (match_operand:V2DF 0 "register_operand" "=x")
21560 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21561 "TARGET_SSE2"
21562 "sqrtpd\t{%1, %0|%0, %1}"
21563 [(set_attr "type" "sse")
21564 (set_attr "mode" "V2DF")])
21565
21566 (define_insn "vmsqrtv2df2"
21567 [(set (match_operand:V2DF 0 "register_operand" "=x")
21568 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21569 (match_operand:V2DF 2 "register_operand" "0")
21570 (const_int 1)))]
21571 "TARGET_SSE2"
21572 "sqrtsd\t{%1, %0|%0, %1}"
21573 [(set_attr "type" "sse")
21574 (set_attr "mode" "SF")])
21575
21576 ;; SSE mask-generating compares
21577
21578 (define_insn "maskcmpv2df3"
21579 [(set (match_operand:V2DI 0 "register_operand" "=x")
21580 (match_operator:V2DI 3 "sse_comparison_operator"
21581 [(match_operand:V2DF 1 "register_operand" "0")
21582 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21583 "TARGET_SSE2"
21584 "cmp%D3pd\t{%2, %0|%0, %2}"
21585 [(set_attr "type" "ssecmp")
21586 (set_attr "mode" "V2DF")])
21587
21588 (define_insn "maskncmpv2df3"
21589 [(set (match_operand:V2DI 0 "register_operand" "=x")
21590 (not:V2DI
21591 (match_operator:V2DI 3 "sse_comparison_operator"
21592 [(match_operand:V2DF 1 "register_operand" "0")
21593 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21594 "TARGET_SSE2"
21595 {
21596 if (GET_CODE (operands[3]) == UNORDERED)
21597 return "cmpordps\t{%2, %0|%0, %2}";
21598 else
21599 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21600 }
21601 [(set_attr "type" "ssecmp")
21602 (set_attr "mode" "V2DF")])
21603
21604 (define_insn "vmmaskcmpv2df3"
21605 [(set (match_operand:V2DI 0 "register_operand" "=x")
21606 (vec_merge:V2DI
21607 (match_operator:V2DI 3 "sse_comparison_operator"
21608 [(match_operand:V2DF 1 "register_operand" "0")
21609 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21610 (subreg:V2DI (match_dup 1) 0)
21611 (const_int 1)))]
21612 "TARGET_SSE2"
21613 "cmp%D3sd\t{%2, %0|%0, %2}"
21614 [(set_attr "type" "ssecmp")
21615 (set_attr "mode" "DF")])
21616
21617 (define_insn "vmmaskncmpv2df3"
21618 [(set (match_operand:V2DI 0 "register_operand" "=x")
21619 (vec_merge:V2DI
21620 (not:V2DI
21621 (match_operator:V2DI 3 "sse_comparison_operator"
21622 [(match_operand:V2DF 1 "register_operand" "0")
21623 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21624 (subreg:V2DI (match_dup 1) 0)
21625 (const_int 1)))]
21626 "TARGET_SSE2"
21627 {
21628 if (GET_CODE (operands[3]) == UNORDERED)
21629 return "cmpordsd\t{%2, %0|%0, %2}";
21630 else
21631 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21632 }
21633 [(set_attr "type" "ssecmp")
21634 (set_attr "mode" "DF")])
21635
21636 (define_insn "sse2_comi"
21637 [(set (reg:CCFP 17)
21638 (compare:CCFP (vec_select:DF
21639 (match_operand:V2DF 0 "register_operand" "x")
21640 (parallel [(const_int 0)]))
21641 (vec_select:DF
21642 (match_operand:V2DF 1 "register_operand" "x")
21643 (parallel [(const_int 0)]))))]
21644 "TARGET_SSE2"
21645 "comisd\t{%1, %0|%0, %1}"
21646 [(set_attr "type" "ssecomi")
21647 (set_attr "mode" "DF")])
21648
21649 (define_insn "sse2_ucomi"
21650 [(set (reg:CCFPU 17)
21651 (compare:CCFPU (vec_select:DF
21652 (match_operand:V2DF 0 "register_operand" "x")
21653 (parallel [(const_int 0)]))
21654 (vec_select:DF
21655 (match_operand:V2DF 1 "register_operand" "x")
21656 (parallel [(const_int 0)]))))]
21657 "TARGET_SSE2"
21658 "ucomisd\t{%1, %0|%0, %1}"
21659 [(set_attr "type" "ssecomi")
21660 (set_attr "mode" "DF")])
21661
21662 ;; SSE Strange Moves.
21663
21664 (define_insn "sse2_movmskpd"
21665 [(set (match_operand:SI 0 "register_operand" "=r")
21666 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21667 UNSPEC_MOVMSK))]
21668 "TARGET_SSE2"
21669 "movmskpd\t{%1, %0|%0, %1}"
21670 [(set_attr "type" "ssecvt")
21671 (set_attr "mode" "V2DF")])
21672
21673 (define_insn "sse2_pmovmskb"
21674 [(set (match_operand:SI 0 "register_operand" "=r")
21675 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21676 UNSPEC_MOVMSK))]
21677 "TARGET_SSE2"
21678 "pmovmskb\t{%1, %0|%0, %1}"
21679 [(set_attr "type" "ssecvt")
21680 (set_attr "mode" "V2DF")])
21681
21682 (define_insn "sse2_maskmovdqu"
21683 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21684 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21685 (match_operand:V16QI 2 "register_operand" "x")]
21686 UNSPEC_MASKMOV))]
21687 "TARGET_SSE2"
21688 ;; @@@ check ordering of operands in intel/nonintel syntax
21689 "maskmovdqu\t{%2, %1|%1, %2}"
21690 [(set_attr "type" "ssecvt")
21691 (set_attr "mode" "TI")])
21692
21693 (define_insn "sse2_maskmovdqu_rex64"
21694 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21695 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21696 (match_operand:V16QI 2 "register_operand" "x")]
21697 UNSPEC_MASKMOV))]
21698 "TARGET_SSE2"
21699 ;; @@@ check ordering of operands in intel/nonintel syntax
21700 "maskmovdqu\t{%2, %1|%1, %2}"
21701 [(set_attr "type" "ssecvt")
21702 (set_attr "mode" "TI")])
21703
21704 (define_insn "sse2_movntv2df"
21705 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21706 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21707 UNSPEC_MOVNT))]
21708 "TARGET_SSE2"
21709 "movntpd\t{%1, %0|%0, %1}"
21710 [(set_attr "type" "ssecvt")
21711 (set_attr "mode" "V2DF")])
21712
21713 (define_insn "sse2_movntv2di"
21714 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21715 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21716 UNSPEC_MOVNT))]
21717 "TARGET_SSE2"
21718 "movntdq\t{%1, %0|%0, %1}"
21719 [(set_attr "type" "ssecvt")
21720 (set_attr "mode" "TI")])
21721
21722 (define_insn "sse2_movntsi"
21723 [(set (match_operand:SI 0 "memory_operand" "=m")
21724 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21725 UNSPEC_MOVNT))]
21726 "TARGET_SSE2"
21727 "movnti\t{%1, %0|%0, %1}"
21728 [(set_attr "type" "ssecvt")
21729 (set_attr "mode" "V2DF")])
21730
21731 ;; SSE <-> integer/MMX conversions
21732
21733 ;; Conversions between SI and SF
21734
21735 (define_insn "cvtdq2ps"
21736 [(set (match_operand:V4SF 0 "register_operand" "=x")
21737 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21738 "TARGET_SSE2"
21739 "cvtdq2ps\t{%1, %0|%0, %1}"
21740 [(set_attr "type" "ssecvt")
21741 (set_attr "mode" "V2DF")])
21742
21743 (define_insn "cvtps2dq"
21744 [(set (match_operand:V4SI 0 "register_operand" "=x")
21745 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21746 "TARGET_SSE2"
21747 "cvtps2dq\t{%1, %0|%0, %1}"
21748 [(set_attr "type" "ssecvt")
21749 (set_attr "mode" "TI")])
21750
21751 (define_insn "cvttps2dq"
21752 [(set (match_operand:V4SI 0 "register_operand" "=x")
21753 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21754 UNSPEC_FIX))]
21755 "TARGET_SSE2"
21756 "cvttps2dq\t{%1, %0|%0, %1}"
21757 [(set_attr "type" "ssecvt")
21758 (set_attr "mode" "TI")])
21759
21760 ;; Conversions between SI and DF
21761
21762 (define_insn "cvtdq2pd"
21763 [(set (match_operand:V2DF 0 "register_operand" "=x")
21764 (float:V2DF (vec_select:V2SI
21765 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21766 (parallel
21767 [(const_int 0)
21768 (const_int 1)]))))]
21769 "TARGET_SSE2"
21770 "cvtdq2pd\t{%1, %0|%0, %1}"
21771 [(set_attr "type" "ssecvt")
21772 (set_attr "mode" "V2DF")])
21773
21774 (define_insn "cvtpd2dq"
21775 [(set (match_operand:V4SI 0 "register_operand" "=x")
21776 (vec_concat:V4SI
21777 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21778 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21779 "TARGET_SSE2"
21780 "cvtpd2dq\t{%1, %0|%0, %1}"
21781 [(set_attr "type" "ssecvt")
21782 (set_attr "mode" "TI")])
21783
21784 (define_insn "cvttpd2dq"
21785 [(set (match_operand:V4SI 0 "register_operand" "=x")
21786 (vec_concat:V4SI
21787 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21788 UNSPEC_FIX)
21789 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21790 "TARGET_SSE2"
21791 "cvttpd2dq\t{%1, %0|%0, %1}"
21792 [(set_attr "type" "ssecvt")
21793 (set_attr "mode" "TI")])
21794
21795 (define_insn "cvtpd2pi"
21796 [(set (match_operand:V2SI 0 "register_operand" "=y")
21797 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21798 "TARGET_SSE2"
21799 "cvtpd2pi\t{%1, %0|%0, %1}"
21800 [(set_attr "type" "ssecvt")
21801 (set_attr "mode" "TI")])
21802
21803 (define_insn "cvttpd2pi"
21804 [(set (match_operand:V2SI 0 "register_operand" "=y")
21805 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21806 UNSPEC_FIX))]
21807 "TARGET_SSE2"
21808 "cvttpd2pi\t{%1, %0|%0, %1}"
21809 [(set_attr "type" "ssecvt")
21810 (set_attr "mode" "TI")])
21811
21812 (define_insn "cvtpi2pd"
21813 [(set (match_operand:V2DF 0 "register_operand" "=x")
21814 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21815 "TARGET_SSE2"
21816 "cvtpi2pd\t{%1, %0|%0, %1}"
21817 [(set_attr "type" "ssecvt")
21818 (set_attr "mode" "TI")])
21819
21820 ;; Conversions between SI and DF
21821
21822 (define_insn "cvtsd2si"
21823 [(set (match_operand:SI 0 "register_operand" "=r,r")
21824 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21825 (parallel [(const_int 0)]))))]
21826 "TARGET_SSE2"
21827 "cvtsd2si\t{%1, %0|%0, %1}"
21828 [(set_attr "type" "sseicvt")
21829 (set_attr "athlon_decode" "double,vector")
21830 (set_attr "mode" "SI")])
21831
21832 (define_insn "cvtsd2siq"
21833 [(set (match_operand:DI 0 "register_operand" "=r,r")
21834 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21835 (parallel [(const_int 0)]))))]
21836 "TARGET_SSE2 && TARGET_64BIT"
21837 "cvtsd2siq\t{%1, %0|%0, %1}"
21838 [(set_attr "type" "sseicvt")
21839 (set_attr "athlon_decode" "double,vector")
21840 (set_attr "mode" "DI")])
21841
21842 (define_insn "cvttsd2si"
21843 [(set (match_operand:SI 0 "register_operand" "=r,r")
21844 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21845 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21846 "TARGET_SSE2"
21847 "cvttsd2si\t{%1, %0|%0, %1}"
21848 [(set_attr "type" "sseicvt")
21849 (set_attr "mode" "SI")
21850 (set_attr "athlon_decode" "double,vector")])
21851
21852 (define_insn "cvttsd2siq"
21853 [(set (match_operand:DI 0 "register_operand" "=r,r")
21854 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21855 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21856 "TARGET_SSE2 && TARGET_64BIT"
21857 "cvttsd2siq\t{%1, %0|%0, %1}"
21858 [(set_attr "type" "sseicvt")
21859 (set_attr "mode" "DI")
21860 (set_attr "athlon_decode" "double,vector")])
21861
21862 (define_insn "cvtsi2sd"
21863 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21864 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21865 (vec_duplicate:V2DF
21866 (float:DF
21867 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21868 (const_int 2)))]
21869 "TARGET_SSE2"
21870 "cvtsi2sd\t{%2, %0|%0, %2}"
21871 [(set_attr "type" "sseicvt")
21872 (set_attr "mode" "DF")
21873 (set_attr "athlon_decode" "double,direct")])
21874
21875 (define_insn "cvtsi2sdq"
21876 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21877 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21878 (vec_duplicate:V2DF
21879 (float:DF
21880 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21881 (const_int 2)))]
21882 "TARGET_SSE2 && TARGET_64BIT"
21883 "cvtsi2sdq\t{%2, %0|%0, %2}"
21884 [(set_attr "type" "sseicvt")
21885 (set_attr "mode" "DF")
21886 (set_attr "athlon_decode" "double,direct")])
21887
21888 ;; Conversions between SF and DF
21889
21890 (define_insn "cvtsd2ss"
21891 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21892 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21893 (vec_duplicate:V4SF
21894 (float_truncate:V2SF
21895 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21896 (const_int 14)))]
21897 "TARGET_SSE2"
21898 "cvtsd2ss\t{%2, %0|%0, %2}"
21899 [(set_attr "type" "ssecvt")
21900 (set_attr "athlon_decode" "vector,double")
21901 (set_attr "mode" "SF")])
21902
21903 (define_insn "cvtss2sd"
21904 [(set (match_operand:V2DF 0 "register_operand" "=x")
21905 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21906 (float_extend:V2DF
21907 (vec_select:V2SF
21908 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21909 (parallel [(const_int 0)
21910 (const_int 1)])))
21911 (const_int 2)))]
21912 "TARGET_SSE2"
21913 "cvtss2sd\t{%2, %0|%0, %2}"
21914 [(set_attr "type" "ssecvt")
21915 (set_attr "mode" "DF")])
21916
21917 (define_insn "cvtpd2ps"
21918 [(set (match_operand:V4SF 0 "register_operand" "=x")
21919 (subreg:V4SF
21920 (vec_concat:V4SI
21921 (subreg:V2SI (float_truncate:V2SF
21922 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21923 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21924 "TARGET_SSE2"
21925 "cvtpd2ps\t{%1, %0|%0, %1}"
21926 [(set_attr "type" "ssecvt")
21927 (set_attr "mode" "V4SF")])
21928
21929 (define_insn "cvtps2pd"
21930 [(set (match_operand:V2DF 0 "register_operand" "=x")
21931 (float_extend:V2DF
21932 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21933 (parallel [(const_int 0)
21934 (const_int 1)]))))]
21935 "TARGET_SSE2"
21936 "cvtps2pd\t{%1, %0|%0, %1}"
21937 [(set_attr "type" "ssecvt")
21938 (set_attr "mode" "V2DF")])
21939
21940 ;; SSE2 variants of MMX insns
21941
21942 ;; MMX arithmetic
21943
21944 (define_insn "addv16qi3"
21945 [(set (match_operand:V16QI 0 "register_operand" "=x")
21946 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21947 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21948 "TARGET_SSE2"
21949 "paddb\t{%2, %0|%0, %2}"
21950 [(set_attr "type" "sseiadd")
21951 (set_attr "mode" "TI")])
21952
21953 (define_insn "addv8hi3"
21954 [(set (match_operand:V8HI 0 "register_operand" "=x")
21955 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21956 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21957 "TARGET_SSE2"
21958 "paddw\t{%2, %0|%0, %2}"
21959 [(set_attr "type" "sseiadd")
21960 (set_attr "mode" "TI")])
21961
21962 (define_insn "addv4si3"
21963 [(set (match_operand:V4SI 0 "register_operand" "=x")
21964 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21965 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21966 "TARGET_SSE2"
21967 "paddd\t{%2, %0|%0, %2}"
21968 [(set_attr "type" "sseiadd")
21969 (set_attr "mode" "TI")])
21970
21971 (define_insn "addv2di3"
21972 [(set (match_operand:V2DI 0 "register_operand" "=x")
21973 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21974 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21975 "TARGET_SSE2"
21976 "paddq\t{%2, %0|%0, %2}"
21977 [(set_attr "type" "sseiadd")
21978 (set_attr "mode" "TI")])
21979
21980 (define_insn "ssaddv16qi3"
21981 [(set (match_operand:V16QI 0 "register_operand" "=x")
21982 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21983 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21984 "TARGET_SSE2"
21985 "paddsb\t{%2, %0|%0, %2}"
21986 [(set_attr "type" "sseiadd")
21987 (set_attr "mode" "TI")])
21988
21989 (define_insn "ssaddv8hi3"
21990 [(set (match_operand:V8HI 0 "register_operand" "=x")
21991 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21992 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21993 "TARGET_SSE2"
21994 "paddsw\t{%2, %0|%0, %2}"
21995 [(set_attr "type" "sseiadd")
21996 (set_attr "mode" "TI")])
21997
21998 (define_insn "usaddv16qi3"
21999 [(set (match_operand:V16QI 0 "register_operand" "=x")
22000 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22001 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22002 "TARGET_SSE2"
22003 "paddusb\t{%2, %0|%0, %2}"
22004 [(set_attr "type" "sseiadd")
22005 (set_attr "mode" "TI")])
22006
22007 (define_insn "usaddv8hi3"
22008 [(set (match_operand:V8HI 0 "register_operand" "=x")
22009 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22010 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22011 "TARGET_SSE2"
22012 "paddusw\t{%2, %0|%0, %2}"
22013 [(set_attr "type" "sseiadd")
22014 (set_attr "mode" "TI")])
22015
22016 (define_insn "subv16qi3"
22017 [(set (match_operand:V16QI 0 "register_operand" "=x")
22018 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22019 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22020 "TARGET_SSE2"
22021 "psubb\t{%2, %0|%0, %2}"
22022 [(set_attr "type" "sseiadd")
22023 (set_attr "mode" "TI")])
22024
22025 (define_insn "subv8hi3"
22026 [(set (match_operand:V8HI 0 "register_operand" "=x")
22027 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22028 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22029 "TARGET_SSE2"
22030 "psubw\t{%2, %0|%0, %2}"
22031 [(set_attr "type" "sseiadd")
22032 (set_attr "mode" "TI")])
22033
22034 (define_insn "subv4si3"
22035 [(set (match_operand:V4SI 0 "register_operand" "=x")
22036 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22037 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22038 "TARGET_SSE2"
22039 "psubd\t{%2, %0|%0, %2}"
22040 [(set_attr "type" "sseiadd")
22041 (set_attr "mode" "TI")])
22042
22043 (define_insn "subv2di3"
22044 [(set (match_operand:V2DI 0 "register_operand" "=x")
22045 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22046 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22047 "TARGET_SSE2"
22048 "psubq\t{%2, %0|%0, %2}"
22049 [(set_attr "type" "sseiadd")
22050 (set_attr "mode" "TI")])
22051
22052 (define_insn "sssubv16qi3"
22053 [(set (match_operand:V16QI 0 "register_operand" "=x")
22054 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22055 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22056 "TARGET_SSE2"
22057 "psubsb\t{%2, %0|%0, %2}"
22058 [(set_attr "type" "sseiadd")
22059 (set_attr "mode" "TI")])
22060
22061 (define_insn "sssubv8hi3"
22062 [(set (match_operand:V8HI 0 "register_operand" "=x")
22063 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22064 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22065 "TARGET_SSE2"
22066 "psubsw\t{%2, %0|%0, %2}"
22067 [(set_attr "type" "sseiadd")
22068 (set_attr "mode" "TI")])
22069
22070 (define_insn "ussubv16qi3"
22071 [(set (match_operand:V16QI 0 "register_operand" "=x")
22072 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22073 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22074 "TARGET_SSE2"
22075 "psubusb\t{%2, %0|%0, %2}"
22076 [(set_attr "type" "sseiadd")
22077 (set_attr "mode" "TI")])
22078
22079 (define_insn "ussubv8hi3"
22080 [(set (match_operand:V8HI 0 "register_operand" "=x")
22081 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22082 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22083 "TARGET_SSE2"
22084 "psubusw\t{%2, %0|%0, %2}"
22085 [(set_attr "type" "sseiadd")
22086 (set_attr "mode" "TI")])
22087
22088 (define_insn "mulv8hi3"
22089 [(set (match_operand:V8HI 0 "register_operand" "=x")
22090 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22091 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22092 "TARGET_SSE2"
22093 "pmullw\t{%2, %0|%0, %2}"
22094 [(set_attr "type" "sseimul")
22095 (set_attr "mode" "TI")])
22096
22097 (define_insn "smulv8hi3_highpart"
22098 [(set (match_operand:V8HI 0 "register_operand" "=x")
22099 (truncate:V8HI
22100 (lshiftrt:V8SI
22101 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22102 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22103 (const_int 16))))]
22104 "TARGET_SSE2"
22105 "pmulhw\t{%2, %0|%0, %2}"
22106 [(set_attr "type" "sseimul")
22107 (set_attr "mode" "TI")])
22108
22109 (define_insn "umulv8hi3_highpart"
22110 [(set (match_operand:V8HI 0 "register_operand" "=x")
22111 (truncate:V8HI
22112 (lshiftrt:V8SI
22113 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22114 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22115 (const_int 16))))]
22116 "TARGET_SSE2"
22117 "pmulhuw\t{%2, %0|%0, %2}"
22118 [(set_attr "type" "sseimul")
22119 (set_attr "mode" "TI")])
22120
22121 (define_insn "sse2_umulsidi3"
22122 [(set (match_operand:DI 0 "register_operand" "=y")
22123 (mult:DI (zero_extend:DI (vec_select:SI
22124 (match_operand:V2SI 1 "register_operand" "0")
22125 (parallel [(const_int 0)])))
22126 (zero_extend:DI (vec_select:SI
22127 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22128 (parallel [(const_int 0)])))))]
22129 "TARGET_SSE2"
22130 "pmuludq\t{%2, %0|%0, %2}"
22131 [(set_attr "type" "sseimul")
22132 (set_attr "mode" "TI")])
22133
22134 (define_insn "sse2_umulv2siv2di3"
22135 [(set (match_operand:V2DI 0 "register_operand" "=x")
22136 (mult:V2DI (zero_extend:V2DI
22137 (vec_select:V2SI
22138 (match_operand:V4SI 1 "register_operand" "0")
22139 (parallel [(const_int 0) (const_int 2)])))
22140 (zero_extend:V2DI
22141 (vec_select:V2SI
22142 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22143 (parallel [(const_int 0) (const_int 2)])))))]
22144 "TARGET_SSE2"
22145 "pmuludq\t{%2, %0|%0, %2}"
22146 [(set_attr "type" "sseimul")
22147 (set_attr "mode" "TI")])
22148
22149 (define_insn "sse2_pmaddwd"
22150 [(set (match_operand:V4SI 0 "register_operand" "=x")
22151 (plus:V4SI
22152 (mult:V4SI
22153 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22154 (parallel [(const_int 0)
22155 (const_int 2)
22156 (const_int 4)
22157 (const_int 6)])))
22158 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22159 (parallel [(const_int 0)
22160 (const_int 2)
22161 (const_int 4)
22162 (const_int 6)]))))
22163 (mult:V4SI
22164 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22165 (parallel [(const_int 1)
22166 (const_int 3)
22167 (const_int 5)
22168 (const_int 7)])))
22169 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22170 (parallel [(const_int 1)
22171 (const_int 3)
22172 (const_int 5)
22173 (const_int 7)]))))))]
22174 "TARGET_SSE2"
22175 "pmaddwd\t{%2, %0|%0, %2}"
22176 [(set_attr "type" "sseiadd")
22177 (set_attr "mode" "TI")])
22178
22179 ;; Same as pxor, but don't show input operands so that we don't think
22180 ;; they are live.
22181 (define_insn "sse2_clrti"
22182 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22183 "TARGET_SSE2"
22184 {
22185 if (get_attr_mode (insn) == MODE_TI)
22186 return "pxor\t%0, %0";
22187 else
22188 return "xorps\t%0, %0";
22189 }
22190 [(set_attr "type" "ssemov")
22191 (set_attr "memory" "none")
22192 (set (attr "mode")
22193 (if_then_else
22194 (ne (symbol_ref "optimize_size")
22195 (const_int 0))
22196 (const_string "V4SF")
22197 (const_string "TI")))])
22198
22199 ;; MMX unsigned averages/sum of absolute differences
22200
22201 (define_insn "sse2_uavgv16qi3"
22202 [(set (match_operand:V16QI 0 "register_operand" "=x")
22203 (ashiftrt:V16QI
22204 (plus:V16QI (plus:V16QI
22205 (match_operand:V16QI 1 "register_operand" "0")
22206 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22207 (const_vector:V16QI [(const_int 1) (const_int 1)
22208 (const_int 1) (const_int 1)
22209 (const_int 1) (const_int 1)
22210 (const_int 1) (const_int 1)
22211 (const_int 1) (const_int 1)
22212 (const_int 1) (const_int 1)
22213 (const_int 1) (const_int 1)
22214 (const_int 1) (const_int 1)]))
22215 (const_int 1)))]
22216 "TARGET_SSE2"
22217 "pavgb\t{%2, %0|%0, %2}"
22218 [(set_attr "type" "sseiadd")
22219 (set_attr "mode" "TI")])
22220
22221 (define_insn "sse2_uavgv8hi3"
22222 [(set (match_operand:V8HI 0 "register_operand" "=x")
22223 (ashiftrt:V8HI
22224 (plus:V8HI (plus:V8HI
22225 (match_operand:V8HI 1 "register_operand" "0")
22226 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22227 (const_vector:V8HI [(const_int 1) (const_int 1)
22228 (const_int 1) (const_int 1)
22229 (const_int 1) (const_int 1)
22230 (const_int 1) (const_int 1)]))
22231 (const_int 1)))]
22232 "TARGET_SSE2"
22233 "pavgw\t{%2, %0|%0, %2}"
22234 [(set_attr "type" "sseiadd")
22235 (set_attr "mode" "TI")])
22236
22237 ;; @@@ this isn't the right representation.
22238 (define_insn "sse2_psadbw"
22239 [(set (match_operand:V2DI 0 "register_operand" "=x")
22240 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22241 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22242 UNSPEC_PSADBW))]
22243 "TARGET_SSE2"
22244 "psadbw\t{%2, %0|%0, %2}"
22245 [(set_attr "type" "sseiadd")
22246 (set_attr "mode" "TI")])
22247
22248
22249 ;; MMX insert/extract/shuffle
22250
22251 (define_insn "sse2_pinsrw"
22252 [(set (match_operand:V8HI 0 "register_operand" "=x")
22253 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22254 (vec_duplicate:V8HI
22255 (truncate:HI
22256 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22257 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22258 "TARGET_SSE2"
22259 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22260 [(set_attr "type" "ssecvt")
22261 (set_attr "mode" "TI")])
22262
22263 (define_insn "sse2_pextrw"
22264 [(set (match_operand:SI 0 "register_operand" "=r")
22265 (zero_extend:SI
22266 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22267 (parallel
22268 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22269 "TARGET_SSE2"
22270 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22271 [(set_attr "type" "ssecvt")
22272 (set_attr "mode" "TI")])
22273
22274 (define_insn "sse2_pshufd"
22275 [(set (match_operand:V4SI 0 "register_operand" "=x")
22276 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22277 (match_operand:SI 2 "immediate_operand" "i")]
22278 UNSPEC_SHUFFLE))]
22279 "TARGET_SSE2"
22280 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22281 [(set_attr "type" "ssecvt")
22282 (set_attr "mode" "TI")])
22283
22284 (define_insn "sse2_pshuflw"
22285 [(set (match_operand:V8HI 0 "register_operand" "=x")
22286 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22287 (match_operand:SI 2 "immediate_operand" "i")]
22288 UNSPEC_PSHUFLW))]
22289 "TARGET_SSE2"
22290 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22291 [(set_attr "type" "ssecvt")
22292 (set_attr "mode" "TI")])
22293
22294 (define_insn "sse2_pshufhw"
22295 [(set (match_operand:V8HI 0 "register_operand" "=x")
22296 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22297 (match_operand:SI 2 "immediate_operand" "i")]
22298 UNSPEC_PSHUFHW))]
22299 "TARGET_SSE2"
22300 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22301 [(set_attr "type" "ssecvt")
22302 (set_attr "mode" "TI")])
22303
22304 ;; MMX mask-generating comparisons
22305
22306 (define_insn "eqv16qi3"
22307 [(set (match_operand:V16QI 0 "register_operand" "=x")
22308 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22309 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22310 "TARGET_SSE2"
22311 "pcmpeqb\t{%2, %0|%0, %2}"
22312 [(set_attr "type" "ssecmp")
22313 (set_attr "mode" "TI")])
22314
22315 (define_insn "eqv8hi3"
22316 [(set (match_operand:V8HI 0 "register_operand" "=x")
22317 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22318 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22319 "TARGET_SSE2"
22320 "pcmpeqw\t{%2, %0|%0, %2}"
22321 [(set_attr "type" "ssecmp")
22322 (set_attr "mode" "TI")])
22323
22324 (define_insn "eqv4si3"
22325 [(set (match_operand:V4SI 0 "register_operand" "=x")
22326 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22327 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22328 "TARGET_SSE2"
22329 "pcmpeqd\t{%2, %0|%0, %2}"
22330 [(set_attr "type" "ssecmp")
22331 (set_attr "mode" "TI")])
22332
22333 (define_insn "gtv16qi3"
22334 [(set (match_operand:V16QI 0 "register_operand" "=x")
22335 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22336 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22337 "TARGET_SSE2"
22338 "pcmpgtb\t{%2, %0|%0, %2}"
22339 [(set_attr "type" "ssecmp")
22340 (set_attr "mode" "TI")])
22341
22342 (define_insn "gtv8hi3"
22343 [(set (match_operand:V8HI 0 "register_operand" "=x")
22344 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22345 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22346 "TARGET_SSE2"
22347 "pcmpgtw\t{%2, %0|%0, %2}"
22348 [(set_attr "type" "ssecmp")
22349 (set_attr "mode" "TI")])
22350
22351 (define_insn "gtv4si3"
22352 [(set (match_operand:V4SI 0 "register_operand" "=x")
22353 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22354 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22355 "TARGET_SSE2"
22356 "pcmpgtd\t{%2, %0|%0, %2}"
22357 [(set_attr "type" "ssecmp")
22358 (set_attr "mode" "TI")])
22359
22360
22361 ;; MMX max/min insns
22362
22363 (define_insn "umaxv16qi3"
22364 [(set (match_operand:V16QI 0 "register_operand" "=x")
22365 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22366 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22367 "TARGET_SSE2"
22368 "pmaxub\t{%2, %0|%0, %2}"
22369 [(set_attr "type" "sseiadd")
22370 (set_attr "mode" "TI")])
22371
22372 (define_insn "smaxv8hi3"
22373 [(set (match_operand:V8HI 0 "register_operand" "=x")
22374 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22375 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22376 "TARGET_SSE2"
22377 "pmaxsw\t{%2, %0|%0, %2}"
22378 [(set_attr "type" "sseiadd")
22379 (set_attr "mode" "TI")])
22380
22381 (define_insn "uminv16qi3"
22382 [(set (match_operand:V16QI 0 "register_operand" "=x")
22383 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22384 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22385 "TARGET_SSE2"
22386 "pminub\t{%2, %0|%0, %2}"
22387 [(set_attr "type" "sseiadd")
22388 (set_attr "mode" "TI")])
22389
22390 (define_insn "sminv8hi3"
22391 [(set (match_operand:V8HI 0 "register_operand" "=x")
22392 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22393 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22394 "TARGET_SSE2"
22395 "pminsw\t{%2, %0|%0, %2}"
22396 [(set_attr "type" "sseiadd")
22397 (set_attr "mode" "TI")])
22398
22399
22400 ;; MMX shifts
22401
22402 (define_insn "ashrv8hi3"
22403 [(set (match_operand:V8HI 0 "register_operand" "=x")
22404 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22405 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22406 "TARGET_SSE2"
22407 "psraw\t{%2, %0|%0, %2}"
22408 [(set_attr "type" "sseishft")
22409 (set_attr "mode" "TI")])
22410
22411 (define_insn "ashrv4si3"
22412 [(set (match_operand:V4SI 0 "register_operand" "=x")
22413 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22414 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22415 "TARGET_SSE2"
22416 "psrad\t{%2, %0|%0, %2}"
22417 [(set_attr "type" "sseishft")
22418 (set_attr "mode" "TI")])
22419
22420 (define_insn "lshrv8hi3"
22421 [(set (match_operand:V8HI 0 "register_operand" "=x")
22422 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22423 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22424 "TARGET_SSE2"
22425 "psrlw\t{%2, %0|%0, %2}"
22426 [(set_attr "type" "sseishft")
22427 (set_attr "mode" "TI")])
22428
22429 (define_insn "lshrv4si3"
22430 [(set (match_operand:V4SI 0 "register_operand" "=x")
22431 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22432 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22433 "TARGET_SSE2"
22434 "psrld\t{%2, %0|%0, %2}"
22435 [(set_attr "type" "sseishft")
22436 (set_attr "mode" "TI")])
22437
22438 (define_insn "lshrv2di3"
22439 [(set (match_operand:V2DI 0 "register_operand" "=x")
22440 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22441 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22442 "TARGET_SSE2"
22443 "psrlq\t{%2, %0|%0, %2}"
22444 [(set_attr "type" "sseishft")
22445 (set_attr "mode" "TI")])
22446
22447 (define_insn "ashlv8hi3"
22448 [(set (match_operand:V8HI 0 "register_operand" "=x")
22449 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22450 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22451 "TARGET_SSE2"
22452 "psllw\t{%2, %0|%0, %2}"
22453 [(set_attr "type" "sseishft")
22454 (set_attr "mode" "TI")])
22455
22456 (define_insn "ashlv4si3"
22457 [(set (match_operand:V4SI 0 "register_operand" "=x")
22458 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22459 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22460 "TARGET_SSE2"
22461 "pslld\t{%2, %0|%0, %2}"
22462 [(set_attr "type" "sseishft")
22463 (set_attr "mode" "TI")])
22464
22465 (define_insn "ashlv2di3"
22466 [(set (match_operand:V2DI 0 "register_operand" "=x")
22467 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22468 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22469 "TARGET_SSE2"
22470 "psllq\t{%2, %0|%0, %2}"
22471 [(set_attr "type" "sseishft")
22472 (set_attr "mode" "TI")])
22473
22474 (define_insn "ashrv8hi3_ti"
22475 [(set (match_operand:V8HI 0 "register_operand" "=x")
22476 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22477 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22478 "TARGET_SSE2"
22479 "psraw\t{%2, %0|%0, %2}"
22480 [(set_attr "type" "sseishft")
22481 (set_attr "mode" "TI")])
22482
22483 (define_insn "ashrv4si3_ti"
22484 [(set (match_operand:V4SI 0 "register_operand" "=x")
22485 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22486 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22487 "TARGET_SSE2"
22488 "psrad\t{%2, %0|%0, %2}"
22489 [(set_attr "type" "sseishft")
22490 (set_attr "mode" "TI")])
22491
22492 (define_insn "lshrv8hi3_ti"
22493 [(set (match_operand:V8HI 0 "register_operand" "=x")
22494 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22495 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22496 "TARGET_SSE2"
22497 "psrlw\t{%2, %0|%0, %2}"
22498 [(set_attr "type" "sseishft")
22499 (set_attr "mode" "TI")])
22500
22501 (define_insn "lshrv4si3_ti"
22502 [(set (match_operand:V4SI 0 "register_operand" "=x")
22503 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22504 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22505 "TARGET_SSE2"
22506 "psrld\t{%2, %0|%0, %2}"
22507 [(set_attr "type" "sseishft")
22508 (set_attr "mode" "TI")])
22509
22510 (define_insn "lshrv2di3_ti"
22511 [(set (match_operand:V2DI 0 "register_operand" "=x")
22512 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22513 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22514 "TARGET_SSE2"
22515 "psrlq\t{%2, %0|%0, %2}"
22516 [(set_attr "type" "sseishft")
22517 (set_attr "mode" "TI")])
22518
22519 (define_insn "ashlv8hi3_ti"
22520 [(set (match_operand:V8HI 0 "register_operand" "=x")
22521 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22522 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22523 "TARGET_SSE2"
22524 "psllw\t{%2, %0|%0, %2}"
22525 [(set_attr "type" "sseishft")
22526 (set_attr "mode" "TI")])
22527
22528 (define_insn "ashlv4si3_ti"
22529 [(set (match_operand:V4SI 0 "register_operand" "=x")
22530 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22531 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22532 "TARGET_SSE2"
22533 "pslld\t{%2, %0|%0, %2}"
22534 [(set_attr "type" "sseishft")
22535 (set_attr "mode" "TI")])
22536
22537 (define_insn "ashlv2di3_ti"
22538 [(set (match_operand:V2DI 0 "register_operand" "=x")
22539 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22540 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22541 "TARGET_SSE2"
22542 "psllq\t{%2, %0|%0, %2}"
22543 [(set_attr "type" "sseishft")
22544 (set_attr "mode" "TI")])
22545
22546 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22547 ;; we wouldn't need here it since we never generate TImode arithmetic.
22548
22549 ;; There has to be some kind of prize for the weirdest new instruction...
22550 (define_insn "sse2_ashlti3"
22551 [(set (match_operand:TI 0 "register_operand" "=x")
22552 (unspec:TI
22553 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22554 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22555 (const_int 8)))] UNSPEC_NOP))]
22556 "TARGET_SSE2"
22557 "pslldq\t{%2, %0|%0, %2}"
22558 [(set_attr "type" "sseishft")
22559 (set_attr "mode" "TI")])
22560
22561 (define_insn "sse2_lshrti3"
22562 [(set (match_operand:TI 0 "register_operand" "=x")
22563 (unspec:TI
22564 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22565 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22566 (const_int 8)))] UNSPEC_NOP))]
22567 "TARGET_SSE2"
22568 "psrldq\t{%2, %0|%0, %2}"
22569 [(set_attr "type" "sseishft")
22570 (set_attr "mode" "TI")])
22571
22572 ;; SSE unpack
22573
22574 (define_insn "sse2_unpckhpd"
22575 [(set (match_operand:V2DF 0 "register_operand" "=x")
22576 (vec_concat:V2DF
22577 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22578 (parallel [(const_int 1)]))
22579 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22580 (parallel [(const_int 1)]))))]
22581 "TARGET_SSE2"
22582 "unpckhpd\t{%2, %0|%0, %2}"
22583 [(set_attr "type" "ssecvt")
22584 (set_attr "mode" "V2DF")])
22585
22586 (define_insn "sse2_unpcklpd"
22587 [(set (match_operand:V2DF 0 "register_operand" "=x")
22588 (vec_concat:V2DF
22589 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22590 (parallel [(const_int 0)]))
22591 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22592 (parallel [(const_int 0)]))))]
22593 "TARGET_SSE2"
22594 "unpcklpd\t{%2, %0|%0, %2}"
22595 [(set_attr "type" "ssecvt")
22596 (set_attr "mode" "V2DF")])
22597
22598 ;; MMX pack/unpack insns.
22599
22600 (define_insn "sse2_packsswb"
22601 [(set (match_operand:V16QI 0 "register_operand" "=x")
22602 (vec_concat:V16QI
22603 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22604 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22605 "TARGET_SSE2"
22606 "packsswb\t{%2, %0|%0, %2}"
22607 [(set_attr "type" "ssecvt")
22608 (set_attr "mode" "TI")])
22609
22610 (define_insn "sse2_packssdw"
22611 [(set (match_operand:V8HI 0 "register_operand" "=x")
22612 (vec_concat:V8HI
22613 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22614 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22615 "TARGET_SSE2"
22616 "packssdw\t{%2, %0|%0, %2}"
22617 [(set_attr "type" "ssecvt")
22618 (set_attr "mode" "TI")])
22619
22620 (define_insn "sse2_packuswb"
22621 [(set (match_operand:V16QI 0 "register_operand" "=x")
22622 (vec_concat:V16QI
22623 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22624 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22625 "TARGET_SSE2"
22626 "packuswb\t{%2, %0|%0, %2}"
22627 [(set_attr "type" "ssecvt")
22628 (set_attr "mode" "TI")])
22629
22630 (define_insn "sse2_punpckhbw"
22631 [(set (match_operand:V16QI 0 "register_operand" "=x")
22632 (vec_merge:V16QI
22633 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22634 (parallel [(const_int 8) (const_int 0)
22635 (const_int 9) (const_int 1)
22636 (const_int 10) (const_int 2)
22637 (const_int 11) (const_int 3)
22638 (const_int 12) (const_int 4)
22639 (const_int 13) (const_int 5)
22640 (const_int 14) (const_int 6)
22641 (const_int 15) (const_int 7)]))
22642 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22643 (parallel [(const_int 0) (const_int 8)
22644 (const_int 1) (const_int 9)
22645 (const_int 2) (const_int 10)
22646 (const_int 3) (const_int 11)
22647 (const_int 4) (const_int 12)
22648 (const_int 5) (const_int 13)
22649 (const_int 6) (const_int 14)
22650 (const_int 7) (const_int 15)]))
22651 (const_int 21845)))]
22652 "TARGET_SSE2"
22653 "punpckhbw\t{%2, %0|%0, %2}"
22654 [(set_attr "type" "ssecvt")
22655 (set_attr "mode" "TI")])
22656
22657 (define_insn "sse2_punpckhwd"
22658 [(set (match_operand:V8HI 0 "register_operand" "=x")
22659 (vec_merge:V8HI
22660 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22661 (parallel [(const_int 4) (const_int 0)
22662 (const_int 5) (const_int 1)
22663 (const_int 6) (const_int 2)
22664 (const_int 7) (const_int 3)]))
22665 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22666 (parallel [(const_int 0) (const_int 4)
22667 (const_int 1) (const_int 5)
22668 (const_int 2) (const_int 6)
22669 (const_int 3) (const_int 7)]))
22670 (const_int 85)))]
22671 "TARGET_SSE2"
22672 "punpckhwd\t{%2, %0|%0, %2}"
22673 [(set_attr "type" "ssecvt")
22674 (set_attr "mode" "TI")])
22675
22676 (define_insn "sse2_punpckhdq"
22677 [(set (match_operand:V4SI 0 "register_operand" "=x")
22678 (vec_merge:V4SI
22679 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22680 (parallel [(const_int 2) (const_int 0)
22681 (const_int 3) (const_int 1)]))
22682 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22683 (parallel [(const_int 0) (const_int 2)
22684 (const_int 1) (const_int 3)]))
22685 (const_int 5)))]
22686 "TARGET_SSE2"
22687 "punpckhdq\t{%2, %0|%0, %2}"
22688 [(set_attr "type" "ssecvt")
22689 (set_attr "mode" "TI")])
22690
22691 (define_insn "sse2_punpcklbw"
22692 [(set (match_operand:V16QI 0 "register_operand" "=x")
22693 (vec_merge:V16QI
22694 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22695 (parallel [(const_int 0) (const_int 8)
22696 (const_int 1) (const_int 9)
22697 (const_int 2) (const_int 10)
22698 (const_int 3) (const_int 11)
22699 (const_int 4) (const_int 12)
22700 (const_int 5) (const_int 13)
22701 (const_int 6) (const_int 14)
22702 (const_int 7) (const_int 15)]))
22703 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22704 (parallel [(const_int 8) (const_int 0)
22705 (const_int 9) (const_int 1)
22706 (const_int 10) (const_int 2)
22707 (const_int 11) (const_int 3)
22708 (const_int 12) (const_int 4)
22709 (const_int 13) (const_int 5)
22710 (const_int 14) (const_int 6)
22711 (const_int 15) (const_int 7)]))
22712 (const_int 21845)))]
22713 "TARGET_SSE2"
22714 "punpcklbw\t{%2, %0|%0, %2}"
22715 [(set_attr "type" "ssecvt")
22716 (set_attr "mode" "TI")])
22717
22718 (define_insn "sse2_punpcklwd"
22719 [(set (match_operand:V8HI 0 "register_operand" "=x")
22720 (vec_merge:V8HI
22721 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22722 (parallel [(const_int 0) (const_int 4)
22723 (const_int 1) (const_int 5)
22724 (const_int 2) (const_int 6)
22725 (const_int 3) (const_int 7)]))
22726 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22727 (parallel [(const_int 4) (const_int 0)
22728 (const_int 5) (const_int 1)
22729 (const_int 6) (const_int 2)
22730 (const_int 7) (const_int 3)]))
22731 (const_int 85)))]
22732 "TARGET_SSE2"
22733 "punpcklwd\t{%2, %0|%0, %2}"
22734 [(set_attr "type" "ssecvt")
22735 (set_attr "mode" "TI")])
22736
22737 (define_insn "sse2_punpckldq"
22738 [(set (match_operand:V4SI 0 "register_operand" "=x")
22739 (vec_merge:V4SI
22740 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22741 (parallel [(const_int 0) (const_int 2)
22742 (const_int 1) (const_int 3)]))
22743 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22744 (parallel [(const_int 2) (const_int 0)
22745 (const_int 3) (const_int 1)]))
22746 (const_int 5)))]
22747 "TARGET_SSE2"
22748 "punpckldq\t{%2, %0|%0, %2}"
22749 [(set_attr "type" "ssecvt")
22750 (set_attr "mode" "TI")])
22751
22752 (define_insn "sse2_punpcklqdq"
22753 [(set (match_operand:V2DI 0 "register_operand" "=x")
22754 (vec_merge:V2DI
22755 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22756 (parallel [(const_int 1)
22757 (const_int 0)]))
22758 (match_operand:V2DI 1 "register_operand" "0")
22759 (const_int 1)))]
22760 "TARGET_SSE2"
22761 "punpcklqdq\t{%2, %0|%0, %2}"
22762 [(set_attr "type" "ssecvt")
22763 (set_attr "mode" "TI")])
22764
22765 (define_insn "sse2_punpckhqdq"
22766 [(set (match_operand:V2DI 0 "register_operand" "=x")
22767 (vec_merge:V2DI
22768 (match_operand:V2DI 1 "register_operand" "0")
22769 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22770 (parallel [(const_int 1)
22771 (const_int 0)]))
22772 (const_int 1)))]
22773 "TARGET_SSE2"
22774 "punpckhqdq\t{%2, %0|%0, %2}"
22775 [(set_attr "type" "ssecvt")
22776 (set_attr "mode" "TI")])
22777
22778 ;; SSE2 moves
22779
22780 (define_insn "sse2_movapd"
22781 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22782 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22783 UNSPEC_MOVA))]
22784 "TARGET_SSE2
22785 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22786 "movapd\t{%1, %0|%0, %1}"
22787 [(set_attr "type" "ssemov")
22788 (set_attr "mode" "V2DF")])
22789
22790 (define_insn "sse2_movupd"
22791 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22792 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22793 UNSPEC_MOVU))]
22794 "TARGET_SSE2
22795 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22796 "movupd\t{%1, %0|%0, %1}"
22797 [(set_attr "type" "ssecvt")
22798 (set_attr "mode" "V2DF")])
22799
22800 (define_insn "sse2_movdqa"
22801 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22802 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22803 UNSPEC_MOVA))]
22804 "TARGET_SSE2
22805 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22806 "movdqa\t{%1, %0|%0, %1}"
22807 [(set_attr "type" "ssemov")
22808 (set_attr "mode" "TI")])
22809
22810 (define_insn "sse2_movdqu"
22811 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22812 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22813 UNSPEC_MOVU))]
22814 "TARGET_SSE2
22815 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22816 "movdqu\t{%1, %0|%0, %1}"
22817 [(set_attr "type" "ssecvt")
22818 (set_attr "mode" "TI")])
22819
22820 (define_insn "sse2_movdq2q"
22821 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22822 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22823 (parallel [(const_int 0)])))]
22824 "TARGET_SSE2 && !TARGET_64BIT"
22825 "@
22826 movq\t{%1, %0|%0, %1}
22827 movdq2q\t{%1, %0|%0, %1}"
22828 [(set_attr "type" "ssecvt")
22829 (set_attr "mode" "TI")])
22830
22831 (define_insn "sse2_movdq2q_rex64"
22832 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22833 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22834 (parallel [(const_int 0)])))]
22835 "TARGET_SSE2 && TARGET_64BIT"
22836 "@
22837 movq\t{%1, %0|%0, %1}
22838 movdq2q\t{%1, %0|%0, %1}
22839 movd\t{%1, %0|%0, %1}"
22840 [(set_attr "type" "ssecvt")
22841 (set_attr "mode" "TI")])
22842
22843 (define_insn "sse2_movq2dq"
22844 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22845 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22846 (const_int 0)))]
22847 "TARGET_SSE2 && !TARGET_64BIT"
22848 "@
22849 movq\t{%1, %0|%0, %1}
22850 movq2dq\t{%1, %0|%0, %1}"
22851 [(set_attr "type" "ssecvt,ssemov")
22852 (set_attr "mode" "TI")])
22853
22854 (define_insn "sse2_movq2dq_rex64"
22855 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22856 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22857 (const_int 0)))]
22858 "TARGET_SSE2 && TARGET_64BIT"
22859 "@
22860 movq\t{%1, %0|%0, %1}
22861 movq2dq\t{%1, %0|%0, %1}
22862 movd\t{%1, %0|%0, %1}"
22863 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22864 (set_attr "mode" "TI")])
22865
22866 (define_insn "sse2_movq"
22867 [(set (match_operand:V2DI 0 "register_operand" "=x")
22868 (vec_concat:V2DI (vec_select:DI
22869 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22870 (parallel [(const_int 0)]))
22871 (const_int 0)))]
22872 "TARGET_SSE2"
22873 "movq\t{%1, %0|%0, %1}"
22874 [(set_attr "type" "ssemov")
22875 (set_attr "mode" "TI")])
22876
22877 (define_insn "sse2_loadd"
22878 [(set (match_operand:V4SI 0 "register_operand" "=x")
22879 (vec_merge:V4SI
22880 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22881 (const_vector:V4SI [(const_int 0)
22882 (const_int 0)
22883 (const_int 0)
22884 (const_int 0)])
22885 (const_int 1)))]
22886 "TARGET_SSE2"
22887 "movd\t{%1, %0|%0, %1}"
22888 [(set_attr "type" "ssemov")
22889 (set_attr "mode" "TI")])
22890
22891 (define_insn "sse2_stored"
22892 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22893 (vec_select:SI
22894 (match_operand:V4SI 1 "register_operand" "x")
22895 (parallel [(const_int 0)])))]
22896 "TARGET_SSE2"
22897 "movd\t{%1, %0|%0, %1}"
22898 [(set_attr "type" "ssemov")
22899 (set_attr "mode" "TI")])
22900
22901 (define_insn "sse2_movhpd"
22902 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22903 (vec_merge:V2DF
22904 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22905 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22906 (const_int 2)))]
22907 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22908 "movhpd\t{%2, %0|%0, %2}"
22909 [(set_attr "type" "ssecvt")
22910 (set_attr "mode" "V2DF")])
22911
22912 (define_expand "sse2_loadsd"
22913 [(match_operand:V2DF 0 "register_operand" "")
22914 (match_operand:DF 1 "memory_operand" "")]
22915 "TARGET_SSE2"
22916 {
22917 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22918 CONST0_RTX (V2DFmode)));
22919 DONE;
22920 })
22921
22922 (define_insn "sse2_loadsd_1"
22923 [(set (match_operand:V2DF 0 "register_operand" "=x")
22924 (vec_merge:V2DF
22925 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22926 (match_operand:V2DF 2 "const0_operand" "X")
22927 (const_int 1)))]
22928 "TARGET_SSE2"
22929 "movsd\t{%1, %0|%0, %1}"
22930 [(set_attr "type" "ssecvt")
22931 (set_attr "mode" "DF")])
22932
22933 (define_insn "sse2_movsd"
22934 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22935 (vec_merge:V2DF
22936 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22937 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22938 (const_int 1)))]
22939 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22940 "@movsd\t{%2, %0|%0, %2}
22941 movlpd\t{%2, %0|%0, %2}
22942 movlpd\t{%2, %0|%0, %2}"
22943 [(set_attr "type" "ssecvt")
22944 (set_attr "mode" "DF,V2DF,V2DF")])
22945
22946 (define_insn "sse2_storesd"
22947 [(set (match_operand:DF 0 "memory_operand" "=m")
22948 (vec_select:DF
22949 (match_operand:V2DF 1 "register_operand" "x")
22950 (parallel [(const_int 0)])))]
22951 "TARGET_SSE2"
22952 "movsd\t{%1, %0|%0, %1}"
22953 [(set_attr "type" "ssecvt")
22954 (set_attr "mode" "DF")])
22955
22956 (define_insn "sse2_shufpd"
22957 [(set (match_operand:V2DF 0 "register_operand" "=x")
22958 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22959 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22960 (match_operand:SI 3 "immediate_operand" "i")]
22961 UNSPEC_SHUFFLE))]
22962 "TARGET_SSE2"
22963 ;; @@@ check operand order for intel/nonintel syntax
22964 "shufpd\t{%3, %2, %0|%0, %2, %3}"
22965 [(set_attr "type" "ssecvt")
22966 (set_attr "mode" "V2DF")])
22967
22968 (define_insn "sse2_clflush"
22969 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22970 UNSPECV_CLFLUSH)]
22971 "TARGET_SSE2"
22972 "clflush %0"
22973 [(set_attr "type" "sse")
22974 (set_attr "memory" "unknown")])
22975
22976 (define_expand "sse2_mfence"
22977 [(set (match_dup 0)
22978 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22979 "TARGET_SSE2"
22980 {
22981 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22982 MEM_VOLATILE_P (operands[0]) = 1;
22983 })
22984
22985 (define_insn "*mfence_insn"
22986 [(set (match_operand:BLK 0 "" "")
22987 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22988 "TARGET_SSE2"
22989 "mfence"
22990 [(set_attr "type" "sse")
22991 (set_attr "memory" "unknown")])
22992
22993 (define_expand "sse2_lfence"
22994 [(set (match_dup 0)
22995 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22996 "TARGET_SSE2"
22997 {
22998 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22999 MEM_VOLATILE_P (operands[0]) = 1;
23000 })
23001
23002 (define_insn "*lfence_insn"
23003 [(set (match_operand:BLK 0 "" "")
23004 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23005 "TARGET_SSE2"
23006 "lfence"
23007 [(set_attr "type" "sse")
23008 (set_attr "memory" "unknown")])
23009
23010 ;; SSE3
23011
23012 (define_insn "mwait"
23013 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23014 (match_operand:SI 1 "register_operand" "c")]
23015 UNSPECV_MWAIT)]
23016 "TARGET_SSE3"
23017 "mwait\t%0, %1"
23018 [(set_attr "length" "3")])
23019
23020 (define_insn "monitor"
23021 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23022 (match_operand:SI 1 "register_operand" "c")
23023 (match_operand:SI 2 "register_operand" "d")]
23024 UNSPECV_MONITOR)]
23025 "TARGET_SSE3"
23026 "monitor\t%0, %1, %2"
23027 [(set_attr "length" "3")])
23028
23029 ;; SSE3 arithmetic
23030
23031 (define_insn "addsubv4sf3"
23032 [(set (match_operand:V4SF 0 "register_operand" "=x")
23033 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23034 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23035 UNSPEC_ADDSUB))]
23036 "TARGET_SSE3"
23037 "addsubps\t{%2, %0|%0, %2}"
23038 [(set_attr "type" "sseadd")
23039 (set_attr "mode" "V4SF")])
23040
23041 (define_insn "addsubv2df3"
23042 [(set (match_operand:V2DF 0 "register_operand" "=x")
23043 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23044 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23045 UNSPEC_ADDSUB))]
23046 "TARGET_SSE3"
23047 "addsubpd\t{%2, %0|%0, %2}"
23048 [(set_attr "type" "sseadd")
23049 (set_attr "mode" "V2DF")])
23050
23051 (define_insn "haddv4sf3"
23052 [(set (match_operand:V4SF 0 "register_operand" "=x")
23053 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23054 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23055 UNSPEC_HADD))]
23056 "TARGET_SSE3"
23057 "haddps\t{%2, %0|%0, %2}"
23058 [(set_attr "type" "sseadd")
23059 (set_attr "mode" "V4SF")])
23060
23061 (define_insn "haddv2df3"
23062 [(set (match_operand:V2DF 0 "register_operand" "=x")
23063 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23064 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23065 UNSPEC_HADD))]
23066 "TARGET_SSE3"
23067 "haddpd\t{%2, %0|%0, %2}"
23068 [(set_attr "type" "sseadd")
23069 (set_attr "mode" "V2DF")])
23070
23071 (define_insn "hsubv4sf3"
23072 [(set (match_operand:V4SF 0 "register_operand" "=x")
23073 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23074 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23075 UNSPEC_HSUB))]
23076 "TARGET_SSE3"
23077 "hsubps\t{%2, %0|%0, %2}"
23078 [(set_attr "type" "sseadd")
23079 (set_attr "mode" "V4SF")])
23080
23081 (define_insn "hsubv2df3"
23082 [(set (match_operand:V2DF 0 "register_operand" "=x")
23083 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23084 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23085 UNSPEC_HSUB))]
23086 "TARGET_SSE3"
23087 "hsubpd\t{%2, %0|%0, %2}"
23088 [(set_attr "type" "sseadd")
23089 (set_attr "mode" "V2DF")])
23090
23091 (define_insn "movshdup"
23092 [(set (match_operand:V4SF 0 "register_operand" "=x")
23093 (unspec:V4SF
23094 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23095 "TARGET_SSE3"
23096 "movshdup\t{%1, %0|%0, %1}"
23097 [(set_attr "type" "sse")
23098 (set_attr "mode" "V4SF")])
23099
23100 (define_insn "movsldup"
23101 [(set (match_operand:V4SF 0 "register_operand" "=x")
23102 (unspec:V4SF
23103 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23104 "TARGET_SSE3"
23105 "movsldup\t{%1, %0|%0, %1}"
23106 [(set_attr "type" "sse")
23107 (set_attr "mode" "V4SF")])
23108
23109 (define_insn "lddqu"
23110 [(set (match_operand:V16QI 0 "register_operand" "=x")
23111 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23112 UNSPEC_LDQQU))]
23113 "TARGET_SSE3"
23114 "lddqu\t{%1, %0|%0, %1}"
23115 [(set_attr "type" "ssecvt")
23116 (set_attr "mode" "TI")])
23117
23118 (define_insn "loadddup"
23119 [(set (match_operand:V2DF 0 "register_operand" "=x")
23120 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23121 "TARGET_SSE3"
23122 "movddup\t{%1, %0|%0, %1}"
23123 [(set_attr "type" "ssecvt")
23124 (set_attr "mode" "DF")])
23125
23126 (define_insn "movddup"
23127 [(set (match_operand:V2DF 0 "register_operand" "=x")
23128 (vec_duplicate:V2DF
23129 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23130 (parallel [(const_int 0)]))))]
23131 "TARGET_SSE3"
23132 "movddup\t{%1, %0|%0, %1}"
23133 [(set_attr "type" "ssecvt")
23134 (set_attr "mode" "DF")])